First take on grammar
This commit is contained in:
parent
8681e78e50
commit
6029c5371e
|
@ -35,6 +35,14 @@ import journeyDb from '../diagrams/user-journey/journeyDb';
|
|||
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||
import { addDetector } from './detectType';
|
||||
import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
|
||||
import { getConfig as _getConfig } from '../config';
|
||||
let title = '';
|
||||
let diagramTitle = '';
|
||||
let description = '';
|
||||
|
||||
export const getConfig = _getConfig;
|
||||
export const sanitizeText = (txt) => _sanitizeText(txt, getConfig());
|
||||
|
||||
const diagrams = {
|
||||
c4: {
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
describe('when parsing an info graph it', function () {
|
||||
var ex;
|
||||
beforeEach(function () {
|
||||
ex = require('./parser/info').parser;
|
||||
ex.yy = require('./infoDb');
|
||||
});
|
||||
|
||||
it('should handle an info definition', function () {
|
||||
var str = `info
|
||||
showInfo`;
|
||||
|
||||
ex.parse(str);
|
||||
});
|
||||
});
|
|
@ -1,34 +0,0 @@
|
|||
/** Created by knut on 15-01-14. */
|
||||
import { log } from '../../logger';
|
||||
|
||||
var message = '';
|
||||
var info = false;
|
||||
|
||||
export const setMessage = (txt) => {
|
||||
log.debug('Setting message to: ' + txt);
|
||||
message = txt;
|
||||
};
|
||||
|
||||
export const getMessage = () => {
|
||||
return message;
|
||||
};
|
||||
|
||||
export const setInfo = (inf) => {
|
||||
info = inf;
|
||||
};
|
||||
|
||||
export const getInfo = () => {
|
||||
return info;
|
||||
};
|
||||
|
||||
// export const parseError = (err, hash) => {
|
||||
// global.mermaidAPI.parseError(err, hash)
|
||||
// }
|
||||
|
||||
export default {
|
||||
setMessage,
|
||||
getMessage,
|
||||
setInfo,
|
||||
getInfo,
|
||||
// parseError
|
||||
};
|
|
@ -0,0 +1,201 @@
|
|||
import mindmapDB from './mindmapDb';
|
||||
|
||||
describe('when parsing a mindmap ', function () {
|
||||
var mindmap;
|
||||
beforeEach(function () {
|
||||
mindmap = require('./parser/mindmap').parser;
|
||||
mindmap.yy = require('./mindmapDb');
|
||||
mindmap.yy.clear();
|
||||
});
|
||||
describe('hiearchy', function () {
|
||||
it('should handle a simple root definition', function () {
|
||||
var str = `mindmap
|
||||
root`;
|
||||
|
||||
mindmap.parse(str);
|
||||
// console.log('Time for checks', mindmap.yy.getMindmap().descr);
|
||||
expect(mindmap.yy.getMindmap().descr).toEqual('root');
|
||||
});
|
||||
it('should handle a hierachial mindmap definition', function () {
|
||||
var str = `mindmap
|
||||
root
|
||||
child1
|
||||
child2
|
||||
`;
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.descr).toEqual('root');
|
||||
expect(mm.children.length).toEqual(2);
|
||||
expect(mm.children[0].descr).toEqual('child1');
|
||||
expect(mm.children[1].descr).toEqual('child2');
|
||||
});
|
||||
it('should handle a hierachial mindmap definition', function () {
|
||||
var str = `mindmap
|
||||
root
|
||||
child1
|
||||
leaf1
|
||||
child2`;
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.descr).toEqual('root');
|
||||
expect(mm.children.length).toEqual(2);
|
||||
expect(mm.children[0].descr).toEqual('child1');
|
||||
expect(mm.children[0].children[0].descr).toEqual('leaf1');
|
||||
expect(mm.children[1].descr).toEqual('child2');
|
||||
});
|
||||
it('Multiple roots are illegal', function () {
|
||||
var str = `mindmap
|
||||
root
|
||||
fakeRoot`;
|
||||
|
||||
try {
|
||||
mindmap.parse(str);
|
||||
// Fail test if above expression doesn't throw anything.
|
||||
expect(true).toBe(false);
|
||||
} catch (e) {
|
||||
expect(e.message).toBe(
|
||||
'There can be only one root. No parent could be found for ("fakeRoot")'
|
||||
);
|
||||
}
|
||||
});
|
||||
it('real root in wrong place', function () {
|
||||
var str = `mindmap
|
||||
root
|
||||
fakeRoot
|
||||
realRootWrongPlace`;
|
||||
|
||||
try {
|
||||
mindmap.parse(str);
|
||||
// Fail test if above expression doesn't throw anything.
|
||||
expect(true).toBe(false);
|
||||
} catch (e) {
|
||||
expect(e.message).toBe(
|
||||
'There can be only one root. No parent could be found for ("fakeRoot")'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('nodes', function () {
|
||||
it('should handle an id and type for a node definition', function () {
|
||||
var str = `mindmap
|
||||
root[The root]
|
||||
`;
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.id).toEqual('root');
|
||||
expect(mm.descr).toEqual('The root');
|
||||
expect(mm.type).toEqual(mindmap.yy.nodeType.RECT);
|
||||
});
|
||||
it('should handle an id and type for a node definition', function () {
|
||||
var str = `mindmap
|
||||
root
|
||||
theId(child1)`;
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.descr).toEqual('root');
|
||||
expect(mm.children.length).toEqual(1);
|
||||
const child = mm.children[0];
|
||||
expect(child.descr).toEqual('child1');
|
||||
expect(child.id).toEqual('theId');
|
||||
expect(child.type).toEqual(mindmap.yy.nodeType.ROUNDED_RECT);
|
||||
});
|
||||
it('should handle an id and type for a node definition', function () {
|
||||
var str = `mindmap
|
||||
root
|
||||
theId(child1)`;
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.descr).toEqual('root');
|
||||
expect(mm.children.length).toEqual(1);
|
||||
const child = mm.children[0];
|
||||
expect(child.descr).toEqual('child1');
|
||||
expect(child.id).toEqual('theId');
|
||||
expect(child.type).toEqual(mindmap.yy.nodeType.ROUNDED_RECT);
|
||||
});
|
||||
it('mutiple types (circle)', function () {
|
||||
var str = `mindmap
|
||||
root((the root))
|
||||
`;
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.descr).toEqual('the root');
|
||||
expect(mm.children.length).toEqual(0);
|
||||
expect(mm.type).toEqual(mindmap.yy.nodeType.CIRCLE);
|
||||
});
|
||||
});
|
||||
describe('decorations', function () {
|
||||
it('should be possible to set an icon for the node', function () {
|
||||
var str = `mindmap
|
||||
root[The root]
|
||||
::icon(bomb)
|
||||
`;
|
||||
// ::class1 class2
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.id).toEqual('root');
|
||||
expect(mm.descr).toEqual('The root');
|
||||
expect(mm.type).toEqual(mindmap.yy.nodeType.RECT);
|
||||
expect(mm.icon).toEqual('bomb');
|
||||
});
|
||||
it('should be possible to set classes for the node', function () {
|
||||
var str = `mindmap
|
||||
root[The root]
|
||||
:::m-4 p-8
|
||||
`;
|
||||
// ::class1 class2
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.id).toEqual('root');
|
||||
expect(mm.descr).toEqual('The root');
|
||||
expect(mm.type).toEqual(mindmap.yy.nodeType.RECT);
|
||||
expect(mm.class).toEqual('m-4 p-8');
|
||||
});
|
||||
it('should be possible to set both classes and icon for the node', function () {
|
||||
var str = `mindmap
|
||||
root[The root]
|
||||
:::m-4 p-8
|
||||
::icon(bomb)
|
||||
`;
|
||||
// ::class1 class2
|
||||
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.id).toEqual('root');
|
||||
expect(mm.descr).toEqual('The root');
|
||||
expect(mm.type).toEqual(mindmap.yy.nodeType.RECT);
|
||||
expect(mm.class).toEqual('m-4 p-8');
|
||||
expect(mm.icon).toEqual('bomb');
|
||||
});
|
||||
});
|
||||
describe('descriptions', function () {
|
||||
it('should be possible to use node syntax in the descriptions', function () {
|
||||
var str = `mindmap
|
||||
root["String containing []"]
|
||||
`;
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.id).toEqual('root');
|
||||
expect(mm.descr).toEqual('String containing []');
|
||||
});
|
||||
it('should be possible to use node syntax in the descriptions in children', function () {
|
||||
var str = `mindmap
|
||||
root["String containing []"]
|
||||
child1["String containing ()"]
|
||||
`;
|
||||
mindmap.parse(str);
|
||||
const mm = mindmap.yy.getMindmap();
|
||||
expect(mm.id).toEqual('root');
|
||||
expect(mm.descr).toEqual('String containing []');
|
||||
expect(mm.children.length).toEqual(1);
|
||||
expect(mm.children[0].descr).toEqual('String containing ()');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,94 @@
|
|||
/** Created by knut on 15-01-14. */
|
||||
import { log } from '../../logger';
|
||||
import { sanitizeText } from '../../diagram-api/diagramAPI';
|
||||
|
||||
var message = '';
|
||||
var info = false;
|
||||
const root = {};
|
||||
let nodes = [];
|
||||
|
||||
export const clear = () => {
|
||||
nodes = [];
|
||||
};
|
||||
|
||||
const getParent = function (level) {
|
||||
for (let i = nodes.length - 1; i >= 0; i--) {
|
||||
if (nodes[i].level < level) {
|
||||
return nodes[i];
|
||||
}
|
||||
}
|
||||
// No parent found
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getMindmap = () => {
|
||||
console.log('getMindmap', nodes[0]);
|
||||
return nodes.length > 0 ? nodes[0] : null;
|
||||
};
|
||||
export const addNode = (level, id, descr, type) => {
|
||||
const node = { id: sanitizeText(id), level, descr: sanitizeText(descr), type, children: [] };
|
||||
const parent = getParent(level);
|
||||
if (parent) {
|
||||
parent.children.push(node);
|
||||
// Keep all nodes in the list
|
||||
nodes.push(node);
|
||||
} else {
|
||||
if (nodes.length === 0) {
|
||||
// First node, the root
|
||||
nodes.push(node);
|
||||
} else {
|
||||
// Syntax error ... there can only bee one root
|
||||
let error = new Error(
|
||||
'There can be only one root. No parent could be found for ("' + node.descr + '")'
|
||||
);
|
||||
error.hash = {
|
||||
text: 'branch ' + name,
|
||||
token: 'branch ' + name,
|
||||
line: '1',
|
||||
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
|
||||
expected: ['"checkout ' + name + '"'],
|
||||
};
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const nodeType = {
|
||||
DEFAULT: 0,
|
||||
NO_BORDER: 0,
|
||||
ROUNDED_RECT: 1,
|
||||
RECT: 2,
|
||||
CIRCLE: 3,
|
||||
};
|
||||
|
||||
export const getTypeFromStart = (str) => {
|
||||
switch (str) {
|
||||
case '[':
|
||||
return nodeType.RECT;
|
||||
case '(':
|
||||
return nodeType.ROUNDED_RECT;
|
||||
case '((':
|
||||
return nodeType.CIRCLE;
|
||||
default:
|
||||
return nodeType.DEFAULT;
|
||||
}
|
||||
};
|
||||
export const decorateNode = (decoration) => {
|
||||
console.log('decorateNode', decoration);
|
||||
const node = nodes[nodes.length - 1];
|
||||
if (decoration && decoration.icon) {
|
||||
node.icon = sanitizeText(decoration.icon);
|
||||
}
|
||||
if (decoration && decoration.class) {
|
||||
node.class = sanitizeText(decoration.class);
|
||||
}
|
||||
};
|
||||
export default {
|
||||
getMindmap,
|
||||
addNode,
|
||||
clear,
|
||||
nodeType,
|
||||
getTypeFromStart,
|
||||
decorateNode,
|
||||
// parseError
|
||||
};
|
|
@ -1,48 +0,0 @@
|
|||
/** mermaid
|
||||
* https://knsv.github.io/mermaid
|
||||
* (c) 2015 Knut Sveidqvist
|
||||
* MIT license.
|
||||
*/
|
||||
%lex
|
||||
|
||||
%options case-insensitive
|
||||
|
||||
%{
|
||||
// Pre-lexer code can go here
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
"info" return 'info' ;
|
||||
[\s\n\r]+ return 'NL' ;
|
||||
[\s]+ return 'space';
|
||||
"showInfo" return 'showInfo';
|
||||
<<EOF>> return 'EOF' ;
|
||||
. return 'TXT' ;
|
||||
|
||||
/lex
|
||||
|
||||
%start start
|
||||
|
||||
%% /* language grammar */
|
||||
|
||||
start
|
||||
// %{ : info document 'EOF' { return yy; } }
|
||||
: info document 'EOF' { return yy; }
|
||||
;
|
||||
|
||||
document
|
||||
: /* empty */
|
||||
| document line
|
||||
;
|
||||
|
||||
line
|
||||
: statement { }
|
||||
| 'NL'
|
||||
;
|
||||
|
||||
statement
|
||||
: showInfo { yy.setInfo(true); }
|
||||
;
|
||||
|
||||
%%
|
|
@ -0,0 +1,79 @@
|
|||
/** mermaid
|
||||
* https://knsv.github.io/mermaid
|
||||
* (c) 2015 Knut Sveidqvist
|
||||
* MIT license.
|
||||
*/
|
||||
%lex
|
||||
|
||||
%options case-insensitive
|
||||
|
||||
%{
|
||||
// Pre-lexer code can go here
|
||||
%}
|
||||
%x NODE
|
||||
%x NSTR
|
||||
%x ICON
|
||||
%x CLASS
|
||||
|
||||
%%
|
||||
|
||||
"mindmap" return 'MINDMAP';
|
||||
":::" { this.begin('CLASS'); }
|
||||
<CLASS>.+ { return 'CLASS';this.popState(); }
|
||||
<CLASS>\n { this.popState();}
|
||||
[\n\s]*"::icon(" { this.begin('ICON'); }
|
||||
<ICON>[^\)]+ { return 'ICON'; }
|
||||
<ICON>\) {this.popState();}
|
||||
"((" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"(" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"[" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
[^\(\[\n]+ return 'NODE_ID';
|
||||
[\s]+ return 'SPACELIST' /* skip all whitespace */ ;
|
||||
<<EOF>> return 'EOF';
|
||||
<NODE>["] { console.log('Starting NSTR');this.begin("NSTR");}
|
||||
<NSTR>[^"]+ { console.log('description:', yytext); return "NODE_DESCR";}
|
||||
<NSTR>["] {this.popState();}
|
||||
<NODE>[\)] {this.popState();console.log('node end');return "NODE_DEND";}
|
||||
<NODE>[\]] {this.popState();console.log('node end');return "NODE_DEND";}
|
||||
<NODE>[^\)\]]+ { console.log('Long description:', yytext); return 'NODE_DESCR';}
|
||||
|
||||
[\n]+ /* return 'NL'; */
|
||||
// [\[] return 'NODE_START';
|
||||
// .+ return 'TXT' ;
|
||||
|
||||
/lex
|
||||
|
||||
%start start
|
||||
|
||||
%% /* language grammar */
|
||||
|
||||
start
|
||||
// %{ : info document 'EOF' { return yy; } }
|
||||
: MINDMAP document { return yy; }
|
||||
;
|
||||
|
||||
document
|
||||
: document line
|
||||
| line
|
||||
;
|
||||
|
||||
line
|
||||
: statement { }
|
||||
;
|
||||
|
||||
statement
|
||||
: node
|
||||
| SPACELIST node { yy.addNode($1.length, $2.id, $2.descr, $2.type); }
|
||||
| SPACELIST EOF
|
||||
| SPACELIST ICON { yy.decorateNode({icon: $2}); }
|
||||
| ICON { yy.decorateNode({icon: $1}); }
|
||||
| SPACELIST CLASS { yy.decorateNode({class: $2}); }
|
||||
| CLASS { yy.decorateNode({class: $1}); }
|
||||
| EOF
|
||||
;
|
||||
node
|
||||
: NODE_ID { $$ = { id: $1, descr: $1, type: yy.nodeType.DEFAULT }; }
|
||||
| NODE_ID NODE_DSTART NODE_DESCR NODE_DEND
|
||||
{ $$ = { id: $1, descr: $3, type: yy.getTypeFromStart($2) }; }
|
||||
;
|
||||
%%
|
Loading…
Reference in New Issue