diff --git a/ci/release/build_in_docker.sh b/ci/release/build_in_docker.sh index cbfcbcdec..839449137 100755 --- a/ci/release/build_in_docker.sh +++ b/ci/release/build_in_docker.sh @@ -4,7 +4,7 @@ cd -- "$(dirname "$0")/../.." . ./ci/sub/lib.sh tag="$(sh_c docker build \ - --build-arg GOVERSION="1.22.2.linux-$ARCH" \ + --build-arg GOVERSION="1.23.6.linux-$ARCH" \ -qf ./ci/release/linux/Dockerfile ./ci/release/linux)" docker_run \ -e DRY_RUN \ diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index ed05eec20..e705612b3 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -17,10 +17,12 @@ - `salt` - `noXMLTag` - Support relative imports. Improve elk error handling: [#2382](https://github.com/terrastruct/d2/pull/2382) + - Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): [#2384](https://github.com/terrastruct/d2/pull/2384) #### Bugfixes ⛑️ - 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) diff --git a/d2ast/keywords.go b/d2ast/keywords.go index 65f67b775..d1454a51d 100644 --- a/d2ast/keywords.go +++ b/d2ast/keywords.go @@ -8,6 +8,7 @@ var ReservedKeywords map[string]struct{} // Non Style/Holder keywords. var SimpleReservedKeywords = map[string]struct{}{ "label": {}, + "legend-label": {}, "shape": {}, "icon": {}, "constraint": {}, diff --git a/d2compiler/compile.go b/d2compiler/compile.go index e8af01b14..28c6ba7f2 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -547,6 +547,10 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) { attrs.Tooltip = &d2graph.Scalar{} attrs.Tooltip.Value = scalar.ScalarString() attrs.Tooltip.MapKey = f.LastPrimaryKey() + case "legend-label": + attrs.LegendLabel = &d2graph.Scalar{} + attrs.LegendLabel.Value = scalar.ScalarString() + attrs.LegendLabel.MapKey = f.LastPrimaryKey() case "width": _, err := strconv.Atoi(scalar.ScalarString()) if err != nil { diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index ca2c76a47..fcd7eb454 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) { @@ -5415,6 +5433,23 @@ b -> c assert.Equal(t, "red", g.Edges[0].Style.Stroke.Value) }, }, + { + name: "legend-label", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a.legend-label: This is A +b: {legend-label: This is B} +a -> b: { + legend-label: "This is a->b" +} +`, ``) + assert.Equal(t, "a", g.Objects[0].ID) + assert.Equal(t, "This is A", g.Objects[0].LegendLabel.Value) + assert.Equal(t, "b", g.Objects[1].ID) + assert.Equal(t, "This is B", g.Objects[1].LegendLabel.Value) + assert.Equal(t, "This is a->b", g.Edges[0].LegendLabel.Value) + }, + }, } for _, tc := range tca { diff --git a/d2exporter/export.go b/d2exporter/export.go index 672bae188..fb820b782 100644 --- a/d2exporter/export.go +++ b/d2exporter/export.go @@ -196,6 +196,9 @@ func toShape(obj *d2graph.Object, g *d2graph.Graph) d2target.Shape { if obj.Tooltip != nil { shape.Tooltip = obj.Tooltip.Value } + if obj.LegendLabel != nil { + shape.LegendLabel = obj.LegendLabel.Value + } if obj.Style.Animated != nil { shape.Animated, _ = strconv.ParseBool(obj.Style.Animated.Value) } diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 0776849ab..52848bc1a 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -222,7 +222,8 @@ type Attributes struct { // These names are attached to the rendered elements in SVG // so that users can target them however they like outside of D2 - Classes []string `json:"classes,omitempty"` + Classes []string `json:"classes,omitempty"` + LegendLabel *Scalar `json:"legendLabel,omitempty"` } // ApplyTextTransform will alter the `Label.Value` of the current object based 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/d2js/d2wasm/functions.go b/d2js/d2wasm/functions.go index 2d5080775..ca36e08fa 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" ) const DEFAULT_INPUT_PATH = "index" @@ -210,6 +209,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: 400} + } + 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} @@ -222,9 +245,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 5e7299bd4..68550958c 100644 --- a/d2js/d2wasm/types.go +++ b/d2js/d2wasm/types.go @@ -53,7 +53,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 7089adb2c..55cb9e159 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -103,6 +103,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 @@