Parsing of block arrows with directions, creating a dedicated new node for this.

This commit is contained in:
Knut Sveidqvist 2023-10-26 22:01:44 +02:00
parent f3f25c7874
commit 7198fe55a9
6 changed files with 84 additions and 41 deletions

View File

@ -62,24 +62,23 @@
</style>
</head>
<body>
<pre id="diagram" class="mermaid2">
block-beta
block
id3("Wider then")
end
</pre>
<pre id="diagram" class="mermaid">
block-beta
blockArrowId<["Label"]>(right, down)
</pre>
<pre id="diagram" class="mermaid2">
block-beta
columns 3
space:2
id1("Wider then")
space:9
space
id2{{"Wider then"}}
space
id3("Wider then")
space
space
space:3
ida idb idc
id1 id2
blockArrowId<["Label"]>(right)
blockArrowId2<["Label"]>(left)
blockArrowId3<["Label"]>(up)
blockArrowId4<["Label"]>(down)
blockArrowId5<["Label"]>(x)
blockArrowId6<["Label"]>(y)
blockArrowId6<["Label"]>(x, down)
</pre>
<pre id="diagram" class="mermaid2">
block-beta

View File

@ -95,6 +95,32 @@ const hexagon = async (parent, node) => {
return shapeSvg;
};
const block_arrow = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
const f = 2;
const h = bbox.height + node.padding;
const m = h / f;
const w = bbox.width + 2 * m + node.padding;
const points = [
{ x: m, y: 0 },
{ x: w - m, y: 0 },
{ x: w, y: -h / 2 },
{ x: w - m, y: -h },
{ x: m, y: -h },
{ x: 0, y: -h / 2 },
];
const hex = insertPolygonShape(shapeSvg, w, h, points);
hex.attr('style', node.style);
updateNodeBounds(node, hex);
node.intersect = function (point) {
return intersect.polygon(node, points, point);
};
return shapeSvg;
};
const rect_left_inv_arrow = async (parent, node) => {
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
@ -1016,6 +1042,7 @@ const shapes = {
doublecircle,
stadium,
hexagon,
block_arrow,
rect_left_inv_arrow,
lean_right,
lean_left,

View File

@ -99,6 +99,8 @@ export function typeStr2Type(typeStr: string) {
return 'trapezoid';
case '[\\/]':
return 'inv_trapezoid';
case '<[]>':
return 'block_arrow';
default:
return 'square';
}

View File

@ -7,6 +7,8 @@ export interface BlockConfig extends BaseDiagramConfig {
export type BlockType =
| 'column-setting'
| 'round'
| 'block_arrow'
| 'space'
| 'square'
| 'diamond'
| 'hexagon'
@ -40,6 +42,7 @@ export interface Block {
node?: any;
columns?: number; // | TBlockColumnsDefaultValue;
classes?: string[];
directions?: string[];
}
export interface Link {

View File

@ -16,6 +16,8 @@
%x space
%x md_string
%x NODE
%x BLOCK_ARROW
%x ARROW_DIR
// as per section 6.1 of RFC 2234 [2]
@ -42,11 +44,10 @@ CRLF \u000D\u000A
<md_string>[^`"]+ { return "MD_STR";}
<md_string>[`]["] { this.popState();}
["] this.pushState("string");
<string>["] this.popState();
<string>[^"]* return "STR";
<string>["] { log.debug('LEX: POPPING STR:', yytext);this.popState();}
<string>[^"]* { log.debug('LEX: STR ebd:', yytext); return "STR";}
space[:]\d+ { yytext = yytext.replace(/space\:/,'');yy.getLogger().info('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; }
space { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; }
<string>[^"]* return "STR";
"style" return 'STYLE';
"default" return 'DEFAULT';
"linkStyle" return 'LINKSTYLE';
@ -68,15 +69,15 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul
.*direction\s+LR[^\n]* return 'direction_lr';
// Start of nodes with shapes and description
"-)" { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_DSTART'; }
"(-" { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; }
"))" { yy.getLogger().info('Lex: ))'); this.pushState('NODE');return 'NODE_DSTART'; }
")" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"((" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"{{" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"(" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"[" { yy.getLogger().info('Lex: ['); this.pushState('NODE');return 'NODE_DSTART'; }
"([" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"-)" { yy.getLogger().info('Lexa: -)'); this.pushState('NODE');return 'NODE_DSTART'; }
"(-" { yy.getLogger().info('Lexa: (-'); this.pushState('NODE');return 'NODE_DSTART'; }
"))" { yy.getLogger().info('Lexa: ))'); this.pushState('NODE');return 'NODE_DSTART'; }
")" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"((" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"{{" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"(" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; }
"[" { yy.getLogger().info('Lexa: ['); this.pushState('NODE');return 'NODE_DSTART'; }
"([" { yy.getLogger().info('Lexa: (['); this.pushState('NODE');return 'NODE_DSTART'; }
"[[" { this.pushState('NODE');return 'NODE_DSTART'; }
"[|" { this.pushState('NODE');return 'NODE_DSTART'; }
"[(" { this.pushState('NODE');return 'NODE_DSTART'; }
@ -85,19 +86,23 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul
"[/" { this.pushState('NODE');return 'NODE_DSTART'; }
"[\\" { this.pushState('NODE');return 'NODE_DSTART'; }
"<[" { this.pushState('BLOCK_ARROW');log.debug('LEX ARR START');return 'BLOCK_ARROW_START'; }
[^\(\[\n\-\)\{\}]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
[^\(\[\n\-\)\{\}\s\<]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
<<EOF>> { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; }
// Handling of strings in node
<BLOCK_ARROW>["][`] { this.pushState("md_string");}
<NODE>["][`] { this.pushState("md_string");}
<md_string>[^`"]+ { return "NODE_DESCR";}
<md_string>[`]["] { this.popState();}
<NODE>["] { yy.getLogger().info('Lex: Starting string');this.pushState("string");}
<string>[^"]+ { yy.getLogger().info('Lex: NODE_DESCR:', yytext); return "NODE_DESCR";}
<string>["] {this.popState();}
<BLOCK_ARROW>["] { yy.getLogger().info('LEX ARR: Starting string');this.pushState("string");}
<string>[^"]+ { log.debug('LEX: NODE_DESCR:', yytext); return "NODE_DESCR";}
<string>["] {log.debug('LEX POPPING');this.popState();}
// Node end of shape
<NODE>\]\> { this.popState();yy.getLogger().info('Lex: ]>'); return "NODE_DEND"; }
<NODE>[\)]\) { this.popState();yy.getLogger().info('Lex: ))'); return "NODE_DEND"; }
<NODE>[\)] { this.popState();yy.getLogger().info('Lex: )'); return "NODE_DEND"; }
<NODE>[\]] { this.popState();yy.getLogger().info('Lex: ]'); return "NODE_DEND"; }
@ -111,6 +116,15 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul
<NODE>"/]" { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; }
<NODE>")]" { this.popState();yy.getLogger().info('Lex: )]'); return "NODE_DEND"; }
<BLOCK_ARROW>"]>"\s*"(" { log.debug('Lex: =>BAE'); this.pushState('ARROW_DIR'); }
<ARROW_DIR>","?right\s* { log.debug('Lex (right): dir:',yytext);return "DIR"; }
<ARROW_DIR>","?left\s* { log.debug('Lex (left):',yytext);return "DIR"; }
<ARROW_DIR>","?x\s* { log.debug('Lex (x):',yytext); return "DIR"; }
<ARROW_DIR>","?y\s* { log.debug('Lex (y):',yytext); return "DIR"; }
<ARROW_DIR>","?up\s* { log.debug('Lex (up):',yytext); return "DIR"; }
<ARROW_DIR>","?\s*down\s* { yytext = yytext.replace(/^,\s*/, ''); log.debug('Lex (down):',yytext); return "DIR"; }
<ARROW_DIR>")"\s* { yytext=']>';log.debug('Lex (ARROW_DIR end):',yytext);this.popState();this.popState();return "BLOCK_ARROW_END"; }
// Edges
\s*[xo<]?\-\-+[-xo>]\s* { yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; }
\s*[xo<]?\=\=+[=xo>]\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; }
@ -174,16 +188,6 @@ statement
| SPACE_BLOCK
{ const num=parseInt($1); const spaceId = yy.generateId(); $$ = { id: spaceId, type:'space', label:'', width: num, children: [] }}
| blockStatement
// SPACELIST node { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); }
// | SPACELIST ICON { yy.getLogger().info('Icon: ',$2);yy.decorateNode({icon: $2}); }
// | SPACELIST CLASS { yy.decorateNode({class: $2}); }
// | SPACELINE { yy.getLogger().info('SPACELIST');}
// |
// node { yy.getLogger().info('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); }
// | ICON { yy.decorateNode({icon: $1}); }
// | CLASS { yy.decorateNode({class: $1}); }
// // | SPACELIST
;
nodeStatement
@ -200,7 +204,6 @@ blockStatement
| block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; }
;
node
: NODE_ID
{ yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; }
@ -210,9 +213,15 @@ node
// { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); }
;
dirList: DIR { yy.getLogger().info("Rule: dirList: ", $1); $$ = [$1]; }
| DIR dirList { yy.getLogger().info("Rule: dirList: ", $1, $2); $$ = [$1].concat($2); }
;
nodeShapeNLabel
: NODE_DSTART STR NODE_DEND
{ yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; }
| BLOCK_ARROW_START STR dirList BLOCK_ARROW_END
{ yy.getLogger().info("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, $3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; }
;
%%

View File

@ -50,6 +50,9 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
case 'hexagon':
_shape = 'hexagon';
break;
case 'block_arrow':
_shape = 'block_arrow';
break;
case 'odd':
_shape = 'rect_left_inv_arrow';
break;