From 2dfa0bef86c7e0ac2020c83c87ae3e5296924e1d Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 13 Feb 2023 14:47:35 -0800 Subject: [PATCH 01/68] add failing test --- d2oracle/edit_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index dd3b430fc..02669c453 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -1755,6 +1755,20 @@ b assert.JSON(t, 0, len(g.Objects[0].Children)) }, }, + { + name: "out_of_newline_container", + + text: `"a\n": { + b +} +`, + key: `"a\n".b`, + newKey: `b`, + + exp: `"a\n" +b +`, + }, { name: "partial_slice", From 74ee027dabb33c68a85cc0cc74fc4123638fafb7 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 13 Feb 2023 16:28:54 -0800 Subject: [PATCH 02/68] [ci-base] add mongo plugin --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1e4dafee5..95e6cfe9f 100644 --- a/README.md +++ b/README.md @@ -226,6 +226,7 @@ let us know and we'll be happy to include it here! - **Confluence plugin**: [https://github.com/andrinmeier/unofficial-d2lang-confluence-plugin](https://github.com/andrinmeier/unofficial-d2lang-confluence-plugin) - **CIL (C#, Visual Basic, F#, C++ CLR) to D2**: [https://github.com/HugoVG/AppDiagram](https://github.com/HugoVG/AppDiagram) - **D2 Snippets (for text editors)**: [https://github.com/Paracelsus-Rose/D2-Language-Code-Snippets](https://github.com/Paracelsus-Rose/D2-Language-Code-Snippets) +- **Mongo to D2**: [https://github.com/novuhq/mongo-to-D2](https://github.com/novuhq/mongo-to-D2) ### Misc From 11d1c111d51d993d60966c56e4dc9ed0ce85eece Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Mon, 13 Feb 2023 17:30:10 -0800 Subject: [PATCH 03/68] d2oracle: Fix out_of_newline_container --- d2compiler/compile.go | 4 +- d2graph/d2graph.go | 32 ++++ .../out_of_newline_container.exp.json | 179 ++++++++++++++++++ 3 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 testdata/d2oracle/TestMove/out_of_newline_container.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 584dd20af..8442e5417 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -178,7 +178,7 @@ func (c *compiler) compileField(obj *d2graph.Object, f *d2ir.Field) { } } scopeObjIDA := d2ir.IDA(fr.Context.ScopeMap) - scopeObj, _ := obj.Graph.Root.HasChild(scopeObjIDA) + scopeObj, _ := obj.Graph.Root.HasChildIDVal(scopeObjIDA) obj.References = append(obj.References, d2graph.Reference{ Key: fr.KeyPath, KeyPathIndex: fr.KeyPathIndex(), @@ -382,7 +382,7 @@ func (c *compiler) compileEdge(obj *d2graph.Object, e *d2ir.Edge) { edge.Attributes.Label.MapKey = e.LastPrimaryKey() for _, er := range e.References { scopeObjIDA := d2ir.IDA(er.Context.ScopeMap) - scopeObj, _ := edge.Src.Graph.Root.HasChild(d2graphIDA(scopeObjIDA)) + scopeObj, _ := edge.Src.Graph.Root.HasChildIDVal(d2graphIDA(scopeObjIDA)) edge.References = append(edge.References, d2graph.EdgeReference{ Edge: er.Context.Edge, MapKey: er.Context.Key, diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 317e30eee..1300289d6 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -558,6 +558,38 @@ func (obj *Object) HasChild(ids []string) (*Object, bool) { return child, true } +// Keep in sync with HasChild. +func (obj *Object) HasChildIDVal(ids []string) (*Object, bool) { + if len(ids) == 0 { + return obj, true + } + if len(ids) == 1 && ids[0] != "style" { + _, ok := ReservedKeywords[ids[0]] + if ok { + return obj, true + } + } + + id := ids[0] + ids = ids[1:] + + var child *Object + for _, ch2 := range obj.ChildrenArray { + if ch2.IDVal == id { + child = ch2 + break + } + } + if child == nil { + return nil, false + } + + if len(ids) >= 1 { + return child.HasChildIDVal(ids) + } + return child, true +} + func (obj *Object) HasEdge(mk *d2ast.Key) (*Edge, bool) { ea, ok := obj.FindEdges(mk) if !ok { diff --git a/testdata/d2oracle/TestMove/out_of_newline_container.exp.json b/testdata/d2oracle/TestMove/out_of_newline_container.exp.json new file mode 100644 index 000000000..53bcddb77 --- /dev/null +++ b/testdata/d2oracle/TestMove/out_of_newline_container.exp.json @@ -0,0 +1,179 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,0:0:0-2:0:8", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,0:0:0-0:5:5", + "key": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,0:0:0-0:5:5", + "path": [ + { + "double_quoted_string": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,0:0:0-0:5:5", + "value": [ + { + "string": "a\n", + "raw_string": "a\\n" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,1:0:6-1:1:7", + "key": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,1:0:6-1:1:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,1:0:6-1:1:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "\"a\\n\"", + "id_val": "a\n", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,0:0:0-0:5:5", + "path": [ + { + "double_quoted_string": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,0:0:0-0:5:5", + "value": [ + { + "string": "a\n", + "raw_string": "a\\n" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a\n" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,1:0:6-1:1:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/out_of_newline_container.d2,1:0:6-1:1:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From ffea3c9ab25d0f914109f4da67c78623d9bb93c2 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 14 Feb 2023 11:34:18 -0800 Subject: [PATCH 04/68] fix --- d2layouts/d2dagrelayout/layout.go | 3 +- e2etests/regression_test.go | 26 + .../dagre-disconnect/dagre/board.exp.json | 1722 +++++++++++++++++ .../dagre-disconnect/dagre/sketch.exp.svg | 66 + .../dagre-disconnect/elk/board.exp.json | 1434 ++++++++++++++ .../dagre-disconnect/elk/sketch.exp.svg | 66 + 6 files changed, 3316 insertions(+), 1 deletion(-) create mode 100644 e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json create mode 100644 e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/regression/dagre-disconnect/elk/board.exp.json create mode 100644 e2etests/testdata/regression/dagre-disconnect/elk/sketch.exp.svg diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index d1c91f2ed..d46da1e7c 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -350,7 +350,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err return true } // Edge should only move if it's not connected to the bottom side of the shrinking container - return p.Y != obj.TopLeft.Y+obj.Height + // Give some margin for error + return !(obj.TopLeft.Y+obj.Height-1 <= p.Y && obj.TopLeft.Y+obj.Height+1 >= p.Y && p.X != obj.TopLeft.X && p.X != (obj.TopLeft.X+obj.Width)) } for _, e := range g.Edges { if _, ok := movedEdges[e]; ok { diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index d01b0be52..d1e139cec 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -489,6 +489,32 @@ group: { } &foo &&bar +`, + }, + { + name: "dagre-disconnect", + script: `a: { + k.t -> f.i + f.g -> _.s.n +} +k +k.s <-> u.o +h.m.s -> a.f.g + +a.f.j -> u.s.j +u: { + c -> _.s.z.c +} + +s: { + n: { + style.stroke: red + f + } +} + +s.n -> y.r: {style.stroke-width: 2; style.stroke: red} +y.r -> a.g.i: 1\n2\n3\n4 `, }, } diff --git a/e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json b/e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json new file mode 100644 index 000000000..d23f2dfc5 --- /dev/null +++ b/e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json @@ -0,0 +1,1722 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 41 + }, + "width": 394, + "height": 1829, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.k", + "type": "rectangle", + "pos": { + "x": 20, + "y": 111 + }, + "width": 131, + "height": 139, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "k", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.k.t", + "type": "rectangle", + "pos": { + "x": 60, + "y": 147 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "t", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.f", + "type": "rectangle", + "pos": { + "x": 21, + "y": 504 + }, + "width": 353, + "height": 139, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "f", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.f.i", + "type": "rectangle", + "pos": { + "x": 61, + "y": 540 + }, + "width": 49, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "i", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 4, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.f.g", + "type": "rectangle", + "pos": { + "x": 170, + "y": 540 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "s", + "type": "rectangle", + "pos": { + "x": 565, + "y": 827 + }, + "width": 258, + "height": 636, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "s.n", + "type": "rectangle", + "pos": { + "x": 585, + "y": 897 + }, + "width": 131, + "height": 139, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "red", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "n", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "k", + "type": "rectangle", + "pos": { + "x": 1108, + "y": 434 + }, + "width": 132, + "height": 243, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "k", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "k.s", + "type": "rectangle", + "pos": { + "x": 1148, + "y": 522 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "u", + "type": "rectangle", + "pos": { + "x": 844, + "y": 827 + }, + "width": 397, + "height": 243, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "u.o", + "type": "rectangle", + "pos": { + "x": 1147, + "y": 915 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "o", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "h", + "type": "rectangle", + "pos": { + "x": 741, + "y": 41 + }, + "width": 172, + "height": 243, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "h", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "h.m", + "type": "rectangle", + "pos": { + "x": 761, + "y": 111 + }, + "width": 132, + "height": 139, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "m", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 18, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "h.m.s", + "type": "rectangle", + "pos": { + "x": 801, + "y": 147 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.f.j", + "type": "rectangle", + "pos": { + "x": 284, + "y": 540 + }, + "width": 50, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "j", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 5, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "u.s", + "type": "rectangle", + "pos": { + "x": 864, + "y": 897 + }, + "width": 130, + "height": 139, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 10, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "u.s.j", + "type": "rectangle", + "pos": { + "x": 904, + "y": 933 + }, + "width": 50, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "j", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 5, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "u.c", + "type": "rectangle", + "pos": { + "x": 1034, + "y": 915 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "s.z", + "type": "rectangle", + "pos": { + "x": 671, + "y": 1290 + }, + "width": 133, + "height": 139, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 10, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "s.z.c", + "type": "rectangle", + "pos": { + "x": 711, + "y": 1326 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "s.n.f", + "type": "rectangle", + "pos": { + "x": 625, + "y": 933 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "y", + "type": "rectangle", + "pos": { + "x": 414, + "y": 1220 + }, + "width": 131, + "height": 243, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y.r", + "type": "rectangle", + "pos": { + "x": 454, + "y": 1308 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "r", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.g", + "type": "rectangle", + "pos": { + "x": 133, + "y": 1697 + }, + "width": 129, + "height": 139, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "g", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.g.i", + "type": "rectangle", + "pos": { + "x": 173, + "y": 1734 + }, + "width": 49, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "i", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 4, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + } + ], + "connections": [ + { + "id": "a.(k.t -> f.i)[0]", + "src": "a.k.t", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.f.i", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 85.5, + "y": 213.5 + }, + { + "x": 85.5, + "y": 242.7 + }, + { + "x": 85.5, + "y": 260.9 + }, + { + "x": 85.5, + "y": 277.25 + }, + { + "x": 85.5, + "y": 293.6 + }, + { + "x": 85.5, + "y": 315.4 + }, + { + "x": 85.5, + "y": 331.75 + }, + { + "x": 85.5, + "y": 348.1 + }, + { + "x": 85.5, + "y": 369.9 + }, + { + "x": 85.5, + "y": 386.25 + }, + { + "x": 85.5, + "y": 402.6 + }, + { + "x": 85.5, + "y": 482.6 + }, + { + "x": 85.5, + "y": 541 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a.f.g -> s.n)[0]", + "src": "a.f.g", + "srcArrow": "none", + "srcLabel": "", + "dst": "s.n", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 197, + "y": 606.5 + }, + { + "x": 197, + "y": 619.3 + }, + { + "x": 197, + "y": 633.4 + }, + { + "x": 197, + "y": 649.75 + }, + { + "x": 197, + "y": 666.1 + }, + { + "x": 197, + "y": 687.9 + }, + { + "x": 197, + "y": 704.25 + }, + { + "x": 197, + "y": 720.6 + }, + { + "x": 197, + "y": 742.4 + }, + { + "x": 197, + "y": 758.75 + }, + { + "x": 197, + "y": 775.1 + }, + { + "x": 274.6, + "y": 866.8 + }, + { + "x": 585, + "y": 972 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k.s <-> u.o)[0]", + "src": "k.s", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "u.o", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1173.5, + "y": 588.5 + }, + { + "x": 1173.5, + "y": 615.7 + }, + { + "x": 1173.5, + "y": 633.4 + }, + { + "x": 1173.5, + "y": 649.75 + }, + { + "x": 1173.5, + "y": 666.1 + }, + { + "x": 1173.5, + "y": 687.9 + }, + { + "x": 1173.5, + "y": 704.25 + }, + { + "x": 1173.5, + "y": 720.6 + }, + { + "x": 1173.5, + "y": 742.4 + }, + { + "x": 1173.5, + "y": 758.75 + }, + { + "x": 1173.5, + "y": 775.1 + }, + { + "x": 1173.5, + "y": 855.6 + }, + { + "x": 1173.5, + "y": 916 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(h.m.s -> a.f.g)[0]", + "src": "h.m.s", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.f.g", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 827.25, + "y": 213.5 + }, + { + "x": 827.25, + "y": 226.3 + }, + { + "x": 827.25, + "y": 240.4 + }, + { + "x": 827.25, + "y": 256.75 + }, + { + "x": 827.25, + "y": 273.1 + }, + { + "x": 701.2, + "y": 294.9 + }, + { + "x": 512.125, + "y": 311.25 + }, + { + "x": 323.04999999999995, + "y": 327.6 + }, + { + "x": 197, + "y": 349.4 + }, + { + "x": 197, + "y": 365.75 + }, + { + "x": 197, + "y": 382.1 + }, + { + "x": 197, + "y": 466.2 + }, + { + "x": 197, + "y": 541 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a.f.j -> u.s.j)[0]", + "src": "a.f.j", + "srcArrow": "none", + "srcLabel": "", + "dst": "u.s.j", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 309, + "y": 606.5 + }, + { + "x": 309, + "y": 619.3 + }, + { + "x": 309, + "y": 633.4 + }, + { + "x": 309, + "y": 649.75 + }, + { + "x": 309, + "y": 666.1 + }, + { + "x": 309, + "y": 687.9 + }, + { + "x": 309, + "y": 704.25 + }, + { + "x": 309, + "y": 720.6 + }, + { + "x": 309, + "y": 742.4 + }, + { + "x": 309, + "y": 758.75 + }, + { + "x": 309, + "y": 775.1 + }, + { + "x": 427.9, + "y": 864.9937853107344 + }, + { + "x": 903.5, + "y": 962.9689265536723 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(u.c -> s.z.c)[0]", + "src": "u.c", + "srcArrow": "none", + "srcLabel": "", + "dst": "s.z.c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1060, + "y": 981.5 + }, + { + "x": 1060, + "y": 1008.7 + }, + { + "x": 1060, + "y": 1026.4 + }, + { + "x": 1060, + "y": 1042.75 + }, + { + "x": 1060, + "y": 1059.1 + }, + { + "x": 995.4, + "y": 1080.9 + }, + { + "x": 898.5, + "y": 1097.25 + }, + { + "x": 801.5999999999999, + "y": 1113.6 + }, + { + "x": 737, + "y": 1135.4 + }, + { + "x": 737, + "y": 1151.75 + }, + { + "x": 737, + "y": 1168.1 + }, + { + "x": 737, + "y": 1252.2 + }, + { + "x": 737, + "y": 1327 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(s.n -> y.r)[0]", + "src": "s.n", + "srcArrow": "none", + "srcLabel": "", + "dst": "y.r", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "red", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 650.5, + "y": 1037 + }, + { + "x": 650.5, + "y": 1063.4 + }, + { + "x": 650.5, + "y": 1080.9 + }, + { + "x": 650.5, + "y": 1097.25 + }, + { + "x": 650.5, + "y": 1113.6 + }, + { + "x": 650.5, + "y": 1135.4 + }, + { + "x": 650.5, + "y": 1151.75 + }, + { + "x": 650.5, + "y": 1168.1 + }, + { + "x": 621.3, + "y": 1252.4 + }, + { + "x": 504.5, + "y": 1328 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(y.r -> a.g.i)[0]", + "src": "y.r", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.g.i", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "1\n2\n3\n4", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 9, + "labelHeight": 69, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 479.5, + "y": 1374.5 + }, + { + "x": 479.5, + "y": 1401.7 + }, + { + "x": 479.5, + "y": 1419.4 + }, + { + "x": 479.5, + "y": 1435.75 + }, + { + "x": 479.5, + "y": 1452.1 + }, + { + "x": 423, + "y": 1480.8 + }, + { + "x": 338.25, + "y": 1507.5 + }, + { + "x": 253.5, + "y": 1534.2 + }, + { + "x": 197, + "y": 1659.6 + }, + { + "x": 197, + "y": 1734 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg b/e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg new file mode 100644 index 000000000..79f321744 --- /dev/null +++ b/e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg @@ -0,0 +1,66 @@ + +askuhykfnsomsczrgtigsjjcfi 1234 + + + \ No newline at end of file diff --git a/e2etests/testdata/regression/dagre-disconnect/elk/board.exp.json b/e2etests/testdata/regression/dagre-disconnect/elk/board.exp.json new file mode 100644 index 000000000..b729f559f --- /dev/null +++ b/e2etests/testdata/regression/dagre-disconnect/elk/board.exp.json @@ -0,0 +1,1434 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 184, + "y": 373 + }, + "width": 421, + "height": 527, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.k", + "type": "rectangle", + "pos": { + "x": 234, + "y": 423 + }, + "width": 151, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "k", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.k.t", + "type": "rectangle", + "pos": { + "x": 284, + "y": 473 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "t", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.f", + "type": "rectangle", + "pos": { + "x": 235, + "y": 679 + }, + "width": 293, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "f", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.f.i", + "type": "rectangle", + "pos": { + "x": 285, + "y": 729 + }, + "width": 49, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "i", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 4, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.f.g", + "type": "rectangle", + "pos": { + "x": 354, + "y": 729 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "s", + "type": "rectangle", + "pos": { + "x": 277, + "y": 1401 + }, + "width": 424, + "height": 271, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "s.n", + "type": "rectangle", + "pos": { + "x": 327, + "y": 1453 + }, + "width": 151, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "red", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "n", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "k", + "type": "rectangle", + "pos": { + "x": 12, + "y": 734 + }, + "width": 152, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "k", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "k.s", + "type": "rectangle", + "pos": { + "x": 62, + "y": 784 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "u", + "type": "rectangle", + "pos": { + "x": 254, + "y": 1040 + }, + "width": 397, + "height": 271, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "u.o", + "type": "rectangle", + "pos": { + "x": 304, + "y": 1095 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "o", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "h", + "type": "rectangle", + "pos": { + "x": 269, + "y": 12 + }, + "width": 252, + "height": 271, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "h", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "h.m", + "type": "rectangle", + "pos": { + "x": 319, + "y": 62 + }, + "width": 152, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "m", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 18, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "h.m.s", + "type": "rectangle", + "pos": { + "x": 369, + "y": 112 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.f.j", + "type": "rectangle", + "pos": { + "x": 428, + "y": 729 + }, + "width": 50, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "j", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 5, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "u.s", + "type": "rectangle", + "pos": { + "x": 378, + "y": 1095 + }, + "width": 150, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "s", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 10, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "u.s.j", + "type": "rectangle", + "pos": { + "x": 428, + "y": 1145 + }, + "width": 50, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "j", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 5, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "u.c", + "type": "rectangle", + "pos": { + "x": 548, + "y": 1195 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "s.z", + "type": "rectangle", + "pos": { + "x": 498, + "y": 1456 + }, + "width": 153, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 10, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "s.z.c", + "type": "rectangle", + "pos": { + "x": 548, + "y": 1506 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "s.n.f", + "type": "rectangle", + "pos": { + "x": 377, + "y": 1503 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "y", + "type": "rectangle", + "pos": { + "x": 327, + "y": 1752 + }, + "width": 151, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "y.r", + "type": "rectangle", + "pos": { + "x": 377, + "y": 1802 + }, + "width": 51, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "r", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 6, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.g", + "type": "rectangle", + "pos": { + "x": 406, + "y": 428 + }, + "width": 149, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "g", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.g.i", + "type": "rectangle", + "pos": { + "x": 456, + "y": 478 + }, + "width": 49, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "i", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 4, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + } + ], + "connections": [ + { + "id": "a.(k.t -> f.i)[0]", + "src": "a.k.t", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.f.i", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 309.5, + "y": 539 + }, + { + "x": 309.5, + "y": 729 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a.f.g -> s.n)[0]", + "src": "a.f.g", + "srcArrow": "none", + "srcLabel": "", + "dst": "s.n", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 381, + "y": 795 + }, + { + "x": 381, + "y": 945 + }, + { + "x": 243, + "y": 945 + }, + { + "x": 243, + "y": 1356 + }, + { + "x": 402.5, + "y": 1356 + }, + { + "x": 402.5, + "y": 1453.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k.s <-> u.o)[0]", + "src": "k.s", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "u.o", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 88, + "y": 850 + }, + { + "x": 88, + "y": 995 + }, + { + "x": 331, + "y": 995 + }, + { + "x": 331, + "y": 1095 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(h.m.s -> a.f.g)[0]", + "src": "h.m.s", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.f.g", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 395, + "y": 178 + }, + { + "x": 395, + "y": 634 + }, + { + "x": 381, + "y": 634 + }, + { + "x": 381, + "y": 729 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a.f.j -> u.s.j)[0]", + "src": "a.f.j", + "srcArrow": "none", + "srcLabel": "", + "dst": "u.s.j", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 453, + "y": 795 + }, + { + "x": 453, + "y": 1145 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(u.c -> s.z.c)[0]", + "src": "u.c", + "srcArrow": "none", + "srcLabel": "", + "dst": "s.z.c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 574.5, + "y": 1261 + }, + { + "x": 574.5, + "y": 1506 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(s.n -> y.r)[0]", + "src": "s.n", + "srcArrow": "none", + "srcLabel": "", + "dst": "y.r", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "red", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 402.5, + "y": 1619.5 + }, + { + "x": 402.5, + "y": 1802 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(y.r -> a.g.i)[0]", + "src": "y.r", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.g.i", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "1\n2\n3\n4", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 9, + "labelHeight": 69, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 402.5, + "y": 1868 + }, + { + "x": 402.5, + "y": 1963 + }, + { + "x": 711, + "y": 1963 + }, + { + "x": 711, + "y": 328 + }, + { + "x": 480.5, + "y": 328 + }, + { + "x": 480.5, + "y": 478 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/regression/dagre-disconnect/elk/sketch.exp.svg b/e2etests/testdata/regression/dagre-disconnect/elk/sketch.exp.svg new file mode 100644 index 000000000..dc6e8b644 --- /dev/null +++ b/e2etests/testdata/regression/dagre-disconnect/elk/sketch.exp.svg @@ -0,0 +1,66 @@ + +askuhykfnsomsczrgtigsjjcfi 1234 + + + \ No newline at end of file From 02e69bfd31661e392bc15aef91a4a4a045494e0f Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 14 Feb 2023 11:35:00 -0800 Subject: [PATCH 05/68] original test --- e2etests/regression_test.go | 2 +- .../testdata/regression/dagre-disconnect/dagre/board.exp.json | 2 +- .../testdata/regression/dagre-disconnect/dagre/sketch.exp.svg | 2 +- .../testdata/regression/dagre-disconnect/elk/board.exp.json | 2 +- .../testdata/regression/dagre-disconnect/elk/sketch.exp.svg | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index d1e139cec..17a7e6e18 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -513,7 +513,7 @@ s: { } } -s.n -> y.r: {style.stroke-width: 2; style.stroke: red} +s.n -> y.r: {style.stroke-width: 8; style.stroke: red} y.r -> a.g.i: 1\n2\n3\n4 `, }, diff --git a/e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json b/e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json index d23f2dfc5..6a59b3706 100644 --- a/e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json +++ b/e2etests/testdata/regression/dagre-disconnect/dagre/board.exp.json @@ -1584,7 +1584,7 @@ "dstLabel": "", "opacity": 1, "strokeDash": 0, - "strokeWidth": 2, + "strokeWidth": 8, "stroke": "red", "label": "", "fontSize": 16, diff --git a/e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg b/e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg index 79f321744..1890600ee 100644 --- a/e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/dagre-disconnect/dagre/sketch.exp.svg @@ -39,7 +39,7 @@ width="1445" height="2072" viewBox="-102 -100 1445 2072">🙈🙈🙈🙈🙈🙈🙈🙈✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/emojis/elk/board.exp.json b/e2etests/testdata/unicode/emojis/elk/board.exp.json new file mode 100644 index 000000000..2e524b35a --- /dev/null +++ b/e2etests/testdata/unicode/emojis/elk/board.exp.json @@ -0,0 +1,170 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 205, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "🙈🙈🙈🙈🙈🙈🙈🙈", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 160, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "type": "rectangle", + "pos": { + "x": 237, + "y": 12 + }, + "width": 833, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 788, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "type": "rectangle", + "pos": { + "x": 201, + "y": 148 + }, + "width": 905, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 860, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊ -> ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️)[0]", + "src": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "srcArrow": "none", + "srcLabel": "", + "dst": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 653.5, + "y": 78 + }, + { + "x": 653.5, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/emojis/elk/sketch.exp.svg b/e2etests/testdata/unicode/emojis/elk/sketch.exp.svg new file mode 100644 index 000000000..7ccc8cb4f --- /dev/null +++ b/e2etests/testdata/unicode/emojis/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +🙈🙈🙈🙈🙈🙈🙈🙈✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-basic/dagre/board.exp.json b/e2etests/testdata/unicode/japanese-basic/dagre/board.exp.json new file mode 100644 index 000000000..4bc654165 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/dagre/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 246, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ああああああああああ", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 201, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/japanese-basic/dagre/sketch.exp.svg b/e2etests/testdata/unicode/japanese-basic/dagre/sketch.exp.svg new file mode 100644 index 000000000..b30f6e8c4 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +ああああああああああ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-basic/elk/board.exp.json b/e2etests/testdata/unicode/japanese-basic/elk/board.exp.json new file mode 100644 index 000000000..7b54eaf15 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/elk/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 246, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ああああああああああ", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 201, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/japanese-basic/elk/sketch.exp.svg b/e2etests/testdata/unicode/japanese-basic/elk/sketch.exp.svg new file mode 100644 index 000000000..29d9caa5c --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +ああああああああああ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-full/dagre/board.exp.json b/e2etests/testdata/unicode/japanese-full/dagre/board.exp.json new file mode 100644 index 000000000..76f3ee1c3 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/dagre/board.exp.json @@ -0,0 +1,138 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 1382, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。\nトマトは驚いて尋ねました。\n「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1337, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 8, + "y": 219 + }, + "width": 1367, + "height": 115, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "「バナナは皮を剥いて食べるものです。」", + "fontSize": 55, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1322, + "labelHeight": 70, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "「バカは死ななきゃ治らない。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 289, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 691, + "y": 98 + }, + { + "x": 691, + "y": 146.4 + }, + { + "x": 691, + "y": 170.7 + }, + { + "x": 691, + "y": 219.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-full/dagre/sketch.exp.svg b/e2etests/testdata/unicode/japanese-full/dagre/sketch.exp.svg new file mode 100644 index 000000000..e821ce14a --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/dagre/sketch.exp.svg @@ -0,0 +1,59 @@ + +ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。トマトは驚いて尋ねました。「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」「バナナは皮を剥いて食べるものです。」 「バカは死ななきゃ治らない。」 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-full/elk/board.exp.json b/e2etests/testdata/unicode/japanese-full/elk/board.exp.json new file mode 100644 index 000000000..08cca5c14 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/elk/board.exp.json @@ -0,0 +1,129 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 1382, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。\nトマトは驚いて尋ねました。\n「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1337, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 19, + "y": 271 + }, + "width": 1367, + "height": 115, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "「バナナは皮を剥いて食べるものです。」", + "fontSize": 55, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1322, + "labelHeight": 70, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "「バカは死ななきゃ治らない。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 289, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 703, + "y": 110 + }, + { + "x": 703, + "y": 271 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-full/elk/sketch.exp.svg b/e2etests/testdata/unicode/japanese-full/elk/sketch.exp.svg new file mode 100644 index 000000000..16635fff6 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。トマトは驚いて尋ねました。「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」「バナナは皮を剥いて食べるものです。」 「バカは死ななきゃ治らない。」 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-mixed/dagre/board.exp.json b/e2etests/testdata/unicode/japanese-mixed/dagre/board.exp.json new file mode 100644 index 000000000..506dfab48 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/dagre/board.exp.json @@ -0,0 +1,494 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 1646, + "y": 0 + }, + "width": 668, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 623, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 0, + "y": 166 + }, + "width": 3959, + "height": 171, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶", + "fontSize": 100, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 3914, + "labelHeight": 126, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 1817, + "y": 437 + }, + "width": 326, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "今日はTokyoでsushiを食べました", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 281, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 888, + "y": 603 + }, + "width": 2184, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。", + "fontSize": 43, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 2139, + "labelHeight": 55, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 1877, + "y": 803 + }, + "width": 206, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "English English English", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 161, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 1897, + "y": 969 + }, + "width": 165, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日先日先日", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 120, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 66 + }, + { + "x": 1979.5, + "y": 106 + }, + { + "x": 1979.5, + "y": 126 + }, + { + "x": 1979.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> c)[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 337 + }, + { + "x": 1979.5, + "y": 377 + }, + { + "x": 1979.5, + "y": 397 + }, + { + "x": 1979.5, + "y": 437 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c -> d)[0]", + "src": "c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 503 + }, + { + "x": 1979.5, + "y": 543 + }, + { + "x": 1979.5, + "y": 563 + }, + { + "x": 1979.5, + "y": 603 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(d -> e)[0]", + "src": "d", + "srcArrow": "none", + "srcLabel": "", + "dst": "e", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 703 + }, + { + "x": 1979.5, + "y": 743 + }, + { + "x": 1979.5, + "y": 763 + }, + { + "x": 1979.5, + "y": 803 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> f)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "f", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 869 + }, + { + "x": 1979.5, + "y": 909 + }, + { + "x": 1979.5, + "y": 929 + }, + { + "x": 1979.5, + "y": 969 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-mixed/dagre/sketch.exp.svg b/e2etests/testdata/unicode/japanese-mixed/dagre/sketch.exp.svg new file mode 100644 index 000000000..77274b84b --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶今日はTokyoでsushiを食べました先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。English English English先日先日先日 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-mixed/elk/board.exp.json b/e2etests/testdata/unicode/japanese-mixed/elk/board.exp.json new file mode 100644 index 000000000..622db44fb --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/elk/board.exp.json @@ -0,0 +1,449 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 1657, + "y": 12 + }, + "width": 668, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 623, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 12, + "y": 148 + }, + "width": 3959, + "height": 171, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶", + "fontSize": 100, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 3914, + "labelHeight": 126, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 1828, + "y": 389 + }, + "width": 326, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "今日はTokyoでsushiを食べました", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 281, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 899, + "y": 525 + }, + "width": 2184, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。", + "fontSize": 43, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 2139, + "labelHeight": 55, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 1888, + "y": 695 + }, + "width": 206, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "English English English", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 161, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 1909, + "y": 831 + }, + "width": 165, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日先日先日", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 120, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 78 + }, + { + "x": 1991.5, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> c)[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 319 + }, + { + "x": 1991.5, + "y": 389 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c -> d)[0]", + "src": "c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 455 + }, + { + "x": 1991.5, + "y": 525 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(d -> e)[0]", + "src": "d", + "srcArrow": "none", + "srcLabel": "", + "dst": "e", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 625 + }, + { + "x": 1991.5, + "y": 695 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> f)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "f", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 761 + }, + { + "x": 1991.5, + "y": 831 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-mixed/elk/sketch.exp.svg b/e2etests/testdata/unicode/japanese-mixed/elk/sketch.exp.svg new file mode 100644 index 000000000..6edeb9aa3 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶今日はTokyoでsushiを食べました先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。English English English先日先日先日 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/with-style/dagre/board.exp.json b/e2etests/testdata/unicode/with-style/dagre/board.exp.json new file mode 100644 index 000000000..475a72efb --- /dev/null +++ b/e2etests/testdata/unicode/with-style/dagre/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "おやすみなさい", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 185, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 15, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": true, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "おやすみなさい", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 140, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/with-style/dagre/sketch.exp.svg b/e2etests/testdata/unicode/with-style/dagre/sketch.exp.svg new file mode 100644 index 000000000..64a18001c --- /dev/null +++ b/e2etests/testdata/unicode/with-style/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +おやすみなさい + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/with-style/elk/board.exp.json b/e2etests/testdata/unicode/with-style/elk/board.exp.json new file mode 100644 index 000000000..201320c67 --- /dev/null +++ b/e2etests/testdata/unicode/with-style/elk/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "おやすみなさい", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 185, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 15, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": true, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "おやすみなさい", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 140, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/with-style/elk/sketch.exp.svg b/e2etests/testdata/unicode/with-style/elk/sketch.exp.svg new file mode 100644 index 000000000..fa4d7d8a1 --- /dev/null +++ b/e2etests/testdata/unicode/with-style/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +おやすみなさい + + + \ No newline at end of file diff --git a/e2etests/unicode_test.go b/e2etests/unicode_test.go new file mode 100644 index 000000000..0629cdf09 --- /dev/null +++ b/e2etests/unicode_test.go @@ -0,0 +1,56 @@ +package e2etests + +import ( + _ "embed" + "testing" +) + +func testUnicode(t *testing.T) { + tcs := []testCase{ + { + name: "japanese-basic", + script: `a: ああああああああああ +`, + }, + { + name: "japanese-full", + script: `a: "ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。\nトマトは驚いて尋ねました。\n「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」" + +b: "「バナナは皮を剥いて食べるものです。」" { + style.font-size: 55 +} + +a -> b: 「バカは死ななきゃ治らない。」 +`, + }, + { + name: "emojis", + script: `a: 🙈🙈🙈🙈🙈🙈🙈🙈 +✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊ -> ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ +`, + }, + { + name: "with-style", + script: `おやすみなさい: {style.stroke-width: 15; style.double-border: true} +`, + }, + { + name: "japanese-mixed", + script: `a: "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶" +b: "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩‍👩‍👧‍👶👩‍👩‍👧‍👶" { + style.font-size: 100 +} +c: 今日はTokyoでsushiを食べました +d: 先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。{ + style.font-size: 43 +} +e: English English English +f: 先日先日先日 +a -> b -> c -> d -> e -> f + +`, + }, + } + + runa(t, tcs) +} diff --git a/go.mod b/go.mod index feec9b43c..c8986bd2f 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,10 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/lucasb-eyer/go-colorful v1.2.0 + github.com/mattn/go-runewidth v0.0.14 github.com/mazznoer/csscolorparser v0.1.3 github.com/playwright-community/playwright-go v0.2000.1 + github.com/rivo/uniseg v0.4.3 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.1 github.com/yuin/goldmark v1.5.3 diff --git a/go.sum b/go.sum index 1f31c5679..9b83338c3 100644 --- a/go.sum +++ b/go.sum @@ -115,6 +115,8 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mazznoer/csscolorparser v0.1.3 h1:vug4zh6loQxAUxfU1DZEu70gTPufDPspamZlHAkKcxE= github.com/mazznoer/csscolorparser v0.1.3/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= @@ -128,6 +130,10 @@ github.com/playwright-community/playwright-go v0.2000.1/go.mod h1:1y9cM9b9dVHnuR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= diff --git a/lib/textmeasure/textmeasure.go b/lib/textmeasure/textmeasure.go index b46cc1711..cdf9c811c 100644 --- a/lib/textmeasure/textmeasure.go +++ b/lib/textmeasure/textmeasure.go @@ -5,10 +5,12 @@ package textmeasure import ( "math" + "strings" "unicode" "unicode/utf8" "github.com/golang/freetype/truetype" + "github.com/rivo/uniseg" "oss.terrastruct.com/d2/d2renderers/d2fonts" "oss.terrastruct.com/d2/lib/geo" @@ -166,6 +168,44 @@ func (r *Ruler) addFontSize(font d2fonts.Font) { func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int) { w, h := t.MeasurePrecise(font, s) + // Weird unicode stuff is going on when this is true + // See https://github.com/rivo/uniseg#grapheme-clusters + // This method is a good-enough approximation. It overshoots, but not by much. + // I suspect we need to import a font with the right glyphs to get the precise measurements + // but Hans fonts are heavy. + if uniseg.GraphemeClusterCount(s) != len(s) { + for _, line := range strings.Split(s, "\n") { + lineW, _ := t.MeasurePrecise(font, line) + gr := uniseg.NewGraphemes(line) + + mono := d2fonts.SourceCodePro.Font(font.Size, font.Style) + for gr.Next() { + if gr.Width() == 1 { + continue + } + // For each grapheme which doesn't have width=1, the ruler measured wrongly. + // So, replace the measured width with a scaled measurement of a monospace version + var prevRune rune + dot := t.Orig.Copy() + b := newRect() + for _, r := range gr.Runes() { + var control bool + dot, control = t.controlRune(r, dot, font) + if control { + continue + } + + var bounds *rect + _, _, bounds, dot = t.atlases[font].DrawRune(prevRune, r, dot) + b = b.union(bounds) + prevRune = r + } + lineW -= b.w() + lineW += t.spaceWidth(mono) * float64(gr.Width()) + } + w = math.Max(w, lineW) + } + } return int(math.Ceil(w)), int(math.Ceil(h)) } From 156c9742411207981766a4f67aaee52b932d4855 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 14 Feb 2023 10:13:23 -0800 Subject: [PATCH 08/68] unicode tests --- .../dagre_special_ids/dagre/board.exp.json | 36 +- .../dagre_special_ids/dagre/sketch.exp.svg | 6 +- .../dagre_special_ids/elk/board.exp.json | 32 +- .../dagre_special_ids/elk/sketch.exp.svg | 6 +- .../unicode/chinese/dagre/board.exp.json | 137 +++ .../unicode/chinese/dagre/sketch.exp.svg | 820 ++++++++++++++++ .../unicode/chinese/elk/board.exp.json | 128 +++ .../unicode/chinese/elk/sketch.exp.svg | 820 ++++++++++++++++ .../unicode/korean/dagre/board.exp.json | 48 + .../unicode/korean/dagre/sketch.exp.svg | 52 + .../unicode/korean/elk/board.exp.json | 48 + .../unicode/korean/elk/sketch.exp.svg | 52 + .../mixed-language-2/dagre/board.exp.json | 909 ++++++++++++++++++ .../mixed-language-2/dagre/sketch.exp.svg | 52 + .../mixed-language-2/elk/board.exp.json | 909 ++++++++++++++++++ .../mixed-language-2/elk/sketch.exp.svg | 52 + .../mixed-language/dagre/board.exp.json | 226 +++++ .../mixed-language/dagre/sketch.exp.svg | 818 ++++++++++++++++ .../unicode/mixed-language/elk/board.exp.json | 216 +++++ .../unicode/mixed-language/elk/sketch.exp.svg | 818 ++++++++++++++++ e2etests/unicode_test.go | 78 ++ go.mod | 1 - go.sum | 4 - lib/textmeasure/markdown.go | 2 + lib/textmeasure/textmeasure.go | 10 +- 25 files changed, 6233 insertions(+), 47 deletions(-) create mode 100644 e2etests/testdata/unicode/chinese/dagre/board.exp.json create mode 100644 e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/unicode/chinese/elk/board.exp.json create mode 100644 e2etests/testdata/unicode/chinese/elk/sketch.exp.svg create mode 100644 e2etests/testdata/unicode/korean/dagre/board.exp.json create mode 100644 e2etests/testdata/unicode/korean/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/unicode/korean/elk/board.exp.json create mode 100644 e2etests/testdata/unicode/korean/elk/sketch.exp.svg create mode 100644 e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json create mode 100644 e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/unicode/mixed-language-2/elk/board.exp.json create mode 100644 e2etests/testdata/unicode/mixed-language-2/elk/sketch.exp.svg create mode 100644 e2etests/testdata/unicode/mixed-language/dagre/board.exp.json create mode 100644 e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/unicode/mixed-language/elk/board.exp.json create mode 100644 e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg diff --git a/e2etests/testdata/regression/dagre_special_ids/dagre/board.exp.json b/e2etests/testdata/regression/dagre_special_ids/dagre/board.exp.json index 2cb1ebfab..d7c736755 100644 --- a/e2etests/testdata/regression/dagre_special_ids/dagre/board.exp.json +++ b/e2etests/testdata/regression/dagre_special_ids/dagre/board.exp.json @@ -91,7 +91,7 @@ "x": 302, "y": 0 }, - "width": 97, + "width": 102, "height": 82, "opacity": 1, "strokeDash": 0, @@ -119,7 +119,7 @@ "italic": false, "bold": true, "underline": false, - "labelWidth": 52, + "labelWidth": 57, "labelHeight": 37, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, @@ -129,7 +129,7 @@ "id": "\"a\\\\yode\"", "type": "rectangle", "pos": { - "x": 459, + "x": 464, "y": 8 }, "width": 94, @@ -170,7 +170,7 @@ "id": "there", "type": "rectangle", "pos": { - "x": 619, + "x": 624, "y": 182 }, "width": 83, @@ -211,7 +211,7 @@ "id": "'a\\\"ode'", "type": "rectangle", "pos": { - "x": 613, + "x": 618, "y": 8 }, "width": 94, @@ -252,7 +252,7 @@ "id": "\"a\\\\node\"", "type": "rectangle", "pos": { - "x": 767, + "x": 772, "y": 8 }, "width": 95, @@ -317,19 +317,19 @@ "labelPercentage": 0, "route": [ { - "x": 506, + "x": 511, "y": 74 }, { - "x": 506, + "x": 511, "y": 120.4 }, { - "x": 528.5, + "x": 533.5, "y": 144.12662337662337 }, { - "x": 618.5, + "x": 623.5, "y": 192.63311688311688 } ], @@ -365,19 +365,19 @@ "labelPercentage": 0, "route": [ { - "x": 660, + "x": 665, "y": 74 }, { - "x": 660, + "x": 665, "y": 120.4 }, { - "x": 660, + "x": 665, "y": 142 }, { - "x": 660, + "x": 665, "y": 182 } ], @@ -413,19 +413,19 @@ "labelPercentage": 0, "route": [ { - "x": 814.5, + "x": 819.5, "y": 74 }, { - "x": 814.5, + "x": 819.5, "y": 120.4 }, { - "x": 791.9, + "x": 796.9, "y": 144 }, { - "x": 701.5, + "x": 706.5, "y": 192 } ], diff --git a/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg b/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg index 5b4018056..35734e017 100644 --- a/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg @@ -3,7 +3,7 @@ id="d2-svg" style="background: white;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" -width="1066" height="452" viewBox="-102 -102 1066 452">

床前明月光,

+

疑是地上霜。

+

举头望明月,

+

低头思故乡。

+
所以,即使夏天很热 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/chinese/elk/board.exp.json b/e2etests/testdata/unicode/chinese/elk/board.exp.json new file mode 100644 index 000000000..a6fe84f83 --- /dev/null +++ b/e2etests/testdata/unicode/chinese/elk/board.exp.json @@ -0,0 +1,128 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "poem", + "type": "text", + "pos": { + "x": 66, + "y": 12 + }, + "width": 118, + "height": 144, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "床前明月光,\n\n疑是地上霜。\n\n举头望明月,\n\n低头思故乡。", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 118, + "labelHeight": 144, + "zIndex": 0, + "level": 1 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 226 + }, + "width": 226, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "所以,即使夏天很热", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 181, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(poem -> a)[0]", + "src": "poem", + "srcArrow": "none", + "srcLabel": "", + "dst": "a", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 125, + "y": 156 + }, + { + "x": 125, + "y": 226 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg new file mode 100644 index 000000000..a2ddcd832 --- /dev/null +++ b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg @@ -0,0 +1,820 @@ + +

