@@ -20,14 +20,16 @@ class KatexParser {
20
20
final span = _parseSpan (node);
21
21
resultSpans.add (span);
22
22
23
- final marginRightEm = span.styles.marginRightEm;
24
- if (marginRightEm != null && marginRightEm.isNegative) {
25
- final previousSpansReversed =
26
- resultSpans.reversed.toList (growable: false );
27
- resultSpans = [];
28
- resultSpans.add (KatexNegativeMarginNode (
29
- marginRightEm: marginRightEm,
30
- nodes: previousSpansReversed));
23
+ if (span is KatexSpanNode ) {
24
+ final marginRightEm = span.styles.marginRightEm;
25
+ if (marginRightEm != null && marginRightEm.isNegative) {
26
+ final previousSpansReversed =
27
+ resultSpans.reversed.toList (growable: false );
28
+ resultSpans = [];
29
+ resultSpans.add (KatexNegativeMarginNode (
30
+ marginRightEm: marginRightEm,
31
+ nodes: previousSpansReversed));
32
+ }
31
33
}
32
34
}
33
35
@@ -37,9 +39,111 @@ class KatexParser {
37
39
static final _resetSizeClassRegExp = RegExp (r'^reset-size(\d\d?)$' );
38
40
static final _sizeClassRegExp = RegExp (r'^size(\d\d?)$' );
39
41
40
- KatexSpanNode _parseSpan (dom.Element element) {
42
+ KatexNode _parseSpan (dom.Element element) {
41
43
final spanClasses = List <String >.unmodifiable (element.className.split (' ' ));
42
44
45
+ if (element case dom.Element (localName: 'span' , : final className)
46
+ when className.startsWith ('vlist' )) {
47
+ switch (element) {
48
+ case dom.Element (
49
+ localName: 'span' ,
50
+ className: 'vlist-t' ,
51
+ attributes: final attributesVlistT,
52
+ nodes: [
53
+ dom.Element (
54
+ localName: 'span' ,
55
+ className: 'vlist-r' ,
56
+ attributes: final attributesVlistR,
57
+ nodes: [
58
+ dom.Element (
59
+ localName: 'span' ,
60
+ className: 'vlist' ,
61
+ nodes: [
62
+ dom.Element (
63
+ localName: 'span' ,
64
+ className: '' ,
65
+ nodes: [
66
+ dom.Element (localName: 'span' , className: 'pstrut' )
67
+ && final pstrutSpan,
68
+ ...,
69
+ ]) && final innerSpan,
70
+ ]),
71
+ ]),
72
+ ])
73
+ when ! attributesVlistT.containsKey ('style' ) &&
74
+ ! attributesVlistR.containsKey ('style' ):
75
+ // TODO vlist element should only have `height` style, which we ignore.
76
+
77
+ var styles = _parseSpanInlineStyles (innerSpan)! ;
78
+ final topEm = styles.topEm ?? 0 ;
79
+
80
+ final pstrutStyles = _parseSpanInlineStyles (pstrutSpan)! ;
81
+ final pstrutHeight = pstrutStyles.heightEm ?? 0 ;
82
+
83
+ // TODO handle negative right-margin inline style on row nodes.
84
+ return KatexVlistNode (rows: [
85
+ KatexVlistRowNode (
86
+ verticalOffsetEm: topEm + pstrutHeight,
87
+ nodes: _parseChildSpans (innerSpan)),
88
+ ]);
89
+
90
+ case dom.Element (
91
+ localName: 'span' ,
92
+ className: 'vlist-t vlist-t2' ,
93
+ attributes: final attributesVlistT,
94
+ nodes: [
95
+ dom.Element (
96
+ localName: 'span' ,
97
+ className: 'vlist-r' ,
98
+ attributes: final attributesVlistR,
99
+ nodes: [
100
+ dom.Element (
101
+ localName: 'span' ,
102
+ className: 'vlist' ,
103
+ nodes: [...]) && final vlist1,
104
+ dom.Element (localName: 'span' , className: 'vlist-s' ),
105
+ ]),
106
+ dom.Element (localName: 'span' , className: 'vlist-r' , nodes: [
107
+ dom.Element (localName: 'span' , className: 'vlist' , nodes: [
108
+ dom.Element (localName: 'span' , className: '' , nodes: []),
109
+ ])
110
+ ]),
111
+ ])
112
+ when ! attributesVlistT.containsKey ('style' ) &&
113
+ ! attributesVlistR.containsKey ('style' ):
114
+ // TODO Ensure both should only have a `height` style.
115
+
116
+ final rows = < KatexVlistRowNode > [];
117
+
118
+ for (final innerSpan in vlist1.nodes) {
119
+ if (innerSpan case dom.Element (
120
+ localName: 'span' ,
121
+ className: '' ,
122
+ nodes: [
123
+ dom.Element (localName: 'span' , className: 'pstrut' ) &&
124
+ final pstrutSpan,
125
+ ...,
126
+ ])) {
127
+ final styles = _parseSpanInlineStyles (innerSpan)! ;
128
+ final topEm = styles.topEm ?? 0 ;
129
+
130
+ final pstrutStyles = _parseSpanInlineStyles (pstrutSpan)! ;
131
+ final pstrutHeight = pstrutStyles.heightEm ?? 0 ;
132
+
133
+ // TODO handle negative right-margin inline style on row nodes.
134
+ rows.add (KatexVlistRowNode (
135
+ verticalOffsetEm: topEm + pstrutHeight,
136
+ nodes: _parseChildSpans (innerSpan)));
137
+ }
138
+ }
139
+
140
+ return KatexVlistNode (rows: rows);
141
+
142
+ default :
143
+ throw KatexHtmlParseError ();
144
+ }
145
+ }
146
+
43
147
var styles = KatexSpanStyles ();
44
148
var index = 0 ;
45
149
while (index < spanClasses.length) {
@@ -261,9 +365,12 @@ class KatexParser {
261
365
if (topLevel is ! css_visitor.RuleSet ) throw KatexHtmlParseError ();
262
366
final rule = topLevel;
263
367
368
+ double ? heightEm;
264
369
double ? marginLeftEm;
265
370
double ? marginRightEm;
266
371
double ? paddingLeftEm;
372
+ double ? topEm;
373
+ double ? widthEm;
267
374
268
375
for (final declaration in rule.declarationGroup.declarations) {
269
376
if (declaration is ! css_visitor.Declaration ) throw KatexHtmlParseError ();
@@ -275,6 +382,10 @@ class KatexParser {
275
382
final expression = expressions.expressions.single;
276
383
277
384
switch (property) {
385
+ case 'height' :
386
+ heightEm = _getEm (expression);
387
+ if (heightEm != null ) continue ;
388
+
278
389
case 'margin-left' :
279
390
marginLeftEm = _getEm (expression);
280
391
if (marginLeftEm != null ) continue ;
@@ -287,16 +398,27 @@ class KatexParser {
287
398
paddingLeftEm = _getEm (expression);
288
399
if (paddingLeftEm != null ) continue ;
289
400
401
+ case 'top' :
402
+ topEm = _getEm (expression);
403
+ if (topEm != null ) continue ;
404
+
405
+ case 'width' :
406
+ widthEm = _getEm (expression);
407
+ if (widthEm != null ) continue ;
408
+
290
409
default :
291
410
// TODO handle more CSS properties
292
411
assert (debugLog ('Unsupported CSS property: $property of type ${expression .runtimeType }' ));
293
412
}
294
413
}
295
414
296
415
return KatexSpanStyles (
416
+ heightEm: heightEm,
297
417
marginLeftEm: marginLeftEm,
298
418
marginRightEm: marginRightEm,
299
419
paddingLeftEm: paddingLeftEm,
420
+ topEm: topEm,
421
+ widthEm: widthEm,
300
422
);
301
423
}
302
424
return null ;
@@ -326,9 +448,12 @@ enum KatexSpanTextAlign {
326
448
}
327
449
328
450
class KatexSpanStyles {
451
+ double ? heightEm;
329
452
double ? marginLeftEm;
330
453
double ? marginRightEm;
331
454
double ? paddingLeftEm;
455
+ double ? topEm;
456
+ double ? widthEm;
332
457
333
458
String ? fontFamily;
334
459
double ? fontSizeEm;
@@ -337,9 +462,12 @@ class KatexSpanStyles {
337
462
KatexSpanTextAlign ? textAlign;
338
463
339
464
KatexSpanStyles ({
465
+ this .heightEm,
340
466
this .marginLeftEm,
341
467
this .marginRightEm,
342
468
this .paddingLeftEm,
469
+ this .topEm,
470
+ this .widthEm,
343
471
this .fontFamily,
344
472
this .fontSizeEm,
345
473
this .fontStyle,
@@ -350,9 +478,12 @@ class KatexSpanStyles {
350
478
@override
351
479
int get hashCode => Object .hash (
352
480
'KatexSpanStyles' ,
481
+ heightEm,
353
482
marginLeftEm,
354
483
marginRightEm,
355
484
paddingLeftEm,
485
+ topEm,
486
+ widthEm,
356
487
fontFamily,
357
488
fontSizeEm,
358
489
fontStyle,
@@ -363,9 +494,12 @@ class KatexSpanStyles {
363
494
@override
364
495
bool operator == (Object other) {
365
496
return other is KatexSpanStyles &&
497
+ other.heightEm == heightEm &&
366
498
other.marginLeftEm == marginLeftEm &&
367
499
other.marginRightEm == marginRightEm &&
368
500
other.paddingLeftEm == paddingLeftEm &&
501
+ other.topEm == topEm &&
502
+ other.widthEm == widthEm &&
369
503
other.fontFamily == fontFamily &&
370
504
other.fontSizeEm == fontSizeEm &&
371
505
other.fontStyle == fontStyle &&
@@ -380,9 +514,12 @@ class KatexSpanStyles {
380
514
if (this == _zero) return '${objectRuntimeType (this , 'KatexSpanStyles' )}()' ;
381
515
382
516
final args = < String > [];
517
+ if (heightEm != null ) args.add ('heightEm: $heightEm ' );
383
518
if (marginLeftEm != null ) args.add ('marginLeftEm: $marginLeftEm ' );
384
519
if (marginRightEm != null ) args.add ('marginRightEm: $marginRightEm ' );
385
520
if (paddingLeftEm != null ) args.add ('paddingLeftEm: $paddingLeftEm ' );
521
+ if (topEm != null ) args.add ('topEm: $topEm ' );
522
+ if (widthEm != null ) args.add ('width: $widthEm ' );
386
523
if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
387
524
if (fontSizeEm != null ) args.add ('fontSizeEm: $fontSizeEm ' );
388
525
if (fontStyle != null ) args.add ('fontStyle: $fontStyle ' );
@@ -393,9 +530,12 @@ class KatexSpanStyles {
393
530
394
531
KatexSpanStyles merge (KatexSpanStyles other) {
395
532
return KatexSpanStyles (
533
+ heightEm: other.heightEm ?? heightEm,
396
534
marginLeftEm: other.marginLeftEm ?? marginLeftEm,
397
535
marginRightEm: other.marginRightEm ?? marginRightEm,
398
536
paddingLeftEm: other.paddingLeftEm ?? paddingLeftEm,
537
+ topEm: other.topEm ?? topEm,
538
+ widthEm: other.widthEm ?? widthEm,
399
539
fontFamily: other.fontFamily ?? fontFamily,
400
540
fontSizeEm: other.fontSizeEm ?? fontSizeEm,
401
541
fontStyle: other.fontStyle ?? fontStyle,
0 commit comments