@@ -138,6 +138,110 @@ class _KatexParser {
138138 KatexNode _parseSpan (dom.Element element) {
139139 // TODO maybe check if the sequence of ancestors matter for spans.
140140
141+ final spanClasses = List <String >.unmodifiable (element.className.split (' ' ));
142+
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+
141245 // Aggregate the CSS styles that apply, in the same order as the CSS
142246 // classes specified for this span, mimicking the behaviour on web.
143247 //
@@ -146,7 +250,6 @@ class _KatexParser {
146250 // https://github.com/KaTeX/KaTeX/blob/2fe1941b/src/styles/katex.scss
147251 // A copy of class definition (where possible) is accompanied in a comment
148252 // with each case statement to keep track of updates.
149- final spanClasses = List <String >.unmodifiable (element.className.split (' ' ));
150253 String ? fontFamily;
151254 double ? fontSizeEm;
152255 KatexSpanFontWeight ? fontWeight;
@@ -374,6 +477,7 @@ class _KatexParser {
374477 final stylesheet = css_parser.parse ('*{$styleStr }' );
375478 if (stylesheet.topLevels case [css_visitor.RuleSet () && final rule]) {
376479 double ? heightEm;
480+ double ? topEm;
377481 double ? verticalAlignEm;
378482
379483 for (final declaration in rule.declarationGroup.declarations) {
@@ -387,6 +491,10 @@ class _KatexParser {
387491 heightEm = _getEm (expression);
388492 if (heightEm != null ) continue ;
389493
494+ case 'top' :
495+ topEm = _getEm (expression);
496+ if (topEm != null ) continue ;
497+
390498 case 'vertical-align' :
391499 verticalAlignEm = _getEm (expression);
392500 if (verticalAlignEm != null ) continue ;
@@ -402,6 +510,7 @@ class _KatexParser {
402510
403511 return KatexSpanStyles (
404512 heightEm: heightEm,
513+ topEm: topEm,
405514 verticalAlignEm: verticalAlignEm,
406515 );
407516 } else {
@@ -437,6 +546,7 @@ enum KatexSpanTextAlign {
437546@immutable
438547class KatexSpanStyles {
439548 final double ? heightEm;
549+ final double ? topEm;
440550 final double ? verticalAlignEm;
441551
442552 final String ? fontFamily;
@@ -447,6 +557,7 @@ class KatexSpanStyles {
447557
448558 const KatexSpanStyles ({
449559 this .heightEm,
560+ this .topEm,
450561 this .verticalAlignEm,
451562 this .fontFamily,
452563 this .fontSizeEm,
@@ -459,6 +570,7 @@ class KatexSpanStyles {
459570 int get hashCode => Object .hash (
460571 'KatexSpanStyles' ,
461572 heightEm,
573+ topEm,
462574 verticalAlignEm,
463575 fontFamily,
464576 fontSizeEm,
@@ -471,6 +583,7 @@ class KatexSpanStyles {
471583 bool operator == (Object other) {
472584 return other is KatexSpanStyles &&
473585 other.heightEm == heightEm &&
586+ other.topEm == topEm &&
474587 other.verticalAlignEm == verticalAlignEm &&
475588 other.fontFamily == fontFamily &&
476589 other.fontSizeEm == fontSizeEm &&
@@ -483,6 +596,7 @@ class KatexSpanStyles {
483596 String toString () {
484597 final args = < String > [];
485598 if (heightEm != null ) args.add ('heightEm: $heightEm ' );
599+ if (topEm != null ) args.add ('topEm: $topEm ' );
486600 if (verticalAlignEm != null ) args.add ('verticalAlignEm: $verticalAlignEm ' );
487601 if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
488602 if (fontSizeEm != null ) args.add ('fontSizeEm: $fontSizeEm ' );
@@ -495,6 +609,7 @@ class KatexSpanStyles {
495609 KatexSpanStyles merge (KatexSpanStyles other) {
496610 return KatexSpanStyles (
497611 heightEm: other.heightEm ?? heightEm,
612+ topEm: other.topEm ?? topEm,
498613 verticalAlignEm: other.verticalAlignEm ?? verticalAlignEm,
499614 fontFamily: other.fontFamily ?? fontFamily,
500615 fontSizeEm: other.fontSizeEm ?? fontSizeEm,
0 commit comments