1
+ import 'package:csslib/parser.dart' as css_parser;
2
+ import 'package:csslib/visitor.dart' as css_visitor;
1
3
import 'package:flutter/foundation.dart' ;
2
4
import 'package:html/dom.dart' as dom;
3
5
@@ -292,11 +294,72 @@ class KatexParser {
292
294
}
293
295
if (text == null && spans == null ) throw KatexHtmlParseError ();
294
296
297
+ final inlineStyles = _parseSpanInlineStyles (element);
298
+
295
299
return KatexNode (
296
300
text: text,
297
- styles: styles,
301
+ styles: inlineStyles != null
302
+ ? styles.merge (inlineStyles)
303
+ : styles,
298
304
nodes: spans);
299
305
}
306
+
307
+ KatexSpanStyles ? _parseSpanInlineStyles (dom.Element element) {
308
+ if (element.attributes case {'style' : final styleStr}) {
309
+ final stylesheet = css_parser.parse ('*{$styleStr }' );
310
+ final topLevels = stylesheet.topLevels;
311
+ if (topLevels.length != 1 ) throw KatexHtmlParseError ();
312
+ final topLevel = topLevels.single;
313
+ if (topLevel is ! css_visitor.RuleSet ) throw KatexHtmlParseError ();
314
+ final rule = topLevel;
315
+
316
+ double ? marginLeftEm;
317
+ double ? marginRightEm;
318
+ double ? paddingLeftEm;
319
+
320
+ for (final declaration in rule.declarationGroup.declarations) {
321
+ if (declaration is ! css_visitor.Declaration ) throw KatexHtmlParseError ();
322
+ final property = declaration.property;
323
+
324
+ final expressions = declaration.expression;
325
+ if (expressions is ! css_visitor.Expressions ) throw KatexHtmlParseError ();
326
+ if (expressions.expressions.length != 1 ) throw KatexHtmlParseError ();
327
+ final expression = expressions.expressions.single;
328
+
329
+ switch (property) {
330
+ case 'margin-left' :
331
+ marginLeftEm = _getEm (expression);
332
+ if (marginLeftEm != null ) continue ;
333
+
334
+ case 'margin-right' :
335
+ marginRightEm = _getEm (expression);
336
+ if (marginRightEm != null ) continue ;
337
+
338
+ case 'padding-left' :
339
+ paddingLeftEm = _getEm (expression);
340
+ if (paddingLeftEm != null ) continue ;
341
+
342
+ default :
343
+ // TODO handle more CSS properties
344
+ assert (debugLog ('Unsupported CSS property: $property of type ${expression .runtimeType }' ));
345
+ }
346
+ }
347
+
348
+ return KatexSpanStyles (
349
+ marginLeftEm: marginLeftEm,
350
+ marginRightEm: marginRightEm,
351
+ paddingLeftEm: paddingLeftEm,
352
+ );
353
+ }
354
+ return null ;
355
+ }
356
+
357
+ double ? _getEm (css_visitor.Expression expression) {
358
+ if (expression is css_visitor.EmTerm && expression.value is num ) {
359
+ return (expression.value as num ).toDouble ();
360
+ }
361
+ return null ;
362
+ }
300
363
}
301
364
302
365
enum KatexSpanFontWeight {
@@ -315,13 +378,22 @@ enum KatexSpanTextAlign {
315
378
}
316
379
317
380
class KatexSpanStyles {
381
+ double ? heightEm;
382
+ double ? marginLeftEm;
383
+ double ? marginRightEm;
384
+ double ? paddingLeftEm;
385
+
318
386
String ? fontFamily;
319
387
double ? fontSizeEm;
320
388
KatexSpanFontStyle ? fontStyle;
321
389
KatexSpanFontWeight ? fontWeight;
322
390
KatexSpanTextAlign ? textAlign;
323
391
324
392
KatexSpanStyles ({
393
+ this .heightEm,
394
+ this .marginLeftEm,
395
+ this .marginRightEm,
396
+ this .paddingLeftEm,
325
397
this .fontFamily,
326
398
this .fontSizeEm,
327
399
this .fontStyle,
@@ -332,6 +404,10 @@ class KatexSpanStyles {
332
404
@override
333
405
int get hashCode => Object .hash (
334
406
'KatexSpanStyles' ,
407
+ heightEm,
408
+ marginLeftEm,
409
+ marginRightEm,
410
+ paddingLeftEm,
335
411
fontFamily,
336
412
fontSizeEm,
337
413
fontStyle,
@@ -342,6 +418,10 @@ class KatexSpanStyles {
342
418
@override
343
419
bool operator == (Object other) {
344
420
return other is KatexSpanStyles &&
421
+ other.heightEm == heightEm &&
422
+ other.marginLeftEm == marginLeftEm &&
423
+ other.marginRightEm == marginRightEm &&
424
+ other.paddingLeftEm == paddingLeftEm &&
345
425
other.fontFamily == fontFamily &&
346
426
other.fontSizeEm == fontSizeEm &&
347
427
other.fontStyle == fontStyle &&
@@ -356,13 +436,31 @@ class KatexSpanStyles {
356
436
if (this == _zero) return '${objectRuntimeType (this , 'KatexSpanStyles' )}()' ;
357
437
358
438
final args = < String > [];
439
+ if (heightEm != null ) args.add ('heightEm: $heightEm ' );
440
+ if (marginLeftEm != null ) args.add ('marginLeftEm: $marginLeftEm ' );
441
+ if (marginRightEm != null ) args.add ('marginRightEm: $marginRightEm ' );
442
+ if (paddingLeftEm != null ) args.add ('paddingLeftEm: $paddingLeftEm ' );
359
443
if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
360
444
if (fontSizeEm != null ) args.add ('fontSizeEm: $fontSizeEm ' );
361
445
if (fontStyle != null ) args.add ('fontStyle: $fontStyle ' );
362
446
if (fontWeight != null ) args.add ('fontWeight: $fontWeight ' );
363
447
if (textAlign != null ) args.add ('textAlign: $textAlign ' );
364
448
return '${objectRuntimeType (this , 'KatexSpanStyles' )}(${args .join (', ' )})' ;
365
449
}
450
+
451
+ KatexSpanStyles merge (KatexSpanStyles other) {
452
+ return KatexSpanStyles (
453
+ heightEm: other.heightEm ?? heightEm,
454
+ marginLeftEm: other.marginLeftEm ?? marginLeftEm,
455
+ marginRightEm: other.marginRightEm ?? marginRightEm,
456
+ paddingLeftEm: other.paddingLeftEm ?? paddingLeftEm,
457
+ fontFamily: other.fontFamily ?? fontFamily,
458
+ fontSizeEm: other.fontSizeEm ?? fontSizeEm,
459
+ fontStyle: other.fontStyle ?? fontStyle,
460
+ fontWeight: other.fontWeight ?? fontWeight,
461
+ textAlign: other.textAlign ?? textAlign,
462
+ );
463
+ }
366
464
}
367
465
368
466
class KatexSpanStylesProperty extends DiagnosticsProperty <KatexSpanStyles > {
0 commit comments