diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 315c33b21..ab5c0aa3c 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -62,9 +62,17 @@ +
+block-beta
+      columns 3
+      space blockArrowId1<["down"]>(down) space
+      blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left)
+      space blockArrowId5<["up"]>(up) space
+      blockArrowId6<["x"]>(x) space blockArrowId7<["y"]>(y)
+    
 block-beta
-      blockArrowId<["Label"]>(right, down)
+      A("APA") --> B("GORILLA")
     
 block-beta
diff --git a/packages/mermaid/src/dagre-wrapper/blockArrowHelper.js b/packages/mermaid/src/dagre-wrapper/blockArrowHelper.js
new file mode 100644
index 000000000..60ff77a57
--- /dev/null
+++ b/packages/mermaid/src/dagre-wrapper/blockArrowHelper.js
@@ -0,0 +1,218 @@
+const expandAndDeduplicateDirections = (directions) => {
+  const uniqueDirections = new Set();
+
+  for (const direction of directions) {
+    switch (direction) {
+      case 'x':
+        uniqueDirections.add('right');
+        uniqueDirections.add('left');
+        break;
+      case 'y':
+        uniqueDirections.add('up');
+        uniqueDirections.add('down');
+        break;
+      default:
+        uniqueDirections.add(direction);
+        break;
+    }
+  }
+
+  return uniqueDirections;
+};
+export const getArrowPoints = (directions, bbox, node) => {
+  const ud = expandAndDeduplicateDirections(directions);
+
+  // console.log('block_arrow abc123', node.id, node.directions, ud);
+
+  const f = 2;
+  const h = bbox.height + 2 * node.padding;
+  const m = h / f;
+  const w = bbox.width + 2 * m + node.padding;
+  const p = node.padding / 2;
+
+  let points = [];
+
+  if (ud.has('right') && ud.has('left') && ud.has('up') && ud.has('down')) {
+    // SQUARE
+    points = [
+      // Bottom
+      { x: 0, y: 0 },
+      { x: m, y: 0 },
+      { x: w / 2, y: 2 * p },
+      { x: w - m, y: 0 },
+      { x: w, y: 0 },
+
+      // Right
+      { x: w, y: -h / 3 },
+      { x: w + 2 * p, y: -h / 2 },
+      { x: w, y: (-2 * h) / 3 },
+      { x: w, y: -h },
+
+      // Top
+      { x: w - m, y: -h },
+      { x: w / 2, y: -h - 2 * p },
+      { x: m, y: -h },
+
+      // Left
+      { x: 0, y: -h },
+      { x: 0, y: (-2 * h) / 3 },
+      { x: -2 * p, y: -h / 2 },
+      { x: 0, y: -h / 3 },
+    ];
+  } else if (ud.has('right') && ud.has('left') && ud.has('up')) {
+    // RECTANGLE_VERTICAL (Top Open)
+    points = [
+      { x: m, y: 0 },
+      { x: w - m, y: 0 },
+      { x: w, y: -h / 2 },
+      { x: w - m, y: -h },
+      { x: m, y: -h },
+      { x: 0, y: -h / 2 },
+    ];
+  } else if (ud.has('right') && ud.has('left') && ud.has('down')) {
+    // RECTANGLE_VERTICAL (Bottom Open)
+    points = [
+      { x: 0, y: 0 },
+      { x: m, y: -h },
+      { x: w - m, y: -h },
+      { x: w, y: 0 },
+    ];
+  } else if (ud.has('right') && ud.has('up') && ud.has('down')) {
+    // RECTANGLE_HORIZONTAL (Right Open)
+    points = [
+      { x: 0, y: 0 },
+      { x: w, y: -m },
+      { x: w, y: -h + m },
+      { x: 0, y: -h },
+    ];
+  } else if (ud.has('left') && ud.has('up') && ud.has('down')) {
+    // RECTANGLE_HORIZONTAL (Left Open)
+    points = [
+      { x: w, y: 0 },
+      { x: 0, y: -m },
+      { x: 0, y: -h + m },
+      { x: w, y: -h },
+    ];
+  } else if (ud.has('right') && ud.has('left')) {
+    // HORIZONTAL_LINE
+    points = [
+      { x: m, y: 0 },
+      { x: m, y: -p },
+      { x: w - m, y: -p },
+      { x: w - m, y: 0 },
+      { x: w, y: -h / 2 },
+      { x: w - m, y: -h },
+      { x: w - m, y: -h + p },
+      { x: m, y: -h + p },
+      { x: m, y: -h },
+      { x: 0, y: -h / 2 },
+    ];
+  } else if (ud.has('up') && ud.has('down')) {
+    // VERTICAL_LINE
+    points = [
+      // Bottom center
+      { x: w / 2, y: 0 },
+      // Left pont of bottom arrow
+      { x: 0, y: -p },
+      { x: m, y: -p },
+      // Left top over vertical section
+      { x: m, y: -h + p },
+      { x: 0, y: -h + p },
+      // Top of arrow
+      { x: w / 2, y: -h },
+      { x: w, y: -h + p },
+      // Top of right vertical bar
+      { x: w - m, y: -h + p },
+      { x: w - m, y: -p },
+      { x: w, y: -p },
+    ];
+  } else if (ud.has('right') && ud.has('up')) {
+    // ANGLE_RT
+    points = [
+      { x: 0, y: 0 },
+      { x: w, y: -m },
+      { x: 0, y: -h },
+    ];
+  } else if (ud.has('right') && ud.has('down')) {
+    // ANGLE_RB
+    points = [
+      { x: 0, y: 0 },
+      { x: w, y: 0 },
+      { x: 0, y: -h },
+    ];
+  } else if (ud.has('left') && ud.has('up')) {
+    // ANGLE_LT
+    points = [
+      { x: w, y: 0 },
+      { x: 0, y: -m },
+      { x: w, y: -h },
+    ];
+  } else if (ud.has('left') && ud.has('down')) {
+    // ANGLE_LB
+    points = [
+      { x: w, y: 0 },
+      { x: 0, y: 0 },
+      { x: w, y: -h },
+    ];
+  } else if (ud.has('right')) {
+    // ARROW_RIGHT
+    points = [
+      { x: m, y: -p },
+      { x: m, y: -p },
+      { x: w - m, y: -p },
+      { x: w - m, y: 0 },
+      { x: w, y: -h / 2 },
+      { x: w - m, y: -h },
+      { x: w - m, y: -h + p },
+      // top left corner of arrow
+      { x: m, y: -h + p },
+      { x: m, y: -h + p },
+    ];
+  } else if (ud.has('left')) {
+    // ARROW_LEFT
+    points = [
+      { x: m, y: 0 },
+      { x: m, y: -p },
+      // Two points, the right corners
+      { x: w - m, y: -p },
+      { x: w - m, y: -h + p },
+      { x: m, y: -h + p },
+      { x: m, y: -h },
+      { x: 0, y: -h / 2 },
+    ];
+  } else if (ud.has('up')) {
+    // ARROW_TOP
+    points = [
+      // Bottom center
+      { x: m, y: -p },
+      // Left top over vertical section
+      { x: m, y: -h + p },
+      { x: 0, y: -h + p },
+      // Top of arrow
+      { x: w / 2, y: -h },
+      { x: w, y: -h + p },
+      // Top of right vertical bar
+      { x: w - m, y: -h + p },
+      { x: w - m, y: -p },
+    ];
+  } else if (ud.has('down')) {
+    // ARROW_BOTTOM
+    points = [
+      // Bottom center
+      { x: w / 2, y: 0 },
+      // Left pont of bottom arrow
+      { x: 0, y: -p },
+      { x: m, y: -p },
+      // Left top over vertical section
+      { x: m, y: -h + p },
+      { x: w - m, y: -h + p },
+      { x: w - m, y: -p },
+      { x: w, y: -p },
+    ];
+  } else {
+    // POINT
+    points = [{ x: 0, y: 0 }];
+  }
+
+  return points;
+};
diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
index 41578f584..afe1b3a3f 100644
--- a/packages/mermaid/src/dagre-wrapper/nodes.js
+++ b/packages/mermaid/src/dagre-wrapper/nodes.js
@@ -7,6 +7,7 @@ import createLabel from './createLabel.js';
 import note from './shapes/note.js';
 import { parseMember } from '../diagrams/class/svgDraw.js';
 import { evaluate } from '../diagrams/common/common.js';
