Fixed a regression in sequence diagram parsing.

Added the parser as the first argument to parseDirective to support custom directive handling (for now delegated within mermaidAPI but should probably discriminate based on type for delegation)
This commit is contained in:
chris moran
2020-07-27 06:50:54 -04:00
parent 38d4b5be1a
commit c4ad95760a
9 changed files with 17 additions and 26 deletions

View File

@@ -16,7 +16,7 @@ let classCounter = 0;
let funs = []; let funs = [];
export const parseDirective = function(statement, context, type) { export const parseDirective = function(statement, context, type) {
mermaidAPI.parseDirective(statement, context, type); mermaidAPI.parseDirective(this, statement, context, type);
}; };
const splitClassNameAndType = function(id) { const splitClassNameAndType = function(id) {

View File

@@ -21,7 +21,7 @@ const Identification = {
}; };
export const parseDirective = function(statement, context, type) { export const parseDirective = function(statement, context, type) {
mermaidAPI.parseDirective(statement, context, type); mermaidAPI.parseDirective(this, statement, context, type);
}; };
const addEntity = function(name) { const addEntity = function(name) {

View File

@@ -21,7 +21,7 @@ let direction;
let funs = []; let funs = [];
export const parseDirective = function(statement, context, type) { export const parseDirective = function(statement, context, type) {
mermaidAPI.parseDirective(statement, context, type); mermaidAPI.parseDirective(this, statement, context, type);
}; };
/** /**

View File

@@ -26,12 +26,12 @@
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; } <type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; } <type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive'; <arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */
[\n]+ return 'NEWLINE'; [\n]+ return 'NEWLINE';
\s+ /* skip all whitespace */ \s+ /* skip all whitespace */
<ID,ALIAS,LINE>((?!\n)\s)+ /* skip same-line whitespace */ <ID,ALIAS,LINE>((?!\n)\s)+ /* skip same-line whitespace */
<INITIAL,ID,ALIAS,LINE,arg_directive,type_directive,open_directive>\#[^\n]* /* skip comments */ <INITIAL,ID,ALIAS,LINE,arg_directive,type_directive,open_directive>\#[^\n]* /* skip comments */
\%%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */
"participant" { this.begin('ID'); return 'participant'; } "participant" { this.begin('ID'); return 'participant'; }
<ID>[^\->:\n,;]+?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; } <ID>[^\->:\n,;]+?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } <ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }

View File

@@ -13,7 +13,7 @@ let sequenceNumbersEnabled = false;
let wrapEnabled = false; let wrapEnabled = false;
export const parseDirective = function(statement, context, type) { export const parseDirective = function(statement, context, type) {
mermaidAPI.parseDirective(statement, context, type); mermaidAPI.parseDirective(this, statement, context, type);
}; };
export const addActor = function(id, name, description) { export const addActor = function(id, name, description) {
@@ -140,12 +140,12 @@ export const parseMessage = function(str) {
text: _str.replace(/^[:]?(?:no)?wrap:/, '').trim(), text: _str.replace(/^[:]?(?:no)?wrap:/, '').trim(),
wrap: wrap:
_str.match(/^[:]?(?:no)?wrap:/) === null _str.match(/^[:]?(?:no)?wrap:/) === null
? common.hasBreaks(_str) || autoWrap() ? common.hasBreaks(_str) || undefined
: _str.match(/^[:]?wrap:/) !== null : _str.match(/^[:]?wrap:/) !== null
? true ? true
: _str.match(/^[:]?nowrap:/) !== null : _str.match(/^[:]?nowrap:/) !== null
? false ? false
: autoWrap() : undefined
}; };
logger.debug('parseMessage:', message); logger.debug('parseMessage:', message);
return message; return message;

View File

@@ -932,7 +932,6 @@ describe('when rendering a sequenceDiagram', function() {
parser.yy = sequenceDb; parser.yy = sequenceDb;
parser.yy.clear(); parser.yy.clear();
conf = parser.yy.getConfig(); conf = parser.yy.getConfig();
renderer.bounds.init();
}); });
['tspan', 'fo', 'old', undefined].forEach(function(textPlacement) { ['tspan', 'fo', 'old', undefined].forEach(function(textPlacement) {
it(` it(`

View File

@@ -8,7 +8,7 @@ const tasks = [];
const rawTasks = []; const rawTasks = [];
export const parseDirective = function(statement, context, type) { export const parseDirective = function(statement, context, type) {
mermaidAPI.parseDirective(statement, context, type); mermaidAPI.parseDirective(this, statement, context, type);
}; };
export const clear = function() { export const clear = function() {

View File

@@ -438,7 +438,7 @@ const render = function(id, _txt, cb, container) {
let currentDirective = {}; let currentDirective = {};
const parseDirective = function(statement, context, type) { const parseDirective = function(p, statement, context, type) {
try { try {
if (statement !== undefined) { if (statement !== undefined) {
statement = statement.trim(); statement = statement.trim();
@@ -453,7 +453,7 @@ const parseDirective = function(statement, context, type) {
currentDirective.args = JSON.parse(statement); currentDirective.args = JSON.parse(statement);
break; break;
case 'close_directive': case 'close_directive':
handleDirective(currentDirective, type); handleDirective(p, currentDirective, type);
currentDirective = null; currentDirective = null;
break; break;
} }
@@ -466,7 +466,7 @@ const parseDirective = function(statement, context, type) {
} }
}; };
const handleDirective = function(directive, type) { const handleDirective = function(p, directive, type) {
logger.debug(`Directive type=${directive.type} with args:`, directive.args); logger.debug(`Directive type=${directive.type} with args:`, directive.args);
switch (directive.type) { switch (directive.type) {
case 'init': case 'init':
@@ -486,17 +486,9 @@ const handleDirective = function(directive, type) {
} }
case 'wrap': case 'wrap':
case 'nowrap': case 'nowrap':
directive.args = { config: { wrap: directive.type === 'wrap' } }; if (p && p['setWrap']) {
['config'].forEach(prop => { p.setWrap(directive.type === 'wrap');
if (typeof directive.args[prop] !== 'undefined') { }
if (type === 'flowchart-v2') {
type = 'flowchart';
}
directive.args[type] = directive.args[prop];
delete directive.args[prop];
}
});
reinitialize(directive.args);
break; break;
default: default:
logger.warn( logger.warn(

View File

@@ -116,13 +116,13 @@ Alice->Bob: hi`;
}); });
it('should handle an init definition with config converted to the proper diagram configuration', function() { it('should handle an init definition with config converted to the proper diagram configuration', function() {
const str = ` const str = `
%%{init: { 'logLevel': 0, 'theme': 'dark', 'config': {'wrapEnabled': true} } }%% %%{init: { 'logLevel': 0, 'theme': 'dark', 'config': {'wrap': true} } }%%
sequenceDiagram sequenceDiagram
Alice->Bob: hi`; Alice->Bob: hi`;
const type = utils.detectType(str); const type = utils.detectType(str);
const init = utils.detectInit(str); const init = utils.detectInit(str);
expect(type).toBe('sequence'); expect(type).toBe('sequence');
expect(init).toEqual({logLevel:0, theme:"dark", sequence: { wrapEnabled: true }}); expect(init).toEqual({logLevel:0, theme:"dark", sequence: { wrap: true }});
}); });
it('should handle a multiline init definition', function() { it('should handle a multiline init definition', function() {
const str = ` const str = `