From b5d2dba267cc45c91699418b2cf2b3dc9d7e4283 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 20 Feb 2023 19:34:38 -0800 Subject: [PATCH 1/2] 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 2/2] 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) {