+import { getArrowPoints } from './blockArrowHelper.js';
 
 const question = async (parent, node) => {
   const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
@@ -14,6 +15,7 @@ const question = async (parent, node) => {
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
   const s = w + h;
+
   const points = [
     { x: s / 2, y: 0 },
     { x: s, y: -s / 2 },
@@ -95,21 +97,33 @@ const hexagon = async (parent, node) => {
 
   return shapeSvg;
 };
+
 const block_arrow = async (parent, node) => {
   const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
 
   const f = 2;
-  const h = bbox.height + node.padding;
+  const h = bbox.height + 2 * node.padding;
   const m = h / f;
   const w = bbox.width + 2 * m + node.padding;
-  const points = [
-    { x: m, y: 0 },
-    { x: w - m, y: 0 },
-    { x: w, y: -h / 2 },
-    { x: w - m, y: -h },
-    { x: m, y: -h },
-    { x: 0, y: -h / 2 },
-  ];
+
+  const p = node.padding / 2;
+  //
+  // const points = [
+  //   { x: m, y: 0 },
+  //   { x: m, y: -p },
+  //   { x: w - m, y: -p },
+  //   { x: w - m, y: 0 },
+  //   // Right point
+  //   { x: w, y: -h / 2 },
+  //   // Point moving left and up from right point
+  //   { x: w - m, y: -h },
+  //   { x: w - m, y: -h + p },
+  //   { x: m, y: -h + p },
+  //   { x: m, y: -h },
+  //   { x: 0, y: -h / 2 },
+  // ];
+
+  const points = getArrowPoints(node.directions, bbox, node);
 
   const hex = insertPolygonShape(shapeSvg, w, h, points);
   hex.attr('style', node.style);
@@ -1085,6 +1099,9 @@ export const insertNode = async (elem, node, dir) => {
   if (node.class) {
     el.attr('class', 'node default ' + node.class);
   }
+  // MC Special
+  newEl.attr('data-node', 'true');
+  newEl.attr('data-id', node.id);
 
   nodeElems[node.id] = newEl;
 
diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
index 3cc9ec11d..86f0b78bb 100644
--- a/packages/mermaid/src/diagrams/block/blockDB.ts
+++ b/packages/mermaid/src/diagrams/block/blockDB.ts
@@ -66,9 +66,8 @@ const clear = (): void => {
 };
 
 type ITypeStr2Type = (typeStr: string) => BlockType;
-export function typeStr2Type(typeStr: string) {
+export function typeStr2Type(typeStr: string): BlockType {
   log.debug('typeStr2Type', typeStr);
-  // TODO: add all types
   switch (typeStr) {
     case '[]':
       return 'square';
@@ -80,7 +79,7 @@ export function typeStr2Type(typeStr: string) {
     case '>]':
       return 'rect_left_inv_arrow';
     case '{}':
-      return 'question';
+      return 'diamond';
     case '{{}}':
       return 'hexagon';
     case '([])':
@@ -115,9 +114,10 @@ export const generateId = () => {
 
 type ISetHierarchy = (block: Block[]) => void;
 const setHierarchy = (block: Block[]): void => {
+  // log.debug('The hierarchy', JSON.stringify(block, null, 2));
   rootBlock.children = block;
   populateBlockDatabase(block, rootBlock);
-  log.debug('The hierarchy', JSON.stringify(rootBlock, null, 2));
+  // log.debug('The hierarchy', JSON.stringify(rootBlock, null, 2));
   blocks = rootBlock.children;
 };
 
diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
index 91d26faf3..448ce0f41 100644
--- a/packages/mermaid/src/diagrams/block/parser/block.jison
+++ b/packages/mermaid/src/diagrams/block/parser/block.jison
@@ -44,8 +44,8 @@ CRLF \u000D\u000A
 [^`"]+        { return "MD_STR";}
 [`]["]          { this.popState();}
 ["]                     this.pushState("string");
-["]             { log.debug('LEX: POPPING STR:', yytext);this.popState();}
-[^"]*           { log.debug('LEX: STR ebd:', yytext); return "STR";}
+["]             { yy.getLogger().debug('LEX: POPPING STR:', yytext);this.popState();}
+[^"]*           { yy.getLogger().debug('LEX: STR ebd:', yytext); return "STR";}
 space[:]\d+            {  yytext = yytext.replace(/space\:/,'');yy.getLogger().info('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; }
 space                  { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; }
 "style"               return 'STYLE';
@@ -86,7 +86,7 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
 "[/"                   { this.pushState('NODE');return 'NODE_DSTART'; }
 "[\\"                  { this.pushState('NODE');return 'NODE_DSTART'; }
 
-"<["                   { this.pushState('BLOCK_ARROW');log.debug('LEX ARR START');return 'BLOCK_ARROW_START'; }
+"<["                   { this.pushState('BLOCK_ARROW');yy.getLogger().debug('LEX ARR START');return 'BLOCK_ARROW_START'; }
 
 [^\(\[\n\-\)\{\}\s\<]+     { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
 <>                { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; }
@@ -98,8 +98,8 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
 [`]["]      { this.popState();}
 ["]              { yy.getLogger().info('Lex: Starting string');this.pushState("string");}
 ["]              { yy.getLogger().info('LEX ARR: Starting string');this.pushState("string");}
-[^"]+          { log.debug('LEX: NODE_DESCR:', yytext); return "NODE_DESCR";}
-["]            {log.debug('LEX POPPING');this.popState();}
+[^"]+          { yy.getLogger().debug('LEX: NODE_DESCR:', yytext); return "NODE_DESCR";}
+["]            {yy.getLogger().debug('LEX POPPING');this.popState();}
 
 // Node end of shape
 \]\>             { this.popState();yy.getLogger().info('Lex: ]>'); return "NODE_DEND"; }
@@ -116,14 +116,14 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
 "/]"             { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; }
 ")]"             { this.popState();yy.getLogger().info('Lex: )]'); return "NODE_DEND"; }
 
-"]>"\s*"("       { log.debug('Lex: =>BAE');  this.pushState('ARROW_DIR');  }
-","?right\s*           { log.debug('Lex (right): dir:',yytext);return "DIR"; }
-","?left\s*            { log.debug('Lex (left):',yytext);return "DIR"; }
-","?x\s*               { log.debug('Lex (x):',yytext); return "DIR"; }
-","?y\s*               { log.debug('Lex (y):',yytext); return "DIR"; }
-","?up\s*              { log.debug('Lex (up):',yytext); return "DIR"; }
-","?\s*down\s*     { yytext = yytext.replace(/^,\s*/, ''); log.debug('Lex (down):',yytext); return "DIR"; }
-")"\s*             { yytext=']>';log.debug('Lex (ARROW_DIR end):',yytext);this.popState();this.popState();return "BLOCK_ARROW_END"; }
+"]>"\s*"("       { yy.getLogger().debug('Lex: =>BAE');  this.pushState('ARROW_DIR');  }
+","?\s*right\s*           { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (right): dir:',yytext);return "DIR"; }
+","?\s*left\s*            { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (left):',yytext);return "DIR"; }
+","?\s*x\s*               { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (x):',yytext); return "DIR"; }
+","?\s*y\s*               { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (y):',yytext); return "DIR"; }
+","?\s*up\s*              { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (up):',yytext); return "DIR"; }
+","?\s*down\s*     { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (down):',yytext); return "DIR"; }
+")"\s*             { yytext=']>';yy.getLogger().debug('Lex (ARROW_DIR end):',yytext);this.popState();this.popState();return "BLOCK_ARROW_END"; }
 
 // Edges
 \s*[xo<]?\-\-+[-xo>]\s*                 { yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; }
@@ -157,7 +157,7 @@ seperator
   ;
 
 start: BLOCK_DIAGRAM_KEY document EOF
-  { yy.setHierarchy($2); }
+  { yy.getLogger().info("Rule: hierarchy: ", $2); yy.setHierarchy($2); }
   ;
 
 
@@ -171,8 +171,8 @@ stop
 
 //array of statements
 document
-	: statement { yy.getLogger().info("Rule: statement: ", $1); $$ = [$1]; }
-	| statement document { yy.getLogger().info("Rule: document statement: ", $1, $2); $$ = [$1].concat($2); }
+	: statement { yy.getLogger().info("Rule: statement: ", $1); typeof $1.length === 'number'?$$ = $1:$$ = [$1]; }
+	| statement document { yy.getLogger().info("Rule: statement #2: ", $1); $$ = [$1].concat($2); }
 	;
 
 link
@@ -191,12 +191,12 @@ statement
 	;
 
 nodeStatement
-  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); $$ = {id: $1.id}; }
-  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr)}; }
+  : nodeStatement link node { yy.getLogger().info('Rule: (nodeStatement link node) ', $1, $2, $3); $$ = [{id: $1.id, label: $1.label, type:$1.type, directions: $1.directions}, {id: $3.id, label: $3.label, type: yy.typeStr2Type($3.typeStr), directions: $3.directions}]; }
+  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr), directions: $1.directions}; }
   ;
 
 columnsStatement
-  : COLUMNS { yy.getLogger().info("COLUMNS: ", $1); $$ = {type: 'column-setting', columns: $1 === 'auto'?-1:parseInt($1) } }
+  : COLUMNS { yy.getLogger().info('APA123', this? this:'na'); yy.getLogger().info("COLUMNS: ", $1); $$ = {type: 'column-setting', columns: $1 === 'auto'?-1:parseInt($1) } }
   ;
 
 blockStatement
@@ -207,10 +207,11 @@ blockStatement
 node
   : NODE_ID
   { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; }
-  |NODE_ID nodeShapeNLabel
-    { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); $$ = { id: $1, label: $2.label, typeStr: $2.typeStr };}
-  // |nodeShapeNLabel seperator
-  // { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); }
+  | NODE_ID nodeShapeNLabel
+  {
+    yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2);
+    $$ = { id: $1, label: $2.label, typeStr: $2.typeStr, directions: $2.directions };
+  }
   ;
 
 dirList: DIR { yy.getLogger().info("Rule: dirList: ", $1); $$ = [$1]; }
@@ -221,7 +222,7 @@ nodeShapeNLabel
   :   NODE_DSTART STR NODE_DEND
 	      { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; }
 	|    BLOCK_ARROW_START STR dirList BLOCK_ARROW_END
-    	      { yy.getLogger().info("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, $3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; }
+    	      { yy.getLogger().info("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, " #3:",$3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; }
   ;
 
 %%
diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
index 142de0c5c..125cd2997 100644
--- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
+++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
@@ -114,6 +114,7 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
     class: classStr,
     style: styles.style,
     id: vertex.id,
+    directions: vertex.directions,
     // link: vertex.link,
     // linkTarget: vertex.linkTarget,
     // tooltip: diagObj.db.getTooltip(vertex.id) || '',
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
index 23f94942c..a887511d5 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
@@ -360,8 +360,10 @@ export const getClasses = function (text, diagObj) {
  *
  * @param text
  * @param id
+ * @param _version
+ * @param diagObj
  */
-
+// [MermaidChart: 33a97b35-1f95-4ce9-81b5-3038669bc170]
 export const draw = async function (text, id, _version, diagObj) {
   log.info('Drawing flowchart');
   diagObj.db.clear();
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
index 70fb49162..1957b4555 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
@@ -332,7 +332,7 @@ spaceList
 
 statement
     : verticeStatement separator
-    { /* console.warn('finat vs', $1.nodes); */ $$=$1.nodes}
+    { $$=$1.nodes}
     | styleStatement separator
     {$$=[];}
     | linkStyleStatement separator
@@ -359,9 +359,9 @@ statement
 
 separator: NEWLINE | SEMI | EOF ;
 
- 
+
 verticeStatement: verticeStatement link node
-        { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
+        {/* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
     |  verticeStatement link node spaceList
         { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
     |node spaceList {/*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }}
@@ -377,7 +377,7 @@ node: styledVertex
 styledVertex: vertex
         { /* console.warn('nod', $1); */ $$ = $1;}
     | vertex STYLE_SEPARATOR idString
-        {$$ = $1;yy.setClass($1,$3)}
+        { $$ = $1;yy.setClass($1,$3)}
     ;
 
 vertex:  idString SQS text SQE