@@ -209,11 +209,102 @@ 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
+ nodes: [
250
+ dom.Element (localName: 'span' , className: 'pstrut' ) &&
251
+ final pstrutSpan,
252
+ ...final otherSpans,
253
+ ],
254
+ )) {
255
+ if (innerSpan.className != '' ) {
256
+ throw _KatexHtmlParseError ('unexpected CSS class for '
257
+ 'vlist inner span: ${innerSpan .className }' );
258
+ }
259
+
260
+ var styles = _parseSpanInlineStyles (innerSpan);
261
+ if (styles == null ) throw _KatexHtmlParseError ();
262
+ if (styles.verticalAlignEm != null ) throw _KatexHtmlParseError ();
263
+ final topEm = styles.topEm ?? 0 ;
264
+
265
+ styles = styles.filter (topEm: false );
266
+
267
+ final pstrutStyles = _parseSpanInlineStyles (pstrutSpan);
268
+ if (pstrutStyles == null ) throw _KatexHtmlParseError ();
269
+ if (pstrutStyles.filter (heightEm: false )
270
+ != const KatexSpanStyles ()) {
271
+ throw _KatexHtmlParseError ();
272
+ }
273
+ final pstrutHeight = pstrutStyles.heightEm ?? 0 ;
274
+
275
+ rows.add (KatexVlistRowNode (
276
+ verticalOffsetEm: topEm + pstrutHeight,
277
+ debugHtmlNode: kDebugMode ? innerSpan : null ,
278
+ node: KatexSpanNode (
279
+ styles: styles,
280
+ text: null ,
281
+ nodes: _parseChildSpans (otherSpans))));
282
+ } else {
283
+ throw _KatexHtmlParseError ();
284
+ }
285
+ }
286
+
287
+ return KatexVlistNode (
288
+ rows: rows,
289
+ debugHtmlNode: kDebugMode ? vlistT : null ,
290
+ );
291
+ } else {
292
+ throw _KatexHtmlParseError ();
293
+ }
294
+ } else {
295
+ throw _KatexHtmlParseError ();
296
+ }
297
+ }
298
+
212
299
final inlineStyles = _parseSpanInlineStyles (element);
213
300
if (inlineStyles != null ) {
214
301
// We expect `vertical-align` inline style to be only present on a
215
302
// `strut` span, for which we emit `KatexStrutNode` separately.
216
303
if (inlineStyles.verticalAlignEm != null ) throw _KatexHtmlParseError ();
304
+
305
+ // Currently, we expect `top` to only be inside a vlist, and
306
+ // we handle that case separately above.
307
+ if (inlineStyles.topEm != null ) throw _KatexHtmlParseError ();
217
308
}
218
309
219
310
// Aggregate the CSS styles that apply, in the same order as the CSS
@@ -224,7 +315,9 @@ class _KatexParser {
224
315
// https://github.com/KaTeX/KaTeX/blob/2fe1941b/src/styles/katex.scss
225
316
// A copy of class definition (where possible) is accompanied in a comment
226
317
// with each case statement to keep track of updates.
227
- final spanClasses = List <String >.unmodifiable (element.className.split (' ' ));
318
+ final spanClasses = element.className != ''
319
+ ? List <String >.unmodifiable (element.className.split (' ' ))
320
+ : const < String > [];
228
321
String ? fontFamily;
229
322
double ? fontSizeEm;
230
323
KatexSpanFontWeight ? fontWeight;
@@ -492,6 +585,7 @@ class _KatexParser {
492
585
if (stylesheet.topLevels case [css_visitor.RuleSet () && final rule]) {
493
586
double ? heightEm;
494
587
double ? verticalAlignEm;
588
+ double ? topEm;
495
589
double ? marginRightEm;
496
590
double ? marginLeftEm;
497
591
@@ -510,6 +604,10 @@ class _KatexParser {
510
604
verticalAlignEm = _getEm (expression);
511
605
if (verticalAlignEm != null ) continue ;
512
606
607
+ case 'top' :
608
+ topEm = _getEm (expression);
609
+ if (topEm != null ) continue ;
610
+
513
611
case 'margin-right' :
514
612
marginRightEm = _getEm (expression);
515
613
if (marginRightEm != null ) {
@@ -537,6 +635,7 @@ class _KatexParser {
537
635
538
636
return KatexSpanStyles (
539
637
heightEm: heightEm,
638
+ topEm: topEm,
540
639
verticalAlignEm: verticalAlignEm,
541
640
marginRightEm: marginRightEm,
542
641
marginLeftEm: marginLeftEm,
@@ -578,6 +677,8 @@ class KatexSpanStyles {
578
677
final double ? heightEm;
579
678
final double ? verticalAlignEm;
580
679
680
+ final double ? topEm;
681
+
581
682
final double ? marginRightEm;
582
683
final double ? marginLeftEm;
583
684
@@ -590,6 +691,7 @@ class KatexSpanStyles {
590
691
const KatexSpanStyles ({
591
692
this .heightEm,
592
693
this .verticalAlignEm,
694
+ this .topEm,
593
695
this .marginRightEm,
594
696
this .marginLeftEm,
595
697
this .fontFamily,
@@ -604,6 +706,7 @@ class KatexSpanStyles {
604
706
'KatexSpanStyles' ,
605
707
heightEm,
606
708
verticalAlignEm,
709
+ topEm,
607
710
marginRightEm,
608
711
marginLeftEm,
609
712
fontFamily,
@@ -618,6 +721,7 @@ class KatexSpanStyles {
618
721
return other is KatexSpanStyles &&
619
722
other.heightEm == heightEm &&
620
723
other.verticalAlignEm == verticalAlignEm &&
724
+ other.topEm == topEm &&
621
725
other.marginRightEm == marginRightEm &&
622
726
other.marginLeftEm == marginLeftEm &&
623
727
other.fontFamily == fontFamily &&
@@ -632,6 +736,7 @@ class KatexSpanStyles {
632
736
final args = < String > [];
633
737
if (heightEm != null ) args.add ('heightEm: $heightEm ' );
634
738
if (verticalAlignEm != null ) args.add ('verticalAlignEm: $verticalAlignEm ' );
739
+ if (topEm != null ) args.add ('topEm: $topEm ' );
635
740
if (marginRightEm != null ) args.add ('marginRightEm: $marginRightEm ' );
636
741
if (marginLeftEm != null ) args.add ('marginLeftEm: $marginLeftEm ' );
637
742
if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
@@ -653,6 +758,7 @@ class KatexSpanStyles {
653
758
return KatexSpanStyles (
654
759
heightEm: other.heightEm ?? heightEm,
655
760
verticalAlignEm: other.verticalAlignEm ?? verticalAlignEm,
761
+ topEm: other.topEm ?? topEm,
656
762
marginRightEm: other.marginRightEm ?? marginRightEm,
657
763
marginLeftEm: other.marginLeftEm ?? marginLeftEm,
658
764
fontFamily: other.fontFamily ?? fontFamily,
@@ -666,6 +772,7 @@ class KatexSpanStyles {
666
772
KatexSpanStyles filter ({
667
773
bool heightEm = true ,
668
774
bool verticalAlignEm = true ,
775
+ bool topEm = true ,
669
776
bool marginRightEm = true ,
670
777
bool marginLeftEm = true ,
671
778
bool fontFamily = true ,
@@ -677,6 +784,7 @@ class KatexSpanStyles {
677
784
return KatexSpanStyles (
678
785
heightEm: heightEm ? this .heightEm : null ,
679
786
verticalAlignEm: verticalAlignEm ? this .verticalAlignEm : null ,
787
+ topEm: topEm ? this .topEm : null ,
680
788
marginRightEm: marginRightEm ? this .marginRightEm : null ,
681
789
marginLeftEm: marginLeftEm ? this .marginLeftEm : null ,
682
790
fontFamily: fontFamily ? this .fontFamily : null ,
0 commit comments