@@ -258,23 +258,45 @@ class _KatexParser {
258
258
if (vlistT.nodes.isEmpty) throw _KatexHtmlParseError ();
259
259
if (vlistT.attributes.containsKey ('style' )) throw _KatexHtmlParseError ();
260
260
261
+ // A .vlist-t node is a CSS table; .vlist-r are rows, and
262
+ // .vlist and .vlist-s are cells. See the CSS rules:
263
+ // https://github.com/KaTeX/KaTeX/blob/9fb63136e/src/styles/katex.scss#L183-L231
264
+ //
265
+ // The structure of a .vlist-t node is very specific.
266
+ // See the code that generates it:
267
+ // https://github.com/KaTeX/KaTeX/blob/9fb63136e/src/buildCommon.js#L589-L620
268
+ // As seen in that code, there are either two rows totalling three cells
269
+ // (namely [[vlist, topStrut], [depthStrut]]), or one row with one cell
270
+ // ([[vlist]]), where "vlist" is a .vlist node which contains all the
271
+ // real content of the .vlist-t.
272
+ //
273
+ // The extra cells "topStrut" and "depthStrut" are workarounds for
274
+ // Safari circa 2017, as seen in comments in the linked KaTeX code.
275
+ // When present, the .vlist-t node has another class `vlist-t2`,
276
+ // whose only effect is to cancel out part of the effect of "topStrut"
277
+ // (which is a .vlist-s); see the commit that added `vlist-t2`:
278
+ // https://github.com/KaTeX/KaTeX/commit/766487bfe
279
+ // So we ignore that part of the CSS. We ignore the rest of those
280
+ // two "strut" cells too, because they don't seem to have any effect
281
+ // in rendering on the web (in e.g. a modern Chrome, in 2025).
282
+
261
283
final hasVlistT2 = vlistT.className == 'vlist-t vlist-t2' ;
262
284
if (! hasVlistT2 && vlistT.nodes.length != 1 ) throw _KatexHtmlParseError ();
263
285
if (hasVlistT2) {
264
286
if (vlistT.nodes case [
265
- _,
287
+ _, // this row should have two cells [vlist, topStrut]; see details above
266
288
dom.Element (localName: 'span' , className: 'vlist-r' , nodes: [
267
289
dom.Element (localName: 'span' , className: 'vlist' , nodes: [
268
290
dom.Element (localName: 'span' , className: '' , nodes: []),
269
- ]) && final vlist ,
291
+ ]) && final depthStrut ,
270
292
]),
271
293
]) {
272
- // In the generated HTML the .vlist in second .vlist-r span will have
273
- // a "height" inline style which we ignore, because it doesn't seem
274
- // to have any effect in rendering on the web .
275
- // But also make sure there aren't any other inline styles present.
276
- final vlistStyles = _parseInlineStyles (vlist );
277
- if (vlistStyles != null && vlistStyles .keys.any ((p) => p != 'height' )) {
294
+ // This "depthStrut" cell will have a "height" inline style,
295
+ // which we ignore because it doesn't seem to have any effect in web;
296
+ // see detailed comment above .
297
+ // Make sure there aren't any other, unexpected, inline styles present.
298
+ final styles = _parseInlineStyles (depthStrut );
299
+ if (styles != null && styles .keys.any ((p) => p != 'height' )) {
278
300
throw _KatexHtmlParseError ();
279
301
}
280
302
} else {
@@ -290,11 +312,10 @@ class _KatexParser {
290
312
if (vlistR.nodes.first
291
313
case dom.Element (localName: 'span' , className: 'vlist' ) &&
292
314
final vlist) {
293
- // Same as above for the second .vlist-r span, .vlist span in first
294
- // .vlist-r span will have "height" inline style which we ignore,
295
- // because it doesn't seem to have any effect in rendering on
296
- // the web.
297
- // But also make sure there aren't any other inline styles present.
315
+ // Same as above for the "depthStrut" node, the main "vlist" cell
316
+ // will have a "height" inline style which we ignore
317
+ // because it doesn't seem to have any effect in rendering on the web.
318
+ // Make sure there aren't any other, unexpected, inline styles present.
298
319
final vlistStyles = _parseInlineStyles (vlist);
299
320
if (vlistStyles != null && vlistStyles.keys.any ((p) => p != 'height' )) {
300
321
throw _KatexHtmlParseError ();
@@ -355,21 +376,6 @@ class _KatexParser {
355
376
}
356
377
}
357
378
358
- // The katex.css has .vlist-t2 and .vlist-s classes for working around
359
- // Safari rendering issues. In HTML the .vlist-t2 class will be present
360
- // along with the .vlist-t class, and .vlist-s class will be present on
361
- // an empty span in the first (of the two) .vlist-r span.
362
- //
363
- // The KaTeX implementation confirms that both classes are always
364
- // present in tandem. And by experimenting via browser devtools and
365
- // the CSS definition and, it can be confirmed that both cancel each
366
- // others effect of the 2px shift.
367
- // See:
368
- // https://github.com/KaTeX/KaTeX/blob/9fb63136e/src/buildCommon.js#L596-L620
369
- // https://github.com/KaTeX/KaTeX/commit/766487bfe
370
- //
371
- // So, we ignore these classes, as those workarounds aren't needed.
372
-
373
379
return KatexVlistNode (
374
380
rows: rows,
375
381
debugHtmlNode: kDebugMode ? element : null ,
0 commit comments