add par statement to sequenceDiagram

This commit is contained in:
Minoru Nakata 2017-02-02 17:16:26 +09:00
parent 96be32225e
commit 38c5e65c35
6 changed files with 136 additions and 13 deletions

View File

@ -34,6 +34,8 @@
"opt" { this.begin('LINE'); return 'opt'; }
"alt" { this.begin('LINE'); return 'alt'; }
"else" { this.begin('LINE'); return 'else'; }
"par" { this.begin('LINE'); return 'par'; }
"and" { this.begin('LINE'); return 'and'; }
<LINE>[^#\n;]* { this.popState(); return 'restOfLine'; }
"end" return 'end';
"left of" return 'left_of';
@ -115,6 +117,20 @@ statement
$3.push({type: 'altEnd', signalType: yy.LINETYPE.ALT_END});
$$=$3;}
| par restOfLine par_sections end
{
// Parallel start
$3.unshift({type: 'parStart', parText:$2, signalType: yy.LINETYPE.PAR_START});
// Content in par is already in $3
// End
$3.push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END});
$$=$3;}
;
par_sections
: document
| document and restOfLine par_sections
{ $$ = $1.concat([{type: 'and', parText:$3, signalType: yy.LINETYPE.PAR_AND}, $4]); }
;
note_statement

View File

@ -71,7 +71,10 @@ exports.LINETYPE = {
OPT_START : 15 ,
OPT_END : 16 ,
ACTIVE_START : 17 ,
ACTIVE_END : 18
ACTIVE_END : 18 ,
PAR_START : 19 ,
PAR_AND : 20 ,
PAR_END : 21
};
exports.ARROWTYPE = {
@ -156,6 +159,16 @@ exports.apply = function(param){
break;
case 'setTitle':
exports.setTitle(param.text);
break;
case 'parStart':
exports.addSignal(undefined, undefined, param.parText, param.signalType);
break;
case 'and':
exports.addSignal(undefined, undefined, param.parText, param.signalType);
break;
case 'parEnd':
exports.addSignal(undefined, undefined, undefined, param.signalType);
break;
}
}
};

View File

