Skip to content

Move \global and \def to functions#2138

Merged
k4b7 merged 9 commits intomasterfrom
internal
Dec 5, 2019
Merged

Move \global and \def to functions#2138
k4b7 merged 9 commits intomasterfrom
internal

Conversation

@ylemkimon
Copy link
Member

TeX primitive commands are more like functions, so move to functions and return new parseNode type internal, which is skipped during parseExpression.

@codecov-io
Copy link

codecov-io commented Oct 27, 2019

Codecov Report

Merging #2138 into master will increase coverage by <.01%.
The diff coverage is 93.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2138      +/-   ##
==========================================
+ Coverage   94.75%   94.75%   +<.01%     
==========================================
  Files          82       83       +1     
  Lines        5315     5316       +1     
  Branches      927      927              
==========================================
+ Hits         5036     5037       +1     
  Misses        256      256              
  Partials       23       23
Flag Coverage Δ
#screenshotter 89.26% <44.82%> (+0.02%) ⬆️
#test 88.48% <93.33%> (ø) ⬆️
Impacted Files Coverage Δ
src/parseNode.js 80% <ø> (ø) ⬆️
src/macros.js 97.08% <ø> (+0.26%) ⬆️
src/functions.js 100% <ø> (ø) ⬆️
contrib/render-a11y-string/render-a11y-string.js 89.18% <0%> (-0.35%) ⬇️
src/Parser.js 96.85% <100%> (+0.01%) ⬆️
src/functions/def.js 96.29% <96.29%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0d8830a...6694bee. Read the comment docs.

Move \newcommand back to macros for now
@ylemkimon ylemkimon changed the title Move \def and \newcommand to functions Move \global and \def to functions Nov 3, 2019
@edemaine
Copy link
Member

@ylemkimon Could you clarify the sense in which \def is more like a function than a macro? I assumed functions were a match for things that produced output, but \defs do not. Could you show an example that parses more correctly this way? (Apologies if this is mentioned in another issue/PR -- I'm far from caught up.) Would also make sense to add this as a test.

@ylemkimon
Copy link
Member Author

ylemkimon commented Dec 1, 2019

@edemaine \def is a primitive TeX command, which is unexpandable and consumed in the TeX's "stomach", whereas macros are expandable and consumed in the TeX's "gullet". Currently in KaTeX, \def is defined as a macro that expands into an empty string before reaching the "stomach". So, for instance, 2^\def\foo{1}2 expands into 2^2 in KaTeX, but doesn't work in TeX.

Furthermore, this is required in two pending PRs:

it("should prevent expansion", () => {
expect`\gdef\foo{1}\foo`.toParse();
expect`\gdef\foo{1}\foo`.toParse(new Settings({maxExpand: 2}));
expect`\gdef\foo{1}\foo`.not.toParse(new Settings({maxExpand: 1}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the behavior was wrong before this PR. It it safe to say that the following will pass now?

expect`\gdef\foo{1}\foo`.toParse(new Settings({maxExpand: 1}));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinbarabash That seems better!

Comment on lines +658 to +660
case "internal": {
break;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In reality we should never have to handle this case since all all internal nodes in the AST should get expanded, right?

Copy link
Member

@edemaine edemaine Dec 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the \def function returns an internal node (at least that's what the PR main text says), and this throws it away.

Edit: Oops, I see: yes, maybe not possible in render-a11y-string.js, given that they're eaten by Parser.js. This might just be to handle lint?

@@ -0,0 +1,79 @@
//@flow
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name of this file feels a bit misleading. Could you renamed it to internal.js?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think assignment refers to \def and \gdef which is the purpose of this file. (The idea is that other commands might also generate internal.) I could see calling it def.js. The name assignment.js is presumably future-proofing for an eventual \let definition? But I'd still lean toward def.js.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why I suggested internal.js was that it also handles \global, but if \global can only be used with \def then def.js should be fine as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to def.js.

Copy link
Member

@k4b7 k4b7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting a filename change from assignment.js to internal.js. Other than that, this looks great. The fact that all existing tests pass and it fixed one of the test cases gives me confidence in this change.

@edemaine
Copy link
Member

edemaine commented Dec 2, 2019

@ylemkimon Thanks for the explanation! I see now and agree.

Ideally we should mention in a comment somewhere that KaTeX macros correspond to TeX gullet and KaTeX functions correspond to TeX stomach. I was (mostly) aware of this, but wasn't really aware of how \def fit in.

2^\def\foo{1}2 is a great example to think about, and I think we should add it as a test too (unless you already did and I missed it).

expect`\global\def\foo{}\foo`.toParseLike``;
// TODO: This doesn't work yet; \global needs to expand argument.
//expect`\def\DEF{\def}\global\DEF\foo{}\foo`.toParseLike``;
expect`\def\DEF{\def}\global\DEF\foo{}\foo`.toParseLike``;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out this fixes another test case.

Copy link
Member

@k4b7 k4b7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for improving the behavior of \def.

@k4b7 k4b7 merged commit b1eeeec into master Dec 5, 2019
@ylemkimon ylemkimon deleted the internal branch July 11, 2020 19:19
@edemaine edemaine mentioned this pull request Mar 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants