Skip to content

Commit 53973ea

Browse files
committed
feat: add theme support
1 parent 7781551 commit 53973ea

File tree

5 files changed

+30
-7
lines changed

5 files changed

+30
-7
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ D2-Live is a dynamic tool for creating live, embeddable diagrams using the D2 la
3232

3333
![Diagram Example](https://d2.atlas.lucas.tools/?script=LNExDsIwEETR3qf4nSt8ABeUSNCGCzhkRSxIHGUXiHN6ZET9NKORZotcx2ReuRfDCr1go9CLGktekwln_xZaFBWZ3cbhSHU10hWy8Smv59BoCiG42nSPXNLtQbf8FnttnZOgllZTt0dOaRDybIX_ge4bAAD__w%3D%3D)
3434

35+
You can use any of the [D2-Themes](https://d2lang.com/tour/themes) to customize the look of your diagram, just add `&theme=<theme_id>` to the URL.
36+
3537
## Contributing to D2-Live
3638
We welcome contributions! Please refer to our [Contribution Guidelines](https://github.com/Watt3r/d2-live/CONTRIBUTING.md) for details on how to submit changes, coding standards, and testing procedures.
3739

go.mod

-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ go 1.20
55
require (
66
github.com/DataDog/datadog-go/v5 v5.3.0
77
github.com/husobee/vestigo v1.1.1
8-
github.com/smartystreets/assertions v1.13.1
98
github.com/stretchr/testify v1.8.1
109
oss.terrastruct.com/d2 v0.4.1
1110
)
@@ -31,7 +30,6 @@ require (
3130
github.com/mazznoer/csscolorparser v0.1.3 // indirect
3231
github.com/pmezard/go-difflib v1.0.0 // indirect
3332
github.com/rivo/uniseg v0.4.3 // indirect
34-
github.com/stretchr/objx v0.5.0 // indirect
3533
github.com/yuin/goldmark v1.5.3 // indirect
3634
go.opencensus.io v0.24.0 // indirect
3735
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect

go.sum

-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO
109109
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
110110
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
111111
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
112-
github.com/smartystreets/assertions v1.13.1 h1:Ef7KhSmjZcK6AVf9YbJdvPYG9avaF0ZxudX+ThRdWfU=
113-
github.com/smartystreets/assertions v1.13.1/go.mod h1:cXr/IwVfSo/RbCSPhoAPv73p3hlSdrBH/b3SdnW/LMY=
114112
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
115113
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
116114
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=

internal/handlers/get_svg.go

+21-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import (
44
"context"
55
"errors"
66
"net/http"
7+
"strconv"
78

89
"github.com/husobee/vestigo"
910
"github.com/watt3r/d2-live/internal/urlenc"
1011
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
1112
"oss.terrastruct.com/d2/d2lib"
1213
"oss.terrastruct.com/d2/d2renderers/d2svg"
14+
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
1315
"oss.terrastruct.com/d2/lib/textmeasure"
1416
)
1517

@@ -30,10 +32,25 @@ func (c *Controller) GetD2SVGHandler(rw http.ResponseWriter, req *http.Request)
3032
return
3133
}
3234

35+
// Get theme if provided
36+
themeStr := req.URL.Query().Get("theme")
37+
var theme int64
38+
var err error
39+
if themeStr != "" {
40+
theme, err = strconv.ParseInt(themeStr, 10, 64)
41+
if err != nil {
42+
http.Error(rw, "Invalid theme parameter", http.StatusBadRequest)
43+
return
44+
}
45+
} else {
46+
// Use a default theme if none is provided
47+
theme = d2themescatalog.NeutralDefault.ID
48+
}
49+
3350
// Emit complexity metric
3451
c.Metrics.Histogram("d2-live.complexity", float64(len(urlencoded)), []string{}, 1)
3552

36-
svg, err := c.handleGetD2SVG(ctx, urlencoded)
53+
svg, err := c.handleGetD2SVG(ctx, urlencoded, theme)
3754

3855
if err != nil {
3956
http.Error(rw, err.Error(), http.StatusBadRequest)
@@ -44,7 +61,7 @@ func (c *Controller) GetD2SVGHandler(rw http.ResponseWriter, req *http.Request)
4461
rw.Write(svg)
4562
}
4663

47-
func (c *Controller) handleGetD2SVG(ctx context.Context, encoded string) ([]byte, error) {
64+
func (c *Controller) handleGetD2SVG(ctx context.Context, encoded string, theme int64) ([]byte, error) {
4865
decoded, err := urlenc.Decode(encoded)
4966
if err != nil {
5067
return nil, errors.New("Invalid Base64 data.")
@@ -59,7 +76,8 @@ func (c *Controller) handleGetD2SVG(ctx context.Context, encoded string) ([]byte
5976

6077
// Render to SVG
6178
out, err := d2svg.Render(diagram, &d2svg.RenderOpts{
62-
Pad: d2svg.DEFAULT_PADDING,
79+
Pad: d2svg.DEFAULT_PADDING,
80+
ThemeID: theme,
6381
})
6482
if err != nil {
6583
return nil, errors.New("Invalid D2 data.")

internal/handlers/get_svg_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ func TestController_GetD2SVGHandler(t *testing.T) {
1616
type state struct {
1717
pathEncoded string
1818
queryEncoded string
19+
queryTheme string
1920
}
2021
type want struct {
2122
code int
@@ -28,8 +29,11 @@ func TestController_GetD2SVGHandler(t *testing.T) {
2829
}{
2930
{"happy path with path param", state{pathEncoded: "qlDQtVOo5AIEAAD__w=="}, want{200, "<?xml version=\"1.0\" encoding=\"utf-8\"?>"}},
3031
{"happy path with query param", state{queryEncoded: "qlDQtVOo5AIEAAD__w=="}, want{200, "<?xml version=\"1.0\" encoding=\"utf-8\"?>"}},
32+
{"happy path with valid theme", state{queryEncoded: "qlDQtVOo5AIEAAD__w==", queryTheme: "100"}, want{200, "<?xml version=\"1.0\" encoding=\"utf-8\"?>"}},
3133
{"fail bad request with path param", state{pathEncoded: "qlDQtVOo5AIEAAD__w==&"}, want{400, "Invalid Base64 data."}},
3234
{"fail bad request with query param", state{queryEncoded: "qlDQtVOo5AIEAAD__w==&"}, want{400, "Invalid Base64 data."}},
35+
{"fail bad request with no param", state{}, want{400, "encodedD2 or script parameter not provided"}},
36+
{"fail bad request with invalid theme", state{queryEncoded: "qlDQtVOo5AIEAAD__w==", queryTheme: "invalid"}, want{400, "Invalid theme parameter"}},
3337
}
3438

3539
for _, tc := range testCases {
@@ -44,6 +48,9 @@ func TestController_GetD2SVGHandler(t *testing.T) {
4448
if tc.state.queryEncoded != "" {
4549
q.Set("script", tc.state.queryEncoded)
4650
}
51+
if tc.state.queryTheme != "" {
52+
q.Set("theme", tc.state.queryTheme)
53+
}
4754
req.URL.RawQuery = q.Encode()
4855

4956
resp := httptest.NewRecorder()

0 commit comments

Comments
 (0)