diff --git a/src/trackChangesModel.ts b/src/trackChangesModel.ts index 1eb1765..ffb44bc 100644 --- a/src/trackChangesModel.ts +++ b/src/trackChangesModel.ts @@ -10,6 +10,7 @@ */ import MarkdownIt from "markdown-it"; import { diffArrays, diffWords } from "diff"; +import { diffMermaid } from "./mermaidDiff"; export type BlockType = "prose" | "code" | "mermaid"; @@ -204,6 +205,24 @@ md.renderer.rules.fence = (tokens, idx, options, env, self) => { return defaultFence(tokens, idx, options, env, self); }; +/** Inner source of a ```mermaid fence (drops the fence lines), or null. */ +function mermaidFenceBody(raw: string): string | null { + const lines = raw.split(/\r?\n/); + const open = lines[0]?.match(/^(\s*)(`{3,}|~{3,})\s*(\w+)?/); + if (!open || open[3]?.toLowerCase() !== "mermaid") return null; + const body = lines.slice(1); + if (body.length && /^(\s*)(`{3,}|~{3,})/.test(body[body.length - 1])) body.pop(); + return body.join("\n"); +} + +/** F7.1 (#22): legend shown beneath an intra-diagram-diffed mermaid block. */ +const MERMAID_LEGEND = + '
for a mermaid fence + a changed badge', () => {
+ it('emits for a changed flowchart, augmented intra-diagram (#22)', () => {
const html = renderTrackChanges(
"```mermaid\nflowchart LR\n a-->b\n```\n",
"```mermaid\nflowchart LR\n a-->c\n```\n",
);
expect(html).toContain('');
- expect(html).toContain("a-->c"); // current source, escaped
- expect(html).toContain("cw-badge");
+ expect(html).toContain("a-->c"); // current source preserved as prefix, escaped
+ // a changed flowchart is now diffed in place (INV-29): styling, not a whole-block badge
+ expect(html).toContain("classDef cwAdded");
+ expect(html).not.toContain('changed');
});
it("unchanged doc renders with no marks", () => {
@@ -232,3 +234,33 @@ describe("renderAuthorship", () => {
expect(renderAuthorship(text, spans)).toBe(renderAuthorship(text, spans));
});
});
+
+import { renderTrackChanges as rtc2 } from "../src/trackChangesModel";
+
+describe("renderTrackChanges — intra-diagram mermaid (#22)", () => {
+ it("augments a changed flowchart with styling directives (INV-29)", () => {
+ const base = "```mermaid\nflowchart LR\n A-->B\n```\n";
+ const cur = "```mermaid\nflowchart LR\n A-->B\n B-->C\n```\n";
+ const html = rtc2(base, cur);
+ expect(html).toContain("classDef cwAdded");
+ expect(html).toMatch(/class\s+C\s+cwAdded/);
+ expect(html).toContain('class="cw-mermaid-legend"');
+ // no single whole-block "changed" badge when we augmented
+ expect(html).not.toContain('changed');
+ });
+
+ it("augments a changed sequence diagram", () => {
+ const base = "```mermaid\nsequenceDiagram\n A->>B: hi\n```\n";
+ const cur = "```mermaid\nsequenceDiagram\n A->>B: hi\n B->>C: on\n```\n";
+ const html = rtc2(base, cur);
+ expect(html).toContain("rect rgb(46, 160, 67)");
+ });
+
+ it("falls back to the v1 badge for an unsupported diagram type (INV-30)", () => {
+ const base = "```mermaid\nclassDiagram\n class A\n```\n";
+ const cur = "```mermaid\nclassDiagram\n class B\n```\n";
+ const html = rtc2(base, cur);
+ expect(html).toContain('changed');
+ expect(html).not.toContain("classDef cwAdded");
+ });
+});