@@ -9,10 +9,40 @@ import 'binding.dart';
99import 'content.dart' ;
1010import 'settings.dart' ;
1111
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+
1240class MathParserResult {
1341 const MathParserResult ({
1442 required this .texSource,
1543 required this .nodes,
44+ this .hardFailReason,
45+ this .softFailReason,
1646 });
1747
1848 final String texSource;
@@ -23,6 +53,9 @@ class MathParserResult {
2353 /// CSS style, indicating that the widget should render the [texSource] as a
2454 /// fallback instead.
2555 final List <KatexNode >? nodes;
56+
57+ final KatexParserHardFailReason ? hardFailReason;
58+ final KatexParserSoftFailReason ? softFailReason;
2659}
2760
2861/// Parses the HTML spans containing KaTeX HTML tree.
@@ -88,21 +121,33 @@ MathParserResult? parseMath(dom.Element element, { required bool block }) {
88121 final flagForceRenderKatex =
89122 globalSettings.getBool (BoolGlobalSetting .forceRenderKatex);
90123
124+ KatexParserHardFailReason ? hardFailReason;
125+ KatexParserSoftFailReason ? softFailReason;
91126 List <KatexNode >? nodes;
92127 if (flagRenderKatex) {
93128 final parser = _KatexParser ();
94129 try {
95130 nodes = parser.parseKatexHtml (katexHtmlElement);
96131 } on _KatexHtmlParseError catch (e, st) {
97132 assert (debugLog ('$e \n $st ' ));
133+ hardFailReason = KatexParserHardFailReason (
134+ error: e.message ?? 'unknown' ,
135+ stackTrace: st);
98136 }
99137
100138 if (parser.hasError && ! flagForceRenderKatex) {
101139 nodes = null ;
140+ softFailReason = KatexParserSoftFailReason (
141+ unsupportedCssClasses: parser.unsupportedCssClasses,
142+ unsupportedInlineCssProperties: parser.unsupportedInlineCssProperties);
102143 }
103144 }
104145
105- return MathParserResult (nodes: nodes, texSource: texSource);
146+ return MathParserResult (
147+ nodes: nodes,
148+ texSource: texSource,
149+ hardFailReason: hardFailReason,
150+ softFailReason: softFailReason);
106151 } else {
107152 return null ;
108153 }
@@ -112,6 +157,9 @@ class _KatexParser {
112157 bool get hasError => _hasError;
113158 bool _hasError = false ;
114159
160+ final unsupportedCssClasses = < String > [];
161+ final unsupportedInlineCssProperties = < String > [];
162+
115163 List <KatexNode > parseKatexHtml (dom.Element element) {
116164 assert (element.localName == 'span' );
117165 assert (element.className == 'katex-html' );
@@ -123,7 +171,10 @@ class _KatexParser {
123171 if (node case dom.Element (localName: 'span' )) {
124172 return _parseSpan (node);
125173 } else {
126- throw _KatexHtmlParseError ();
174+ throw _KatexHtmlParseError (
175+ node is dom.Element
176+ ? 'unsupported html node: ${node .localName }'
177+ : 'unsupported html node' );
127178 }
128179 }));
129180 }
@@ -374,6 +425,7 @@ class _KatexParser {
374425
375426 default :
376427 assert (debugLog ('KaTeX: Unsupported CSS class: $spanClass ' ));
428+ unsupportedCssClasses.add (spanClass);
377429 _hasError = true ;
378430 }
379431 }
@@ -427,6 +479,7 @@ class _KatexParser {
427479 // TODO handle more CSS properties
428480 assert (debugLog ('KaTeX: Unsupported CSS expression:'
429481 ' ${expression .toDebugString ()}' ));
482+ unsupportedInlineCssProperties.add (property);
430483 _hasError = true ;
431484 } else {
432485 throw _KatexHtmlParseError ();
0 commit comments