Adding support for compound blocks

This commit is contained in:
Knut Sveidqvist 2023-08-08 15:56:02 +02:00
parent 13114ebaa1
commit b9531d56c4
3 changed files with 98 additions and 31 deletions

View File

@ -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,
};

View File

@ -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

View File

@ -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);