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
6
+ import '../log.dart' ;
4
7
import 'content.dart' ;
5
8
6
9
class KatexParser {
@@ -225,11 +228,72 @@ class KatexParser {
225
228
}
226
229
if (text == null && spans == null ) throw KatexHtmlParseError ();
227
230
231
+ final inlineStyles = _parseSpanInlineStyles (element);
232
+
228
233
return KatexSpanNode (
229
234
text: text,
230
- styles: styles,
235
+ styles: inlineStyles != null
236
+ ? styles.merge (inlineStyles)
237
+ : styles,
231
238
nodes: spans ?? const []);
232
239
}
240
+
241
+ KatexSpanStyles ? _parseSpanInlineStyles (dom.Element element) {
242
+ if (element.attributes case {'style' : final styleStr}) {
243
+ final stylesheet = css_parser.parse ('*{$styleStr }' );
244
+ final topLevels = stylesheet.topLevels;
245
+ if (topLevels.length != 1 ) throw KatexHtmlParseError ();
246
+ final topLevel = topLevels.single;
247
+ if (topLevel is ! css_visitor.RuleSet ) throw KatexHtmlParseError ();
248
+ final rule = topLevel;
249
+
250
+ double ? marginLeftEm;
251
+ double ? marginRightEm;
252
+ double ? paddingLeftEm;
253
+
254
+ for (final declaration in rule.declarationGroup.declarations) {
255
+ if (declaration is ! css_visitor.Declaration ) throw KatexHtmlParseError ();
256
+ final property = declaration.property;
257
+
258
+ final expressions = declaration.expression;
259
+ if (expressions is ! css_visitor.Expressions ) throw KatexHtmlParseError ();
260
+ if (expressions.expressions.length != 1 ) throw KatexHtmlParseError ();
261
+ final expression = expressions.expressions.single;
262
+
263
+ switch (property) {
264
+ case 'margin-left' :
265
+ marginLeftEm = _getEm (expression);
266
+ if (marginLeftEm != null ) continue ;
267
+
268
+ case 'margin-right' :
269
+ marginRightEm = _getEm (expression);
270
+ if (marginRightEm != null ) continue ;
271
+
272
+ case 'padding-left' :
273
+ paddingLeftEm = _getEm (expression);
274
+ if (paddingLeftEm != null ) continue ;
275
+
276
+ default :
277
+ // TODO handle more CSS properties
278
+ assert (debugLog ('Unsupported CSS property: $property of type ${expression .runtimeType }' ));
279
+ }
280
+ }
281
+
282
+ return KatexSpanStyles (
283
+ marginLeftEm: marginLeftEm,
284
+ marginRightEm: marginRightEm,
285
+ paddingLeftEm: paddingLeftEm,
286
+ );
287
+ }
288
+ return null ;
289
+ }
290
+
291
+ double ? _getEm (css_visitor.Expression expression) {
292
+ if (expression is css_visitor.EmTerm && expression.value is num ) {
293
+ return (expression.value as num ).toDouble ();
294
+ }
295
+ return null ;
296
+ }
233
297
}
234
298
235
299
enum KatexSpanFontWeight {
@@ -248,13 +312,20 @@ enum KatexSpanTextAlign {
248
312
}
249
313
250
314
class KatexSpanStyles {
315
+ double ? marginLeftEm;
316
+ double ? marginRightEm;
317
+ double ? paddingLeftEm;
318
+
251
319
String ? fontFamily;
252
320
double ? fontSizeEm;
253
321
KatexSpanFontStyle ? fontStyle;
254
322
KatexSpanFontWeight ? fontWeight;
255
323
KatexSpanTextAlign ? textAlign;
256
324
257
325
KatexSpanStyles ({
326
+ this .marginLeftEm,
327
+ this .marginRightEm,
328
+ this .paddingLeftEm,
258
329
this .fontFamily,
259
330
this .fontSizeEm,
260
331
this .fontStyle,
@@ -265,6 +336,9 @@ class KatexSpanStyles {
265
336
@override
266
337
int get hashCode => Object .hash (
267
338
'KatexSpanStyles' ,
339
+ marginLeftEm,
340
+ marginRightEm,
341
+ paddingLeftEm,
268
342
fontFamily,
269
343
fontSizeEm,
270
344
fontStyle,
@@ -275,6 +349,9 @@ class KatexSpanStyles {
275
349
@override
276
350
bool operator == (Object other) {
277
351
return other is KatexSpanStyles &&
352
+ other.marginLeftEm == marginLeftEm &&
353
+ other.marginRightEm == marginRightEm &&
354
+ other.paddingLeftEm == paddingLeftEm &&
278
355
other.fontFamily == fontFamily &&
279
356
other.fontSizeEm == fontSizeEm &&
280
357
other.fontStyle == fontStyle &&
@@ -289,6 +366,9 @@ class KatexSpanStyles {
289
366
if (this == _zero) return '${objectRuntimeType (this , 'KatexSpanStyles' )}()' ;
290
367
291
368
final args = < String > [];
369
+ if (marginLeftEm != null ) args.add ('marginLeftEm: $marginLeftEm ' );
370
+ if (marginRightEm != null ) args.add ('marginRightEm: $marginRightEm ' );
371
+ if (paddingLeftEm != null ) args.add ('paddingLeftEm: $paddingLeftEm ' );
292
372
if (fontFamily != null ) args.add ('fontFamily: $fontFamily ' );
293
373
if (fontSizeEm != null ) args.add ('fontSizeEm: $fontSizeEm ' );
294
374
if (fontStyle != null ) args.add ('fontStyle: $fontStyle ' );
@@ -299,6 +379,9 @@ class KatexSpanStyles {
299
379
300
380
KatexSpanStyles merge (KatexSpanStyles other) {
301
381
return KatexSpanStyles (
382
+ marginLeftEm: other.marginLeftEm ?? marginLeftEm,
383
+ marginRightEm: other.marginRightEm ?? marginRightEm,
384
+ paddingLeftEm: other.paddingLeftEm ?? paddingLeftEm,
302
385
fontFamily: other.fontFamily ?? fontFamily,
303
386
fontSizeEm: other.fontSizeEm ?? fontSizeEm,
304
387
fontStyle: other.fontStyle ?? fontStyle,
0 commit comments