床前明月光,

+

疑是地上霜。

+

举头望明月,

+

低头思故乡。

+
所以,即使夏天很热 + + +
\ No newline at end of file diff --git a/e2etests/testdata/unicode/korean/dagre/board.exp.json b/e2etests/testdata/unicode/korean/dagre/board.exp.json new file mode 100644 index 000000000..57d6026fc --- /dev/null +++ b/e2etests/testdata/unicode/korean/dagre/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 205, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "고생끝에낙이온다", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 160, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/korean/dagre/sketch.exp.svg b/e2etests/testdata/unicode/korean/dagre/sketch.exp.svg new file mode 100644 index 000000000..0f7567734 --- /dev/null +++ b/e2etests/testdata/unicode/korean/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +고생끝에낙이온다 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/korean/elk/board.exp.json b/e2etests/testdata/unicode/korean/elk/board.exp.json new file mode 100644 index 000000000..bf70b2118 --- /dev/null +++ b/e2etests/testdata/unicode/korean/elk/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 205, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "고생끝에낙이온다", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 160, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/korean/elk/sketch.exp.svg b/e2etests/testdata/unicode/korean/elk/sketch.exp.svg new file mode 100644 index 000000000..b61a68b53 --- /dev/null +++ b/e2etests/testdata/unicode/korean/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +고생끝에낙이온다 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json b/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json new file mode 100644 index 000000000..bb5c666f8 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json @@ -0,0 +1,909 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 240, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "我 (wǒ) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 195, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 300, + "y": 0 + }, + "width": 241, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaai dii) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 196, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 601, + "y": 0 + }, + "width": 301, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ជំរាបសួរ (jomreab suor) - Khmer", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 256, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"สวัสดี (sà-wàt-dii) - Thai\"", + "type": "rectangle", + "pos": { + "x": 962, + "y": 0 + }, + "width": 244, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "สวัสดี (sà-wàt-dii) - Thai", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 199, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ສະບາຍດີ (sabaidee) - Lao\"", + "type": "rectangle", + "pos": { + "x": 1266, + "y": 0 + }, + "width": 237, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaidee) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 192, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ဟယ်လို (helaou) - Burmese\"", + "type": "rectangle", + "pos": { + "x": 1563, + "y": 0 + }, + "width": 247, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ဟယ်လို (helaou) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 202, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"mari (まり) - Ainu\"", + "type": "rectangle", + "pos": { + "x": 1870, + "y": 0 + }, + "width": 176, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mari (まり) - Ainu", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 131, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"cào (草) - Zhuang\"", + "type": "rectangle", + "pos": { + "x": 2106, + "y": 0 + }, + "width": 173, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "cào (草) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 128, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"күнтізбе (kúntízbe) - Kazakh\"", + "type": "rectangle", + "pos": { + "x": 2339, + "y": 0 + }, + "width": 282, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "күнтізбе (kúntízbe) - Kazakh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 237, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"բարև (barev) - Armenian\"", + "type": "rectangle", + "pos": { + "x": 2681, + "y": 0 + }, + "width": 224, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "բարև (barev) - Armenian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 179, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"монгол (mongol) - Mongolian\"", + "type": "rectangle", + "pos": { + "x": 2965, + "y": 0 + }, + "width": 265, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "монгол (mongol) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 220, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"mila (میلا) - Uyghur\"", + "type": "rectangle", + "pos": { + "x": 3290, + "y": 0 + }, + "width": 199, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mila (میلا) - Uyghur", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 154, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"નમસ્તે (namaste) - Gujarati\"", + "type": "rectangle", + "pos": { + "x": 3549, + "y": 0 + }, + "width": 255, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "નમસ્તે (namaste) - Gujarati", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 210, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"漢字 (kanji) - Japanese\"", + "type": "rectangle", + "pos": { + "x": 3864, + "y": 0 + }, + "width": 213, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "漢字 (kanji) - Japanese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 168, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"위 (wi) - Korean\"", + "type": "rectangle", + "pos": { + "x": 4137, + "y": 0 + }, + "width": 158, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "위 (wi) - Korean", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 113, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"吾哥 (ngǔgāi) - Cantonese\"", + "type": "rectangle", + "pos": { + "x": 4355, + "y": 0 + }, + "width": 238, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "吾哥 (ngǔgāi) - Cantonese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 193, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"မင်္ဂလာပါ (mingalaba) - Burmese\"", + "type": "rectangle", + "pos": { + "x": 4653, + "y": 0 + }, + "width": 307, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "မင်္ဂလာပါ (mingalaba) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 262, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"сайн уу (sain uu) - Mongolian\"", + "type": "rectangle", + "pos": { + "x": 5020, + "y": 0 + }, + "width": 264, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "сайн уу (sain uu) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 219, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi\"", + "type": "rectangle", + "pos": { + "x": 5344, + "y": 0 + }, + "width": 328, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 283, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"你吃了吗 (ní chī le ma) - Mandarin Chinese\"", + "type": "rectangle", + "pos": { + "x": 5732, + "y": 0 + }, + "width": 370, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "你吃了吗 (ní chī le ma) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 325, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"饭 (fan) - Zhuang\"", + "type": "rectangle", + "pos": { + "x": 6162, + "y": 0 + }, + "width": 167, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "饭 (fan) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 122, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "مەن سىزنى ياخشى ئۈمىد ق", + "type": "rectangle", + "pos": { + "x": 6389, + "y": 0 + }, + "width": 266, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "مەن سىزنى ياخشى ئۈمىد ق", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 221, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg new file mode 100644 index 000000000..2947dbba3 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +我 (wǒ) - Mandarin Chineseສະບາຍດີ (sabaai dii) - Laoជំរាបសួរ (jomreab suor) - Khmerสวัสดี (sà-wàt-dii) - Thaiສະບາຍດີ (sabaidee) - Laoဟယ်လို (helaou) - Burmesemari (まり) - Ainucào (草) - Zhuangкүнтізбе (kúntízbe) - Kazakhբարև (barev) - Armenianмонгол (mongol) - Mongolianmila (میلا) - Uyghurનમસ્તે (namaste) - Gujarati漢字 (kanji) - Japanese위 (wi) - Korean吾哥 (ngǔgāi) - Cantoneseမင်္ဂလာပါ (mingalaba) - Burmeseсайн уу (sain uu) - Mongolianਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi你吃了吗 (ní chī le ma) - Mandarin Chinese饭 (fan) - Zhuangمەن سىزنى ياخشى ئۈمىد ق + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language-2/elk/board.exp.json b/e2etests/testdata/unicode/mixed-language-2/elk/board.exp.json new file mode 100644 index 000000000..6f5f1cbd9 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/elk/board.exp.json @@ -0,0 +1,909 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 240, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "我 (wǒ) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 195, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 272, + "y": 12 + }, + "width": 241, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaai dii) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 196, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 533, + "y": 12 + }, + "width": 301, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ជំរាបសួរ (jomreab suor) - Khmer", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 256, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"สวัสดี (sà-wàt-dii) - Thai\"", + "type": "rectangle", + "pos": { + "x": 854, + "y": 12 + }, + "width": 244, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "สวัสดี (sà-wàt-dii) - Thai", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 199, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ສະບາຍດີ (sabaidee) - Lao\"", + "type": "rectangle", + "pos": { + "x": 1118, + "y": 12 + }, + "width": 237, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaidee) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 192, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ဟယ်လို (helaou) - Burmese\"", + "type": "rectangle", + "pos": { + "x": 1375, + "y": 12 + }, + "width": 247, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ဟယ်လို (helaou) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 202, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"mari (まり) - Ainu\"", + "type": "rectangle", + "pos": { + "x": 1642, + "y": 12 + }, + "width": 176, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mari (まり) - Ainu", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 131, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"cào (草) - Zhuang\"", + "type": "rectangle", + "pos": { + "x": 1838, + "y": 12 + }, + "width": 173, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "cào (草) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 128, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"күнтізбе (kúntízbe) - Kazakh\"", + "type": "rectangle", + "pos": { + "x": 2031, + "y": 12 + }, + "width": 282, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "күнтізбе (kúntízbe) - Kazakh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 237, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"բարև (barev) - Armenian\"", + "type": "rectangle", + "pos": { + "x": 2333, + "y": 12 + }, + "width": 224, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "բարև (barev) - Armenian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 179, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"монгол (mongol) - Mongolian\"", + "type": "rectangle", + "pos": { + "x": 2577, + "y": 12 + }, + "width": 265, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "монгол (mongol) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 220, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"mila (میلا) - Uyghur\"", + "type": "rectangle", + "pos": { + "x": 2862, + "y": 12 + }, + "width": 199, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mila (میلا) - Uyghur", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 154, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"નમસ્તે (namaste) - Gujarati\"", + "type": "rectangle", + "pos": { + "x": 3081, + "y": 12 + }, + "width": 255, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "નમસ્તે (namaste) - Gujarati", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 210, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"漢字 (kanji) - Japanese\"", + "type": "rectangle", + "pos": { + "x": 3356, + "y": 12 + }, + "width": 213, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "漢字 (kanji) - Japanese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 168, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"위 (wi) - Korean\"", + "type": "rectangle", + "pos": { + "x": 3589, + "y": 12 + }, + "width": 158, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "위 (wi) - Korean", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 113, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"吾哥 (ngǔgāi) - Cantonese\"", + "type": "rectangle", + "pos": { + "x": 3767, + "y": 12 + }, + "width": 238, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "吾哥 (ngǔgāi) - Cantonese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 193, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"မင်္ဂလာပါ (mingalaba) - Burmese\"", + "type": "rectangle", + "pos": { + "x": 4025, + "y": 12 + }, + "width": 307, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "မင်္ဂလာပါ (mingalaba) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 262, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"сайн уу (sain uu) - Mongolian\"", + "type": "rectangle", + "pos": { + "x": 4352, + "y": 12 + }, + "width": 264, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "сайн уу (sain uu) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 219, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi\"", + "type": "rectangle", + "pos": { + "x": 4636, + "y": 12 + }, + "width": 328, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 283, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"你吃了吗 (ní chī le ma) - Mandarin Chinese\"", + "type": "rectangle", + "pos": { + "x": 4984, + "y": 12 + }, + "width": 370, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "你吃了吗 (ní chī le ma) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 325, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"饭 (fan) - Zhuang\"", + "type": "rectangle", + "pos": { + "x": 5374, + "y": 12 + }, + "width": 167, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "饭 (fan) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 122, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "مەن سىزنى ياخشى ئۈمىد ق", + "type": "rectangle", + "pos": { + "x": 5561, + "y": 12 + }, + "width": 266, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "مەن سىزنى ياخشى ئۈمىد ق", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 221, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/mixed-language-2/elk/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language-2/elk/sketch.exp.svg new file mode 100644 index 000000000..1e19459bf --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +我 (wǒ) - Mandarin Chineseສະບາຍດີ (sabaai dii) - Laoជំរាបសួរ (jomreab suor) - Khmerสวัสดี (sà-wàt-dii) - Thaiສະບາຍດີ (sabaidee) - Laoဟယ်လို (helaou) - Burmesemari (まり) - Ainucào (草) - Zhuangкүнтізбе (kúntízbe) - Kazakhբարև (barev) - Armenianмонгол (mongol) - Mongolianmila (میلا) - Uyghurનમસ્તે (namaste) - Gujarati漢字 (kanji) - Japanese위 (wi) - Korean吾哥 (ngǔgāi) - Cantoneseမင်္ဂလာပါ (mingalaba) - Burmeseсайн уу (sain uu) - Mongolianਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi你吃了吗 (ní chī le ma) - Mandarin Chinese饭 (fan) - Zhuangمەن سىزنى ياخشى ئۈمىد ق + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language/dagre/board.exp.json b/e2etests/testdata/unicode/mixed-language/dagre/board.exp.json new file mode 100644 index 000000000..310f55112 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/dagre/board.exp.json @@ -0,0 +1,226 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 275, + "y": 0 + }, + "width": 428, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "有一个叫做夏天的季节。\n ある季節、夏という名前がついています。\n한 계절, 여름이란 이름이 있습니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 383, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 0, + "y": 198 + }, + "width": 448, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏天的时候,天气非常热,人们总是流着汗。", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 403, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "text", + "pos": { + "x": 508, + "y": 199 + }, + "width": 492, + "height": 64, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏になると、とても暑くて、人々は汗を流しています。\n\n여름에는 매우 더워서 사람들은 땀을 흘립니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 492, + "labelHeight": 64, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 357.83838383838383, + "y": 98 + }, + { + "x": 250.76767676767676, + "y": 138 + }, + { + "x": 224, + "y": 158 + }, + { + "x": 224, + "y": 198 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> c)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 620.1616161616162, + "y": 98 + }, + { + "x": 727.2323232323232, + "y": 138 + }, + { + "x": 754, + "y": 158.2 + }, + { + "x": 754, + "y": 199 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg new file mode 100644 index 000000000..a3682641a --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg @@ -0,0 +1,818 @@ + +有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

