-
Notifications
You must be signed in to change notification settings - Fork 318
KaTeX (2/n): Support for vertical offsets in spans #1698
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
base: main
Are you sure you want to change the base?
Conversation
d8b0539
to
de8b678
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.
Thanks for all your work on this! Now that #1452 is merged, I'm reaching these commits for detailed review :-)
Comments below. Posting this now because I'm going AFK, but I've read most of the branch so far: partway through the tests, and read all the other changes.
dom.Element(localName: 'span', className: 'vlist-r', nodes: [ | ||
dom.Element(localName: 'span', className: 'vlist', nodes: [ | ||
dom.Element(localName: 'span', className: '', nodes: []), | ||
]), | ||
]), | ||
]) { |
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.
Interesting — do we not need any information from this second row of the table?
It looks like an example of how that second row looks in the HTML is (from ContentExample.mathBlockKatexVertical2 added here):
<span class="vlist-r">
<span class="vlist" style="height:0.15em;"><span></span></span></span>
What's the effect of that height
value when the whole vlist-t gets rendered in a browser?
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.
The value of height
on span.vlist-r span.vlist
specifies the height of the whole span.vlist-t
. And if there are two span.vlist-r
then the addition of height
value of both span.vlist-r span.vlist
specifies the height of the whole span.vlist-t
.
From the web dev console, disabling height
on either span.vlist-r span.vlist
doesn't seem to affect the rendering.
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.
Hmm, OK. A bit odd that there's that information there and it's not getting used; but maybe it's another example where it either used to get used, or gets used within KaTeX's internal processing.
Let's definitely mark that with a comment, though, because otherwise it looks wrong to a reader who's comparing this parsing code to the HTML. In fact we should do that for both of the .vlist
cases — this one for the second .vlist-r
's child, and below for the first/main .vlist-r
's child.
if (vlistT.nodes.isEmpty) throw _KatexHtmlParseError(); | ||
if (vlistT.attributes.containsKey('style')) throw _KatexHtmlParseError(); | ||
|
||
final hasTwoVlistR = vlistT.className == 'vlist-t vlist-t2'; |
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.
There's also a CSS rule for .vlist-t2 in the KaTeX CSS:
.vlist-t2 {
margin-right: -2px;
}
What's the net effect of that? On its face it looks like something we should have to take account of.
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 will need support for negative margins, so will add a commit in the next PR for this. (It will also need changes for supporting non-em
values in KatexSpanStyles.)
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.
Cool, sounds good. Please file a brief follow-up issue for that, then; and then this code can have a TODO comment mentioning that issue.
lib/model/katex.dart
Outdated
|
||
return KatexVlistNode( | ||
rows: rows, | ||
debugHtmlNode: kDebugMode ? vlistT : 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.
nit:
debugHtmlNode: kDebugMode ? vlistT : null, | |
debugHtmlNode: debugHtmlNode, |
This is equivalent, right? Seems simpler for the reader — makes it the same as most of our debugHtmlNode
arguments.
final rows = <KatexVlistRowNode>[]; | ||
|
||
for (final innerSpan in vlist.nodes) { |
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.
Hmm, what's meant by calling these "rows"?
In CSS terms, the element that's a "row" here is the .vlist-r
— that's the one with display: table-row
. But that's the grandparent of these elements — these are the children of the .vlist
, which is one cell of the table (having display: table-cell
).
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.
IIRC, I called them "rows" because they seem like rows in a column with different vertical offset.
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.
OK, we can go with that.
if (innerSpan.className != '') { | ||
throw _KatexHtmlParseError('unexpected CSS class for ' | ||
'vlist inner span: ${innerSpan.className}'); | ||
} |
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 guess this points at a different, sometimes-applicable downside of if-case syntax (other than the fact that it puts the failure case way at the bottom on the other side of the main code, which we can hope to someday have a "guard let" feature to address): it doesn't make room for emitting specific errors for specific types of failures to match.
test/model/content_test.dart
Outdated
static const mathBlockKatexVertical2 = ContentExample( | ||
'math block katex vertical 2', |
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.
Can you give these examples names that reflect what interesting situations they're each exercising that isn't covered by the other examples?
For example, this one introduces vlist-t2
, which is definitely an interesting case that's good to be sure to cover.
test/model/content_test.dart
Outdated
static const mathBlockKatexVertical3 = ContentExample( | ||
'math block katex vertical 3', |
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.
(And I'm not sure what this example demonstrates that isn't covered by the "vertical 1" example above. So that would be good to make explicit.)
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.
Removed this example as it was technically same as "vertical 1", just different characters.
(As we discussed on #1452 earlier, let's avoid major revisions to these commits until this PR and #1559 are merged — that will help reduce the work of tracking what changed between the last few releases, which have already included versions of these, and the version we eventually merge. Instead let's stick to small edits for the moment where possible, and make larger changes as follow-up PRs.) |
Implement handling most common types of `vlist` spans.
de8b678
to
8c6b215
Compare
Turns out that anything under KatexVlistRowNode wasn't being tested by content tests, fix that by implementing this method. Fortunately there were no fixes needed in the tests.
Thanks for the review @gnprice! Pushed an update, PTAL. Also, I've added commits for 2 bug fixes: |
CI failure is unrelated, will investigate later.
|
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.
Thanks for the revision! Comments below.
final rows = <KatexVlistRowNode>[]; | ||
|
||
for (final innerSpan in vlist.nodes) { |
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.
OK, we can go with that.
if (vlistT.nodes.isEmpty) throw _KatexHtmlParseError(); | ||
if (vlistT.attributes.containsKey('style')) throw _KatexHtmlParseError(); | ||
|
||
final hasTwoVlistR = vlistT.className == 'vlist-t vlist-t2'; |
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.
Cool, sounds good. Please file a brief follow-up issue for that, then; and then this code can have a TODO comment mentioning that issue.
List<DiagnosticsNode> debugDescribeChildren() { | ||
return [node.toDiagnosticsNode()]; |
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.
content: Implement debugDescribeChildren for KatexVlistRowNode
Turns out that anything under KatexVlistRowNode wasn't being
tested by content tests, fix that by implementing this method.
Hmm indeed, good to catch this!
This meant it wasn't appearing in either the actual or expected tree, so it just got missed.
I went and scanned through all the other node classes in this file, and I think this is the only such omission.
dom.Element(localName: 'span', className: 'vlist-r', nodes: [ | ||
dom.Element(localName: 'span', className: 'vlist', nodes: [ | ||
dom.Element(localName: 'span', className: '', nodes: []), | ||
]), | ||
]), | ||
]) { |
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.
Hmm, OK. A bit odd that there's that information there and it's not getting used; but maybe it's another example where it either used to get used, or gets used within KaTeX's internal processing.
Let's definitely mark that with a comment, though, because otherwise it looks wrong to a reader who's comparing this parsing code to the HTML. In fact we should do that for both of the .vlist
cases — this one for the second .vlist-r
's child, and below for the first/main .vlist-r
's child.
MathBlockNode( | ||
texSource: 'a\'', | ||
nodes: [ | ||
KatexSpanNode( | ||
styles: KatexSpanStyles(), | ||
text: null, | ||
nodes: [ |
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.
Let's make these examples more compact in the same way I described today at #1559 (comment) . I think that will help making it easier to visually scan for the interesting parts.
I think the problem is that the last tag is more than 1000 commits behind origin/main (or, equally, master):
The quick fix is to bump the Then we should probably also follow up to get the upstream Flutter release team to start putting tags in main again, so that version numbers in the main/master channel are accurate. (There's been a 3.34 and a 3.35 at this point, so the version number shouldn't be saying "3.33".) That's an issue whenever using the main (or master) channel, even when one makes a full clone without using |
Stacked on top of: #1452
Related: #46