mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Adding support for compound blocks
This commit is contained in:
parent
13114ebaa1
commit
b9531d56c4
@ -18,7 +18,7 @@ import {
|
||||
|
||||
// TODO: Convert to generic TreeNode type? Convert to class?
|
||||
export interface Block {
|
||||
ID?: string;
|
||||
ID: string;
|
||||
label?: string;
|
||||
parent?: Block;
|
||||
children?: Block[];
|
||||
@ -32,16 +32,21 @@ export interface Link {
|
||||
|
||||
let rootBlocks: Block[] = [];
|
||||
let blocks: Block[] = [];
|
||||
let links: Link[] = [];
|
||||
const links: Link[] = [];
|
||||
let rootBlock = { ID: 'root', children: [], columns: -1 } as Block;
|
||||
let currentBlock: Block | undefined;
|
||||
|
||||
const clear = (): void => {
|
||||
rootBlocks = [];
|
||||
blocks = [];
|
||||
commonClear();
|
||||
rootBlock = { ID: 'root', children: [], columns: -1 };
|
||||
currentBlock = rootBlock;
|
||||
};
|
||||
|
||||
type IAddBlock = (block: Block) => Block;
|
||||
const addBlock: IAddBlock = (block: Block, parent?: Block): Block => {
|
||||
if(parent) {
|
||||
if (parent) {
|
||||
parent.children ??= [];
|
||||
parent.children.push(block);
|
||||
} else {
|
||||
@ -57,14 +62,44 @@ const addLink: IAddLink = (link: Link): Link => {
|
||||
return link;
|
||||
};
|
||||
|
||||
type ISetColumns = (columnsStr: string) => void;
|
||||
const setColumns = (columnsStr: string): void => {
|
||||
const columns = columnsStr === 'auto' ? -1 : parseInt(columnsStr);
|
||||
currentBlock!.columns = columns;
|
||||
};
|
||||
|
||||
const getBlock = (id: string, blocks: Block[]): Block | undefined => {
|
||||
for (const block of blocks) {
|
||||
if (block.ID === id) {
|
||||
return block;
|
||||
}
|
||||
if (block.children) {
|
||||
const foundBlock = getBlock(id, block.children);
|
||||
if (foundBlock) {
|
||||
return foundBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
type IGetColumns = (blockID: string) => number;
|
||||
const getColumns = (blockID: string): number => {
|
||||
const blocks = [rootBlock];
|
||||
const block = getBlock(blockID, blocks);
|
||||
if (!block) {
|
||||
return -1;
|
||||
}
|
||||
return block.columns || -1;
|
||||
};
|
||||
|
||||
type IGetBlocks = () => Block[];
|
||||
const getBlocks:IGetBlocks = () => blocks;
|
||||
const getBlocks: IGetBlocks = () => blocks;
|
||||
|
||||
type IGetLinks = () => Link[];
|
||||
const getLinks:IGetLinks = () => links;
|
||||
const getLinks: IGetLinks = () => links;
|
||||
|
||||
type IGetLogger = () => Console;
|
||||
const getLogger:IGetLogger = () => console;
|
||||
const getLogger: IGetLogger = () => console;
|
||||
|
||||
export interface BlockDB extends DiagramDB {
|
||||
clear: () => void;
|
||||
@ -74,6 +109,8 @@ export interface BlockDB extends DiagramDB {
|
||||
getLogger: IGetLogger;
|
||||
getBlocks: IGetBlocks;
|
||||
getLinks: IGetLinks;
|
||||
setColumns: ISetColumns;
|
||||
getColumns: IGetColumns;
|
||||
}
|
||||
|
||||
const db: BlockDB = {
|
||||
@ -89,6 +126,8 @@ const db: BlockDB = {
|
||||
// setAccDescription,
|
||||
// getDiagramTitle,
|
||||
// setDiagramTitle,
|
||||
setColumns,
|
||||
getColumns,
|
||||
clear,
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
%x string
|
||||
%x md_string
|
||||
%x NODE
|
||||
%options easy_keword_rules
|
||||
|
||||
|
||||
// as per section 6.1 of RFC 2234 [2]
|
||||
@ -28,11 +27,15 @@ CRLF \u000D\u000A
|
||||
%%
|
||||
|
||||
"block-beta" { return 'BLOCK_DIAGRAM_KEY'; }
|
||||
"block"\s+ { yy.getLogger().info('Found space-block'); return 'block';}
|
||||
"block"\n+ { yy.getLogger().info('Found nl-block'); return 'block';}
|
||||
// \s*\%\%.* { yy.getLogger().info('Found comment',yytext); }
|
||||
[\s]+ { yy.getLogger().info('.', yytext); /* skip all whitespace */ }
|
||||
[\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ }
|
||||
// [\n] return 'NL';
|
||||
<INITIAL>({CRLF}|{LF}) { return 'NL' }
|
||||
"columns"\s+"auto" { yytext=-1; return 'COLUMNS'; }
|
||||
"columns"\s+[\d]+ { yytext = yytext.replace(/columns\s+/,''); yy.getLogger().info('COLUMNS (LEX)', yytext); return 'COLUMNS'; }
|
||||
["][`] { this.pushState("md_string");}
|
||||
<md_string>[^`"]+ { return "MD_STR";}
|
||||
<md_string>[`]["] { this.popState();}
|
||||
@ -114,6 +117,7 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul
|
||||
|
||||
/lex
|
||||
|
||||
%left '^'
|
||||
%start start
|
||||
|
||||
%% // language grammar
|
||||
@ -133,12 +137,8 @@ seperator
|
||||
{yy.getLogger().info('Rule: seperator (EOF) ');}
|
||||
;
|
||||
|
||||
start: BLOCK_DIAGRAM_KEY document;
|
||||
start: BLOCK_DIAGRAM_KEY document EOF;
|
||||
|
||||
blockDiagram
|
||||
: blockDiagram document { return yy; }
|
||||
| blockDiagram NL document { return yy; }
|
||||
;
|
||||
|
||||
stop
|
||||
: NL {yy.getLogger().info('Stop NL ');}
|
||||
@ -149,8 +149,8 @@ stop
|
||||
;
|
||||
|
||||
document
|
||||
: document statement
|
||||
| statement
|
||||
: statement { yy.getLogger().info("Rule: statement: ", $1);}
|
||||
| statement document { yy.getLogger().info("Rule: document statement: ", $1);}
|
||||
;
|
||||
|
||||
link
|
||||
@ -162,6 +162,8 @@ link
|
||||
|
||||
statement
|
||||
: nodeStatement
|
||||
| columnsStatement
|
||||
| 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}); }
|
||||
@ -171,12 +173,22 @@ statement
|
||||
// | ICON { yy.decorateNode({icon: $1}); }
|
||||
// | CLASS { yy.decorateNode({class: $1}); }
|
||||
// // | SPACELIST
|
||||
| EOF
|
||||
|
||||
;
|
||||
|
||||
nodeStatement: nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');}
|
||||
|node { yy.getLogger().info('Rule: nodeStatement (node) ');}
|
||||
;
|
||||
nodeStatement
|
||||
: nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');}
|
||||
| node { yy.getLogger().info('Rule: nodeStatement (node) ', $1);}
|
||||
;
|
||||
|
||||
columnsStatement
|
||||
: COLUMNS { yy.getLogger().info("COLUMNS: ", $1);yy.setColumns($1); }
|
||||
;
|
||||
|
||||
blockStatement
|
||||
: block document end { yy.getLogger().info('Rule: blockStatement : ', $1); }
|
||||
;
|
||||
|
||||
|
||||
node
|
||||
: NODE_ID
|
||||
|
@ -55,19 +55,38 @@ describe('Block diagram', function () {
|
||||
|
||||
block.parse(str);
|
||||
});
|
||||
it.skip('a diagram with column statements', async () => {
|
||||
it('a diagram with column statements', async () => {
|
||||
const str = `block-beta
|
||||
columns 1
|
||||
columns 2
|
||||
block1["Block 1"]
|
||||
`;
|
||||
|
||||
block.parse(str);
|
||||
expect(db.getColumns('root')).toBe(2);
|
||||
// Todo: DB check that the we have one block and that the root block has one column
|
||||
});
|
||||
it('a diagram withput column statements', async () => {
|
||||
const str = `block-beta
|
||||
block1["Block 1"]
|
||||
`;
|
||||
|
||||
block.parse(str);
|
||||
expect(db.getColumns('root')).toBe(-1);
|
||||
// Todo: DB check that the we have one block and that the root block has one column
|
||||
});
|
||||
it('a diagram with auto column statements', async () => {
|
||||
const str = `block-beta
|
||||
columns auto
|
||||
block1["Block 1"]
|
||||
`;
|
||||
|
||||
block.parse(str);
|
||||
expect(db.getColumns('root')).toBe(-1);
|
||||
// Todo: DB check that the we have one block and that the root block has one column
|
||||
});
|
||||
|
||||
it.skip('blocks next to each other', async () => {
|
||||
it('blocks next to each other', async () => {
|
||||
const str = `block-beta
|
||||
block
|
||||
columns 2
|
||||
block1["Block 1"]
|
||||
block2["Block 2"]
|
||||
@ -78,9 +97,8 @@ describe('Block diagram', function () {
|
||||
// Todo: DB check that the we have two blocks and that the root block has two columns
|
||||
});
|
||||
|
||||
it.skip('blocks on top of each other', async () => {
|
||||
it('blocks on top of each other', async () => {
|
||||
const str = `block-beta
|
||||
block
|
||||
columns 1
|
||||
block1["Block 1"]
|
||||
block2["Block 2"]
|
||||
@ -91,13 +109,11 @@ describe('Block diagram', function () {
|
||||
// Todo: DB check that the we have two blocks and that the root block has one column
|
||||
});
|
||||
|
||||
it.skip('compound blocks', async () => {
|
||||
const str = `block
|
||||
it('compound blocks', async () => {
|
||||
const str = `block-beta
|
||||
block
|
||||
columns 2
|
||||
block2["Block 2"]
|
||||
block3["Block 3"]
|
||||
end %% End the compound block
|
||||
aBlock["Block"]
|
||||
end
|
||||
`;
|
||||
|
||||
block.parse(str);
|
||||
@ -121,7 +137,7 @@ describe('Block diagram', function () {
|
||||
columns 2
|
||||
block2["Block 2"]
|
||||
block3["Block 3"]
|
||||
end %% End the compound block
|
||||
end
|
||||
`;
|
||||
|
||||
block.parse(str);
|
||||
|
Loading…
x
Reference in New Issue
Block a user