Skip to content

Commit 1c4ca34

Browse files
fix: escape quotes in Mermaid labels and fix misleading comment
- Add escapeLabel() to replace double quotes with #quot; in all Mermaid labels (node shapes, file basenames, directory names, subgraph titles) - Fix misleading comment: "picking the most specific kind" → "keeping the first encountered kind" Impact: 3 functions changed, 2 affected
1 parent ae301c0 commit 1c4ca34

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

src/export.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,24 +125,30 @@ export function exportDOT(db, opts = {}) {
125125
return lines.join('\n');
126126
}
127127

128+
/** Escape double quotes for Mermaid labels. */
129+
function escapeLabel(label) {
130+
return label.replace(/"/g, '#quot;');
131+
}
132+
128133
/** Map node kind to Mermaid shape wrapper. */
129134
function mermaidShape(kind, label) {
135+
const escaped = escapeLabel(label);
130136
switch (kind) {
131137
case 'function':
132138
case 'method':
133-
return `(["${label}"])`;
139+
return `(["${escaped}"])`;
134140
case 'class':
135141
case 'interface':
136142
case 'type':
137143
case 'struct':
138144
case 'enum':
139145
case 'trait':
140146
case 'record':
141-
return `{{"${label}"}}`;
147+
return `{{"${escaped}"}}`;
142148
case 'module':
143-
return `[["${label}"]]`;
149+
return `[["${escaped}"]]`;
144150
default:
145-
return `["${label}"]`;
151+
return `["${escaped}"]`;
146152
}
147153
}
148154

@@ -222,15 +228,15 @@ export function exportMermaid(db, opts = {}) {
222228
// Emit subgraphs
223229
for (const [dir, files] of [...dirs].sort((a, b) => a[0].localeCompare(b[0]))) {
224230
const sgId = dir.replace(/[^a-zA-Z0-9]/g, '_');
225-
lines.push(` subgraph ${sgId}["${dir}"]`);
231+
lines.push(` subgraph ${sgId}["${escapeLabel(dir)}"]`);
226232
for (const f of files) {
227233
const nId = nodeId(f);
228-
lines.push(` ${nId}["${path.basename(f)}"]`);
234+
lines.push(` ${nId}["${escapeLabel(path.basename(f))}"]`);
229235
}
230236
lines.push(' end');
231237
}
232238

233-
// Deduplicate edges per source-target pair, picking the most specific kind
239+
// Deduplicate edges per source-target pair, keeping the first encountered kind
234240
const edgeMap = new Map();
235241
for (const { source, target, edge_kind } of edges) {
236242
const key = `${source}|${target}`;
@@ -280,7 +286,7 @@ export function exportMermaid(db, opts = {}) {
280286
// Emit subgraphs grouped by file
281287
for (const [file, nodes] of [...fileNodes].sort((a, b) => a[0].localeCompare(b[0]))) {
282288
const sgId = file.replace(/[^a-zA-Z0-9]/g, '_');
283-
lines.push(` subgraph ${sgId}["${file}"]`);
289+
lines.push(` subgraph ${sgId}["${escapeLabel(file)}"]`);
284290
for (const [key, name] of nodes) {
285291
const kind = nodeKinds.get(key);
286292
lines.push(` ${nodeId(key)}${mermaidShape(kind, name)}`);

0 commit comments

Comments
 (0)