@ -448,6 +448,32 @@ describe('when parsing a sequenceDiagram',function() {
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should handle par statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'par Parallel one\n' +
'Alice->>Bob: Hello Bob, how are you?\n' +
'Bob-->>Alice: I am good thanks!\n' +
'and Parallel two\n' +
'Alice->>Bob: Are you OK?\n' +
'Bob-->>Alice: Fine!\n' +
'and Parallel three\n' +
'Alice->>Bob: What do you think about it?\n' +
'Bob-->>Alice: It\'s good!\n' +
'end';
sq.parse(str);
var actors = sq.yy.getActors();
expect(actors.Alice.description).toBe('Alice');
expect(actors.Bob.description).toBe('Bob');
var messages = sq.yy.getMessages();
expect(messages.length).toBe(10);
expect(messages[0].message).toBe('Parallel one');
expect(messages[1].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle special characters in signals', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: -:<>,;# comment';
@ -506,6 +532,21 @@ describe('when parsing a sequenceDiagram',function() {
expect(messages[1].message).toBe('-:<>,');
expect(messages[3].message).toBe(',<>:-');
});
it('it should handle special characters in par', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'par -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'and ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
expect(messages[3].message).toBe(',<>:-');
});
it('it should handle no-label loop', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
@ -543,6 +584,23 @@ describe('when parsing a sequenceDiagram',function() {
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('');
expect(messages[2].message).toBe('I am good thanks!');
expect(messages[3].message).toBe('');
expect(messages[4].message).toBe('I am good thanks!');
});
it('it should handle no-label par', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'par;' +
'Bob-->Alice: I am good thanks!\n' +
'and # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end';
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages[1].message).toBe('');
expect(messages[2].message).toBe('I am good thanks!');

View File

@ -134,10 +134,12 @@ exports.bounds = {
var loop = this.sequenceItems.pop();
return loop;
},
addElseToLoop:function(message){
addSectionToLoop: function(message) {
var loop = this.sequenceItems.pop();
loop.elsey = exports.bounds.getVerticalPos();
loop.elseText = message;
loop.sections = loop.sections || [];
loop.sectionTitles = loop.sectionTitles || [];
loop.sections.push(exports.bounds.getVerticalPos());
loop.sectionTitles.push(message);
this.sequenceItems.push(loop);
},
bumpVerticalPos:function(bump){
@ -424,10 +426,8 @@ module.exports.draw = function (text, id) {
exports.bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin);
break;
case sq.yy.LINETYPE.ALT_ELSE:
//exports.drawLoop(diagram, loopData);
exports.bounds.bumpVerticalPos(conf.boxMargin);
loopData = exports.bounds.addElseToLoop(msg.message);
loopData = exports.bounds.addSectionToLoop(msg.message);
exports.bounds.bumpVerticalPos(conf.boxMargin);
break;
case sq.yy.LINETYPE.ALT_END:
@ -436,6 +436,21 @@ module.exports.draw = function (text, id) {
svgDraw.drawLoop(diagram, loopData,'alt', conf);
exports.bounds.bumpVerticalPos(conf.boxMargin);
break;
case sq.yy.LINETYPE.PAR_START:
exports.bounds.bumpVerticalPos(conf.boxMargin);
exports.bounds.newLoop(msg.message);
exports.bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin);
break;
case sq.yy.LINETYPE.PAR_AND:
exports.bounds.bumpVerticalPos(conf.boxMargin);
loopData = exports.bounds.addSectionToLoop(msg.message);
exports.bounds.bumpVerticalPos(conf.boxMargin);
break;
case sq.yy.LINETYPE.PAR_END:
loopData = exports.bounds.endLoop();
svgDraw.drawLoop(diagram, loopData, 'par', conf);
exports.bounds.bumpVerticalPos(conf.boxMargin);
break;
default:
try {
lastMsg = msg;

View File

@ -158,8 +158,10 @@ exports.drawLoop = function(elem,bounds,labelText, conf){
drawLoopLine(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy );
drawLoopLine(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy );
drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy );
if(typeof bounds.elsey !== 'undefined'){
drawLoopLine(bounds.startx, bounds.elsey, bounds.stopx, bounds.elsey).style('stroke-dasharray', '3, 3');
if (typeof bounds.sections !== 'undefined') {
bounds.sections.forEach(function(item) {
drawLoopLine(bounds.startx, item, bounds.stopx, item).style('stroke-dasharray', '3, 3');
});
}
var txt = exports.getTextObj();
@ -181,10 +183,14 @@ exports.drawLoop = function(elem,bounds,labelText, conf){
exports.drawText(g,txt);
if (typeof bounds.elseText !== 'undefined' && bounds.elseText !== "") {
txt.text = '[ ' + bounds.elseText + ' ]';
txt.y = bounds.elsey + 1.5 * conf.boxMargin;
exports.drawText(g, txt);
if (typeof bounds.sectionTitles !== 'undefined') {
bounds.sectionTitles.forEach(function(item, idx) {
if (item !== '') {
txt.text = '[ ' + item + ' ]';
txt.y = bounds.sections[idx] + 1.5 * conf.boxMargin;
exports.drawText(g, txt);
}
});
}
};

View File

@ -122,6 +122,21 @@
Alice->>John the Long: Yes... John, how are you?
John the Long-->>Alice: Super!
</div>
<h1>Parallel</h1>
<div class="mermaid">
sequenceDiagram
par Parallel one
Alice->>Bob: Hello Bob, how are you?
Bob-->>Alice: I am good thanks!
and Parallel two
Alice->>Bob: Are you OK?
Bob-->>Alice: Fine!
and Parallel three
Alice->>Bob: What do you think about it?
Bob-->>Alice: It's good!
end
</div>
<br/>