2019-09-21 08:19:55 -07:00
|
|
|
import { logger } from '../../logger';
|
2020-04-02 19:35:12 +02:00
|
|
|
import { generateId } from '../../utils';
|
2020-07-27 19:44:45 -04:00
|
|
|
import mermaidAPI from '../../mermaidAPI';
|
2020-07-29 18:38:59 +02:00
|
|
|
import * as configApi from '../../config';
|
2020-04-02 19:35:12 +02:00
|
|
|
|
|
|
|
const clone = o => JSON.parse(JSON.stringify(o));
|
2019-09-21 08:19:55 -07:00
|
|
|
|
2019-10-03 19:08:15 +02:00
|
|
|
let rootDoc = [];
|
2020-07-27 19:44:45 -04:00
|
|
|
|
|
|
|
export const parseDirective = function(statement, context, type) {
|
|
|
|
mermaidAPI.parseDirective(this, statement, context, type);
|
|
|
|
};
|
|
|
|
|
2019-10-03 19:08:15 +02:00
|
|
|
const setRootDoc = o => {
|
2019-10-06 16:06:15 +02:00
|
|
|
logger.info('Setting root doc', o);
|
2020-03-30 22:08:48 +02:00
|
|
|
// rootDoc = { id: 'root', doc: o };
|
|
|
|
rootDoc = o;
|
2019-10-03 19:08:15 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const getRootDoc = () => rootDoc;
|
|
|
|
|
2020-03-25 20:16:27 +01:00
|
|
|
const docTranslator = (parent, node, first) => {
|
|
|
|
if (node.stmt === 'relation') {
|
|
|
|
docTranslator(parent, node.state1, true);
|
|
|
|
docTranslator(parent, node.state2, false);
|
|
|
|
} else {
|
|
|
|
if (node.stmt === 'state') {
|
|
|
|
if (node.id === '[*]') {
|
|
|
|
node.id = first ? parent.id + '_start' : parent.id + '_end';
|
|
|
|
node.start = first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (node.doc) {
|
2020-04-02 19:35:12 +02:00
|
|
|
const doc = [];
|
|
|
|
// Check for concurrency
|
|
|
|
let i = 0;
|
|
|
|
let currentDoc = [];
|
|
|
|
for (i = 0; i < node.doc.length; i++) {
|
|
|
|
if (node.doc[i].type === 'divider') {
|
|
|
|
// debugger;
|
|
|
|
const newNode = clone(node.doc[i]);
|
|
|
|
newNode.doc = clone(currentDoc);
|
|
|
|
doc.push(newNode);
|
|
|
|
currentDoc = [];
|
|
|
|
} else {
|
|
|
|
currentDoc.push(node.doc[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If any divider was encountered
|
|
|
|
if (doc.length > 0 && currentDoc.length > 0) {
|
|
|
|
const newNode = {
|
|
|
|
stmt: 'state',
|
|
|
|
id: generateId(),
|
|
|
|
type: 'divider',
|
|
|
|
doc: clone(currentDoc)
|
|
|
|
};
|
|
|
|
doc.push(clone(newNode));
|
|
|
|
node.doc = doc;
|
|
|
|
}
|
|
|
|
|
2020-03-25 20:16:27 +01:00
|
|
|
node.doc.forEach(docNode => docTranslator(node, docNode, true));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const getRootDocV2 = () => {
|
2020-03-30 22:08:48 +02:00
|
|
|
docTranslator({ id: 'root' }, { id: 'root', doc: rootDoc }, true);
|
|
|
|
return { id: 'root', doc: rootDoc };
|
2020-03-25 20:16:27 +01:00
|
|
|
};
|
|
|
|
|
2020-04-02 19:35:12 +02:00
|
|
|
const extract = _doc => {
|
2019-10-27 15:24:56 +01:00
|
|
|
// const res = { states: [], relations: [] };
|
2020-04-02 19:35:12 +02:00
|
|
|
let doc;
|
|
|
|
if (_doc.doc) {
|
|
|
|
doc = _doc.doc;
|
|
|
|
} else {
|
|
|
|
doc = _doc;
|
|
|
|
}
|
2020-03-30 22:08:48 +02:00
|
|
|
// let doc = root.doc;
|
|
|
|
// if (!doc) {
|
|
|
|
// doc = root;
|
|
|
|
// }
|
|
|
|
logger.info(doc);
|
2019-10-03 19:08:15 +02:00
|
|
|
clear();
|
2019-10-05 10:02:58 +02:00
|
|
|
|
2020-04-02 19:35:12 +02:00
|
|
|
logger.info('Extract', doc);
|
|
|
|
|
2019-10-03 19:08:15 +02:00
|
|
|
doc.forEach(item => {
|
|
|
|
if (item.stmt === 'state') {
|
2019-10-06 10:52:37 +02:00
|
|
|
addState(item.id, item.type, item.doc, item.description, item.note);
|
2019-10-03 19:08:15 +02:00
|
|
|
}
|
|
|
|
if (item.stmt === 'relation') {
|
|
|
|
addRelation(item.state1.id, item.state2.id, item.description);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2019-10-02 19:32:13 +02:00
|
|
|
const newDoc = () => {
|
|
|
|
return {
|
|
|
|
relations: [],
|
|
|
|
states: {},
|
|
|
|
documents: {}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
let documents = {
|
|
|
|
root: newDoc()
|
|
|
|
};
|
|
|
|
|
|
|
|
let currentDocument = documents.root;
|
2019-09-21 08:19:55 -07:00
|
|
|
|
2019-09-25 21:29:32 +02:00
|
|
|
let startCnt = 0;
|
2019-10-27 15:24:56 +01:00
|
|
|
let endCnt = 0; // eslint-disable-line
|
|
|
|
// let stateCnt = 0;
|
2019-09-25 21:29:32 +02:00
|
|
|
|
2019-09-21 08:19:55 -07:00
|
|
|
/**
|
|
|
|
* Function called by parser when a node definition has been found.
|
|
|
|
* @param id
|
|
|
|
* @param text
|
|
|
|
* @param type
|
|
|
|
* @param style
|
|
|
|
*/
|
2019-10-06 10:52:37 +02:00
|
|
|
export const addState = function(id, type, doc, descr, note) {
|
2019-10-02 19:32:13 +02:00
|
|
|
if (typeof currentDocument.states[id] === 'undefined') {
|
|
|
|
currentDocument.states[id] = {
|
2019-09-21 08:19:55 -07:00
|
|
|
id: id,
|
2019-09-25 21:29:32 +02:00
|
|
|
descriptions: [],
|
2019-10-03 19:08:15 +02:00
|
|
|
type,
|
2019-10-06 10:52:37 +02:00
|
|
|
doc,
|
|
|
|
note
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|
2019-10-03 19:08:15 +02:00
|
|
|
} else {
|
|
|
|
if (!currentDocument.states[id].doc) {
|
|
|
|
currentDocument.states[id].doc = doc;
|
|
|
|
}
|
|
|
|
if (!currentDocument.states[id].type) {
|
|
|
|
currentDocument.states[id].type = type;
|
|
|
|
}
|
2019-09-21 08:19:55 -07:00
|
|
|
}
|
2019-10-23 19:22:36 +02:00
|
|
|
if (descr) {
|
2020-04-26 09:47:47 +02:00
|
|
|
logger.info('Adding state ', id, descr);
|
2019-10-23 19:22:36 +02:00
|
|
|
if (typeof descr === 'string') addDescription(id, descr.trim());
|
|
|
|
|
|
|
|
if (typeof descr === 'object') {
|
|
|
|
descr.forEach(des => addDescription(id, des.trim()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-06 10:52:37 +02:00
|
|
|
if (note) currentDocument.states[id].note = note;
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
export const clear = function() {
|
2019-10-02 19:32:13 +02:00
|
|
|
documents = {
|
|
|
|
root: newDoc()
|
|
|
|
};
|
2019-10-03 19:08:15 +02:00
|
|
|
currentDocument = documents.root;
|
2020-05-27 22:18:59 +02:00
|
|
|
|
|
|
|
currentDocument = documents.root;
|
|
|
|
|
|
|
|
startCnt = 0;
|
|
|
|
endCnt = 0; // eslint-disable-line
|
|
|
|
classes = [];
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|
|
|
|
|
2019-09-25 21:01:21 +02:00
|
|
|
export const getState = function(id) {
|
2019-10-02 19:32:13 +02:00
|
|
|
return currentDocument.states[id];
|
|
|
|
};
|
2019-10-05 10:02:58 +02:00
|
|
|
|
2019-09-25 21:29:32 +02:00
|
|
|
export const getStates = function() {
|
2019-10-02 19:32:13 +02:00
|
|
|
return currentDocument.states;
|
|
|
|
};
|
|
|
|
export const logDocuments = function() {
|
2019-10-06 16:06:15 +02:00
|
|
|
logger.info('Documents = ', documents);
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|
|
|
|
export const getRelations = function() {
|
2019-10-02 19:32:13 +02:00
|
|
|
return currentDocument.relations;
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|
|
|
|
|
2019-09-28 13:31:10 +02:00
|
|
|
export const addRelation = function(_id1, _id2, title) {
|
2019-09-25 21:29:32 +02:00
|
|
|
let id1 = _id1;
|
|
|
|
let id2 = _id2;
|
|
|
|
let type1 = 'default';
|
|
|
|
let type2 = 'default';
|
|
|
|
if (_id1 === '[*]') {
|
|
|
|
startCnt++;
|
|
|
|
id1 = 'start' + startCnt;
|
|
|
|
type1 = 'start';
|
|
|
|
}
|
|
|
|
if (_id2 === '[*]') {
|
|
|
|
endCnt++;
|
|
|
|
id2 = 'end' + startCnt;
|
|
|
|
type2 = 'end';
|
|
|
|
}
|
|
|
|
addState(id1, type1);
|
|
|
|
addState(id2, type2);
|
2019-10-02 19:32:13 +02:00
|
|
|
currentDocument.relations.push({ id1, id2, title });
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|
|
|
|
|
2019-10-05 12:15:14 +02:00
|
|
|
const addDescription = function(id, _descr) {
|
2019-10-02 19:32:13 +02:00
|
|
|
const theState = currentDocument.states[id];
|
2019-09-29 15:50:43 +02:00
|
|
|
let descr = _descr;
|
|
|
|
if (descr[0] === ':') {
|
|
|
|
descr = descr.substr(1).trim();
|
2019-09-21 08:19:55 -07:00
|
|
|
}
|
2019-09-29 15:50:43 +02:00
|
|
|
|
|
|
|
theState.descriptions.push(descr);
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
export const cleanupLabel = function(label) {
|
|
|
|
if (label.substring(0, 1) === ':') {
|
|
|
|
return label.substr(2).trim();
|
|
|
|
} else {
|
|
|
|
return label.trim();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const lineType = {
|
|
|
|
LINE: 0,
|
|
|
|
DOTTED_LINE: 1
|
|
|
|
};
|
|
|
|
|
2019-10-06 15:44:31 +02:00
|
|
|
let dividerCnt = 0;
|
|
|
|
const getDividerId = () => {
|
|
|
|
dividerCnt++;
|
|
|
|
return 'divider-id-' + dividerCnt;
|
|
|
|
};
|
|
|
|
|
2020-05-27 22:18:59 +02:00
|
|
|
let classes = [];
|
2020-03-22 21:45:14 +01:00
|
|
|
|
|
|
|
const getClasses = () => classes;
|
|
|
|
|
|
|
|
const getDirection = () => 'TB';
|
|
|
|
|
2019-09-21 08:19:55 -07:00
|
|
|
export const relationType = {
|
|
|
|
AGGREGATION: 0,
|
|
|
|
EXTENSION: 1,
|
|
|
|
COMPOSITION: 2,
|
|
|
|
DEPENDENCY: 3
|
|
|
|
};
|
|
|
|
|
2020-03-29 14:20:49 +02:00
|
|
|
const trimColon = str => (str && str[0] === ':' ? str.substr(1).trim() : str.trim());
|
|
|
|
|
2019-09-21 08:19:55 -07:00
|
|
|
export default {
|
2020-07-27 19:44:45 -04:00
|
|
|
parseDirective,
|
|
|
|
getConfig: () => configApi.getConfig().state,
|
2019-09-25 21:01:21 +02:00
|
|
|
addState,
|
2019-09-21 08:19:55 -07:00
|
|
|
clear,
|
2019-09-25 21:01:21 +02:00
|
|
|
getState,
|
2019-09-25 21:29:32 +02:00
|
|
|
getStates,
|
2019-09-21 08:19:55 -07:00
|
|
|
getRelations,
|
2020-03-22 21:45:14 +01:00
|
|
|
getClasses,
|
|
|
|
getDirection,
|
2019-09-21 08:19:55 -07:00
|
|
|
addRelation,
|
2019-10-06 15:44:31 +02:00
|
|
|
getDividerId,
|
2019-10-05 12:15:14 +02:00
|
|
|
// addDescription,
|
2019-09-21 08:19:55 -07:00
|
|
|
cleanupLabel,
|
|
|
|
lineType,
|
2019-10-02 19:32:13 +02:00
|
|
|
relationType,
|
|
|
|
logDocuments,
|
2019-10-03 19:08:15 +02:00
|
|
|
getRootDoc,
|
|
|
|
setRootDoc,
|
2020-03-25 20:16:27 +01:00
|
|
|
getRootDocV2,
|
2020-03-29 14:20:49 +02:00
|
|
|
extract,
|
|
|
|
trimColon
|
2019-09-21 08:19:55 -07:00
|
|
|
};
|