@@ -9,10 +9,40 @@ import 'binding.dart';
9
9
import 'content.dart' ;
10
10
import 'settings.dart' ;
11
11
12
+ /// The failure reason in case the KaTeX parser encountered a
13
+ /// `_KatexHtmlParseError` exception.
14
+ ///
15
+ /// Generally this means that parser encountered an unexpected HTML structure,
16
+ /// an unsupported HTML node, or an unexpected inline CSS style or CSS class on
17
+ /// a specific node.
18
+ class KatexParserHardFailReason {
19
+ const KatexParserHardFailReason ({
20
+ required this .error,
21
+ required this .stackTrace,
22
+ });
23
+
24
+ final String error;
25
+ final StackTrace stackTrace;
26
+ }
27
+
28
+ /// The failure reason in case the KaTeX parser found an unsupported
29
+ /// CSS class or unsupported inline CSS style property.
30
+ class KatexParserSoftFailReason {
31
+ const KatexParserSoftFailReason ({
32
+ this .unsupportedCssClasses = const [],
33
+ this .unsupportedInlineCssProperties = const [],
34
+ });
35
+
36
+ final List <String > unsupportedCssClasses;
37
+ final List <String > unsupportedInlineCssProperties;
38
+ }
39
+
12
40
class MathParserResult {
13
41
const MathParserResult ({
14
42
required this .texSource,
15
43
required this .nodes,
44
+ this .hardFailReason,
45
+ this .softFailReason,
16
46
});
17
47
18
48
final String texSource;
@@ -23,6 +53,9 @@ class MathParserResult {
23
53
/// CSS style, indicating that the widget should render the [texSource] as a
24
54
/// fallback instead.
25
55
final List <KatexNode >? nodes;
56
+
57
+ final KatexParserHardFailReason ? hardFailReason;
58
+ final KatexParserSoftFailReason ? softFailReason;
26
59
}
27
60
28
61
/// Parses the HTML spans containing KaTeX HTML tree.
@@ -88,21 +121,33 @@ MathParserResult? parseMath(dom.Element element, { required bool block }) {
88
121
final flagForceRenderKatex =
89
122
globalSettings.getBool (BoolGlobalSetting .forceRenderKatex);
90
123
124
+ KatexParserHardFailReason ? hardFailReason;
125
+ KatexParserSoftFailReason ? softFailReason;
91
126
List <KatexNode >? nodes;
92
127
if (flagRenderKatex) {
93
128
final parser = _KatexParser ();
94
129
try {
95
130
nodes = parser.parseKatexHtml (katexHtmlElement);
96
131
} on _KatexHtmlParseError catch (e, st) {
97
132
assert (debugLog ('$e \n $st ' ));
133
+ hardFailReason = KatexParserHardFailReason (
134
+ error: e.message ?? 'unknown' ,
135
+ stackTrace: st);
98
136
}
99
137
100
138
if (parser.hasError && ! flagForceRenderKatex) {
101
139
nodes = null ;
140
+ softFailReason = KatexParserSoftFailReason (
141
+ unsupportedCssClasses: parser.unsupportedCssClasses,
142
+ unsupportedInlineCssProperties: parser.unsupportedInlineCssProperties);
102
143
}
103
144
}
104
145
105
- return MathParserResult (nodes: nodes, texSource: texSource);
146
+ return MathParserResult (
147
+ nodes: nodes,
148
+ texSource: texSource,
149
+ hardFailReason: hardFailReason,
150
+ softFailReason: softFailReason);
106
151
} else {
107
152
return null ;
108
153
}
@@ -112,6 +157,9 @@ class _KatexParser {
112
157
bool get hasError => _hasError;
113
158
bool _hasError = false ;
114
159
160
+ final unsupportedCssClasses = < String > [];
161
+ final unsupportedInlineCssProperties = < String > [];
162
+
115
163
List <KatexNode > parseKatexHtml (dom.Element element) {
116
164
assert (element.localName == 'span' );
117
165
assert (element.className == 'katex-html' );
@@ -122,7 +170,10 @@ class _KatexParser {
122
170
var resultSpans = QueueList <KatexNode >();
123
171
for (final node in nodes.reversed) {
124
172
if (node is ! dom.Element || node.localName != 'span' ) {
125
- throw _KatexHtmlParseError ();
173
+ throw _KatexHtmlParseError (
174
+ node is dom.Element
175
+ ? 'unsupported html node: ${node .localName }'
176
+ : 'unsupported html node' );
126
177
}
127
178
128
179
final span = _parseSpan (node);
@@ -518,6 +569,7 @@ class _KatexParser {
518
569
519
570
default :
520
571
assert (debugLog ('KaTeX: Unsupported CSS class: $spanClass ' ));
572
+ unsupportedCssClasses.add (spanClass);
521
573
_hasError = true ;
522
574
}
523
575
}
@@ -591,6 +643,7 @@ class _KatexParser {
591
643
// TODO handle more CSS properties
592
644
assert (debugLog ('KaTeX: Unsupported CSS expression:'
593
645
' ${expression .toDebugString ()}' ));
646
+ unsupportedInlineCssProperties.add (property);
594
647
_hasError = true ;
595
648
} else {
596
649
throw _KatexHtmlParseError ();
0 commit comments