Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 37 additions & 18 deletions lib/model/katex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -258,24 +258,45 @@ class _KatexParser {
if (vlistT.nodes.isEmpty) throw _KatexHtmlParseError();
if (vlistT.attributes.containsKey('style')) throw _KatexHtmlParseError();

final hasTwoVlistR = vlistT.className == 'vlist-t vlist-t2';
if (!hasTwoVlistR && vlistT.nodes.length != 1) throw _KatexHtmlParseError();

if (hasTwoVlistR) {
// A .vlist-t node is a CSS table; .vlist-r are rows, and
// .vlist and .vlist-s are cells. See the CSS rules:
// https://github.com/KaTeX/KaTeX/blob/9fb63136e/src/styles/katex.scss#L183-L231
//
// The structure of a .vlist-t node is very specific.
// See the code that generates it:
// https://github.com/KaTeX/KaTeX/blob/9fb63136e/src/buildCommon.js#L589-L620
// As seen in that code, there are either two rows totalling three cells
// (namely [[vlist, topStrut], [depthStrut]]), or one row with one cell
// ([[vlist]]), where "vlist" is a .vlist node which contains all the
// real content of the .vlist-t.
//
// The extra cells "topStrut" and "depthStrut" are workarounds for
// Safari circa 2017, as seen in comments in the linked KaTeX code.
// When those are present, the .vlist-t node has another class `vlist-t2`,
// whose only effect is to cancel out part of the effect of "topStrut"
// (which is a .vlist-s); see the commit that added `vlist-t2`:
// https://github.com/KaTeX/KaTeX/commit/766487bfe
// So we ignore that part of the CSS. We ignore the rest of those
// two "strut" cells too, because they don't seem to have any effect
// in rendering on the web (in e.g. a modern Chrome, in 2025).

final hasVlistT2 = vlistT.className == 'vlist-t vlist-t2';
if (!hasVlistT2 && vlistT.nodes.length != 1) throw _KatexHtmlParseError();
if (hasVlistT2) {
if (vlistT.nodes case [
_,
_, // this row should have two cells [vlist, topStrut]; see details above
dom.Element(localName: 'span', className: 'vlist-r', nodes: [
dom.Element(localName: 'span', className: 'vlist', nodes: [
dom.Element(localName: 'span', className: '', nodes: []),
]) && final vlist,
]) && final depthStrut,
]),
]) {
// In the generated HTML the .vlist in second .vlist-r span will have
// a "height" inline style which we ignore, because it doesn't seem
// to have any effect in rendering on the web.
// But also make sure there aren't any other inline styles present.
final vlistStyles = _parseInlineStyles(vlist);
if (vlistStyles != null && vlistStyles.keys.any((p) => p != 'height')) {
// This "depthStrut" cell will have a "height" inline style,
// which we ignore because it doesn't seem to have any effect in web;
// see detailed comment above.
// Make sure there aren't any other, unexpected, inline styles present.
final styles = _parseInlineStyles(depthStrut);
if (styles != null && styles.keys.any((p) => p != 'height')) {
throw _KatexHtmlParseError();
}
} else {
Expand All @@ -291,11 +312,10 @@ class _KatexParser {
if (vlistR.nodes.first
case dom.Element(localName: 'span', className: 'vlist') &&
final vlist) {
// Same as above for the second .vlist-r span, .vlist span in first
// .vlist-r span will have "height" inline style which we ignore,
// because it doesn't seem to have any effect in rendering on
// the web.
// But also make sure there aren't any other inline styles present.
// Same as above for the "depthStrut" node, the main "vlist" cell
// will have a "height" inline style which we ignore because
// it doesn't seem to have any effect in rendering on the web.
// Make sure there aren't any other, unexpected, inline styles present.
final vlistStyles = _parseInlineStyles(vlist);
if (vlistStyles != null && vlistStyles.keys.any((p) => p != 'height')) {
throw _KatexHtmlParseError();
Expand Down Expand Up @@ -356,7 +376,6 @@ class _KatexParser {
}
}

// TODO(#1716) Handle styling for .vlist-t2 spans
return KatexVlistNode(
rows: rows,
debugHtmlNode: kDebugMode ? element : null,
Expand Down