1
+ import 'package:convert/convert.dart' ;
1
2
import 'package:csslib/parser.dart' as css_parser;
2
3
import 'package:csslib/visitor.dart' as css_visitor;
3
4
import 'package:flutter/foundation.dart' ;
4
- import 'package:flutter/widgets.dart' ;
5
5
import 'package:html/dom.dart' as dom;
6
6
7
7
import '../log.dart' ;
@@ -463,6 +463,7 @@ class _KatexParser {
463
463
final stylesheet = css_parser.parse ('*{$styleStr }' );
464
464
if (stylesheet.topLevels case [css_visitor.RuleSet () && final rule]) {
465
465
double ? heightEm;
466
+ KatexSpanColor ? color;
466
467
467
468
for (final declaration in rule.declarationGroup.declarations) {
468
469
if (declaration case css_visitor.Declaration (
@@ -474,6 +475,18 @@ class _KatexParser {
474
475
case 'height' :
475
476
heightEm = _getEm (expression);
476
477
if (heightEm != null ) continue ;
478
+
479
+ case 'color' :
480
+ final valueStr = _getRawValue (expression);
481
+ if (valueStr != null ) {
482
+ if (valueStr.startsWith ('#' )) {
483
+ color = parseCssHexColor (valueStr);
484
+ if (color != null ) continue ;
485
+ }
486
+
487
+ color = _cssNamedColorsMap[valueStr];
488
+ if (color != null ) continue ;
489
+ }
477
490
}
478
491
479
492
// TODO handle more CSS properties
@@ -488,6 +501,7 @@ class _KatexParser {
488
501
489
502
return KatexSpanStyles (
490
503
heightEm: heightEm,
504
+ color: color,
491
505
);
492
506
} else {
493
507
throw _KatexHtmlParseError ();
@@ -504,6 +518,10 @@ class _KatexParser {
504
518
}
505
519
return null ;
506
520
}
521
+
522
+ String ? _getRawValue (css_visitor.Expression expression) {
523
+ return expression.span? .text;
524
+ }
507
525
}
508
526
509
527
enum KatexSpanFontWeight {
@@ -521,6 +539,32 @@ enum KatexSpanTextAlign {
521
539
right,
522
540
}
523
541
542
+ class KatexSpanColor {
543
+ const KatexSpanColor (this .r, this .g, this .b, this .a);
544
+
545
+ final int r;
546
+ final int g;
547
+ final int b;
548
+ final int a;
549
+
550
+ @override
551
+ bool operator == (Object other) {
552
+ return other is KatexSpanColor &&
553
+ other.r == r &&
554
+ other.g == g &&
555
+ other.b == b &&
556
+ other.a == a;
557
+ }
558
+
559
+ @override
560
+ int get hashCode => Object .hash ('KatexSpanColor' , r, g, b, a);
561
+
562
+ @override
563
+ String toString () {
564
+ return '${objectRuntimeType (this , 'KatexSpanColor' )}($r , $g , $b , $a )' ;
565
+ }
566
+ }
567
+
524
568
@immutable
525
569
class KatexSpanStyles {
526
570
final double ? heightEm;
@@ -531,13 +575,16 @@ class KatexSpanStyles {
531
575
final KatexSpanFontStyle ? fontStyle;
532
576
final KatexSpanTextAlign ? textAlign;
533
577
578
+ final KatexSpanColor ? color;
579
+
534
580
const KatexSpanStyles ({
535
581
this .heightEm,
536
582
this .fontFamily,
537
583
this .fontSizeEm,
538
584
this .fontWeight,
539
585
this .fontStyle,
540
586
this .textAlign,
587
+ this .color,
541
588
});
542
589
543
590
@override
@@ -549,6 +596,7 @@ class KatexSpanStyles {
549
596
fontWeight,
550
597
fontStyle,
551
598
textAlign,
599
+ color,
552
600
);
553
601
554
602
@override
@@ -559,7 +607,8 @@ class KatexSpanStyles {
559
607
other.fontSizeEm == fontSizeEm &&
560
608
other.fontWeight == fontWeight &&
561
609
other.fontStyle == fontStyle &&
562
- other.textAlign == textAlign;
610
+ other.textAlign == textAlign &&
611
+ other.color == color;
563
612
}
564
613
565
614
@override
@@ -571,6 +620,7 @@ class KatexSpanStyles {
571
620
if (fontWeight != null ) args.add ('fontWeight: $fontWeight ' );
572
621
if (fontStyle != null ) args.add ('fontStyle: $fontStyle ' );
573
622
if (textAlign != null ) args.add ('textAlign: $textAlign ' );
623
+ if (color != null ) args.add ('color: $color ' );
574
624
return '${objectRuntimeType (this , 'KatexSpanStyles' )}(${args .join (', ' )})' ;
575
625
}
576
626
@@ -589,10 +639,201 @@ class KatexSpanStyles {
589
639
fontStyle: other.fontStyle ?? fontStyle,
590
640
fontWeight: other.fontWeight ?? fontWeight,
591
641
textAlign: other.textAlign ?? textAlign,
642
+ color: other.color ?? color,
592
643
);
593
644
}
594
645
}
595
646
647
+ final _hexColorRegExp =
648
+ RegExp (r'^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$' );
649
+
650
+ /// Parses the CSS hex color notation.
651
+ ///
652
+ /// See: https://drafts.csswg.org/css-color/#hex-notation
653
+ KatexSpanColor ? parseCssHexColor (String hexStr) {
654
+ final match = _hexColorRegExp.firstMatch (hexStr);
655
+ if (match == null ) return null ;
656
+
657
+ String hexValue = match.group (1 )! ;
658
+ hexValue = hexValue.toLowerCase ();
659
+ switch (hexValue.length) {
660
+ case 3 :
661
+ hexValue = '${hexValue [0 ]}${hexValue [0 ]}'
662
+ '${hexValue [1 ]}${hexValue [1 ]}'
663
+ '${hexValue [2 ]}${hexValue [2 ]}'
664
+ 'ff' ;
665
+ case 4 :
666
+ hexValue = '${hexValue [0 ]}${hexValue [0 ]}'
667
+ '${hexValue [1 ]}${hexValue [1 ]}'
668
+ '${hexValue [2 ]}${hexValue [2 ]}'
669
+ '${hexValue [3 ]}${hexValue [3 ]}' ;
670
+ case 6 :
671
+ hexValue += 'ff' ;
672
+ }
673
+
674
+ try {
675
+ final [r, g, b, a] = hex.decode (hexValue);
676
+ return KatexSpanColor (r, g, b, a);
677
+ } catch (_) {
678
+ return null ; // TODO(log)
679
+ }
680
+ }
681
+
682
+ // CSS named colors: https://drafts.csswg.org/css-color/#named-colors
683
+ // Map adapted from the following source file:
684
+ // https://github.com/w3c/csswg-drafts/blob/1942d0918/css-color-4/Overview.bs#L1562-L1859
685
+ const _cssNamedColorsMap = {
686
+ 'transparent' : KatexSpanColor (0 , 0 , 0 , 0 ), // https://drafts.csswg.org/css-color/#transparent-color
687
+ 'aliceblue' : KatexSpanColor (240 , 248 , 255 , 255 ),
688
+ 'antiquewhite' : KatexSpanColor (250 , 235 , 215 , 255 ),
689
+ 'aqua' : KatexSpanColor (0 , 255 , 255 , 255 ),
690
+ 'aquamarine' : KatexSpanColor (127 , 255 , 212 , 255 ),
691
+ 'azure' : KatexSpanColor (240 , 255 , 255 , 255 ),
692
+ 'beige' : KatexSpanColor (245 , 245 , 220 , 255 ),
693
+ 'bisque' : KatexSpanColor (255 , 228 , 196 , 255 ),
694
+ 'black' : KatexSpanColor (0 , 0 , 0 , 255 ),
695
+ 'blanchedalmond' : KatexSpanColor (255 , 235 , 205 , 255 ),
696
+ 'blue' : KatexSpanColor (0 , 0 , 255 , 255 ),
697
+ 'blueviolet' : KatexSpanColor (138 , 43 , 226 , 255 ),
698
+ 'brown' : KatexSpanColor (165 , 42 , 42 , 255 ),
699
+ 'burlywood' : KatexSpanColor (222 , 184 , 135 , 255 ),
700
+ 'cadetblue' : KatexSpanColor (95 , 158 , 160 , 255 ),
701
+ 'chartreuse' : KatexSpanColor (127 , 255 , 0 , 255 ),
702
+ 'chocolate' : KatexSpanColor (210 , 105 , 30 , 255 ),
703
+ 'coral' : KatexSpanColor (255 , 127 , 80 , 255 ),
704
+ 'cornflowerblue' : KatexSpanColor (100 , 149 , 237 , 255 ),
705
+ 'cornsilk' : KatexSpanColor (255 , 248 , 220 , 255 ),
706
+ 'crimson' : KatexSpanColor (220 , 20 , 60 , 255 ),
707
+ 'cyan' : KatexSpanColor (0 , 255 , 255 , 255 ),
708
+ 'darkblue' : KatexSpanColor (0 , 0 , 139 , 255 ),
709
+ 'darkcyan' : KatexSpanColor (0 , 139 , 139 , 255 ),
710
+ 'darkgoldenrod' : KatexSpanColor (184 , 134 , 11 , 255 ),
711
+ 'darkgray' : KatexSpanColor (169 , 169 , 169 , 255 ),
712
+ 'darkgreen' : KatexSpanColor (0 , 100 , 0 , 255 ),
713
+ 'darkgrey' : KatexSpanColor (169 , 169 , 169 , 255 ),
714
+ 'darkkhaki' : KatexSpanColor (189 , 183 , 107 , 255 ),
715
+ 'darkmagenta' : KatexSpanColor (139 , 0 , 139 , 255 ),
716
+ 'darkolivegreen' : KatexSpanColor (85 , 107 , 47 , 255 ),
717
+ 'darkorange' : KatexSpanColor (255 , 140 , 0 , 255 ),
718
+ 'darkorchid' : KatexSpanColor (153 , 50 , 204 , 255 ),
719
+ 'darkred' : KatexSpanColor (139 , 0 , 0 , 255 ),
720
+ 'darksalmon' : KatexSpanColor (233 , 150 , 122 , 255 ),
721
+ 'darkseagreen' : KatexSpanColor (143 , 188 , 143 , 255 ),
722
+ 'darkslateblue' : KatexSpanColor (72 , 61 , 139 , 255 ),
723
+ 'darkslategray' : KatexSpanColor (47 , 79 , 79 , 255 ),
724
+ 'darkslategrey' : KatexSpanColor (47 , 79 , 79 , 255 ),
725
+ 'darkturquoise' : KatexSpanColor (0 , 206 , 209 , 255 ),
726
+ 'darkviolet' : KatexSpanColor (148 , 0 , 211 , 255 ),
727
+ 'deeppink' : KatexSpanColor (255 , 20 , 147 , 255 ),
728
+ 'deepskyblue' : KatexSpanColor (0 , 191 , 255 , 255 ),
729
+ 'dimgray' : KatexSpanColor (105 , 105 , 105 , 255 ),
730
+ 'dimgrey' : KatexSpanColor (105 , 105 , 105 , 255 ),
731
+ 'dodgerblue' : KatexSpanColor (30 , 144 , 255 , 255 ),
732
+ 'firebrick' : KatexSpanColor (178 , 34 , 34 , 255 ),
733
+ 'floralwhite' : KatexSpanColor (255 , 250 , 240 , 255 ),
734
+ 'forestgreen' : KatexSpanColor (34 , 139 , 34 , 255 ),
735
+ 'fuchsia' : KatexSpanColor (255 , 0 , 255 , 255 ),
736
+ 'gainsboro' : KatexSpanColor (220 , 220 , 220 , 255 ),
737
+ 'ghostwhite' : KatexSpanColor (248 , 248 , 255 , 255 ),
738
+ 'gold' : KatexSpanColor (255 , 215 , 0 , 255 ),
739
+ 'goldenrod' : KatexSpanColor (218 , 165 , 32 , 255 ),
740
+ 'gray' : KatexSpanColor (128 , 128 , 128 , 255 ),
741
+ 'green' : KatexSpanColor (0 , 128 , 0 , 255 ),
742
+ 'greenyellow' : KatexSpanColor (173 , 255 , 47 , 255 ),
743
+ 'grey' : KatexSpanColor (128 , 128 , 128 , 255 ),
744
+ 'honeydew' : KatexSpanColor (240 , 255 , 240 , 255 ),
745
+ 'hotpink' : KatexSpanColor (255 , 105 , 180 , 255 ),
746
+ 'indianred' : KatexSpanColor (205 , 92 , 92 , 255 ),
747
+ 'indigo' : KatexSpanColor (75 , 0 , 130 , 255 ),
748
+ 'ivory' : KatexSpanColor (255 , 255 , 240 , 255 ),
749
+ 'khaki' : KatexSpanColor (240 , 230 , 140 , 255 ),
750
+ 'lavender' : KatexSpanColor (230 , 230 , 250 , 255 ),
751
+ 'lavenderblush' : KatexSpanColor (255 , 240 , 245 , 255 ),
752
+ 'lawngreen' : KatexSpanColor (124 , 252 , 0 , 255 ),
753
+ 'lemonchiffon' : KatexSpanColor (255 , 250 , 205 , 255 ),
754
+ 'lightblue' : KatexSpanColor (173 , 216 , 230 , 255 ),
755
+ 'lightcoral' : KatexSpanColor (240 , 128 , 128 , 255 ),
756
+ 'lightcyan' : KatexSpanColor (224 , 255 , 255 , 255 ),
757
+ 'lightgoldenrodyellow' : KatexSpanColor (250 , 250 , 210 , 255 ),
758
+ 'lightgray' : KatexSpanColor (211 , 211 , 211 , 255 ),
759
+ 'lightgreen' : KatexSpanColor (144 , 238 , 144 , 255 ),
760
+ 'lightgrey' : KatexSpanColor (211 , 211 , 211 , 255 ),
761
+ 'lightpink' : KatexSpanColor (255 , 182 , 193 , 255 ),
762
+ 'lightsalmon' : KatexSpanColor (255 , 160 , 122 , 255 ),
763
+ 'lightseagreen' : KatexSpanColor (32 , 178 , 170 , 255 ),
764
+ 'lightskyblue' : KatexSpanColor (135 , 206 , 250 , 255 ),
765
+ 'lightslategray' : KatexSpanColor (119 , 136 , 153 , 255 ),
766
+ 'lightslategrey' : KatexSpanColor (119 , 136 , 153 , 255 ),
767
+ 'lightsteelblue' : KatexSpanColor (176 , 196 , 222 , 255 ),
768
+ 'lightyellow' : KatexSpanColor (255 , 255 , 224 , 255 ),
769
+ 'lime' : KatexSpanColor (0 , 255 , 0 , 255 ),
770
+ 'limegreen' : KatexSpanColor (50 , 205 , 50 , 255 ),
771
+ 'linen' : KatexSpanColor (250 , 240 , 230 , 255 ),
772
+ 'magenta' : KatexSpanColor (255 , 0 , 255 , 255 ),
773
+ 'maroon' : KatexSpanColor (128 , 0 , 0 , 255 ),
774
+ 'mediumaquamarine' : KatexSpanColor (102 , 205 , 170 , 255 ),
775
+ 'mediumblue' : KatexSpanColor (0 , 0 , 205 , 255 ),
776
+ 'mediumorchid' : KatexSpanColor (186 , 85 , 211 , 255 ),
777
+ 'mediumpurple' : KatexSpanColor (147 , 112 , 219 , 255 ),
778
+ 'mediumseagreen' : KatexSpanColor (60 , 179 , 113 , 255 ),
779
+ 'mediumslateblue' : KatexSpanColor (123 , 104 , 238 , 255 ),
780
+ 'mediumspringgreen' : KatexSpanColor (0 , 250 , 154 , 255 ),
781
+ 'mediumturquoise' : KatexSpanColor (72 , 209 , 204 , 255 ),
782
+ 'mediumvioletred' : KatexSpanColor (199 , 21 , 133 , 255 ),
783
+ 'midnightblue' : KatexSpanColor (25 , 25 , 112 , 255 ),
784
+ 'mintcream' : KatexSpanColor (245 , 255 , 250 , 255 ),
785
+ 'mistyrose' : KatexSpanColor (255 , 228 , 225 , 255 ),
786
+ 'moccasin' : KatexSpanColor (255 , 228 , 181 , 255 ),
787
+ 'navajowhite' : KatexSpanColor (255 , 222 , 173 , 255 ),
788
+ 'navy' : KatexSpanColor (0 , 0 , 128 , 255 ),
789
+ 'oldlace' : KatexSpanColor (253 , 245 , 230 , 255 ),
790
+ 'olive' : KatexSpanColor (128 , 128 , 0 , 255 ),
791
+ 'olivedrab' : KatexSpanColor (107 , 142 , 35 , 255 ),
792
+ 'orange' : KatexSpanColor (255 , 165 , 0 , 255 ),
793
+ 'orangered' : KatexSpanColor (255 , 69 , 0 , 255 ),
794
+ 'orchid' : KatexSpanColor (218 , 112 , 214 , 255 ),
795
+ 'palegoldenrod' : KatexSpanColor (238 , 232 , 170 , 255 ),
796
+ 'palegreen' : KatexSpanColor (152 , 251 , 152 , 255 ),
797
+ 'paleturquoise' : KatexSpanColor (175 , 238 , 238 , 255 ),
798
+ 'palevioletred' : KatexSpanColor (219 , 112 , 147 , 255 ),
799
+ 'papayawhip' : KatexSpanColor (255 , 239 , 213 , 255 ),
800
+ 'peachpuff' : KatexSpanColor (255 , 218 , 185 , 255 ),
801
+ 'peru' : KatexSpanColor (205 , 133 , 63 , 255 ),
802
+ 'pink' : KatexSpanColor (255 , 192 , 203 , 255 ),
803
+ 'plum' : KatexSpanColor (221 , 160 , 221 , 255 ),
804
+ 'powderblue' : KatexSpanColor (176 , 224 , 230 , 255 ),
805
+ 'purple' : KatexSpanColor (128 , 0 , 128 , 255 ),
806
+ 'rebeccapurple' : KatexSpanColor (102 , 51 , 153 , 255 ),
807
+ 'red' : KatexSpanColor (255 , 0 , 0 , 255 ),
808
+ 'rosybrown' : KatexSpanColor (188 , 143 , 143 , 255 ),
809
+ 'royalblue' : KatexSpanColor (65 , 105 , 225 , 255 ),
810
+ 'saddlebrown' : KatexSpanColor (139 , 69 , 19 , 255 ),
811
+ 'salmon' : KatexSpanColor (250 , 128 , 114 , 255 ),
812
+ 'sandybrown' : KatexSpanColor (244 , 164 , 96 , 255 ),
813
+ 'seagreen' : KatexSpanColor (46 , 139 , 87 , 255 ),
814
+ 'seashell' : KatexSpanColor (255 , 245 , 238 , 255 ),
815
+ 'sienna' : KatexSpanColor (160 , 82 , 45 , 255 ),
816
+ 'silver' : KatexSpanColor (192 , 192 , 192 , 255 ),
817
+ 'skyblue' : KatexSpanColor (135 , 206 , 235 , 255 ),
818
+ 'slateblue' : KatexSpanColor (106 , 90 , 205 , 255 ),
819
+ 'slategray' : KatexSpanColor (112 , 128 , 144 , 255 ),
820
+ 'slategrey' : KatexSpanColor (112 , 128 , 144 , 255 ),
821
+ 'snow' : KatexSpanColor (255 , 250 , 250 , 255 ),
822
+ 'springgreen' : KatexSpanColor (0 , 255 , 127 , 255 ),
823
+ 'steelblue' : KatexSpanColor (70 , 130 , 180 , 255 ),
824
+ 'tan' : KatexSpanColor (210 , 180 , 140 , 255 ),
825
+ 'teal' : KatexSpanColor (0 , 128 , 128 , 255 ),
826
+ 'thistle' : KatexSpanColor (216 , 191 , 216 , 255 ),
827
+ 'tomato' : KatexSpanColor (255 , 99 , 71 , 255 ),
828
+ 'turquoise' : KatexSpanColor (64 , 224 , 208 , 255 ),
829
+ 'violet' : KatexSpanColor (238 , 130 , 238 , 255 ),
830
+ 'wheat' : KatexSpanColor (245 , 222 , 179 , 255 ),
831
+ 'white' : KatexSpanColor (255 , 255 , 255 , 255 ),
832
+ 'whitesmoke' : KatexSpanColor (245 , 245 , 245 , 255 ),
833
+ 'yellow' : KatexSpanColor (255 , 255 , 0 , 255 ),
834
+ 'yellowgreen' : KatexSpanColor (154 , 205 , 50 , 255 ),
835
+ };
836
+
596
837
class _KatexHtmlParseError extends Error {
597
838
final String ? message;
598
839
0 commit comments