-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow sizing commands inside optional groups #885
Conversation
src/Parser.js
Outdated
@@ -165,7 +165,8 @@ class Parser { | |||
if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) { | |||
break; | |||
} | |||
const atom = this.parseAtom(); | |||
const optional = breakOnTokenText === "]"; | |||
const atom = this.parseAtom(optional); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't thought about this deeply, but is there a reason to just pass in ]
and not just breakOnTokenText
in general? I think the latter might be useful for more general macro support in the future... Maybe worth reviewing what other values this currently takes on in the code, if any.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. I'll look into this evening.
1bfae05
to
80e4b68
Compare
"type": "sizing", | ||
"value": Object { | ||
"size": 5, | ||
"value": Array [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of weird. I hope that in the future that sizing
nodes could maybe look like:
ParseNode: {
mode: "math",
type: "sizing",
size: 5,
body: Array [ ... ],
}
I'm going to update the jsDocs to include the new |
Will do. I'll do one pass now. And if there are any changes. Then one in the morning. |
src/Parser.js
Outdated
@@ -165,7 +165,8 @@ class Parser { | |||
if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) { | |||
break; | |||
} | |||
const atom = this.parseAtom(); | |||
// const optional = breakOnTokenText === "]"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this now be removed?
src/Parser.js
Outdated
@@ -308,10 +309,10 @@ class Parser { | |||
* | |||
* @return {?ParseNode} | |||
*/ | |||
parseAtom() { | |||
parseAtom(breakOnTokenText) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Mind adding a @param
documenting the type of the new parameter?
src/Parser.js
Outdated
@@ -425,7 +426,7 @@ class Parser { | |||
* | |||
* @return {?ParseNode} | |||
*/ | |||
parseImplicitGroup() { | |||
parseImplicitGroup(breakOnTokenText) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, please.
}, | ||
], | ||
}, | ||
"type": "sqrt", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(optional) I don't know whether an arbitrary strict order is enforced here, but if not, moving this up would make it much easier to see which level it is in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can set up a custom formatter for the snapshots to always put "type"
first.
// The body of an atom is an implicit group, so that things like | ||
// \left(x\right)^2 work correctly. | ||
const base = this.parseImplicitGroup(); | ||
const base = this.parseImplicitGroup(breakOnTokenText); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth adding a comment somewhere as to why it's okay not to pass this parameter down to other methods below. The reason seems to be subtle: as handleSupSubscript
can call parseGroup
which can call parseExpression
, but parseExpression
is only called in parseGroup
only if a {
or [
is encountered, opening a deeper layer. But I haven't yet done an exhaustive check.
I'm also fine with completely deferring this if we intend to formalize the various non-obvious invariants in this file some point to aid comprehensibility so that they aren't violated in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a comment. handleSupSubscript
should always be parsing non-optional groups afaict because x^[2]
isn't valid (or rather it's valid it's treated as x^{[}2]
).
80e4b68
to
b44efb3
Compare
@@ -834,7 +836,7 @@ export default class Parser { | |||
if (this.nextToken.text === (optional ? "[" : "{")) { | |||
// If we get a brace, parse an expression | |||
this.consume(); | |||
const expression = this.parseExpression(false, optional ? "]" : null); | |||
const expression = this.parseExpression(false, optional ? "]" : "}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this was null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parsing always ends on }
, so I'm not sure specifying "}"
is necessary... hence the null
. (It's been a while since I've looked at this code, so I forget the exact details...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels nice to have symmetry the ? "[" : "{"
check above.
29827f5
to
7bfc125
Compare
@@ -527,7 +529,7 @@ export default class Parser { | |||
} else if (utils.contains(Parser.sizeFuncs, func)) { | |||
// If we see a sizing function, parse out the implicit body | |||
this.consumeSpaces(); | |||
const body = this.parseExpression(false); | |||
const body = this.parseExpression(false, breakOnTokenText); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this only apply to this block and not to the rest below: styleFuncs
, oldFontFuncs
, and \color
? Are they not similarly affected? Or do none of our functions currently want to allow these in optional groups?
Otherwise, this PR mostly LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I was fixing only the issue, but I'm sure there are places where KA also uses \color
inside of optional groups (apparently LaTeX supports this too). LaTeX also supports style functions within optional blocks too.
91ac174
to
5ba86ca
Compare
5ba86ca
to
326f17f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@marcianx thanks for the review. Feel free to merge PRs as well. |
Fixes #650 and #516.
TODO: