Skip to content

Commit e37129c

Browse files
content: Handle multiple class names in code block nodes
Fixes: #933
1 parent ce3302e commit e37129c

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

lib/model/content.dart

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,17 +1023,28 @@ class _ZulipContentParser {
10231023
span = CodeBlockSpanNode(text: text, type: CodeBlockSpanType.text);
10241024

10251025
case dom.Element(localName: 'span', :final text, :final className):
1026-
final CodeBlockSpanType type = codeBlockSpanTypeFromClassName(className);
1027-
switch (type) {
1028-
case CodeBlockSpanType.unknown:
1026+
// The general form for Pygments nodes with multiple classes observed
1027+
// are, that the first class is the standard token class and trailing
1028+
// tokens are non-standard tokens. Zulip web client only styles the
1029+
// standard tokens classes. Same is done here, only standard token
1030+
// class names are emitted.
1031+
// See: https://github.com/zulip/zulip-flutter/issues/933
1032+
final spanType =
1033+
className
1034+
.split(' ')
1035+
.map(codeBlockSpanTypeFromClassName)
1036+
.firstWhereOrNull((e) => e != CodeBlockSpanType.unknown);
1037+
1038+
switch (spanType) {
1039+
case null:
10291040
// TODO(#194): Show these as un-syntax-highlighted code, in production.
10301041
return UnimplementedBlockContentNode(htmlNode: divElement);
10311042
case CodeBlockSpanType.highlightedLines:
10321043
// TODO: Implement nesting in CodeBlockSpanNode to support hierarchically
10331044
// inherited styles for `span.hll` nodes.
10341045
return UnimplementedBlockContentNode(htmlNode: divElement);
10351046
default:
1036-
span = CodeBlockSpanNode(text: text, type: type);
1047+
span = CodeBlockSpanNode(text: text, type: spanType);
10371048
}
10381049

10391050
default:

test/model/content_test.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,23 @@ class ContentExample {
395395
ParagraphNode(links: null, nodes: [TextNode("some content")]),
396396
]);
397397

398+
static const codeBlockNodesWithMultipleClasses = ContentExample(
399+
'code block nodes with multiple class names',
400+
'```yaml\n- item\n```',
401+
expectedText: '- item',
402+
// https://chat.zulip.org/#narrow/channel/7-test-here/topic/Greg/near/1949014
403+
'<div class="codehilite" data-code-language="YAML">'
404+
'<pre><span></span><code><span class="p p-Indicator">-</span>'
405+
'<span class="w"> </span>'
406+
'<span class="l l-Scalar l-Scalar-Plain">item</span>\n'
407+
'</code></pre></div>', [
408+
CodeBlockNode([
409+
CodeBlockSpanNode(text: "-", type: CodeBlockSpanType.punctuation),
410+
CodeBlockSpanNode(text: " ", type: CodeBlockSpanType.whitespace),
411+
CodeBlockSpanNode(text: "item", type: CodeBlockSpanType.literal)
412+
]),
413+
]);
414+
398415
static final mathInline = ContentExample.inline(
399416
'inline math',
400417
r"$$ \lambda $$",
@@ -1164,6 +1181,7 @@ void main() {
11641181
testParseExample(ContentExample.codeBlockWithHighlightedLines);
11651182
testParseExample(ContentExample.codeBlockWithUnknownSpanType);
11661183
testParseExample(ContentExample.codeBlockFollowedByMultipleLineBreaks);
1184+
testParseExample(ContentExample.codeBlockNodesWithMultipleClasses);
11671185

11681186
testParseExample(ContentExample.mathBlock);
11691187
testParseExample(ContentExample.mathBlockInQuote);

test/widgets/content_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ void main() {
480480
testContentSmoke(ContentExample.codeBlockPlain);
481481
testContentSmoke(ContentExample.codeBlockHighlightedShort);
482482
testContentSmoke(ContentExample.codeBlockHighlightedMultiline);
483+
testContentSmoke(ContentExample.codeBlockNodesWithMultipleClasses);
483484

484485
testFontWeight('syntax highlighting: non-bold span',
485486
expectedWght: 400,

0 commit comments

Comments
 (0)