1+ import 'package:csslib/parser.dart' as css_parser;
2+ import 'package:csslib/visitor.dart' as css_visitor;
13import 'package:flutter/foundation.dart' ;
24import 'package:html/dom.dart' as dom;
35
@@ -292,11 +294,72 @@ class KatexParser {
292294 }
293295 if (text == null && spans == null ) throw KatexHtmlParseError ();
294296
297+ final inlineStyles = _parseSpanInlineStyles (element);
298+
295299 return KatexNode (
296300 text: text,
297- styles: styles,
301+ styles: inlineStyles != null
302+ ? styles.merge (inlineStyles)
303+ : styles,
298304 nodes: spans);
299305 }
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+ }
300363}
301364
302365enum KatexSpanFontWeight {
@@ -315,13 +378,22 @@ enum KatexSpanTextAlign {
315378}
316379
317380class KatexSpanStyles {
381+ double ? heightEm;
382+ double ? marginLeftEm;
383+ double ? marginRightEm;
384+ double ? paddingLeftEm;
385+
318386 String ? fontFamily;
319387 double ? fontSizeEm;
320388 KatexSpanFontStyle ? fontStyle;
321389 KatexSpanFontWeight ? fontWeight;
322390 KatexSpanTextAlign ? textAlign;
323391
324392 KatexSpanStyles ({
393+ this .heightEm,
394+ this .marginLeftEm,
395+ this .marginRightEm,
396+ this .paddingLeftEm,
325397 this .fontFamily,
326398 this .fontSizeEm,
327399 this .fontStyle,
@@ -332,6 +404,10 @@ class KatexSpanStyles {
332404 @override
333405 int get hashCode => Object .hash (
334406 'KatexSpanStyles' ,
407+ heightEm,
408+ marginLeftEm,
409+ marginRightEm,
410+ paddingLeftEm,
335411 fontFamily,
336412 fontSizeEm,
337413 fontStyle,
@@ -342,6 +418,10 @@ class KatexSpanStyles {
342418 @override
343419 bool operator == (Object other) {
344420 return other is KatexSpanStyles &&
421+ other.heightEm == heightEm &&
422+ other.marginLeftEm == marginLeftEm &&
423+ other.marginRightEm == marginRightEm &&
424+ other.paddingLeftEm == paddingLeftEm &&
345425 other.fontFamily == fontFamily &&
346426 other.fontSizeEm == fontSizeEm &&
347427 other.fontStyle == fontStyle &&
@@ -356,13 +436,31 @@ class KatexSpanStyles {
356436 if (this == _zero) return '${objectRuntimeType (this , 'KatexSpanStyles' )}()' ;
357437
358438 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 ' );
359443 if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
360444 if (fontSizeEm != null ) args.add ('fontSizeEm: $fontSizeEm ' );
361445 if (fontStyle != null ) args.add ('fontStyle: $fontStyle ' );
362446 if (fontWeight != null ) args.add ('fontWeight: $fontWeight ' );
363447 if (textAlign != null ) args.add ('textAlign: $textAlign ' );
364448 return '${objectRuntimeType (this , 'KatexSpanStyles' )}(${args .join (', ' )})' ;
365449 }
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+ }
366464}
367465
368466class KatexSpanStylesProperty extends DiagnosticsProperty <KatexSpanStyles > {
0 commit comments