diff --git a/grammar.js b/grammar.js index 9ad7fa8..0c942ab 100644 --- a/grammar.js +++ b/grammar.js @@ -46,7 +46,12 @@ module.exports = grammar({ seq( $._connection_path, repeat1(seq($.arrow, $._connection_path)), - optional(seq($._colon, $.label)) + optional( + seq( + optional(seq($._colon, optional($.label))), + optional(seq(alias($._connection_block, $.block))) + ) + ) ), _connection_path: ($) => @@ -57,6 +62,12 @@ module.exports = grammar({ $.shape_key ), + _connection_block: ($) => + seq("{", repeat($._connection_block_definition), "}"), + + _connection_block_definition: ($) => + choice($._eol, seq($._connection_attribute, $._end)), + // containers container: ($) => @@ -67,10 +78,8 @@ module.exports = grammar({ choice( seq($.dot, choice($.shape, $.container)), seq( - seq( - optional(seq($._colon, optional($.label))), - optional(seq(alias($._container_block, $.block))) - ) + optional(seq($._colon, optional($.label))), + optional(seq(alias($._container_block, $.block))) ) ) ) @@ -205,7 +214,29 @@ module.exports = grammar({ _text_attr_key: ($) => "near", - _connection_attr_key: ($) => choice("source-arrowhead", "target-arrowhead"), + _connection_attribute: ($) => + choice( + alias($._connection_arrowhead_attribute, $.attribute), + alias($._style_attribute, $.attribute) + ), + + _connection_arrowhead_attribute: ($) => + seq( + alias($._connection_arrowhead_attr_key, $.attr_key), + choice( + seq($.dot, alias($._style_attribute, $.attribute)), + seq( + optional(seq($._colon, optional($.label))), + optional(seq(alias($._container_block, $.block))) + ) + ) + ), + + _connection_arrowhead_block: ($) => + seq("{", repeat(choice($._eol, seq($._shape_attribute, $._end))), "}"), + + _connection_arrowhead_attr_key: ($) => + choice("source-arrowhead", "target-arrowhead"), // diff --git a/src/grammar.json b/src/grammar.json index 9b6a3e6..3d2e8fd 100644 --- a/src/grammar.json +++ b/src/grammar.json @@ -51,6 +51,10 @@ { "type": "SYMBOL", "name": "_end" + }, + { + "type": "STRING", + "value": "\u0000" } ] } @@ -88,12 +92,55 @@ "type": "SEQ", "members": [ { - "type": "SYMBOL", - "name": "_colon" + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "label" + }, + { + "type": "BLANK" + } + ] + } + ] + }, + { + "type": "BLANK" + } + ] }, { - "type": "SYMBOL", - "name": "label" + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_connection_block" + }, + "named": true, + "value": "block" + } + ] + }, + { + "type": "BLANK" + } + ] } ] }, @@ -138,6 +185,48 @@ } ] }, + "_connection_block": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "{" + }, + { + "type": "REPEAT", + "content": { + "type": "SYMBOL", + "name": "_connection_block_definition" + } + }, + { + "type": "STRING", + "value": "}" + } + ] + }, + "_connection_block_definition": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_eol" + }, + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_connection_attribute" + }, + { + "type": "SYMBOL", + "name": "_end" + } + ] + } + ] + }, "container": { "type": "PREC", "value": 2, @@ -182,58 +271,53 @@ "type": "SEQ", "members": [ { - "type": "SEQ", + "type": "CHOICE", "members": [ { - "type": "CHOICE", + "type": "SEQ", "members": [ { - "type": "SEQ", + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "CHOICE", "members": [ { "type": "SYMBOL", - "name": "_colon" + "name": "label" }, { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "label" - }, - { - "type": "BLANK" - } - ] + "type": "BLANK" } ] - }, - { - "type": "BLANK" } ] }, { - "type": "CHOICE", + "type": "BLANK" + } + ] + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", "members": [ { - "type": "SEQ", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_container_block" - }, - "named": true, - "value": "block" - } - ] - }, - { - "type": "BLANK" + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_container_block" + }, + "named": true, + "value": "block" } ] + }, + { + "type": "BLANK" } ] } @@ -763,7 +847,161 @@ "type": "STRING", "value": "near" }, - "_connection_attr_key": { + "_connection_attribute": { + "type": "CHOICE", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_connection_arrowhead_attribute" + }, + "named": true, + "value": "attribute" + }, + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_style_attribute" + }, + "named": true, + "value": "attribute" + } + ] + }, + "_connection_arrowhead_attribute": { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_connection_arrowhead_attr_key" + }, + "named": true, + "value": "attr_key" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "dot" + }, + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_style_attribute" + }, + "named": true, + "value": "attribute" + } + ] + }, + { + "type": "SEQ", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "label" + }, + { + "type": "BLANK" + } + ] + } + ] + }, + { + "type": "BLANK" + } + ] + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_container_block" + }, + "named": true, + "value": "block" + } + ] + }, + { + "type": "BLANK" + } + ] + } + ] + } + ] + } + ] + }, + "_connection_arrowhead_block": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "{" + }, + { + "type": "REPEAT", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_eol" + }, + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_shape_attribute" + }, + { + "type": "SYMBOL", + "name": "_end" + } + ] + } + ] + } + }, + { + "type": "STRING", + "value": "}" + } + ] + }, + "_connection_arrowhead_attr_key": { "type": "CHOICE", "members": [ { diff --git a/src/node-types.json b/src/node-types.json index 810cf29..419c1eb 100644 --- a/src/node-types.json +++ b/src/node-types.json @@ -56,6 +56,10 @@ { "type": "dot", "named": true + }, + { + "type": "label", + "named": true } ] } @@ -99,6 +103,10 @@ "type": "arrow", "named": true }, + { + "type": "block", + "named": true + }, { "type": "container_key", "named": true @@ -262,6 +270,10 @@ "named": true, "fields": {} }, + { + "type": "\u0000", + "named": false + }, { "type": "\"", "named": false diff --git a/src/parser.c b/src/parser.c index ab92f90..6356a1e 100644 Binary files a/src/parser.c and b/src/parser.c differ diff --git a/test/corpus/attributes.txt b/test/corpus/attributes.txt index 9017546..f3c80f7 100644 --- a/test/corpus/attributes.txt +++ b/test/corpus/attributes.txt @@ -226,3 +226,169 @@ foo: { ) ) +================================================================================ +Block style attributes inside a connection +================================================================================ +foo -> bar: { + style: { + opacity: 5 + fill: red + stroke: red + stroke-width: 5 + stroke-dash: 4 + border-radius: 1 + font-color: red + shadow: true + multiple: true + animated: true + link: https://to + } +} + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + (block + (attribute + (attr_key) + (block + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + ) + ) + ) + ) +) + +================================================================================ +Labels for connection arrowheads +================================================================================ +foo -> bar: { + source-arrowhead: 0 + target-arrowhead: 1 +} + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + (block + (attribute + (attr_key) + (label) + ) + (attribute + (attr_key) + (label) + ) + ) + ) +) + +================================================================================ +Block style attributes inside a connection arrowhead +================================================================================ +foo -> bar: { + target-arrowhead: { + style: { + opacity: 5 + fill: red + stroke: red + stroke-width: 5 + stroke-dash: 4 + border-radius: 1 + font-color: red + shadow: true + multiple: true + animated: true + link: https://to + } + } +} + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + (block + (attribute + (attr_key) + (block + (attribute + (attr_key) + (block + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + ) + ) + ) + ) + ) + ) +) + +================================================================================ +Container attributes inside a connection arrowhead +================================================================================ +foo -> bar: { + target-arrowhead: { + shape: oval + label: Baz + constraint: primary-key + icon: pathto + width: 100 + height: 200 + } +} + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + (block + (attribute + (attr_key) + (block + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + ) + ) + ) + ) +) + diff --git a/tree-sitter-d2.wasm b/tree-sitter-d2.wasm index bb3ea26..c0b5f8a 100755 Binary files a/tree-sitter-d2.wasm and b/tree-sitter-d2.wasm differ