@@ -140,6 +140,108 @@ class _KatexParser {
140140
141141 final spanClasses = List <String >.unmodifiable (element.className.split (' ' ));
142142
143+ if (element case dom.Element (localName: 'span' , : final className)
144+ when className.startsWith ('vlist' )) {
145+ switch (element) {
146+ case dom.Element (
147+ localName: 'span' ,
148+ className: 'vlist-t' ,
149+ attributes: final attributesVlistT,
150+ nodes: [
151+ dom.Element (
152+ localName: 'span' ,
153+ className: 'vlist-r' ,
154+ attributes: final attributesVlistR,
155+ nodes: [
156+ dom.Element (
157+ localName: 'span' ,
158+ className: 'vlist' ,
159+ nodes: [
160+ dom.Element (
161+ localName: 'span' ,
162+ className: '' ,
163+ nodes: [
164+ dom.Element (localName: 'span' , className: 'pstrut' )
165+ && final pstrutSpan,
166+ ...,
167+ ]) && final innerSpan,
168+ ]),
169+ ]),
170+ ])
171+ when ! attributesVlistT.containsKey ('style' ) &&
172+ ! attributesVlistR.containsKey ('style' ):
173+ // TODO vlist element should only have `height` style, which we ignore.
174+
175+ var styles = _parseSpanInlineStyles (innerSpan)! ;
176+ final topEm = styles.topEm ?? 0 ;
177+
178+ final pstrutStyles = _parseSpanInlineStyles (pstrutSpan)! ;
179+ final pstrutHeight = pstrutStyles.heightEm ?? 0 ;
180+
181+ // TODO handle negative right-margin inline style on row nodes.
182+ return KatexVlistNode (rows: [
183+ KatexVlistRowNode (
184+ verticalOffsetEm: topEm + pstrutHeight,
185+ nodes: _parseChildSpans (innerSpan)),
186+ ]);
187+
188+ case dom.Element (
189+ localName: 'span' ,
190+ className: 'vlist-t vlist-t2' ,
191+ attributes: final attributesVlistT,
192+ nodes: [
193+ dom.Element (
194+ localName: 'span' ,
195+ className: 'vlist-r' ,
196+ attributes: final attributesVlistR,
197+ nodes: [
198+ dom.Element (
199+ localName: 'span' ,
200+ className: 'vlist' ,
201+ nodes: [...]) && final vlist1,
202+ dom.Element (localName: 'span' , className: 'vlist-s' ),
203+ ]),
204+ dom.Element (localName: 'span' , className: 'vlist-r' , nodes: [
205+ dom.Element (localName: 'span' , className: 'vlist' , nodes: [
206+ dom.Element (localName: 'span' , className: '' , nodes: []),
207+ ])
208+ ]),
209+ ])
210+ when ! attributesVlistT.containsKey ('style' ) &&
211+ ! attributesVlistR.containsKey ('style' ):
212+ // TODO Ensure both should only have a `height` style.
213+
214+ final rows = < KatexVlistRowNode > [];
215+
216+ for (final innerSpan in vlist1.nodes) {
217+ if (innerSpan case dom.Element (
218+ localName: 'span' ,
219+ className: '' ,
220+ nodes: [
221+ dom.Element (localName: 'span' , className: 'pstrut' ) &&
222+ final pstrutSpan,
223+ ...,
224+ ])) {
225+ final styles = _parseSpanInlineStyles (innerSpan)! ;
226+ final topEm = styles.topEm ?? 0 ;
227+
228+ final pstrutStyles = _parseSpanInlineStyles (pstrutSpan)! ;
229+ final pstrutHeight = pstrutStyles.heightEm ?? 0 ;
230+
231+ // TODO handle negative right-margin inline style on row nodes.
232+ rows.add (KatexVlistRowNode (
233+ verticalOffsetEm: topEm + pstrutHeight,
234+ nodes: _parseChildSpans (innerSpan)));
235+ }
236+ }
237+
238+ return KatexVlistNode (rows: rows);
239+
240+ default :
241+ throw KatexHtmlParseError ();
242+ }
243+ }
244+
143245 // Aggregate the CSS styles that apply, in the same order as the CSS
144246 // classes specified for this span, mimicking the behaviour on web.
145247 //
@@ -406,7 +508,7 @@ class _KatexParser {
406508
407509 final inlineStyles = _parseSpanInlineStyles (element);
408510
409- return KatexNode (
511+ return KatexSpanNode (
410512 styles: inlineStyles != null
411513 ? styles.merge (inlineStyles)
412514 : styles,
@@ -422,6 +524,7 @@ class _KatexParser {
422524 final stylesheet = css_parser.parse ('*{$styleStr }' );
423525 if (stylesheet.topLevels case [css_visitor.RuleSet () && final rule]) {
424526 double ? heightEm;
527+ double ? topEm;
425528 double ? verticalAlignEm;
426529
427530 for (final declaration in rule.declarationGroup.declarations) {
@@ -435,6 +538,10 @@ class _KatexParser {
435538 heightEm = _getEm (expression);
436539 if (heightEm != null ) continue ;
437540
541+ case 'top' :
542+ topEm = _getEm (expression);
543+ if (topEm != null ) continue ;
544+
438545 case 'vertical-align' :
439546 verticalAlignEm = _getEm (expression);
440547 if (verticalAlignEm != null ) continue ;
@@ -450,6 +557,7 @@ class _KatexParser {
450557
451558 return KatexSpanStyles (
452559 heightEm: heightEm,
560+ topEm: topEm,
453561 verticalAlignEm: verticalAlignEm,
454562 );
455563 } else {
@@ -484,6 +592,7 @@ enum KatexSpanTextAlign {
484592
485593class KatexSpanStyles {
486594 double ? heightEm;
595+ double ? topEm;
487596 double ? verticalAlignEm;
488597
489598 String ? fontFamily;
@@ -494,6 +603,7 @@ class KatexSpanStyles {
494603
495604 KatexSpanStyles ({
496605 this .heightEm,
606+ this .topEm,
497607 this .verticalAlignEm,
498608 this .fontFamily,
499609 this .fontSizeEm,
@@ -506,6 +616,7 @@ class KatexSpanStyles {
506616 int get hashCode => Object .hash (
507617 'KatexSpanStyles' ,
508618 heightEm,
619+ topEm,
509620 verticalAlignEm,
510621 fontFamily,
511622 fontSizeEm,
@@ -518,6 +629,7 @@ class KatexSpanStyles {
518629 bool operator == (Object other) {
519630 return other is KatexSpanStyles &&
520631 other.heightEm == heightEm &&
632+ other.topEm == topEm &&
521633 other.verticalAlignEm == verticalAlignEm &&
522634 other.fontFamily == fontFamily &&
523635 other.fontSizeEm == fontSizeEm &&
@@ -530,6 +642,7 @@ class KatexSpanStyles {
530642 String toString () {
531643 final args = < String > [];
532644 if (heightEm != null ) args.add ('heightEm: $heightEm ' );
645+ if (topEm != null ) args.add ('topEm: $topEm ' );
533646 if (verticalAlignEm != null ) args.add ('verticalAlignEm: $verticalAlignEm ' );
534647 if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
535648 if (fontSizeEm != null ) args.add ('fontSizeEm: $fontSizeEm ' );
@@ -542,6 +655,7 @@ class KatexSpanStyles {
542655 KatexSpanStyles merge (KatexSpanStyles other) {
543656 return KatexSpanStyles (
544657 heightEm: other.heightEm ?? heightEm,
658+ topEm: other.topEm ?? topEm,
545659 verticalAlignEm: other.verticalAlignEm ?? verticalAlignEm,
546660 fontFamily: other.fontFamily ?? fontFamily,
547661 fontSizeEm: other.fontSizeEm ?? fontSizeEm,
0 commit comments