夏になると、とても暑くて、人々は汗を流しています。

+

여름에는 매우 더워서 사람들은 땀을 흘립니다.

+
+ + +
\ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language/elk/board.exp.json b/e2etests/testdata/unicode/mixed-language/elk/board.exp.json new file mode 100644 index 000000000..cdd2c0da3 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/elk/board.exp.json @@ -0,0 +1,216 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 93, + "y": 12 + }, + "width": 428, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "有一个叫做夏天的季节。\n ある季節、夏という名前がついています。\n한 계절, 여름이란 이름이 있습니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 383, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 12, + "y": 190 + }, + "width": 448, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏天的时候,天气非常热,人们总是流着汗。", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 403, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "text", + "pos": { + "x": 480, + "y": 190 + }, + "width": 492, + "height": 64, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏になると、とても暑くて、人々は汗を流しています。\n\n여름에는 매우 더워서 사람들은 땀을 흘립니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 492, + "labelHeight": 64, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 236, + "y": 110 + }, + { + "x": 236, + "y": 190 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> c)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 378.66666666666663, + "y": 110 + }, + { + "x": 378.66666666666663, + "y": 150 + }, + { + "x": 726, + "y": 150 + }, + { + "x": 726, + "y": 190 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg new file mode 100644 index 000000000..d013202bf --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg @@ -0,0 +1,818 @@ + +有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

夏になると、とても暑くて、人々は汗を流しています。

+

여름에는 매우 더워서 사람들은 땀을 흘립니다.

+
+ + +
\ No newline at end of file diff --git a/e2etests/unicode_test.go b/e2etests/unicode_test.go index 0629cdf09..d6131857f 100644 --- a/e2etests/unicode_test.go +++ b/e2etests/unicode_test.go @@ -48,6 +48,84 @@ e: English English English f: 先日先日先日 a -> b -> c -> d -> e -> f +`, + }, + { + name: "chinese", + script: `poem: |md + 床前明月光, + + 疑是地上霜。 + + 举头望明月, + + 低头思故乡。 +| +a: 所以,即使夏天很热 +poem -> a +`, + }, + { + name: "korean", + script: `a: 고생끝에낙이온다 +`, + }, + { + name: "mixed-language", + script: `a: 有一个叫做夏天的季节。\n ある季節、夏という名前がついています。\n한 계절, 여름이란 이름이 있습니다. +b: 夏天的时候,天气非常热,人们总是流着汗。 +c: |md + 夏になると、とても暑くて、人々は汗を流しています。 + + 여름에는 매우 더워서 사람들은 땀을 흘립니다. +| +a -> b +a -> c +`, + }, + { + name: "mixed-language-2", + script: `a: 我 (wǒ) - Mandarin Chinese +b: ສະບາຍດີ (sabaai dii) - Lao +c: ជំរាបសួរ (jomreab suor) - Khmer + +สวัสดี (sà-wàt-dii) - Thai + +ສະບາຍດີ (sabaidee) - Lao + +ဟယ်လို (helaou) - Burmese + +mari (まり) - Ainu + +cào (草) - Zhuang + +күнтізбе (kúntízbe) - Kazakh + +բարև (barev) - Armenian + +монгол (mongol) - Mongolian + +mila (میلا) - Uyghur + +નમસ્તે (namaste) - Gujarati + +漢字 (kanji) - Japanese + +위 (wi) - Korean + +吾哥 (ngǔgāi) - Cantonese + +မင်္ဂလာပါ (mingalaba) - Burmese + +сайн уу (sain uu) - Mongolian + +ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi + +你吃了吗 (ní chī le ma) - Mandarin Chinese + +饭 (fan) - Zhuang + +مەن سىزنى ياخشى ئۈمىد ق `, }, } diff --git a/go.mod b/go.mod index c8986bd2f..d586076c6 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/lucasb-eyer/go-colorful v1.2.0 - github.com/mattn/go-runewidth v0.0.14 github.com/mazznoer/csscolorparser v0.1.3 github.com/playwright-community/playwright-go v0.2000.1 github.com/rivo/uniseg v0.4.3 diff --git a/go.sum b/go.sum index 9b83338c3..b98f3d151 100644 --- a/go.sum +++ b/go.sum @@ -115,8 +115,6 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mazznoer/csscolorparser v0.1.3 h1:vug4zh6loQxAUxfU1DZEu70gTPufDPspamZlHAkKcxE= github.com/mazznoer/csscolorparser v0.1.3/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= @@ -130,8 +128,6 @@ github.com/playwright-community/playwright-go v0.2000.1/go.mod h1:1y9cM9b9dVHnuR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= diff --git a/lib/textmeasure/markdown.go b/lib/textmeasure/markdown.go index 4a30afbbb..bb9cdaa46 100644 --- a/lib/textmeasure/markdown.go +++ b/lib/textmeasure/markdown.go @@ -257,6 +257,8 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, fontFamily *d2fonts.Fon if isCode { w *= FontSize_pre_code_em h *= FontSize_pre_code_em + } else { + w = ruler.scaleUnicode(w, font, str) } if debugMeasure { fmt.Printf("%stext(%v,%v)\n", depthStr, w, h) diff --git a/lib/textmeasure/textmeasure.go b/lib/textmeasure/textmeasure.go index cdf9c811c..2e539e86d 100644 --- a/lib/textmeasure/textmeasure.go +++ b/lib/textmeasure/textmeasure.go @@ -166,8 +166,7 @@ func (r *Ruler) addFontSize(font d2fonts.Font) { r.tabWidths[font] = atlas.glyph(' ').advance * TAB_SIZE } -func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int) { - w, h := t.MeasurePrecise(font, s) +func (t *Ruler) scaleUnicode(w float64, font d2fonts.Font, s string) float64 { // Weird unicode stuff is going on when this is true // See https://github.com/rivo/uniseg#grapheme-clusters // This method is a good-enough approximation. It overshoots, but not by much. @@ -198,6 +197,7 @@ func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int) { var bounds *rect _, _, bounds, dot = t.atlases[font].DrawRune(prevRune, r, dot) b = b.union(bounds) + prevRune = r } lineW -= b.w() @@ -206,6 +206,12 @@ func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int) { w = math.Max(w, lineW) } } + return w +} + +func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int) { + w, h := t.MeasurePrecise(font, s) + w = t.scaleUnicode(w, font, s) return int(math.Ceil(w)), int(math.Ceil(h)) } From cbfa02825849ba844bab659a503fa35ac93085b6 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 14 Feb 2023 10:39:15 -0800 Subject: [PATCH 09/68] regenerate tests --- .../mixed-language-2/dagre/board.exp.json | 673 ++++++++++++++++-- .../mixed-language-2/dagre/sketch.exp.svg | 6 +- .../mixed-language-2/elk/board.exp.json | 565 +++++++++++++-- .../mixed-language-2/elk/sketch.exp.svg | 6 +- e2etests/unicode_test.go | 31 +- 5 files changed, 1166 insertions(+), 115 deletions(-) diff --git a/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json b/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json index bb5c666f8..de3b3e2bf 100644 --- a/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json +++ b/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json @@ -6,7 +6,7 @@ "id": "a", "type": "rectangle", "pos": { - "x": 0, + "x": 31, "y": 0 }, "width": 240, @@ -47,8 +47,8 @@ "id": "b", "type": "rectangle", "pos": { - "x": 300, - "y": 0 + "x": 30, + "y": 166 }, "width": 241, "height": 66, @@ -88,8 +88,8 @@ "id": "c", "type": "rectangle", "pos": { - "x": 601, - "y": 0 + "x": 0, + "y": 332 }, "width": 301, "height": 66, @@ -126,11 +126,11 @@ "level": 1 }, { - "id": "\"สวัสดี (sà-wàt-dii) - Thai\"", + "id": "d", "type": "rectangle", "pos": { - "x": 962, - "y": 0 + "x": 29, + "y": 498 }, "width": 244, "height": 66, @@ -167,10 +167,10 @@ "level": 1 }, { - "id": "\"ສະບາຍດີ (sabaidee) - Lao\"", + "id": "e", "type": "rectangle", "pos": { - "x": 1266, + "x": 336, "y": 0 }, "width": 237, @@ -208,11 +208,11 @@ "level": 1 }, { - "id": "\"ဟယ်လို (helaou) - Burmese\"", + "id": "f", "type": "rectangle", "pos": { - "x": 1563, - "y": 0 + "x": 331, + "y": 166 }, "width": 247, "height": 66, @@ -249,11 +249,11 @@ "level": 1 }, { - "id": "\"mari (まり) - Ainu\"", + "id": "g", "type": "rectangle", "pos": { - "x": 1870, - "y": 0 + "x": 367, + "y": 332 }, "width": 176, "height": 66, @@ -290,11 +290,11 @@ "level": 1 }, { - "id": "\"cào (草) - Zhuang\"", + "id": "h", "type": "rectangle", "pos": { - "x": 2106, - "y": 0 + "x": 368, + "y": 498 }, "width": 173, "height": 66, @@ -331,10 +331,10 @@ "level": 1 }, { - "id": "\"күнтізбе (kúntízbe) - Kazakh\"", + "id": "i", "type": "rectangle", "pos": { - "x": 2339, + "x": 633, "y": 0 }, "width": 282, @@ -372,11 +372,11 @@ "level": 1 }, { - "id": "\"բարև (barev) - Armenian\"", + "id": "j", "type": "rectangle", "pos": { - "x": 2681, - "y": 0 + "x": 662, + "y": 166 }, "width": 224, "height": 66, @@ -413,11 +413,11 @@ "level": 1 }, { - "id": "\"монгол (mongol) - Mongolian\"", + "id": "k", "type": "rectangle", "pos": { - "x": 2965, - "y": 0 + "x": 642, + "y": 332 }, "width": 265, "height": 66, @@ -454,11 +454,11 @@ "level": 1 }, { - "id": "\"mila (میلا) - Uyghur\"", + "id": "l", "type": "rectangle", "pos": { - "x": 3290, - "y": 0 + "x": 675, + "y": 498 }, "width": 199, "height": 66, @@ -495,10 +495,10 @@ "level": 1 }, { - "id": "\"નમસ્તે (namaste) - Gujarati\"", + "id": "m", "type": "rectangle", "pos": { - "x": 3549, + "x": 975, "y": 0 }, "width": 255, @@ -536,11 +536,11 @@ "level": 1 }, { - "id": "\"漢字 (kanji) - Japanese\"", + "id": "n", "type": "rectangle", "pos": { - "x": 3864, - "y": 0 + "x": 996, + "y": 166 }, "width": 213, "height": 66, @@ -577,11 +577,11 @@ "level": 1 }, { - "id": "\"위 (wi) - Korean\"", + "id": "o", "type": "rectangle", "pos": { - "x": 4137, - "y": 0 + "x": 1024, + "y": 332 }, "width": 158, "height": 66, @@ -618,11 +618,11 @@ "level": 1 }, { - "id": "\"吾哥 (ngǔgāi) - Cantonese\"", + "id": "p", "type": "rectangle", "pos": { - "x": 4355, - "y": 0 + "x": 984, + "y": 498 }, "width": 238, "height": 66, @@ -662,7 +662,7 @@ "id": "\"မင်္ဂလာပါ (mingalaba) - Burmese\"", "type": "rectangle", "pos": { - "x": 4653, + "x": 1290, "y": 0 }, "width": 307, @@ -703,7 +703,7 @@ "id": "\"сайн уу (sain uu) - Mongolian\"", "type": "rectangle", "pos": { - "x": 5020, + "x": 1657, "y": 0 }, "width": 264, @@ -744,7 +744,7 @@ "id": "\"ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi\"", "type": "rectangle", "pos": { - "x": 5344, + "x": 1981, "y": 0 }, "width": 328, @@ -785,7 +785,7 @@ "id": "\"你吃了吗 (ní chī le ma) - Mandarin Chinese\"", "type": "rectangle", "pos": { - "x": 5732, + "x": 2369, "y": 0 }, "width": 370, @@ -826,7 +826,7 @@ "id": "\"饭 (fan) - Zhuang\"", "type": "rectangle", "pos": { - "x": 6162, + "x": 2799, "y": 0 }, "width": 167, @@ -867,7 +867,7 @@ "id": "مەن سىزنى ياخشى ئۈمىد ق", "type": "rectangle", "pos": { - "x": 6389, + "x": 3026, "y": 0 }, "width": 266, @@ -905,5 +905,582 @@ "level": 1 } ], - "connections": [] + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 150.5, + "y": 66 + }, + { + "x": 150.5, + "y": 106 + }, + { + "x": 150.5, + "y": 126 + }, + { + "x": 150.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> c)[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 150.5, + "y": 232 + }, + { + "x": 150.5, + "y": 272 + }, + { + "x": 150.5, + "y": 292 + }, + { + "x": 150.5, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c -> d)[0]", + "src": "c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 150.5, + "y": 398 + }, + { + "x": 150.5, + "y": 438 + }, + { + "x": 150.5, + "y": 458 + }, + { + "x": 150.5, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> f)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "f", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 454.5, + "y": 66 + }, + { + "x": 454.5, + "y": 106 + }, + { + "x": 454.5, + "y": 126 + }, + { + "x": 454.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(f -> g)[0]", + "src": "f", + "srcArrow": "none", + "srcLabel": "", + "dst": "g", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 454.5, + "y": 232 + }, + { + "x": 454.5, + "y": 272 + }, + { + "x": 454.5, + "y": 292 + }, + { + "x": 454.5, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(g -> h)[0]", + "src": "g", + "srcArrow": "none", + "srcLabel": "", + "dst": "h", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 454.5, + "y": 398 + }, + { + "x": 454.5, + "y": 438 + }, + { + "x": 454.5, + "y": 458 + }, + { + "x": 454.5, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(i -> j)[0]", + "src": "i", + "srcArrow": "none", + "srcLabel": "", + "dst": "j", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 774, + "y": 66 + }, + { + "x": 774, + "y": 106 + }, + { + "x": 774, + "y": 126 + }, + { + "x": 774, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(j -> k)[0]", + "src": "j", + "srcArrow": "none", + "srcLabel": "", + "dst": "k", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 774, + "y": 232 + }, + { + "x": 774, + "y": 272 + }, + { + "x": 774, + "y": 292 + }, + { + "x": 774, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k -> l)[0]", + "src": "k", + "srcArrow": "none", + "srcLabel": "", + "dst": "l", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 774, + "y": 398 + }, + { + "x": 774, + "y": 438 + }, + { + "x": 774, + "y": 458 + }, + { + "x": 774, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(m -> n)[0]", + "src": "m", + "srcArrow": "none", + "srcLabel": "", + "dst": "n", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1102.5, + "y": 66 + }, + { + "x": 1102.5, + "y": 106 + }, + { + "x": 1102.5, + "y": 126 + }, + { + "x": 1102.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(n -> o)[0]", + "src": "n", + "srcArrow": "none", + "srcLabel": "", + "dst": "o", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1102.5, + "y": 232 + }, + { + "x": 1102.5, + "y": 272 + }, + { + "x": 1102.5, + "y": 292 + }, + { + "x": 1102.5, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(o -> p)[0]", + "src": "o", + "srcArrow": "none", + "srcLabel": "", + "dst": "p", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1102.5, + "y": 398 + }, + { + "x": 1102.5, + "y": 438 + }, + { + "x": 1102.5, + "y": 458 + }, + { + "x": 1102.5, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] } diff --git a/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg index 2947dbba3..b3c441a46 100644 --- a/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg +++ b/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg @@ -3,7 +3,7 @@ id="d2-svg" style="background: white;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" -width="6859" height="270" viewBox="-102 -102 6859 270"> \ No newline at end of file diff --git a/e2etests/testdata/measured/empty-shape/dagre/sketch.exp.svg b/e2etests/testdata/measured/empty-shape/dagre/sketch.exp.svg index 914a423a0..659fb392c 100644 --- a/e2etests/testdata/measured/empty-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/measured/empty-shape/dagre/sketch.exp.svg @@ -39,7 +39,7 @@ width="304" height="304" viewBox="-102 -102 304 304"> \ No newline at end of file diff --git a/e2etests/testdata/measured/empty-sql_table/dagre/sketch.exp.svg b/e2etests/testdata/measured/empty-sql_table/dagre/sketch.exp.svg index 53a789b51..565c497b9 100644 --- a/e2etests/testdata/measured/empty-sql_table/dagre/sketch.exp.svg +++ b/e2etests/testdata/measured/empty-sql_table/dagre/sketch.exp.svg @@ -39,7 +39,7 @@ width="254" height="216" viewBox="-102 -102 254 216"> \ No newline at end of file diff --git a/e2etests/testdata/regression/ampersand-escape/dagre/sketch.exp.svg b/e2etests/testdata/regression/ampersand-escape/dagre/sketch.exp.svg index 15a7a2d4d..9b25cef7b 100644 --- a/e2etests/testdata/regression/ampersand-escape/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/ampersand-escape/dagre/sketch.exp.svg @@ -52,8 +52,8 @@ width="572" height="286" viewBox="-102 -118 572 286"> \ No newline at end of file diff --git a/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg b/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg index 18f97f6a3..1df0f1fd3 100644 --- a/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg @@ -39,7 +39,7 @@ width="452" height="332" viewBox="-90 -90 452 332"> \ No newline at end of file diff --git a/e2etests/testdata/regression/elk_loop_panic/dagre/sketch.exp.svg b/e2etests/testdata/regression/elk_loop_panic/dagre/sketch.exp.svg index 636457be9..272e6397b 100644 --- a/e2etests/testdata/regression/elk_loop_panic/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_loop_panic/dagre/sketch.exp.svg @@ -39,8 +39,8 @@ width="470" height="368" viewBox="-102 -100 470 368">x

linux: because a PC is a terrible thing to waste

-
a You don't have to know how the computer works,just how to work the computer. - +a You don't have to know how the computer works,just how to work the computer. + x

linux: because a PC is a terrible thing to waste

-
a You don't have to know how the computer works,just how to work the computer. - +a You don't have to know how the computer works,just how to work the computer. + aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 + diff --git a/e2etests/testdata/stable/chaos2/elk/sketch.exp.svg b/e2etests/testdata/stable/chaos2/elk/sketch.exp.svg index 742b1557d..dc33a8744 100644 --- a/e2etests/testdata/stable/chaos2/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/chaos2/elk/sketch.exp.svg @@ -796,8 +796,8 @@ width="898" height="2166" viewBox="-90 -90 898 2166">aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 - +aabbllmmnnoocciikkddgghhjjeeff1122 334455667788 + diff --git a/e2etests/testdata/stable/circle_arrowhead/dagre/sketch.exp.svg b/e2etests/testdata/stable/circle_arrowhead/dagre/sketch.exp.svg index 0304d0331..8eb599547 100644 --- a/e2etests/testdata/stable/circle_arrowhead/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/circle_arrowhead/dagre/sketch.exp.svg @@ -39,8 +39,8 @@ width="379" height="457" viewBox="-102 -102 379 457">xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right - +JoeDonaldi am top lefti am top righti am bottom lefti am bottom right + xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right - +JoeDonaldi am top lefti am top righti am bottom lefti am bottom right + poll the peopleresultsunfavorablefavorablewill of the people

A winning strategy

-
- + + poll the peopleresultsunfavorablefavorablewill of the people

A winning strategy

-
- + + mixed togethersugarsolution we get - +mixed togethersugarsolution we get + mixed togethersugarsolution we get - +mixed togethersugarsolution we get +

Markdown: Syntax

-
ab - +ab +

Markdown: Syntax

-
ab - +ab + markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- + + markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- + + markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- + + markdown

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
- + +

code

-
ab - +ab +

code

-
ab - +ab + bearmama bearpapa bear - +bearmama bearpapa bear + bearmama bearpapa bear - +bearmama bearpapa bear + 有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

夏になると、とても暑くて、人々は汗を流しています。

여름에는 매우 더워서 사람들은 땀을 흘립니다.

-
- + + 有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

夏になると、とても暑くて、人々は汗を流しています。

여름에는 매우 더워서 사람들은 땀을 흘립니다.

-
- + + abcbcbcea + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/container_dimensions/elk/board.exp.json b/e2etests/testdata/stable/container_dimensions/elk/board.exp.json new file mode 100644 index 000000000..96eb760eb --- /dev/null +++ b/e2etests/testdata/stable/container_dimensions/elk/board.exp.json @@ -0,0 +1,455 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 134 + }, + "width": 700, + "height": 292, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.b", + "type": "rectangle", + "pos": { + "x": 162, + "y": 184 + }, + "width": 400, + "height": 61, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.c", + "type": "rectangle", + "pos": { + "x": 62, + "y": 315 + }, + "width": 600, + "height": 61, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 732, + "y": 12 + }, + "width": 700, + "height": 536, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b.b", + "type": "rectangle", + "pos": { + "x": 782, + "y": 296 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.c", + "type": "rectangle", + "pos": { + "x": 782, + "y": 432 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.e", + "type": "rectangle", + "pos": { + "x": 855, + "y": 62 + }, + "width": 48, + "height": 300, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 1452, + "y": 130 + }, + "width": 200, + "height": 300, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c.a", + "type": "rectangle", + "pos": { + "x": 1502, + "y": 180 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + } + ], + "connections": [ + { + "id": "a.(b -> c)[0]", + "src": "a.b", + "srcArrow": "none", + "srcLabel": "", + "dst": "a.c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 362, + "y": 245 + }, + { + "x": 362, + "y": 315 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "b.(b -> c)[0]", + "src": "b.b", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 808.5, + "y": 362 + }, + { + "x": 808.5, + "y": 432 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/stable/container_dimensions/elk/sketch.exp.svg b/e2etests/testdata/stable/container_dimensions/elk/sketch.exp.svg new file mode 100644 index 000000000..3a1b99b89 --- /dev/null +++ b/e2etests/testdata/stable/container_dimensions/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +abcbcbcea + + + \ No newline at end of file diff --git a/main.go b/main.go index 6634e25a8..9b7da5cba 100644 --- a/main.go +++ b/main.go @@ -251,7 +251,17 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, sketc if sketch { opts.FontFamily = go2.Pointer(d2fonts.HandDrawn) } - diagram, _, err := d2lib.Compile(ctx, string(input), opts) + diagram, g, err := d2lib.Compile(ctx, string(input), opts) + if err != nil { + return nil, false, err + } + + pluginInfo, err := plugin.Info(ctx) + if err != nil { + return nil, false, err + } + + err = d2plugin.FeatureSupportCheck(pluginInfo, g) if err != nil { return nil, false, err } diff --git a/testdata/d2compiler/TestCompile/dimensions_on_containers.exp.json b/testdata/d2compiler/TestCompile/dimensions_on_containers.exp.json new file mode 100644 index 000000000..a5b45a2b1 --- /dev/null +++ b/testdata/d2compiler/TestCompile/dimensions_on_containers.exp.json @@ -0,0 +1,1435 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,0:0:0-45:0:505", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,1:0:1-44:1:504", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,1:0:1-1:10:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,1:0:1-1:10:11", + "value": [ + { + "string": "containers", + "raw_string": "containers" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,1:12:13-44:0:503", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,2:1:16-11:2:131", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,2:1:16-2:17:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,2:1:16-2:17:32", + "value": [ + { + "string": "circle container", + "raw_string": "circle container" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,2:19:34-11:1:130", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,3:2:38-3:15:51", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,3:2:38-3:7:43", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,3:2:38-3:7:43", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,3:9:45-3:15:51", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,4:2:54-4:12:64", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,4:2:54-4:7:59", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,4:2:54-4:7:59", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,4:9:61-4:12:64", + "raw": "512", + "value": "512" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,6:2:68-10:3:128", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,6:2:68-6:9:75", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,6:2:68-6:9:75", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,6:11:77-10:2:127", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,7:3:82-7:17:96", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,7:3:82-7:8:87", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,7:3:82-7:8:87", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,7:10:89-7:17:96", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,8:3:100-8:13:110", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,8:3:100-8:8:105", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,8:3:100-8:8:105", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,8:10:107-8:13:110", + "raw": "128", + "value": "128" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,9:3:114-9:13:124", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,9:3:114-9:9:120", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,9:3:114-9:9:120", + "value": [ + { + "string": "height", + "raw_string": "height" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,9:11:122-9:13:124", + "raw": "64", + "value": "64" + } + } + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,12:1:133-21:2:248", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,12:1:133-12:18:150", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,12:1:133-12:18:150", + "value": [ + { + "string": "diamond container", + "raw_string": "diamond container" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,12:20:152-21:1:247", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,13:2:156-13:16:170", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,13:2:156-13:7:161", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,13:2:156-13:7:161", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,13:9:163-13:16:170", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,14:2:173-14:12:183", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,14:2:173-14:7:178", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,14:2:173-14:7:178", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,14:9:180-14:12:183", + "raw": "512", + "value": "512" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,15:2:186-15:13:197", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,15:2:186-15:8:192", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,15:2:186-15:8:192", + "value": [ + { + "string": "height", + "raw_string": "height" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,15:10:194-15:13:197", + "raw": "256", + "value": "256" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,17:2:201-20:3:245", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,17:2:201-17:8:207", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,17:2:201-17:8:207", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,17:10:209-20:2:244", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,18:3:214-18:16:227", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,18:3:214-18:8:219", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,18:3:214-18:8:219", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,18:10:221-18:16:227", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,19:3:231-19:13:241", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,19:3:231-19:8:236", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,19:3:231-19:8:236", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,19:10:238-19:13:241", + "raw": "128", + "value": "128" + } + } + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,22:1:250-32:2:375", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,22:1:250-22:15:264", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,22:1:250-22:15:264", + "value": [ + { + "string": "oval container", + "raw_string": "oval container" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,22:17:266-32:1:374", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,23:2:270-23:13:281", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,23:2:270-23:7:275", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,23:2:270-23:7:275", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,23:9:277-23:13:281", + "value": [ + { + "string": "oval", + "raw_string": "oval" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,24:2:284-24:12:294", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,24:2:284-24:7:289", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,24:2:284-24:7:289", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,24:9:291-24:12:294", + "raw": "512", + "value": "512" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,25:2:297-25:13:308", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,25:2:297-25:8:303", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,25:2:297-25:8:303", + "value": [ + { + "string": "height", + "raw_string": "height" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,25:10:305-25:13:308", + "raw": "256", + "value": "256" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,27:2:312-31:3:372", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,27:2:312-27:9:319", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,27:2:312-27:9:319", + "value": [ + { + "string": "hexagon", + "raw_string": "hexagon" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,27:11:321-31:2:371", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,28:3:326-28:17:340", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,28:3:326-28:8:331", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,28:3:326-28:8:331", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,28:10:333-28:17:340", + "value": [ + { + "string": "hexagon", + "raw_string": "hexagon" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,29:3:344-29:13:354", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,29:3:344-29:8:349", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,29:3:344-29:8:349", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,29:10:351-29:13:354", + "raw": "128", + "value": "128" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,30:3:358-30:13:368", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,30:3:358-30:9:364", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,30:3:358-30:9:364", + "value": [ + { + "string": "height", + "raw_string": "height" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,30:11:366-30:13:368", + "raw": "64", + "value": "64" + } + } + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,33:1:377-43:2:502", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,33:1:377-33:18:394", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,33:1:377-33:18:394", + "value": [ + { + "string": "hexagon container", + "raw_string": "hexagon container" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,33:20:396-43:1:501", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,34:2:400-34:16:414", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,34:2:400-34:7:405", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,34:2:400-34:7:405", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,34:9:407-34:16:414", + "value": [ + { + "string": "hexagon", + "raw_string": "hexagon" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,35:2:417-35:12:427", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,35:2:417-35:7:422", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,35:2:417-35:7:422", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,35:9:424-35:12:427", + "raw": "512", + "value": "512" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,36:2:430-36:13:441", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,36:2:430-36:8:436", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,36:2:430-36:8:436", + "value": [ + { + "string": "height", + "raw_string": "height" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,36:10:438-36:13:441", + "raw": "256", + "value": "256" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,38:2:445-42:3:499", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,38:2:445-38:6:449", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,38:2:445-38:6:449", + "value": [ + { + "string": "oval", + "raw_string": "oval" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,38:8:451-42:2:498", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,39:3:456-39:14:467", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,39:3:456-39:8:461", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,39:3:456-39:8:461", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,39:10:463-39:14:467", + "value": [ + { + "string": "oval", + "raw_string": "oval" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,40:3:471-40:13:481", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,40:3:471-40:8:476", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,40:3:471-40:8:476", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,40:10:478-40:13:481", + "raw": "128", + "value": "128" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,41:3:485-41:13:495", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,41:3:485-41:9:491", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,41:3:485-41:9:491", + "value": [ + { + "string": "height", + "raw_string": "height" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,41:11:493-41:13:495", + "raw": "64", + "value": "64" + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "containers", + "id_val": "containers", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,1:0:1-1:10:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,1:0:1-1:10:11", + "value": [ + { + "string": "containers", + "raw_string": "containers" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "containers" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "circle container", + "id_val": "circle container", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,2:1:16-2:17:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,2:1:16-2:17:32", + "value": [ + { + "string": "circle container", + "raw_string": "circle container" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "circle container" + }, + "style": {}, + "width": { + "value": "512" + }, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "diamond", + "id_val": "diamond", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,6:2:68-6:9:75", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,6:2:68-6:9:75", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "diamond" + }, + "style": {}, + "width": { + "value": "128" + }, + "height": { + "value": "64" + }, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "diamond container", + "id_val": "diamond container", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,12:1:133-12:18:150", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,12:1:133-12:18:150", + "value": [ + { + "string": "diamond container", + "raw_string": "diamond container" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "diamond container" + }, + "style": {}, + "width": { + "value": "512" + }, + "height": { + "value": "256" + }, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "circle", + "id_val": "circle", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,17:2:201-17:8:207", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,17:2:201-17:8:207", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "circle" + }, + "style": {}, + "width": { + "value": "128" + }, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "oval container", + "id_val": "oval container", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,22:1:250-22:15:264", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,22:1:250-22:15:264", + "value": [ + { + "string": "oval container", + "raw_string": "oval container" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "oval container" + }, + "style": {}, + "width": { + "value": "512" + }, + "height": { + "value": "256" + }, + "near_key": null, + "shape": { + "value": "oval" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "hexagon", + "id_val": "hexagon", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,27:2:312-27:9:319", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,27:2:312-27:9:319", + "value": [ + { + "string": "hexagon", + "raw_string": "hexagon" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "hexagon" + }, + "style": {}, + "width": { + "value": "128" + }, + "height": { + "value": "64" + }, + "near_key": null, + "shape": { + "value": "hexagon" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "hexagon container", + "id_val": "hexagon container", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,33:1:377-33:18:394", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,33:1:377-33:18:394", + "value": [ + { + "string": "hexagon container", + "raw_string": "hexagon container" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "hexagon container" + }, + "style": {}, + "width": { + "value": "512" + }, + "height": { + "value": "256" + }, + "near_key": null, + "shape": { + "value": "hexagon" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "oval", + "id_val": "oval", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,38:2:445-38:6:449", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/dimensions_on_containers.d2,38:2:445-38:6:449", + "value": [ + { + "string": "oval", + "raw_string": "oval" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "oval" + }, + "style": {}, + "width": { + "value": "128" + }, + "height": { + "value": "64" + }, + "near_key": null, + "shape": { + "value": "oval" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/no_dimensions_on_containers.exp.json b/testdata/d2compiler/TestCompile/no_dimensions_on_containers.exp.json deleted file mode 100644 index ec21bacd7..000000000 --- a/testdata/d2compiler/TestCompile/no_dimensions_on_containers.exp.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "graph": null, - "err": { - "ioerr": null, - "errs": [ - { - "range": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2,4:2:54-4:12:64", - "errmsg": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:5:3: width cannot be used on container: containers.circle container" - }, - { - "range": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2,14:2:173-14:12:183", - "errmsg": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:15:3: width cannot be used on container: containers.diamond container" - }, - { - "range": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2,15:2:186-15:13:197", - "errmsg": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:16:3: height cannot be used on container: containers.diamond container" - }, - { - "range": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2,24:2:284-24:12:294", - "errmsg": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:25:3: width cannot be used on container: containers.oval container" - }, - { - "range": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2,25:2:297-25:13:308", - "errmsg": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:26:3: height cannot be used on container: containers.oval container" - }, - { - "range": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2,35:2:417-35:12:427", - "errmsg": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:36:3: width cannot be used on container: containers.hexagon container" - }, - { - "range": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2,36:2:430-36:13:441", - "errmsg": "d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height cannot be used on container: containers.hexagon container" - } - ] - } -} From 3803107c6e37d1d06df47e64043046ed01f1f2c9 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sat, 18 Feb 2023 23:37:43 -0800 Subject: [PATCH 45/68] changelog --- ci/release/changelogs/next.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index acd76b3fc..e5c1ebdf4 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,11 +1,13 @@ #### Features 🚀 - Many non-Latin languages (e.g. Chinese, Japanese, Korean) are usable now that multi-byte characters are measured correctly. [#817](https://github.com/terrastruct/d2/pull/817) -- Fix duplicate success logs in watch mode. [830](https://github.com/terrastruct/d2/pull/830) +- Dimensions can be set on containers (layout engine dependent). [#845](https://github.com/terrastruct/d2/pull/845) #### Improvements 🧹 -- Cleaner watch mode logs without timestamps. [830](https://github.com/terrastruct/d2/pull/830) +- Cleaner watch mode logs without timestamps. [#830](https://github.com/terrastruct/d2/pull/830) +- Remove duplicate success logs in watch mode. [#830](https://github.com/terrastruct/d2/pull/830) +- CLI reports when a feature is incompatible with layout engine, instead of silently ignoring. [#845](https://github.com/terrastruct/d2/pull/845) #### Bugfixes ⛑️ @@ -13,4 +15,4 @@ - Fixes rare compiler bug when using underscores in edges to create objects across containers. [#824](https://github.com/terrastruct/d2/pull/824) - Fixes rare possibility of rendered connections being hidden or cut off. [#828](https://github.com/terrastruct/d2/pull/828) - Creating nested children within `sql_table` and `class` shapes are now prevented (caused confusion when accidentally done). [#834](https://github.com/terrastruct/d2/pull/834) -- Fixes graph deserialization bug. [#837](https://github.com/terrastruct/d2/pull/837) \ No newline at end of file +- Fixes graph deserialization bug. [#837](https://github.com/terrastruct/d2/pull/837) From f1ac119c09d5fc5787735877319bd41364d0e5bc Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 08:15:59 -0800 Subject: [PATCH 46/68] validate near key better --- d2compiler/compile.go | 51 ++++++++++++++----- d2compiler/compile_test.go | 23 +++++++++ .../TestCompile/near-invalid.exp.json | 16 ++++++ 3 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 testdata/d2compiler/TestCompile/near-invalid.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index df5efd7cd..af0acfd0c 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -648,21 +648,33 @@ func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) { func (c *compiler) validateNear(g *d2graph.Graph) { for _, obj := range g.Objects { if obj.Attributes.NearKey != nil { - _, isKey := g.Root.HasChild(d2graph.Key(obj.Attributes.NearKey)) + nearObj, isKey := g.Root.HasChild(d2graph.Key(obj.Attributes.NearKey)) _, isConst := d2graph.NearConstants[d2graph.Key(obj.Attributes.NearKey)[0]] - if !isKey && !isConst { - c.errorf(obj.Attributes.NearKey, "near key %#v must be the absolute path to a shape or one of the following constants: %s", d2format.Format(obj.Attributes.NearKey), strings.Join(d2graph.NearConstantsArray, ", ")) - continue - } - if !isKey && isConst && obj.Parent != g.Root { - c.errorf(obj.Attributes.NearKey, "constant near keys can only be set on root level shapes") - continue - } - if !isKey && isConst && len(obj.ChildrenArray) > 0 { - c.errorf(obj.Attributes.NearKey, "constant near keys cannot be set on shapes with children") - continue - } - if !isKey && isConst { + if isKey { + // Doesn't make sense to set near to an ancestor or descendant + nearIsAncestor := false + for curr := obj; curr != nil; curr = curr.Parent { + if curr == nearObj { + nearIsAncestor = true + break + } + } + if nearIsAncestor { + c.errorf(obj.Attributes.NearKey, "near keys cannot be set to an ancestor") + continue + } + nearIsDescendant := false + for curr := nearObj; curr != nil; curr = curr.Parent { + if curr == obj { + nearIsDescendant = true + break + } + } + if nearIsDescendant { + c.errorf(obj.Attributes.NearKey, "near keys cannot be set to an descendant") + continue + } + } else if isConst { is := false for _, e := range g.Edges { if e.Src == obj || e.Dst == obj { @@ -674,6 +686,17 @@ func (c *compiler) validateNear(g *d2graph.Graph) { c.errorf(obj.Attributes.NearKey, "constant near keys cannot be set on connected shapes") continue } + if obj.Parent != g.Root { + c.errorf(obj.Attributes.NearKey, "constant near keys can only be set on root level shapes") + continue + } + if len(obj.ChildrenArray) > 0 { + c.errorf(obj.Attributes.NearKey, "constant near keys cannot be set on shapes with children") + continue + } + } else { + c.errorf(obj.Attributes.NearKey, "near key %#v must be the absolute path to a shape or one of the following constants: %s", d2format.Format(obj.Attributes.NearKey), strings.Join(d2graph.NearConstantsArray, ", ")) + continue } } } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 537cec457..1f4df3b93 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -1398,6 +1398,29 @@ x -> y: { text: `x.near: top-center `, + }, + { + name: "near-invalid", + + text: `mongodb: MongoDB { + perspective: perspective (View) { + password + } + + explanation: |md + perspective.model.js + | { + near: mongodb + } +} + +a: { + near: a.b + b +} +`, + expErr: `d2/testdata/d2compiler/TestCompile/near-invalid.d2:9:11: near keys cannot be set to an ancestor +d2/testdata/d2compiler/TestCompile/near-invalid.d2:14:9: near keys cannot be set to an descendant`, }, { name: "near_bad_constant", diff --git a/testdata/d2compiler/TestCompile/near-invalid.exp.json b/testdata/d2compiler/TestCompile/near-invalid.exp.json new file mode 100644 index 000000000..f04575527 --- /dev/null +++ b/testdata/d2compiler/TestCompile/near-invalid.exp.json @@ -0,0 +1,16 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/near-invalid.d2,8:10:133-8:17:140", + "errmsg": "d2/testdata/d2compiler/TestCompile/near-invalid.d2:9:11: near keys cannot be set to an ancestor" + }, + { + "range": "d2/testdata/d2compiler/TestCompile/near-invalid.d2,13:8:161-13:11:164", + "errmsg": "d2/testdata/d2compiler/TestCompile/near-invalid.d2:14:9: near keys cannot be set to an descendant" + } + ] + } +} From 1a11eb00cbc2776a797207b34fecfb5d4ba4373f Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 08:22:20 -0800 Subject: [PATCH 47/68] fix d2oracle test --- d2oracle/edit_test.go | 29 ++++- .../d2oracle/TestMove/invalid-near.exp.json | 4 + testdata/d2oracle/TestMove/near.exp.json | 102 +++++++++++++++--- 3 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 testdata/d2oracle/TestMove/invalid-near.exp.json diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 489f3384b..6dd62ffec 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -2220,7 +2220,7 @@ a.b.c: { `, }, { - name: "near", + name: "invalid-near", text: `x: { near: y @@ -2234,6 +2234,33 @@ y near: x.y y } +`, + expErr: `failed to move: "y" to "x.y": failed to recompile: +x: { + near: x.y + y +} + +d2/testdata/d2oracle/TestMove/invalid-near.d2:2:9: near keys cannot be set to an descendant`, + }, + { + name: "near", + + text: `x: { + near: y +} +a +y +`, + key: `y`, + newKey: `a.y`, + + exp: `x: { + near: a.y +} +a: { + y +} `, }, { diff --git a/testdata/d2oracle/TestMove/invalid-near.exp.json b/testdata/d2oracle/TestMove/invalid-near.exp.json new file mode 100644 index 000000000..f557d2637 --- /dev/null +++ b/testdata/d2oracle/TestMove/invalid-near.exp.json @@ -0,0 +1,4 @@ +{ + "graph": null, + "err": "failed to move: \"y\" to \"x.y\": failed to recompile:\nx: {\n near: x.y\n y\n}\n\nd2/testdata/d2oracle/TestMove/invalid-near.d2:2:9: near keys cannot be set to an descendant" +} diff --git a/testdata/d2oracle/TestMove/near.exp.json b/testdata/d2oracle/TestMove/near.exp.json index 81e71d5e4..1bb25dbb0 100644 --- a/testdata/d2oracle/TestMove/near.exp.json +++ b/testdata/d2oracle/TestMove/near.exp.json @@ -2,11 +2,11 @@ "graph": { "name": "", "ast": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,0:0:0-4:0:23", + "range": "d2/testdata/d2oracle/TestMove/near.d2,0:0:0-6:0:30", "nodes": [ { "map_key": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,0:0:0-3:1:22", + "range": "d2/testdata/d2oracle/TestMove/near.d2,0:0:0-2:1:18", "key": { "range": "d2/testdata/d2oracle/TestMove/near.d2,0:0:0-0:1:1", "path": [ @@ -26,7 +26,7 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,0:3:3-3:0:21", + "range": "d2/testdata/d2oracle/TestMove/near.d2,0:3:3-2:0:17", "nodes": [ { "map_key": { @@ -53,23 +53,52 @@ "range": "d2/testdata/d2oracle/TestMove/near.d2,1:8:13-1:11:16", "value": [ { - "string": "x.y", - "raw_string": "x.y" + "string": "a.y", + "raw_string": "a.y" } ] } } } - }, + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/near.d2,3:0:19-5:1:29", + "key": { + "range": "d2/testdata/d2oracle/TestMove/near.d2,3:0:19-3:1:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/near.d2,3:0:19-3:1:20", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestMove/near.d2,3:3:22-5:0:28", + "nodes": [ { "map_key": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,2:2:19-2:3:20", + "range": "d2/testdata/d2oracle/TestMove/near.d2,4:2:26-4:3:27", "key": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,2:2:19-2:3:20", + "range": "d2/testdata/d2oracle/TestMove/near.d2,4:2:26-4:3:27", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,2:2:19-2:3:20", + "range": "d2/testdata/d2oracle/TestMove/near.d2,4:2:26-4:3:27", "value": [ { "string": "y", @@ -160,8 +189,8 @@ "range": ",0:0:0-0:1:1", "value": [ { - "string": "x", - "raw_string": "x" + "string": "a", + "raw_string": "a" } ] } @@ -191,6 +220,53 @@ }, "zIndex": 0 }, + { + "id": "a", + "id_val": "a", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/near.d2,3:0:19-3:1:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/near.d2,3:0:19-3:1:20", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, { "id": "y", "id_val": "y", @@ -201,11 +277,11 @@ "references": [ { "key": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,2:2:19-2:3:20", + "range": "d2/testdata/d2oracle/TestMove/near.d2,4:2:26-4:3:27", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2oracle/TestMove/near.d2,2:2:19-2:3:20", + "range": "d2/testdata/d2oracle/TestMove/near.d2,4:2:26-4:3:27", "value": [ { "string": "y", From 9a54b8237ffbb90afe3808b627c0a500a1af4d5a Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 08:23:24 -0800 Subject: [PATCH 48/68] changelog --- ci/release/changelogs/next.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index acd76b3fc..e07c71298 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -6,6 +6,7 @@ #### Improvements 🧹 - Cleaner watch mode logs without timestamps. [830](https://github.com/terrastruct/d2/pull/830) +- `near` key set to direct parent or ancestor throws an appropriate error message. [#851](https://github.com/terrastruct/d2/pull/851) #### Bugfixes ⛑️ @@ -13,4 +14,4 @@ - Fixes rare compiler bug when using underscores in edges to create objects across containers. [#824](https://github.com/terrastruct/d2/pull/824) - Fixes rare possibility of rendered connections being hidden or cut off. [#828](https://github.com/terrastruct/d2/pull/828) - Creating nested children within `sql_table` and `class` shapes are now prevented (caused confusion when accidentally done). [#834](https://github.com/terrastruct/d2/pull/834) -- Fixes graph deserialization bug. [#837](https://github.com/terrastruct/d2/pull/837) \ No newline at end of file +- Fixes graph deserialization bug. [#837](https://github.com/terrastruct/d2/pull/837) From 0c0e7d6134a45acd72a3052e2dc7c6b47e9acd88 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 14:08:56 -0800 Subject: [PATCH 49/68] set and replace position and dimensions --- d2oracle/edit.go | 20 +++ d2oracle/edit_test.go | 48 ++++++ .../TestSet/replace_dimensions.exp.json | 147 ++++++++++++++++++ .../d2oracle/TestSet/set_dimensions.exp.json | 147 ++++++++++++++++++ .../d2oracle/TestSet/set_position.exp.json | 147 ++++++++++++++++++ 5 files changed, 509 insertions(+) create mode 100644 testdata/d2oracle/TestSet/replace_dimensions.exp.json create mode 100644 testdata/d2oracle/TestSet/set_dimensions.exp.json create mode 100644 testdata/d2oracle/TestSet/set_position.exp.json diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 3537677b3..fb63fd419 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -234,6 +234,26 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.Shape.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } + case "width": + if attrs.Width != nil && attrs.Width.MapKey != nil { + attrs.Width.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "height": + if attrs.Height != nil && attrs.Height.MapKey != nil { + attrs.Height.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "top": + if attrs.Top != nil && attrs.Top.MapKey != nil { + attrs.Top.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "left": + if attrs.Left != nil && attrs.Left.MapKey != nil { + attrs.Left.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } case "style": if len(mk.Key.Path[reservedIndex:]) != 2 { return errors.New("malformed style setting, expected 2 part path") diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 6dd62ffec..d01f44b5e 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -695,6 +695,54 @@ square.style.opacity: 0.2 } }, }, + { + name: "set_position", + text: `square +`, + key: `square.top`, + value: go2.Pointer(`200`), + exp: `square: {top: 200} +`, + }, + { + name: "replace_position", + text: `square: { + width: 100 + top: 32 + left: 44 +} +`, + key: `square.top`, + value: go2.Pointer(`200`), + exp: `square: { + width: 100 + top: 200 + left: 44 +} +`, + }, + { + name: "set_dimensions", + text: `square +`, + key: `square.width`, + value: go2.Pointer(`200`), + exp: `square: {width: 200} +`, + }, + { + name: "replace_dimensions", + text: `square: { + width: 100 +} +`, + key: `square.width`, + value: go2.Pointer(`200`), + exp: `square: { + width: 200 +} +`, + }, { name: "label_unset", text: `square: "Always try to do things in chronological order; it's less confusing that way." diff --git a/testdata/d2oracle/TestSet/replace_dimensions.exp.json b/testdata/d2oracle/TestSet/replace_dimensions.exp.json new file mode 100644 index 000000000..cfb65d1c3 --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_dimensions.exp.json @@ -0,0 +1,147 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,0:0:0-3:0:25", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,0:0:0-2:1:24", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,0:8:8-2:0:23", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,1:2:12-1:12:22", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,1:2:12-1:7:17", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,1:2:12-1:7:17", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,1:9:19-1:12:22", + "raw": "200", + "value": "200" + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "square", + "id_val": "square", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_dimensions.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "square" + }, + "style": {}, + "width": { + "value": "200" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/set_dimensions.exp.json b/testdata/d2oracle/TestSet/set_dimensions.exp.json new file mode 100644 index 000000000..073461ca1 --- /dev/null +++ b/testdata/d2oracle/TestSet/set_dimensions.exp.json @@ -0,0 +1,147 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:0:0-1:0:21", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:0:0-0:20:20", + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:8:8-0:19:19", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:9:9-0:19:19", + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:9:9-0:14:14", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:9:9-0:14:14", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:16:16-0:19:19", + "raw": "200", + "value": "200" + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "square", + "id_val": "square", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_dimensions.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "square" + }, + "style": {}, + "width": { + "value": "200" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/set_position.exp.json b/testdata/d2oracle/TestSet/set_position.exp.json new file mode 100644 index 000000000..321da083b --- /dev/null +++ b/testdata/d2oracle/TestSet/set_position.exp.json @@ -0,0 +1,147 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:0:0-1:0:19", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:0:0-0:18:18", + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:8:8-0:17:17", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:9:9-0:17:17", + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:9:9-0:12:12", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:9:9-0:12:12", + "value": [ + { + "string": "top", + "raw_string": "top" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:14:14-0:17:17", + "raw": "200", + "value": "200" + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "square", + "id_val": "square", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_position.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "square" + }, + "style": {}, + "top": { + "value": "200" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From d31c7e37bbbd9dd82a6e636cac0dd13543bb5e00 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 14:10:10 -0800 Subject: [PATCH 50/68] changelog --- ci/release/changelogs/next.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index e07c71298..7519eeeca 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -7,6 +7,7 @@ - Cleaner watch mode logs without timestamps. [830](https://github.com/terrastruct/d2/pull/830) - `near` key set to direct parent or ancestor throws an appropriate error message. [#851](https://github.com/terrastruct/d2/pull/851) +- Dimensions and positions are able to be set from API. [#853](https://github.com/terrastruct/d2/pull/853) #### Bugfixes ⛑️ From 2951a7d8780d88ec87bcc3bed69092d8c6fecba8 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 18:52:00 -0800 Subject: [PATCH 51/68] test --- .../TestSet/replace_position.exp.json | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 testdata/d2oracle/TestSet/replace_position.exp.json diff --git a/testdata/d2oracle/TestSet/replace_position.exp.json b/testdata/d2oracle/TestSet/replace_position.exp.json new file mode 100644 index 000000000..8a0cfec54 --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_position.exp.json @@ -0,0 +1,211 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,0:0:0-5:0:47", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,0:0:0-4:1:46", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,0:8:8-4:0:45", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,1:2:12-1:12:22", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,1:2:12-1:7:17", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,1:2:12-1:7:17", + "value": [ + { + "string": "width", + "raw_string": "width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,1:9:19-1:12:22", + "raw": "100", + "value": "100" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,2:2:25-2:10:33", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,2:2:25-2:5:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,2:2:25-2:5:28", + "value": [ + { + "string": "top", + "raw_string": "top" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,2:7:30-2:10:33", + "raw": "200", + "value": "200" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,3:2:36-3:10:44", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,3:2:36-3:6:40", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,3:2:36-3:6:40", + "value": [ + { + "string": "left", + "raw_string": "left" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,3:8:42-3:10:44", + "raw": "44", + "value": "44" + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "square", + "id_val": "square", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_position.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "square" + }, + "style": {}, + "width": { + "value": "100" + }, + "top": { + "value": "200" + }, + "left": { + "value": "44" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From aa49c9c1b8474e5bbcb0baa664408a9a546135fd Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 19:38:49 -0800 Subject: [PATCH 52/68] update contributing --- docs/CONTRIBUTING.md | 78 ++++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 9c3fb421d..1ae29d85f 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,8 +1,8 @@ # Contributing +- Welcome - CI -- Flow - Logistics - Dev - Content @@ -10,12 +10,46 @@ - Documentation - Questions +## Welcome + +D2's [long-term mission](https://d2lang.com/tour/future/) is to significantly reduce the +amount of time and effort it takes to create and maintain high-quality diagrams for every +software team. We started this because we love the idea of creating diagrams with text -- +but it was clear the existing solutions were inadequete in their state and speed of +execution for this idea to be mainstream. + +We've tried our best to avoid the mistakes of the past and take inspiration from the most +successful modern programming and configuration languages. + +D2 has built up each step of the text-to-diagram pipeline from scratch, rethinking each +one from first principles, from the dead simple syntax, to the readable compiler, our own +SVG renderer, etc. + +D2 is committed to making something people want to use. That means contributions don't +only have to be in the form of pull requests. Your bug reports, plugins, examples, +discussions of new ideas, help a great deal. + +If you'd like to get involved, we're also committed to helping you merge that first +pull request. You should be able to freely pick up Issues tagged as "good first issue". If +you need help getting started, please don't hesitate to pop into Discord -- if you want to +help, I'm sure we'll find the perfect task (complexity matches your appetite and +programming experience, in an area you're interested in, etc). + ## CI Most of D2's CI is open sourced in its own -[repository](https://github.com/terrastruct/ci). You can find commands in the Github -workflows. E.g. run `./make.sh fmt` to run the formatter. Please make sure all CI is -passing for any PRs. +[repository](https://github.com/terrastruct/ci). + +`./make.sh` runs everything. Subcommands to run individual parts of the CI: + +- `./make.sh fmt` +- `./make.sh lint` +- `./make.sh test` +- `./make.sh race` +- `./make.sh build` + + +Please make sure CI is passing for any PRs submitted for review. Most of the CI scripts rely on a submodule shared between many D2 repositories: [https://github.com/terrastruct/ci](https://github.com/terrastruct/ci). You should fetch @@ -31,21 +65,14 @@ If running for the first time for a repo (e.g. new clone), add `--init`: git submodule update --init --recursive ``` -## Flow - -The simplified D2 flow at a package level looks like: - -D2 flow - ## Logistics - Use Go 1.18. Go 1.19's autofmt inexplicably strips spacing from ASCII art in comments. + We're working on it. - Please sign your commits ([https://github.com/terrastruct/d2/pull/557#issuecomment-1367468730](https://github.com/terrastruct/d2/pull/557#issuecomment-1367468730)). - D2 uses Issues as TODOs. No auto-closing on staleness. - Branch off `master`. -- Prefix pull request titles with a short descriptor of the domain, e.g. `d2renderer: Add - x`. - If there's an Issue related, include it by adding "[one-word] #[issue]", e.g. "Fixes #123" somewhere in the description. - Whenever possible and relevant, include a screenshot or screen-recording. @@ -54,25 +81,34 @@ The simplified D2 flow at a package level looks like: ### Content -Please choose an Issue with a "TODO" label. If you'd like to propose new functionality or -change to current functionality, please create an Issue first with a proposal. When you -start work on an Issue, please leave a comment so others know that it's being worked on. +Unless you've contributed before, it's safest to choose an Issue with a "good first issue" +label. If you'd like to propose new functionality or change to current functionality, +please create an Issue first with a proposal. When you start work on an Issue, please +leave a comment so others know that it's being worked on. ### Tests -All code changes must include tests. D2 mostly has functional tests, and uses -[diff](https://github.com/terrastruct/diff) as a framework that gives Git-style -comparisons of expected vs actual output for each stage. There are ample examples in each -package of this -- try changing some test and run it to see. +D2 has extensive tests, and all code changes must include tests. With the exception of changes to the renderer, all code should include a package-specific -test. If it's a visual change, an e2e test should accompany. +test. If it's a visual change, an end-to-end (e2e) test should accompany. + +Let's say I make some code changes. I can easily see how this affects the end result by +running: + +``` +./ci/e2ereport.sh -delta +``` + +This gives me a nice HMTL output of what the test expected vs what it got: + +![screencapture-file-Users-alexanderwang-dev-alixander-d2-e2etests-out-e2e-report-html-2023-02-14-10_15_07](https://user-images.githubusercontent.com/3120367/218822836-bcc517f2-ae3e-4e0d-83f6-2cbaa2fd9275.png) If you're testing labels and strings, it's encouraged to use 1-letter strings (`x`) in small functional tests to minimally pinpoint issues. If you are testing something that exercises variations in strings, or want to mimic more realistic diagram text, it's encouraged you generate random strings and words from `fortune`. It gives a good range of the English -language. Sometimes it gives controversial sentences -- don't use those. +language. (Sometimes it gives controversial sentences -- don't use those.) Script to generate one line of random text: ``` From 95cf986928560dde98454af6fecad4983ef80669 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 19:45:21 -0800 Subject: [PATCH 53/68] update --- docs/CONTRIBUTING.md | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 1ae29d85f..20f84d078 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -16,29 +16,32 @@ D2's [long-term mission](https://d2lang.com/tour/future/) is to significantly re amount of time and effort it takes to create and maintain high-quality diagrams for every software team. We started this because we love the idea of creating diagrams with text -- but it was clear the existing solutions were inadequete in their state and speed of -execution for this idea to be mainstream. +execution for this idea to be widely usable. We've tried our best to avoid the mistakes of the past and take inspiration from the most -successful modern programming and configuration languages. - -D2 has built up each step of the text-to-diagram pipeline from scratch, rethinking each -one from first principles, from the dead simple syntax, to the readable compiler, our own -SVG renderer, etc. +successful modern programming and configuration languages. D2 has built up each step of +the text-to-diagram pipeline from scratch, rethinking each one from first principles, from +the dead simple syntax, to the readable compiler, our own SVG renderer, etc. D2 is committed to making something people want to use. That means contributions don't only have to be in the form of pull requests. Your bug reports, plugins, examples, discussions of new ideas, help a great deal. -If you'd like to get involved, we're also committed to helping you merge that first -pull request. You should be able to freely pick up Issues tagged as "good first issue". If -you need help getting started, please don't hesitate to pop into Discord -- if you want to -help, I'm sure we'll find the perfect task (complexity matches your appetite and +If you'd like to get involved, we're also committed to helping you merge that first pull +request. You should be able to freely pick up Issues tagged as "good first issue". If you +need help getting started, please don't hesitate to pop into Discord -- as long as you +want to help, we'll find the perfect task (complexity matches your appetite and programming experience, in an area you're interested in, etc). ## CI Most of D2's CI is open sourced in its own -[repository](https://github.com/terrastruct/ci). +[repository](https://github.com/terrastruct/ci), included as a submodule. After you clone +D2, make sure you initialize the submodules: + +```sh +git submodule update --init --recursive +``` `./make.sh` runs everything. Subcommands to run individual parts of the CI: @@ -51,20 +54,12 @@ Most of D2's CI is open sourced in its own Please make sure CI is passing for any PRs submitted for review. -Most of the CI scripts rely on a submodule shared between many D2 repositories: -[https://github.com/terrastruct/ci](https://github.com/terrastruct/ci). You should fetch -the submodule whenever it differs: +Be sure to update the submodule whenever there are changes: ```sh git submodule update --recursive ``` -If running for the first time for a repo (e.g. new clone), add `--init`: - -```sh -git submodule update --init --recursive -``` - ## Logistics - Use Go 1.18. Go 1.19's autofmt inexplicably strips spacing from ASCII art in comments. @@ -100,7 +95,8 @@ running: ./ci/e2ereport.sh -delta ``` -This gives me a nice HMTL output of what the test expected vs what it got: +This gives me a nice HMTL output of what the test expected vs what it got (this was a PR +fixing multi-byte character labels): ![screencapture-file-Users-alexanderwang-dev-alixander-d2-e2etests-out-e2e-report-html-2023-02-14-10_15_07](https://user-images.githubusercontent.com/3120367/218822836-bcc517f2-ae3e-4e0d-83f6-2cbaa2fd9275.png) From eac0c5361027a38ccabae0ad97203500361083d2 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 19:48:16 -0800 Subject: [PATCH 54/68] Update CONTRIBUTING.md --- docs/CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 20f84d078..8f2cc1917 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -51,6 +51,10 @@ git submodule update --init --recursive - `./make.sh race` - `./make.sh build` +Here's what a successful run should look like: + +Screen Shot 2023-02-19 at 7 46 34 PM + Please make sure CI is passing for any PRs submitted for review. From b40eb5a4d86497dc151085e16715e55cfe9a13db Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 21:33:37 -0800 Subject: [PATCH 55/68] d2oracle: delete dimensions and positions --- d2oracle/edit.go | 4 + d2oracle/edit_test.go | 24 +++++ testdata/d2oracle/TestDelete/left.exp.json | 109 ++++++++++++++++++++ testdata/d2oracle/TestDelete/width.exp.json | 109 ++++++++++++++++++++ 4 files changed, 246 insertions(+) create mode 100644 testdata/d2oracle/TestDelete/left.exp.json create mode 100644 testdata/d2oracle/TestDelete/width.exp.json diff --git a/d2oracle/edit.go b/d2oracle/edit.go index fb63fd419..8813755bf 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -687,6 +687,10 @@ func deleteReserved(g *d2graph.Graph, mk *d2ast.Key) (*d2graph.Graph, error) { if id == "near" || id == "tooltip" || id == "icon" || + id == "width" || + id == "height" || + id == "left" || + id == "top" || id == "link" { err := deleteObjField(g, obj, id) if err != nil { diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index d01f44b5e..f6dc0cf3a 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -4507,6 +4507,30 @@ A -> B: {style.stroke: "#2b50c2"} exp: `A: {style.stroke: "#000e3d"} B A -> B +`, + }, + { + name: "width", + + text: `x: { + width: 200 +} +`, + key: `x.width`, + + exp: `x +`, + }, + { + name: "left", + + text: `x: { + left: 200 +} +`, + key: `x.left`, + + exp: `x `, }, } diff --git a/testdata/d2oracle/TestDelete/left.exp.json b/testdata/d2oracle/TestDelete/left.exp.json new file mode 100644 index 000000000..0be52a3ad --- /dev/null +++ b/testdata/d2oracle/TestDelete/left.exp.json @@ -0,0 +1,109 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestDelete/left.d2,0:0:0-1:0:2", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/left.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2oracle/TestDelete/left.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/left.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/left.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/left.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestDelete/width.exp.json b/testdata/d2oracle/TestDelete/width.exp.json new file mode 100644 index 000000000..c1c010bcb --- /dev/null +++ b/testdata/d2oracle/TestDelete/width.exp.json @@ -0,0 +1,109 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestDelete/width.d2,0:0:0-1:0:2", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/width.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2oracle/TestDelete/width.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/width.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/width.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/width.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From 16679e8d6950d5ce6c79de1b665b2284167bf4f4 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 19 Feb 2023 22:24:10 -0800 Subject: [PATCH 56/68] [ci-base] update contributing --- docs/CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 8f2cc1917..c074c4235 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -104,6 +104,8 @@ fixing multi-byte character labels): ![screencapture-file-Users-alexanderwang-dev-alixander-d2-e2etests-out-e2e-report-html-2023-02-14-10_15_07](https://user-images.githubusercontent.com/3120367/218822836-bcc517f2-ae3e-4e0d-83f6-2cbaa2fd9275.png) +Run `./ci/e2ereport.sh -help` for flags, including how to get deltas for a single test. + If you're testing labels and strings, it's encouraged to use 1-letter strings (`x`) in small functional tests to minimally pinpoint issues. If you are testing something that exercises variations in strings, or want to mimic more realistic diagram text, it's encouraged you From c174efb9c464ddddb4d58c5a06b05c3347cc0532 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 09:05:00 -0800 Subject: [PATCH 57/68] change to array --- d2plugin/plugin.go | 2 +- d2plugin/plugin_dagre.go | 1 - d2plugin/plugin_elk.go | 4 ++-- d2plugin/plugin_features.go | 11 ++++++++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index 456c3cbad..56002678d 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -78,7 +78,7 @@ type PluginInfo struct { // If Type == binary then this contains the absolute path to the binary. Path string `json:"path"` - Features map[PluginFeature]struct{} `json:"features"` + Features []PluginFeature `json:"features"` } const binaryPrefix = "d2plugin-" diff --git a/d2plugin/plugin_dagre.go b/d2plugin/plugin_dagre.go index 478aca5bf..6c0237060 100644 --- a/d2plugin/plugin_dagre.go +++ b/d2plugin/plugin_dagre.go @@ -67,7 +67,6 @@ func (p dagrePlugin) Info(ctx context.Context) (*PluginInfo, error) { return &PluginInfo{ Name: "dagre", Type: "bundled", - Features: make(map[PluginFeature]struct{}), ShortHelp: "The directed graph layout library Dagre", LongHelp: fmt.Sprintf(`dagre is a directed graph layout library for JavaScript. See https://d2lang.com/tour/dagre for more. diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index f67af65ab..3b2113c6d 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -87,8 +87,8 @@ func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) { return &PluginInfo{ Name: "elk", Type: "bundled", - Features: map[PluginFeature]struct{}{ - CONTAINER_DIMENSIONS: {}, + Features: []PluginFeature{ + CONTAINER_DIMENSIONS, }, ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.", LongHelp: fmt.Sprintf(`ELK is a layout engine offered by Eclipse. diff --git a/d2plugin/plugin_features.go b/d2plugin/plugin_features.go index 5ea4518b0..f41462b37 100644 --- a/d2plugin/plugin_features.go +++ b/d2plugin/plugin_features.go @@ -24,14 +24,19 @@ func FeatureSupportCheck(info *PluginInfo, g *d2graph.Graph) error { return nil } + featureMap := make(map[PluginFeature]struct{}, len(info.Features)) + for _, f := range info.Features { + featureMap[f] = struct{}{} + } + for _, obj := range g.Objects { if obj.Attributes.Top != nil || obj.Attributes.Left != nil { - if _, ok := info.Features[TOP_LEFT]; !ok { + if _, ok := featureMap[TOP_LEFT]; !ok { return fmt.Errorf(`Object "%s" has attribute "top" and/or "left" set, but layout engine "%s" does not support locked positions.`, obj.AbsID(), info.Name) } } if (obj.Attributes.Width != nil || obj.Attributes.Height != nil) && len(obj.ChildrenArray) > 0 { - if _, ok := info.Features[CONTAINER_DIMENSIONS]; !ok { + if _, ok := featureMap[CONTAINER_DIMENSIONS]; !ok { return fmt.Errorf(`Object "%s" has attribute "width" and/or "height" set, but layout engine "%s" does not support dimensions set on containers.`, obj.AbsID(), info.Name) } } @@ -39,7 +44,7 @@ func FeatureSupportCheck(info *PluginInfo, g *d2graph.Graph) error { if obj.Attributes.NearKey != nil { _, isKey := g.Root.HasChild(d2graph.Key(obj.Attributes.NearKey)) if isKey { - if _, ok := info.Features[NEAR_OBJECT]; !ok { + if _, ok := featureMap[NEAR_OBJECT]; !ok { return fmt.Errorf(`Object "%s" has "near" set to another object, but layout engine "%s" only supports constant values for "near".`, obj.AbsID(), info.Name) } } From 95eccae9c1a4a59037b930332d93962235541c7f Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 09:21:48 -0800 Subject: [PATCH 58/68] [ci-base] fix last PR --- d2plugin/plugin_dagre.go | 1 + 1 file changed, 1 insertion(+) diff --git a/d2plugin/plugin_dagre.go b/d2plugin/plugin_dagre.go index 6c0237060..815c64910 100644 --- a/d2plugin/plugin_dagre.go +++ b/d2plugin/plugin_dagre.go @@ -67,6 +67,7 @@ func (p dagrePlugin) Info(ctx context.Context) (*PluginInfo, error) { return &PluginInfo{ Name: "dagre", Type: "bundled", + Features: []PluginFeature{}, ShortHelp: "The directed graph layout library Dagre", LongHelp: fmt.Sprintf(`dagre is a directed graph layout library for JavaScript. See https://d2lang.com/tour/dagre for more. From b1a1b2300c98b58301e0a15131bd78cd9b3b305c Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 09:39:32 -0800 Subject: [PATCH 59/68] delete id deltas reserved --- d2oracle/edit.go | 6 ++++++ d2oracle/edit_test.go | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 8813755bf..7bdb555f5 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -1864,6 +1864,12 @@ func DeleteIDDeltas(g *d2graph.Graph, key string) (deltas map[string]string, err conflictNewIDs := make(map[*d2graph.Object]string) conflictOldIDs := make(map[*d2graph.Object]string) if mk.Key != nil { + ida := d2graph.Key(mk.Key) + // Deleting a reserved field cannot possibly have any deltas + if _, ok := d2graph.ReservedKeywords[ida[len(ida)-1]]; ok { + return nil, nil + } + var ok bool obj, ok = g.Root.HasChild(d2graph.Key(mk.Key)) if !ok { diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index f6dc0cf3a..e51893812 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -4895,7 +4895,18 @@ x.y.z.w.e.p.l -> x.y.z.1.2.3.4 "x.x": "x" }`, }, + { + name: "nested-height", + text: `x: { + a -> b + height: 200 +} +`, + key: `x.height`, + + exp: `null`, + }, { name: "only-reserved", text: `guitar: { From 40f757f4d46613d0a5db93eeafd18aa0aa40ba5e Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 09:44:43 -0800 Subject: [PATCH 60/68] add test for edge key too --- d2oracle/edit_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index e51893812..e58fbd1cc 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -4907,6 +4907,18 @@ x.y.z.w.e.p.l -> x.y.z.1.2.3.4 exp: `null`, }, + { + name: "edge-style", + + text: `x <-> y: { + target-arrowhead: circle + source-arrowhead: diamond +} +`, + key: `(x <-> y)[0].target-arrowhead`, + + exp: `null`, + }, { name: "only-reserved", text: `guitar: { From aff6723d38fa22a0092eb70d6b01fdfd71cad3c2 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 14:15:47 -0800 Subject: [PATCH 61/68] replace link and tooltip --- d2compiler/compile.go | 8 +- d2graph/d2graph.go | 8 +- d2oracle/edit.go | 29 +- d2oracle/edit_test.go | 94 +++++ .../d2oracle/TestDelete/arrowhead.exp.json | 214 +++++++++++ .../TestDelete/arrowhead_shape.exp.json | 214 +++++++++++ .../d2oracle/TestDelete/delete_icon.exp.json | 4 +- .../TestDelete/edge-only-style.exp.json | 214 +++++++++++ .../TestSet/edge_replace_arrowhead.exp.json | 280 ++++++++++++++ .../edge_replace_arrowhead_indexed.exp.json | 361 ++++++++++++++++++ .../TestSet/edge_replace_style.exp.json | 280 ++++++++++++++ .../TestSet/edge_set_arrowhead.exp.json | 280 ++++++++++++++ .../d2oracle/TestSet/replace_link.exp.json | 151 ++++++++ .../d2oracle/TestSet/replace_tooltip.exp.json | 151 ++++++++ 14 files changed, 2280 insertions(+), 8 deletions(-) create mode 100644 testdata/d2oracle/TestDelete/arrowhead.exp.json create mode 100644 testdata/d2oracle/TestDelete/arrowhead_shape.exp.json create mode 100644 testdata/d2oracle/TestDelete/edge-only-style.exp.json create mode 100644 testdata/d2oracle/TestSet/edge_replace_arrowhead.exp.json create mode 100644 testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.exp.json create mode 100644 testdata/d2oracle/TestSet/edge_replace_style.exp.json create mode 100644 testdata/d2oracle/TestSet/edge_set_arrowhead.exp.json create mode 100644 testdata/d2oracle/TestSet/replace_link.exp.json create mode 100644 testdata/d2oracle/TestSet/replace_tooltip.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index b2df640da..2a2e3becd 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -266,7 +266,9 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { nearKey.Range = scalar.GetRange() attrs.NearKey = nearKey case "tooltip": - attrs.Tooltip = scalar.ScalarString() + attrs.Tooltip = &d2graph.Scalar{} + attrs.Tooltip.Value = scalar.ScalarString() + attrs.Tooltip.MapKey = f.LastPrimaryKey() case "width": _, err := strconv.Atoi(scalar.ScalarString()) if err != nil { @@ -304,7 +306,9 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { attrs.Left.Value = scalar.ScalarString() attrs.Left.MapKey = f.LastPrimaryKey() case "link": - attrs.Link = scalar.ScalarString() + attrs.Link = &d2graph.Scalar{} + attrs.Link.Value = scalar.ScalarString() + attrs.Link.MapKey = f.LastPrimaryKey() case "direction": dirs := []string{"up", "down", "right", "left"} if !go2.Contains(dirs, scalar.ScalarString()) { diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 30bdedcbf..385a6b2ed 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -95,8 +95,8 @@ type Attributes struct { Label Scalar `json:"label"` Style Style `json:"style"` Icon *url.URL `json:"icon,omitempty"` - Tooltip string `json:"tooltip,omitempty"` - Link string `json:"link,omitempty"` + Tooltip *Scalar `json:"tooltip,omitempty"` + Link *Scalar `json:"link,omitempty"` Width *Scalar `json:"width,omitempty"` Height *Scalar `json:"height,omitempty"` @@ -1313,10 +1313,10 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler switch shapeType { case shape.TABLE_TYPE, shape.CLASS_TYPE, shape.CODE_TYPE, shape.IMAGE_TYPE: default: - if obj.Attributes.Link != "" { + if obj.Attributes.Link != nil { paddingX += 32 } - if obj.Attributes.Tooltip != "" { + if obj.Attributes.Tooltip != nil { paddingX += 32 } } diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 8813755bf..669443541 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -37,6 +37,7 @@ func Create(g *d2graph.Graph, key string) (_ *d2graph.Graph, newKey string, err if err != nil { return nil, "", err } + g, err = recompile(g) if err != nil { return nil, "", err @@ -195,6 +196,20 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { reserved = true toSkip = 1 + if len(mk.EdgeKey.Path) > 1 { + switch mk.EdgeKey.Path[len(mk.EdgeKey.Path)-2].Unbox().ScalarString() { + case "source-arrowhead": + if edge.SrcArrowhead != nil { + toSkip++ + attrs = edge.SrcArrowhead + } + case "target-arrowhead": + if edge.DstArrowhead != nil { + toSkip++ + attrs = edge.DstArrowhead + } + } + } mk = &d2ast.Key{ Key: cloneKey(mk.EdgeKey), Value: mk.Value, @@ -234,6 +249,16 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.Shape.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } + case "link": + if attrs.Link.MapKey != nil { + attrs.Link.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "tooltip": + if attrs.Tooltip.MapKey != nil { + attrs.Tooltip.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } case "width": if attrs.Width != nil && attrs.Width.MapKey != nil { attrs.Width.MapKey.SetScalar(mk.Value.ScalarBox()) @@ -714,7 +739,9 @@ func deleteMapField(m *d2ast.Map, field string) { if n.MapKey != nil && n.MapKey.Key != nil { if n.MapKey.Key.Path[0].Unbox().ScalarString() == field { deleteFromMap(m, n.MapKey) - } else if n.MapKey.Key.Path[0].Unbox().ScalarString() == "style" { + } else if n.MapKey.Key.Path[0].Unbox().ScalarString() == "style" || + n.MapKey.Key.Path[0].Unbox().ScalarString() == "source-arrowhead" || + n.MapKey.Key.Path[0].Unbox().ScalarString() == "target-arrowhead" { if n.MapKey.Value.Map != nil { deleteMapField(n.MapKey.Value.Map, field) if len(n.MapKey.Value.Map.Nodes) == 0 { diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index f6dc0cf3a..c5116b925 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -741,6 +741,32 @@ square.style.opacity: 0.2 exp: `square: { width: 200 } +`, + }, + { + name: "replace_tooltip", + text: `square: { + tooltip: x +} +`, + key: `square.tooltip`, + value: go2.Pointer(`y`), + exp: `square: { + tooltip: y +} +`, + }, + { + name: "replace_link", + text: `square: { + link: https://google.com +} +`, + key: `square.link`, + value: go2.Pointer(`https://apple.com`), + exp: `square: { + link: https://apple.com +} `, }, { @@ -1072,6 +1098,38 @@ a.b -> a.c: {style.animated: true} value: go2.Pointer(`true`), exp: `x -> y: {style.animated: true} +`, + }, + { + name: "edge_set_arrowhead", + text: `x -> y +`, + key: `(x -> y)[0].target-arrowhead.shape`, + value: go2.Pointer(`diamond`), + + exp: `x -> y: {target-arrowhead.shape: diamond} +`, + }, + { + name: "edge_replace_arrowhead", + text: `x -> y: {target-arrowhead.shape: circle} +`, + key: `(x -> y)[0].target-arrowhead.shape`, + value: go2.Pointer(`diamond`), + + exp: `x -> y: {target-arrowhead.shape: diamond} +`, + }, + { + name: "edge_replace_arrowhead_indexed", + text: `x -> y +(x -> y)[0].target-arrowhead.shape: circle +`, + key: `(x -> y)[0].target-arrowhead.shape`, + value: go2.Pointer(`diamond`), + + exp: `x -> y +(x -> y)[0].target-arrowhead.shape: diamond `, }, { @@ -3459,6 +3517,42 @@ x key: `x`, exp: `y +`, + }, + { + name: "arrowhead", + + text: `x -> y: { + target-arrowhead.shape: diamond +} +`, + key: `(x -> y)[0].target-arrowhead`, + + exp: `x -> y +`, + }, + { + name: "arrowhead_shape", + + text: `x -> y: { + target-arrowhead.shape: diamond +} +`, + key: `(x -> y)[0].target-arrowhead.shape`, + + exp: `x -> y +`, + }, + { + name: "edge-only-style", + + text: `x -> y: { + style.stroke: red +} +`, + key: `(x -> y)[0].style.stroke`, + + exp: `x -> y `, }, { diff --git a/testdata/d2oracle/TestDelete/arrowhead.exp.json b/testdata/d2oracle/TestDelete/arrowhead.exp.json new file mode 100644 index 000000000..eb4cd6ebb --- /dev/null +++ b/testdata/d2oracle/TestDelete/arrowhead.exp.json @@ -0,0 +1,214 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:0:0-1:0:7", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:0:0-0:6:6", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestDelete/arrowhead_shape.exp.json b/testdata/d2oracle/TestDelete/arrowhead_shape.exp.json new file mode 100644 index 000000000..6ad6f3824 --- /dev/null +++ b/testdata/d2oracle/TestDelete/arrowhead_shape.exp.json @@ -0,0 +1,214 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:0:0-1:0:7", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:0:0-0:6:6", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_shape.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestDelete/delete_icon.exp.json b/testdata/d2oracle/TestDelete/delete_icon.exp.json index 374b88cb2..66fcdfb72 100644 --- a/testdata/d2oracle/TestDelete/delete_icon.exp.json +++ b/testdata/d2oracle/TestDelete/delete_icon.exp.json @@ -209,7 +209,9 @@ "value": "x" }, "style": {}, - "link": "https://google.com", + "link": { + "value": "https://google.com" + }, "near_key": null, "shape": { "value": "rectangle" diff --git a/testdata/d2oracle/TestDelete/edge-only-style.exp.json b/testdata/d2oracle/TestDelete/edge-only-style.exp.json new file mode 100644 index 000000000..50846ea3b --- /dev/null +++ b/testdata/d2oracle/TestDelete/edge-only-style.exp.json @@ -0,0 +1,214 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:0:0-1:0:7", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:0:0-0:6:6", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/edge-only-style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/edge_replace_arrowhead.exp.json b/testdata/d2oracle/TestSet/edge_replace_arrowhead.exp.json new file mode 100644 index 000000000..2099babb4 --- /dev/null +++ b/testdata/d2oracle/TestSet/edge_replace_arrowhead.exp.json @@ -0,0 +1,280 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:0:0-1:0:42", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:0:0-0:41:41", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:8:8-0:40:40", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:9:9-0:40:40", + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:9:9-0:31:31", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:9:9-0:25:25", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:26:26-0:31:31", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:33:33-0:40:40", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.exp.json b/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.exp.json new file mode 100644 index 000000000..17bc34333 --- /dev/null +++ b/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.exp.json @@ -0,0 +1,361 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:0:0-2:0:51", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:0:0-0:6:6", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:0:7-1:43:50", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:1:8-1:7:14", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:1:8-1:3:10", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:1:8-1:2:9", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:5:12-1:7:14", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:6:13-1:7:14", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:8:15-1:11:18", + "int": 0, + "glob": false + }, + "edge_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:12:19-1:34:41", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:12:19-1:28:35", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:29:36-1:34:41", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:36:43-1:43:50", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:1:8-1:3:10", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:1:8-1:2:9", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:5:12-1:7:14", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_arrowhead_indexed.d2,1:6:13-1:7:14", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/edge_replace_style.exp.json b/testdata/d2oracle/TestSet/edge_replace_style.exp.json new file mode 100644 index 000000000..f15dc4109 --- /dev/null +++ b/testdata/d2oracle/TestSet/edge_replace_style.exp.json @@ -0,0 +1,280 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:0:0-1:0:42", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:0:0-0:41:41", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:8:8-0:40:40", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:9:9-0:40:40", + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:9:9-0:31:31", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:9:9-0:25:25", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:26:26-0:31:31", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:33:33-0:40:40", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_replace_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/edge_set_arrowhead.exp.json b/testdata/d2oracle/TestSet/edge_set_arrowhead.exp.json new file mode 100644 index 000000000..0c3855cc9 --- /dev/null +++ b/testdata/d2oracle/TestSet/edge_set_arrowhead.exp.json @@ -0,0 +1,280 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:0:0-1:0:42", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:0:0-0:41:41", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:8:8-0:40:40", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:9:9-0:40:40", + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:9:9-0:31:31", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:9:9-0:25:25", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:26:26-0:31:31", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:33:33-0:40:40", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_set_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/replace_link.exp.json b/testdata/d2oracle/TestSet/replace_link.exp.json new file mode 100644 index 000000000..a6ad42efe --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_link.exp.json @@ -0,0 +1,151 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,0:0:0-3:0:38", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,0:0:0-2:1:37", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,0:8:8-2:0:36", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,1:2:12-1:25:35", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,1:2:12-1:6:16", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,1:2:12-1:6:16", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,1:8:18-1:25:35", + "value": [ + { + "string": "https://apple.com", + "raw_string": "https://apple.com" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "square", + "id_val": "square", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_link.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "square" + }, + "style": {}, + "link": { + "value": "https://apple.com" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/replace_tooltip.exp.json b/testdata/d2oracle/TestSet/replace_tooltip.exp.json new file mode 100644 index 000000000..7aab2f7e2 --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_tooltip.exp.json @@ -0,0 +1,151 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,0:0:0-3:0:25", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,0:0:0-2:1:24", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,0:8:8-2:0:23", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,1:2:12-1:12:22", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,1:2:12-1:9:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,1:2:12-1:9:19", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,1:11:21-1:12:22", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "square", + "id_val": "square", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_tooltip.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "square" + }, + "style": {}, + "tooltip": { + "value": "y" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From f7a5689280e3a5f8ef3b631f7110fb70669006de Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 14:18:55 -0800 Subject: [PATCH 62/68] fix --- d2compiler/compile_test.go | 8 ++++---- d2exporter/export.go | 12 +++++++++--- testdata/d2compiler/TestCompile/path_link.exp.json | 4 +++- testdata/d2compiler/TestCompile/url_link.exp.json | 4 +++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 4623190b4..85a27d860 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -1364,8 +1364,8 @@ x -> y: { if len(g.Objects) != 1 { t.Fatal(g.Objects) } - if g.Objects[0].Attributes.Link != "https://google.com" { - t.Fatal(g.Objects[0].Attributes.Link) + if g.Objects[0].Attributes.Link.Value != "https://google.com" { + t.Fatal(g.Objects[0].Attributes.Link.Value) } }, }, @@ -1380,8 +1380,8 @@ x -> y: { if len(g.Objects) != 1 { t.Fatal(g.Objects) } - if g.Objects[0].Attributes.Link != "Overview.Untitled board 7.zzzzz" { - t.Fatal(g.Objects[0].Attributes.Link) + if g.Objects[0].Attributes.Link.Value != "Overview.Untitled board 7.zzzzz" { + t.Fatal(g.Objects[0].Attributes.Link.Value) } }, }, diff --git a/d2exporter/export.go b/d2exporter/export.go index 0237d554a..1dcf55179 100644 --- a/d2exporter/export.go +++ b/d2exporter/export.go @@ -152,8 +152,12 @@ func toShape(obj *d2graph.Object, theme *d2themes.Theme) d2target.Shape { } } - shape.Tooltip = obj.Attributes.Tooltip - shape.Link = obj.Attributes.Link + if obj.Attributes.Tooltip != nil { + shape.Tooltip = obj.Attributes.Tooltip.Value + } + if obj.Attributes.Link != nil { + shape.Link = obj.Attributes.Link.Value + } shape.Icon = obj.Attributes.Icon if obj.IconPosition != nil { shape.IconPosition = *obj.IconPosition @@ -232,7 +236,9 @@ func toConnection(edge *d2graph.Edge, theme *d2themes.Theme) d2target.Connection connection.Animated, _ = strconv.ParseBool(edge.Attributes.Style.Animated.Value) } - connection.Tooltip = edge.Attributes.Tooltip + if edge.Attributes.Tooltip != nil { + connection.Tooltip = edge.Attributes.Tooltip.Value + } connection.Icon = edge.Attributes.Icon if edge.Attributes.Style.Italic != nil { diff --git a/testdata/d2compiler/TestCompile/path_link.exp.json b/testdata/d2compiler/TestCompile/path_link.exp.json index 9a1cb6fc3..7c96d68c6 100644 --- a/testdata/d2compiler/TestCompile/path_link.exp.json +++ b/testdata/d2compiler/TestCompile/path_link.exp.json @@ -129,7 +129,9 @@ "value": "x" }, "style": {}, - "link": "Overview.Untitled board 7.zzzzz", + "link": { + "value": "Overview.Untitled board 7.zzzzz" + }, "near_key": null, "shape": { "value": "rectangle" diff --git a/testdata/d2compiler/TestCompile/url_link.exp.json b/testdata/d2compiler/TestCompile/url_link.exp.json index b0ebf8a9d..eca980a30 100644 --- a/testdata/d2compiler/TestCompile/url_link.exp.json +++ b/testdata/d2compiler/TestCompile/url_link.exp.json @@ -129,7 +129,9 @@ "value": "x" }, "style": {}, - "link": "https://google.com", + "link": { + "value": "https://google.com" + }, "near_key": null, "shape": { "value": "rectangle" From dab8215f9efc2bba00cecb605aac1693381fe4b7 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 14:21:51 -0800 Subject: [PATCH 63/68] more tests --- d2oracle/edit.go | 1 - d2oracle/edit_test.go | 29 ++ .../TestDelete/arrowhead_label.exp.json | 280 ++++++++++++++++++ .../TestDelete/arrowhead_map.exp.json | 214 +++++++++++++ 4 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 testdata/d2oracle/TestDelete/arrowhead_label.exp.json create mode 100644 testdata/d2oracle/TestDelete/arrowhead_map.exp.json diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 669443541..1df240a70 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -37,7 +37,6 @@ func Create(g *d2graph.Graph, key string) (_ *d2graph.Graph, newKey string, err if err != nil { return nil, "", err } - g, err = recompile(g) if err != nil { return nil, "", err diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index c5116b925..2ab778cc0 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -3542,6 +3542,35 @@ x exp: `x -> y `, + }, + { + name: "arrowhead_label", + + text: `x -> y: { + target-arrowhead.shape: diamond + target-arrowhead.label: 1 +} +`, + key: `(x -> y)[0].target-arrowhead.label`, + + exp: `x -> y: { + target-arrowhead.shape: diamond +} +`, + }, + { + name: "arrowhead_map", + + text: `x -> y: { + target-arrowhead: { + shape: diamond + } +} +`, + key: `(x -> y)[0].target-arrowhead.shape`, + + exp: `x -> y +`, }, { name: "edge-only-style", diff --git a/testdata/d2oracle/TestDelete/arrowhead_label.exp.json b/testdata/d2oracle/TestDelete/arrowhead_label.exp.json new file mode 100644 index 000000000..30ff73b25 --- /dev/null +++ b/testdata/d2oracle/TestDelete/arrowhead_label.exp.json @@ -0,0 +1,280 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:0:0-3:0:46", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:0:0-2:1:45", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:8:8-2:0:44", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,1:2:12-1:33:43", + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,1:2:12-1:24:34", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,1:2:12-1:18:28", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,1:19:29-1:24:34", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,1:26:36-1:33:43", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_label.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestDelete/arrowhead_map.exp.json b/testdata/d2oracle/TestDelete/arrowhead_map.exp.json new file mode 100644 index 000000000..9fab0d94b --- /dev/null +++ b/testdata/d2oracle/TestDelete/arrowhead_map.exp.json @@ -0,0 +1,214 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:0:0-1:0:7", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:0:0-0:6:6", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestDelete/arrowhead_map.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From d082d97469b7898529016ace5b64f6937a104895 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 14:31:26 -0800 Subject: [PATCH 64/68] [ci-base] fix last pr --- d2oracle/edit.go | 4 +- d2oracle/edit_test.go | 9 ++ .../d2oracle/TestSet/set_tooltip.exp.json | 151 ++++++++++++++++++ 3 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 testdata/d2oracle/TestSet/set_tooltip.exp.json diff --git a/d2oracle/edit.go b/d2oracle/edit.go index ec27b63a2..76f34c240 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -249,12 +249,12 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { return nil } case "link": - if attrs.Link.MapKey != nil { + if attrs.Link != nil && attrs.Link.MapKey != nil { attrs.Link.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } case "tooltip": - if attrs.Tooltip.MapKey != nil { + if attrs.Tooltip != nil && attrs.Tooltip.MapKey != nil { attrs.Tooltip.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 4da115a8e..965ce4826 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -741,6 +741,15 @@ square.style.opacity: 0.2 exp: `square: { width: 200 } +`, + }, + { + name: "set_tooltip", + text: `square +`, + key: `square.tooltip`, + value: go2.Pointer(`y`), + exp: `square: {tooltip: y} `, }, { diff --git a/testdata/d2oracle/TestSet/set_tooltip.exp.json b/testdata/d2oracle/TestSet/set_tooltip.exp.json new file mode 100644 index 000000000..15cd02ebd --- /dev/null +++ b/testdata/d2oracle/TestSet/set_tooltip.exp.json @@ -0,0 +1,151 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:0:0-1:0:21", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:0:0-0:20:20", + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:8:8-0:19:19", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:9:9-0:19:19", + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:9:9-0:16:16", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:9:9-0:16:16", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:18:18-0:19:19", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "square", + "id_val": "square", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/set_tooltip.d2,0:0:0-0:6:6", + "value": [ + { + "string": "square", + "raw_string": "square" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "square" + }, + "style": {}, + "tooltip": { + "value": "y" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From fdb6133f04c7f422ae2f27e0b772b90138996efb Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 17:00:37 -0800 Subject: [PATCH 65/68] replace arrowhead --- d2oracle/edit.go | 4 +- d2oracle/edit_test.go | 30 ++ .../TestSet/replace_arrowhead.exp.json | 280 ++++++++++++++++ .../TestSet/replace_arrowhead_map.exp.json | 298 ++++++++++++++++++ 4 files changed, 609 insertions(+), 3 deletions(-) create mode 100644 testdata/d2oracle/TestSet/replace_arrowhead.exp.json create mode 100644 testdata/d2oracle/TestSet/replace_arrowhead_map.exp.json diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 76f34c240..8e6b81c27 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -194,17 +194,14 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { } reserved = true - toSkip = 1 if len(mk.EdgeKey.Path) > 1 { switch mk.EdgeKey.Path[len(mk.EdgeKey.Path)-2].Unbox().ScalarString() { case "source-arrowhead": if edge.SrcArrowhead != nil { - toSkip++ attrs = edge.SrcArrowhead } case "target-arrowhead": if edge.DstArrowhead != nil { - toSkip++ attrs = edge.DstArrowhead } } @@ -236,6 +233,7 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.Label.MapKey.Value = d2ast.MakeValueBox(edgeMap) scope = edgeMap } + toSkip = len(mk.Key.Path) } } diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 965ce4826..3e738fd9d 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -776,6 +776,36 @@ square.style.opacity: 0.2 exp: `square: { link: https://apple.com } +`, + }, + { + name: "replace_arrowhead", + text: `x -> y: { + target-arrowhead.shape: diamond +} +`, + key: `(x -> y)[0].target-arrowhead.shape`, + value: go2.Pointer(`circle`), + exp: `x -> y: { + target-arrowhead.shape: circle +} +`, + }, + { + name: "replace_arrowhead_map", + text: `x -> y: { + target-arrowhead: { + shape: diamond + } +} +`, + key: `(x -> y)[0].target-arrowhead.shape`, + value: go2.Pointer(`circle`), + exp: `x -> y: { + target-arrowhead: { + shape: circle + } +} `, }, { diff --git a/testdata/d2oracle/TestSet/replace_arrowhead.exp.json b/testdata/d2oracle/TestSet/replace_arrowhead.exp.json new file mode 100644 index 000000000..dcc2c7bdc --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_arrowhead.exp.json @@ -0,0 +1,280 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:0:0-3:0:45", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:0:0-2:1:44", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:8:8-2:0:43", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,1:2:12-1:32:42", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,1:2:12-1:24:34", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,1:2:12-1:18:28", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,1:19:29-1:24:34", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,1:26:36-1:32:42", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/replace_arrowhead_map.exp.json b/testdata/d2oracle/TestSet/replace_arrowhead_map.exp.json new file mode 100644 index 000000000..dcabb24e7 --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_arrowhead_map.exp.json @@ -0,0 +1,298 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:0:0-5:0:56", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:0:0-4:1:55", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:8:8-4:0:54", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,1:2:12-3:3:53", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,1:2:12-1:18:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,1:2:12-1:18:28", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,1:20:30-3:2:52", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,2:4:36-2:17:49", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,2:4:36-2:9:41", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,2:4:36-2:9:41", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,2:11:43-2:17:49", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_arrowhead_map.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From b5d2dba267cc45c91699418b2cf2b3dc9d7e4283 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 19:34:38 -0800 Subject: [PATCH 66/68] fix edge keying --- d2oracle/edit.go | 83 +++-- d2oracle/edit_test.go | 51 +++ .../TestSet/edge_merge_arrowhead.exp.json | 327 ++++++++++++++++++ .../TestSet/replace_edge_style.exp.json | 307 ++++++++++++++++ .../TestSet/replace_edge_style_map.exp.json | 282 +++++++++++++++ 5 files changed, 1027 insertions(+), 23 deletions(-) create mode 100644 testdata/d2oracle/TestSet/edge_merge_arrowhead.exp.json create mode 100644 testdata/d2oracle/TestSet/replace_edge_style.exp.json create mode 100644 testdata/d2oracle/TestSet/replace_edge_style_map.exp.json diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 8e6b81c27..5761f2250 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -111,6 +111,8 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { toSkip := 1 reserved := false + reservedKey := "" + reservedTargetKey := "" if mk.Key != nil { found := true for _, idel := range d2graph.Key(mk.Key) { @@ -162,12 +164,14 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { } attrs := obj.Attributes + var edge *d2graph.Edge if len(mk.Edges) == 1 { if mk.EdgeIndex == nil { appendMapKey(scope, mk) return nil } - edge, ok := obj.HasEdge(mk) + var ok bool + edge, ok = obj.HasEdge(mk) if !ok { return errors.New("edge not found") } @@ -194,18 +198,7 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { } reserved = true - if len(mk.EdgeKey.Path) > 1 { - switch mk.EdgeKey.Path[len(mk.EdgeKey.Path)-2].Unbox().ScalarString() { - case "source-arrowhead": - if edge.SrcArrowhead != nil { - attrs = edge.SrcArrowhead - } - case "target-arrowhead": - if edge.DstArrowhead != nil { - attrs = edge.DstArrowhead - } - } - } + toSkip = 1 mk = &d2ast.Key{ Key: cloneKey(mk.EdgeKey), Value: mk.Value, @@ -217,10 +210,26 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { if ref.MapKey.Value.Map != nil { foundMap = true scope = ref.MapKey.Value.Map - // TODO when edges can have more fields, search for style - if len(scope.Nodes) == 1 && scope.Nodes[0].MapKey.Value.Map != nil { - scope = scope.Nodes[0].MapKey.Value.Map - mk.Key.Path = mk.Key.Path[1:] + for _, n := range scope.Nodes { + if n.MapKey.Value.Map == nil { + continue + } + if n.MapKey.Key == nil || len(n.MapKey.Key.Path) != 1 { + continue + } + if n.MapKey.Key.Path[0].Unbox().ScalarString() == mk.Key.Path[toSkip-1].Unbox().ScalarString() { + scope = n.MapKey.Value.Map + if mk.Key.Path[0].Unbox().ScalarString() == "source-arrowhead" && edge.SrcArrowhead != nil { + attrs = edge.SrcArrowhead + } + if mk.Key.Path[0].Unbox().ScalarString() == "target-arrowhead" && edge.DstArrowhead != nil { + attrs = edge.DstArrowhead + } + reservedKey = mk.Key.Path[0].Unbox().ScalarString() + mk.Key.Path = mk.Key.Path[1:] + reservedTargetKey = mk.Key.Path[0].Unbox().ScalarString() + break + } } break } @@ -233,14 +242,16 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.Label.MapKey.Value = d2ast.MakeValueBox(edgeMap) scope = edgeMap } - toSkip = len(mk.Key.Path) } } if reserved { reservedIndex := toSkip - 1 if mk.Key != nil && len(mk.Key.Path) > 0 { - switch mk.Key.Path[reservedIndex].Unbox().ScalarString() { + if reservedKey == "" { + reservedKey = mk.Key.Path[reservedIndex].Unbox().ScalarString() + } + switch reservedKey { case "shape": if attrs.Shape.MapKey != nil { attrs.Shape.MapKey.SetScalar(mk.Value.ScalarBox()) @@ -276,11 +287,34 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { attrs.Left.MapKey.SetScalar(mk.Value.ScalarBox()) return nil } - case "style": - if len(mk.Key.Path[reservedIndex:]) != 2 { - return errors.New("malformed style setting, expected 2 part path") + case "source-arrowhead", "target-arrowhead": + if reservedKey == "source-arrowhead" { + attrs = edge.SrcArrowhead + } else { + attrs = edge.DstArrowhead } - switch mk.Key.Path[reservedIndex+1].Unbox().ScalarString() { + if attrs != nil { + if reservedTargetKey == "" { + reservedTargetKey = mk.Key.Path[reservedIndex+1].Unbox().ScalarString() + } + switch reservedTargetKey { + case "shape": + if attrs.Shape.MapKey != nil { + attrs.Shape.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + case "label": + if attrs.Label.MapKey != nil { + attrs.Label.MapKey.SetScalar(mk.Value.ScalarBox()) + return nil + } + } + } + case "style": + if reservedTargetKey == "" { + reservedTargetKey = mk.Key.Path[reservedIndex+1].Unbox().ScalarString() + } + switch reservedTargetKey { case "opacity": if attrs.Style.Opacity != nil { attrs.Style.Opacity.MapKey.SetScalar(mk.Value.ScalarBox()) @@ -382,6 +416,9 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { return nil } +// func setStyleAttr(attr *d2graph.Attributes, k string, v *d2ast.Key) { +// } + func appendUniqueMapKey(m *d2ast.Map, mk *d2ast.Key) { for _, n := range m.Nodes { if n.MapKey != nil && n.MapKey.Equals(mk) { diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 3e738fd9d..ab67b090e 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -806,6 +806,38 @@ square.style.opacity: 0.2 shape: circle } } +`, + }, + { + name: "replace_edge_style_map", + text: `x -> y: { + style: { + stroke-dash: 3 + } +} +`, + key: `(x -> y)[0].style.stroke-dash`, + value: go2.Pointer(`4`), + exp: `x -> y: { + style: { + stroke-dash: 4 + } +} +`, + }, + { + name: "replace_edge_style", + text: `x -> y: { + style.stroke-width: 1 + style.stroke-dash: 4 +} +`, + key: `(x -> y)[0].style.stroke-dash`, + value: go2.Pointer(`3`), + exp: `x -> y: { + style.stroke-width: 1 + style.stroke-dash: 3 +} `, }, { @@ -1169,6 +1201,25 @@ a.b -> a.c: {style.animated: true} exp: `x -> y (x -> y)[0].target-arrowhead.shape: diamond +`, + }, + { + name: "edge_merge_arrowhead", + text: `x -> y: { + target-arrowhead: { + label: 1 + } +} +`, + key: `(x -> y)[0].target-arrowhead.shape`, + value: go2.Pointer(`diamond`), + + exp: `x -> y: { + target-arrowhead: { + label: 1 + shape: diamond + } +} `, }, { diff --git a/testdata/d2oracle/TestSet/edge_merge_arrowhead.exp.json b/testdata/d2oracle/TestSet/edge_merge_arrowhead.exp.json new file mode 100644 index 000000000..5ab8b6250 --- /dev/null +++ b/testdata/d2oracle/TestSet/edge_merge_arrowhead.exp.json @@ -0,0 +1,327 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:0:0-6:0:70", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:0:0-5:1:69", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:8:8-5:0:68", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,1:2:12-4:3:67", + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,1:2:12-1:18:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,1:2:12-1:18:28", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,1:20:30-4:2:66", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,2:4:36-2:12:44", + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,2:4:36-2:9:41", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,2:4:36-2:9:41", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,2:11:43-2:12:44", + "raw": "1", + "value": "1" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,3:4:49-3:18:63", + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,3:4:49-3:9:54", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,3:4:49-3:9:54", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,3:11:56-3:18:63", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "1" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "diamond" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_merge_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/replace_edge_style.exp.json b/testdata/d2oracle/TestSet/replace_edge_style.exp.json new file mode 100644 index 000000000..0b015d938 --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_edge_style.exp.json @@ -0,0 +1,307 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:0:0-4:0:59", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:0:0-3:1:58", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:8:8-3:0:57", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,1:2:12-1:23:33", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,1:2:12-1:20:30", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,1:2:12-1:7:17", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,1:8:18-1:20:30", + "value": [ + { + "string": "stroke-width", + "raw_string": "stroke-width" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,1:22:32-1:23:33", + "raw": "1", + "value": "1" + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,2:2:36-2:22:56", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,2:2:36-2:19:53", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,2:2:36-2:7:41", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,2:8:42-2:19:53", + "value": [ + { + "string": "stroke-dash", + "raw_string": "stroke-dash" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,2:21:55-2:22:56", + "raw": "3", + "value": "3" + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": { + "strokeWidth": { + "value": "1" + }, + "strokeDash": { + "value": "3" + } + }, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/replace_edge_style_map.exp.json b/testdata/d2oracle/TestSet/replace_edge_style_map.exp.json new file mode 100644 index 000000000..5bacdac19 --- /dev/null +++ b/testdata/d2oracle/TestSet/replace_edge_style_map.exp.json @@ -0,0 +1,282 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:0:0-5:0:46", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:0:0-4:1:45", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:0:0-0:6:6", + "src": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:8:8-4:0:44", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,1:2:12-3:3:43", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,1:2:12-1:7:17", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,1:2:12-1:7:17", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,1:9:19-3:2:42", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,2:4:25-2:18:39", + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,2:4:25-2:15:36", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,2:4:25-2:15:36", + "value": [ + { + "string": "stroke-dash", + "raw_string": "stroke-dash" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,2:17:38-2:18:39", + "raw": "4", + "value": "4" + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": { + "strokeDash": { + "value": "4" + } + }, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/replace_edge_style_map.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} From f15614066b884cdd2fc31720d494f9195a67a25a Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 19:41:40 -0800 Subject: [PATCH 67/68] comment --- d2oracle/edit.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 5761f2250..7dd142f79 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -111,6 +111,23 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { toSkip := 1 reserved := false + + // If you're setting `(x -> y)[0].style.opacity` + // There's 3 cases you need to handle: + // 1. The edge has no map. + // 2. The edge has a style map with opacity not existing + // 3. The edge has a style map with opacity existing + // + // How each case is handled: + // 1. Append that mapkey to edge. + // 2. Append opacity to the style map + // 3. Set opacity + // + // There's certainly cleaner code to achieve this, but currently, there's a lot of logic to correctly scope, merge, append. + // The tests should be comprehensive enough for a safe refactor someday + // + // reservedKey = "style" + // reservedTargetKey = "opacity" reservedKey := "" reservedTargetKey := "" if mk.Key != nil { @@ -295,6 +312,9 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { } if attrs != nil { if reservedTargetKey == "" { + if len(mk.Key.Path[reservedIndex:]) != 2 { + return errors.New("malformed style setting, expected 2 part path") + } reservedTargetKey = mk.Key.Path[reservedIndex+1].Unbox().ScalarString() } switch reservedTargetKey { @@ -312,6 +332,9 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { } case "style": if reservedTargetKey == "" { + if len(mk.Key.Path[reservedIndex:]) != 2 { + return errors.New("malformed style setting, expected 2 part path") + } reservedTargetKey = mk.Key.Path[reservedIndex+1].Unbox().ScalarString() } switch reservedTargetKey { @@ -416,9 +439,6 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { return nil } -// func setStyleAttr(attr *d2graph.Attributes, k string, v *d2ast.Key) { -// } - func appendUniqueMapKey(m *d2ast.Map, mk *d2ast.Key) { for _, n := range m.Nodes { if n.MapKey != nil && n.MapKey.Equals(mk) { From e91a046990ba4041c48dddf741379393112349e6 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 20:17:17 -0800 Subject: [PATCH 68/68] fix edge key index value --- d2ast/d2ast.go | 15 +- d2oracle/edit.go | 12 +- d2oracle/edit_test.go | 24 + .../edge_flat_merge_arrowhead.exp.json | 499 ++++++++++++++++++ .../TestSet/edge_index_merge_style.exp.json | 483 +++++++++++++++++ 5 files changed, 1031 insertions(+), 2 deletions(-) create mode 100644 testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.exp.json create mode 100644 testdata/d2oracle/TestSet/edge_index_merge_style.exp.json diff --git a/d2ast/d2ast.go b/d2ast/d2ast.go index 85d6f8620..3d209be6a 100644 --- a/d2ast/d2ast.go +++ b/d2ast/d2ast.go @@ -593,8 +593,11 @@ type Key struct { Value ValueBox `json:"value"` } -// TODO there's more stuff to compare +// TODO maybe need to compare Primary func (mk1 *Key) Equals(mk2 *Key) bool { + if mk1.Ampersand != mk2.Ampersand { + return false + } if (mk1.Key == nil) != (mk2.Key == nil) { return false } @@ -624,6 +627,16 @@ func (mk1 *Key) Equals(mk2 *Key) bool { } } } + if mk1.EdgeKey != nil { + if len(mk1.EdgeKey.Path) != len(mk2.EdgeKey.Path) { + return false + } + for i, id := range mk1.EdgeKey.Path { + if id.Unbox().ScalarString() != mk2.EdgeKey.Path[i].Unbox().ScalarString() { + return false + } + } + } if mk1.Value.Map != nil { if len(mk1.Value.Map.Nodes) != len(mk2.Value.Map.Nodes) { diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 7dd142f79..8905450a7 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -200,7 +200,17 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error { // (y -> z)[0].style.animated: true if len(ref.MapKey.Edges) == 1 && ref.MapKey.EdgeIndex == nil { onlyInChain = false - break + } + // If a ref has an exact match on this key, just change the value + tmp1 := *ref.MapKey + tmp2 := *mk + noVal1 := &tmp1 + noVal2 := &tmp2 + noVal1.Value = d2ast.ValueBox{} + noVal2.Value = d2ast.ValueBox{} + if noVal1.Equals(noVal2) { + ref.MapKey.Value = mk.Value + return nil } } if onlyInChain { diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index ab67b090e..7cd1ef697 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -1239,6 +1239,30 @@ a.b -> a.c: {style.animated: true} animated: true } } +`, + }, + { + name: "edge_flat_merge_arrowhead", + text: `x -> y -> z +(x -> y)[0].target-arrowhead.shape: diamond +`, + key: `(x -> y)[0].target-arrowhead.shape`, + value: go2.Pointer(`circle`), + + exp: `x -> y -> z +(x -> y)[0].target-arrowhead.shape: circle +`, + }, + { + name: "edge_index_merge_style", + text: `x -> y -> z +(x -> y)[0].style.opacity: 0.4 +`, + key: `(x -> y)[0].style.opacity`, + value: go2.Pointer(`0.5`), + + exp: `x -> y -> z +(x -> y)[0].style.opacity: 0.5 `, }, { diff --git a/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.exp.json b/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.exp.json new file mode 100644 index 000000000..36c828de4 --- /dev/null +++ b/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.exp.json @@ -0,0 +1,499 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:0:0-2:0:55", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:0:0-0:11:11", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:0:0-0:7:7", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + }, + { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:4:4-0:11:11", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:9:9-0:11:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:10:10-0:11:11", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:0:12-1:42:54", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:1:13-1:7:19", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:1:13-1:3:15", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:1:13-1:2:14", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:5:17-1:7:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:6:18-1:7:19", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:8:20-1:11:23", + "int": 0, + "glob": false + }, + "edge_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:12:24-1:34:46", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:12:24-1:28:40", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:29:41-1:34:46", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:36:48-1:42:54", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "dstArrowhead": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 1 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:1:13-1:3:15", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:1:13-1:2:14", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:5:17-1:7:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,1:6:18-1:7:19", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "z", + "id_val": "z", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:9:9-0:11:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_flat_merge_arrowhead.d2,0:10:10-0:11:11", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 1 + } + ], + "attributes": { + "label": { + "value": "z" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/edge_index_merge_style.exp.json b/testdata/d2oracle/TestSet/edge_index_merge_style.exp.json new file mode 100644 index 000000000..d8dcf3782 --- /dev/null +++ b/testdata/d2oracle/TestSet/edge_index_merge_style.exp.json @@ -0,0 +1,483 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:0:0-2:0:43", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:0:0-0:11:11", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:0:0-0:7:7", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + }, + { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:4:4-0:11:11", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:9:9-0:11:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:10:10-0:11:11", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:0:12-1:30:42", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:1:13-1:7:19", + "src": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:1:13-1:3:15", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:1:13-1:2:14", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:5:17-1:7:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:6:18-1:7:19", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:8:20-1:11:23", + "int": 0, + "glob": false + }, + "edge_key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:12:24-1:25:37", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:12:24-1:17:29", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:18:30-1:25:37", + "value": [ + { + "string": "opacity", + "raw_string": "opacity" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:27:39-1:30:42", + "raw": "0.5", + "value": "1/2" + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": { + "opacity": { + "value": "0.5" + } + }, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 1 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "x", + "id_val": "x", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:1:13-1:3:15", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:1:13-1:2:14", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:4:4-0:7:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:5:17-1:7:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,1:6:18-1:7:19", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "z", + "id_val": "z", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:9:9-0:11:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/edge_index_merge_style.d2,0:10:10-0:11:11", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 1 + } + ], + "attributes": { + "label": { + "value": "z" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +}