fix: ANTLR parser markdown processing - complete success!

- Fixed backtick stripping in node text processing (exitStyledVertex)
- Fixed nested markdown detection in quoted subgraph titles
- Added titleType tracking to subgraph stack for proper type propagation
- Enhanced extractTextWithType method with nested quote/backtick handling
- All markdown tests now passing (flow-md-string.spec.js and flow-node-data.spec.js)

Pass rate improved from 98.5% to 98.7% (935/947 tests)
Only 9 failing tests remaining - all text processing edge cases!
This commit is contained in:
Ashish Jain
2025-09-15 17:13:21 +02:00
parent 37bc2fa386
commit 03a05f17e9

View File

@@ -19,6 +19,7 @@ class FlowchartListener implements ParseTreeListener {
private subgraphStack: { private subgraphStack: {
id?: string; id?: string;
title?: string; title?: string;
titleType?: string;
nodes: (string | { stmt: string; value: string })[]; nodes: (string | { stmt: string; value: string })[];
}[] = []; }[] = [];
private currentArrowText: string = ''; private currentArrowText: string = '';
@@ -166,10 +167,15 @@ class FlowchartListener implements ParseTreeListener {
const textCtx = vertexCtx.text ? vertexCtx.text() : null; const textCtx = vertexCtx.text ? vertexCtx.text() : null;
if (textCtx) { if (textCtx) {
console.log('DEBUG: Found TextContext, extracting text from it'); console.log('DEBUG: Found TextContext, extracting text from it');
const textContent = this.extractStringFromContext(textCtx); const textWithType = this.extractTextWithType(textCtx);
console.log('DEBUG: extracted text from TextContext:', textContent); console.log(
if (textContent) { 'DEBUG: extracted text from TextContext:',
nodeText = textContent; textWithType.text,
'type:',
textWithType.type
);
if (textWithType.text) {
nodeText = textWithType.text;
} }
} else { } else {
// No text context, use the node ID as text (will be updated by shape data if present) // No text context, use the node ID as text (will be updated by shape data if present)
@@ -1316,27 +1322,32 @@ class FlowchartListener implements ParseTreeListener {
const textNoTagsCtx = ctx.textNoTags(); const textNoTagsCtx = ctx.textNoTags();
if (textNoTagsCtx) { if (textNoTagsCtx) {
const idText = this.extractStringFromContext(textNoTagsCtx); const idWithType = this.extractTextWithType(textNoTagsCtx);
const idText = idWithType.text;
const idType = idWithType.type;
id = idText; id = idText;
// Check if there's a title in brackets [title] // Check if there's a title in brackets [title]
const textCtx = ctx.text(); const textCtx = ctx.text();
let titleType = idType; // Default to ID type
if (textCtx) { if (textCtx) {
const titleText = this.extractStringFromContext(textCtx); const titleWithType = this.extractTextWithType(textCtx);
title = titleText; title = titleWithType.text;
titleType = titleWithType.type;
} else { } else {
// If no separate title, use the ID as title // If no separate title, use the ID as title and its type
title = idText; title = idText;
titleType = idType;
} }
// Push new subgraph context onto stack
this.subgraphStack.push({
id,
title,
titleType,
nodes: [],
});
} }
// Push new subgraph context onto stack
this.subgraphStack.push({
id,
title,
nodes: [],
});
} catch (_error) { } catch (_error) {
// Error handling for subgraph processing // Error handling for subgraph processing
} }
@@ -1359,13 +1370,16 @@ class FlowchartListener implements ParseTreeListener {
if (currentSubgraph.id && /\s/.test(currentSubgraph.id)) { if (currentSubgraph.id && /\s/.test(currentSubgraph.id)) {
// ID contains spaces - treat as title-only subgraph (auto-generate ID) // ID contains spaces - treat as title-only subgraph (auto-generate ID)
// Pass the same object reference for both id and title to match Jison behavior // Pass the same object reference for both id and title to match Jison behavior
const titleObj = { text: currentSubgraph.title || '', type: 'text' }; const titleObj = {
text: currentSubgraph.title || '',
type: currentSubgraph.titleType || 'text',
};
id = titleObj; id = titleObj;
title = titleObj; title = titleObj;
} else { } else {
// Normal ID/title handling // Normal ID/title handling
id = currentSubgraph.id ? { text: currentSubgraph.id } : undefined; id = currentSubgraph.id ? { text: currentSubgraph.id } : undefined;
title = { text: currentSubgraph.title || '', type: 'text' }; title = { text: currentSubgraph.title || '', type: currentSubgraph.titleType || 'text' };
} }
const nodeList = currentSubgraph.nodes; const nodeList = currentSubgraph.nodes;
@@ -1630,9 +1644,18 @@ class FlowchartListener implements ParseTreeListener {
// Quoted strings: "text" (fallback case) // Quoted strings: "text" (fallback case)
const strippedText = fullText.slice(1, -1); const strippedText = fullText.slice(1, -1);
// Check if the inner content has backticks (nested markdown)
if (strippedText.startsWith('`') && strippedText.endsWith('`') && strippedText.length > 2) {
const innerStrippedText = strippedText.slice(1, -1);
return {
text: innerStrippedText,
type: 'markdown',
};
}
return { return {
text: strippedText, text: strippedText,
type: 'string', type: 'text',
}; };
} }