Skip to content

Commit a8a6df1

Browse files
committed
feat: mermaid class-relation arrows — color <|--, --|>, ..|> as single operator tokens (| joins the run only adjacent to the arrow, so edge labels still split)
1 parent 254630b commit a8a6df1

1 file changed

Lines changed: 30 additions & 3 deletions

File tree

src/tokenize.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,22 @@ pub fn highlight_mermaid(src: &str) -> Vec<HighlightSpan> {
364364
// arrowhead (`--x`, `--o`) when it's not the start of an identifier.
365365
if is_arrow_char(c) {
366366
let start = i;
367-
while i < b.len() && is_arrow_char(b[i]) {
368-
i += 1;
367+
// A `|` joins the run only as part of a class relation edge — right after a `<`
368+
// (`<|--`, `<|..`) or right before `>`/`-`/`.`/`=` (`--|>`, `..|>`). A normal edge
369+
// label `-->|yes|` has the `|` followed by label text, so it stays a separate token.
370+
while i < b.len() {
371+
let relation_pipe = b[i] == b'|'
372+
&& ((i > start && b[i - 1] == b'<')
373+
|| (i + 1 < b.len() && matches!(b[i + 1], b'>' | b'-' | b'.' | b'=')));
374+
if is_arrow_char(b[i]) || relation_pipe {
375+
i += 1;
376+
} else {
377+
break;
378+
}
369379
}
370-
let connector = b[start..i].iter().any(|&x| matches!(x, b'-' | b'=' | b'>'));
380+
let connector = b[start..i]
381+
.iter()
382+
.any(|&x| matches!(x, b'-' | b'=' | b'>' | b'.'));
371383
if connector
372384
&& i < b.len()
373385
&& matches!(b[i], b'x' | b'o')
@@ -576,6 +588,21 @@ mod tests {
576588
assert_eq!(cat_of(&c, "<<fork>>"), Some("type"));
577589
}
578590

591+
#[test]
592+
fn mermaid_class_relation_arrows() {
593+
// Class relations with `|` color as one operator token...
594+
let src = "classDiagram\n A <|-- B\n C --|> D\n E ..|> F";
595+
let c = cats(src, &highlight_mermaid(src));
596+
assert_eq!(cat_of(&c, "<|--"), Some("operator"));
597+
assert_eq!(cat_of(&c, "--|>"), Some("operator"));
598+
assert_eq!(cat_of(&c, "..|>"), Some("operator"));
599+
// ...but a flowchart edge label keeps the arrow and label separate.
600+
let flow = "flowchart LR\n A -->|yes| B";
601+
let c = cats(flow, &highlight_mermaid(flow));
602+
assert_eq!(cat_of(&c, "-->"), Some("operator"));
603+
assert_eq!(cat_of(&c, "|yes|"), Some("string"));
604+
}
605+
579606
#[test]
580607
fn latex_categories() {
581608
let src = "\\frac{1}{2} + x^2 = \\alpha \\\\ \\begin{matrix} % c";

0 commit comments

Comments
 (0)