From 68f04b4161a7477e0eb50f91d39c5a5a7f49a124 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 25 Feb 2025 11:20:39 -0700 Subject: [PATCH 1/8] d2ir: do not interpret comment in array as array node --- d2compiler/compile_test.go | 18 ++ d2ir/compile.go | 2 + .../vars/basic/comment-array.exp.json | 214 ++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 testdata/d2compiler/TestCompile2/vars/basic/comment-array.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index ca2c76a47..31e11235f 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -4409,6 +4409,24 @@ a: { assert.Equal(t, 2, len(g.Objects[0].SQLTable.Columns[0].Constraint)) }, }, + { + name: "comment-array", + run: func(t *testing.T) { + assertCompile(t, ` +vars: { + list: [ + "a"; + "b"; + "c"; + "d" + # e + ] +} + +a +`, "") + }, + }, { name: "spread-array", run: func(t *testing.T) { diff --git a/d2ir/compile.go b/d2ir/compile.go index 60a35cf38..668bc9190 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -1282,6 +1282,8 @@ func (c *compiler) compileArray(dst *Array, a *d2ast.Array, scopeAST *d2ast.Map) Value: []d2ast.InterpolationBox{{Substitution: an.Substitution}}, }, } + case *d2ast.Comment: + continue } dst.Values = append(dst.Values, irv) diff --git a/testdata/d2compiler/TestCompile2/vars/basic/comment-array.exp.json b/testdata/d2compiler/TestCompile2/vars/basic/comment-array.exp.json new file mode 100644 index 000000000..392d58b96 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/basic/comment-array.exp.json @@ -0,0 +1,214 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,0:0:0-12:0:71", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,1:0:1-9:1:67", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,1:0:1-1:4:5", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,1:6:7-9:1:67", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,2:2:11-8:3:65", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,2:2:11-2:6:15", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,2:2:11-2:6:15", + "value": [ + { + "string": "list", + "raw_string": "list" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "array": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,2:8:17-8:2:64", + "nodes": [ + { + "double_quoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,3:4:23-3:7:26", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "double_quoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,4:4:32-4:7:35", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + }, + { + "double_quoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,5:4:41-5:7:44", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "double_quoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,6:4:50-6:7:53", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + }, + { + "comment": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,7:4:58-7:7:61", + "value": "e" + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,11:0:69-11:1:70", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,11:0:69-11:1:70", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,11:0:69-11:1:70", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,11:0:69-11:1:70", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/comment-array.d2,11:0:69-11:1:70", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} From 06b29a5815598ef4b0290ba8bef17b2e70a8e0a9 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 25 Feb 2025 11:21:27 -0700 Subject: [PATCH 2/8] next --- 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 cdc65f746..fba3a90cc 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -9,4 +9,5 @@ - Compiler: - fixes panic when `sql_shape` shape value had mixed casing [#2349](https://github.com/terrastruct/d2/pull/2349) - fixes support for `center` in `d2-config` [#2360](https://github.com/terrastruct/d2/pull/2360) + - fixes panic when comment lines appear in arrays [#2378](https://github.com/terrastruct/d2/pull/2378) - CLI: fetch and render remote images of mimetype octet-stream correctly [#2370](https://github.com/terrastruct/d2/pull/2370) From a7528c40b32a260631efacb17e9d9fe739dbce9a Mon Sep 17 00:00:00 2001 From: delfino Date: Tue, 25 Feb 2025 23:38:27 +0000 Subject: [PATCH 3/8] d2js: add support for custom fonts --- ci/release/changelogs/next.md | 24 ++++++----- d2js/d2wasm/functions.go | 28 ++++++++++-- d2js/d2wasm/types.go | 6 ++- d2js/js/README.md | 4 ++ d2js/js/examples/customizable.html | 69 ++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 16 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 931433ee9..66e87b07d 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -4,17 +4,19 @@ #### Improvements 🧹 -- d2js: Support `d2-config`. Support additional options: [#2343](https://github.com/terrastruct/d2/pull/2343) - - `themeID` - - `darkThemeID` - - `center` - - `pad` - - `scale` - - `forceAppendix` - - `target` - - `animateInterval` - - `salt` - - `noXMLTag` +- d2js: + - Support `d2-config`. Support additional options: [#2343](https://github.com/terrastruct/d2/pull/2343) + - `themeID` + - `darkThemeID` + - `center` + - `pad` + - `scale` + - `forceAppendix` + - `target` + - `animateInterval` + - `salt` + - `noXMLTag` + - Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): (PR Pending) #### Bugfixes ⛑️ diff --git a/d2js/d2wasm/functions.go b/d2js/d2wasm/functions.go index 192ac068e..4df3882c2 100644 --- a/d2js/d2wasm/functions.go +++ b/d2js/d2wasm/functions.go @@ -29,7 +29,6 @@ import ( "oss.terrastruct.com/d2/lib/textmeasure" "oss.terrastruct.com/d2/lib/urlenc" "oss.terrastruct.com/d2/lib/version" - "oss.terrastruct.com/util-go/go2" ) func GetParentID(args []js.Value) (interface{}, error) { @@ -194,6 +193,30 @@ func Compile(args []js.Value) (interface{}, error) { return nil, &WASMError{Message: fmt.Sprintf("invalid fs input: %s", err.Error()), Code: 400} } + var fontRegular []byte + var fontItalic []byte + var fontBold []byte + var fontSemibold []byte + if input.Opts != nil && (input.Opts.FontRegular != nil) { + fontRegular = *input.Opts.FontRegular + } + if input.Opts != nil && (input.Opts.FontItalic != nil) { + fontItalic = *input.Opts.FontItalic + } + if input.Opts != nil && (input.Opts.FontBold != nil) { + fontBold = *input.Opts.FontBold + } + if input.Opts != nil && (input.Opts.FontSemibold != nil) { + fontSemibold = *input.Opts.FontSemibold + } + if fontRegular != nil || fontItalic != nil || fontBold != nil || fontSemibold != nil { + fontFamily, err := d2fonts.AddFontFamily("custom", fontRegular, fontItalic, fontBold, fontSemibold) + if err != nil { + return nil, &WASMError{Message: fmt.Sprintf("custom fonts could not be initialized: %s", err.Error()), Code: 500} + } + compileOpts.FontFamily = fontFamily + } + compileOpts.Ruler, err = textmeasure.NewRuler() if err != nil { return nil, &WASMError{Message: fmt.Sprintf("text ruler cannot be initialized: %s", err.Error()), Code: 500} @@ -206,9 +229,6 @@ func Compile(args []js.Value) (interface{}, error) { renderOpts := &d2svg.RenderOpts{} if input.Opts != nil && input.Opts.Sketch != nil { renderOpts.Sketch = input.Opts.Sketch - if *input.Opts.Sketch { - compileOpts.FontFamily = go2.Pointer(d2fonts.HandDrawn) - } } if input.Opts != nil && input.Opts.Pad != nil { renderOpts.Pad = input.Opts.Pad diff --git a/d2js/d2wasm/types.go b/d2js/d2wasm/types.go index 70b3e1154..a74624610 100644 --- a/d2js/d2wasm/types.go +++ b/d2js/d2wasm/types.go @@ -52,7 +52,11 @@ type RenderOptions struct { type CompileOptions struct { RenderOptions - Layout *string `json:"layout"` + Layout *string `json:"layout"` + FontRegular *[]byte `json:"FontRegular"` + FontItalic *[]byte `json:"FontItalic"` + FontBold *[]byte `json:"FontBold"` + FontSemibold *[]byte `json:"FontSemibold"` } type CompileResponse struct { diff --git a/d2js/js/README.md b/d2js/js/README.md index 411586036..a72545a3e 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -77,6 +77,10 @@ Renders a compiled diagram to SVG. All [RenderOptions](#renderoptions) properties in addition to: - `layout`: Layout engine to use ('dagre' | 'elk') [default: 'dagre'] +- `fontRegular` A byte array containing .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used. +- `fontItalic` A byte array containing .ttf file to use for the italic font. If none provided, Source Sans Pro Italic is used. +- `fontBold` A byte array containing .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used. +- `fontSemibold` A byte array containing .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used. ### `RenderOptions` diff --git a/d2js/js/examples/customizable.html b/d2js/js/examples/customizable.html index 54df63a49..afa6e60a3 100644 --- a/d2js/js/examples/customizable.html +++ b/d2js/js/examples/customizable.html @@ -319,6 +319,53 @@ +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
@@ -326,6 +373,12 @@