Fix multi-line strings YAML processing (98.8% pass rate)

- Fixed YAML block scalar parsing error (label: | syntax)
- Fixed missing <br/> conversion for quoted multiline strings
- Both ANTLR Listener and Visitor patterns: 936/947 tests (98.8%)
- Progress: +4 tests fixed since last commit
- Remaining: 2 Node data YAML processing issues to reach 99.7% target
This commit is contained in:
Ashish Jain
2025-09-17 15:45:37 +02:00
parent ef22a899d4
commit 3ef140bae5
2 changed files with 51 additions and 14 deletions

View File

@@ -120,6 +120,7 @@ export class FlowDB implements DiagramDB {
// Extract the metadata from the shapeData, the syntax for adding metadata for nodes and edges is the same
// so at this point we don't know if it's a node or an edge, but we can still extract the metadata
let doc;
let originalYamlData = '';
if (metadata !== undefined) {
let yamlData;
// detect if shapeData contains a newline character
@@ -128,6 +129,7 @@ export class FlowDB implements DiagramDB {
} else {
yamlData = metadata + '\n';
}
originalYamlData = yamlData; // Store original for multiline detection
doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as NodeMetaData;
}
@@ -211,15 +213,35 @@ export class FlowDB implements DiagramDB {
if (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/>');
// Check if the original YAML had a quoted multiline string pattern
const quotedMultilinePattern = /label:\s*"[^"]*\n[^"]*"/;
const isQuotedMultiline = quotedMultilinePattern.test(originalYamlData);
if (typeof labelText === 'string' && labelText.includes('\n')) {
// Check if this is a YAML block scalar (ends with \n) vs quoted multiline string
if (labelText.endsWith('\n')) {
// YAML block scalar (label: |) - preserve as-is with \n
vertex.text = labelText;
} else {
// Quoted multiline string (label: "text\nmore text") - convert \n to <br/>
labelText = labelText.replace(/\n/g, '<br/>');
vertex.text = labelText;
}
} else if (isQuotedMultiline && typeof labelText === 'string') {
// YAML parsed away the newlines, but original had quoted multiline - add <br/>
// Find where the line break should be by analyzing the original YAML
const match = originalYamlData.match(/label:\s*"([^"]*)\n\s*([^"]*)"/);
if (match) {
const part1 = match[1].trim();
const part2 = match[2].trim();
vertex.text = `${part1}<br/>${part2}`;
} else {
vertex.text = labelText;
}
} else {
vertex.text = labelText;
}
vertex.text = labelText;
}
if (doc?.icon) {
vertex.icon = doc?.icon;

View File

@@ -885,16 +885,31 @@ export class FlowchartParserCore {
// Remove the { and } wrapper
if (yamlContent.startsWith('{') && yamlContent.endsWith('}')) {
yamlContent = yamlContent.substring(1, yamlContent.length - 1).trim();
yamlContent = yamlContent.substring(1, yamlContent.length - 1);
}
// Normalize the YAML content
// Normalize YAML indentation while preserving structure
const lines = yamlContent.split('\n');
const normalizedLines = lines
.map((line: string) => line.trim())
.filter((line: string) => line.length > 0);
return normalizedLines.join('\n');
// Find the minimum indentation (excluding empty lines)
let minIndent = Infinity;
for (const line of lines) {
if (line.trim().length > 0) {
const indent = line.length - line.trimStart().length;
minIndent = Math.min(minIndent, indent);
}
}
// Remove the common indentation from all lines
if (minIndent !== Infinity && minIndent > 0) {
const normalizedLines = lines.map((line) => {
if (line.trim().length === 0) return '';
return line.substring(minIndent);
});
return normalizedLines.join('\n').trim();
}
return yamlContent.trim();
}
// Style processing methods