mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-23 10:16:43 +02:00
21 failing
This commit is contained in:
@@ -1494,11 +1494,96 @@ class LezerFlowParser {
|
|||||||
return this.parseEdgeStatement(tokens, i);
|
return this.parseEdgeStatement(tokens, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New: handle combined single-token edge patterns like A---B, A--xB, A--oB
|
||||||
|
if (lookahead.length >= 1 && lookahead[0].type === 'NODE_STRING') {
|
||||||
|
const combined = this.matchCombinedEdgeToken(lookahead[0].value);
|
||||||
|
if (combined) {
|
||||||
|
console.log(`UIO DEBUG: Taking combined single-token edge path for ${lookahead[0].value}`);
|
||||||
|
return this.parseCombinedSingleTokenEdge(tokens, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, treat as a single node
|
// Otherwise, treat as a single node
|
||||||
console.log(`UIO DEBUG: Taking node statement path (single node)`);
|
console.log(`UIO DEBUG: Taking node statement path (single node)`);
|
||||||
return this.parseNodeStatement(tokens, i);
|
return this.parseNodeStatement(tokens, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect combined single-token edge like A---B, A--xB, A--oB, A-.-.B
|
||||||
|
private matchCombinedEdgeToken(
|
||||||
|
val: string
|
||||||
|
): { source: string; arrow: string; target: string } | null {
|
||||||
|
// Patterns:
|
||||||
|
// 1) A---B or A===B
|
||||||
|
// 2) A--xB / A--oB (arrow head inside token)
|
||||||
|
// 3) A-.-.B (dotted open)
|
||||||
|
// Keep it conservative: only match when there is exactly one “source part”, one “arrow part”, one “target part”
|
||||||
|
const m1 = /^([^\s%=\-]+)(-{3,}|={3,})([^\s%=\-]+)$/.exec(val);
|
||||||
|
if (m1) {
|
||||||
|
return { source: m1[1], arrow: m1[2], target: m1[3] };
|
||||||
|
}
|
||||||
|
|
||||||
|
const m2 = /^([^\s%=\-]+)(--[ox])([^\s%=\-]+)$/.exec(val);
|
||||||
|
if (m2) {
|
||||||
|
return { source: m2[1], arrow: m2[2], target: m2[3] };
|
||||||
|
}
|
||||||
|
|
||||||
|
const m3 = /^([^\s%=\-]+)(-\.+-)([^\s%=\-]+)$/.exec(val);
|
||||||
|
if (m3) {
|
||||||
|
return { source: m3[1], arrow: m3[2], target: m3[3] };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the combined single-token edge by creating the source/target and link
|
||||||
|
private parseCombinedSingleTokenEdge(
|
||||||
|
tokens: { type: string; value: string; from: number; to: number }[],
|
||||||
|
startIndex: number
|
||||||
|
): number {
|
||||||
|
const token = tokens[startIndex];
|
||||||
|
const match = this.matchCombinedEdgeToken(token.value);
|
||||||
|
if (!match) {
|
||||||
|
return startIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { source, arrow, target } = match;
|
||||||
|
|
||||||
|
// Create vertices
|
||||||
|
if (this.yy) {
|
||||||
|
this.yy.addVertex(
|
||||||
|
source,
|
||||||
|
{ text: source, type: 'text' },
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
{},
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
this.yy.addVertex(
|
||||||
|
target,
|
||||||
|
{ text: target, type: 'text' },
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
{},
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create edge
|
||||||
|
this.yy.addSingleLink(source, target, {
|
||||||
|
text: { text: '', type: 'text' },
|
||||||
|
type: this.getArrowType(arrow),
|
||||||
|
stroke: this.getArrowStroke(arrow),
|
||||||
|
length: this.getArrowLength(arrow),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance to next token
|
||||||
|
return startIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look ahead in the token stream
|
* Look ahead in the token stream
|
||||||
* @param tokens - Array of tokens
|
* @param tokens - Array of tokens
|
||||||
@@ -1756,6 +1841,17 @@ class LezerFlowParser {
|
|||||||
// Check for shape patterns: A[text], A(text), A{text}, etc.
|
// Check for shape patterns: A[text], A(text), A{text}, etc.
|
||||||
if (lookahead.length >= 3 && this.isShapeStart(lookahead[1].type)) {
|
if (lookahead.length >= 3 && this.isShapeStart(lookahead[1].type)) {
|
||||||
console.log(`UIO DEBUG: Detected shaped node: ${nodeId} with shape ${lookahead[1].type}`);
|
console.log(`UIO DEBUG: Detected shaped node: ${nodeId} with shape ${lookahead[1].type}`);
|
||||||
|
// Special-case dotted simple edge tokenization: A-.- + > + B => A -.-> B
|
||||||
|
if (
|
||||||
|
lookahead[1].type === 'TagEnd' &&
|
||||||
|
lookahead[0]?.type === 'NODE_STRING' &&
|
||||||
|
lookahead[0]?.value.endsWith('-.-') &&
|
||||||
|
i + 2 < tokens.length &&
|
||||||
|
(tokens[i + 2].type === 'Identifier' || tokens[i + 2].type === 'NODE_STRING')
|
||||||
|
) {
|
||||||
|
// Delegate to edge parsing starting from the NODE_STRING token
|
||||||
|
return this.parseEdgeStatement(tokens, i);
|
||||||
|
}
|
||||||
return this.parseShapedNode(tokens, i, inlineClasses);
|
return this.parseShapedNode(tokens, i, inlineClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3003,14 +3099,14 @@ class LezerFlowParser {
|
|||||||
console.log(`UIO DEBUG: parseEdgeWithIdStatement: skipping @ symbol`);
|
console.log(`UIO DEBUG: parseEdgeWithIdStatement: skipping @ symbol`);
|
||||||
i++; // Skip '@'
|
i++; // Skip '@'
|
||||||
|
|
||||||
// Parse the arrow/text/target using the same logic as general edges
|
// Parse the arrow/text/target using the standard edge parser (same as normal edges)
|
||||||
const complex = this.parseComplexArrowPattern(tokens, i);
|
const parsed = this.parseEdgePattern(tokens, i);
|
||||||
if (!complex) {
|
if (!parsed) {
|
||||||
console.log(`UIO DEBUG: parseEdgeWithIdStatement: no valid arrow pattern after id`);
|
console.log(`UIO DEBUG: parseEdgeWithIdStatement: no valid arrow pattern after id`);
|
||||||
return i + 1;
|
return i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { arrow: arrowVal, targetId, text, type, stroke, length, nextIndex } = complex;
|
const { arrow: arrowVal, targetId, text, type, stroke, length, nextIndex } = parsed;
|
||||||
i = nextIndex;
|
i = nextIndex;
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
@@ -3554,8 +3650,21 @@ class LezerFlowParser {
|
|||||||
/--[ox].+/.test(sourceToken.value) && // Contains --x or --o followed by more characters
|
/--[ox].+/.test(sourceToken.value) && // Contains --x or --o followed by more characters
|
||||||
this.isShapeStart(tokens[i + 1].type); // Followed by a shape start
|
this.isShapeStart(tokens[i + 1].type); // Followed by a shape start
|
||||||
|
|
||||||
|
// Check for dotted split arrow tail: NODE_STRING like "A-.-" followed by TagEnd:'>' => A -.->
|
||||||
|
const dottedTailMatch = /^(?<id>.+?)-(?<dots>\.+)-$/.exec(sourceToken.value);
|
||||||
|
const hasDottedSplitArrow =
|
||||||
|
i + 1 < tokens.length &&
|
||||||
|
!!dottedTailMatch &&
|
||||||
|
tokens[i + 1].type === 'TagEnd' &&
|
||||||
|
tokens[i + 1].value === '>';
|
||||||
|
|
||||||
let sourceId: string;
|
let sourceId: string;
|
||||||
if (hasSplitArrow) {
|
if (hasDottedSplitArrow) {
|
||||||
|
sourceId = dottedTailMatch.groups!.id;
|
||||||
|
console.log(
|
||||||
|
`UIO DEBUG: parseEdgeStatement: detected dotted split arrow tail, sourceId=${sourceId}`
|
||||||
|
);
|
||||||
|
} else if (hasSplitArrow) {
|
||||||
// Extract the actual node ID by removing the arrow part
|
// Extract the actual node ID by removing the arrow part
|
||||||
sourceId = sourceToken.value.slice(0, -2); // Remove the trailing "--"
|
sourceId = sourceToken.value.slice(0, -2); // Remove the trailing "--"
|
||||||
console.log(
|
console.log(
|
||||||
@@ -3592,7 +3701,8 @@ class LezerFlowParser {
|
|||||||
!hasEmbeddedArrowWithPipe &&
|
!hasEmbeddedArrowWithPipe &&
|
||||||
!hasEmbeddedArrowWithNode &&
|
!hasEmbeddedArrowWithNode &&
|
||||||
i < tokens.length &&
|
i < tokens.length &&
|
||||||
this.isShapeStart(tokens[i].type)
|
this.isShapeStart(tokens[i].type) &&
|
||||||
|
tokens[i].type !== 'TagEnd' // Do not treat '>' as shape start in edge context; it's an arrow head
|
||||||
) {
|
) {
|
||||||
console.log(`UIO DEBUG: parseEdgeStatement: parsing shaped source node ${sourceId}`);
|
console.log(`UIO DEBUG: parseEdgeStatement: parsing shaped source node ${sourceId}`);
|
||||||
// Parse the shaped node, but start from the node ID token
|
// Parse the shaped node, but start from the node ID token
|
||||||
@@ -3614,12 +3724,33 @@ class LezerFlowParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look for edge pattern - could be simple (A --> B) or complex (A<-- text -->B)
|
// Look for edge pattern - could be simple (A --> B) or complex (A<-- text -->B)
|
||||||
console.log(
|
|
||||||
`UIO DEBUG: parseEdgeStatement calling parseEdgePattern at index ${i}, token: ${tokens[i]?.type}:${tokens[i]?.value}`
|
|
||||||
);
|
|
||||||
|
|
||||||
let edgeInfo;
|
let edgeInfo;
|
||||||
if (hasEmbeddedArrowWithPipe) {
|
if (hasDottedSplitArrow) {
|
||||||
|
const dots = dottedTailMatch.groups!.dots;
|
||||||
|
const dotCount = dots.length;
|
||||||
|
const arrow = `-${'.'.repeat(dotCount)}->`;
|
||||||
|
// Expect current token at i is TagEnd '>' and next token is target
|
||||||
|
if (
|
||||||
|
i < tokens.length &&
|
||||||
|
tokens[i].type === 'TagEnd' &&
|
||||||
|
i + 1 < tokens.length &&
|
||||||
|
(tokens[i + 1].type === 'Identifier' ||
|
||||||
|
tokens[i + 1].type === 'NODE_STRING' ||
|
||||||
|
tokens[i + 1].type === 'DIR')
|
||||||
|
) {
|
||||||
|
const targetToken = tokens[i + 1];
|
||||||
|
edgeInfo = {
|
||||||
|
arrow,
|
||||||
|
targetId: targetToken.value,
|
||||||
|
text: '',
|
||||||
|
type: this.getArrowType(arrow),
|
||||||
|
stroke: this.getArrowStroke(arrow),
|
||||||
|
length: this.getArrowLength(arrow),
|
||||||
|
nextIndex: i + 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (hasEmbeddedArrowWithPipe) {
|
||||||
// For embedded arrows like "A--x", extract the arrow and handle pipe-delimited text
|
// For embedded arrows like "A--x", extract the arrow and handle pipe-delimited text
|
||||||
const arrowMatch = /--([ox])$/.exec(sourceToken.value);
|
const arrowMatch = /--([ox])$/.exec(sourceToken.value);
|
||||||
if (arrowMatch) {
|
if (arrowMatch) {
|
||||||
|
Reference in New Issue
Block a user