mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-15 06:19:24 +02:00
#3061 Log handing and other fixes, error handling in diagram creation
This commit is contained in:
@@ -97,7 +97,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
||||
|
||||
if (watch && config.build) {
|
||||
config.build.watch = {
|
||||
include: 'src/**',
|
||||
include: ['packages/mermaid-mindmap/src/**', 'packages/mermaid/src/**'],
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -45,12 +45,12 @@
|
||||
</head>
|
||||
<body>
|
||||
<div>Security check</div>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
flowchart LR
|
||||
A --> B
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid">
|
||||
mindmap
|
||||
flowchart LR
|
||||
A -> B
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
mindmap((
|
||||
root
|
||||
ch1
|
||||
ch2
|
||||
@@ -71,6 +71,10 @@ flowchart LR
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -29,7 +29,7 @@
|
||||
"clean": "rimraf dist",
|
||||
"build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts",
|
||||
"build:types": "concurrently \"tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly\" \"tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly\"",
|
||||
"build:watch": "pnpm build:code --watch",
|
||||
"build:watch": "pnpm build:vite --watch",
|
||||
"build": "pnpm clean; concurrently \"pnpm build:vite\" \"pnpm build:types\"",
|
||||
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server\"",
|
||||
"docs:build": "ts-node-esm --transpileOnly packages/mermaid/src/docs.mts",
|
||||
|
@@ -41,10 +41,13 @@ export const injectUtils = (
|
||||
_sanitizeText: any,
|
||||
_setupGraphViewbox: any
|
||||
) => {
|
||||
_log.info('Mermaid utils injected');
|
||||
log.trace = _log.trace;
|
||||
log.debug = _log.debug;
|
||||
log.info = _log.info;
|
||||
log.warn = _log.warn;
|
||||
log.error = _log.error;
|
||||
log.fatal = _log.fatal;
|
||||
setLogLevel = _setLogLevel;
|
||||
getConfig = _getConfig;
|
||||
sanitizeText = _sanitizeText;
|
||||
@@ -55,6 +58,7 @@ export const injectUtils = (
|
||||
const warning = (..._args: any[]) => {
|
||||
console.error('Log function was called before initialization');
|
||||
};
|
||||
|
||||
export let log = {
|
||||
trace: warning,
|
||||
debug: warning,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/** Created by knut on 15-01-14. */
|
||||
import { sanitizeText, getConfig, log as _log } from './mermaidUtils';
|
||||
import { sanitizeText, getConfig, log } from './mermaidUtils';
|
||||
|
||||
let nodes = [];
|
||||
let cnt = 0;
|
||||
@@ -131,9 +131,19 @@ export const type2Str = (type) => {
|
||||
return 'no-border';
|
||||
}
|
||||
};
|
||||
|
||||
export let parseError; // = (str, hash)
|
||||
// => {
|
||||
// const error = { str, hash };
|
||||
// throw error;
|
||||
// };
|
||||
export const setErrorHandler = (handler) => {
|
||||
parseError = handler;
|
||||
};
|
||||
|
||||
// Expose logger to grammar
|
||||
export const log = _log;
|
||||
export let graphType = 'mindmap';
|
||||
export const getLogger = () => log;
|
||||
|
||||
export const getNodeById = (id) => nodes[id];
|
||||
export const getElementById = (id) => elements[id];
|
||||
// export default {
|
||||
|
@@ -215,51 +215,53 @@ function positionNodes(node, conf) {
|
||||
* @param {any} version
|
||||
* @param diagObj
|
||||
*/
|
||||
|
||||
export const draw = (text, id, version, diagObj) => {
|
||||
const conf = getConfig();
|
||||
try {
|
||||
log.debug('Renering info diagram\n' + text);
|
||||
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
// Parse the graph definition
|
||||
// This is done only for throwing the error if the text is not valid.
|
||||
diagObj.db.clear();
|
||||
// Parse the graph definition
|
||||
diagObj.parser.parse(text);
|
||||
|
||||
const svg = root.select('#' + id);
|
||||
log.debug('Renering info diagram\n' + text);
|
||||
|
||||
svg.append('g');
|
||||
const mm = diagObj.db.getMindmap();
|
||||
|
||||
// Draw the graph and start with drawing the nodes without proper position
|
||||
// this gives us the size of the nodes and we can set the positions later
|
||||
|
||||
const edgesElem = svg.append('g');
|
||||
edgesElem.attr('class', 'mindmap-edges');
|
||||
const nodesElem = svg.append('g');
|
||||
nodesElem.attr('class', 'mindmap-nodes');
|
||||
drawNodes(nodesElem, mm, -1, conf);
|
||||
|
||||
// Next step is to layout the mindmap, giving each node a position
|
||||
|
||||
const positionedMindmap = layoutMindmap(mm, conf);
|
||||
|
||||
// After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
|
||||
positionNodes(positionedMindmap, conf);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
} catch (e) {
|
||||
log.error('Error while rendering info diagram');
|
||||
log.error(e.message);
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and Document for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
// Parse the graph definition
|
||||
|
||||
const svg = root.select('#' + id);
|
||||
|
||||
svg.append('g');
|
||||
const mm = diagObj.db.getMindmap();
|
||||
|
||||
// Draw the graph and start with drawing the nodes without proper position
|
||||
// this gives us the size of the nodes and we can set the positions later
|
||||
|
||||
const edgesElem = svg.append('g');
|
||||
edgesElem.attr('class', 'mindmap-edges');
|
||||
const nodesElem = svg.append('g');
|
||||
nodesElem.attr('class', 'mindmap-nodes');
|
||||
drawNodes(nodesElem, mm, -1, conf);
|
||||
|
||||
// Next step is to layout the mindmap, giving each node a position
|
||||
|
||||
const positionedMindmap = layoutMindmap(mm, conf);
|
||||
|
||||
// After this we can draw, first the edges and the then nodes with the correct position
|
||||
drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
|
||||
positionNodes(positionedMindmap, conf);
|
||||
|
||||
// Setup the view box and size of the svg element
|
||||
setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@@ -17,21 +17,21 @@
|
||||
|
||||
%%
|
||||
|
||||
\s*\%\%.* {yy.log.trace('Found comment',yytext);}
|
||||
\s*\%\%.* {yy.getLogger().trace('Found comment',yytext);}
|
||||
// \%\%[^\n]*\n /* skip comments */
|
||||
"mindmap" return 'MINDMAP';
|
||||
":::" { this.begin('CLASS'); }
|
||||
<CLASS>.+ { this.popState();return 'CLASS'; }
|
||||
<CLASS>\n { this.popState();}
|
||||
// [\s]*"::icon(" { this.begin('ICON'); }
|
||||
"::icon(" { yy.log.trace('Begin icon');this.begin('ICON'); }
|
||||
"::icon(" { yy.getLogger().trace('Begin icon');this.begin('ICON'); }
|
||||
[\n]+ return 'NL';
|
||||
<ICON>[^\)]+ { return 'ICON'; }
|
||||
<ICON>\) {yy.log.trace('end icon');this.popState();}
|
||||
"-)" { yy.log.trace('Exploding node'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"(-" { yy.log.trace('Cloud'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"))" { yy.log.trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
")" { yy.log.trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
<ICON>\) {yy.getLogger().trace('end icon');this.popState();}
|
||||
"-)" { yy.getLogger().trace('Exploding node'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"(-" { yy.getLogger().trace('Cloud'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"))" { yy.getLogger().trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
")" { yy.getLogger().trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"((" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"(" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
"[" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||
@@ -39,18 +39,18 @@
|
||||
// !(-\() return 'NODE_ID';
|
||||
[^\(\[\n\-\)]+ return 'NODE_ID';
|
||||
<<EOF>> return 'EOF';
|
||||
<NODE>["] { yy.log.trace('Starting NSTR');this.begin("NSTR");}
|
||||
<NSTR>[^"]+ { yy.log.trace('description:', yytext); return "NODE_DESCR";}
|
||||
<NODE>["] { yy.getLogger().trace('Starting NSTR');this.begin("NSTR");}
|
||||
<NSTR>[^"]+ { yy.getLogger().trace('description:', yytext); return "NODE_DESCR";}
|
||||
<NSTR>["] {this.popState();}
|
||||
<NODE>[\)]\) {this.popState();yy.log.trace('node end ))');return "NODE_DEND";}
|
||||
<NODE>[\)] {this.popState();yy.log.trace('node end )');return "NODE_DEND";}
|
||||
<NODE>[\]] {this.popState();yy.log.trace('node end ...',yytext);return "NODE_DEND";}
|
||||
<NODE>"(-" {this.popState();yy.log.trace('node end (-');return "NODE_DEND";}
|
||||
<NODE>"-)" {this.popState();yy.log.trace('node end (-');return "NODE_DEND";}
|
||||
<NODE>"((" {this.popState();yy.log.trace('node end ((');return "NODE_DEND";}
|
||||
<NODE>"(" {this.popState();yy.log.trace('node end ((');return "NODE_DEND";}
|
||||
<NODE>[^\)\]\(]+ { yy.log.trace('Long description:', yytext); return 'NODE_DESCR';}
|
||||
<NODE>.+(?!\(\() { yy.log.trace('Long description:', yytext); return 'NODE_DESCR';}
|
||||
<NODE>[\)]\) {this.popState();yy.getLogger().trace('node end ))');return "NODE_DEND";}
|
||||
<NODE>[\)] {this.popState();yy.getLogger().trace('node end )');return "NODE_DEND";}
|
||||
<NODE>[\]] {this.popState();yy.getLogger().trace('node end ...',yytext);return "NODE_DEND";}
|
||||
<NODE>"(-" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
|
||||
<NODE>"-)" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
|
||||
<NODE>"((" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
|
||||
<NODE>"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
|
||||
<NODE>[^\)\]\(]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';}
|
||||
<NODE>.+(?!\(\() { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';}
|
||||
// [\[] return 'NODE_START';
|
||||
// .+ return 'TXT' ;
|
||||
|
||||
@@ -68,10 +68,10 @@ start
|
||||
;
|
||||
|
||||
stop
|
||||
: NL {yy.log.trace('Stop NL ');}
|
||||
| EOF {yy.log.trace('Stop EOF ');}
|
||||
| stop NL {yy.log.trace('Stop NL2 ');}
|
||||
| stop EOF {yy.log.trace('Stop EOF2 ');}
|
||||
: NL {yy.getLogger().trace('Stop NL ');}
|
||||
| EOF {yy.getLogger().trace('Stop EOF ');}
|
||||
| stop NL {yy.getLogger().trace('Stop NL2 ');}
|
||||
| stop EOF {yy.getLogger().trace('Stop EOF2 ');}
|
||||
;
|
||||
document
|
||||
: document statement stop
|
||||
@@ -79,10 +79,10 @@ document
|
||||
;
|
||||
|
||||
statement
|
||||
: SPACELIST node { yy.log.trace('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); }
|
||||
| SPACELIST ICON { yy.log.trace('Icon: ',$2);yy.decorateNode({icon: $2}); }
|
||||
: SPACELIST node { yy.getLogger().trace('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); }
|
||||
| SPACELIST ICON { yy.getLogger().trace('Icon: ',$2);yy.decorateNode({icon: $2}); }
|
||||
| SPACELIST CLASS { yy.decorateNode({class: $2}); }
|
||||
| node { yy.log.trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); }
|
||||
| node { yy.getLogger().trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); }
|
||||
| ICON { yy.decorateNode({icon: $1}); }
|
||||
| CLASS { yy.decorateNode({class: $1}); }
|
||||
| SPACELIST
|
||||
@@ -97,12 +97,12 @@ node
|
||||
|
||||
nodeWithoutId
|
||||
: NODE_DSTART NODE_DESCR NODE_DEND
|
||||
{ yy.log.trace("node found ..", $1); $$ = { id: $2, descr: $2, type: yy.getType($1, $3) }; }
|
||||
{ yy.getLogger().trace("node found ..", $1); $$ = { id: $2, descr: $2, type: yy.getType($1, $3) }; }
|
||||
;
|
||||
|
||||
nodeWithId
|
||||
: NODE_ID { $$ = { id: $1, descr: $1, type: yy.nodeType.DEFAULT }; }
|
||||
| NODE_ID NODE_DSTART NODE_DESCR NODE_DEND
|
||||
{ yy.log.trace("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getType($2, $4) }; }
|
||||
{ yy.getLogger().trace("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getType($2, $4) }; }
|
||||
;
|
||||
%%
|
||||
|
@@ -5,10 +5,10 @@ if (typeof document !== 'undefined') {
|
||||
if (window.mermaid && typeof window.mermaid.detectors === 'object') {
|
||||
window.mermaid.detectors.push({ id: 'mindmap', detector: mindmapDetector });
|
||||
} else {
|
||||
console.error('window.mermaid.detectors not found'); // eslint-disable-line no-console
|
||||
// console.error('window.mermaid.detectors was not found!'); // eslint-disable-line no-console
|
||||
window.mermaid = {};
|
||||
window.mermaid.detectors = [{ id: 'mindmap', detector: mindmapDetector }];
|
||||
console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console
|
||||
// console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@@ -15,33 +15,19 @@ export class Diagram {
|
||||
this.type = detectType(txt, cnf);
|
||||
const diagram = getDiagram(this.type);
|
||||
log.debug('Type ' + this.type);
|
||||
// console.log('Type ' + this.type);
|
||||
// Setup diagram
|
||||
this.db = diagram.db;
|
||||
this.db.clear?.();
|
||||
this.renderer = diagram.renderer;
|
||||
this.parser = diagram.parser;
|
||||
// console.log('Setting db to !', this.db);
|
||||
this.parser.parser.yy = this.db;
|
||||
if (diagram.init) {
|
||||
diagram.init(cnf);
|
||||
log.debug('Initialized diagram ' + this.type, cnf);
|
||||
}
|
||||
this.txt += '\n';
|
||||
try {
|
||||
this.parser.parser.yy.graphType = this.type;
|
||||
this.parser.parser.yy.parseError = (str: string, hash: string) => {
|
||||
const error = { str, hash };
|
||||
throw error;
|
||||
};
|
||||
} catch (error) {
|
||||
log.error('error', error);
|
||||
}
|
||||
try {
|
||||
this.parse(this.txt, parseError);
|
||||
} catch (error) {
|
||||
log.error('error', error);
|
||||
}
|
||||
|
||||
this.parse(this.txt, parseError);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
|
@@ -53,7 +53,7 @@ const init = function (
|
||||
callback?: Function
|
||||
) {
|
||||
try {
|
||||
console.error('Detectors in init', mermaid.detectors); // eslint-disable-line
|
||||
log.info('Detectors in init', mermaid.detectors); // eslint-disable-line
|
||||
mermaid.detectors.forEach(({ id, detector }) => {
|
||||
addDetector(id, detector);
|
||||
});
|
||||
|
Reference in New Issue
Block a user