@@ -219,149 +219,167 @@ class _KatexParser {
219
219
return resultSpans;
220
220
}
221
221
222
- static final _resetSizeClassRegExp = RegExp (r'^reset-size(\d\d?)$' );
223
- static final _sizeClassRegExp = RegExp (r'^size(\d\d?)$' );
224
-
225
222
KatexNode _parseSpan (dom.Element element) {
223
+ assert (element.localName == 'span' );
226
224
// TODO maybe check if the sequence of ancestors matter for spans.
227
225
228
- final debugHtmlNode = kDebugMode ? element : null ;
229
-
230
226
if (element.className == 'strut' ) {
231
- if (element.nodes.isNotEmpty) throw _KatexHtmlParseError ();
232
-
233
- final styles = _parseInlineStyles (element);
234
- if (styles == null ) throw _KatexHtmlParseError ();
235
- final heightEm = _takeStyleEm (styles, 'height' );
236
- if (heightEm == null ) throw _KatexHtmlParseError ();
237
- final verticalAlignEm = _takeStyleEm (styles, 'vertical-align' );
238
- if (styles.isNotEmpty) throw _KatexHtmlParseError ();
239
-
240
- return KatexStrutNode (
241
- heightEm: heightEm,
242
- verticalAlignEm: verticalAlignEm,
243
- debugHtmlNode: debugHtmlNode);
227
+ return _parseStrut (element);
244
228
}
245
229
246
230
if (element.className == 'vlist-t'
247
231
|| element.className == 'vlist-t vlist-t2' ) {
248
- final vlistT = element;
249
- if (vlistT.nodes.isEmpty) throw _KatexHtmlParseError ();
250
- if (vlistT.attributes.containsKey ('style' )) throw _KatexHtmlParseError ();
251
-
252
- final hasTwoVlistR = vlistT.className == 'vlist-t vlist-t2' ;
253
- if (! hasTwoVlistR && vlistT.nodes.length != 1 ) throw _KatexHtmlParseError ();
254
-
255
- if (hasTwoVlistR) {
256
- if (vlistT.nodes case [
257
- _,
258
- dom.Element (localName: 'span' , className: 'vlist-r' , nodes: [
259
- dom.Element (localName: 'span' , className: 'vlist' , nodes: [
260
- dom.Element (localName: 'span' , className: '' , nodes: []),
261
- ]) && final vlist,
262
- ]),
263
- ]) {
264
- // In the generated HTML the .vlist in second .vlist-r span will have
265
- // a "height" inline style which we ignore, because it doesn't seem
266
- // to have any effect in rendering on the web.
267
- // But also make sure there aren't any other inline styles present.
268
- final vlistStyles = _parseInlineStyles (vlist);
269
- if (vlistStyles != null && vlistStyles.keys.any ((p) => p != 'height' )) {
270
- throw _KatexHtmlParseError ();
271
- }
272
- } else {
232
+ return _parseVlist (element);
233
+ }
234
+
235
+ return _parseGenericSpan (element);
236
+ }
237
+
238
+ KatexNode _parseStrut (dom.Element element) {
239
+ assert (element.localName == 'span' );
240
+ assert (element.className == 'strut' );
241
+ if (element.nodes.isNotEmpty) throw _KatexHtmlParseError ();
242
+
243
+ final styles = _parseInlineStyles (element);
244
+ if (styles == null ) throw _KatexHtmlParseError ();
245
+ final heightEm = _takeStyleEm (styles, 'height' );
246
+ if (heightEm == null ) throw _KatexHtmlParseError ();
247
+ final verticalAlignEm = _takeStyleEm (styles, 'vertical-align' );
248
+ if (styles.isNotEmpty) throw _KatexHtmlParseError ();
249
+
250
+ return KatexStrutNode (
251
+ heightEm: heightEm,
252
+ verticalAlignEm: verticalAlignEm,
253
+ debugHtmlNode: kDebugMode ? element : null );
254
+ }
255
+
256
+ KatexNode _parseVlist (dom.Element element) {
257
+ assert (element.localName == 'span' );
258
+ assert (element.className == 'vlist-t'
259
+ || element.className == 'vlist-t vlist-t2' );
260
+ final vlistT = element;
261
+ if (vlistT.nodes.isEmpty) throw _KatexHtmlParseError ();
262
+ if (vlistT.attributes.containsKey ('style' )) throw _KatexHtmlParseError ();
263
+
264
+ final hasTwoVlistR = vlistT.className == 'vlist-t vlist-t2' ;
265
+ if (! hasTwoVlistR && vlistT.nodes.length != 1 ) throw _KatexHtmlParseError ();
266
+
267
+ if (hasTwoVlistR) {
268
+ if (vlistT.nodes case [
269
+ _,
270
+ dom.Element (localName: 'span' , className: 'vlist-r' , nodes: [
271
+ dom.Element (localName: 'span' , className: 'vlist' , nodes: [
272
+ dom.Element (localName: 'span' , className: '' , nodes: []),
273
+ ]) && final vlist,
274
+ ]),
275
+ ]) {
276
+ // In the generated HTML the .vlist in second .vlist-r span will have
277
+ // a "height" inline style which we ignore, because it doesn't seem
278
+ // to have any effect in rendering on the web.
279
+ // But also make sure there aren't any other inline styles present.
280
+ final vlistStyles = _parseInlineStyles (vlist);
281
+ if (vlistStyles != null && vlistStyles.keys.any ((p) => p != 'height' )) {
273
282
throw _KatexHtmlParseError ();
274
283
}
284
+ } else {
285
+ throw _KatexHtmlParseError ();
275
286
}
287
+ }
276
288
277
- if (vlistT.nodes.first
278
- case dom.Element (localName: 'span' , className: 'vlist-r' ) &&
279
- final vlistR) {
280
- if (vlistR.attributes.containsKey ('style' )) throw _KatexHtmlParseError ();
281
-
282
- if (vlistR.nodes.first
283
- case dom.Element (localName: 'span' , className: 'vlist' ) &&
284
- final vlist) {
285
- // Same as above for the second .vlist-r span, .vlist span in first
286
- // .vlist-r span will have "height" inline style which we ignore,
287
- // because it doesn't seem to have any effect in rendering on
288
- // the web.
289
- // But also make sure there aren't any other inline styles present.
290
- final vlistStyles = _parseInlineStyles (vlist);
291
- if (vlistStyles != null && vlistStyles.keys.any ((p) => p != 'height' )) {
292
- throw _KatexHtmlParseError ();
293
- }
289
+ if (vlistT.nodes.first
290
+ case dom.Element (localName: 'span' , className: 'vlist-r' ) &&
291
+ final vlistR) {
292
+ if (vlistR.attributes.containsKey ('style' )) throw _KatexHtmlParseError ();
293
+
294
+ if (vlistR.nodes.first
295
+ case dom.Element (localName: 'span' , className: 'vlist' ) &&
296
+ final vlist) {
297
+ // Same as above for the second .vlist-r span, .vlist span in first
298
+ // .vlist-r span will have "height" inline style which we ignore,
299
+ // because it doesn't seem to have any effect in rendering on
300
+ // the web.
301
+ // But also make sure there aren't any other inline styles present.
302
+ final vlistStyles = _parseInlineStyles (vlist);
303
+ if (vlistStyles != null && vlistStyles.keys.any ((p) => p != 'height' )) {
304
+ throw _KatexHtmlParseError ();
305
+ }
306
+
307
+ final rows = < KatexVlistRowNode > [];
308
+
309
+ for (final innerSpan in vlist.nodes) {
310
+ if (innerSpan case dom.Element (
311
+ localName: 'span' ,
312
+ nodes: [
313
+ dom.Element (localName: 'span' , className: 'pstrut' ) &&
314
+ final pstrutSpan,
315
+ ...final otherSpans,
316
+ ],
317
+ )) {
318
+ if (innerSpan.className != '' ) {
319
+ throw _KatexHtmlParseError ('unexpected CSS class for '
320
+ 'vlist inner span: ${innerSpan .className }' );
321
+ }
294
322
295
- final rows = < KatexVlistRowNode > [];
296
-
297
- for (final innerSpan in vlist.nodes) {
298
- if (innerSpan case dom.Element (
299
- localName: 'span' ,
300
- nodes: [
301
- dom.Element (localName: 'span' , className: 'pstrut' ) &&
302
- final pstrutSpan,
303
- ...final otherSpans,
304
- ],
305
- )) {
306
- if (innerSpan.className != '' ) {
307
- throw _KatexHtmlParseError ('unexpected CSS class for '
308
- 'vlist inner span: ${innerSpan .className }' );
309
- }
310
-
311
- final inlineStyles = _parseInlineStyles (innerSpan);
312
- if (inlineStyles == null ) throw _KatexHtmlParseError ();
313
- final marginLeftEm = _takeStyleEm (inlineStyles, 'margin-left' );
314
- final marginLeftIsNegative = marginLeftEm? .isNegative ?? false ;
315
- final marginRightEm = _takeStyleEm (inlineStyles, 'margin-right' );
316
- if (marginRightEm? .isNegative ?? false ) throw _KatexHtmlParseError ();
317
- final styles = KatexSpanStyles (
318
- marginLeftEm: marginLeftIsNegative ? null : marginLeftEm,
319
- marginRightEm: marginRightEm,
320
- );
321
- final topEm = _takeStyleEm (inlineStyles, 'top' );
322
- if (inlineStyles.isNotEmpty) throw _KatexHtmlParseError ();
323
-
324
- final pstrutStyles = _parseInlineStyles (pstrutSpan);
325
- if (pstrutStyles == null ) throw _KatexHtmlParseError ();
326
- final pstrutHeightEm = _takeStyleEm (pstrutStyles, 'height' );
327
- if (pstrutHeightEm == null ) throw _KatexHtmlParseError ();
328
- if (pstrutStyles.isNotEmpty) throw _KatexHtmlParseError ();
329
-
330
- KatexSpanNode child = KatexSpanNode (
331
- styles: styles,
323
+ final inlineStyles = _parseInlineStyles (innerSpan);
324
+ if (inlineStyles == null ) throw _KatexHtmlParseError ();
325
+ final marginLeftEm = _takeStyleEm (inlineStyles, 'margin-left' );
326
+ final marginLeftIsNegative = marginLeftEm? .isNegative ?? false ;
327
+ final marginRightEm = _takeStyleEm (inlineStyles, 'margin-right' );
328
+ if (marginRightEm? .isNegative ?? false ) throw _KatexHtmlParseError ();
329
+ final styles = KatexSpanStyles (
330
+ marginLeftEm: marginLeftIsNegative ? null : marginLeftEm,
331
+ marginRightEm: marginRightEm,
332
+ );
333
+ final topEm = _takeStyleEm (inlineStyles, 'top' );
334
+ if (inlineStyles.isNotEmpty) throw _KatexHtmlParseError ();
335
+
336
+ final pstrutStyles = _parseInlineStyles (pstrutSpan);
337
+ if (pstrutStyles == null ) throw _KatexHtmlParseError ();
338
+ final pstrutHeightEm = _takeStyleEm (pstrutStyles, 'height' );
339
+ if (pstrutHeightEm == null ) throw _KatexHtmlParseError ();
340
+ if (pstrutStyles.isNotEmpty) throw _KatexHtmlParseError ();
341
+
342
+ KatexSpanNode child = KatexSpanNode (
343
+ styles: styles,
344
+ text: null ,
345
+ nodes: _parseChildSpans (otherSpans));
346
+
347
+ if (marginLeftIsNegative) {
348
+ child = KatexSpanNode (
349
+ styles: KatexSpanStyles (),
332
350
text: null ,
333
- nodes: _parseChildSpans (otherSpans));
334
-
335
- if (marginLeftIsNegative) {
336
- child = KatexSpanNode (
337
- styles: KatexSpanStyles (),
338
- text: null ,
339
- nodes: [KatexNegativeMarginNode (
340
- leftOffsetEm: marginLeftEm! ,
341
- nodes: [child])]);
342
- }
343
-
344
- rows.add (KatexVlistRowNode (
345
- verticalOffsetEm: (topEm ?? 0 ) + pstrutHeightEm,
346
- debugHtmlNode: kDebugMode ? innerSpan : null ,
347
- node: child));
348
- } else {
349
- throw _KatexHtmlParseError ();
351
+ nodes: [KatexNegativeMarginNode (
352
+ leftOffsetEm: marginLeftEm! ,
353
+ nodes: [child])]);
350
354
}
351
- }
352
355
353
- // TODO(#1716) Handle styling for .vlist-t2 spans
354
- return KatexVlistNode (
355
- rows : rows ,
356
- debugHtmlNode : debugHtmlNode,
357
- );
358
- } else {
359
- throw _KatexHtmlParseError ();
356
+ rows. add ( KatexVlistRowNode (
357
+ verticalOffsetEm : (topEm ?? 0 ) + pstrutHeightEm,
358
+ debugHtmlNode : kDebugMode ? innerSpan : null ,
359
+ node : child));
360
+ } else {
361
+ throw _KatexHtmlParseError ();
362
+ }
360
363
}
364
+
365
+ // TODO(#1716) Handle styling for .vlist-t2 spans
366
+ return KatexVlistNode (
367
+ rows: rows,
368
+ debugHtmlNode: kDebugMode ? element : null ,
369
+ );
361
370
} else {
362
371
throw _KatexHtmlParseError ();
363
372
}
373
+ } else {
374
+ throw _KatexHtmlParseError ();
364
375
}
376
+ }
377
+
378
+ static final _resetSizeClassRegExp = RegExp (r'^reset-size(\d\d?)$' );
379
+ static final _sizeClassRegExp = RegExp (r'^size(\d\d?)$' );
380
+
381
+ KatexNode _parseGenericSpan (dom.Element element) {
382
+ assert (element.localName == 'span' );
365
383
366
384
// Aggregate the CSS styles that apply, in the same order as the CSS
367
385
// classes specified for this span, mimicking the behaviour on web.
@@ -646,7 +664,7 @@ class _KatexParser {
646
664
styles: styles,
647
665
text: text,
648
666
nodes: spans,
649
- debugHtmlNode: debugHtmlNode );
667
+ debugHtmlNode: kDebugMode ? element : null );
650
668
}
651
669
652
670
/// Parse the inline CSS styles from the given element.
0 commit comments