|
| 1 | +import 'package:collection/collection.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'; |
@@ -167,16 +168,42 @@ class _KatexParser { |
167 | 168 | } |
168 | 169 |
|
169 | 170 | List<KatexNode> _parseChildSpans(List<dom.Node> nodes) { |
170 | | - return List.unmodifiable(nodes.map((node) { |
171 | | - if (node case dom.Element(localName: 'span')) { |
172 | | - return _parseSpan(node); |
173 | | - } else { |
| 171 | + var resultSpans = QueueList<KatexNode>(); |
| 172 | + for (final node in nodes.reversed) { |
| 173 | + if (node is! dom.Element || node.localName != 'span') { |
174 | 174 | throw _KatexHtmlParseError( |
175 | 175 | node is dom.Element |
176 | 176 | ? 'unsupported html node: ${node.localName}' |
177 | 177 | : 'unsupported html node'); |
178 | 178 | } |
179 | | - })); |
| 179 | + |
| 180 | + final span = _parseSpan(node); |
| 181 | + |
| 182 | + if (span is KatexSpanNode) { |
| 183 | + final marginRightEm = span.styles.marginRightEm; |
| 184 | + if (marginRightEm != null && marginRightEm.isNegative) { |
| 185 | + final previousSpans = resultSpans; |
| 186 | + resultSpans = QueueList<KatexNode>(); |
| 187 | + resultSpans.addFirst(KatexNegativeMarginNode( |
| 188 | + leftOffsetEm: marginRightEm, |
| 189 | + nodes: previousSpans)); |
| 190 | + } |
| 191 | + } |
| 192 | + |
| 193 | + resultSpans.addFirst(span); |
| 194 | + |
| 195 | + if (span is KatexSpanNode) { |
| 196 | + final marginLeftEm = span.styles.marginLeftEm; |
| 197 | + if (marginLeftEm != null && marginLeftEm.isNegative) { |
| 198 | + final previousSpans = resultSpans; |
| 199 | + resultSpans = QueueList<KatexNode>(); |
| 200 | + resultSpans.addFirst(KatexNegativeMarginNode( |
| 201 | + leftOffsetEm: marginLeftEm, |
| 202 | + nodes: previousSpans)); |
| 203 | + } |
| 204 | + } |
| 205 | + } |
| 206 | + return resultSpans; |
180 | 207 | } |
181 | 208 |
|
182 | 209 | static final _resetSizeClassRegExp = RegExp(r'^reset-size(\d\d?)$'); |
@@ -266,13 +293,31 @@ class _KatexParser { |
266 | 293 | final pstrutStyles = _parseSpanInlineStyles(pstrutSpan)!; |
267 | 294 | final pstrutHeight = pstrutStyles.heightEm ?? 0; |
268 | 295 |
|
| 296 | + KatexSpanNode innerSpanNode = KatexSpanNode( |
| 297 | + styles: styles, |
| 298 | + text: null, |
| 299 | + nodes: _parseChildSpans(otherSpans)); |
| 300 | + |
| 301 | + final marginRightEm = styles.marginRightEm; |
| 302 | + final marginLeftEm = styles.marginLeftEm; |
| 303 | + if (marginRightEm != null && marginRightEm.isNegative) { |
| 304 | + throw _KatexHtmlParseError(); |
| 305 | + } |
| 306 | + if (marginLeftEm != null && marginLeftEm.isNegative) { |
| 307 | + innerSpanNode = KatexSpanNode( |
| 308 | + styles: KatexSpanStyles(), |
| 309 | + text: null, |
| 310 | + nodes: [ |
| 311 | + KatexNegativeMarginNode( |
| 312 | + leftOffsetEm: marginLeftEm, |
| 313 | + nodes: [innerSpanNode]), |
| 314 | + ]); |
| 315 | + } |
| 316 | + |
269 | 317 | rows.add(KatexVlistRowNode( |
270 | 318 | verticalOffsetEm: topEm + pstrutHeight, |
271 | 319 | debugHtmlNode: kDebugMode ? innerSpan : null, |
272 | | - node: KatexSpanNode( |
273 | | - styles: styles, |
274 | | - text: null, |
275 | | - nodes: _parseChildSpans(otherSpans)))); |
| 320 | + node: innerSpanNode)); |
276 | 321 | } else { |
277 | 322 | throw _KatexHtmlParseError(); |
278 | 323 | } |
@@ -605,17 +650,11 @@ class _KatexParser { |
605 | 650 |
|
606 | 651 | case 'margin-right': |
607 | 652 | marginRightEm = _getEm(expression); |
608 | | - if (marginRightEm != null) { |
609 | | - if (marginRightEm < 0) throw _KatexHtmlParseError(); |
610 | | - continue; |
611 | | - } |
| 653 | + if (marginRightEm != null) continue; |
612 | 654 |
|
613 | 655 | case 'margin-left': |
614 | 656 | marginLeftEm = _getEm(expression); |
615 | | - if (marginLeftEm != null) { |
616 | | - if (marginLeftEm < 0) throw _KatexHtmlParseError(); |
617 | | - continue; |
618 | | - } |
| 657 | + if (marginLeftEm != null) continue; |
619 | 658 | } |
620 | 659 |
|
621 | 660 | // TODO handle more CSS properties |
|
0 commit comments