@@ -1451,6 +1451,60 @@ class _ZulipContentParser {
1451
1451
return tableNode ?? UnimplementedBlockContentNode (htmlNode: tableElement);
1452
1452
}
1453
1453
1454
+ List <BlockContentNode > parseMathBlocks (dom.Element element) {
1455
+ assert (_debugParserContext == _ParserContext .block);
1456
+ assert (element.localName == 'p' );
1457
+ assert ((() {
1458
+ final first = element.nodes.first;
1459
+ return first is dom.Element
1460
+ && first.localName == 'span'
1461
+ && first.className == 'katex-display' ;
1462
+ })());
1463
+ final debugHtmlNode = kDebugMode ? element : null ;
1464
+
1465
+ final blocks = < BlockContentNode > [];
1466
+
1467
+ // The case with the `<br>\n` can happen when at the end of a quote;
1468
+ // it seems like a glitch in the server's Markdown processing,
1469
+ // so hopefully there just aren't any further such glitches.
1470
+ bool hasTrailingBreakNewline = false ;
1471
+ if (element.nodes
1472
+ case [..., dom.Element (localName: 'br' ), dom.Text (text: '\n ' )]
1473
+ ) {
1474
+ hasTrailingBreakNewline = true ;
1475
+ }
1476
+
1477
+ final length = hasTrailingBreakNewline
1478
+ ? element.nodes.length - 2
1479
+ : element.nodes.length;
1480
+ for (var i = 0 ; i < length; i++ ) {
1481
+ final child = element.nodes[i];
1482
+
1483
+ // If there are multiple <span class="katex-display"> nodes in a <p>
1484
+ // each node is interleaved by '\n\n'. Whitespaces are ignored in HTML
1485
+ // on web but each node has `display: block`, which renders each node
1486
+ // on a newline. So do the same here.
1487
+ if (child case dom.Text (text: '\n\n ' )) continue ;
1488
+
1489
+ if (child is ! dom.Element ) {
1490
+ blocks.add (UnimplementedBlockContentNode (htmlNode: child));
1491
+ continue ;
1492
+ }
1493
+ if (child.className != 'katex-display' ) {
1494
+ blocks.add (UnimplementedBlockContentNode (htmlNode: child));
1495
+ continue ;
1496
+ }
1497
+
1498
+ final texSource = parseMath (child, block: true );
1499
+ if (texSource == null ) {
1500
+ blocks.add (UnimplementedBlockContentNode (htmlNode: child));
1501
+ continue ;
1502
+ }
1503
+ blocks.add (MathBlockNode (texSource: texSource, debugHtmlNode: debugHtmlNode));
1504
+ }
1505
+ return blocks;
1506
+ }
1507
+
1454
1508
BlockContentNode parseBlockContent (dom.Node node) {
1455
1509
assert (_debugParserContext == _ParserContext .block);
1456
1510
final debugHtmlNode = kDebugMode ? node : null ;
@@ -1470,23 +1524,6 @@ class _ZulipContentParser {
1470
1524
}
1471
1525
1472
1526
if (localName == 'p' && className.isEmpty) {
1473
- // Oddly, the way a math block gets encoded in Zulip HTML is inside a <p>.
1474
- if (element.nodes case [dom.Element (localName: 'span' ) && var child, ...]) {
1475
- if (child.className == 'katex-display' ) {
1476
- if (element.nodes case [_]
1477
- || [_, dom.Element (localName: 'br' ),
1478
- dom.Text (text: "\n " )]) {
1479
- // This might be too specific; we'll find out when we do #190.
1480
- // The case with the `<br>\n` can happen when at the end of a quote;
1481
- // it seems like a glitch in the server's Markdown processing,
1482
- // so hopefully there just aren't any further such glitches.
1483
- final texSource = parseMath (child, block: true );
1484
- if (texSource == null ) return UnimplementedBlockContentNode (htmlNode: node);
1485
- return MathBlockNode (texSource: texSource, debugHtmlNode: debugHtmlNode);
1486
- }
1487
- }
1488
- }
1489
-
1490
1527
final parsed = parseBlockInline (element.nodes);
1491
1528
return ParagraphNode (debugHtmlNode: debugHtmlNode,
1492
1529
links: parsed.links,
@@ -1638,6 +1675,16 @@ class _ZulipContentParser {
1638
1675
continue ;
1639
1676
}
1640
1677
1678
+ // Oddly, the way math blocks get encoded in Zulip HTML is inside a <p>.
1679
+ // And there can be multiple math blocks inside the paragraph node, so
1680
+ // handle it explicitly here.
1681
+ if (node case
1682
+ dom.Element (localName: 'p' , nodes: [
1683
+ dom.Element (localName: 'span' , className: 'katex-display' ), ...])) {
1684
+ result.addAll (parseMathBlocks (node));
1685
+ continue ;
1686
+ }
1687
+
1641
1688
final block = parseBlockContent (node);
1642
1689
if (block is ImageNode ) {
1643
1690
imageNodes.add (block);
0 commit comments