@@ -209,11 +209,98 @@ class _KatexParser {
209
209
debugHtmlNode: debugHtmlNode);
210
210
}
211
211
212
+ if (element.className == 'vlist-t'
213
+ || element.className == 'vlist-t vlist-t2' ) {
214
+ final vlistT = element;
215
+ if (vlistT.nodes.isEmpty) throw _KatexHtmlParseError ();
216
+ if (vlistT.attributes.containsKey ('style' )) throw _KatexHtmlParseError ();
217
+
218
+ final hasTwoVlistR = vlistT.className == 'vlist-t vlist-t2' ;
219
+ if (! hasTwoVlistR && vlistT.nodes.length != 1 ) throw _KatexHtmlParseError ();
220
+
221
+ if (hasTwoVlistR) {
222
+ if (vlistT.nodes case [
223
+ _,
224
+ dom.Element (localName: 'span' , className: 'vlist-r' , nodes: [
225
+ dom.Element (localName: 'span' , className: 'vlist' , nodes: [
226
+ dom.Element (localName: 'span' , className: '' , nodes: []),
227
+ ]),
228
+ ]),
229
+ ]) {
230
+ // Do nothing.
231
+ } else {
232
+ throw _KatexHtmlParseError ();
233
+ }
234
+ }
235
+
236
+ if (vlistT.nodes.first
237
+ case dom.Element (localName: 'span' , className: 'vlist-r' ) &&
238
+ final vlistR) {
239
+ if (vlistR.attributes.containsKey ('style' )) throw _KatexHtmlParseError ();
240
+
241
+ if (vlistR.nodes.first
242
+ case dom.Element (localName: 'span' , className: 'vlist' ) &&
243
+ final vlist) {
244
+ final rows = < KatexVlistRowNode > [];
245
+
246
+ for (final innerSpan in vlist.nodes) {
247
+ if (innerSpan case dom.Element (
248
+ localName: 'span' ,
249
+ className: '' ,
250
+ nodes: [
251
+ dom.Element (localName: 'span' , className: 'pstrut' ) &&
252
+ final pstrutSpan,
253
+ ...final otherSpans,
254
+ ],
255
+ )) {
256
+ var styles = _parseSpanInlineStyles (innerSpan);
257
+ if (styles == null ) throw _KatexHtmlParseError ();
258
+ if (styles.verticalAlignEm != null ) throw _KatexHtmlParseError ();
259
+ final topEm = styles.topEm ?? 0 ;
260
+
261
+ styles = styles.filter (topEm: false );
262
+
263
+ final pstrutStyles = _parseSpanInlineStyles (pstrutSpan);
264
+ if (pstrutStyles == null ) throw _KatexHtmlParseError ();
265
+ if (pstrutStyles.filter (heightEm: false )
266
+ != const KatexSpanStyles ()) {
267
+ throw _KatexHtmlParseError ();
268
+ }
269
+ final pstrutHeight = pstrutStyles.heightEm ?? 0 ;
270
+
271
+ rows.add (KatexVlistRowNode (
272
+ verticalOffsetEm: topEm + pstrutHeight,
273
+ debugHtmlNode: kDebugMode ? innerSpan : null ,
274
+ node: KatexSpanNode (
275
+ styles: styles,
276
+ text: null ,
277
+ nodes: _parseChildSpans (otherSpans))));
278
+ } else {
279
+ throw _KatexHtmlParseError ();
280
+ }
281
+ }
282
+
283
+ return KatexVlistNode (
284
+ rows: rows,
285
+ debugHtmlNode: kDebugMode ? vlistT : null ,
286
+ );
287
+ } else {
288
+ throw _KatexHtmlParseError ();
289
+ }
290
+ } else {
291
+ throw _KatexHtmlParseError ();
292
+ }
293
+ }
294
+
212
295
final inlineStyles = _parseSpanInlineStyles (element);
213
296
if (inlineStyles != null ) {
214
297
// We expect `vertical-align` inline style to be only present on a
215
298
// `strut` span, for which we emit `KatexStrutNode` separately.
216
299
if (inlineStyles.verticalAlignEm != null ) throw _KatexHtmlParseError ();
300
+
301
+ // Currently, we expect `top` to only be inside a vlist, and
302
+ // we handle that case separately above.
303
+ if (inlineStyles.topEm != null ) throw _KatexHtmlParseError ();
217
304
}
218
305
219
306
// Aggregate the CSS styles that apply, in the same order as the CSS
@@ -224,7 +311,9 @@ class _KatexParser {
224
311
// https://github.com/KaTeX/KaTeX/blob/2fe1941b/src/styles/katex.scss
225
312
// A copy of class definition (where possible) is accompanied in a comment
226
313
// with each case statement to keep track of updates.
227
- final spanClasses = List <String >.unmodifiable (element.className.split (' ' ));
314
+ final spanClasses = element.className != ''
315
+ ? List <String >.unmodifiable (element.className.split (' ' ))
316
+ : const < String > [];
228
317
String ? fontFamily;
229
318
double ? fontSizeEm;
230
319
KatexSpanFontWeight ? fontWeight;
@@ -492,6 +581,7 @@ class _KatexParser {
492
581
if (stylesheet.topLevels case [css_visitor.RuleSet () && final rule]) {
493
582
double ? heightEm;
494
583
double ? verticalAlignEm;
584
+ double ? topEm;
495
585
double ? marginRightEm;
496
586
double ? marginLeftEm;
497
587
@@ -510,6 +600,10 @@ class _KatexParser {
510
600
verticalAlignEm = _getEm (expression);
511
601
if (verticalAlignEm != null ) continue ;
512
602
603
+ case 'top' :
604
+ topEm = _getEm (expression);
605
+ if (topEm != null ) continue ;
606
+
513
607
case 'margin-right' :
514
608
marginRightEm = _getEm (expression);
515
609
if (marginRightEm != null ) {
@@ -537,6 +631,7 @@ class _KatexParser {
537
631
538
632
return KatexSpanStyles (
539
633
heightEm: heightEm,
634
+ topEm: topEm,
540
635
verticalAlignEm: verticalAlignEm,
541
636
marginRightEm: marginRightEm,
542
637
marginLeftEm: marginLeftEm,
@@ -578,6 +673,8 @@ class KatexSpanStyles {
578
673
final double ? heightEm;
579
674
final double ? verticalAlignEm;
580
675
676
+ final double ? topEm;
677
+
581
678
final double ? marginRightEm;
582
679
final double ? marginLeftEm;
583
680
@@ -590,6 +687,7 @@ class KatexSpanStyles {
590
687
const KatexSpanStyles ({
591
688
this .heightEm,
592
689
this .verticalAlignEm,
690
+ this .topEm,
593
691
this .marginRightEm,
594
692
this .marginLeftEm,
595
693
this .fontFamily,
@@ -604,6 +702,7 @@ class KatexSpanStyles {
604
702
'KatexSpanStyles' ,
605
703
heightEm,
606
704
verticalAlignEm,
705
+ topEm,
607
706
marginRightEm,
608
707
marginLeftEm,
609
708
fontFamily,
@@ -618,6 +717,7 @@ class KatexSpanStyles {
618
717
return other is KatexSpanStyles &&
619
718
other.heightEm == heightEm &&
620
719
other.verticalAlignEm == verticalAlignEm &&
720
+ other.topEm == topEm &&
621
721
other.marginRightEm == marginRightEm &&
622
722
other.marginLeftEm == marginLeftEm &&
623
723
other.fontFamily == fontFamily &&
@@ -632,6 +732,7 @@ class KatexSpanStyles {
632
732
final args = < String > [];
633
733
if (heightEm != null ) args.add ('heightEm: $heightEm ' );
634
734
if (verticalAlignEm != null ) args.add ('verticalAlignEm: $verticalAlignEm ' );
735
+ if (topEm != null ) args.add ('topEm: $topEm ' );
635
736
if (marginRightEm != null ) args.add ('marginRightEm: $marginRightEm ' );
636
737
if (marginLeftEm != null ) args.add ('marginLeftEm: $marginLeftEm ' );
637
738
if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
@@ -653,6 +754,7 @@ class KatexSpanStyles {
653
754
return KatexSpanStyles (
654
755
heightEm: other.heightEm ?? heightEm,
655
756
verticalAlignEm: other.verticalAlignEm ?? verticalAlignEm,
757
+ topEm: other.topEm ?? topEm,
656
758
marginRightEm: other.marginRightEm ?? marginRightEm,
657
759
marginLeftEm: other.marginLeftEm ?? marginLeftEm,
658
760
fontFamily: other.fontFamily ?? fontFamily,
@@ -666,6 +768,7 @@ class KatexSpanStyles {
666
768
KatexSpanStyles filter ({
667
769
bool heightEm = true ,
668
770
bool verticalAlignEm = true ,
771
+ bool topEm = true ,
669
772
bool marginRightEm = true ,
670
773
bool marginLeftEm = true ,
671
774
bool fontFamily = true ,
@@ -677,6 +780,7 @@ class KatexSpanStyles {
677
780
return KatexSpanStyles (
678
781
heightEm: heightEm ? this .heightEm : null ,
679
782
verticalAlignEm: verticalAlignEm ? this .verticalAlignEm : null ,
783
+ topEm: topEm ? this .topEm : null ,
680
784
marginRightEm: marginRightEm ? this .marginRightEm : null ,
681
785
marginLeftEm: marginLeftEm ? this .marginLeftEm : null ,
682
786
fontFamily: fontFamily ? this .fontFamily : null ,
0 commit comments