diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 1a7075a1f..0fec115fa 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -25,3 +25,34 @@ jobs: with: name: d2chaos path: ./d2chaos/out + npm-nightly: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Needed for git history and version tags + + - name: Check for changes + id: check_changes + run: | + if [ $(git rev-list --count --since="24 hours ago" HEAD) -gt 0 ]; then + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "Found changes in the last 24 hours, proceeding to publish d2js nightly" + else + echo "has_changes=false" >> $GITHUB_OUTPUT + echo "No changes in the last 24 hours, skipping d2js nightly publish" + fi + + - uses: actions/setup-go@v4 + if: steps.check_changes.outputs.has_changes == 'true' + with: + go-version-file: ./go.mod + cache: true + + - name: Publish nightly version to NPM + if: steps.check_changes.outputs.has_changes == 'true' + run: COLOR=1 NPM_VERSION=nightly ./make.sh js + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }} + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} diff --git a/README.md b/README.md index 12133f941..7a9763a4d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ [![ci](https://github.com/terrastruct/d2/actions/workflows/ci.yml/badge.svg)](https://github.com/terrastruct/d2/actions/workflows/ci.yml) [![daily](https://github.com/terrastruct/d2/actions/workflows/daily.yml/badge.svg)](https://github.com/terrastruct/d2/actions/workflows/daily.yml) [![release](https://img.shields.io/github/v/release/terrastruct/d2)](https://github.com/terrastruct/d2/releases) +[![changelog](https://img.shields.io/badge/changelog-read-blue)](./CHANGELOG.md) +[![npm version](https://img.shields.io/npm/v/@terrastruct/d2)](https://www.npmjs.com/package/@terrastruct/d2) [![discord](https://img.shields.io/discord/1039184639652265985?label=discord)](https://discord.gg/NF6X8K4eDq) [![twitter](https://img.shields.io/twitter/follow/terrastruct?style=social)](https://twitter.com/terrastruct) [![license](https://img.shields.io/github/license/terrastruct/d2?color=9cf)](./LICENSE.txt) @@ -267,6 +269,7 @@ let us know and we'll be happy to include it here! - **VitePress Plugin**: [https://github.com/BadgerHobbs/vitepress-plugin-d2](https://github.com/BadgerHobbs/vitepress-plugin-d2) - **Zed extension**: [https://github.com/gabeidx/zed-d2](https://github.com/gabeidx/zed-d2) - **Hexo blog extension**: [https://github.com/leverimmy/hexo-d2](https://github.com/leverimmy/hexo-d2) +- **Rehype Plugin**: [https://github.com/stereobooster/beoe/tree/main/packages/rehype-d2](https://github.com/stereobooster/beoe/tree/main/packages/rehype-d2) ### Misc diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 66ca47e84..b292912f9 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -7,30 +7,28 @@ - markdown, latex, and code can be used as object labels [#2204](https://github.com/terrastruct/d2/pull/2204) - `shape: c4-person` to render a person shape like what the C4 model prescribes [#2397](https://github.com/terrastruct/d2/pull/2397) - Icons: border-radius should work on icon [#2409](https://github.com/terrastruct/d2/issues/2409) +- Diagram legends are implemented [#2416](https://github.com/terrastruct/d2/pull/2416) #### 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` - - 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) +- d2cli: + - Support `validate` command. [#2415](https://github.com/terrastruct/d2/pull/2415) + - Watch mode ignores backup files (e.g. files created by certain editors like Helix). [#2131](https://github.com/terrastruct/d2/issues/2131) +- d2compiler: + - `link`s can be set to root path, e.g. `/xyz`. [#2357](https://github.com/terrastruct/d2/issues/2357) #### Bugfixes ⛑️ - Compiler: - fixes panic when `sql_shape` shape value had mixed casing [#2349](https://github.com/terrastruct/d2/pull/2349) + - fixes panic when importing from a file with spread substitutions in `vars` [#2427](https://github.com/terrastruct/d2/pull/2427) - 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) - fixes inconsistencies when objects were double quoted [#2390](https://github.com/terrastruct/d2/pull/2390) + - fixes globs not applying to spread substitutions [#2426](https://github.com/terrastruct/d2/issues/2426) - CLI: fetch and render remote images of mimetype octet-stream correctly [#2370](https://github.com/terrastruct/d2/pull/2370) - d2js: handle unicode characters [#2393](https://github.com/terrastruct/d2/pull/2393) + +--- + +For the latest d2.js changes, see separate [changelog](https://github.com/terrastruct/d2/blob/master/d2js/js/CHANGELOG.md). diff --git a/ci/release/changelogs/template.md b/ci/release/changelogs/template.md index f3c0d2a77..65780a72c 100644 --- a/ci/release/changelogs/template.md +++ b/ci/release/changelogs/template.md @@ -3,3 +3,7 @@ #### Improvements 🧹 #### Bugfixes ⛑️ + +--- + +For the latest d2.js changes, see separate [changelog](https://github.com/terrastruct/d2/blob/master/d2js/js/CHANGELOG.md). diff --git a/ci/release/release-js.sh b/ci/release/release-js.sh new file mode 100755 index 000000000..5cb5abea6 --- /dev/null +++ b/ci/release/release-js.sh @@ -0,0 +1,39 @@ +#!/bin/sh +set -eu +cd -- "$(dirname "$0")/../.." +. "./ci/sub/lib.sh" + +VERSION="" + +help() { + cat < + +Publishes the d2.js to NPM. + +Flags: + --version Version to publish (e.g., "0.1.2" or "nightly"). Note this is the js version, not related to the d2 version. A non-nightly version will publish to latest. +EOF +} + +for arg in "$@"; do + case "$arg" in + --help|-h) + help + exit 0 + ;; + --version=*) + VERSION="${arg#*=}" + ;; + esac +done + +if [ -z "$VERSION" ]; then + flag_errusage "--version is required" +fi + +FGCOLOR=6 header "Publishing JavaScript package to NPM (version: $VERSION)" + +sh_c "NPM_VERSION=$VERSION ./make.sh js" + +FGCOLOR=2 header 'NPM publish completed' diff --git a/ci/release/release.sh b/ci/release/release.sh index 517ae778d..c85120722 100755 --- a/ci/release/release.sh +++ b/ci/release/release.sh @@ -1,5 +1,26 @@ #!/bin/sh set -eu cd -- "$(dirname "$0")/../.." +. "./ci/sub/lib.sh" + + +NPM_VERSION="" + +for arg in "$@"; do + case "$arg" in + --npm-version=*) + NPM_VERSION="${arg#*=}" + ;; + esac +done + +if [ -z "$NPM_VERSION" ]; then + flag_errusage "--npm-version is required" +fi ./ci/sub/release/release.sh "$@" + +if [ -n "$NPM_VERSION" ]; then + ./ci/release/release-js.sh --version="$NPM_VERSION" +fi + diff --git a/ci/release/template/man/d2.1 b/ci/release/template/man/d2.1 index 24ebdd7e1..70269172b 100644 --- a/ci/release/template/man/d2.1 +++ b/ci/release/template/man/d2.1 @@ -17,6 +17,8 @@ .Ar fmt Ar file.d2 ... .Nm d2 .Ar play Ar file.d2 +.Nm d2 +.Ar validate Ar file.d2 .Sh DESCRIPTION .Nm compiles and renders @@ -162,6 +164,8 @@ Lists available themes Format all passed files .It Ar play Ar file.d2 Opens the file in playground, an online web viewer (https://play.d2lang.com) +.It Ar validate Ar file.d2 +Validates file.d2 .El .Sh ENVIRONMENT VARIABLES Many flags can also be set with environment variables. diff --git a/d2cli/help.go b/d2cli/help.go index eb80c85bf..5b025b6bb 100644 --- a/d2cli/help.go +++ b/d2cli/help.go @@ -23,6 +23,7 @@ Usage: %[1]s layout [name] %[1]s fmt file.d2 ... %[1]s play [--theme=0] [--sketch] file.d2 + %[1]s validate file.d2 %[1]s compiles and renders file.d2 to file.svg | file.png It defaults to file.svg if an output path is not provided. @@ -40,6 +41,7 @@ Subcommands: %[1]s themes - Lists available themes %[1]s fmt file.d2 ... - Format passed files %[1]s play file.d2 - Opens the file in playground, an online web viewer (https://play.d2lang.com) + %[1]s validate file.d2 - Validates file.d2 See more docs and the source code at https://oss.terrastruct.com/d2. Hosted icons at https://icons.terrastruct.com. diff --git a/d2cli/main.go b/d2cli/main.go index dbf1ae2c4..3eb486d70 100644 --- a/d2cli/main.go +++ b/d2cli/main.go @@ -173,6 +173,8 @@ func Run(ctx context.Context, ms *xmain.State) (err error) { return fmtCmd(ctx, ms, *checkFlag) case "play": return playCmd(ctx, ms) + case "validate": + return validateCmd(ctx, ms) case "version": if len(ms.Opts.Flags.Args()) > 1 { return xmain.UsageErrorf("version subcommand accepts no arguments") diff --git a/d2cli/validate.go b/d2cli/validate.go new file mode 100644 index 000000000..69bd6028e --- /dev/null +++ b/d2cli/validate.go @@ -0,0 +1,41 @@ +package d2cli + +import ( + "context" + "fmt" + + "oss.terrastruct.com/d2/d2lib" + "oss.terrastruct.com/util-go/xdefer" + "oss.terrastruct.com/util-go/xmain" +) + +func validateCmd(ctx context.Context, ms *xmain.State) (err error) { + defer xdefer.Errorf(&err, "") + + ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:]) + if len(ms.Opts.Args) == 0 { + return xmain.UsageErrorf("input argument required") + } + + inputPath := ms.Opts.Args[0] + if inputPath != "-" { + inputPath = ms.AbsPath(inputPath) + } + + input, err := ms.ReadPath(inputPath) + if err != nil { + return err + } + + _, err = d2lib.Parse(ctx, string(input), nil) + if err != nil { + return err + } + + if inputPath == "-" { + inputPath = "Input" + } + + fmt.Printf("Success! [%s] is valid D2.\n", inputPath) + return nil +} diff --git a/d2cli/watch.go b/d2cli/watch.go index 6c240a711..f34dd0a1a 100644 --- a/d2cli/watch.go +++ b/d2cli/watch.go @@ -264,6 +264,12 @@ func (w *watcher) watchLoop(ctx context.Context) error { return errors.New("fsnotify watcher closed") } w.ms.Log.Debug.Printf("received file system event %v", ev) + + if isTemp, reason := isBackupFile(ev.Name); isTemp { + w.ms.Log.Debug.Printf("skipping event for %q: detected as %s", w.ms.HumanPath(ev.Name), reason) + continue + } + mt, err := w.ensureAddWatch(ctx, ev.Name) if err != nil { return err @@ -349,6 +355,11 @@ func (w *watcher) ensureAddWatch(ctx context.Context, path string) (time.Time, e } func (w *watcher) addWatch(ctx context.Context, path string) (time.Time, error) { + if isTemp, reason := isBackupFile(path); isTemp { + w.ms.Log.Debug.Printf("skipping watch for %q: detected as %s", w.ms.HumanPath(path), reason) + return time.Time{}, nil + } + err := w.fw.Add(path) if err != nil { return time.Time{}, err @@ -671,3 +682,41 @@ func (tfs *trackedFS) Open(name string) (fs.File, error) { } return f, err } + +func isBackupFile(path string) (bool, string) { + ext := filepath.Ext(path) + baseName := filepath.Base(path) + + // This list is based off of https://github.com/gohugoio/hugo/blob/master/commands/hugobuilder.go#L795 + switch { + case strings.HasSuffix(ext, "~"): + return true, "generic backup file (~)" + case ext == ".swp": + return true, "vim swap file" + case ext == ".swx": + return true, "vim swap file" + case ext == ".tmp": + return true, "generic temp file" + case ext == ".DS_Store": + return true, "OSX thumbnail" + case ext == ".bck": + return true, "Helix backup" + case baseName == "4913": + return true, "vim temp file" + case strings.HasPrefix(ext, ".goutputstream"): + return true, "GNOME temp file" + case strings.HasSuffix(ext, "jb_old___"): + return true, "IntelliJ old backup" + case strings.HasSuffix(ext, "jb_tmp___"): + return true, "IntelliJ temp file" + case strings.HasSuffix(ext, "jb_bak___"): + return true, "IntelliJ backup" + case strings.HasPrefix(ext, ".sb-"): + return true, "Byword temp file" + case strings.HasPrefix(baseName, ".#"): + return true, "Emacs lock file" + case strings.HasPrefix(baseName, "#"): + return true, "Emacs temp file" + } + return false, "" +} diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 125ae344e..541937799 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -1330,7 +1330,7 @@ func (c *compiler) validateBoardLinks(g *d2graph.Graph) { } u, err := url.Parse(html.UnescapeString(obj.Link.Value)) - isRemote := err == nil && u.Scheme != "" + isRemote := err == nil && (u.Scheme != "" || strings.HasPrefix(u.Path, "/")) if isRemote { continue } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 00f3a24e4..ccd042fad 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -1658,6 +1658,22 @@ x -> y: { } }, }, + { + name: "url_relative_link", + + text: `x: { + link: /google +} +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + if len(g.Objects) != 1 { + t.Fatal(g.Objects) + } + if g.Objects[0].Link.Value != "/google" { + t.Fatal(g.Objects[0].Link.Value) + } + }, + }, { name: "non_url_link", @@ -3125,6 +3141,62 @@ x*: { tassert.Equal(t, "x2.ok", g.Objects[3].AbsID()) }, }, + { + name: "glob-spread-vars/1", + text: `vars: { + b: { + 1 + } +} + +a: { + ...${b} + *.style.fill: red +} +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + assert.Equal(t, "1", g.Objects[1].Label.Value) + assert.Equal(t, "red", g.Objects[1].Style.Fill.Value) + }, + }, + { + name: "glob-spread-vars/2", + text: `vars: { + b: { + 1 + 2 + } +} + +a: { + ...${b} + ** -> _.ok +} + +ok +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + assert.Equal(t, 2, len(g.Edges)) + }, + }, + { + name: "import-var-chain", + + text: `...@dev +`, + files: map[string]string{ + "dev.d2": ` +vars: { + a: { + b + } + c: { + ...${a} + } +} +`, + }, + }, { name: "var_in_markdown", text: `vars: { @@ -5617,6 +5689,98 @@ d -> d: "suspend" assert.Equal(t, 1, len(g.Edges)) }, }, + { + name: "unsuspend-edge-label", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a -> b: hello +c +**: suspend +(** -> **)[*]: suspend + +(* -> *)[*]: unsuspend +`, ``) + assert.Equal(t, 2, len(g.Objects)) + assert.Equal(t, 1, len(g.Edges)) + assert.Equal(t, "hello", g.Edges[0].Label.Value) + }, + }, + { + name: "unsuspend-edge-filter", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a -> b +**: suspend +(** -> **)[*]: suspend +(* -> *)[*]: unsuspend { + &dst: a +} +`, ``) + assert.Equal(t, 0, len(g.Objects)) + assert.Equal(t, 0, len(g.Edges)) + }, + }, + { + name: "unsuspend-edge-child", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: { + b -> c +} + +**: suspend +(** -> **)[*]: suspend +(** -> **)[*]: unsuspend { + &dst: a.c +} +`, ``) + assert.Equal(t, 3, len(g.Objects)) + assert.Equal(t, 1, len(g.Edges)) + }, + }, + { + name: "unsuspend-cross-container-edge-label", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: { + b +} +c: { + d +} +a.b -> c.d: likes +**: suspend +(** -> **)[*]: suspend +(** -> **)[*]: unsuspend { + &label: likes +} +`, ``) + assert.Equal(t, 4, len(g.Objects)) + assert.Equal(t, 1, len(g.Edges)) + }, + }, + { + name: "unsuspend-shape-label", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: hello +*: suspend +*: unsuspend +`, ``) + assert.Equal(t, 1, len(g.Objects)) + assert.Equal(t, "hello", g.Objects[0].Label.Value) + }, + }, + { + name: "suspend-shape", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: hello +*: suspend +`, ``) + assert.Equal(t, 0, len(g.Objects)) + }, + }, { name: "edge-glob-ampersand-filter/1", run: func(t *testing.T) { diff --git a/d2ir/compile.go b/d2ir/compile.go index 63588d8c8..19a77c037 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -280,6 +280,19 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie break } } + + if removedField && len(m.globs) > 0 && !c.lazyGlobBeingApplied { + origGlobStack := c.globContextStack + c.globContextStack = append(c.globContextStack, m.globs) + for _, gctx := range m.globs { + old := c.lazyGlobBeingApplied + c.lazyGlobBeingApplied = true + c.compileKey(gctx.refctx) + c.lazyGlobBeingApplied = old + } + c.globContextStack = origGlobStack + } + } } if resolvedField.Primary() == nil { @@ -869,6 +882,22 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool { for _, part := range edge.ID.SrcPath { srcParts = append(srcParts, part.ScalarString()) } + + container := ParentField(edge) + if container != nil && container.Name.ScalarString() != "root" { + containerPath := []string{} + curr := container + for curr != nil && curr.Name.ScalarString() != "root" { + containerPath = append([]string{curr.Name.ScalarString()}, containerPath...) + curr = ParentField(curr) + } + + srcStart := srcParts[0] + if !strings.EqualFold(srcStart, containerPath[0]) { + srcParts = append(containerPath, srcParts...) + } + } + srcPath := strings.Join(srcParts, ".") return srcPath == filterValue @@ -889,6 +918,23 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool { for _, part := range edge.ID.DstPath { dstParts = append(dstParts, part.ScalarString()) } + + // Find the container that holds this edge + // Build the absolute path by prepending the container's path + container := ParentField(edge) + if container != nil && container.Name.ScalarString() != "root" { + containerPath := []string{} + curr := container + for curr != nil && curr.Name.ScalarString() != "root" { + containerPath = append([]string{curr.Name.ScalarString()}, containerPath...) + curr = ParentField(curr) + } + + dstStart := dstParts[0] + if !strings.EqualFold(dstStart, containerPath[0]) { + dstParts = append(containerPath, dstParts...) + } + } dstPath := strings.Join(dstParts, ".") return dstPath == filterValue @@ -1101,6 +1147,10 @@ func (c *compiler) extendLinks(m *Map, importF *Field, importDir string) { nodeBoardKind := NodeBoardKind(m) importIDA := IDA(importF) for _, f := range m.Fields { + // A substitute or such + if f.Name == nil { + continue + } if f.Name.ScalarString() == "link" && f.Name.IsUnquoted() { if nodeBoardKind != "" { c.errorf(f.LastRef().AST(), "a board itself cannot be linked; only objects within a board can be linked") @@ -1109,7 +1159,7 @@ func (c *compiler) extendLinks(m *Map, importF *Field, importDir string) { val := f.Primary().Value.ScalarString() u, err := url.Parse(html.UnescapeString(val)) - isRemote := err == nil && u.Scheme != "" + isRemote := err == nil && (u.Scheme != "" || strings.HasPrefix(u.Path, "/")) if isRemote { continue } @@ -1147,7 +1197,7 @@ func (c *compiler) extendLinks(m *Map, importF *Field, importDir string) { continue } u, err := url.Parse(html.UnescapeString(val)) - isRemoteImg := err == nil && u.Scheme != "" + isRemoteImg := err == nil && (u.Scheme != "" || strings.HasPrefix(u.Path, "/")) if isRemoteImg { continue } @@ -1273,12 +1323,94 @@ func (c *compiler) _compileEdges(refctx *RefContext) { continue } + if refctx.Key.Value.Map != nil && refctx.Key.Value.Map.HasFilter() { + if e.Map_ == nil { + e.Map_ = &Map{ + parent: e, + } + } + c.mapRefContextStack = append(c.mapRefContextStack, refctx) + ok := c.ampersandFilterMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST) + c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1] + if !ok { + continue + } + } + if refctx.Key.Primary.Suspension != nil || refctx.Key.Value.Suspension != nil { if !c.lazyGlobBeingApplied { + // Check if edge passes filter before applying suspension + if refctx.Key.Value.Map != nil && refctx.Key.Value.Map.HasFilter() { + if e.Map_ == nil { + e.Map_ = &Map{ + parent: e, + } + } + c.mapRefContextStack = append(c.mapRefContextStack, refctx) + ok := c.ampersandFilterMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST) + c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1] + if !ok { + continue + } + } + + var suspensionValue bool if refctx.Key.Primary.Suspension != nil { - e.suspended = refctx.Key.Primary.Suspension.Value + suspensionValue = refctx.Key.Primary.Suspension.Value } else { - e.suspended = refctx.Key.Value.Suspension.Value + suspensionValue = refctx.Key.Value.Suspension.Value + } + e.suspended = suspensionValue + + // If we're unsuspending an edge, we should also unsuspend its src and dst objects + // And their ancestors + if !suspensionValue { + srcPath, dstPath := e.ID.SrcPath, e.ID.DstPath + + // Make paths absolute if they're relative + container := ParentField(e) + if container != nil && container.Name.ScalarString() != "root" { + containerPath := []d2ast.String{} + curr := container + for curr != nil && curr.Name.ScalarString() != "root" { + containerPath = append([]d2ast.String{curr.Name}, containerPath...) + curr = ParentField(curr) + } + + if len(srcPath) > 0 && !strings.EqualFold(srcPath[0].ScalarString(), containerPath[0].ScalarString()) { + absSrcPath := append([]d2ast.String{}, containerPath...) + srcPath = append(absSrcPath, srcPath...) + } + + if len(dstPath) > 0 && !strings.EqualFold(dstPath[0].ScalarString(), containerPath[0].ScalarString()) { + absDstPath := append([]d2ast.String{}, containerPath...) + dstPath = append(absDstPath, dstPath...) + } + } + + rootMap := RootMap(refctx.ScopeMap) + srcObj := rootMap.GetField(srcPath...) + dstObj := rootMap.GetField(dstPath...) + + // Unsuspend source node and all its ancestors + if srcObj != nil { + srcObj.suspended = false + parent := ParentField(srcObj) + for parent != nil && parent.Name.ScalarString() != "root" { + parent.suspended = false + parent = ParentField(parent) + } + } + + // Unsuspend destination node and all its ancestors + if dstObj != nil { + dstObj.suspended = false + parent := ParentField(dstObj) + for parent != nil && parent.Name.ScalarString() != "root" { + parent.suspended = false + parent = ParentField(parent) + } + } } } } @@ -1309,7 +1441,7 @@ func (c *compiler) _compileEdges(refctx *RefContext) { } c.compileField(e.Map_, refctx.Key.EdgeKey, refctx) } else { - if refctx.Key.Primary.Unbox() != nil { + if refctx.Key.Primary.Unbox() != nil && refctx.Key.Primary.Suspension == nil { if c.ignoreLazyGlob(e) { return } @@ -1330,7 +1462,7 @@ func (c *compiler) _compileEdges(refctx *RefContext) { c.mapRefContextStack = append(c.mapRefContextStack, refctx) c.compileMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST) c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1] - } else if refctx.Key.Value.ScalarBox().Unbox() != nil { + } else if refctx.Key.Value.ScalarBox().Unbox() != nil && refctx.Key.Value.Suspension == nil { if c.ignoreLazyGlob(e) { return } diff --git a/d2ir/d2ir.go b/d2ir/d2ir.go index 4ea360b92..e41edbb83 100644 --- a/d2ir/d2ir.go +++ b/d2ir/d2ir.go @@ -650,7 +650,41 @@ func (rc *RefContext) EdgeIndex() int { func (rc *RefContext) Equal(rc2 *RefContext) bool { // We intentionally ignore edges here because the same glob can produce multiple RefContexts that should be treated the same with only the edge as the difference. // Same with ScopeMap. - return rc.Key.Equals(rc2.Key) && rc.Scope == rc2.Scope && rc.ScopeAST == rc2.ScopeAST + if !(rc.Key.Equals(rc2.Key) && rc.Scope == rc2.Scope && rc.ScopeAST == rc2.ScopeAST) { + return false + } + + // Check if suspension values match for suspension operations + // We don't want these two to equal + // 1. *: suspend + // 2. *: unsuspend + hasSuspension1 := (rc.Key.Primary.Suspension != nil || rc.Key.Value.Suspension != nil) + hasSuspension2 := (rc2.Key.Primary.Suspension != nil || rc2.Key.Value.Suspension != nil) + + if hasSuspension1 || hasSuspension2 { + var val1, val2 bool + if rc.Key.Primary.Suspension != nil { + val1 = rc.Key.Primary.Suspension.Value + } else if rc.Key.Value.Suspension != nil { + val1 = rc.Key.Value.Suspension.Value + } + + if rc2.Key.Primary.Suspension != nil { + val2 = rc2.Key.Primary.Suspension.Value + } else if rc2.Key.Value.Suspension != nil { + val2 = rc2.Key.Value.Suspension.Value + } + + if hasSuspension1 && hasSuspension2 && val1 != val2 { + return false + } + + if hasSuspension1 != hasSuspension2 { + return false + } + } + + return true } func (m *Map) FieldCountRecursive() int { diff --git a/d2js/js/CHANGELOG.md b/d2js/js/CHANGELOG.md index 542c51629..18767b5cc 100644 --- a/d2js/js/CHANGELOG.md +++ b/d2js/js/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to only the d2.js package will be documented in this file. **Does not include changes to the main d2 project.** -## [0.1.0] - 2025-01-12 +## Next + +- Fix TypeScript signatures + +## [0.1.22] +### March 20, 2025 + +- 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 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) +- Add TypeScript signatures + +## [0.1.21] +### January 12, 2025 First public release diff --git a/d2js/js/README.md b/d2js/js/README.md index 55cb9e159..1b7298245 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -29,6 +29,18 @@ pnpm add @terrastruct/d2 bun add @terrastruct/d2 ``` +### Nightly + +Use the `@nightly` tag to get the version that is built by daily CI on the master branch. + +For example, + +```bash +yarn add @terrastruct/d2@nightly +``` + +A demo using the nightly build is hosted [here](https://alixander-d2js.web.val.run/). + ## Usage D2.js uses webworkers to call a WASM file. @@ -162,6 +174,16 @@ You can browse the examples by running the dev server: Visit `http://localhost:3000` to see the example page. +### Publishing + +TODO stable release publishing. + +Nightly builds are automated by CI by running: + +```bash +PUBLISH=1 ./make.sh build +``` + ## Contributing Contributions are welcome! diff --git a/d2js/js/ci/build.sh b/d2js/js/ci/build.sh index f081d8e4f..87a692196 100755 --- a/d2js/js/ci/build.sh +++ b/d2js/js/ci/build.sh @@ -17,3 +17,59 @@ fi cd d2js/js sh_c bun build.js + +if [ -n "${NPM_VERSION:-}" ]; then + cp package.json package.json.bak + trap 'rm -f .npmrc; mv package.json.bak package.json' EXIT + + if [ "$NPM_VERSION" = "nightly" ]; then + echo "Publishing nightly version to npm..." + + DATE_TAG=$(date +'%Y%m%d') + COMMIT_SHORT=$(git rev-parse --short HEAD) + CURRENT_VERSION=$(node -p "require('./package.json').version") + PUBLISH_VERSION="${CURRENT_VERSION}-nightly.${DATE_TAG}.${COMMIT_SHORT}" + NPM_TAG="nightly" + + echo "Updating package version to ${PUBLISH_VERSION}" + else + echo "Publishing official version ${NPM_VERSION} to npm..." + PUBLISH_VERSION="$NPM_VERSION" + NPM_TAG="latest" + + echo "Setting package version to ${PUBLISH_VERSION}" + fi + + # Update package.json with the new version + npm version "${PUBLISH_VERSION}" --no-git-tag-version + + echo "Publishing to npm with tag '${NPM_TAG}'..." + if [ -n "${NPM_TOKEN-}" ]; then + # Create .npmrc file with auth token + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc + + if npm publish --tag "$NPM_TAG"; then + echo "Successfully published @terrastruct/d2@${PUBLISH_VERSION} to npm with tag '${NPM_TAG}'" + + # For official releases, bump the patch version + if [ "$NPM_VERSION" != "nightly" ]; then + # Restore original package.json first + mv package.json.bak package.json + + echo "Bumping version to ${NPM_VERSION}" + npm version "${NPM_VERSION}" --no-git-tag-version + git add package.json + git commit -m "Bump version to ${NPM_VERSION} [skip ci]" + + # Cancel the trap since we manually restored and don't want it to execute on exit + trap - EXIT + fi + else + echoerr "Failed to publish package to npm" + exit 1 + fi + else + echoerr "NPM_TOKEN environment variable is required for publishing to npm" + exit 1 + fi +fi diff --git a/d2js/js/index.d.ts b/d2js/js/index.d.ts new file mode 100644 index 000000000..0b455af6e --- /dev/null +++ b/d2js/js/index.d.ts @@ -0,0 +1,343 @@ +export class D2 { + compile(input: string, options?: Omit): Promise; + compile(input: CompileRequest): Promise; + + render(diagram: Diagram, options?: RenderOptions): Promise; +} + +export interface RenderOptions { + /** Enable sketch mode [default: false] */ + sketch?: boolean; + /** Theme ID to use [default: 0] */ + themeID?: number; + /** Theme ID to use when client is in dark mode */ + darkThemeID?: number; + /** Center the SVG in the containing viewbox [default: false] */ + center?: boolean; + /** Pixels padded around the rendered diagram [default: 100] */ + pad?: number; + /** Scale the output. E.g., 0.5 to halve the default size. The default will render SVG's that will fit to screen. Setting to 1 turns off SVG fitting to screen. */ + scale?: number; + /** Adds an appendix for tooltips and links [default: false] */ + forceAppendix?: boolean; + /** Target board/s to render. If target ends with '', it will be rendered with all of its scenarios, steps, and layers. Otherwise, only the target board will be rendered. E.g. target: 'layers.x.*' to render layer 'x' with all of its children. Pass '' to render all scenarios, steps, and layers. By default, only the root board is rendered. Multi-board outputs are currently only supported for animated SVGs and so animateInterval must be set to a value greater than 0 when targeting multiple boards. */ + target?: string; + /** If given, multiple boards are packaged as 1 SVG which transitions through each board at the interval (in milliseconds). */ + animateInterval?: number; + /** Add a salt value to ensure the output uses unique IDs. This is useful when generating multiple identical diagrams to be included in the same HTML doc, so that duplicate IDs do not cause invalid HTML. The salt value is a string that will be appended to IDs in the output. */ + salt?: string; + /** Omit XML tag () from output SVG files. Useful when generating SVGs for direct HTML embedding. */ + noXMLTag?: boolean; +} + +export interface CompileOptions extends RenderOptions { + /** Layout engine to use [default: 'dagre'] */ + layout?: "dagre" | "elk"; + /** A byte array containing .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used. */ + fontRegular?: Uint8Array; + /** A byte array containing .ttf file to use for the italic font. If none provided, Source Sans Pro Italic is used. */ + fontItalic?: Uint8Array; + /** A byte array containing .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used. */ + fontBold?: Uint8Array; + /** A byte array containing .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used. */ + fontSemibold?: Uint8Array; +} + +export interface CompileRequest { + /** A mapping of D2 file paths to their content*/ + fs: Record; + /** The path of the entry D2 file [default: index]*/ + inputPath?: string; + /** The CompileOptions to pass to the compiler*/ + options: CompileOptions; +} + +export interface CompileResponse { + /** Compiled D2 diagram*/ + diagram: Diagram /* d2target.Diagram */; + /** RenderOptions: Render options merged with configuration set in diagram*/ + renderOptions: RenderOptions; + fs: Record; + graph: Graph; + inputPath: string; +} + +export interface Diagram { + config?: RenderOptions; + name: string; + /** + * See docs on the same field in d2graph to understand what it means. + */ + isFolderOnly: boolean; + description?: string; + fontFamily?: any /* d2fonts.FontFamily */; + shapes: Shape[]; + connections: Connection[]; + root: Shape; + legend?: Legend; + layers?: (Diagram | undefined)[]; + scenarios?: (Diagram | undefined)[]; + steps?: (Diagram | undefined)[]; +} + +export interface Legend { + shapes?: Shape[]; + connections?: Connection[]; +} + +export type Shape = (Class | SQLTable | Text) & ShapeBase; + +export interface ShapeBase { + id: string; + type: string; + classes?: string[]; + pos: Point; + width: number /* int */; + height: number /* int */; + opacity: number /* float64 */; + strokeDash: number /* float64 */; + strokeWidth: number /* int */; + borderRadius: number /* int */; + fill: string; + fillPattern?: string; + stroke: string; + animated: boolean; + shadow: boolean; + "3d": boolean; + multiple: boolean; + "double-border": boolean; + tooltip: string; + link: string; + prettyLink?: string; + icon?: string /* url.URL */; + iconPosition: string; + /** + * Whether the shape should allow shapes behind it to bleed through + * Currently just used for sequence diagram groups + */ + blend: boolean; + contentAspectRatio?: number /* float64 */; + labelPosition?: string; + zIndex: number /* int */; + level: number /* int */; + /** + * These are used for special shapes, sql_table and class + */ + primaryAccentColor?: string; + secondaryAccentColor?: string; + neutralAccentColor?: string; +} + +export interface Point { + x: number /* int */; + y: number /* int */; +} + +export interface Class { + fields: ClassField[]; + methods: ClassMethod[]; +} + +export interface ClassField { + name: string; + type: string; + visibility: string; +} + +export interface ClassMethod { + name: string; + return: string; + visibility: string; +} + +export interface SQLTable { + columns: SQLColumn[]; +} + +export interface SQLColumn { + name: Text; + type: Text; + constraint: string[]; + reference: string; +} + +export interface Text { + label: string; + fontSize: number /* int */; + fontFamily: string; + language: string; + color: string; + italic: boolean; + bold: boolean; + underline: boolean; + labelWidth: number /* int */; + labelHeight: number /* int */; + labelFill?: string; +} + +export interface Connection extends Text { + id: string; + classes?: string[]; + src: string; + srcArrow: Arrowhead; + srcLabel?: Text; + dst: string; + dstArrow: Arrowhead; + dstLabel?: Text; + opacity: number /* float64 */; + strokeDash: number /* float64 */; + strokeWidth: number /* int */; + stroke: string; + fill?: string; + borderRadius?: number /* float64 */; + labelPosition: string; + labelPercentage: number /* float64 */; + link: string; + prettyLink?: string; + route: (any /* geo.Point */ | undefined)[]; + isCurve?: boolean; + animated: boolean; + tooltip: string; + icon?: string /* url.URL */; + iconPosition?: string; + zIndex: number /* int */; +} + +export type Arrowhead = + | "none" + | "arrow" + | "unfilled-triangle" + | "triangle" + | "diamond" + | "filled-diamond" + | "circle" + | "filled-circle" + | "box" + | "filled-box" + | "line" + | "cf-one" + | "cf-many" + | "cf-one-required" + | "cf-many-required"; + +export interface Graph { + name: string; + /** + * IsFolderOnly indicates a board or scenario itself makes no modifications from its + * base. Folder only boards do not have a render and are used purely for organizing + * the board tree. + */ + isFolderOnly: boolean; + ast?: any /* d2ast.Map */; + root?: Object; + legend?: Legend; + edges: (Edge | undefined)[]; + objects: (Object | undefined)[]; + layers?: (Graph | undefined)[]; + scenarios?: (Graph | undefined)[]; + steps?: (Graph | undefined)[]; + theme?: any /* d2themes.Theme */; + /** + * Object.Level uses the location of a nested graph + */ + rootLevel?: number /* int */; + /** + * Currently this holds data embedded from source code configuration variables + * Plugins only have access to exported graph, so this data structure allows + * carrying arbitrary metadata that any plugin might handle + */ + data?: { [key: string]: any }; +} + +export interface Edge { + index: number /* int */; + srcTableColumnIndex?: number /* int */; + dstTableColumnIndex?: number /* int */; + labelPosition?: string; + labelPercentage?: number /* float64 */; + isCurve: boolean; + route?: (any /* geo.Point */ | undefined)[]; + src_arrow: boolean; + srcArrowhead?: Attributes; + /** + * TODO alixander (Mon Sep 12 2022): deprecate SrcArrow and DstArrow and just use SrcArrowhead and DstArrowhead + */ + dst_arrow: boolean; + dstArrowhead?: Attributes; + references?: EdgeReference[]; + attributes?: Attributes; + zIndex: number /* int */; +} + +export interface Attributes { + label: Scalar; + labelDimensions: TextDimensions; + style: Style; + icon?: string /* url.URL */; + tooltip?: Scalar; + link?: Scalar; + width?: Scalar; + height?: Scalar; + top?: Scalar; + left?: Scalar; + /** + * TODO consider separate Attributes struct for shape-specific and edge-specific + * Shapes only + */ + near_key?: any /* d2ast.KeyPath */; + language?: string; + /** + * TODO: default to ShapeRectangle instead of empty string + */ + shape: Scalar; + direction: Scalar; + constraint: string[]; + gridRows?: Scalar; + gridColumns?: Scalar; + gridGap?: Scalar; + verticalGap?: Scalar; + horizontalGap?: Scalar; + labelPosition?: Scalar; + iconPosition?: Scalar; + /** + * These names are attached to the rendered elements in SVG + * so that users can target them however they like outside of D2 + */ + classes?: string[]; +} + +export interface EdgeReference { + map_key_edge_index: number /* int */; +} + +export interface Scalar { + value: string; +} + +export interface Style { + opacity?: Scalar; + stroke?: Scalar; + fill?: Scalar; + fillPattern?: Scalar; + strokeWidth?: Scalar; + strokeDash?: Scalar; + borderRadius?: Scalar; + shadow?: Scalar; + "3d"?: Scalar; + multiple?: Scalar; + font?: Scalar; + fontSize?: Scalar; + fontColor?: Scalar; + animated?: Scalar; + bold?: Scalar; + italic?: Scalar; + underline?: Scalar; + filled?: Scalar; + doubleBorder?: Scalar; + textTransform?: Scalar; +} + +export interface TextDimensions { + width: number /* int */; + height: number /* int */; +} diff --git a/d2js/js/package.json b/d2js/js/package.json index 9a7834975..3eee22350 100644 --- a/d2js/js/package.json +++ b/d2js/js/package.json @@ -2,7 +2,7 @@ "name": "@terrastruct/d2", "author": "Terrastruct, Inc.", "description": "D2.js is a wrapper around the WASM build of D2, the modern text-to-diagram language.", - "version": "0.1.21", + "version": "0.1.23", "repository": { "type": "git", "url": "git+https://github.com/terrastruct/d2.git", @@ -23,23 +23,29 @@ "browser": "./dist/browser/index.js", "import": { "browser": "./dist/browser/index.js", - "default": "./dist/node-esm/index.js" + "default": "./dist/node-esm/index.js", + "types": "./index.d.ts" + }, + "require": { + "default": "./dist/node-cjs/index.js", + "types": "./index.d.ts" }, - "require": "./dist/node-cjs/index.js", "default": "./dist/node-esm/index.js" }, "./worker": "./dist/browser/worker.js" }, "files": [ - "dist" + "dist", + "index.d.ts" ], + "types": "./index.d.ts", "scripts": { "build": "./make.sh build", "test": "bun test test/unit", "test:integration": "bun test test/integration", "test:all": "bun run test && bun run test:integration", "dev": "bun --watch dev-server.js", - "prepublishOnly": "./make.sh all" + "prepublishOnly": "NPM_VERSION= ./make.sh all" }, "keywords": [ "d2", diff --git a/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg b/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg index 44e8664c5..d51852d51 100644 --- a/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-601677588-font-regular"; font-size: 16px; @@ -855,7 +854,7 @@ -x

linux: because a PC is a terrible thing to waste

+x

linux: because a PC is a terrible thing to waste

auserslast_logindatetime You don't have to know how the computer works,just how to work the computer. diff --git a/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg b/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg index 8a7266c98..1de7cbb6d 100644 --- a/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1742880122-font-regular"; font-size: 16px; @@ -852,7 +851,7 @@ -x

linux: because a PC is a terrible thing to waste

+x

linux: because a PC is a terrible thing to waste

auserslast_logindatetime You don't have to know how the computer works,just how to work the computer. diff --git a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg index c8fc0dc00..8c982dbe7 100644 --- a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1318841297-font-regular"; font-size: 16px; @@ -848,7 +847,7 @@ -Flow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseMasterRegional-1Regional-2Regional-N

company Warehouse

+Flow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseMasterRegional-1Regional-2Regional-N

company Warehouse

  • Asset Tagging
  • Inventory
  • diff --git a/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg b/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg index 8188e20a1..543d8a066 100644 --- a/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg @@ -143,7 +143,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-300145350-font-regular"; font-size: 16px; @@ -863,7 +862,7 @@ -People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    +People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    • Inject ads, who-to-follow, onboarding
    • Conversation module
    • @@ -871,7 +870,7 @@
    • Tweat deduplication
    • Served data logging
    -
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    +
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    TLS-API (being deprecated)CrMixerEarlyBirdUtagSpaceCommunities iPhone web HTTP Android Thrift RPC Candidate Fetch Feature Hydration Candidate sources diff --git a/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg b/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg index f875a214b..cf59e2ebb 100644 --- a/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg @@ -143,7 +143,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-151669824-font-regular"; font-size: 16px; @@ -863,7 +862,7 @@ -People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    +People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    • Inject ads, who-to-follow, onboarding
    • Conversation module
    • @@ -871,7 +870,7 @@
    • Tweat deduplication
    • Served data logging
    -
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    +
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    TLS-API (being deprecated)CrMixerEarlyBirdUtagSpaceCommunities iPhone web HTTP Android Thrift RPC Candidate Fetch Feature Hydration Candidate sources diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index f6dab0bbd..2c3cd30ea 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -44,6 +44,13 @@ const ( DEFAULT_PADDING = 100 appendixIconRadius = 16 + + // Legend constants + LEGEND_PADDING = 20 + LEGEND_ITEM_SPACING = 15 + LEGEND_ICON_SIZE = 24 + LEGEND_FONT_SIZE = 14 + LEGEND_CORNER_PADDING = 10 ) var multipleOffset = geo.NewVector(d2target.MULTIPLE_OFFSET, -d2target.MULTIPLE_OFFSET) @@ -101,6 +108,262 @@ func dimensions(diagram *d2target.Diagram, pad int) (left, top, width, height in return left, top, width, height } +func renderLegend(buf *bytes.Buffer, diagram *d2target.Diagram, diagramHash string, theme *d2themes.Theme) error { + if diagram.Legend == nil || (len(diagram.Legend.Shapes) == 0 && len(diagram.Legend.Connections) == 0) { + return nil + } + + _, br := diagram.BoundingBox() + + ruler, err := textmeasure.NewRuler() + if err != nil { + return err + } + + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + + itemCount := 0 + + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 + } + + if itemCount > 0 && len(diagram.Legend.Connections) > 0 { + totalHeight += LEGEND_PADDING * 1.5 + } else { + totalHeight += LEGEND_PADDING * 1.2 + } + + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + legendX := br.X + LEGEND_CORNER_PADDING + tl, _ := diagram.BoundingBox() + legendY := br.Y - totalHeight + if legendY < tl.Y { + legendY = tl.Y + } + + shadowEl := d2themes.NewThemableElement("rect", theme) + shadowEl.Fill = "#F7F7FA" + shadowEl.Stroke = "#DEE1EB" + shadowEl.Style = "stroke-width: 1px; filter: drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.1))" + shadowEl.X = float64(legendX) + shadowEl.Y = float64(legendY) + shadowEl.Width = float64(legendWidth) + shadowEl.Height = float64(totalHeight) + shadowEl.Rx = 4 + fmt.Fprint(buf, shadowEl.Render()) + + legendEl := d2themes.NewThemableElement("rect", theme) + legendEl.Fill = "#ffffff" + legendEl.Stroke = "#DEE1EB" + legendEl.Style = "stroke-width: 1px" + legendEl.X = float64(legendX) + legendEl.Y = float64(legendY) + legendEl.Width = float64(legendWidth) + legendEl.Height = float64(totalHeight) + legendEl.Rx = 4 + fmt.Fprint(buf, legendEl.Render()) + + fmt.Fprintf(buf, `Legend`, + legendX+LEGEND_PADDING, legendY+LEGEND_PADDING+LEGEND_FONT_SIZE, LEGEND_FONT_SIZE+2) + + currentY := legendY + LEGEND_PADDING*2 + LEGEND_FONT_SIZE + + shapeCount := 0 + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + + shapeIcon, err := renderLegendShapeIcon(s, iconX, iconY, diagramHash, theme) + if err != nil { + return err + } + fmt.Fprint(buf, shapeIcon) + + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + + rowHeight := go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + textY := currentY + rowHeight/2 + int(float64(dims.Height)*0.3) + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(s.Label)) + + currentY += rowHeight + LEGEND_ITEM_SPACING + shapeCount++ + } + + if shapeCount > 0 && len(diagram.Legend.Connections) > 0 { + currentY += LEGEND_ITEM_SPACING / 2 + + separatorEl := d2themes.NewThemableElement("line", theme) + separatorEl.X1 = float64(legendX + LEGEND_PADDING) + separatorEl.Y1 = float64(currentY) + separatorEl.X2 = float64(legendX + legendWidth - LEGEND_PADDING) + separatorEl.Y2 = float64(currentY) + separatorEl.Stroke = "#DEE1EB" + separatorEl.StrokeDashArray = "2,2" + fmt.Fprint(buf, separatorEl.Render()) + + currentY += LEGEND_ITEM_SPACING + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + LEGEND_ICON_SIZE/2 + + connIcon, err := renderLegendConnectionIcon(c, iconX, iconY, theme) + if err != nil { + return err + } + fmt.Fprint(buf, connIcon) + + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + + rowHeight := go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + textY := currentY + rowHeight/2 + int(float64(dims.Height)*0.2) + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(c.Label)) + + currentY += rowHeight + LEGEND_ITEM_SPACING + } + + if shapeCount > 0 && len(diagram.Legend.Connections) > 0 { + currentY += LEGEND_PADDING / 2 + } else { + currentY += LEGEND_PADDING / 4 + } + + return nil +} + +func renderLegendShapeIcon(s d2target.Shape, x, y int, diagramHash string, theme *d2themes.Theme) (string, error) { + iconShape := s + const sizeFactor = 5 + iconShape.Pos.X = 0 + iconShape.Pos.Y = 0 + iconShape.Width = LEGEND_ICON_SIZE * sizeFactor + iconShape.Height = LEGEND_ICON_SIZE * sizeFactor + iconShape.Label = "" + buf := &bytes.Buffer{} + appendixBuf := &bytes.Buffer{} + finalBuf := &bytes.Buffer{} + fmt.Fprintf(finalBuf, ``, + x, y, 1.0/sizeFactor) + _, err := drawShape(buf, appendixBuf, diagramHash, iconShape, nil, theme) + if err != nil { + return "", err + } + + fmt.Fprint(finalBuf, buf.String()) + + fmt.Fprint(finalBuf, ``) + + return finalBuf.String(), nil +} + +func renderLegendConnectionIcon(c d2target.Connection, x, y int, theme *d2themes.Theme) (string, error) { + finalBuf := &bytes.Buffer{} + + buf := &bytes.Buffer{} + + const sizeFactor = 2 + + legendConn := *d2target.BaseConnection() + + legendConn.ID = c.ID + legendConn.SrcArrow = c.SrcArrow + legendConn.DstArrow = c.DstArrow + legendConn.StrokeDash = c.StrokeDash + legendConn.StrokeWidth = c.StrokeWidth + legendConn.Stroke = c.Stroke + legendConn.Fill = c.Fill + legendConn.BorderRadius = c.BorderRadius + legendConn.Opacity = c.Opacity + legendConn.Animated = c.Animated + + startX := 0.0 + midY := 0.0 + width := float64(LEGEND_ICON_SIZE * sizeFactor) + + legendConn.Route = []*geo.Point{ + {X: startX, Y: midY}, + {X: startX + width, Y: midY}, + } + + legendHash := fmt.Sprintf("legend-%s", hash(fmt.Sprintf("%s-%d-%d", c.ID, x, y))) + + markers := make(map[string]struct{}) + idToShape := make(map[string]d2target.Shape) + + fmt.Fprintf(finalBuf, ``, + x, y, 1.0/sizeFactor) + + _, err := drawConnection(buf, legendHash, legendConn, markers, idToShape, nil, theme) + if err != nil { + return "", err + } + + fmt.Fprint(finalBuf, buf.String()) + + fmt.Fprint(finalBuf, ``) + + return finalBuf.String(), nil +} + func arrowheadMarkerID(diagramHash string, isTarget bool, connection d2target.Connection) string { var arrowhead d2target.Arrowhead if isTarget { @@ -1496,24 +1759,33 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape render = strings.ReplaceAll(render, "
    ", "
    ") mdEl := d2themes.NewThemableElement("div", inlineTheme) - mdEl.ClassName = "md" mdEl.Content = render // We have to set with styles since within foreignObject, we're in html // land and not SVG attributes var styles []string + var classes []string = []string{"md"} if targetShape.FontSize != textmeasure.MarkdownFontSize { styles = append(styles, fmt.Sprintf("font-size:%vpx", targetShape.FontSize)) } + if targetShape.Fill != "" && targetShape.Fill != "transparent" { - styles = append(styles, fmt.Sprintf(`background-color:%s`, targetShape.Fill)) + if color.IsThemeColor(targetShape.Fill) { + classes = append(classes, fmt.Sprintf("fill-%s", targetShape.Fill)) + } else { + styles = append(styles, fmt.Sprintf(`background-color:%s`, targetShape.Fill)) + } } + if !color.IsThemeColor(targetShape.Color) { styles = append(styles, fmt.Sprintf(`color:%s`, targetShape.Color)) } else { - styles = append(styles, fmt.Sprintf(`color:%s`, d2themes.ResolveThemeColor(*inlineTheme, targetShape.Color))) + classes = append(classes, fmt.Sprintf("color-%s", targetShape.Color)) } + mdEl.ClassName = strings.Join(classes, " ") + // When using dark theme, inlineTheme is nil and we rely on CSS variables + mdEl.Style = strings.Join(styles, ";") fmt.Fprint(writer, mdEl.Render()) @@ -1711,6 +1983,7 @@ func EmbedFonts(buf *bytes.Buffer, diagramHash, source string, fontFamily *d2fon `class="text"`, `class="text `, `class="md"`, + `class="md `, }, fmt.Sprintf(` .%s .text { @@ -1730,7 +2003,10 @@ func EmbedFonts(buf *bytes.Buffer, diagramHash, source string, fontFamily *d2fon appendOnTrigger( buf, source, - []string{`class="md"`}, + []string{ + `class="md"`, + `class="md `, + }, fmt.Sprintf(` @font-face { font-family: %s-font-semibold; @@ -2112,8 +2388,85 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { // add all appendix items afterwards so they are always on top fmt.Fprint(buf, appendixItemBuf) + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + legendBuf := &bytes.Buffer{} + err := renderLegend(legendBuf, diagram, diagramHash, inlineTheme) + if err != nil { + return nil, err + } + fmt.Fprint(buf, legendBuf) + } + // Note: we always want this since we reference it on connections even if there end up being no masked labels left, top, w, h := dimensions(diagram, pad) + + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + tl, br := diagram.BoundingBox() + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + itemCount := 0 + ruler, _ := textmeasure.NewRuler() + if ruler != nil { + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 + } + + totalHeight += LEGEND_PADDING + + if totalHeight > 0 && maxLabelWidth > 0 { + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + + legendY := br.Y - totalHeight + if legendY < tl.Y { + legendY = tl.Y + } + + legendRight := br.X + LEGEND_CORNER_PADDING + legendWidth + if left+w < legendRight { + w = legendRight - left + pad/2 + } + + if legendY < top { + diffY := top - legendY + top -= diffY + h += diffY + } + + legendBottom := legendY + totalHeight + if top+h < legendBottom { + h = legendBottom - top + pad/2 + } + } + } + } fmt.Fprint(buf, strings.Join([]string{ fmt.Sprintf(``, isolatedDiagramHash, left, top, w, h, diff --git a/d2renderers/d2svg/d2svg.go-e b/d2renderers/d2svg/d2svg.go-e new file mode 100644 index 000000000..e71eb3f92 --- /dev/null +++ b/d2renderers/d2svg/d2svg.go-e @@ -0,0 +1,2992 @@ +// d2svg implements an SVG renderer for d2 diagrams. +// The input is d2exporter's output +package d2svg + +import ( + "bytes" + _ "embed" + "encoding/base64" + "errors" + "fmt" + "hash/fnv" + "html" + "io" + "sort" + "strings" + + "math" + + "github.com/alecthomas/chroma/v2" + "github.com/alecthomas/chroma/v2/formatters" + "github.com/alecthomas/chroma/v2/lexers" + "github.com/alecthomas/chroma/v2/styles" + + "oss.terrastruct.com/d2/d2ast" + "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2renderers/d2fonts" + "oss.terrastruct.com/d2/d2renderers/d2latex" + "oss.terrastruct.com/d2/d2renderers/d2sketch" + "oss.terrastruct.com/d2/d2target" + "oss.terrastruct.com/d2/d2themes" + "oss.terrastruct.com/d2/d2themes/d2themescatalog" + "oss.terrastruct.com/d2/lib/color" + "oss.terrastruct.com/d2/lib/geo" + "oss.terrastruct.com/d2/lib/jsrunner" + "oss.terrastruct.com/d2/lib/label" + "oss.terrastruct.com/d2/lib/shape" + "oss.terrastruct.com/d2/lib/svg" + "oss.terrastruct.com/d2/lib/textmeasure" + "oss.terrastruct.com/d2/lib/version" + "oss.terrastruct.com/util-go/go2" +) + +const ( + DEFAULT_PADDING = 100 + + appendixIconRadius = 16 + + // Legend constants + LEGEND_PADDING = 20 + LEGEND_ITEM_SPACING = 15 + LEGEND_ICON_SIZE = 24 + LEGEND_FONT_SIZE = 14 + LEGEND_CORNER_PADDING = 10 +) + +var multipleOffset = geo.NewVector(d2target.MULTIPLE_OFFSET, -d2target.MULTIPLE_OFFSET) + +//go:embed tooltip.svg +var TooltipIcon string + +//go:embed link.svg +var LinkIcon string + +//go:embed style.css +var BaseStylesheet string + +//go:embed github-markdown.css +var MarkdownCSS string + +//go:embed dots.txt +var dots string + +//go:embed lines.txt +var lines string + +//go:embed grain.txt +var grain string + +//go:embed paper.txt +var paper string + +type RenderOpts struct { + Pad *int64 + Sketch *bool + Center *bool + ThemeID *int64 + DarkThemeID *int64 + ThemeOverrides *d2target.ThemeOverrides + DarkThemeOverrides *d2target.ThemeOverrides + Font string + // the svg will be scaled by this factor, if unset the svg will fit to screen + Scale *float64 + + // MasterID is passed when the diagram should use something other than its own hash for unique targeting + // Currently, that's when multi-boards are collapsed + MasterID string + NoXMLTag *bool + Salt *string +} + +func dimensions(diagram *d2target.Diagram, pad int) (left, top, width, height int) { + tl, br := diagram.BoundingBox() + left = tl.X - pad + top = tl.Y - pad + width = br.X - tl.X + pad*2 + height = br.Y - tl.Y + pad*2 + + return left, top, width, height +} + +// renderLegend renders the legend box in the bottom right of the diagram +func renderLegend(buf *bytes.Buffer, diagram *d2target.Diagram, diagramHash string, theme *d2themes.Theme) error { + if diagram.Legend == nil || (len(diagram.Legend.Shapes) == 0 && len(diagram.Legend.Connections) == 0) { + return nil + } + + _, br := diagram.BoundingBox() + + // Create a ruler to measure text + ruler, err := textmeasure.NewRuler() + if err != nil { + return err + } + + // Calculate total height of legend items + // Start with top padding and title height + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + + // Track number of items for precise height calculation + itemCount := 0 + + // Measure text for each legend item to determine dimensions + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + // If we have items, remove the extra spacing from the last item and add bottom padding + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 // Remove some of the last spacing + } + + // Add bottom padding + totalHeight += LEGEND_PADDING + + // Calculate legend dimensions + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + + // Position legend to the right of the diagram with padding + // Add extra padding to ensure it doesn't overlap with diagram elements + legendX := br.X + LEGEND_CORNER_PADDING + // Center vertically using the bounding box, but ensure it's not too close to the top + tl, _ := diagram.BoundingBox() + legendY := tl.Y + (br.Y-tl.Y-totalHeight)/2 + if legendY < tl.Y { + legendY = tl.Y + } + + // Draw legend background with subtle shadow for better visual separation + // Add shadow/outline effect first + shadowEl := d2themes.NewThemableElement("rect", theme) + shadowEl.Fill = "#F7F7FA" + shadowEl.Stroke = "#DEE1EB" + shadowEl.Style = "stroke-width: 1px; filter: drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.1))" + shadowEl.X = float64(legendX) + shadowEl.Y = float64(legendY) + shadowEl.Width = float64(legendWidth) + shadowEl.Height = float64(totalHeight) + shadowEl.Rx = 4 + fmt.Fprint(buf, shadowEl.Render()) + + // Draw legend background + legendEl := d2themes.NewThemableElement("rect", theme) + legendEl.Fill = "#ffffff" + legendEl.Stroke = "#DEE1EB" + legendEl.Style = "stroke-width: 1px" + legendEl.X = float64(legendX) + legendEl.Y = float64(legendY) + legendEl.Width = float64(legendWidth) + legendEl.Height = float64(totalHeight) + legendEl.Rx = 4 + fmt.Fprint(buf, legendEl.Render()) + + // Draw legend title + fmt.Fprintf(buf, `Legend`, + legendX+LEGEND_PADDING, legendY+LEGEND_PADDING+LEGEND_FONT_SIZE, LEGEND_FONT_SIZE+2) + + // Current Y position for drawing items + currentY := legendY + LEGEND_PADDING*2 + LEGEND_FONT_SIZE + + // Draw legend shapes + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + + // Draw shape as icon + shapeIcon, err := renderLegendShapeIcon(s, iconX, iconY, diagramHash, theme) + if err != nil { + return err + } + fmt.Fprint(buf, shapeIcon) + + // Draw label + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + textY := currentY + dims.Height/2 + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(s.Label)) + + currentY += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + } + + // Draw legend connections + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + LEGEND_ICON_SIZE/2 + + // Draw connection as line + connIcon, err := renderLegendConnectionIcon(c, iconX, iconY, theme) + if err != nil { + return err + } + fmt.Fprint(buf, connIcon) + + // Draw label + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + textY := currentY + dims.Height/2 + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(c.Label)) + + currentY += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + } + + return nil +} + +// renderLegendShapeIcon creates a small representation of a shape for the legend +// This reuses the existing shape drawing code +func renderLegendShapeIcon(s d2target.Shape, x, y int, diagramHash string, theme *d2themes.Theme) (string, error) { + // Create a miniature version of the shape + iconShape := s + + // Set the position and size for the legend icon + iconShape.X = x + iconShape.Y = y + iconShape.Width = LEGEND_ICON_SIZE + iconShape.Height = LEGEND_ICON_SIZE + + // Remove the label since we don't want it in the icon + iconShape.Label = "" + + // Create wrappers to capture the rendered SVG + buf := &bytes.Buffer{} + appendixBuf := &bytes.Buffer{} + + // Use the existing drawShape function to render the shape with its proper appearance + _, err := drawShape(buf, appendixBuf, diagramHash, iconShape, nil, theme) + if err != nil { + return "", err + } + + return buf.String(), nil +} + +// renderLegendConnectionIcon creates a small representation of a connection for the legend +func renderLegendConnectionIcon(c d2target.Connection, x, y int, theme *d2themes.Theme) (string, error) { + buf := &bytes.Buffer{} + + // Default stroke width and color + strokeWidth := 2.0 + + // Default color + strokeColor := "#000000" + if c.Stroke != "" { + strokeColor = c.Stroke + } else if theme != nil { + strokeColor = theme.Colors.B4 // Use a theme color for connections + } + + // Draw simple line to represent connection + startX := float64(x) + endX := float64(x + LEGEND_ICON_SIZE) + midY := float64(y) + + fmt.Fprintf(buf, ``, + startX, midY, endX, midY, strokeColor, strokeWidth) + + // Add arrowhead if needed - check if either has an arrowhead that's not "none" + if c.SrcArrow != "none" || c.DstArrow != "none" { + // Draw destination arrowhead (right side) + fmt.Fprintf(buf, ``, + endX-6, midY-3, endX, midY, endX-6, midY+3, strokeColor) + } + + return buf.String(), nil +} + +// renderSimplifiedShape creates a simplified version of a shape for the legend +func renderSimplifiedShape(buf *bytes.Buffer, s d2target.Shape, theme *d2themes.Theme) error { + // Get fill and stroke colors + fillColor := "#E8EAF1" // Default fill color + strokeColor := "#CED3E5" // Default stroke color + + if s.Fill != "" { + fillColor = s.Fill + } else if theme != nil { + fillColor = theme.Colors.B5 // Use a theme color for fills + } + + if s.Stroke != "" { + strokeColor = s.Stroke + } else if theme != nil { + strokeColor = theme.Colors.B4 // Use a theme color for strokes + } + + // Create a simplified shape representation based on shape type + switch s.Type { + case d2target.ShapeCircle: + // Circle + circleEl := d2themes.NewThemableElement("circle", theme) + circleEl.Fill = fillColor + circleEl.Stroke = strokeColor + circleEl.Style = "stroke-width: 1px" + circleEl.Cx = float64(LEGEND_ICON_SIZE) / 2 + circleEl.Cy = float64(LEGEND_ICON_SIZE) / 2 + circleEl.R = float64(LEGEND_ICON_SIZE)/2 - 2 + fmt.Fprint(buf, circleEl.Render()) + + case d2target.ShapeDiamond: + // Diamond shape using a simple polygon + size := float64(LEGEND_ICON_SIZE) + halfSize := size / 2 + + diamondEl := d2themes.NewThemableElement("polygon", theme) + diamondEl.Fill = fillColor + diamondEl.Stroke = strokeColor + diamondEl.Style = "stroke-width: 1px" + diamondEl.Points = fmt.Sprintf("%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f", + halfSize, 2.0, // top + size-2.0, halfSize, // right + halfSize, size-2.0, // bottom + 2.0, halfSize) // left + fmt.Fprint(buf, diamondEl.Render()) + + case d2target.ShapeCylinder: + // Simplified cylinder + fmt.Fprintf(buf, ``) + + // Main rectangle part (body of cylinder) + rectEl := d2themes.NewThemableElement("rect", theme) + rectEl.Fill = fillColor + rectEl.Stroke = strokeColor + rectEl.Style = "stroke-width: 1px" + rectEl.X = 2 + rectEl.Y = 6 + rectEl.Width = float64(LEGEND_ICON_SIZE - 4) + rectEl.Height = float64(LEGEND_ICON_SIZE - 10) + fmt.Fprint(buf, rectEl.Render()) + + // Top ellipse + ellipseEl := d2themes.NewThemableElement("ellipse", theme) + ellipseEl.Fill = fillColor + ellipseEl.Stroke = strokeColor + ellipseEl.Style = "stroke-width: 1px" + ellipseEl.Cx = float64(LEGEND_ICON_SIZE) / 2 + ellipseEl.Cy = 6 + ellipseEl.Rx = float64(LEGEND_ICON_SIZE-4) / 2 + ellipseEl.Ry = 3 + fmt.Fprint(buf, ellipseEl.Render()) + + fmt.Fprintf(buf, ``) + + default: + // Default rectangle for all other shapes + rectEl := d2themes.NewThemableElement("rect", theme) + rectEl.Fill = fillColor + rectEl.Stroke = strokeColor + rectEl.Style = "stroke-width: 1px" + rectEl.X = 2 + rectEl.Y = 2 + rectEl.Width = float64(LEGEND_ICON_SIZE - 4) + rectEl.Height = float64(LEGEND_ICON_SIZE - 4) + + // Apply borderRadius appropriately + if s.Type != d2target.ShapeSquare && s.Type != d2target.ShapeRectangle { + rectEl.Rx = 4 + } + + fmt.Fprint(buf, rectEl.Render()) + } + + return nil +} + +func arrowheadMarkerID(diagramHash string, isTarget bool, connection d2target.Connection) string { + var arrowhead d2target.Arrowhead + if isTarget { + arrowhead = connection.DstArrow + } else { + arrowhead = connection.SrcArrow + } + + return fmt.Sprintf("mk-%s-%s", diagramHash, hash(fmt.Sprintf("%s,%t,%d,%s", + arrowhead, isTarget, connection.StrokeWidth, connection.Stroke, + ))) +} + +func arrowheadMarker(isTarget bool, id string, connection d2target.Connection, inlineTheme *d2themes.Theme) string { + arrowhead := connection.DstArrow + if !isTarget { + arrowhead = connection.SrcArrow + } + strokeWidth := float64(connection.StrokeWidth) + width, height := arrowhead.Dimensions(strokeWidth) + + var path string + switch arrowhead { + case d2target.ArrowArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.Fill = connection.Stroke + polygonEl.ClassName = "connection" + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., 0., + width, height/2, + 0., height, + width/4, height/2, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2, + width, 0., + width*3/4, height/2, + width, height, + ) + } + path = polygonEl.Render() + case d2target.UnfilledTriangleArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.Fill = d2target.BG_COLOR + polygonEl.Stroke = connection.Stroke + polygonEl.ClassName = "connection" + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + inset := strokeWidth / 2 + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + inset, inset, + width-inset, height/2.0, + inset, height-inset, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + width-inset, inset, + inset, height/2.0, + width-inset, height-inset, + ) + } + path = polygonEl.Render() + + case d2target.TriangleArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.Fill = connection.Stroke + polygonEl.ClassName = "connection" + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + 0., 0., + width, height/2.0, + 0., height, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + width, 0., + 0., height/2.0, + width, height, + ) + } + path = polygonEl.Render() + case d2target.LineArrowhead: + polylineEl := d2themes.NewThemableElement("polyline", inlineTheme) + polylineEl.Fill = color.None + polylineEl.ClassName = "connection" + polylineEl.Stroke = connection.Stroke + polylineEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polylineEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + strokeWidth/2, strokeWidth/2, + width-strokeWidth/2, height/2, + strokeWidth/2, height-strokeWidth/2, + ) + } else { + polylineEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + width-strokeWidth/2, strokeWidth/2, + strokeWidth/2, height/2, + width-strokeWidth/2, height-strokeWidth/2, + ) + } + path = polylineEl.Render() + case d2target.FilledDiamondArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2.0, + width/2.0, 0., + width, height/2.0, + width/2.0, height, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2.0, + width/2.0, 0., + width, height/2.0, + width/2.0, height, + ) + } + path = polygonEl.Render() + case d2target.DiamondArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = d2target.BG_COLOR + polygonEl.Stroke = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2.0, + width/2, height/8, + width, height/2.0, + width/2.0, height*0.9, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + width/8, height/2.0, + width*0.6, height/8, + width*1.1, height/2.0, + width*0.6, height*7/8, + ) + } + path = polygonEl.Render() + case d2target.FilledCircleArrowhead: + radius := width / 2 + + circleEl := d2themes.NewThemableElement("circle", inlineTheme) + circleEl.Cy = radius + circleEl.R = radius - strokeWidth/2 + circleEl.Fill = connection.Stroke + circleEl.ClassName = "connection" + circleEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + circleEl.Cx = radius + strokeWidth/2 + } else { + circleEl.Cx = radius - strokeWidth/2 + } + + path = circleEl.Render() + case d2target.CircleArrowhead: + radius := width / 2 + + circleEl := d2themes.NewThemableElement("circle", inlineTheme) + circleEl.Cy = radius + circleEl.R = radius - strokeWidth + circleEl.Fill = d2target.BG_COLOR + circleEl.Stroke = connection.Stroke + circleEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + circleEl.Cx = radius + strokeWidth/2 + } else { + circleEl.Cx = radius - strokeWidth/2 + } + + path = circleEl.Render() + case d2target.FilledBoxArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., 0., + 0., height, + width, height, + width, 0., + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., 0., + 0., height, + width, height, + width, 0., + ) + } + + path = polygonEl.Render() + case d2target.BoxArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = d2target.BG_COLOR + polygonEl.Stroke = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + polygonEl.Style = fmt.Sprintf("%sstroke-linejoin:miter;", polygonEl.Style) + + inset := strokeWidth / 2 + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + inset, inset, + inset, height-inset, + width-inset, height-inset, + width-inset, inset, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + inset, inset, + inset, height-inset, + width-inset, height-inset, + width-inset, inset, + ) + } + path = polygonEl.Render() + case d2target.CfOne, d2target.CfMany, d2target.CfOneRequired, d2target.CfManyRequired: + offset := 3.0 + float64(connection.StrokeWidth)*1.8 + + var modifierEl *d2themes.ThemableElement + if arrowhead == d2target.CfOneRequired || arrowhead == d2target.CfManyRequired { + modifierEl = d2themes.NewThemableElement("path", inlineTheme) + modifierEl.D = fmt.Sprintf("M%f,%f %f,%f", + offset, 0., + offset, height, + ) + modifierEl.Fill = d2target.BG_COLOR + modifierEl.Stroke = connection.Stroke + modifierEl.ClassName = "connection" + modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + } else { + modifierEl = d2themes.NewThemableElement("circle", inlineTheme) + modifierEl.Cx = offset/2.0 + 2.0 + modifierEl.Cy = height / 2.0 + modifierEl.R = offset / 2.0 + modifierEl.Fill = d2target.BG_COLOR + modifierEl.Stroke = connection.Stroke + modifierEl.ClassName = "connection" + modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + } + + childPathEl := d2themes.NewThemableElement("path", inlineTheme) + if arrowhead == d2target.CfMany || arrowhead == d2target.CfManyRequired { + childPathEl.D = fmt.Sprintf("M%f,%f %f,%f M%f,%f %f,%f M%f,%f %f,%f", + width-3.0, height/2.0, + width+offset, height/2.0, + offset+3.0, height/2.0, + width+offset, 0., + offset+3.0, height/2.0, + width+offset, height, + ) + } else { + childPathEl.D = fmt.Sprintf("M%f,%f %f,%f M%f,%f %f,%f", + width-3.0, height/2.0, + width+offset, height/2.0, + offset*2.0, 0., + offset*2.0, height, + ) + } + + gEl := d2themes.NewThemableElement("g", inlineTheme) + if !isTarget { + gEl.Transform = fmt.Sprintf("scale(-1) translate(-%f, -%f)", width, height) + } + gEl.Fill = d2target.BG_COLOR + gEl.Stroke = connection.Stroke + gEl.ClassName = "connection" + gEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + gEl.Content = fmt.Sprintf("%s%s", + modifierEl.Render(), childPathEl.Render(), + ) + path = gEl.Render() + default: + return "" + } + + var refX float64 + refY := height / 2 + switch arrowhead { + case d2target.DiamondArrowhead: + if isTarget { + refX = width - 0.6*strokeWidth + } else { + refX = width/8 + 0.6*strokeWidth + } + width *= 1.1 + default: + if isTarget { + refX = width - 1.5*strokeWidth + } else { + refX = 1.5 * strokeWidth + } + } + + return strings.Join([]string{ + fmt.Sprintf(``, + path, + "", + }, " ") +} + +// compute the (dx, dy) adjustment to apply to get the arrowhead-adjusted end point +func arrowheadAdjustment(start, end *geo.Point, arrowhead d2target.Arrowhead, edgeStrokeWidth, shapeStrokeWidth int) *geo.Point { + distance := (float64(edgeStrokeWidth) + float64(shapeStrokeWidth)) / 2.0 + if arrowhead != d2target.NoArrowhead { + distance += float64(edgeStrokeWidth) + } + + v := geo.NewVector(end.X-start.X, end.Y-start.Y) + return v.Unit().Multiply(-distance).ToPoint() +} + +func getArrowheadAdjustments(connection d2target.Connection, idToShape map[string]d2target.Shape) (srcAdj, dstAdj *geo.Point) { + route := connection.Route + srcShape := idToShape[connection.Src] + dstShape := idToShape[connection.Dst] + + sourceAdjustment := arrowheadAdjustment(route[1], route[0], connection.SrcArrow, connection.StrokeWidth, srcShape.StrokeWidth) + + targetAdjustment := arrowheadAdjustment(route[len(route)-2], route[len(route)-1], connection.DstArrow, connection.StrokeWidth, dstShape.StrokeWidth) + return sourceAdjustment, targetAdjustment +} + +// returns the path's d attribute for the given connection +func pathData(connection d2target.Connection, srcAdj, dstAdj *geo.Point) string { + var path []string + route := connection.Route + + path = append(path, fmt.Sprintf("M %f %f", + route[0].X+srcAdj.X, + route[0].Y+srcAdj.Y, + )) + + if connection.IsCurve { + i := 1 + for ; i < len(route)-3; i += 3 { + path = append(path, fmt.Sprintf("C %f %f %f %f %f %f", + route[i].X, route[i].Y, + route[i+1].X, route[i+1].Y, + route[i+2].X, route[i+2].Y, + )) + } + // final curve target adjustment + path = append(path, fmt.Sprintf("C %f %f %f %f %f %f", + route[i].X, route[i].Y, + route[i+1].X, route[i+1].Y, + route[i+2].X+dstAdj.X, + route[i+2].Y+dstAdj.Y, + )) + } else { + for i := 1; i < len(route)-1; i++ { + prevSource := route[i-1] + prevTarget := route[i] + currTarget := route[i+1] + prevVector := prevSource.VectorTo(prevTarget) + currVector := prevTarget.VectorTo(currTarget) + + dist := geo.EuclideanDistance(prevTarget.X, prevTarget.Y, currTarget.X, currTarget.Y) + + connectionBorderRadius := connection.BorderRadius + units := math.Min(connectionBorderRadius, dist/2) + + prevTranslations := prevVector.Unit().Multiply(units).ToPoint() + currTranslations := currVector.Unit().Multiply(units).ToPoint() + + path = append(path, fmt.Sprintf("L %f %f", + prevTarget.X-prevTranslations.X, + prevTarget.Y-prevTranslations.Y, + )) + + // If the segment length is too small, instead of drawing 2 arcs, just skip this segment and bezier curve to the next one + if units < connectionBorderRadius && i < len(route)-2 { + nextTarget := route[i+2] + nextVector := geo.NewVector(nextTarget.X-currTarget.X, nextTarget.Y-currTarget.Y) + i++ + nextTranslations := nextVector.Unit().Multiply(units).ToPoint() + + // These 2 bezier control points aren't just at the corner -- they are reflected at the corner, which causes the curve to be ~tangent to the corner, + // which matches how the two arcs look + path = append(path, fmt.Sprintf("C %f %f %f %f %f %f", + // Control point + prevTarget.X+prevTranslations.X, + prevTarget.Y+prevTranslations.Y, + // Control point + currTarget.X-nextTranslations.X, + currTarget.Y-nextTranslations.Y, + // Where curve ends + currTarget.X+nextTranslations.X, + currTarget.Y+nextTranslations.Y, + )) + } else { + path = append(path, fmt.Sprintf("S %f %f %f %f", + prevTarget.X, + prevTarget.Y, + prevTarget.X+currTranslations.X, + prevTarget.Y+currTranslations.Y, + )) + } + } + + lastPoint := route[len(route)-1] + path = append(path, fmt.Sprintf("L %f %f", + lastPoint.X+dstAdj.X, + lastPoint.Y+dstAdj.Y, + )) + } + + return strings.Join(path, " ") +} + +func makeLabelMask(labelTL *geo.Point, width, height int, opacity float64) string { + fill := "black" + if opacity != 1 { + fill = fmt.Sprintf("rgba(0,0,0,%.2f)", opacity) + } + return fmt.Sprintf(``, + labelTL.X, labelTL.Y, + width, + height, + fill, + ) +} + +func drawConnection(writer io.Writer, diagramHash string, connection d2target.Connection, markers map[string]struct{}, idToShape map[string]d2target.Shape, jsRunner jsrunner.JSRunner, inlineTheme *d2themes.Theme) (labelMask string, _ error) { + opacityStyle := "" + if connection.Opacity != 1.0 { + opacityStyle = fmt.Sprintf(" style='opacity:%f'", connection.Opacity) + } + + classes := []string{base64.URLEncoding.EncodeToString([]byte(svg.EscapeText(connection.ID)))} + classes = append(classes, connection.Classes...) + classStr := fmt.Sprintf(` class="%s"`, strings.Join(classes, " ")) + + fmt.Fprintf(writer, ``, classStr, opacityStyle) + var markerStart string + if connection.SrcArrow != d2target.NoArrowhead { + id := arrowheadMarkerID(diagramHash, false, connection) + if _, in := markers[id]; !in { + marker := arrowheadMarker(false, id, connection, inlineTheme) + if marker == "" { + panic(fmt.Sprintf("received empty arrow head marker for: %#v", connection)) + } + fmt.Fprint(writer, marker) + markers[id] = struct{}{} + } + markerStart = fmt.Sprintf(`marker-start="url(#%s)" `, id) + } + + var markerEnd string + if connection.DstArrow != d2target.NoArrowhead { + id := arrowheadMarkerID(diagramHash, true, connection) + if _, in := markers[id]; !in { + marker := arrowheadMarker(true, id, connection, inlineTheme) + if marker == "" { + panic(fmt.Sprintf("received empty arrow head marker for: %#v", connection)) + } + fmt.Fprint(writer, marker) + markers[id] = struct{}{} + } + markerEnd = fmt.Sprintf(`marker-end="url(#%s)" `, id) + } + + if connection.Icon != nil { + iconPos := connection.GetIconPosition() + if iconPos != nil { + fmt.Fprintf(writer, ``, + html.EscapeString(connection.Icon.String()), + iconPos.X, + iconPos.Y, + d2target.DEFAULT_ICON_SIZE, + d2target.DEFAULT_ICON_SIZE, + ) + } + } + + var labelTL *geo.Point + if connection.Label != "" { + labelTL = connection.GetLabelTopLeft() + labelTL.X = math.Round(labelTL.X) + labelTL.Y = math.Round(labelTL.Y) + + maskTL := labelTL.Copy() + width := connection.LabelWidth + height := connection.LabelHeight + + if connection.Icon != nil { + width += d2target.CONNECTION_ICON_LABEL_GAP + d2target.DEFAULT_ICON_SIZE + maskTL.X -= float64(d2target.CONNECTION_ICON_LABEL_GAP + d2target.DEFAULT_ICON_SIZE) + } + + if label.FromString(connection.LabelPosition).IsOnEdge() { + labelMask = makeLabelMask(maskTL, width, height, 1) + } else { + labelMask = makeLabelMask(maskTL, width, height, 0.75) + } + } else if connection.Icon != nil { + iconPos := connection.GetIconPosition() + if iconPos != nil { + maskTL := &geo.Point{ + X: iconPos.X, + Y: iconPos.Y, + } + if label.FromString(connection.IconPosition).IsOnEdge() { + labelMask = makeLabelMask(maskTL, d2target.DEFAULT_ICON_SIZE, d2target.DEFAULT_ICON_SIZE, 1) + } else { + labelMask = makeLabelMask(maskTL, d2target.DEFAULT_ICON_SIZE, d2target.DEFAULT_ICON_SIZE, 0.75) + } + } + } + + srcAdj, dstAdj := getArrowheadAdjustments(connection, idToShape) + path := pathData(connection, srcAdj, dstAdj) + mask := fmt.Sprintf(`mask="url(#%s)"`, diagramHash) + + if jsRunner != nil { + out, err := d2sketch.Connection(jsRunner, connection, path, mask) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + + // render sketch arrowheads separately + arrowPaths, err := d2sketch.Arrowheads(jsRunner, connection, srcAdj, dstAdj) + if err != nil { + return "", err + } + fmt.Fprint(writer, arrowPaths) + } else { + animatedClass := "" + if connection.Animated { + animatedClass = " animated-connection" + } + + // If connection is animated and bidirectional + if connection.Animated && ((connection.DstArrow == d2target.NoArrowhead && connection.SrcArrow == d2target.NoArrowhead) || (connection.DstArrow != d2target.NoArrowhead && connection.SrcArrow != d2target.NoArrowhead)) { + // There is no pure CSS way to animate bidirectional connections in two directions, so we split it up + path1, path2, err := svg.SplitPath(path, 0.5) + + if err != nil { + return "", err + } + + pathEl1 := d2themes.NewThemableElement("path", inlineTheme) + pathEl1.D = path1 + pathEl1.Fill = color.None + pathEl1.Stroke = connection.Stroke + pathEl1.ClassName = fmt.Sprintf("connection%s", animatedClass) + pathEl1.Style = connection.CSSStyle() + pathEl1.Style += "animation-direction: reverse;" + pathEl1.Attributes = fmt.Sprintf("%s%s", markerStart, mask) + fmt.Fprint(writer, pathEl1.Render()) + + pathEl2 := d2themes.NewThemableElement("path", inlineTheme) + pathEl2.D = path2 + pathEl2.Fill = color.None + pathEl2.Stroke = connection.Stroke + pathEl2.ClassName = fmt.Sprintf("connection%s", animatedClass) + pathEl2.Style = connection.CSSStyle() + pathEl2.Attributes = fmt.Sprintf("%s%s", markerEnd, mask) + fmt.Fprint(writer, pathEl2.Render()) + } else { + pathEl := d2themes.NewThemableElement("path", inlineTheme) + pathEl.D = path + pathEl.Fill = color.None + pathEl.Stroke = connection.Stroke + pathEl.ClassName = fmt.Sprintf("connection%s", animatedClass) + pathEl.Style = connection.CSSStyle() + pathEl.Attributes = fmt.Sprintf("%s%s%s", markerStart, markerEnd, mask) + fmt.Fprint(writer, pathEl.Render()) + } + } + + if connection.Label != "" { + fontClass := "text" + if connection.FontFamily == "mono" { + fontClass = "text-mono" + } + if connection.Bold { + fontClass += "-bold" + } else if connection.Italic { + fontClass += "-italic" + } + if connection.Underline { + fontClass += " text-underline" + } + if connection.Fill != color.Empty { + rectEl := d2themes.NewThemableElement("rect", inlineTheme) + rectEl.Rx = 10 + rectEl.X, rectEl.Y = labelTL.X-4, labelTL.Y-3 + rectEl.Width, rectEl.Height = float64(connection.LabelWidth)+8, float64(connection.LabelHeight)+6 + rectEl.Fill = connection.Fill + fmt.Fprint(writer, rectEl.Render()) + } + + textEl := d2themes.NewThemableElement("text", inlineTheme) + textEl.X = labelTL.X + float64(connection.LabelWidth)/2 + textEl.Y = labelTL.Y + float64(connection.FontSize) + textEl.ClassName = fontClass + textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", connection.FontSize) + textEl.Content = RenderText(connection.Label, textEl.X, float64(connection.LabelHeight)) + + if connection.Link != "" { + textEl.ClassName += " text-underline text-link" + + fmt.Fprintf(writer, ``, svg.EscapeText(connection.Link)) + } else { + textEl.Fill = connection.GetFontColor() + } + + fmt.Fprint(writer, textEl.Render()) + + if connection.Link != "" { + fmt.Fprintf(writer, "") + } + } + + if connection.SrcLabel != nil && connection.SrcLabel.Label != "" { + fmt.Fprint(writer, renderArrowheadLabel(connection, connection.SrcLabel.Label, false, inlineTheme)) + } + if connection.DstLabel != nil && connection.DstLabel.Label != "" { + fmt.Fprint(writer, renderArrowheadLabel(connection, connection.DstLabel.Label, true, inlineTheme)) + } + fmt.Fprintf(writer, ``) + return +} + +func renderArrowheadLabel(connection d2target.Connection, text string, isDst bool, inlineTheme *d2themes.Theme) string { + var width, height float64 + if isDst { + width = float64(connection.DstLabel.LabelWidth) + height = float64(connection.DstLabel.LabelHeight) + } else { + width = float64(connection.SrcLabel.LabelWidth) + height = float64(connection.SrcLabel.LabelHeight) + } + + labelTL := connection.GetArrowheadLabelPosition(isDst) + + // svg text is positioned with the center of its baseline + baselineCenter := geo.Point{ + X: labelTL.X + width/2., + Y: labelTL.Y + float64(connection.FontSize), + } + + textEl := d2themes.NewThemableElement("text", inlineTheme) + textEl.X = baselineCenter.X + textEl.Y = baselineCenter.Y + textEl.Fill = d2target.FG_COLOR + if isDst { + if connection.DstLabel.Color != "" { + textEl.Fill = connection.DstLabel.Color + } + } else { + if connection.SrcLabel.Color != "" { + textEl.Fill = connection.SrcLabel.Color + } + } + textEl.ClassName = "text-italic" + textEl.Style = fmt.Sprintf("text-anchor:middle;font-size:%vpx", connection.FontSize) + textEl.Content = RenderText(text, textEl.X, height) + return textEl.Render() +} + +func renderOval(tl *geo.Point, width, height float64, fill, fillPattern, stroke, style string, inlineTheme *d2themes.Theme) string { + el := d2themes.NewThemableElement("ellipse", inlineTheme) + el.Rx = width / 2 + el.Ry = height / 2 + el.Cx = tl.X + el.Rx + el.Cy = tl.Y + el.Ry + el.Fill, el.Stroke = fill, stroke + el.FillPattern = fillPattern + el.ClassName = "shape" + el.Style = style + return el.Render() +} + +func renderDoubleOval(tl *geo.Point, width, height float64, fill, fillStroke, stroke, style string, inlineTheme *d2themes.Theme) string { + var innerTL *geo.Point = tl.AddVector(geo.NewVector(d2target.INNER_BORDER_OFFSET, d2target.INNER_BORDER_OFFSET)) + return renderOval(tl, width, height, fill, fillStroke, stroke, style, inlineTheme) + renderOval(innerTL, width-10, height-10, fill, "", stroke, style, inlineTheme) +} + +func defineGradients(writer io.Writer, cssGradient string) { + gradient, _ := color.ParseGradient(cssGradient) + fmt.Fprint(writer, fmt.Sprintf(`%s`, color.GradientToSVG(gradient))) +} + +func defineShadowFilter(writer io.Writer) { + fmt.Fprint(writer, ` + + + + + + + +`) +} + +func render3DRect(diagramHash string, targetShape d2target.Shape, inlineTheme *d2themes.Theme) string { + moveTo := func(p d2target.Point) string { + return fmt.Sprintf("M%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + lineTo := func(p d2target.Point) string { + return fmt.Sprintf("L%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + + // draw border all in one path to prevent overlapping sections + var borderSegments []string + borderSegments = append(borderSegments, + moveTo(d2target.Point{X: 0, Y: 0}), + ) + for _, v := range []d2target.Point{ + {X: d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width, Y: targetShape.Height}, + {X: 0, Y: targetShape.Height}, + {X: 0, Y: 0}, + {X: targetShape.Width, Y: 0}, + {X: targetShape.Width, Y: targetShape.Height}, + } { + borderSegments = append(borderSegments, lineTo(v)) + } + // move to top right to draw last segment without overlapping + borderSegments = append(borderSegments, + moveTo(d2target.Point{X: targetShape.Width, Y: 0}), + ) + borderSegments = append(borderSegments, + lineTo(d2target.Point{X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}), + ) + border := d2themes.NewThemableElement("path", inlineTheme) + border.D = strings.Join(borderSegments, " ") + border.Fill = color.None + _, borderStroke := d2themes.ShapeTheme(targetShape) + border.Stroke = borderStroke + borderStyle := targetShape.CSSStyle() + border.Style = borderStyle + renderedBorder := border.Render() + + // create mask from border stroke, to cut away from the shape fills + maskID := fmt.Sprintf("border-mask-%v-%v", diagramHash, svg.EscapeText(targetShape.ID)) + borderMask := strings.Join([]string{ + fmt.Sprintf(``, + maskID, targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + strings.Join(borderSegments, ""), borderStyle), + }, "\n") + + // render the main rectangle without stroke and the border mask + mainShape := d2themes.NewThemableElement("rect", inlineTheme) + mainShape.X = float64(targetShape.Pos.X) + mainShape.Y = float64(targetShape.Pos.Y) + mainShape.Width = float64(targetShape.Width) + mainShape.Height = float64(targetShape.Height) + mainShape.SetMaskUrl(maskID) + mainShapeFill, _ := d2themes.ShapeTheme(targetShape) + mainShape.Fill = mainShapeFill + mainShape.FillPattern = targetShape.FillPattern + mainShape.Stroke = color.None + mainShape.Style = targetShape.CSSStyle() + mainShapeRendered := mainShape.Render() + + // render the side shapes in the darkened color without stroke and the border mask + var sidePoints []string + for _, v := range []d2target.Point{ + {X: 0, Y: 0}, + {X: d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width, Y: targetShape.Height}, + {X: targetShape.Width, Y: 0}, + } { + sidePoints = append(sidePoints, + fmt.Sprintf("%d,%d", v.X+targetShape.Pos.X, v.Y+targetShape.Pos.Y), + ) + } + darkerColor, err := color.Darken(targetShape.Fill) + if err != nil { + darkerColor = targetShape.Fill + } + sideShape := d2themes.NewThemableElement("polygon", inlineTheme) + sideShape.Fill = darkerColor + sideShape.Points = strings.Join(sidePoints, " ") + sideShape.SetMaskUrl(maskID) + sideShape.Style = targetShape.CSSStyle() + renderedSides := sideShape.Render() + + return borderMask + mainShapeRendered + renderedSides + renderedBorder +} + +func render3DHexagon(diagramHash string, targetShape d2target.Shape, inlineTheme *d2themes.Theme) string { + moveTo := func(p d2target.Point) string { + return fmt.Sprintf("M%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + lineTo := func(p d2target.Point) string { + return fmt.Sprintf("L%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + scale := func(n int, f float64) int { + return int(float64(n) * f) + } + halfYFactor := 43.6 / 87.3 + + // draw border all in one path to prevent overlapping sections + var borderSegments []string + // start from the top-left + borderSegments = append(borderSegments, + moveTo(d2target.Point{X: scale(targetShape.Width, 0.25), Y: 0}), + ) + Y_OFFSET := d2target.THREE_DEE_OFFSET / 2 + // The following iterates through the sidepoints in clockwise order from top-left, then the main points in clockwise order from bottom-right + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.25) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: scale(targetShape.Height, halfYFactor) - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + {X: scale(targetShape.Width, 0.25), Y: targetShape.Height}, + {X: 0, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.25), Y: 0}, + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + } { + borderSegments = append(borderSegments, lineTo(v)) + } + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + } { + borderSegments = append(borderSegments, moveTo(v)) + borderSegments = append(borderSegments, lineTo( + d2target.Point{X: v.X + d2target.THREE_DEE_OFFSET, Y: v.Y - Y_OFFSET}, + )) + } + border := d2themes.NewThemableElement("path", inlineTheme) + border.D = strings.Join(borderSegments, " ") + border.Fill = color.None + _, borderStroke := d2themes.ShapeTheme(targetShape) + border.Stroke = borderStroke + borderStyle := targetShape.CSSStyle() + border.Style = borderStyle + renderedBorder := border.Render() + + var mainPoints []string + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.25), Y: 0}, + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + {X: scale(targetShape.Width, 0.25), Y: targetShape.Height}, + {X: 0, Y: scale(targetShape.Height, halfYFactor)}, + } { + mainPoints = append(mainPoints, + fmt.Sprintf("%d,%d", v.X+targetShape.Pos.X, v.Y+targetShape.Pos.Y), + ) + } + + mainPointsPoly := strings.Join(mainPoints, " ") + // create mask from border stroke, to cut away from the shape fills + maskID := fmt.Sprintf("border-mask-%v-%v", diagramHash, svg.EscapeText(targetShape.ID)) + borderMask := strings.Join([]string{ + fmt.Sprintf(``, + maskID, targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + strings.Join(borderSegments, ""), borderStyle), + }, "\n") + // render the main hexagon without stroke and the border mask + mainShape := d2themes.NewThemableElement("polygon", inlineTheme) + mainShape.X = float64(targetShape.Pos.X) + mainShape.Y = float64(targetShape.Pos.Y) + mainShape.Points = mainPointsPoly + mainShape.SetMaskUrl(maskID) + mainShapeFill, _ := d2themes.ShapeTheme(targetShape) + mainShape.FillPattern = targetShape.FillPattern + mainShape.Fill = mainShapeFill + mainShape.Stroke = color.None + mainShape.Style = targetShape.CSSStyle() + mainShapeRendered := mainShape.Render() + + // render the side shapes in the darkened color without stroke and the border mask + var sidePoints []string + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.25) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: scale(targetShape.Height, halfYFactor) - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: scale(targetShape.Width, 0.25), Y: 0}, + } { + sidePoints = append(sidePoints, + fmt.Sprintf("%d,%d", v.X+targetShape.Pos.X, v.Y+targetShape.Pos.Y), + ) + } + // TODO make darker color part of the theme? or just keep this bypass + darkerColor, err := color.Darken(targetShape.Fill) + if err != nil { + darkerColor = targetShape.Fill + } + sideShape := d2themes.NewThemableElement("polygon", inlineTheme) + sideShape.Fill = darkerColor + sideShape.Points = strings.Join(sidePoints, " ") + sideShape.SetMaskUrl(maskID) + sideShape.Style = targetShape.CSSStyle() + renderedSides := sideShape.Render() + + return borderMask + mainShapeRendered + renderedSides + renderedBorder +} + +func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape d2target.Shape, jsRunner jsrunner.JSRunner, inlineTheme *d2themes.Theme) (labelMask string, err error) { + closingTag := "" + if targetShape.Link != "" { + + fmt.Fprintf(writer, ``, svg.EscapeText(targetShape.Link)) + closingTag += "" + } + // Opacity is a unique style, it applies to everything for a shape + opacityStyle := "" + if targetShape.Opacity != 1.0 { + opacityStyle = fmt.Sprintf(" style='opacity:%f'", targetShape.Opacity) + } + + // this clipPath must be defined outside `g` element + if targetShape.BorderRadius != 0 && (targetShape.Type == d2target.ShapeClass || targetShape.Type == d2target.ShapeSQLTable) { + fmt.Fprint(writer, clipPathForBorderRadius(diagramHash, targetShape)) + } + classes := []string{base64.URLEncoding.EncodeToString([]byte(svg.EscapeText(targetShape.ID)))} + if targetShape.Animated { + classes = append(classes, "animated-shape") + } + classes = append(classes, targetShape.Classes...) + classStr := fmt.Sprintf(` class="%s"`, strings.Join(classes, " ")) + fmt.Fprintf(writer, ``, classStr, opacityStyle) + tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y)) + width := float64(targetShape.Width) + height := float64(targetShape.Height) + fill, stroke := d2themes.ShapeTheme(targetShape) + style := targetShape.CSSStyle() + shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[targetShape.Type] + + s := shape.NewShape(shapeType, geo.NewBox(tl, width, height)) + if shapeType == shape.CLOUD_TYPE && targetShape.ContentAspectRatio != nil { + s.SetInnerBoxAspectRatio(*targetShape.ContentAspectRatio) + } + + var shadowAttr string + if targetShape.Shadow { + switch targetShape.Type { + case d2target.ShapeText, + d2target.ShapeCode, + d2target.ShapeClass, + d2target.ShapeSQLTable: + default: + shadowAttr = `filter="url(#shadow-filter)" ` + } + } + + var blendModeClass string + if targetShape.Blend { + blendModeClass = " blend" + } + + fmt.Fprintf(writer, ``, blendModeClass, shadowAttr) + + var multipleTL *geo.Point + if targetShape.Multiple { + multipleTL = tl.AddVector(multipleOffset) + } + + switch targetShape.Type { + case d2target.ShapeClass: + if jsRunner != nil { + out, err := d2sketch.Class(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + drawClass(writer, diagramHash, targetShape, inlineTheme) + } + addAppendixItems(appendixWriter, diagramHash, targetShape, s) + fmt.Fprint(writer, ``) + fmt.Fprint(writer, closingTag) + return labelMask, nil + case d2target.ShapeSQLTable: + if jsRunner != nil { + out, err := d2sketch.Table(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + drawTable(writer, diagramHash, targetShape, inlineTheme) + } + addAppendixItems(appendixWriter, diagramHash, targetShape, s) + fmt.Fprint(writer, ``) + fmt.Fprint(writer, closingTag) + return labelMask, nil + case d2target.ShapeOval: + if targetShape.DoubleBorder { + if targetShape.Multiple { + fmt.Fprint(writer, renderDoubleOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme)) + } + if jsRunner != nil { + out, err := d2sketch.DoubleOval(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + fmt.Fprint(writer, renderDoubleOval(tl, width, height, fill, targetShape.FillPattern, stroke, style, inlineTheme)) + } + } else { + if targetShape.Multiple { + fmt.Fprint(writer, renderOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme)) + } + if jsRunner != nil { + out, err := d2sketch.Oval(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + fmt.Fprint(writer, renderOval(tl, width, height, fill, targetShape.FillPattern, stroke, style, inlineTheme)) + } + } + + case d2target.ShapeImage: + el := d2themes.NewThemableElement("image", inlineTheme) + el.X = float64(targetShape.Pos.X) + el.Y = float64(targetShape.Pos.Y) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Href = html.EscapeString(targetShape.Icon.String()) + el.Fill = fill + el.Stroke = stroke + el.Style = style + fmt.Fprint(writer, el.Render()) + + // TODO should standardize "" to rectangle + case d2target.ShapeRectangle, d2target.ShapeSequenceDiagram, d2target.ShapeHierarchy, "": + borderRadius := math.MaxFloat64 + if targetShape.BorderRadius != 0 { + borderRadius = float64(targetShape.BorderRadius) + } + if targetShape.ThreeDee { + fmt.Fprint(writer, render3DRect(diagramHash, targetShape, inlineTheme)) + } else { + if !targetShape.DoubleBorder { + if targetShape.Multiple { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + 10) + el.Y = float64(targetShape.Pos.Y - 10) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + if jsRunner != nil { + out, err := d2sketch.Rect(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X) + el.Y = float64(targetShape.Pos.Y) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + } else { + if targetShape.Multiple { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + 10) + el.Y = float64(targetShape.Pos.Y - 10) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + + el = d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + 10 + d2target.INNER_BORDER_OFFSET) + el.Y = float64(targetShape.Pos.Y - 10 + d2target.INNER_BORDER_OFFSET) + el.Width = float64(targetShape.Width - 2*d2target.INNER_BORDER_OFFSET) + el.Height = float64(targetShape.Height - 2*d2target.INNER_BORDER_OFFSET) + el.Fill = fill + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + if jsRunner != nil { + out, err := d2sketch.DoubleRect(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X) + el.Y = float64(targetShape.Pos.Y) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + + el = d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + d2target.INNER_BORDER_OFFSET) + el.Y = float64(targetShape.Pos.Y + d2target.INNER_BORDER_OFFSET) + el.Width = float64(targetShape.Width - 2*d2target.INNER_BORDER_OFFSET) + el.Height = float64(targetShape.Height - 2*d2target.INNER_BORDER_OFFSET) + el.Fill = "transparent" + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + } + } + case d2target.ShapeHexagon: + if targetShape.ThreeDee { + fmt.Fprint(writer, render3DHexagon(diagramHash, targetShape, inlineTheme)) + } else { + if targetShape.Multiple { + multiplePathData := shape.NewShape(shapeType, geo.NewBox(multipleTL, width, height)).GetSVGPathData() + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.Stroke = stroke + el.Style = style + for _, pathData := range multiplePathData { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + + if jsRunner != nil { + out, err := d2sketch.Paths(jsRunner, targetShape, s.GetSVGPathData()) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + for _, pathData := range s.GetSVGPathData() { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + } + case d2target.ShapeText, d2target.ShapeCode: + default: + if targetShape.Multiple { + multiplePathData := shape.NewShape(shapeType, geo.NewBox(multipleTL, width, height)).GetSVGPathData() + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.Stroke = stroke + el.Style = style + for _, pathData := range multiplePathData { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + + if jsRunner != nil { + out, err := d2sketch.Paths(jsRunner, targetShape, s.GetSVGPathData()) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + for _, pathData := range s.GetSVGPathData() { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + } + + // // to examine shape's innerBox + // innerBox := s.GetInnerBox() + // el := d2themes.NewThemableElement("rect", inlineTheme) + // el.X = float64(innerBox.TopLeft.X) + // el.Y = float64(innerBox.TopLeft.Y) + // el.Width = float64(innerBox.Width) + // el.Height = float64(innerBox.Height) + // el.Style = "fill:rgba(255,0,0,0.5);" + // fmt.Fprint(writer, el.Render()) + + // Closes the class=shape + fmt.Fprint(writer, ``) + + if targetShape.Icon != nil && targetShape.Type != d2target.ShapeImage && targetShape.Opacity != 0 { + iconPosition := label.FromString(targetShape.IconPosition) + var box *geo.Box + if iconPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + iconSize := d2target.GetIconSize(box, targetShape.IconPosition) + + tl := iconPosition.GetPointOnBox(box, label.PADDING, float64(iconSize), float64(iconSize)) + + fmt.Fprintf(writer, ``, + html.EscapeString(targetShape.Icon.String()), + tl.X, + tl.Y, + iconSize, + iconSize, + ) + } + + if targetShape.Label != "" && targetShape.Opacity != 0 { + labelPosition := label.FromString(targetShape.LabelPosition) + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox().Copy() + // if it is 3d/multiple, place label using box around those + if targetShape.ThreeDee { + offsetY := d2target.THREE_DEE_OFFSET + if targetShape.Type == d2target.ShapeHexagon { + offsetY /= 2 + } + box.TopLeft.Y -= float64(offsetY) + box.Height += float64(offsetY) + box.Width += d2target.THREE_DEE_OFFSET + } else if targetShape.Multiple { + box.TopLeft.Y -= d2target.MULTIPLE_OFFSET + box.Height += d2target.MULTIPLE_OFFSET + box.Width += d2target.MULTIPLE_OFFSET + } + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + labelMask = makeLabelMask(labelTL, targetShape.LabelWidth, targetShape.LabelHeight, 0.75) + + fontClass := "text" + if targetShape.FontFamily == "mono" { + fontClass = "text-mono" + } + if targetShape.Bold { + fontClass += "-bold" + } else if targetShape.Italic { + fontClass += "-italic" + } + if targetShape.Underline { + fontClass += " text-underline" + } + + if targetShape.Language == "latex" { + render, err := d2latex.Render(targetShape.Label) + if err != nil { + return labelMask, err + } + gEl := d2themes.NewThemableElement("g", inlineTheme) + + labelPosition := label.FromString(targetShape.LabelPosition) + if labelPosition == label.Unset { + labelPosition = label.InsideMiddleCenter + } + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + gEl.SetTranslate(labelTL.X, labelTL.Y) + + gEl.Color = targetShape.Stroke + gEl.Content = render + fmt.Fprint(writer, gEl.Render()) + } else if targetShape.Language == "markdown" { + render, err := textmeasure.RenderMarkdown(targetShape.Label) + if err != nil { + return labelMask, err + } + + labelPosition := label.FromString(targetShape.LabelPosition) + if labelPosition == label.Unset { + labelPosition = label.InsideMiddleCenter + } + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + + fmt.Fprintf(writer, ``, + labelTL.X, labelTL.Y, targetShape.LabelWidth, targetShape.LabelHeight, + ) + + // we need the self closing form in this svg/xhtml context + render = strings.ReplaceAll(render, "
    ", "
    ") + + mdEl := d2themes.NewThemableElement("div", inlineTheme) + mdEl.ClassName = "md" + mdEl.Content = render + + // We have to set with styles since within foreignObject, we're in html + // land and not SVG attributes + var styles []string + if targetShape.FontSize != textmeasure.MarkdownFontSize { + styles = append(styles, fmt.Sprintf("font-size:%vpx", targetShape.FontSize)) + } + if targetShape.Fill != "" && targetShape.Fill != "transparent" { + styles = append(styles, fmt.Sprintf(`background-color:%s`, targetShape.Fill)) + } + if !color.IsThemeColor(targetShape.Color) { + styles = append(styles, fmt.Sprintf(`color:%s`, targetShape.Color)) + } else { + styles = append(styles, fmt.Sprintf(`color:%s`, d2themes.ResolveThemeColor(*inlineTheme, targetShape.Color))) + } + + mdEl.Style = strings.Join(styles, ";") + + fmt.Fprint(writer, mdEl.Render()) + fmt.Fprint(writer, `
    `) + } else if targetShape.Language != "" { + lexer := lexers.Get(targetShape.Language) + if lexer == nil { + lexer = lexers.Fallback + } + for _, isLight := range []bool{true, false} { + theme := "github" + if !isLight { + theme = "catppuccin-mocha" + } + style := styles.Get(theme) + if style == nil { + return labelMask, errors.New(`code snippet style "github" not found`) + } + formatter := formatters.Get("svg") + if formatter == nil { + return labelMask, errors.New(`code snippet formatter "svg" not found`) + } + iterator, err := lexer.Tokenise(nil, targetShape.Label) + if err != nil { + return labelMask, err + } + + svgStyles := styleToSVG(style) + class := "light-code" + if !isLight { + class = "dark-code" + } + var fontSize string + if targetShape.FontSize != d2fonts.FONT_SIZE_M { + fontSize = fmt.Sprintf(` style="font-size:%v"`, targetShape.FontSize) + } + fmt.Fprintf(writer, ``, + box.TopLeft.X, box.TopLeft.Y, class, fontSize, + ) + rectEl := d2themes.NewThemableElement("rect", inlineTheme) + rectEl.Width = float64(targetShape.Width) + rectEl.Height = float64(targetShape.Height) + rectEl.Stroke = targetShape.Stroke + rectEl.ClassName = "shape" + rectEl.Style = fmt.Sprintf(`fill:%s;stroke-width:%d;`, + style.Get(chroma.Background).Background.String(), + targetShape.StrokeWidth, + ) + fmt.Fprint(writer, rectEl.Render()) + // Padding = 0.5em + padding := float64(targetShape.FontSize) / 2. + fmt.Fprintf(writer, ``, padding, padding) + + lineHeight := textmeasure.CODE_LINE_HEIGHT + for index, tokens := range chroma.SplitTokensIntoLines(iterator.Tokens()) { + fmt.Fprintf(writer, "", 1+float64(index)*lineHeight) + for _, token := range tokens { + text := svgEscaper.Replace(token.String()) + attr := styleAttr(svgStyles, token.Type) + if attr != "" { + text = fmt.Sprintf("%s", attr, text) + } + fmt.Fprint(writer, text) + } + fmt.Fprint(writer, "") + } + fmt.Fprint(writer, "") + } + } else { + if targetShape.LabelFill != "" { + rectEl := d2themes.NewThemableElement("rect", inlineTheme) + rectEl.X = labelTL.X + rectEl.Y = labelTL.Y + rectEl.Width = float64(targetShape.LabelWidth) + rectEl.Height = float64(targetShape.LabelHeight) + rectEl.Fill = targetShape.LabelFill + fmt.Fprint(writer, rectEl.Render()) + } + textEl := d2themes.NewThemableElement("text", inlineTheme) + textEl.X = labelTL.X + float64(targetShape.LabelWidth)/2 + // text is vertically positioned at its baseline which is at labelTL+FontSize + textEl.Y = labelTL.Y + float64(targetShape.FontSize) + textEl.Fill = targetShape.GetFontColor() + textEl.ClassName = fontClass + textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", targetShape.FontSize) + textEl.Content = RenderText(targetShape.Label, textEl.X, float64(targetShape.LabelHeight)) + fmt.Fprint(writer, textEl.Render()) + if targetShape.Blend { + labelMask = makeLabelMask(labelTL, targetShape.LabelWidth, targetShape.LabelHeight-d2graph.INNER_LABEL_PADDING, 1) + } + } + } + if targetShape.Tooltip != "" { + fmt.Fprintf(writer, `%s`, + svg.EscapeText(targetShape.Tooltip), + ) + } + addAppendixItems(appendixWriter, diagramHash, targetShape, s) + + fmt.Fprint(writer, closingTag) + return labelMask, nil +} + +func addAppendixItems(writer io.Writer, diagramHash string, targetShape d2target.Shape, s shape.Shape) { + var p1, p2 *geo.Point + if targetShape.Tooltip != "" || targetShape.Link != "" { + bothIcons := targetShape.Tooltip != "" && targetShape.Link != "" + corner := geo.NewPoint(float64(targetShape.Pos.X+targetShape.Width), float64(targetShape.Pos.Y)) + center := geo.NewPoint( + float64(targetShape.Pos.X)+float64(targetShape.Width)/2., + float64(targetShape.Pos.Y)+float64(targetShape.Height)/2., + ) + offset := geo.Vector{-2 * appendixIconRadius, 0} + var leftOnShape bool + switch s.GetType() { + case shape.STEP_TYPE, shape.HEXAGON_TYPE, shape.QUEUE_TYPE, shape.PAGE_TYPE: + // trace straight left for these + center.Y = float64(targetShape.Pos.Y) + case shape.PACKAGE_TYPE: + // trace straight down + center.X = float64(targetShape.Pos.X + targetShape.Width) + case shape.CIRCLE_TYPE, shape.OVAL_TYPE, shape.DIAMOND_TYPE, + shape.PERSON_TYPE, shape.CLOUD_TYPE, shape.CYLINDER_TYPE: + if bothIcons { + leftOnShape = true + corner = corner.AddVector(offset) + } + } + v1 := center.VectorTo(corner) + p1 = shape.TraceToShapeBorder(s, corner, corner.AddVector(v1)) + if bothIcons { + if leftOnShape { + // these shapes should have p1 on shape border + p2 = p1.AddVector(offset.Reverse()) + p1, p2 = p2, p1 + } else { + p2 = p1.AddVector(offset) + } + } + } + + if targetShape.Tooltip != "" { + x := int(math.Ceil(p1.X)) + y := int(math.Ceil(p1.Y)) + + fmt.Fprintf(writer, `%s%s`, + x-appendixIconRadius, + y-appendixIconRadius, + svg.EscapeText(targetShape.Tooltip), + fmt.Sprintf(TooltipIcon, diagramHash, svg.SVGID(targetShape.ID)), + ) + } + if targetShape.Link != "" { + if p2 == nil { + p2 = p1 + } + x := int(math.Ceil(p2.X)) + y := int(math.Ceil(p2.Y)) + fmt.Fprintf(writer, `%s`, + x-appendixIconRadius, + y-appendixIconRadius, + fmt.Sprintf(LinkIcon, diagramHash, svg.SVGID(targetShape.ID)), + ) + } +} + +func RenderText(text string, x, height float64) string { + if !strings.Contains(text, "\n") { + return svg.EscapeText(text) + } + rendered := []string{} + lines := strings.Split(text, "\n") + for i, line := range lines { + dy := height / float64(len(lines)) + if i == 0 { + dy = 0 + } + escaped := svg.EscapeText(line) + if escaped == "" { + // if there are multiple newlines in a row we still need text for the tspan to render + escaped = " " + } + rendered = append(rendered, fmt.Sprintf(`%s`, x, dy, escaped)) + } + return strings.Join(rendered, "") +} + +func EmbedFonts(buf *bytes.Buffer, diagramHash, source string, fontFamily *d2fonts.FontFamily, corpus string) { + fmt.Fprint(buf, ``) +} + +func appendOnTrigger(buf *bytes.Buffer, source string, triggers []string, newContent string) { + for _, trigger := range triggers { + if strings.Contains(source, trigger) { + fmt.Fprint(buf, newContent) + break + } + } +} + +var DEFAULT_DARK_THEME *int64 = nil // no theme selected + +func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { + var jsRunner jsrunner.JSRunner + pad := DEFAULT_PADDING + themeID := d2themescatalog.NeutralDefault.ID + darkThemeID := DEFAULT_DARK_THEME + var scale *float64 + if opts != nil { + if opts.Pad != nil { + pad = int(*opts.Pad) + } + if opts.Sketch != nil && *opts.Sketch { + jsRunner = jsrunner.NewJSRunner() + err := d2sketch.LoadJS(jsRunner) + if err != nil { + return nil, err + } + } + if opts.ThemeID != nil { + themeID = *opts.ThemeID + } + darkThemeID = opts.DarkThemeID + scale = opts.Scale + } else { + opts = &RenderOpts{} + } + + buf := &bytes.Buffer{} + + // only define shadow filter if a shape uses it + for _, s := range diagram.Shapes { + if s.Shadow { + defineShadowFilter(buf) + break + } + } + + if color.IsGradient(diagram.Root.Fill) { + defineGradients(buf, diagram.Root.Fill) + } + if color.IsGradient(diagram.Root.Stroke) { + defineGradients(buf, diagram.Root.Stroke) + } + for _, s := range diagram.Shapes { + if color.IsGradient(s.Fill) { + defineGradients(buf, s.Fill) + } + if color.IsGradient(s.Stroke) { + defineGradients(buf, s.Stroke) + } + if color.IsGradient(s.Color) { + defineGradients(buf, s.Color) + } + } + for _, c := range diagram.Connections { + if color.IsGradient(c.Stroke) { + defineGradients(buf, c.Stroke) + } + if color.IsGradient(c.Fill) { + defineGradients(buf, c.Fill) + } + } + + // Apply hash on IDs for targeting, to be specific for this diagram + diagramHash, err := diagram.HashID(opts.Salt) + if err != nil { + return nil, err + } + // Some targeting is still per-board, like masks for connections + isolatedDiagramHash := diagramHash + if opts != nil && opts.MasterID != "" { + diagramHash = opts.MasterID + } + + // SVG has no notion of z-index. The z-index is effectively the order it's drawn. + // So draw from the least nested to most nested + idToShape := make(map[string]d2target.Shape) + allObjects := make([]DiagramObject, 0, len(diagram.Shapes)+len(diagram.Connections)) + for _, s := range diagram.Shapes { + idToShape[s.ID] = s + allObjects = append(allObjects, s) + } + for _, c := range diagram.Connections { + allObjects = append(allObjects, c) + } + + sortObjects(allObjects) + + appendixItemBuf := &bytes.Buffer{} + + var labelMasks []string + markers := map[string]struct{}{} + var inlineTheme *d2themes.Theme + // We only want to inline when no dark theme is specified, otherwise the inline style will override the CSS + if darkThemeID == nil { + inlineTheme = go2.Pointer(d2themescatalog.Find(themeID)) + inlineTheme.ApplyOverrides(opts.ThemeOverrides) + } + for _, obj := range allObjects { + if c, is := obj.(d2target.Connection); is { + labelMask, err := drawConnection(buf, isolatedDiagramHash, c, markers, idToShape, jsRunner, inlineTheme) + if err != nil { + return nil, err + } + if labelMask != "" { + labelMasks = append(labelMasks, labelMask) + } + } else if s, is := obj.(d2target.Shape); is { + labelMask, err := drawShape(buf, appendixItemBuf, diagramHash, s, jsRunner, inlineTheme) + if err != nil { + return nil, err + } else if labelMask != "" { + labelMasks = append(labelMasks, labelMask) + } + } else { + return nil, fmt.Errorf("unknown object of type %T", obj) + } + } + // add all appendix items afterwards so they are always on top + fmt.Fprint(buf, appendixItemBuf) + + // Render legend if present + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + legendBuf := &bytes.Buffer{} + err := renderLegend(legendBuf, diagram, diagramHash, inlineTheme) + if err != nil { + return nil, err + } + fmt.Fprint(buf, legendBuf) + } + + // Note: we always want this since we reference it on connections even if there end up being no masked labels + left, top, w, h := dimensions(diagram, pad) + + // Adjust the width and height if the legend is present to ensure it's fully visible + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + // Calculate dimensions needed for legend + tl, br := diagram.BoundingBox() + // Start with top padding and title height + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + itemCount := 0 + ruler, _ := textmeasure.NewRuler() + if ruler != nil { + // Calculate height and width of legend + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + // If we have items, remove the extra spacing from the last item and add bottom padding + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 // Remove some of the last spacing + } + + // Add bottom padding + totalHeight += LEGEND_PADDING + + if totalHeight > 0 && maxLabelWidth > 0 { + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + + // Calculate legend vertical position (centered) + legendY := tl.Y + (br.Y-tl.Y-totalHeight)/2 + if legendY < tl.Y { + legendY = tl.Y + } + + // Expand width to include legend to the right + legendRight := br.X + LEGEND_CORNER_PADDING + legendWidth + if left+w < legendRight { + w = legendRight - left + pad/2 + } + + // Make sure the top of the legend is visible + if legendY < top { + diffY := top - legendY + top -= diffY + h += diffY + } + + // Make sure the bottom of the legend is visible + legendBottom := legendY + totalHeight + if top+h < legendBottom { + h = legendBottom - top + pad/2 + } + } + } + } + fmt.Fprint(buf, strings.Join([]string{ + fmt.Sprintf(``, + isolatedDiagramHash, left, top, w, h, + ), + fmt.Sprintf(``, + left, top, w, h, + ), + strings.Join(labelMasks, "\n"), + ``, + }, "\n")) + + // generate style elements that will be appended to the SVG tag + upperBuf := &bytes.Buffer{} + if opts.MasterID == "" { + EmbedFonts(upperBuf, diagramHash, buf.String(), diagram.FontFamily, diagram.GetCorpus()) // EmbedFonts *must* run before `d2sketch.DefineFillPatterns`, but after all elements are appended to `buf` + themeStylesheet, err := ThemeCSS(diagramHash, &themeID, darkThemeID, opts.ThemeOverrides, opts.DarkThemeOverrides) + if err != nil { + return nil, err + } + fmt.Fprintf(upperBuf, ``, BaseStylesheet, themeStylesheet) + + hasMarkdown := false + for _, s := range diagram.Shapes { + if s.Language == "markdown" { + hasMarkdown = true + break + } + } + if hasMarkdown { + css := MarkdownCSS + css = strings.ReplaceAll(css, ".md", fmt.Sprintf(".%s .md", diagramHash)) + css = strings.ReplaceAll(css, "font-italic", fmt.Sprintf("%s-font-italic", diagramHash)) + css = strings.ReplaceAll(css, "font-bold", fmt.Sprintf("%s-font-bold", diagramHash)) + css = strings.ReplaceAll(css, "font-mono", fmt.Sprintf("%s-font-mono", diagramHash)) + css = strings.ReplaceAll(css, "font-regular", fmt.Sprintf("%s-font-regular", diagramHash)) + css = strings.ReplaceAll(css, "font-semibold", fmt.Sprintf("%s-font-semibold", diagramHash)) + fmt.Fprintf(upperBuf, ``, css) + } + + if jsRunner != nil { + d2sketch.DefineFillPatterns(upperBuf, diagramHash) + } + } + + // This shift is for background el to envelop the diagram + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + backgroundEl := d2themes.NewThemableElement("rect", inlineTheme) + // We don't want to change the document viewbox, only the background el + backgroundEl.X = float64(left) + backgroundEl.Y = float64(top) + backgroundEl.Width = float64(w) + backgroundEl.Height = float64(h) + backgroundEl.Fill = diagram.Root.Fill + backgroundEl.Stroke = diagram.Root.Stroke + backgroundEl.FillPattern = diagram.Root.FillPattern + backgroundEl.Rx = float64(diagram.Root.BorderRadius) + if diagram.Root.StrokeDash != 0 { + dashSize, gapSize := svg.GetStrokeDashAttributes(float64(diagram.Root.StrokeWidth), diagram.Root.StrokeDash) + backgroundEl.StrokeDashArray = fmt.Sprintf("%f, %f", dashSize, gapSize) + } + backgroundEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, diagram.Root.StrokeWidth) + + // This shift is for viewbox to envelop the background el + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + + doubleBorderElStr := "" + if diagram.Root.DoubleBorder { + offset := d2target.INNER_BORDER_OFFSET + + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)) + offset + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)) + offset + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)*2.) + 2*offset + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)*2.) + 2*offset + + backgroundEl2 := backgroundEl.Copy() + // No need to double-paint + backgroundEl.Fill = "transparent" + + backgroundEl2.X = float64(left) + backgroundEl2.Y = float64(top) + backgroundEl2.Width = float64(w) + backgroundEl2.Height = float64(h) + doubleBorderElStr = backgroundEl2.Render() + + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + } + + bufStr := buf.String() + patternDefs := "" + for _, pattern := range d2ast.FillPatterns { + if strings.Contains(bufStr, fmt.Sprintf("%s-overlay", pattern)) || diagram.Root.FillPattern == pattern { + if patternDefs == "" { + fmt.Fprint(upperBuf, ``) + fmt.Fprint(upperBuf, "") + fmt.Fprint(upperBuf, patternDefs) + fmt.Fprint(upperBuf, "") + } + + var dimensions string + if scale != nil { + dimensions = fmt.Sprintf(` width="%d" height="%d"`, + int(math.Ceil((*scale)*float64(w))), + int(math.Ceil((*scale)*float64(h))), + ) + } + + alignment := "xMinYMin" + if opts.Center != nil && *opts.Center { + alignment = "xMidYMid" + } + fitToScreenWrapperOpening := "" + xmlTag := "" + fitToScreenWrapperClosing := "" + idAttr := "" + tag := "g" + // Many things change when this is rendering for animation + if opts.MasterID == "" { + fitToScreenWrapperOpening = fmt.Sprintf(``, + version.Version, + alignment, + w, h, + dimensions, + ) + if opts.NoXMLTag == nil || !*opts.NoXMLTag { + xmlTag = `` + } + fitToScreenWrapperClosing = "" + idAttr = `d2-svg` + tag = "svg" + } + + // TODO minify + docRendered := fmt.Sprintf(`%s%s<%s class="%s" width="%d" height="%d" viewBox="%d %d %d %d">%s%s%s%s%s`, + xmlTag, + fitToScreenWrapperOpening, + tag, + strings.Join([]string{diagramHash, idAttr}, " "), + w, h, left, top, w, h, + doubleBorderElStr, + backgroundEl.Render(), + upperBuf.String(), + buf.String(), + tag, + fitToScreenWrapperClosing, + ) + return []byte(docRendered), nil +} + +// TODO include only colors that are being used to reduce size +func ThemeCSS(diagramHash string, themeID *int64, darkThemeID *int64, overrides, darkOverrides *d2target.ThemeOverrides) (stylesheet string, err error) { + if themeID == nil { + themeID = &d2themescatalog.NeutralDefault.ID + } + out, err := singleThemeRulesets(diagramHash, *themeID, overrides) + if err != nil { + return "", err + } + + if darkThemeID != nil { + darkOut, err := singleThemeRulesets(diagramHash, *darkThemeID, darkOverrides) + if err != nil { + return "", err + } + out += fmt.Sprintf("@media screen and (prefers-color-scheme:dark){%s}", darkOut) + } + + return out, nil +} + +func singleThemeRulesets(diagramHash string, themeID int64, overrides *d2target.ThemeOverrides) (rulesets string, err error) { + out := "" + theme := d2themescatalog.Find(themeID) + theme.ApplyOverrides(overrides) + + // Global theme colors + for _, property := range []string{"fill", "stroke", "background-color", "color"} { + out += fmt.Sprintf(` + .%s .%s-N1{%s:%s;} + .%s .%s-N2{%s:%s;} + .%s .%s-N3{%s:%s;} + .%s .%s-N4{%s:%s;} + .%s .%s-N5{%s:%s;} + .%s .%s-N6{%s:%s;} + .%s .%s-N7{%s:%s;} + .%s .%s-B1{%s:%s;} + .%s .%s-B2{%s:%s;} + .%s .%s-B3{%s:%s;} + .%s .%s-B4{%s:%s;} + .%s .%s-B5{%s:%s;} + .%s .%s-B6{%s:%s;} + .%s .%s-AA2{%s:%s;} + .%s .%s-AA4{%s:%s;} + .%s .%s-AA5{%s:%s;} + .%s .%s-AB4{%s:%s;} + .%s .%s-AB5{%s:%s;}`, + diagramHash, + property, property, theme.Colors.Neutrals.N1, + diagramHash, + property, property, theme.Colors.Neutrals.N2, + diagramHash, + property, property, theme.Colors.Neutrals.N3, + diagramHash, + property, property, theme.Colors.Neutrals.N4, + diagramHash, + property, property, theme.Colors.Neutrals.N5, + diagramHash, + property, property, theme.Colors.Neutrals.N6, + diagramHash, + property, property, theme.Colors.Neutrals.N7, + diagramHash, + property, property, theme.Colors.B1, + diagramHash, + property, property, theme.Colors.B2, + diagramHash, + property, property, theme.Colors.B3, + diagramHash, + property, property, theme.Colors.B4, + diagramHash, + property, property, theme.Colors.B5, + diagramHash, + property, property, theme.Colors.B6, + diagramHash, + property, property, theme.Colors.AA2, + diagramHash, + property, property, theme.Colors.AA4, + diagramHash, + property, property, theme.Colors.AA5, + diagramHash, + property, property, theme.Colors.AB4, + diagramHash, + property, property, theme.Colors.AB5, + ) + } + + // Appendix + out += fmt.Sprintf(".appendix text.text{fill:%s}", theme.Colors.Neutrals.N1) + + // Markdown specific rulesets + out += fmt.Sprintf(".md{--color-fg-default:%s;--color-fg-muted:%s;--color-fg-subtle:%s;--color-canvas-default:%s;--color-canvas-subtle:%s;--color-border-default:%s;--color-border-muted:%s;--color-neutral-muted:%s;--color-accent-fg:%s;--color-accent-emphasis:%s;--color-attention-subtle:%s;--color-danger-fg:%s;}", + theme.Colors.Neutrals.N1, theme.Colors.Neutrals.N2, theme.Colors.Neutrals.N3, + theme.Colors.Neutrals.N7, theme.Colors.Neutrals.N6, + theme.Colors.B1, theme.Colors.B2, + theme.Colors.Neutrals.N6, + theme.Colors.B2, theme.Colors.B2, + theme.Colors.Neutrals.N2, // TODO or N3 --color-attention-subtle + "red", + ) + + // Sketch style specific rulesets + // B + lc, err := color.LuminanceCategory(theme.Colors.B1) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B1, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B2) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B2, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B3) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B3, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B5, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B6) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B6, lc, diagramHash, blendMode(lc)) + + // AA + lc, err = color.LuminanceCategory(theme.Colors.AA2) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AA2, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.AA4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AA4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.AA5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AA5, lc, diagramHash, blendMode(lc)) + + // AB + lc, err = color.LuminanceCategory(theme.Colors.AB4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AB4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.AB5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AB5, lc, diagramHash, blendMode(lc)) + + // Neutrals + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N1) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N1, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N2) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N2, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N3) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N3, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N5, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N6) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N6, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N7) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N7, lc, diagramHash, blendMode(lc)) + + if theme.IsDark() { + out += ".light-code{display: none}" + out += ".dark-code{display: block}" + } else { + out += ".light-code{display: block}" + out += ".dark-code{display: none}" + } + + return out, nil +} + +func blendMode(lc string) string { + switch lc { + case "bright": + return "darken" + case "normal": + return "color-burn" + case "dark": + return "overlay" + case "darker": + return "lighten" + } + panic("invalid luminance category") +} + +type DiagramObject interface { + GetID() string + GetZIndex() int +} + +// sortObjects sorts all diagrams objects (shapes and connections) in the desired drawing order +// the sorting criteria is: +// 1. zIndex, lower comes first +// 2. two shapes with the same zIndex are sorted by their level (container nesting), containers come first +// 3. two shapes with the same zIndex and same level, are sorted in the order they were exported +// 4. shape and edge, shapes come first +func sortObjects(allObjects []DiagramObject) { + sort.SliceStable(allObjects, func(i, j int) bool { + // first sort by zIndex + iZIndex := allObjects[i].GetZIndex() + jZIndex := allObjects[j].GetZIndex() + if iZIndex != jZIndex { + return iZIndex < jZIndex + } + + // then, if both are shapes, parents come before their children + iShape, iIsShape := allObjects[i].(d2target.Shape) + jShape, jIsShape := allObjects[j].(d2target.Shape) + if iIsShape && jIsShape { + return iShape.Level < jShape.Level + } + + // then, shapes come before connections + _, jIsConnection := allObjects[j].(d2target.Connection) + return iIsShape && jIsConnection + }) +} + +func hash(s string) string { + const secret = "lalalas" + h := fnv.New32a() + h.Write([]byte(fmt.Sprintf("%s%s", s, secret))) + return fmt.Sprint(h.Sum32()) +} + +func RenderMultiboard(diagram *d2target.Diagram, opts *RenderOpts) ([][]byte, error) { + var boards [][]byte + for _, dl := range diagram.Layers { + childrenBoards, err := RenderMultiboard(dl, opts) + if err != nil { + return nil, err + } + boards = append(boards, childrenBoards...) + } + for _, dl := range diagram.Scenarios { + childrenBoards, err := RenderMultiboard(dl, opts) + if err != nil { + return nil, err + } + boards = append(boards, childrenBoards...) + } + for _, dl := range diagram.Steps { + childrenBoards, err := RenderMultiboard(dl, opts) + if err != nil { + return nil, err + } + boards = append(boards, childrenBoards...) + } + + if !diagram.IsFolderOnly { + out, err := Render(diagram, opts) + if err != nil { + return boards, err + } + boards = append([][]byte{out}, boards...) + return boards, nil + } + return boards, nil +} diff --git a/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg index 1286fa115..f5c0f826a 100644 --- a/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg +++ b/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-41228547-font-regular"; font-size: 16px; @@ -847,7 +846,7 @@   panic("TODO") }func main() {   panic("TODO") -}

    Five is a sufficiently close approximation to infinity.

    +}

    Five is a sufficiently close approximation to infinity.

    Don't hit me!!  I'm in the Twilight Zone!!!Don't hit me!!  I'm in the Twilight Zone!!! diff --git a/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg index 2348d3093..cb43dab8f 100644 --- a/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg +++ b/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3335880637-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3335880637 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -x

    linux: because a PC is a terrible thing to waste

    +x

    linux: because a PC is a terrible thing to waste

    auserslast_logindatetime You don't have to know how the computer works,just how to work the computer. diff --git a/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg index fd67b52b8..bad8193d8 100644 --- a/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg +++ b/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1329315803-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1329315803 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    +People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    • Inject ads, who-to-follow, onboarding
    • Conversation module
    • @@ -851,7 +850,7 @@
    • Tweat deduplication
    • Served data logging
    -
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    +
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    TLS-API (being deprecated)CrMixerEarlyBirdUtagSpaceCommunities iPhone webHTTP AndroidThrift RPC Candidate FetchFeature HydrationCandidate sources diff --git a/d2renderers/d2svg/github-markdown.css b/d2renderers/d2svg/github-markdown.css index c271b67d7..53a7e2102 100644 --- a/d2renderers/d2svg/github-markdown.css +++ b/d2renderers/d2svg/github-markdown.css @@ -26,7 +26,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "font-regular"; font-size: 16px; diff --git a/d2target/d2target.go b/d2target/d2target.go index cfd858d5d..4880c2859 100644 --- a/d2target/d2target.go +++ b/d2target/d2target.go @@ -456,6 +456,16 @@ func (diagram Diagram) GetCorpus() string { } } + if diagram.Legend != nil { + corpus += "Legend" + for _, s := range diagram.Legend.Shapes { + corpus += s.Label + } + for _, c := range diagram.Legend.Connections { + corpus += c.Label + } + } + return corpus } diff --git a/e2etests-cli/main_test.go b/e2etests-cli/main_test.go index dbdcd2833..441fbd986 100644 --- a/e2etests-cli/main_test.go +++ b/e2etests-cli/main_test.go @@ -1346,6 +1346,22 @@ c assert.Success(t, err) }, }, + { + name: "validate-against-correct-d2", + run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { + writeFile(t, dir, "correct.d2", `x -> y`) + err := runTestMainPersist(t, ctx, dir, env, "validate", "correct.d2") + assert.Success(t, err) + }, + }, + { + name: "validate-against-incorrect-d2", + run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { + writeFile(t, dir, "incorrect.d2", `x > y`) + err := runTestMainPersist(t, ctx, dir, env, "validate", "incorrect.d2") + assert.Error(t, err) + }, + }, } ctx := context.Background() diff --git a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg index ed7cdbc16..dcbca7efc 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg @@ -124,7 +124,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2144186222-font-regular"; font-size: 16px; diff --git a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg index dc6c04e0c..ff364797c 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg @@ -124,7 +124,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-629739489-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg b/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg index e785cdab4..a073a5d9a 100644 --- a/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3049291188-font-regular"; font-size: 16px; @@ -836,10 +835,10 @@ .d2-3049291188 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

    Oldest message

    -

    Offset

    -

    Last message

    -

    Next message will be
    +

    Oldest message

    +

    Offset

    +

    Last message

    +

    Next message will be
    inserted here

    M0M1M2M3M4M5M6 diff --git a/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg b/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg index f1f7263f6..9278f1922 100644 --- a/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3542568952-font-regular"; font-size: 16px; @@ -836,10 +835,10 @@ .d2-3542568952 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

    Oldest message

    -

    Offset

    -

    Last message

    -

    Next message will be
    +

    Oldest message

    +

    Offset

    +

    Last message

    +

    Next message will be
    inserted here

    M0M1M2M3M4M5M6 diff --git a/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg b/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg index d306de191..25e5818dc 100644 --- a/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-147443974-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-147443974 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

    I can do headers

    +

    I can do headers

    • lists
    • lists
    • diff --git a/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg b/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg index 75d4fe601..90b3f7532 100644 --- a/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2881380206-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-2881380206 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

      I can do headers

      +

      I can do headers

      • lists
      • lists
      • diff --git a/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg b/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg index 69644a27d..5c15180ff 100644 --- a/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1836715912-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1836715912 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

        hey

        +

        hey

        • they
            diff --git a/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg b/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg index 5b9673ea7..d8ee7c442 100644 --- a/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3788794681-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3788794681 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

            hey

            +

            hey

            • they
                diff --git a/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg b/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg index 89f900846..13fad6d1f 100644 --- a/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1987627880-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1987627880 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -x

                linux: because a PC is a terrible thing to waste

                +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. diff --git a/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg b/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg index 42374bbd2..99b02c34e 100644 --- a/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-856327487-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-856327487 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -x

                linux: because a PC is a terrible thing to waste

                +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. diff --git a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg index bcf7b4344..acf74d5fb 100644 --- a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4271326716-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-4271326716 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                  +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                  • Asset Tagging
                  • Inventory
                  • Staging
                  • diff --git a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg index c6858e1b9..a0cc6c80a 100644 --- a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1235788687-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1235788687 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                      +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                      • Asset Tagging
                      • Inventory
                      • Staging
                      • diff --git a/e2etests/testdata/stable/br/dagre/sketch.exp.svg b/e2etests/testdata/stable/br/dagre/sketch.exp.svg index d136e2968..4b32bcda6 100644 --- a/e2etests/testdata/stable/br/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/br/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3415583374-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-3415583374 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        Headline 1

                        +

                        Headline 1

                        Headline 2

                        Lorem ipsum dolor

                        diff --git a/e2etests/testdata/stable/br/elk/sketch.exp.svg b/e2etests/testdata/stable/br/elk/sketch.exp.svg index 04d063663..9ca88d88b 100644 --- a/e2etests/testdata/stable/br/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/br/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2354018982-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-2354018982 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        Headline 1

                        +

                        Headline 1

                        Headline 2

                        Lorem ipsum dolor

                        diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg index 1df7ab4f7..d051dfacb 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1761626757-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1761626757 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xyThe top of the mountainJoeDonald

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

                        +xyThe top of the mountainJoeDonald

                        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.

                        i am top lefti am top righti am bottom lefti am bottom right diff --git a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg index dfcdc388d..89e1ffcea 100644 --- a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1390049335-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1390049335 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xyThe top of the mountainJoeDonald

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

                        +xyThe top of the mountainJoeDonald

                        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.

                        i am top lefti am top righti am bottom lefti am bottom right diff --git a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg index 792d1e688..3adfcdaeb 100644 --- a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2364978249-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2364978249 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        A winning strategy

                        +

                        A winning strategy

                        poll the peopleresultsunfavorablefavorablewill of the people diff --git a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg index ea5956d84..d5b7b3075 100644 --- a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4212596512-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-4212596512 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        A winning strategy

                        +

                        A winning strategy

                        poll the peopleresultsunfavorablefavorablewill of the people diff --git a/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg b/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg index 04bbf4f48..3164f3577 100644 --- a/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2362348913-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg b/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg index 431a803c0..90397f6b8 100644 --- a/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-664798849-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg index 63f3c768a..4d502a04a 100644 --- a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-851985161-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-851985161 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        Markdown: Syntax

                        +

                        Markdown: Syntax

                        • Overview
                            diff --git a/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg b/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg index 7833bf6cc..d37d1b5b3 100644 --- a/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4122552445-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-4122552445 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                            Markdown: Syntax

                            +

                            Markdown: Syntax

                            • Overview
                                diff --git a/e2etests/testdata/stable/hr/dagre/sketch.exp.svg b/e2etests/testdata/stable/hr/dagre/sketch.exp.svg index ed98d022e..0d3428360 100644 --- a/e2etests/testdata/stable/hr/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/hr/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-142627214-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-142627214 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                Note: This document is itself written using Markdown; you +

                                Note: This document is itself written using Markdown; you can see the source for it by adding '.text' to the URL.


                                Overview

                                diff --git a/e2etests/testdata/stable/hr/elk/sketch.exp.svg b/e2etests/testdata/stable/hr/elk/sketch.exp.svg index c87b096fd..a611ba012 100644 --- a/e2etests/testdata/stable/hr/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/hr/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3115974332-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3115974332 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                Note: This document is itself written using Markdown; you +

                                Note: This document is itself written using Markdown; you can see the source for it by adding '.text' to the URL.


                                Overview

                                diff --git a/e2etests/testdata/stable/li1/dagre/sketch.exp.svg b/e2etests/testdata/stable/li1/dagre/sketch.exp.svg index a75f650ba..94f6601bd 100644 --- a/e2etests/testdata/stable/li1/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li1/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3521704376-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3521704376 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                  +
                                  • Overview
                                    • Philosophy
                                    • diff --git a/e2etests/testdata/stable/li1/elk/sketch.exp.svg b/e2etests/testdata/stable/li1/elk/sketch.exp.svg index 12d7f100a..a1082bda1 100644 --- a/e2etests/testdata/stable/li1/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li1/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2351031357-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2351031357 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                        +
                                        • Overview
                                          • Philosophy
                                          • diff --git a/e2etests/testdata/stable/li2/dagre/sketch.exp.svg b/e2etests/testdata/stable/li2/dagre/sketch.exp.svg index bd9d9b9bf..f72a29d12 100644 --- a/e2etests/testdata/stable/li2/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li2/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3835243374-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3835243374 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                              +
                                              • Overview ok this is all measured
                                                • Philosophy
                                                • diff --git a/e2etests/testdata/stable/li2/elk/sketch.exp.svg b/e2etests/testdata/stable/li2/elk/sketch.exp.svg index 9f0dee141..f635a1a71 100644 --- a/e2etests/testdata/stable/li2/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li2/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2498775702-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2498775702 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                    +
                                                    • Overview ok this is all measured
                                                      • Philosophy
                                                      • diff --git a/e2etests/testdata/stable/li3/dagre/sketch.exp.svg b/e2etests/testdata/stable/li3/dagre/sketch.exp.svg index 7a0b2e864..513a3509d 100644 --- a/e2etests/testdata/stable/li3/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li3/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1850453634-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1850453634 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                          +
                                                          • Overview
                                                            • Philosophy
                                                            • diff --git a/e2etests/testdata/stable/li3/elk/sketch.exp.svg b/e2etests/testdata/stable/li3/elk/sketch.exp.svg index 9812d3afe..8ff7c9640 100644 --- a/e2etests/testdata/stable/li3/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li3/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3625619566-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3625619566 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                +
                                                                • Overview
                                                                  • Philosophy
                                                                  • diff --git a/e2etests/testdata/stable/li4/dagre/sketch.exp.svg b/e2etests/testdata/stable/li4/dagre/sketch.exp.svg index 12cd99727..fee9f3a83 100644 --- a/e2etests/testdata/stable/li4/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li4/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-95635950-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-95635950 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                    List items may consist of multiple paragraphs. Each subsequent +

                                                                    List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab:

                                                                      diff --git a/e2etests/testdata/stable/li4/elk/sketch.exp.svg b/e2etests/testdata/stable/li4/elk/sketch.exp.svg index 42df125b6..e52b88cb9 100644 --- a/e2etests/testdata/stable/li4/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li4/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1253393308-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1253393308 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                      List items may consist of multiple paragraphs. Each subsequent +

                                                                      List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab:

                                                                        diff --git a/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg b/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg index d559875ba..c5b40c60d 100644 --- a/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1741298119-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1741298119 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                        Markdown: Syntax

                                                                        +

                                                                        Markdown: Syntax

                                                                        ab diff --git a/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg b/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg index 722c9fcfd..990ef92b2 100644 --- a/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1073489527-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1073489527 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                        Markdown: Syntax

                                                                        +

                                                                        Markdown: Syntax

                                                                        ab diff --git a/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg b/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg index 53f6af603..d9d20710d 100644 --- a/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1466084009-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1466084009 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                        Every frustum longs to be a cone

                                                                        +

                                                                        Every frustum longs to be a cone

                                                                        • A continuing flow of paper is sufficient to continue the flow of paper
                                                                        • Please remain calm, it's no use both of us being hysterical at the same time
                                                                        • diff --git a/e2etests/testdata/stable/markdown/elk/sketch.exp.svg b/e2etests/testdata/stable/markdown/elk/sketch.exp.svg index 74c9a2cb0..3329ea93e 100644 --- a/e2etests/testdata/stable/markdown/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2237312999-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2237312999 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                          Every frustum longs to be a cone

                                                                          +

                                                                          Every frustum longs to be a cone

                                                                          • A continuing flow of paper is sufficient to continue the flow of paper
                                                                          • Please remain calm, it's no use both of us being hysterical at the same time
                                                                          • diff --git a/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg b/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg index 2217c52da..1ee8a86d8 100644 --- a/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1160608805-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg b/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg index e74f24b3c..f001e0fa5 100644 --- a/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-939069974-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg index 82a28c28b..42d9b3bfa 100644 --- a/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2553377867-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-2553377867 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

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

                                                                            diff --git a/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg b/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg index 829ce37f2..479098e96 100644 --- a/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3503638182-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-3503638182 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

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

                                                                            diff --git a/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg index 9c9904725..0e46c4c06 100644 --- a/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3081693699-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-3081693699 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

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

                                                                            diff --git a/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg b/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg index 6ac49ef83..19eae2d01 100644 --- a/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4149945950-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-4149945950 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

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

                                                                            diff --git a/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg index ad3879b8d..647deb27e 100644 --- a/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1518250751-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1518250751 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                            {
                                                                            +
                                                                            {
                                                                             	fenced: "block",
                                                                             	of: "json",
                                                                             }
                                                                            diff --git a/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg
                                                                            index fc8892b5b..a2c694985 100644
                                                                            --- a/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-3638167430-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-3638167430 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -
                                                                            {
                                                                            +
                                                                            {
                                                                             	fenced: "block",
                                                                             	of: "json",
                                                                             }
                                                                            diff --git a/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg
                                                                            index 93f7e90e7..8fe1a2c88 100644
                                                                            --- a/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-1952230391-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-1952230391 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -

                                                                            a line of text and an

                                                                            +

                                                                            a line of text and an

                                                                            {
                                                                             	indented: "block",
                                                                             	of: "json",
                                                                            diff --git a/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg
                                                                            index 0a14680d2..ba98d85b2 100644
                                                                            --- a/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-538047421-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-538047421 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -

                                                                            a line of text and an

                                                                            +

                                                                            a line of text and an

                                                                            {
                                                                             	indented: "block",
                                                                             	of: "json",
                                                                            diff --git a/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg
                                                                            index 19278c20c..95947cbcd 100644
                                                                            --- a/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-1339768961-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-1339768961 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -

                                                                            code

                                                                            +

                                                                            code

                                                                            ab diff --git a/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg b/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg index edcf5b11e..5a0542978 100644 --- a/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3881944313-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3881944313 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                            code

                                                                            +

                                                                            code

                                                                            ab diff --git a/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg index 4a6cc6146..769cb2b0e 100644 --- a/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2196724626-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2196724626 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                            Every frustum longs to be a cone

                                                                            +

                                                                            Every frustum longs to be a cone

                                                                            • A continuing flow of paper is sufficient to continue the flow of paper
                                                                            • Please remain calm, it's no use both of us being hysterical at the same time
                                                                            • diff --git a/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg b/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg index 1e56c95cb..43378ec0f 100644 --- a/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-632982403-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-632982403 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                              Every frustum longs to be a cone

                                                                              +

                                                                              Every frustum longs to be a cone

                                                                              • A continuing flow of paper is sufficient to continue the flow of paper
                                                                              • Please remain calm, it's no use both of us being hysterical at the same time
                                                                              • diff --git a/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg index c69fd40a9..3c4bf0894 100644 --- a/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2743272479-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2743272479 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -example

                                                                                one two three!

                                                                                +example

                                                                                one two three!

                                                                                diff --git a/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg b/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg index a4895531e..d83f40bb1 100644 --- a/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3779428285-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3779428285 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -example

                                                                                one two three!

                                                                                +example

                                                                                one two three!

                                                                                diff --git a/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg index 95d72ca0c..2445048e8 100644 --- a/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-968008625-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-968008625 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                +

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                diff --git a/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg index 95d72ca0c..2445048e8 100644 --- a/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-968008625-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-968008625 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                +

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                diff --git a/e2etests/testdata/stable/p/dagre/sketch.exp.svg b/e2etests/testdata/stable/p/dagre/sketch.exp.svg index f17d8d962..7d586fc7b 100644 --- a/e2etests/testdata/stable/p/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/p/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3128274021-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3128274021 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                A paragraph is simply one or more consecutive lines of text, separated +

                                                                                A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs.

                                                                                diff --git a/e2etests/testdata/stable/p/elk/sketch.exp.svg b/e2etests/testdata/stable/p/elk/sketch.exp.svg index 85bc75cab..df673875f 100644 --- a/e2etests/testdata/stable/p/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/p/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-979712518-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-979712518 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                A paragraph is simply one or more consecutive lines of text, separated +

                                                                                A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs.

                                                                                diff --git a/e2etests/testdata/stable/pre/dagre/sketch.exp.svg b/e2etests/testdata/stable/pre/dagre/sketch.exp.svg index 9ef6d1ab7..0ee1035b1 100644 --- a/e2etests/testdata/stable/pre/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/pre/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3660705295-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3660705295 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                Here is an example of AppleScript:

                                                                                +

                                                                                Here is an example of AppleScript:

                                                                                tell application "Foo"
                                                                                     beep
                                                                                 end tell
                                                                                diff --git a/e2etests/testdata/stable/pre/elk/sketch.exp.svg b/e2etests/testdata/stable/pre/elk/sketch.exp.svg
                                                                                index eb4b05485..90ed3b2e1 100644
                                                                                --- a/e2etests/testdata/stable/pre/elk/sketch.exp.svg
                                                                                +++ b/e2etests/testdata/stable/pre/elk/sketch.exp.svg
                                                                                @@ -135,7 +135,6 @@
                                                                                   -ms-text-size-adjust: 100%;
                                                                                   -webkit-text-size-adjust: 100%;
                                                                                   margin: 0;
                                                                                -  color: var(--color-fg-default);
                                                                                   background-color: transparent; /* we don't want to define the background color */
                                                                                   font-family: "d2-818404908-font-regular";
                                                                                   font-size: 16px;
                                                                                @@ -843,7 +842,7 @@
                                                                                 .d2-818404908 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                                   margin: 0 -1.6em 0.25em 0.2em;
                                                                                 }
                                                                                -

                                                                                Here is an example of AppleScript:

                                                                                +

                                                                                Here is an example of AppleScript:

                                                                                tell application "Foo"
                                                                                     beep
                                                                                 end tell
                                                                                diff --git a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
                                                                                index 6382dee61..6a68c6dd2 100644
                                                                                --- a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
                                                                                +++ b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
                                                                                @@ -135,7 +135,6 @@
                                                                                   -ms-text-size-adjust: 100%;
                                                                                   -webkit-text-size-adjust: 100%;
                                                                                   margin: 0;
                                                                                -  color: var(--color-fg-default);
                                                                                   background-color: transparent; /* we don't want to define the background color */
                                                                                   font-family: "d2-1817135411-font-regular";
                                                                                   font-size: 16px;
                                                                                @@ -843,7 +842,7 @@
                                                                                 .d2-1817135411 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                                   margin: 0 -1.6em 0.25em 0.2em;
                                                                                 }
                                                                                -TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                +TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged diff --git a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg index b823da1c7..f9b4d1db5 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3185352814-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3185352814 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                +TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged diff --git a/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg b/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg index 9ccbe497e..1dc2c2280 100644 --- a/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg +++ b/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg @@ -149,7 +149,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-85991054-font-regular"; font-size: 16px; @@ -857,7 +856,7 @@ .d2-85991054 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                A tale

                                                                                +networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                A tale

                                                                                • of
                                                                                • two cities
                                                                                • diff --git a/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg b/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg index be20c370a..cc0324ffa 100644 --- a/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg +++ b/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg @@ -149,7 +149,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3004075822-font-regular"; font-size: 16px; @@ -857,7 +856,7 @@ .d2-3004075822 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                  A tale

                                                                                  +networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                  A tale

                                                                                  • of
                                                                                  • two cities
                                                                                  • diff --git a/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg b/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg index ba9d909e2..4634e5f65 100644 --- a/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg +++ b/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1263202776-font-regular"; font-size: 16px; @@ -883,7 +882,7 @@ -NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                    A TALE

                                                                                    +NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                    A TALE

                                                                                    • OF
                                                                                    • TWO CITIES
                                                                                    • diff --git a/e2etests/testdata/themes/terminal/elk/sketch.exp.svg b/e2etests/testdata/themes/terminal/elk/sketch.exp.svg index 19223f112..69733b705 100644 --- a/e2etests/testdata/themes/terminal/elk/sketch.exp.svg +++ b/e2etests/testdata/themes/terminal/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4226491288-font-regular"; font-size: 16px; @@ -883,7 +882,7 @@ -NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                      A TALE

                                                                                      +NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                      A TALE

                                                                                      • OF
                                                                                      • TWO CITIES
                                                                                      • diff --git a/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg b/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg index 7f08aa30c..76dbf72a3 100644 --- a/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg +++ b/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3098341505-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3098341505 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -OEM Factory

                                                                                        company Warehouse

                                                                                        +OEM Factory

                                                                                        company Warehouse

                                                                                        • Asset Tagging
                                                                                        • Inventory
                                                                                        • diff --git a/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg b/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg index 446e1286b..c94df84f7 100644 --- a/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg +++ b/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1471202586-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1471202586 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -OEM Factory

                                                                                          company Warehouse

                                                                                          +OEM Factory

                                                                                          company Warehouse

                                                                                          • Asset Tagging
                                                                                          • Inventory
                                                                                          • diff --git a/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg b/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg index 3f971fb83..5320a484e 100644 --- a/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg +++ b/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3326126261-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-3326126261 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            +containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            := 5 := a + 7 fmt.Printf("%d", b)a := 5 diff --git a/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg b/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg index 0fcd82215..c12a36bdb 100644 --- a/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg +++ b/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-71187753-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-71187753 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            +containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            := 5 := a + 7 fmt.Printf("%d", b)a := 5 diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json new file mode 100644 index 000000000..2c7e30d13 --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -0,0 +1,351 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "c4mdperson", + "type": "c4-person", + "pos": { + "x": 0, + "y": 32 + }, + "width": 410, + "height": 390, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson2", + "type": "c4-person", + "pos": { + "x": 470, + "y": 32 + }, + "width": 410, + "height": 390, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson3", + "type": "c4-person", + "pos": { + "x": 940, + "y": 32 + }, + "width": 410, + "height": 390, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_BOTTOM_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer1", + "type": "c4-person", + "pos": { + "x": 1410, + "y": 14 + }, + "width": 448, + "height": 426, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 388, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer2", + "type": "c4-person", + "pos": { + "x": 1918, + "y": 0 + }, + "width": 457, + "height": 453, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 199, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer3", + "type": "c4-person", + "pos": { + "x": 2435, + "y": 10 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer4", + "type": "c4-person", + "pos": { + "x": 2952, + "y": 10 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg new file mode 100644 index 000000000..04eb5c839 --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -0,0 +1,863 @@ +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank ccountskks.

                                                                                            +

                                                                                            Personal Banking Customerk

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +
                                                                                            + + + + + + + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json new file mode 100644 index 000000000..ecf5fb0fd --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -0,0 +1,351 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "c4mdperson", + "type": "c4-person", + "pos": { + "x": 12, + "y": 43 + }, + "width": 410, + "height": 390, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson2", + "type": "c4-person", + "pos": { + "x": 442, + "y": 43 + }, + "width": 410, + "height": 390, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson3", + "type": "c4-person", + "pos": { + "x": 872, + "y": 43 + }, + "width": 410, + "height": 390, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_BOTTOM_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer1", + "type": "c4-person", + "pos": { + "x": 1302, + "y": 25 + }, + "width": 448, + "height": 426, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 388, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer2", + "type": "c4-person", + "pos": { + "x": 1770, + "y": 12 + }, + "width": 457, + "height": 453, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 199, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer3", + "type": "c4-person", + "pos": { + "x": 2247, + "y": 21 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer4", + "type": "c4-person", + "pos": { + "x": 2724, + "y": 21 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg new file mode 100644 index 000000000..6c07ec7b2 --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -0,0 +1,863 @@ +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank ccountskks.

                                                                                            +

                                                                                            Personal Banking Customerk

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            [person]

                                                                                            +

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            +
                                                                                            + + + + + + + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index f14fb0556..bd1bb8ae3 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 544 + "y": 507 }, - "width": 312, - "height": 350, + "width": 336, + "height": 342, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -57,11 +57,11 @@ "id": "c4person", "type": "c4-person", "pos": { - "x": 244, + "x": 260, "y": 0 }, - "width": 135, - "height": 152, + "width": 139, + "height": 132, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 89, - "y": 339 + "x": 101, + "y": 311 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 362, - "y": 293 + "x": 386, + "y": 273 }, "width": 210, - "height": 546, + "height": 525, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 425, - "y": 323 + "x": 449, + "y": 303 }, - "width": 85, - "height": 121, + "width": 84, + "height": 104, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 392, - "y": 629 + "x": 416, + "y": 588 }, "width": 150, "height": 180, @@ -291,20 +291,20 @@ "link": "", "route": [ { - "x": 156, - "y": 454 + "x": 168, + "y": 426 }, { - "x": 156, - "y": 486 + "x": 168, + "y": 450.79998779296875 }, { - "x": 156, - "y": 502.79998779296875 + "x": 168, + "y": 467 }, { - "x": 156, - "y": 538 + "x": 168, + "y": 507 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 245, - "y": 135 + "x": 262, + "y": 119 }, { - "x": 173.8000030517578, - "y": 197 + "x": 186.8000030517578, + "y": 177.8000030517578 }, { - "x": 156, - "y": 286.20001220703125 + "x": 168, + "y": 264.6000061035156 }, { - "x": 156, - "y": 339 + "x": 168, + "y": 311 } ], "isCurve": true, @@ -387,20 +387,20 @@ "link": "", "route": [ { - "x": 379, - "y": 135 + "x": 397, + "y": 119 }, { - "x": 449.3999938964844, - "y": 197 + "x": 472.20001220703125, + "y": 177.8000030517578 }, { - "x": 467, - "y": 283.6000061035156 + "x": 491, + "y": 263 }, { - "x": 467, - "y": 326 + "x": 491, + "y": 303 } ], "isCurve": true, @@ -435,20 +435,20 @@ "link": "", "route": [ { - "x": 467, - "y": 445 + "x": 491, + "y": 407 }, { - "x": 467, - "y": 484.20001220703125 + "x": 491, + "y": 447 }, { - "x": 467, - "y": 520.7990112304688 + "x": 491, + "y": 483.20001220703125 }, { - "x": 467, - "y": 628 + "x": 491, + "y": 588 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 395dc0e3d..1ad380f87 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with
                                                                                            personal bank accounts

                                                                                            -
                                                                                            C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
                                                                                            C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index c9290285f..52e292df6 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 975 + "y": 938 }, - "width": 312, - "height": 350, + "width": 336, + "height": 342, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -57,11 +57,11 @@ "id": "c4person", "type": "c4-person", "pos": { - "x": 201, + "x": 211, "y": 12 }, - "width": 135, - "height": 152, + "width": 139, + "height": 132, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 101, - "y": 790 + "x": 113, + "y": 753 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 244, - "y": 249 + "x": 256, + "y": 229 }, "width": 250, - "height": 471, + "height": 454, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 327, - "y": 299 + "x": 339, + "y": 279 }, - "width": 85, - "height": 121, + "width": 84, + "height": 104, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 294, - "y": 490 + "x": 306, + "y": 453 }, "width": 150, "height": 180, @@ -291,12 +291,12 @@ "link": "", "route": [ { - "x": 168, - "y": 905 + "x": 180, + "y": 868 }, { - "x": 168, - "y": 969 + "x": 180, + "y": 938 } ], "animated": false, @@ -330,20 +330,20 @@ "link": "", "route": [ { - "x": 246, - "y": 165 + "x": 258, + "y": 143 }, { - "x": 246.25, - "y": 204 + "x": 257.5830078125, + "y": 184 }, { - "x": 168, - "y": 204 + "x": 180, + "y": 184 }, { - "x": 168, - "y": 790 + "x": 180, + "y": 753 } ], "animated": false, @@ -377,20 +377,20 @@ "link": "", "route": [ { - "x": 291, - "y": 165 + "x": 304, + "y": 143 }, { - "x": 291.25, - "y": 204 + "x": 303.9159851074219, + "y": 184 }, { - "x": 369.5, - "y": 204 + "x": 381.5, + "y": 184 }, { - "x": 370, - "y": 302 + "x": 382, + "y": 279 } ], "animated": false, @@ -424,12 +424,12 @@ "link": "", "route": [ { - "x": 369, - "y": 421 + "x": 381, + "y": 383 }, { - "x": 370, - "y": 489 + "x": 382, + "y": 453 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index d04252bfb..3d04164c3 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with
                                                                                            personal bank accounts

                                                                                            -
                                                                                            C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
                                                                                            C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index bdb6871ab..4b80ded31 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 1105, + "x": 1089, "y": 0 }, - "width": 383, - "height": 429, + "width": 415, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 586 + "y": 551 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 616 + "y": 581 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 901 + "y": 866 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 901 + "y": 866 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1202 + "y": 1167 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 901 + "y": 866 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1638 + "y": 1603 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1638 + "y": 1603 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 1105, - "y": 279 + "x": 1089, + "y": 262 }, { - "x": 582.5999755859375, - "y": 453.79998779296875 + "x": 579.4000244140625, + "y": 422.3999938964844 }, { "x": 452, - "y": 576 + "y": 541 }, { "x": 452, - "y": 616 + "y": 581 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 779.5 + "y": 744.5 }, { "x": 452, - "y": 828.2999877929688 + "y": 793.2999877929688 }, { "x": 472.3999938964844, - "y": 852.7000122070312 + "y": 817.7000122070312 }, { "x": 554, - "y": 901.5 + "y": 866.5 } ], "isCurve": true, @@ -513,44 +513,44 @@ "link": "", "route": [ { - "x": 1105, - "y": 365 + "x": 1091, + "y": 349 }, { - "x": 970.5999755859375, - "y": 471 + "x": 967.7999877929688, + "y": 439.79998779296875 }, { "x": 937, - "y": 511.20001220703125 + "y": 476.20001220703125 }, { "x": 937, - "y": 531.75 + "y": 496.75 }, { "x": 937, - "y": 552.2999877929688 + "y": 517.2990112304688 }, { "x": 937, - "y": 592.4000244140625 + "y": 557.4000244140625 }, { "x": 937, - "y": 632 + "y": 597 }, { "x": 937, - "y": 671.5999755859375 + "y": 636.5999755859375 }, { "x": 916.5999755859375, - "y": 852.7000122070312 + "y": 817.7000122070312 }, { "x": 835, - "y": 901.5 + "y": 866.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1432, - "y": 428 + "x": 1430, + "y": 394 }, { - "x": 1467.199951171875, - "y": 483.6000061035156 + "x": 1466.800048828125, + "y": 448.79998779296875 }, { "x": 1476, - "y": 511.20001220703125 + "y": 476.20001220703125 }, { "x": 1476, - "y": 531.75 + "y": 496.75 }, { "x": 1476, - "y": 552.2999877929688 + "y": 517.2990112304688 }, { "x": 1476, - "y": 592.4000244140625 + "y": 557.4000244140625 }, { "x": 1476, - "y": 632 + "y": 597 }, { "x": 1476, - "y": 671.5999755859375 + "y": 636.5999755859375 }, { "x": 1476, - "y": 852.7000122070312 + "y": 817.7000122070312 }, { "x": 1476, - "y": 901.5 + "y": 866.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 1064.5 + "y": 1029.5 }, { "x": 694.5, - "y": 1119.699951171875 + "y": 1084.699951171875 }, { "x": 804.7000122070312, - "y": 1154.7220458984375 + "y": 1119.7220458984375 }, { "x": 1245.5, - "y": 1239.6099853515625 + "y": 1204.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 1064.5 + "y": 1029.5 }, { "x": 1476, - "y": 1119.699951171875 + "y": 1084.699951171875 }, { "x": 1476, - "y": 1147.300048828125 + "y": 1112.300048828125 }, { "x": 1476, - "y": 1202.5 + "y": 1167.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1310.1949462890625 + "y": 1275.1949462890625 }, { "x": 500.6990051269531, - "y": 1462.8389892578125 + "y": 1427.8389892578125 }, { "x": 314.5, - "y": 1583.300048828125 + "y": 1548.300048828125 }, { "x": 314.5, - "y": 1638.5 + "y": 1603.5 } ], "isCurve": true, @@ -801,104 +801,104 @@ "link": "", "route": [ { - "x": 1488, - "y": 255 + "x": 1503, + "y": 238 }, { - "x": 2407.199951171875, - "y": 449 + "x": 2410.199951171875, + "y": 417.6000061035156 }, { "x": 2637, - "y": 511.20001220703125 + "y": 476.20001220703125 }, { "x": 2637, - "y": 531.75 + "y": 496.75 }, { "x": 2637, - "y": 552.2999877929688 + "y": 517.2990112304688 }, { "x": 2637, - "y": 592.4000244140625 + "y": 557.4000244140625 }, { "x": 2637, - "y": 632 + "y": 597 }, { "x": 2637, - "y": 671.5999755859375 + "y": 636.5999755859375 }, { "x": 2637, - "y": 726.5 + "y": 691.5 }, { "x": 2637, - "y": 769.25 + "y": 734.25 }, { "x": 2637, - "y": 812 + "y": 777 }, { "x": 2637, - "y": 869 + "y": 834 }, { "x": 2637, - "y": 911.75 + "y": 876.75 }, { "x": 2637, - "y": 954.5 + "y": 919.5 }, { "x": 2637, - "y": 1013.0999755859375 + "y": 978.0999755859375 }, { "x": 2637, - "y": 1058.25 + "y": 1023.25 }, { "x": 2637, - "y": 1103.4000244140625 + "y": 1068.4000244140625 }, { "x": 2637, - "y": 1163.5999755859375 + "y": 1128.5999755859375 }, { "x": 2637, - "y": 1208.75 + "y": 1173.75 }, { "x": 2637, - "y": 1253.9000244140625 + "y": 1218.9000244140625 }, { "x": 2637, - "y": 1327.4000244140625 + "y": 1292.4000244140625 }, { "x": 2637, - "y": 1392.5 + "y": 1357.5 }, { "x": 2637, - "y": 1457.5999755859375 + "y": 1422.5999755859375 }, { "x": 2632.800048828125, - "y": 1583.300048828125 + "y": 1548.300048828125 }, { "x": 2616, - "y": 1638.5 + "y": 1603.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1317.843994140625 + "y": 1282.843994140625 }, { "x": 2241.5, - "y": 1464.3680419921875 + "y": 1429.3680419921875 }, { "x": 2394.39990234375, - "y": 1583.300048828125 + "y": 1548.300048828125 }, { "x": 2472, - "y": 1638.5 + "y": 1603.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 1064.5 + "y": 1029.5 }, { "x": 2206.5, - "y": 1119.699951171875 + "y": 1084.699951171875 }, { "x": 2106.5, - "y": 1154.0999755859375 + "y": 1119.0999755859375 }, { "x": 1706.5, - "y": 1236.5 + "y": 1201.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index 1982bf242..fb2279b45 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts.

                                                                                            -

                                                                                            Internet Banking System

                                                                                            +

                                                                                            Internet Banking System

                                                                                            [Software System]

                                                                                            -

                                                                                            E-mail System

                                                                                            +

                                                                                            E-mail System

                                                                                            [Software System]

                                                                                            The internal Microsoft Exchange e-mail system.

                                                                                            -

                                                                                            Mainframe Banking System

                                                                                            +

                                                                                            Mainframe Banking System

                                                                                            [Software System]

                                                                                            Stores all of the core banking information about customers, accounts, transactions, etc.

                                                                                            -

                                                                                            Web Application

                                                                                            +

                                                                                            Web Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Delivers the static content and the Internet banking single page application.

                                                                                            -

                                                                                            Single-Page Application

                                                                                            +

                                                                                            Single-Page Application

                                                                                            [Container: JavaScript and Angular]

                                                                                            Provides all of the Internet banking functionality to customers via their web browser.

                                                                                            -

                                                                                            Mobile App

                                                                                            +

                                                                                            Mobile App

                                                                                            [Container: Xamarin]

                                                                                            Provides a limited subset of the Internet banking functionality to customers via their mobile device.

                                                                                            -

                                                                                            API Application

                                                                                            +

                                                                                            API Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Provides Internet banking functionality via a JSON/HTTPS API.

                                                                                            -

                                                                                            Database

                                                                                            +

                                                                                            Database

                                                                                            [Container: Oracle Database Schema]

                                                                                            Stores user registration information, hashed authentication credentials, access logs, etc.

                                                                                            -
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index d2a3bd3f0..4d6d3ccd8 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 720, + "x": 704, "y": 12 }, - "width": 383, - "height": 429, + "width": 415, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 693 + "y": 658 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 743 + "y": 708 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 1078 + "y": 1043 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 1078 + "y": 1043 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1429 + "y": 1394 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 1078 + "y": 1043 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 1930 + "y": 1895 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 1930 + "y": 1895 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 797, - "y": 441 + "x": 788, + "y": 406 }, { - "x": 797.3499755859375, - "y": 481 + "x": 787.75, + "y": 446 }, { "x": 359.25, - "y": 481 + "y": 446 }, { "x": 359.25, - "y": 743 + "y": 708 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 907 + "y": 872 }, { "x": 393, - "y": 1078 + "y": 1043 } ], "animated": false, @@ -503,20 +503,20 @@ "link": "", "route": [ { - "x": 874, - "y": 441 + "x": 871, + "y": 406 }, { - "x": 873.9500122070312, - "y": 531 + "x": 870.75, + "y": 496 }, { "x": 652, - "y": 531 + "y": 496 }, { "x": 652, - "y": 1078 + "y": 1043 } ], "animated": false, @@ -550,12 +550,12 @@ "link": "", "route": [ { - "x": 951, - "y": 441 + "x": 954, + "y": 406 }, { - "x": 950.5499877929688, - "y": 1078 + "x": 953.75, + "y": 1043 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1242 + "y": 1207 }, { "x": 494.5, - "y": 1389 + "y": 1354 }, { "x": 1057.25, - "y": 1389 + "y": 1354 }, { "x": 1057.25, - "y": 1429 + "y": 1394 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1242 + "y": 1207 }, { "x": 1172.5, - "y": 1429 + "y": 1394 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1593 + "y": 1558 }, { "x": 1095.666015625, - "y": 1930 + "y": 1895 } ], "animated": false, @@ -714,28 +714,28 @@ "link": "", "route": [ { - "x": 1027, - "y": 441 + "x": 1037, + "y": 406 }, { - "x": 1027.1500244140625, - "y": 481 + "x": 1036.75, + "y": 446 }, { "x": 2303.5, - "y": 481 + "y": 446 }, { "x": 2303.5, - "y": 1890 + "y": 1855 }, { "x": 1986.8330078125, - "y": 1890 + "y": 1855 }, { "x": 1986.8330078125, - "y": 1930 + "y": 1895 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1593 + "y": 1558 }, { "x": 1249.3330078125, - "y": 1890 + "y": 1855 }, { "x": 1866.8330078125, - "y": 1890 + "y": 1855 }, { "x": 1866.8330078125, - "y": 1930 + "y": 1895 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1242 + "y": 1207 }, { "x": 1863, - "y": 1389 + "y": 1354 }, { "x": 1287.75, - "y": 1389 + "y": 1354 }, { "x": 1287.75, - "y": 1429 + "y": 1394 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 52d5d51f4..46f088711 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts.

                                                                                            -

                                                                                            Internet Banking System

                                                                                            +

                                                                                            Internet Banking System

                                                                                            [Software System]

                                                                                            -

                                                                                            E-mail System

                                                                                            +

                                                                                            E-mail System

                                                                                            [Software System]

                                                                                            The internal Microsoft Exchange e-mail system.

                                                                                            -

                                                                                            Mainframe Banking System

                                                                                            +

                                                                                            Mainframe Banking System

                                                                                            [Software System]

                                                                                            Stores all of the core banking information about customers, accounts, transactions, etc.

                                                                                            -

                                                                                            Web Application

                                                                                            +

                                                                                            Web Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Delivers the static content and the Internet banking single page application.

                                                                                            -

                                                                                            Single-Page Application

                                                                                            +

                                                                                            Single-Page Application

                                                                                            [Container: JavaScript and Angular]

                                                                                            Provides all of the Internet banking functionality to customers via their web browser.

                                                                                            -

                                                                                            Mobile App

                                                                                            +

                                                                                            Mobile App

                                                                                            [Container: Xamarin]

                                                                                            Provides a limited subset of the Internet banking functionality to customers via their mobile device.

                                                                                            -

                                                                                            API Application

                                                                                            +

                                                                                            API Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Provides Internet banking functionality via a JSON/HTTPS API.

                                                                                            -

                                                                                            Database

                                                                                            +

                                                                                            Database

                                                                                            [Container: Oracle Database Schema]

                                                                                            Stores user registration information, hashed authentication credentials, access logs, etc.

                                                                                            -
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/dark-theme-md/dagre/board.exp.json b/e2etests/testdata/txtar/dark-theme-md/dagre/board.exp.json new file mode 100644 index 000000000..f3333ec26 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/dagre/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg new file mode 100644 index 000000000..24f2305e8 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg @@ -0,0 +1,907 @@ +

                                                                                            hey

                                                                                            +
                                                                                            + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/dark-theme-md/elk/board.exp.json b/e2etests/testdata/txtar/dark-theme-md/elk/board.exp.json new file mode 100644 index 000000000..c467d88ac --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/elk/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg new file mode 100644 index 000000000..bab4d3d33 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg @@ -0,0 +1,907 @@ +

                                                                                            hey

                                                                                            +
                                                                                            + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/dark-theme-shape/dagre/board.exp.json b/e2etests/testdata/txtar/dark-theme-shape/dagre/board.exp.json new file mode 100644 index 000000000..f3333ec26 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/dagre/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-shape/dagre/sketch.exp.svg new file mode 100644 index 000000000..a297d152f --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/dagre/sketch.exp.svg @@ -0,0 +1,908 @@ +

                                                                                            hey

                                                                                            +
                                                                                            + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/dark-theme-shape/elk/board.exp.json b/e2etests/testdata/txtar/dark-theme-shape/elk/board.exp.json new file mode 100644 index 000000000..c467d88ac --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/elk/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-shape/elk/sketch.exp.svg new file mode 100644 index 000000000..6409b8037 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/elk/sketch.exp.svg @@ -0,0 +1,908 @@ +

                                                                                            hey

                                                                                            +
                                                                                            + + +
                                                                                            \ No newline at end of file diff --git a/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg b/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg index ad52a49f7..194b5f873 100644 --- a/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1707443195-font-regular"; font-size: 16px; @@ -829,10 +828,10 @@ .d2-1707443195 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ÇéþüðæØÅßñò

                                                                                            -

                                                                                            òØõùßÍÿåÆ

                                                                                            -

                                                                                            çÆÐÞ©ßþúí

                                                                                            -

                                                                                            ÉáøÿÑö

                                                                                            +

                                                                                            ÇéþüðæØÅßñò

                                                                                            +

                                                                                            òØõùßÍÿåÆ

                                                                                            +

                                                                                            çÆÐÞ©ßþúí

                                                                                            +

                                                                                            ÉáøÿÑö

                                                                                            diff --git a/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg b/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg index a567f10f4..ecda75aa7 100644 --- a/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1588638235-font-regular"; font-size: 16px; @@ -829,10 +828,10 @@ .d2-1588638235 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ÇéþüðæØÅßñò

                                                                                            -

                                                                                            òØõùßÍÿåÆ

                                                                                            -

                                                                                            çÆÐÞ©ßþúí

                                                                                            -

                                                                                            ÉáøÿÑö

                                                                                            +

                                                                                            ÇéþüðæØÅßñò

                                                                                            +

                                                                                            òØõùßÍÿåÆ

                                                                                            +

                                                                                            çÆÐÞ©ßþúí

                                                                                            +

                                                                                            ÉáøÿÑö

                                                                                            diff --git a/e2etests/testdata/txtar/legend/dagre/board.exp.json b/e2etests/testdata/txtar/legend/dagre/board.exp.json new file mode 100644 index 000000000..838cefcc8 --- /dev/null +++ b/e2etests/testdata/txtar/legend/dagre/board.exp.json @@ -0,0 +1,725 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "api-1", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-2", + "type": "rectangle", + "pos": { + "x": 141, + "y": 166 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "postgres", + "type": "cylinder", + "pos": { + "x": 18, + "y": 332 + }, + "width": 106, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "postgres", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 61, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "external", + "type": "rectangle", + "pos": { + "x": 18, + "y": 550 + }, + "width": 105, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "external", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 60, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-3", + "type": "rectangle", + "pos": { + "x": 0, + "y": 166 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-3", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(api-1 -> postgres)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 8, + "y": 66 + }, + { + "x": -30.399999618530273, + "y": 106 + }, + { + "x": -40, + "y": 132.60000610351562 + }, + { + "x": -40, + "y": 157.5 + }, + { + "x": -40, + "y": 182.39999389648438 + }, + { + "x": -27.399999618530273, + "y": 294.3999938964844 + }, + { + "x": 23, + "y": 344 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-2 -> postgres)[0]", + "src": "api-2", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 181.5, + "y": 232 + }, + { + "x": 181.5, + "y": 272 + }, + { + "x": 169, + "y": 294.3999938964844 + }, + { + "x": 119, + "y": 344 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(postgres -> external)[0]", + "src": "postgres", + "srcArrow": "none", + "dst": "external", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "black", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 71, + "y": 450 + }, + { + "x": 70.80000305175781, + "y": 490 + }, + { + "x": 70.75, + "y": 510 + }, + { + "x": 70.75, + "y": 550 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 <-> api-2)[0]", + "src": "api-1", + "srcArrow": "triangle", + "dst": "api-2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "stroke": "red", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 80.5, + "y": 57 + }, + { + "x": 161.3000030517578, + "y": 104.19999694824219 + }, + { + "x": 181.5, + "y": 126 + }, + { + "x": 181.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 -> api-3)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "api-3", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 40.5, + "y": 66 + }, + { + "x": 40.5, + "y": 106 + }, + { + "x": 40.5, + "y": 126 + }, + { + "x": 40.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + }, + "legend": { + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Microservice", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "cylinder", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B2", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Database", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a <-> b)[0]", + "src": "a", + "srcArrow": "triangle", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 1, + "stroke": "red", + "borderRadius": 10, + "label": "Good relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Bad relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[1]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Tenuous", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] + } +} diff --git a/e2etests/testdata/txtar/legend/dagre/sketch.exp.svg b/e2etests/testdata/txtar/legend/dagre/sketch.exp.svg new file mode 100644 index 000000000..47b7b2a65 --- /dev/null +++ b/e2etests/testdata/txtar/legend/dagre/sketch.exp.svg @@ -0,0 +1,106 @@ +api-1api-2postgresexternalapi-3 LegendMicroserviceDatabase Good relationship Bad relationship Tenuous + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/legend/elk/board.exp.json b/e2etests/testdata/txtar/legend/elk/board.exp.json new file mode 100644 index 000000000..5376eae0a --- /dev/null +++ b/e2etests/testdata/txtar/legend/elk/board.exp.json @@ -0,0 +1,684 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "api-1", + "type": "rectangle", + "pos": { + "x": 45, + "y": 12 + }, + "width": 120, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-2", + "type": "rectangle", + "pos": { + "x": 65, + "y": 158 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "postgres", + "type": "cylinder", + "pos": { + "x": 12, + "y": 304 + }, + "width": 106, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "postgres", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 61, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "external", + "type": "rectangle", + "pos": { + "x": 12, + "y": 492 + }, + "width": 105, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "external", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 60, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-3", + "type": "rectangle", + "pos": { + "x": 166, + "y": 158 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-3", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(api-1 -> postgres)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 75.75, + "y": 78 + }, + { + "x": 75.75, + "y": 118 + }, + { + "x": 24.249000549316406, + "y": 118 + }, + { + "x": 24, + "y": 311 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-2 -> postgres)[0]", + "src": "api-2", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 82.66600036621094, + "y": 224 + }, + { + "x": 83, + "y": 305 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(postgres -> external)[0]", + "src": "postgres", + "srcArrow": "none", + "dst": "external", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "black", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 65, + "y": 422 + }, + { + "x": 65, + "y": 492 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 <-> api-2)[0]", + "src": "api-1", + "srcArrow": "triangle", + "dst": "api-2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "stroke": "red", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 105.75, + "y": 78 + }, + { + "x": 105.75, + "y": 158 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 -> api-3)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "api-3", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 135.75, + "y": 78 + }, + { + "x": 135.75, + "y": 118 + }, + { + "x": 206.75, + "y": 118 + }, + { + "x": 206.75, + "y": 158 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + }, + "legend": { + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Microservice", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "cylinder", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B2", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Database", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a <-> b)[0]", + "src": "a", + "srcArrow": "triangle", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 1, + "stroke": "red", + "borderRadius": 10, + "label": "Good relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Bad relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[1]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Tenuous", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] + } +} diff --git a/e2etests/testdata/txtar/legend/elk/sketch.exp.svg b/e2etests/testdata/txtar/legend/elk/sketch.exp.svg new file mode 100644 index 000000000..1cf312712 --- /dev/null +++ b/e2etests/testdata/txtar/legend/elk/sketch.exp.svg @@ -0,0 +1,106 @@ +api-1api-2postgresexternalapi-3 LegendMicroserviceDatabase Good relationship Bad relationship Tenuous + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg index ec78bb5e4..e7d517e10 100644 --- a/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1825138808-font-regular"; font-size: 16px; @@ -829,87 +828,87 @@ .d2-1825138808 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world
                                                                                            diff --git a/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg index 4f349e4dd..85a829529 100644 --- a/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1030734791-font-regular"; font-size: 16px; @@ -829,87 +828,87 @@ .d2-1030734791 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world
                                                                                            diff --git a/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg b/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg index 1ab58f720..39d31759f 100644 --- a/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg @@ -134,7 +134,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1180799665-font-regular"; font-size: 16px; @@ -842,7 +841,7 @@ .d2-1180799665 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                                            +
                                                                                            @@ -872,7 +871,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -890,7 +889,7 @@
                                                                                            Status
                                                                                            -
                                                                                            +
                                                                                            @@ -934,7 +933,7 @@
                                                                                            Metric
                                                                                            Financial Overview -System HealthProject TrackingTeam Analytics
                                                                                            +System HealthProject TrackingTeam Analytics
                                                                                            @@ -964,7 +963,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -988,7 +987,7 @@
                                                                                            Quarter
                                                                                            -
                                                                                            +
                                                                                            @@ -1018,7 +1017,7 @@
                                                                                            Service
                                                                                            -
                                                                                            +
                                                                                            @@ -1048,7 +1047,7 @@
                                                                                            Metric
                                                                                            -
                                                                                            +
                                                                                            @@ -1082,7 +1081,7 @@
                                                                                            Project
                                                                                            -
                                                                                            +
                                                                                            @@ -1112,7 +1111,7 @@
                                                                                            Risk ID
                                                                                            -
                                                                                            +
                                                                                            diff --git a/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg b/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg index 1665ba5f7..77b317076 100644 --- a/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg @@ -134,7 +134,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3839636311-font-regular"; font-size: 16px; @@ -842,7 +841,7 @@ .d2-3839636311 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                                            Sprint
                                                                                            +
                                                                                            @@ -872,7 +871,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -890,7 +889,7 @@
                                                                                            Status
                                                                                            -
                                                                                            +
                                                                                            @@ -934,7 +933,7 @@
                                                                                            Metric
                                                                                            Financial Overview -System HealthProject TrackingTeam Analytics
                                                                                            +System HealthProject TrackingTeam Analytics
                                                                                            @@ -964,7 +963,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -988,7 +987,7 @@
                                                                                            Quarter
                                                                                            -
                                                                                            +
                                                                                            @@ -1018,7 +1017,7 @@
                                                                                            Service
                                                                                            -
                                                                                            +
                                                                                            @@ -1048,7 +1047,7 @@
                                                                                            Metric
                                                                                            -
                                                                                            +
                                                                                            @@ -1082,7 +1081,7 @@
                                                                                            Project
                                                                                            -
                                                                                            +
                                                                                            @@ -1112,7 +1111,7 @@
                                                                                            Risk ID
                                                                                            -
                                                                                            +
                                                                                            diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg index 9ebd14667..396afe4f4 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2097271006-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-2097271006 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            +xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            • ...dramatic pause
                                                                                            diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg index 9ebd14667..396afe4f4 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2097271006-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-2097271006 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            +xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            • ...dramatic pause
                                                                                            diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json new file mode 100644 index 000000000..999037997 --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "c4-person", + "pos": { + "x": 0, + "y": 0 + }, + "width": 180, + "height": 97, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c4-person", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 71, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg new file mode 100644 index 000000000..a743498d0 --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -0,0 +1,95 @@ +c4-person + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json new file mode 100644 index 000000000..a6f4b3250 --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "c4-person", + "pos": { + "x": 12, + "y": 12 + }, + "width": 180, + "height": 97, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c4-person", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 71, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg new file mode 100644 index 000000000..fa51d71b6 --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -0,0 +1,95 @@ +c4-person + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg b/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg index 706b867d0..64a04313d 100644 --- a/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-826738456-font-regular"; font-size: 16px; @@ -843,9 +842,9 @@ .d2-826738456 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            -
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            diff --git a/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg b/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg index 2044c42c1..8f27c2e08 100644 --- a/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3895587399-font-regular"; font-size: 16px; @@ -843,9 +842,9 @@ .d2-3895587399 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            -
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            diff --git a/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg b/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg index b58bc204d..2154cc52a 100644 --- a/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2855145504-font-regular"; font-size: 16px; @@ -829,18 +828,18 @@ .d2-2855145504 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ■ foo bar

                                                                                            -

                                                                                            □ foo bar

                                                                                            -

                                                                                            ● foo bar

                                                                                            -

                                                                                            ○ foo bar

                                                                                            -

                                                                                            ◆ foo bar

                                                                                            -

                                                                                            ◇ foo bar

                                                                                            -

                                                                                            ▲ foo bar

                                                                                            -

                                                                                            △ foo bar

                                                                                            -

                                                                                            ▼ foo bar

                                                                                            -

                                                                                            ▽ foo bar

                                                                                            -

                                                                                            ※ foo bar

                                                                                            -

                                                                                            ◎ foo bar

                                                                                            +

                                                                                            ■ foo bar

                                                                                            +

                                                                                            □ foo bar

                                                                                            +

                                                                                            ● foo bar

                                                                                            +

                                                                                            ○ foo bar

                                                                                            +

                                                                                            ◆ foo bar

                                                                                            +

                                                                                            ◇ foo bar

                                                                                            +

                                                                                            ▲ foo bar

                                                                                            +

                                                                                            △ foo bar

                                                                                            +

                                                                                            ▼ foo bar

                                                                                            +

                                                                                            ▽ foo bar

                                                                                            +

                                                                                            ※ foo bar

                                                                                            +

                                                                                            ◎ foo bar

                                                                                            diff --git a/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg b/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg index fb1d9c406..70bcda3cd 100644 --- a/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2037265600-font-regular"; font-size: 16px; @@ -829,18 +828,18 @@ .d2-2037265600 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ■ foo bar

                                                                                            -

                                                                                            □ foo bar

                                                                                            -

                                                                                            ● foo bar

                                                                                            -

                                                                                            ○ foo bar

                                                                                            -

                                                                                            ◆ foo bar

                                                                                            -

                                                                                            ◇ foo bar

                                                                                            -

                                                                                            ▲ foo bar

                                                                                            -

                                                                                            △ foo bar

                                                                                            -

                                                                                            ▼ foo bar

                                                                                            -

                                                                                            ▽ foo bar

                                                                                            -

                                                                                            ※ foo bar

                                                                                            -

                                                                                            ◎ foo bar

                                                                                            +

                                                                                            ■ foo bar

                                                                                            +

                                                                                            □ foo bar

                                                                                            +

                                                                                            ● foo bar

                                                                                            +

                                                                                            ○ foo bar

                                                                                            +

                                                                                            ◆ foo bar

                                                                                            +

                                                                                            ◇ foo bar

                                                                                            +

                                                                                            ▲ foo bar

                                                                                            +

                                                                                            △ foo bar

                                                                                            +

                                                                                            ▼ foo bar

                                                                                            +

                                                                                            ▽ foo bar

                                                                                            +

                                                                                            ※ foo bar

                                                                                            +

                                                                                            ◎ foo bar

                                                                                            diff --git a/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg b/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg index 784187af7..0415cf700 100644 --- a/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2758569173-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2758569173 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Kube

                                                                                            Kube is a service

                                                                                            +Kube

                                                                                            Kube is a service

                                                                                            Let ${y} be ${x}
                                                                                             
                                                                                            ba diff --git a/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg b/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg index c1f320e40..cac976c17 100644 --- a/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3193381320-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3193381320 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Kube

                                                                                            Kube is a service

                                                                                            +Kube

                                                                                            Kube is a service

                                                                                            Let ${y} be ${x}
                                                                                             
                                                                                            ba diff --git a/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg b/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg index 12fccda37..170363eda 100644 --- a/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg +++ b/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2865261911-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2865261911 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            床前明月光,

                                                                                            +

                                                                                            床前明月光,

                                                                                            疑是地上霜。

                                                                                            举头望明月,

                                                                                            低头思故乡。

                                                                                            diff --git a/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg index dd1d64083..cb250c0ce 100644 --- a/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg +++ b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1123938073-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1123938073 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            床前明月光,

                                                                                            +

                                                                                            床前明月光,

                                                                                            疑是地上霜。

                                                                                            举头望明月,

                                                                                            低头思故乡。

                                                                                            diff --git a/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg index 241e39a4c..764cc9f0b 100644 --- a/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg +++ b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2872220387-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2872220387 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

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

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

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

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

                                                                                            diff --git a/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg index cc489394d..fb4388fa5 100644 --- a/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg +++ b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-40175756-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-40175756 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

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

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

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

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

                                                                                            diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index 731562a89..06e97382a 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1046,103 +1046,137 @@ c4person -> styling.c4styled -> styling.c4sized style.stroke-width: 1 } --- c4-theme -- - +-- legend -- vars: { - d2-config: { - theme-id: 303 + d2-legend: { + a: { + label: Microservice + } + b: Database { + shape: cylinder + style.stroke-dash: 2 + } + a <-> b: Good relationship { + style.stroke: red + style.stroke-dash: 2 + style.stroke-width: 1 + } + a -> b: Bad relationship + a -> b: Tenuous { + target-arrowhead.shape: circle + } } } -customer: |md +api-1 +api-2 + +api-1 -> postgres +api-2 -> postgres + +postgres: { + shape: cylinder +} +postgres -> external: { + style.stroke: black +} + +api-1 <-> api-2: { + style.stroke: red + style.stroke-dash: 2 +} +api-1 -> api-3: { + target-arrowhead.shape: circle +} + +-- dark-theme-md -- + +vars: { + d2-config: { + dark-theme-id: 200 + } +} +a.shape: rectangle +a: |md + # hey +| + +-- small-c4-person -- + +a.shape: c4-person +a: c4-person +a.width: 180 + +-- c4-person-label -- +c4mdperson: |md +## Personal Banking Customer + +[person] + +A customer of the bank, with personal bank accounts + | { + shape: c4-person + label.near: center-center + } + +c4mdperson2: |md +## Personal Banking Customer + +[person] + +A customer of the bank, with personal bank accounts + | { + shape: c4-person + label.near: top-center + } + +c4mdperson3: |md +## Personal Banking Customer + +[person] + +A customer of the bank, with personal bank accounts + | { + shape: c4-person + label.near: bottom-center + } + +customer1: |md ## Personal Banking Customer [person] - A customer of the bank, with personal bank accounts. + A customer of the bank, with pekkrsonal bank ccountskks. | { shape: c4-person } -internet_banking_system: |md - ## Internet Banking System - [Software System] +customer2: |md + ## Personal Banking Customerk + [person] + + A customer of the bank, with pekkrsonal bank accountskks. + + A customer of the bank, with pekkrsonal bank accountskks. + + A customer of the bank, with pekkrsonal bank accountskks. | { - shape: rectangle - label.near: bottom-left + shape: c4-person } -internet_banking_system.web_app: |md - ## Web Application - [Container: Java and Spring MVC] +customer3: |md + ## Personal Banking Customer + [person] - Delivers the static content and the Internet banking single page application. + A customer of the bank, with pekkrsonal bank accountskks. | { - shape: rectangle + shape: c4-person } -internet_banking_system.spa: |md - ## Single-Page Application - [Container: JavaScript and Angular] +customer4: |md + ## Personal Banking Customer + [person] - Provides all of the Internet banking functionality to customers via their web browser. + A customer of the bank, with pekkrsonal bank accountskks. | { - shape: rectangle + shape: c4-person } - -internet_banking_system.mobile_app: |md - ## Mobile App - [Container: Xamarin] - - Provides a limited subset of the Internet banking functionality to customers via their mobile device. -| { - shape: rectangle -} - -internet_banking_system.api_app: |md - ## API Application - [Container: Java and Spring MVC] - - Provides Internet banking functionality via a JSON/HTTPS API. -| { - shape: rectangle -} - -internet_banking_system.database: |md - ## Database - [Container: Oracle Database Schema] - - Stores user registration information, hashed authentication credentials, access logs, etc. -| { - shape: rectangle -} - -email_system: |md - ## E-mail System - [Software System] - - The internal Microsoft Exchange e-mail system. -| { - shape: rectangle -} - -mainframe: |md - ## Mainframe Banking System - [Software System] - - Stores all of the core banking information about customers, accounts, transactions, etc. -| { - shape: rectangle -} - -# Connections -customer -> internet_banking_system.web_app: "Visits bigbank.com/ib using\n[HTTPS]" -internet_banking_system.web_app -> internet_banking_system.spa: "Delivers to the customer's web browser" -customer -> internet_banking_system.spa: "Views account balances, and makes payments using" -customer -> internet_banking_system.mobile_app: "Views account balances, and makes payments using" -internet_banking_system.spa -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" -internet_banking_system.mobile_app -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" -internet_banking_system.api_app -> mainframe: "Makes API calls to\n[XML/HTTPS]" -customer -> email_system: "Sends e-mails to" -internet_banking_system.api_app -> email_system: "Sends e-mail using" -internet_banking_system.database <-> internet_banking_system.api_app: "Reads from and writes to\n[SQL/TCP]" - diff --git a/lib/shape/shape.go b/lib/shape/shape.go index 6e3e0b81b..6dd6cec7a 100644 --- a/lib/shape/shape.go +++ b/lib/shape/shape.go @@ -21,7 +21,7 @@ const ( CALLOUT_TYPE = "Callout" STORED_DATA_TYPE = "StoredData" PERSON_TYPE = "Person" - C4_PERSON_TYPE = "c4-person" + C4_PERSON_TYPE = "C4Person" DIAMOND_TYPE = "Diamond" OVAL_TYPE = "Oval" CIRCLE_TYPE = "Circle" diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index eb70c2a62..9424347a1 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -8,8 +8,13 @@ import ( "oss.terrastruct.com/util-go/go2" ) -// Optimal value for circular arc approximation with cubic bezier curves -const kCircleApprox = 0.5522847498307936 // 4*(math.Sqrt(2)-1)/3 +// Constants to match frontend implementation +const ( + C4_PERSON_AR_LIMIT = 1.5 + HEAD_RADIUS_FACTOR = 0.22 + BODY_TOP_FACTOR = 0.8 + CORNER_RADIUS_FACTOR = 0.175 +) type shapeC4Person struct { *baseShape @@ -26,25 +31,25 @@ func NewC4Person(box *geo.Box) Shape { return shape } -const ( - C4_PERSON_AR_LIMIT = 1.5 -) - func (s shapeC4Person) GetInnerBox() *geo.Box { width := s.Box.Width height := s.Box.Height - headRadius := width * 0.22 - headCenterY := height * 0.18 - bodyTop := headCenterY + headRadius*0.8 + headRadius := width * HEAD_RADIUS_FACTOR + headCenterY := headRadius + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR + + // Horizontal padding = 5% of width + horizontalPadding := width * 0.05 + // Vertical padding = 3% of height + verticalPadding := height * 0.03 tl := s.Box.TopLeft.Copy() - horizontalPadding := width * 0.1 tl.X += horizontalPadding - tl.Y += bodyTop + height*0.05 + tl.Y += bodyTop + verticalPadding innerWidth := width - (horizontalPadding * 2) - innerHeight := height - tl.Y + s.Box.TopLeft.Y - (height * 0.05) + innerHeight := height - bodyTop - (verticalPadding * 2) return geo.NewBox(tl, innerWidth, innerHeight) } @@ -55,23 +60,25 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * 0.22 - headCenterY := height * 0.18 - bodyTop := headCenterY + headRadius*0.8 + headRadius := width * HEAD_RADIUS_FACTOR + headCenterY := headRadius + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR bodyWidth := width bodyHeight := height - bodyTop bodyLeft := 0 - cornerRadius := width * 0.175 + + // Use the same corner radius calculation as frontend + cornerRadius := math.Min(width*CORNER_RADIUS_FACTOR, bodyHeight*0.25) pc.StartAt(pc.Absolute(float64(bodyLeft), bodyTop+cornerRadius)) - pc.C(true, 0, -kCircleApprox*cornerRadius, kCircleApprox*cornerRadius, -cornerRadius, cornerRadius, -cornerRadius) + pc.C(true, 0, -4*(math.Sqrt(2)-1)/3*cornerRadius, 4*(math.Sqrt(2)-1)/3*cornerRadius, -cornerRadius, cornerRadius, -cornerRadius) pc.H(true, bodyWidth-2*cornerRadius) - pc.C(true, kCircleApprox*cornerRadius, 0, cornerRadius, kCircleApprox*cornerRadius, cornerRadius, cornerRadius) + pc.C(true, 4*(math.Sqrt(2)-1)/3*cornerRadius, 0, cornerRadius, 4*(math.Sqrt(2)-1)/3*cornerRadius, cornerRadius, cornerRadius) pc.V(true, bodyHeight-2*cornerRadius) - pc.C(true, 0, kCircleApprox*cornerRadius, -kCircleApprox*cornerRadius, cornerRadius, -cornerRadius, cornerRadius) + pc.C(true, 0, 4*(math.Sqrt(2)-1)/3*cornerRadius, -4*(math.Sqrt(2)-1)/3*cornerRadius, cornerRadius, -cornerRadius, cornerRadius) pc.H(true, -(bodyWidth - 2*cornerRadius)) - pc.C(true, -kCircleApprox*cornerRadius, 0, -cornerRadius, -kCircleApprox*cornerRadius, -cornerRadius, -cornerRadius) + pc.C(true, -4*(math.Sqrt(2)-1)/3*cornerRadius, 0, -cornerRadius, -4*(math.Sqrt(2)-1)/3*cornerRadius, -cornerRadius, -cornerRadius) pc.Z() return pc @@ -79,34 +86,33 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { func headPath(box *geo.Box) *svg.SvgPathContext { width := box.Width - height := box.Height pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * 0.22 + headRadius := width * HEAD_RADIUS_FACTOR headCenterX := width / 2 - headCenterY := height * 0.18 + headCenterY := headRadius pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius)) pc.C(false, - headCenterX+headRadius*kCircleApprox, headCenterY-headRadius, - headCenterX+headRadius, headCenterY-headRadius*kCircleApprox, + headCenterX+headRadius*4*(math.Sqrt(2)-1)/3, headCenterY-headRadius, + headCenterX+headRadius, headCenterY-headRadius*4*(math.Sqrt(2)-1)/3, headCenterX+headRadius, headCenterY) pc.C(false, - headCenterX+headRadius, headCenterY+headRadius*kCircleApprox, - headCenterX+headRadius*kCircleApprox, headCenterY+headRadius, + headCenterX+headRadius, headCenterY+headRadius*4*(math.Sqrt(2)-1)/3, + headCenterX+headRadius*4*(math.Sqrt(2)-1)/3, headCenterY+headRadius, headCenterX, headCenterY+headRadius) pc.C(false, - headCenterX-headRadius*kCircleApprox, headCenterY+headRadius, - headCenterX-headRadius, headCenterY+headRadius*kCircleApprox, + headCenterX-headRadius*4*(math.Sqrt(2)-1)/3, headCenterY+headRadius, + headCenterX-headRadius, headCenterY+headRadius*4*(math.Sqrt(2)-1)/3, headCenterX-headRadius, headCenterY) pc.C(false, - headCenterX-headRadius, headCenterY-headRadius*kCircleApprox, - headCenterX-headRadius*kCircleApprox, headCenterY-headRadius, + headCenterX-headRadius, headCenterY-headRadius*4*(math.Sqrt(2)-1)/3, + headCenterX-headRadius*4*(math.Sqrt(2)-1)/3, headCenterY-headRadius, headCenterX, headCenterY-headRadius) return pc @@ -114,13 +120,12 @@ func headPath(box *geo.Box) *svg.SvgPathContext { func (s shapeC4Person) Perimeter() []geo.Intersectable { width := s.Box.Width - height := s.Box.Height bodyPerimeter := bodyPath(s.Box).Path - headRadius := width * 0.22 + headRadius := width * HEAD_RADIUS_FACTOR headCenterX := s.Box.TopLeft.X + width/2 - headCenterY := s.Box.TopLeft.Y + height*0.18 + headCenterY := s.Box.TopLeft.Y + headRadius headCenter := geo.NewPoint(headCenterX, headCenterY) headEllipse := geo.NewEllipse(headCenter, headRadius, headRadius) @@ -136,19 +141,31 @@ func (s shapeC4Person) GetSVGPathData() []string { } func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { - totalWidth := width + paddingX - totalHeight := height + paddingY + contentWidth := width + paddingX + contentHeight := height + paddingY - if totalHeight < totalWidth*0.8 { - totalHeight = totalWidth * 0.8 + // Account for 10% total horizontal padding (5% on each side) + totalWidth := contentWidth / 0.9 + headRadius := totalWidth * HEAD_RADIUS_FACTOR + + // Use positioning matching frontend + headCenterY := headRadius + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR + + // Include vertical padding + verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom + totalHeight := contentHeight + bodyTop + verticalPadding + + // Calculate minimum height + minHeight := totalWidth * 0.95 + if totalHeight < minHeight { + totalHeight = minHeight } - totalHeight *= 1.4 - totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, C4_PERSON_AR_LIMIT) return math.Ceil(totalWidth), math.Ceil(totalHeight) } func (s shapeC4Person) GetDefaultPadding() (paddingX, paddingY float64) { - return 20, defaultPadding * 1.5 + return 10, defaultPadding } diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json new file mode 100644 index 000000000..183600210 --- /dev/null +++ b/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json @@ -0,0 +1,319 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-10:0:65", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-4:1:26", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-0:4:4", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:6:6-4:1:26", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:2:10-3:3:24", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:2:10-1:3:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:2:10-1:3:11", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:5:13-3:3:24", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-9:1:64", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:3:31-9:1:64", + "nodes": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,7:2:35-7:9:42", + "spread": true, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,7:7:40-7:8:41", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:19:62", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:14:57", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:3:46", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:4:47-8:9:52", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:10:53-8:14:57", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:16:59-8:19:62", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "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 + }, + { + "id": "1", + "id_val": "1", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "1" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "fill": { + "value": "red" + } + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars/1.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars/1.exp.json new file mode 100644 index 000000000..b973d1850 --- /dev/null +++ b/testdata/d2compiler/TestCompile/glob-spread-vars/1.exp.json @@ -0,0 +1,319 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-10:0:65", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-4:1:26", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-0:4:4", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:6:6-4:1:26", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:2:10-3:3:24", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:2:10-1:3:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:2:10-1:3:11", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:5:13-3:3:24", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-9:1:64", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:3:31-9:1:64", + "nodes": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,7:2:35-7:9:42", + "spread": true, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,7:7:40-7:8:41", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:2:45-8:19:62", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:2:45-8:14:57", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:2:45-8:3:46", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:4:47-8:9:52", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:10:53-8:14:57", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:16:59-8:19:62", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "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 + }, + { + "id": "1", + "id_val": "1", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "1" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "fill": { + "value": "red" + } + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json new file mode 100644 index 000000000..52b3ca111 --- /dev/null +++ b/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json @@ -0,0 +1,578 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-13:0:66", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-5:1:30", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-0:4:4", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:6:6-5:1:30", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-4:3:28", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-1:3:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-1:3:11", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:5:13-4:3:28", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "value": [ + { + "string": "2", + "raw_string": "2" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-10:1:61", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:3:35-10:1:61", + "nodes": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:39-8:9:46", + "spread": true, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:7:44-8:8:45", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:12:59", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:12:59", + "src": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:4:51", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:4:51", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:12:59", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:9:56", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:10:57-9:12:59", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "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": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", + "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 + }, + { + "id": "1", + "id_val": "1", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "1" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "2", + "id_val": "2", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "value": [ + { + "string": "2", + "raw_string": "2" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "2" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "ok", + "id_val": "ok", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:12:59", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:9:56", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:10:57-9:12:59", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:12:59", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:9:56", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:10:57-9:12:59", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "ok" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/import-var-chain.exp.json b/testdata/d2compiler/TestCompile/import-var-chain.exp.json new file mode 100644 index 000000000..8868dcdb7 --- /dev/null +++ b/testdata/d2compiler/TestCompile/import-var-chain.exp.json @@ -0,0 +1,57 @@ +{ + "graph": { + "name": "", + "isFolderOnly": true, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/import-var-chain.d2,0:0:0-1:0:8", + "nodes": [ + { + "import": { + "range": "d2/testdata/d2compiler/TestCompile/import-var-chain.d2,0:0:0-0:7:7", + "spread": true, + "pre": "", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-var-chain.d2,0:4:4-0:7:7", + "value": [ + { + "string": "dev", + "raw_string": "dev" + } + ] + } + } + ] + } + } + ] + }, + "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": null + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/url_relative_link.exp.json b/testdata/d2compiler/TestCompile/url_relative_link.exp.json new file mode 100644 index 000000000..a781e613f --- /dev/null +++ b/testdata/d2compiler/TestCompile/url_relative_link.exp.json @@ -0,0 +1,148 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-3:0:23", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-2:1:22", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:3:3-2:1:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:2:7-1:15:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:2:7-1:6:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:2:7-1:6:11", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:8:13-1:15:20", + "value": [ + { + "string": "/google", + "raw_string": "/google" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.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" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "link": { + "value": "/google" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json index c5174da58..bfff699cf 100644 --- a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json +++ b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json @@ -629,102 +629,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -763,36 +667,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -837,24 +711,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, diff --git a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json index 11dcad205..f42ea6df7 100644 --- a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json +++ b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json @@ -1150,102 +1150,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -1284,36 +1188,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -1358,24 +1232,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, diff --git a/testdata/d2compiler/TestCompile2/globs/suspend-shape.exp.json b/testdata/d2compiler/TestCompile2/globs/suspend-shape.exp.json new file mode 100644 index 000000000..baf429ece --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/suspend-shape.exp.json @@ -0,0 +1,101 @@ +{ + "graph": { + "name": "", + "isFolderOnly": true, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,0:0:0-3:0:21", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:0:1-1:8:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:3:4-1:8:9", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:0:10-2:10:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:0:10-2:1:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:0:10-2:1:11", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:3:13-2:10:20", + "value": true + } + } + } + } + ] + }, + "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": null + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.exp.json new file mode 100644 index 000000000..70fca048f --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.exp.json @@ -0,0 +1,766 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,0:0:0-13:0:121", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-3:1:11", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:3:4-3:1:11", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-6:1:22", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:3:15-6:1:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:17:40", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:10:33", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:12:35-7:17:40", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:0:41-8:11:52", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:0:41-8:2:43", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:0:41-8:2:43", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:4:45-8:11:52", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:0:53-9:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:1:54-9:9:62", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:1:54-9:3:56", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:1:54-9:3:56", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:7:60-9:9:62", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:7:60-9:9:62", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:10:63-9:13:66", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:15:68-9:22:75", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:0:76-12:1:120", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:1:77-10:9:85", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:1:77-10:3:79", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:1:77-10:3:79", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:7:83-10:9:85", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:7:83-10:9:85", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:10:86-10:13:89", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:15:91-10:24:100", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:25:101-12:1:120", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:2:105-11:15:118", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:3:106-11:8:111", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:3:106-11:8:111", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:10:113-11:15:118", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "likes" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "d", + "id_val": "d", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "d" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.exp.json new file mode 100644 index 000000000..0cc431588 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.exp.json @@ -0,0 +1,490 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,0:0:0-10:0:94", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-3:1:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:3:4-3:1:16", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:8:14", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:8:14", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:11:29", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:2:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:2:20", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:4:22-5:11:29", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:0:30-6:22:52", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:9:39", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:3:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:3:33", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:7:37-6:9:39", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:7:37-6:9:39", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:10:40-6:13:43", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:15:45-6:22:52", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:0:53-9:1:93", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:9:62", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:3:56", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:3:56", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:7:60-7:9:62", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:7:60-7:9:62", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:10:63-7:13:66", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:15:68-7:24:77", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:25:78-9:1:93", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:2:82-8:11:91", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:3:83-8:6:86", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:3:83-8:6:86", + "value": [ + { + "string": "dst", + "raw_string": "dst" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:8:88-8:11:91", + "value": [ + { + "string": "a.c", + "raw_string": "a.c" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "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 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.exp.json new file mode 100644 index 000000000..aaf8ce50e --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.exp.json @@ -0,0 +1,284 @@ +{ + "graph": { + "name": "", + "isFolderOnly": true, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,0:0:0-7:0:80", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:6:7", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:6:7", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:0:8-2:11:19", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:0:8-2:2:10", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:0:8-2:2:10", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:4:12-2:11:19", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:0:20-3:22:42", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:1:21-3:9:29", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:1:21-3:3:23", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:1:21-3:3:23", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:7:27-3:9:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:7:27-3:9:29", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:10:30-3:13:33", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:15:35-3:22:42", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:0:43-6:1:79", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:1:44-4:7:50", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:1:44-4:2:45", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:1:44-4:2:45", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:6:49-4:7:50", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:6:49-4:7:50", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:8:51-4:11:54", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:13:56-4:22:65", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:23:66-6:1:79", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:2:70-5:9:77", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:3:71-5:6:74", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:3:71-5:6:74", + "value": [ + { + "string": "dst", + "raw_string": "dst" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:8:76-5:9:77", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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": null + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.exp.json new file mode 100644 index 000000000..c3508fbc6 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.exp.json @@ -0,0 +1,577 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,0:0:0-13:0:121", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-3:1:11", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:3:4-3:1:11", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:0:12-6:1:22", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:0:12-4:1:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:0:12-4:1:13", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:3:15-6:1:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,5:2:19-5:3:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,5:2:19-5:3:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,5:2:19-5:3:20", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:17:40", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:10:33", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:12:35-7:17:40", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:0:41-8:11:52", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:0:41-8:2:43", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:0:41-8:2:43", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:4:45-8:11:52", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:0:53-9:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:1:54-9:9:62", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:1:54-9:3:56", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:1:54-9:3:56", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:7:60-9:9:62", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:7:60-9:9:62", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:10:63-9:13:66", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:15:68-9:22:75", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:0:76-12:1:120", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:1:77-10:9:85", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:1:77-10:3:79", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:1:77-10:3:79", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:7:83-10:9:85", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:7:83-10:9:85", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:10:86-10:13:89", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:15:91-10:24:100", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:25:101-12:1:120", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:2:105-11:15:118", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:3:106-11:8:111", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:3:106-11:8:111", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:10:113-11:15:118", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.exp.json new file mode 100644 index 000000000..d33cb9b7c --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.exp.json @@ -0,0 +1,405 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,0:0:0-7:0:76", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:13:14", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:6:7", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:8:9-1:13:14", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,2:0:15-2:1:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,2:0:15-2:1:16", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,2:0:15-2:1:16", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:0:17-3:11:28", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:0:17-3:2:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:0:17-3:2:19", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:4:21-3:11:28", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:0:29-4:22:51", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:1:30-4:9:38", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:1:30-4:3:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:1:30-4:3:32", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:7:36-4:9:38", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:7:36-4:9:38", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:10:39-4:13:42", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:15:44-4:22:51", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:0:53-6:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:1:54-6:7:60", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:1:54-6:2:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:1:54-6:2:55", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:6:59-6:7:60", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:6:59-6:7:60", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:8:61-6:11:64", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:13:66-6:22:75", + "value": false + } + } + } + } + ] + }, + "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": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "hello" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-label.exp.json new file mode 100644 index 000000000..3a0edc892 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-label.exp.json @@ -0,0 +1,405 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,0:0:0-7:0:76", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:13:14", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:6:7", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:8:9-1:13:14", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,2:0:15-2:1:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,2:0:15-2:1:16", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,2:0:15-2:1:16", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:0:17-3:11:28", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:0:17-3:2:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:0:17-3:2:19", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:4:21-3:11:28", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:0:29-4:22:51", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:1:30-4:9:38", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:1:30-4:3:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:1:30-4:3:32", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:7:36-4:9:38", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:7:36-4:9:38", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:10:39-4:13:42", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:15:44-4:22:51", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:0:53-6:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:1:54-6:7:60", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:1:54-6:2:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:1:54-6:2:55", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:6:59-6:7:60", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:6:59-6:7:60", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:8:61-6:11:64", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:13:66-6:22:75", + "value": false + } + } + } + } + ] + }, + "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": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "hello" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.exp.json new file mode 100644 index 000000000..2ab9e4cfb --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.exp.json @@ -0,0 +1,178 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,0:0:0-4:0:34", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:8:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:3:4-1:8:9", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:0:10-2:10:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:0:10-2:1:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:0:10-2:1:11", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:3:13-2:10:20", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:0:21-3:12:33", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:0:21-3:1:22", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:0:21-3:1:22", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:3:24-3:12:33", + "value": false + } + } + } + } + ] + }, + "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/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "hello" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2ir/TestCompile/filters/edge.exp.json b/testdata/d2ir/TestCompile/filters/edge.exp.json index 5622ca570..89c6f9104 100644 --- a/testdata/d2ir/TestCompile/filters/edge.exp.json +++ b/testdata/d2ir/TestCompile/filters/edge.exp.json @@ -580,258 +580,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": false - }, - { - "string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - }, - "key_path": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "context": { - "edge": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/edge.d2,6:0:86-10:1:203", - "edges": [ - { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/edge.d2,6:8:94-6:11:97", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/edge.d2,6:13:99-10:1:203", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", - "value": [ - { - "string": "source-arrowhead", - "raw_string": "source-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", - "value": [ - { - "string": "target-arrowhead", - "raw_string": "target-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:32:201", - "key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:8:177-9:32:201", - "value": [ - { - "string": "diamond shape arrowheads", - "raw_string": "diamond shape arrowheads" - } - ] - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": false } ] }, @@ -1318,6 +1066,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", @@ -1495,6 +1329,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", @@ -1702,6 +1622,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", @@ -1879,6 +1885,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", @@ -2588,233 +2680,6 @@ }, "due_to_glob": false, "due_to_lazy_glob": false - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/edge.d2,6:0:86-10:1:203", - "edges": [ - { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/edge.d2,6:8:94-6:11:97", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/edge.d2,6:13:99-10:1:203", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", - "value": [ - { - "string": "source-arrowhead", - "raw_string": "source-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", - "value": [ - { - "string": "target-arrowhead", - "raw_string": "target-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:32:201", - "key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:8:177-9:32:201", - "value": [ - { - "string": "diamond shape arrowheads", - "raw_string": "diamond shape arrowheads" - } - ] - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": false } ] } diff --git a/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json b/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json index c8901f508..a6814b031 100644 --- a/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json +++ b/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json @@ -1505,374 +1505,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true } ] }, @@ -2518,558 +2150,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true } ] } diff --git a/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json b/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json index 987ebd9e8..65f2526bd 100644 --- a/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json +++ b/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json @@ -798,190 +798,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:7:8", - "src": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/3.d2,1:0:1-4:1:51", - "edges": [ - { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:7:8", - "src": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/3.d2,1:8:9-1:11:12", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/3.d2,1:13:14-4:1:51", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/3.d2,2:2:18-2:12:28", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/3.d2,2:3:19-2:8:24", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,2:3:19-2:8:24", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,2:10:26-2:12:28", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/3.d2,3:2:31-3:20:49", - "key": { - "range": "TestCompile/filters/label-filter/3.d2,3:2:31-3:15:44", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,3:2:31-3:7:36", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,3:8:37-3:15:44", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/3.d2,3:17:46-3:20:49", - "raw": "0.1", - "value": "1/10" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true } ] }
                                                                                            Sprint