fix: ANTLR parser YAML multiline string processing

- Fixed YAML pipe syntax (|) processing with proper indentation preservation
- Fixed quoted multiline string conversion to <br/> tags for HTML rendering
- Enhanced YAML content preprocessing to handle both pipe and quoted multiline formats
- Updated FlowDB to convert newlines to <br/> for quoted multiline strings
- Both multiline string tests now passing (2/4 node data tests fixed)
- Pass rate improved from 98.1% to 98.6% (931/947 tests)
This commit is contained in:
Ashish Jain
2025-09-15 16:04:16 +02:00
parent 4ab95fd224
commit df5a9acf0b
2 changed files with 79 additions and 6 deletions

View File

@@ -207,7 +207,17 @@ export class FlowDB implements DiagramDB {
} }
if (doc?.label) { if (doc?.label) {
vertex.text = doc?.label; // Convert newlines to <br/> tags for HTML rendering (except for YAML pipe syntax which preserves \n)
let labelText = doc.label;
if (
typeof labelText === 'string' &&
labelText.includes('\n') &&
!labelText.endsWith('\n')
) {
// This is a quoted multiline string, convert \n to <br/>
labelText = labelText.replace(/\n/g, '<br/>');
}
vertex.text = labelText;
} }
if (doc?.icon) { if (doc?.icon) {
vertex.icon = doc?.icon; vertex.icon = doc?.icon;

View File

@@ -443,13 +443,76 @@ class FlowchartListener implements ParseTreeListener {
yamlContent = yamlContent.substring(1, yamlContent.length - 1).trim(); yamlContent = yamlContent.substring(1, yamlContent.length - 1).trim();
} }
// Normalize YAML indentation to fix inconsistent whitespace // Handle YAML content more carefully to preserve multiline strings
const lines = yamlContent.split('\n'); const lines = yamlContent.split('\n');
const normalizedLines = lines
.map((line) => line.trim()) // Remove leading/trailing whitespace
.filter((line) => line.length > 0); // Remove empty lines
shapeDataYaml = normalizedLines.join('\n'); // Check if this contains YAML pipe syntax (|) which needs special handling
const hasPipeSyntax = yamlContent.includes('|');
// Check if this contains quoted multiline strings that need <br/> conversion
const hasQuotedMultiline =
yamlContent.includes('"') &&
yamlContent.includes('\n') &&
/label:\s*"[^"]*\n[^"]*"/.test(yamlContent);
if (hasQuotedMultiline) {
// Handle quoted multiline strings - convert newlines to <br/> before YAML processing
let processedYaml = yamlContent;
// Find quoted multiline strings and replace newlines with <br/>
processedYaml = processedYaml.replace(
/label:\s*"([^"]*\n[^"]*?)"/g,
(_match: string, content: string) => {
const convertedContent = content.replace(/\n\s*/g, '<br/>');
return `label: "${convertedContent}"`;
}
);
// Normalize the processed YAML
const processedLines = processedYaml.split('\n');
const normalizedLines = processedLines
.map((line: string) => line.trim())
.filter((line: string) => line.length > 0);
shapeDataYaml = normalizedLines.join('\n');
} else if (hasPipeSyntax) {
// For pipe syntax, preserve the structure but fix indentation
// The pipe syntax requires proper indentation to work
let minIndent = Infinity;
const nonEmptyLines = lines.filter((line: string) => line.trim().length > 0);
// Find minimum indentation (excluding the first line which might be "label: |")
for (let i = 1; i < nonEmptyLines.length; i++) {
const line = nonEmptyLines[i];
const match = line.match(/^(\s*)/);
if (match && line.trim().length > 0) {
minIndent = Math.min(minIndent, match[1].length);
}
}
// Normalize indentation while preserving structure
const normalizedLines = lines.map((line: string, index: number) => {
if (line.trim().length === 0) return ''; // Keep empty lines
if (index === 0 || line.includes(':')) {
// First line or lines with colons (property definitions)
return line.trim();
} else {
// Content lines - preserve relative indentation
const currentIndent = line.match(/^(\s*)/)?.[1]?.length || 0;
const relativeIndent = Math.max(0, currentIndent - minIndent);
return ' '.repeat(relativeIndent) + line.trim();
}
});
shapeDataYaml = normalizedLines.join('\n');
} else {
// For regular YAML, normalize as before
const normalizedLines = lines
.map((line: string) => line.trim()) // Remove leading/trailing whitespace
.filter((line: string) => line.length > 0); // Remove empty lines
shapeDataYaml = normalizedLines.join('\n');
}
} }
// Add vertex to database // Add vertex to database