Merge branch 'master' into png-img
This commit is contained in:
commit
7ba3a93217
33 changed files with 3447 additions and 191 deletions
6
.gitattributes
vendored
6
.gitattributes
vendored
|
|
@ -1,3 +1,9 @@
|
||||||
|
# Leading ** is required.
|
||||||
|
**/testdata/**/*.json linguist-generated
|
||||||
|
go.mod linguist-generated
|
||||||
|
go.sum linguist-generated
|
||||||
d2layouts/d2dagrelayout/dagre.js linguist-vendored
|
d2layouts/d2dagrelayout/dagre.js linguist-vendored
|
||||||
d2layouts/d2elklayout/elk.js linguist-vendored
|
d2layouts/d2elklayout/elk.js linguist-vendored
|
||||||
d2renderers/d2svg/github-markdown.css linguist-vendored
|
d2renderers/d2svg/github-markdown.css linguist-vendored
|
||||||
|
d2renderers/d2latex/mathjax.js linguist-vendored
|
||||||
|
d2renderers/d2latex/polyfills.js linguist-vendored
|
||||||
|
|
|
||||||
89
.github/workflows/ci.yml
vendored
89
.github/workflows/ci.yml
vendored
|
|
@ -5,17 +5,7 @@ concurrency:
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
assert-linear:
|
ci:
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- run: COLOR=1 ./make.sh assert-linear
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
fmt:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
@ -25,63 +15,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
go-version-file: ./go.mod
|
go-version-file: ./go.mod
|
||||||
cache: true
|
cache: true
|
||||||
- run: COLOR=1 ./make.sh fmt
|
- run: COLOR=1 ./make.sh all race
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
gen:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version-file: ./go.mod
|
|
||||||
cache: true
|
|
||||||
- run: COLOR=1 ./make.sh gen
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version-file: ./go.mod
|
|
||||||
cache: true
|
|
||||||
- run: COLOR=1 ./make.sh lint
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version-file: ./go.mod
|
|
||||||
cache: true
|
|
||||||
- run: COLOR=1 ./make.sh build
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version-file: ./go.mod
|
|
||||||
cache: true
|
|
||||||
- run: COLOR=1 ./make.sh test
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
|
|
@ -90,22 +24,3 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: d2chaos-test
|
name: d2chaos-test
|
||||||
path: ./d2chaos/out
|
path: ./d2chaos/out
|
||||||
race:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version-file: ./go.mod
|
|
||||||
cache: true
|
|
||||||
- run: COLOR=1 ./make.sh race
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: d2chaos-race
|
|
||||||
path: ./d2chaos/out
|
|
||||||
|
|
|
||||||
4
.github/workflows/daily.yml
vendored
4
.github/workflows/daily.yml
vendored
|
|
@ -10,7 +10,7 @@ concurrency:
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
all:
|
ci:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
@ -20,7 +20,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
go-version-file: ./go.mod
|
go-version-file: ./go.mod
|
||||||
cache: true
|
cache: true
|
||||||
- run: CI_ALL=1 COLOR=1 ./make.sh
|
- run: COLOR=1 CI_FORCE=1 ./make.sh all race
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
|
|
|
||||||
6
Makefile
6
Makefile
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: fmt gen lint build test
|
all: fmt gen lint build test
|
||||||
ifdef CI
|
|
||||||
all: assert-linear
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
|
|
@ -24,6 +21,3 @@ test:
|
||||||
.PHONY: race
|
.PHONY: race
|
||||||
race:
|
race:
|
||||||
prefix "$@" ./ci/test.sh --race ./...
|
prefix "$@" ./ci/test.sh --race ./...
|
||||||
.PHONY: assert-linear
|
|
||||||
assert-linear:
|
|
||||||
prefix "$@" ./ci/sub/assert_linear.sh
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ help() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
usage: $arg0 [--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local]
|
usage: $arg0 [-d|--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local]
|
||||||
[--tala latest] [--force] [--uninstall]
|
[--tala latest] [--force] [--uninstall]
|
||||||
|
|
||||||
install.sh automates the installation of D2 onto your system. It currently only supports
|
install.sh automates the installation of D2 onto your system. It currently only supports
|
||||||
|
|
@ -26,7 +26,7 @@ If you pass --edge, it will clone the source, build a release and install from i
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
|
||||||
--dry-run
|
-d, --dry-run
|
||||||
Pass to have install.sh show the install method and flags that will be used to install
|
Pass to have install.sh show the install method and flags that will be used to install
|
||||||
without executing them. Very useful to understand what changes it will make to your system.
|
without executing them. Very useful to understand what changes it will make to your system.
|
||||||
|
|
||||||
|
|
@ -101,7 +101,7 @@ main() {
|
||||||
help
|
help
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
dry-run)
|
d|dry-run)
|
||||||
flag_noarg && shift "$FLAGSHIFT"
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
DRY_RUN=1
|
DRY_RUN=1
|
||||||
;;
|
;;
|
||||||
|
|
@ -188,12 +188,16 @@ main() {
|
||||||
if [ -n "${UNINSTALL-}" ]; then
|
if [ -n "${UNINSTALL-}" ]; then
|
||||||
uninstall
|
uninstall
|
||||||
if [ -n "${DRY_RUN-}" ]; then
|
if [ -n "${DRY_RUN-}" ]; then
|
||||||
log "Rerun without --dry-run to execute printed commands and perform uninstall."
|
FGCOLOR=3 bigheader "***********
|
||||||
|
Rerun without --dry-run to execute printed commands and perform install.
|
||||||
|
***********"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
install
|
install
|
||||||
if [ -n "${DRY_RUN-}" ]; then
|
if [ -n "${DRY_RUN-}" ]; then
|
||||||
log "Rerun without --dry-run to execute printed commands and perform install."
|
FGCOLOR=3 bigheader "***********
|
||||||
|
Rerun without --dry-run to execute printed commands and perform install.
|
||||||
|
***********"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
#### Features 🚀
|
#### Features 🚀
|
||||||
|
|
||||||
|
- Latex is now supported. See [docs](https://d2lang.com/tour/text) for more.
|
||||||
|
[#229](https://github.com/terrastruct/d2/pull/229)
|
||||||
- Arrowhead labels are now supported. [#182](https://github.com/terrastruct/d2/pull/182)
|
- Arrowhead labels are now supported. [#182](https://github.com/terrastruct/d2/pull/182)
|
||||||
- `stroke-dash` on shapes is now supported. [#188](https://github.com/terrastruct/d2/issues/188)
|
- `stroke-dash` on shapes is now supported. [#188](https://github.com/terrastruct/d2/issues/188)
|
||||||
- `font-color` is now supported on shapes and connections. [#215](https://github.com/terrastruct/d2/pull/215)
|
- `font-color` is now supported on shapes and connections. [#215](https://github.com/terrastruct/d2/pull/215)
|
||||||
- Querying shapes and connections by ID is now supported in renders. [#218](https://github.com/terrastruct/d2/pull/218)
|
- Querying shapes and connections by ID is now supported in renders. [#218](https://github.com/terrastruct/d2/pull/218)
|
||||||
|
- [install.sh](./install.sh) now accepts `-d` as an alias for `--dry-run`.
|
||||||
|
[#266](https://github.com/terrastruct/d2/pull/266)
|
||||||
|
|
||||||
#### Improvements 🔧
|
#### Improvements 🔧
|
||||||
|
|
||||||
- Local images can now be included, e.g. `icon: ./my_img.png`.
|
- Local images can now be included, e.g. `icon: ./my_img.png`.
|
||||||
[#146](https://github.com/terrastruct/d2/issues/146)
|
[#146](https://github.com/terrastruct/d2/issues/146)
|
||||||
|
- [install.sh](./install.sh) prints the dry run message more visibly.
|
||||||
|
[#266](https://github.com/terrastruct/d2/pull/266)
|
||||||
|
|
||||||
#### Bugfixes 🔴
|
#### Bugfixes 🔴
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
.Op Fl -watch Ar false
|
.Op Fl -watch Ar false
|
||||||
.Op Fl -theme Em 0
|
.Op Fl -theme Em 0
|
||||||
.Ar file.d2
|
.Ar file.d2
|
||||||
.Op Ar file.svg
|
.Op Ar file.svg
|
||||||
|
|
|
|
||||||
.Op Ar file.png
|
.Op Ar file.png
|
||||||
.Nm d2
|
.Nm d2
|
||||||
.Op Fl -watch Ar false
|
.Op Fl -watch Ar false
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ should_color() {
|
||||||
_COLOR=1
|
_COLOR=1
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
printf '$COLOR must be 0, 1, false or true but got %s' "$COLOR" >&2
|
printf '$COLOR must be 0, 1, false or true but got %s\n' "$COLOR" >&2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -219,8 +219,9 @@ header() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bigheader() {
|
bigheader() {
|
||||||
|
set -- "$(echo "$*" | sed "s/^/ * /")"
|
||||||
logp "/**
|
logp "/**
|
||||||
* $1
|
$*
|
||||||
**/"
|
**/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2"
|
"oss.terrastruct.com/d2"
|
||||||
|
"oss.terrastruct.com/d2/d2layouts/d2sequence"
|
||||||
"oss.terrastruct.com/d2/d2plugin"
|
"oss.terrastruct.com/d2/d2plugin"
|
||||||
"oss.terrastruct.com/d2/d2renderers/d2svg"
|
"oss.terrastruct.com/d2/d2renderers/d2svg"
|
||||||
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
||||||
|
|
@ -189,8 +190,13 @@ func compile(ctx context.Context, ms *xmain.State, isWatching bool, plugin d2plu
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layout := plugin.Layout
|
||||||
|
// TODO: remove, this is just a feature flag to test sequence diagrams as we work on them
|
||||||
|
if os.Getenv("D2_SEQUENCE") == "1" {
|
||||||
|
layout = d2sequence.Layout
|
||||||
|
}
|
||||||
d, err := d2.Compile(ctx, string(input), &d2.CompileOptions{
|
d, err := d2.Compile(ctx, string(input), &d2.CompileOptions{
|
||||||
Layout: plugin.Layout,
|
Layout: layout,
|
||||||
Ruler: ruler,
|
Ruler: ruler,
|
||||||
ThemeID: themeID,
|
ThemeID: themeID,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,8 @@ func (c *compiler) compileKey(obj *d2graph.Object, m *d2ast.Map, mk *d2ast.Key)
|
||||||
}, unresolvedObj)
|
}, unresolvedObj)
|
||||||
} else if obj.Parent == nil {
|
} else if obj.Parent == nil {
|
||||||
// Top level reserved key set on root.
|
// Top level reserved key set on root.
|
||||||
|
c.compileAttributes(&obj.Attributes, mk)
|
||||||
|
c.applyScalar(&obj.Attributes, reserved, mk.Value.ScalarBox())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -377,7 +379,7 @@ func (c *compiler) applyScalar(attrs *d2graph.Attributes, reserved string, box d
|
||||||
if ok {
|
if ok {
|
||||||
attrs.Language = fullTag
|
attrs.Language = fullTag
|
||||||
}
|
}
|
||||||
if attrs.Language == "markdown" {
|
if attrs.Language == "markdown" || attrs.Language == "latex" {
|
||||||
attrs.Shape.Value = d2target.ShapeText
|
attrs.Shape.Value = d2target.ShapeText
|
||||||
} else {
|
} else {
|
||||||
attrs.Shape.Value = d2target.ShapeCode
|
attrs.Shape.Value = d2target.ShapeCode
|
||||||
|
|
@ -548,12 +550,13 @@ func (c *compiler) compileFlatKey(k *d2ast.KeyPath) ([]string, string, bool) {
|
||||||
|
|
||||||
// TODO add more, e.g. C, bash
|
// TODO add more, e.g. C, bash
|
||||||
var ShortToFullLanguageAliases = map[string]string{
|
var ShortToFullLanguageAliases = map[string]string{
|
||||||
"md": "markdown",
|
"md": "markdown",
|
||||||
"js": "javascript",
|
"tex": "latex",
|
||||||
"go": "golang",
|
"js": "javascript",
|
||||||
"py": "python",
|
"go": "golang",
|
||||||
"rb": "ruby",
|
"py": "python",
|
||||||
"ts": "typescript",
|
"rb": "ruby",
|
||||||
|
"ts": "typescript",
|
||||||
}
|
}
|
||||||
var FullToShortLanguageAliases map[string]string
|
var FullToShortLanguageAliases map[string]string
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1501,6 +1501,26 @@ dst.id <-> src.dst_id
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "basic_sequence",
|
||||||
|
|
||||||
|
text: `x: {
|
||||||
|
shape: sequence_diagram
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
assertions: func(t *testing.T, g *d2graph.Graph) {
|
||||||
|
diff.AssertStringEq(t, "sequence_diagram", g.Objects[0].Attributes.Shape.Value)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "root_sequence",
|
||||||
|
|
||||||
|
text: `shape: sequence_diagram
|
||||||
|
`,
|
||||||
|
assertions: func(t *testing.T, g *d2graph.Graph) {
|
||||||
|
diff.AssertStringEq(t, "sequence_diagram", g.Root.Attributes.Shape.Value)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"oss.terrastruct.com/d2/d2format"
|
"oss.terrastruct.com/d2/d2format"
|
||||||
"oss.terrastruct.com/d2/d2parser"
|
"oss.terrastruct.com/d2/d2parser"
|
||||||
"oss.terrastruct.com/d2/d2renderers/d2fonts"
|
"oss.terrastruct.com/d2/d2renderers/d2fonts"
|
||||||
|
"oss.terrastruct.com/d2/d2renderers/d2latex"
|
||||||
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
||||||
"oss.terrastruct.com/d2/d2target"
|
"oss.terrastruct.com/d2/d2target"
|
||||||
"oss.terrastruct.com/d2/d2themes"
|
"oss.terrastruct.com/d2/d2themes"
|
||||||
|
|
@ -833,10 +834,18 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
|
||||||
var dims *d2target.TextDimensions
|
var dims *d2target.TextDimensions
|
||||||
var innerLabelPadding = 5
|
var innerLabelPadding = 5
|
||||||
if obj.Attributes.Shape.Value == d2target.ShapeText {
|
if obj.Attributes.Shape.Value == d2target.ShapeText {
|
||||||
var err error
|
if obj.Attributes.Language == "latex" {
|
||||||
dims, err = getMarkdownDimensions(mtexts, ruler, obj.Text())
|
width, height, err := d2latex.Measure(obj.Text().Text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
dims = d2target.NewTextDimensions(width, height)
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
dims, err = getMarkdownDimensions(mtexts, ruler, obj.Text())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
innerLabelPadding = 0
|
innerLabelPadding = 0
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
9
d2layouts/d2sequence/constants.go
Normal file
9
d2layouts/d2sequence/constants.go
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package d2sequence
|
||||||
|
|
||||||
|
// leaves at least 25 units of space on the left/right when computing the space required between actors
|
||||||
|
const HORIZONTAL_PAD = 50.
|
||||||
|
|
||||||
|
const MIN_ACTOR_DISTANCE = 200.
|
||||||
|
|
||||||
|
// min vertical distance between edges
|
||||||
|
const MIN_EDGE_DISTANCE = 100.
|
||||||
107
d2layouts/d2sequence/layout.go
Normal file
107
d2layouts/d2sequence/layout.go
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
package d2sequence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/d2/d2graph"
|
||||||
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/d2/lib/go2"
|
||||||
|
"oss.terrastruct.com/d2/lib/label"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Layout(ctx context.Context, g *d2graph.Graph) (err error) {
|
||||||
|
edgeYStep := MIN_EDGE_DISTANCE
|
||||||
|
actorXStep := MIN_ACTOR_DISTANCE
|
||||||
|
maxActorHeight := 0.
|
||||||
|
|
||||||
|
actorRank := make(map[*d2graph.Object]int)
|
||||||
|
for rank, actor := range g.Objects {
|
||||||
|
actorRank[actor] = rank
|
||||||
|
}
|
||||||
|
for _, edge := range g.Edges {
|
||||||
|
edgeYStep = math.Max(edgeYStep, float64(edge.LabelDimensions.Height)+HORIZONTAL_PAD)
|
||||||
|
maxActorHeight = math.Max(maxActorHeight, edge.Src.Height+HORIZONTAL_PAD)
|
||||||
|
maxActorHeight = math.Max(maxActorHeight, edge.Dst.Height+HORIZONTAL_PAD)
|
||||||
|
// ensures that long labels, spanning over multiple actors, don't make for large gaps between actors
|
||||||
|
// by distributing the label length across the actors rank difference
|
||||||
|
rankDiff := math.Abs(float64(actorRank[edge.Src]) - float64(actorRank[edge.Dst]))
|
||||||
|
distributedLabelWidth := float64(edge.LabelDimensions.Width) / rankDiff
|
||||||
|
actorXStep = math.Max(actorXStep, distributedLabelWidth+HORIZONTAL_PAD)
|
||||||
|
}
|
||||||
|
|
||||||
|
placeActors(g.Objects, maxActorHeight, actorXStep)
|
||||||
|
routeEdges(g.Edges, maxActorHeight, edgeYStep)
|
||||||
|
addLifelineEdges(g, g.Objects, edgeYStep)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// placeActors places actors bottom aligned, side by side
|
||||||
|
func placeActors(actors []*d2graph.Object, maxHeight, xStep float64) {
|
||||||
|
x := 0.
|
||||||
|
for _, actors := range actors {
|
||||||
|
yOffset := maxHeight - actors.Height
|
||||||
|
actors.TopLeft = geo.NewPoint(x, yOffset)
|
||||||
|
x += actors.Width + xStep
|
||||||
|
actors.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// routeEdges routes horizontal edges from Src to Dst
|
||||||
|
func routeEdges(edgesInOrder []*d2graph.Edge, startY, yStep float64) {
|
||||||
|
edgeY := startY + yStep // in case the first edge has a tall label
|
||||||
|
for _, edge := range edgesInOrder {
|
||||||
|
start := edge.Src.Center()
|
||||||
|
start.Y = edgeY
|
||||||
|
end := edge.Dst.Center()
|
||||||
|
end.Y = edgeY
|
||||||
|
edge.Route = []*geo.Point{start, end}
|
||||||
|
edgeY += yStep
|
||||||
|
|
||||||
|
if edge.Attributes.Label.Value != "" {
|
||||||
|
isLeftToRight := edge.Src.TopLeft.X < edge.Dst.TopLeft.X
|
||||||
|
if isLeftToRight {
|
||||||
|
edge.LabelPosition = go2.Pointer(string(label.OutsideTopCenter))
|
||||||
|
} else {
|
||||||
|
edge.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// addLifelineEdges adds a new edge for each actor in the graph that represents the
|
||||||
|
// edge below the actor showing its lifespan
|
||||||
|
// ┌──────────────┐
|
||||||
|
// │ actor │
|
||||||
|
// └──────┬───────┘
|
||||||
|
// │
|
||||||
|
// │ lifeline
|
||||||
|
// │
|
||||||
|
// │
|
||||||
|
func addLifelineEdges(g *d2graph.Graph, actors []*d2graph.Object, yStep float64) {
|
||||||
|
endY := g.Edges[len(g.Edges)-1].Route[0].Y + yStep
|
||||||
|
for _, actor := range actors {
|
||||||
|
actorBottom := actor.Center()
|
||||||
|
actorBottom.Y = actor.TopLeft.Y + actor.Height
|
||||||
|
actorLifelineEnd := actor.Center()
|
||||||
|
actorLifelineEnd.Y = endY
|
||||||
|
g.Edges = append(g.Edges, &d2graph.Edge{
|
||||||
|
Attributes: d2graph.Attributes{
|
||||||
|
Style: d2graph.Style{
|
||||||
|
StrokeDash: &d2graph.Scalar{Value: "10"},
|
||||||
|
Stroke: actor.Attributes.Style.Stroke,
|
||||||
|
StrokeWidth: actor.Attributes.Style.StrokeWidth,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Src: actor,
|
||||||
|
SrcArrow: false,
|
||||||
|
Dst: &d2graph.Object{
|
||||||
|
ID: actor.ID + fmt.Sprintf("-lifeline-end-%d", go2.StringToIntHash(actor.ID+"-lifeline-end")),
|
||||||
|
},
|
||||||
|
DstArrow: false,
|
||||||
|
Route: []*geo.Point{actorBottom, actorLifelineEnd},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
112
d2layouts/d2sequence/layout_test.go
Normal file
112
d2layouts/d2sequence/layout_test.go
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
package d2sequence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/d2/d2graph"
|
||||||
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/d2/lib/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLayout(t *testing.T) {
|
||||||
|
g := d2graph.NewGraph(nil)
|
||||||
|
g.Objects = []*d2graph.Object{
|
||||||
|
{
|
||||||
|
ID: "Alice",
|
||||||
|
Box: geo.NewBox(nil, 100, 100),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "Bob",
|
||||||
|
Box: geo.NewBox(nil, 30, 30),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Edges = []*d2graph.Edge{
|
||||||
|
{
|
||||||
|
Src: g.Objects[0],
|
||||||
|
Dst: g.Objects[1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Src: g.Objects[1],
|
||||||
|
Dst: g.Objects[0],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Src: g.Objects[0],
|
||||||
|
Dst: g.Objects[1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Src: g.Objects[1],
|
||||||
|
Dst: g.Objects[0],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
nEdges := len(g.Edges)
|
||||||
|
|
||||||
|
ctx := log.WithTB(context.Background(), t, nil)
|
||||||
|
Layout(ctx, g)
|
||||||
|
|
||||||
|
// asserts that actors were placed in the expected x order and at y=0
|
||||||
|
actors := []*d2graph.Object{
|
||||||
|
g.Objects[0],
|
||||||
|
g.Objects[1],
|
||||||
|
}
|
||||||
|
for i := 1; i < len(actors); i++ {
|
||||||
|
if actors[i].TopLeft.X < actors[i-1].TopLeft.X {
|
||||||
|
t.Fatalf("expected actor[%d].TopLeft.X > actor[%d].TopLeft.X", i, i-1)
|
||||||
|
}
|
||||||
|
actorBottom := actors[i].TopLeft.Y + actors[i].Height
|
||||||
|
prevActorBottom := actors[i-1].TopLeft.Y + actors[i-1].Height
|
||||||
|
if actorBottom != prevActorBottom {
|
||||||
|
t.Fatalf("expected actor[%d] and actor[%d] to be at the same bottom y", i, i-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nExpectedEdges := nEdges + len(actors)
|
||||||
|
if len(g.Edges) != nExpectedEdges {
|
||||||
|
t.Fatalf("expected %d edges, got %d", nExpectedEdges, len(g.Edges))
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert that edges were placed in y order and have the endpoints at their actors
|
||||||
|
// uses `nEdges` because Layout creates some vertical edges to represent the actor lifeline
|
||||||
|
for i := 0; i < nEdges; i++ {
|
||||||
|
edge := g.Edges[i]
|
||||||
|
if len(edge.Route) != 2 {
|
||||||
|
t.Fatalf("expected edge[%d] to have only 2 points", i)
|
||||||
|
}
|
||||||
|
if edge.Route[0].Y != edge.Route[1].Y {
|
||||||
|
t.Fatalf("expected edge[%d] to be a horizontal line", i)
|
||||||
|
}
|
||||||
|
if edge.Route[0].X != edge.Src.Center().X {
|
||||||
|
t.Fatalf("expected edge[%d] source endpoint to be at the middle of the source actor", i)
|
||||||
|
}
|
||||||
|
if edge.Route[1].X != edge.Dst.Center().X {
|
||||||
|
t.Fatalf("expected edge[%d] target endpoint to be at the middle of the target actor", i)
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
prevEdge := g.Edges[i-1]
|
||||||
|
if edge.Route[0].Y < prevEdge.Route[0].Y {
|
||||||
|
t.Fatalf("expected edge[%d].TopLeft.Y > edge[%d].TopLeft.Y", i, i-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSequenceEdge := g.Edges[nEdges-1]
|
||||||
|
for i := nEdges; i < nExpectedEdges; i++ {
|
||||||
|
edge := g.Edges[i]
|
||||||
|
if len(edge.Route) != 2 {
|
||||||
|
t.Fatalf("expected edge[%d] to have only 2 points", i)
|
||||||
|
}
|
||||||
|
if edge.Route[0].X != edge.Route[1].X {
|
||||||
|
t.Fatalf("expected edge[%d] to be a vertical line", i)
|
||||||
|
}
|
||||||
|
if edge.Route[0].X != edge.Src.Center().X {
|
||||||
|
t.Fatalf("expected edge[%d] x to be at the actor center", i)
|
||||||
|
}
|
||||||
|
if edge.Route[0].Y != edge.Src.Height+edge.Src.TopLeft.Y {
|
||||||
|
t.Fatalf("expected edge[%d] to start at the bottom of the source actor", i)
|
||||||
|
}
|
||||||
|
if edge.Route[1].Y < lastSequenceEdge.Route[0].Y {
|
||||||
|
t.Fatalf("expected edge[%d] to end after the last sequence edge", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -158,17 +158,17 @@ meow.(x -> y -> z)[3].shape: "all hail corn"
|
||||||
{
|
{
|
||||||
name: "errs",
|
name: "errs",
|
||||||
text: `
|
text: `
|
||||||
--: meow]]]
|
--: meow]]] ` + `
|
||||||
meow][: ok
|
meow][: ok ` + `
|
||||||
ok: "dmsadmakls" dsamkldkmsa
|
ok: "dmsadmakls" dsamkldkmsa ` + `
|
||||||
|
` + `
|
||||||
s.shape: orochimaru
|
s.shape: orochimaru ` + `
|
||||||
x.shape: dasdasdas
|
x.shape: dasdasdas ` + `
|
||||||
|
|
||||||
wow:
|
wow:
|
||||||
|
|
||||||
:
|
: ` + `
|
||||||
|
` + `
|
||||||
[]
|
[]
|
||||||
|
|
||||||
{}
|
{}
|
||||||
|
|
@ -214,7 +214,7 @@ meow
|
||||||
{
|
{
|
||||||
name: "trailing_whitespace",
|
name: "trailing_whitespace",
|
||||||
text: `
|
text: `
|
||||||
s.shape: orochimaru
|
s.shape: orochimaru ` + `
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -334,16 +334,16 @@ a: | hello |
|
||||||
name: "block_trailing_space",
|
name: "block_trailing_space",
|
||||||
text: `
|
text: `
|
||||||
x: |
|
x: |
|
||||||
meow
|
meow ` + `
|
||||||
|
|
|
|
||||||
""" hello
|
""" hello ` + `
|
||||||
"""
|
"""
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "block_edge_case",
|
name: "block_edge_case",
|
||||||
text: `
|
text: `
|
||||||
x: | meow
|
x: | meow ` + `
|
||||||
hello
|
hello
|
||||||
yes
|
yes
|
||||||
|
|
|
|
||||||
|
|
|
||||||
83
d2renderers/d2latex/latex.go
Normal file
83
d2renderers/d2latex/latex.go
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
//go:build cgo
|
||||||
|
|
||||||
|
package d2latex
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/xdefer"
|
||||||
|
v8 "rogchap.com/v8go"
|
||||||
|
)
|
||||||
|
|
||||||
|
var pxPerEx = 8
|
||||||
|
|
||||||
|
//go:embed polyfills.js
|
||||||
|
var polyfillsJS string
|
||||||
|
|
||||||
|
//go:embed setup.js
|
||||||
|
var setupJS string
|
||||||
|
|
||||||
|
//go:embed mathjax.js
|
||||||
|
var mathjaxJS string
|
||||||
|
|
||||||
|
// Matches this
|
||||||
|
// <svg style="background: white;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="563" height="326" viewBox="-100 -100 563 326"><style type="text/css">
|
||||||
|
var svgRe = regexp.MustCompile(`<svg[^>]+width="([0-9\.]+)ex" height="([0-9\.]+)ex"[^>]+>`)
|
||||||
|
|
||||||
|
func Render(s string) (_ string, err error) {
|
||||||
|
defer xdefer.Errorf(&err, "latex failed to parse")
|
||||||
|
v8ctx := v8.NewContext()
|
||||||
|
|
||||||
|
if _, err := v8ctx.RunScript(polyfillsJS, "polyfills.js"); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := v8ctx.RunScript(mathjaxJS, "mathjax.js"); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := v8ctx.RunScript(setupJS, "setup.js"); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := v8ctx.RunScript(fmt.Sprintf(`adaptor.innerHTML(html.convert(`+"`"+"%s`"+`, {
|
||||||
|
em: %d,
|
||||||
|
ex: %d,
|
||||||
|
}))`, s, pxPerEx*2, pxPerEx), "value.js")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return val.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Measure(s string) (width, height int, err error) {
|
||||||
|
defer xdefer.Errorf(&err, "latex failed to parse")
|
||||||
|
svg, err := Render(s)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dims := svgRe.FindAllStringSubmatch(svg, -1)
|
||||||
|
if len(dims) != 1 || len(dims[0]) != 3 {
|
||||||
|
return 0, 0, fmt.Errorf("svg parsing failed for latex: %v", svg)
|
||||||
|
}
|
||||||
|
|
||||||
|
wEx := dims[0][1]
|
||||||
|
hEx := dims[0][2]
|
||||||
|
|
||||||
|
wf, err := strconv.ParseFloat(wEx, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, fmt.Errorf("svg parsing failed for latex: %v", svg)
|
||||||
|
}
|
||||||
|
hf, err := strconv.ParseFloat(hEx, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, fmt.Errorf("svg parsing failed for latex: %v", svg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(math.Ceil(wf * float64(pxPerEx))), int(math.Ceil(hf * float64(pxPerEx))), nil
|
||||||
|
}
|
||||||
13
d2renderers/d2latex/latex_stub.go
Normal file
13
d2renderers/d2latex/latex_stub.go
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
//go:build !cgo
|
||||||
|
|
||||||
|
package d2latex
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func Render(s string) (string, error) {
|
||||||
|
return "", errors.New("not found in build")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Measure(s string) (width, height int, _ error) {
|
||||||
|
return 0, 0, errors.New("not found in build")
|
||||||
|
}
|
||||||
33
d2renderers/d2latex/latex_test.go
Normal file
33
d2renderers/d2latex/latex_test.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package d2latex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRender(t *testing.T) {
|
||||||
|
txts := []string{
|
||||||
|
`a + b = c`,
|
||||||
|
`\\frac{1}{2}`,
|
||||||
|
`a + b
|
||||||
|
= c
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
for _, txt := range txts {
|
||||||
|
svg, err := Render(txt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var xmlParsed interface{}
|
||||||
|
if err := xml.Unmarshal([]byte(svg), &xmlParsed); err != nil {
|
||||||
|
t.Fatalf("invalid SVG: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRenderError(t *testing.T) {
|
||||||
|
_, err := Render(`\frac{1}{2}`)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected to error on invalid latex syntax")
|
||||||
|
}
|
||||||
|
}
|
||||||
36
d2renderers/d2latex/mathjax.js
vendored
Normal file
36
d2renderers/d2latex/mathjax.js
vendored
Normal file
File diff suppressed because one or more lines are too long
68
d2renderers/d2latex/polyfills.js
vendored
Normal file
68
d2renderers/d2latex/polyfills.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
d2renderers/d2latex/setup.js
Normal file
6
d2renderers/d2latex/setup.js
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
const adaptor = MathJax._.adaptors.liteAdaptor.liteAdaptor();
|
||||||
|
MathJax._.handlers.html_ts.RegisterHTMLHandler(adaptor)
|
||||||
|
const html = MathJax._.mathjax.mathjax.document('', {
|
||||||
|
InputJax: new MathJax._.input.tex_ts.TeX({ packages: ['base', 'mathtools', 'amscd', 'braket', 'cancel', 'cases', 'color', 'gensymb', 'mhchem', 'physics'] }),
|
||||||
|
OutputJax: new MathJax._.output.svg_ts.SVG(),
|
||||||
|
});
|
||||||
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/alecthomas/chroma/styles"
|
"github.com/alecthomas/chroma/styles"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2renderers/d2fonts"
|
"oss.terrastruct.com/d2/d2renderers/d2fonts"
|
||||||
|
"oss.terrastruct.com/d2/d2renderers/d2latex"
|
||||||
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
||||||
"oss.terrastruct.com/d2/d2target"
|
"oss.terrastruct.com/d2/d2target"
|
||||||
"oss.terrastruct.com/d2/lib/color"
|
"oss.terrastruct.com/d2/lib/color"
|
||||||
|
|
@ -701,17 +702,27 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(writer, "</g></g>")
|
fmt.Fprintf(writer, "</g></g>")
|
||||||
case d2target.ShapeText:
|
case d2target.ShapeText:
|
||||||
render, err := textmeasure.RenderMarkdown(targetShape.Label)
|
if targetShape.Language == "latex" {
|
||||||
if err != nil {
|
render, err := d2latex.Render(targetShape.Label)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Fprintf(writer, `<g transform="translate(%f %f)" style="opacity:%f">`, box.TopLeft.X, box.TopLeft.Y, targetShape.Opacity)
|
||||||
|
fmt.Fprintf(writer, render)
|
||||||
|
fmt.Fprintf(writer, "</g>")
|
||||||
|
} else {
|
||||||
|
render, err := textmeasure.RenderMarkdown(targetShape.Label)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Fprintf(writer, `<g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="%f" y="%f" width="%d" height="%d">`,
|
||||||
|
box.TopLeft.X, box.TopLeft.Y, targetShape.Width, targetShape.Height,
|
||||||
|
)
|
||||||
|
// we need the self closing form in this svg/xhtml context
|
||||||
|
render = strings.ReplaceAll(render, "<hr>", "<hr />")
|
||||||
|
fmt.Fprintf(writer, `<div xmlns="http://www.w3.org/1999/xhtml" class="md">%v</div>`, render)
|
||||||
|
fmt.Fprint(writer, `</foreignObject></g>`)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(writer, `<g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="%f" y="%f" width="%d" height="%d">`,
|
|
||||||
box.TopLeft.X, box.TopLeft.Y, targetShape.Width, targetShape.Height,
|
|
||||||
)
|
|
||||||
// we need the self closing form in this svg/xhtml context
|
|
||||||
render = strings.ReplaceAll(render, "<hr>", "<hr />")
|
|
||||||
fmt.Fprintf(writer, `<div xmlns="http://www.w3.org/1999/xhtml" class="md">%v</div>`, render)
|
|
||||||
fmt.Fprint(writer, `</foreignObject></g>`)
|
|
||||||
default:
|
default:
|
||||||
fontColor := "black"
|
fontColor := "black"
|
||||||
if targetShape.Color != "" {
|
if targetShape.Color != "" {
|
||||||
|
|
|
||||||
|
|
@ -255,28 +255,29 @@ func NewPoint(x, y int) Point {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ShapeRectangle = "rectangle"
|
ShapeRectangle = "rectangle"
|
||||||
ShapeSquare = "square"
|
ShapeSquare = "square"
|
||||||
ShapePage = "page"
|
ShapePage = "page"
|
||||||
ShapeParallelogram = "parallelogram"
|
ShapeParallelogram = "parallelogram"
|
||||||
ShapeDocument = "document"
|
ShapeDocument = "document"
|
||||||
ShapeCylinder = "cylinder"
|
ShapeCylinder = "cylinder"
|
||||||
ShapeQueue = "queue"
|
ShapeQueue = "queue"
|
||||||
ShapePackage = "package"
|
ShapePackage = "package"
|
||||||
ShapeStep = "step"
|
ShapeStep = "step"
|
||||||
ShapeCallout = "callout"
|
ShapeCallout = "callout"
|
||||||
ShapeStoredData = "stored_data"
|
ShapeStoredData = "stored_data"
|
||||||
ShapePerson = "person"
|
ShapePerson = "person"
|
||||||
ShapeDiamond = "diamond"
|
ShapeDiamond = "diamond"
|
||||||
ShapeOval = "oval"
|
ShapeOval = "oval"
|
||||||
ShapeCircle = "circle"
|
ShapeCircle = "circle"
|
||||||
ShapeHexagon = "hexagon"
|
ShapeHexagon = "hexagon"
|
||||||
ShapeCloud = "cloud"
|
ShapeCloud = "cloud"
|
||||||
ShapeText = "text"
|
ShapeText = "text"
|
||||||
ShapeCode = "code"
|
ShapeCode = "code"
|
||||||
ShapeClass = "class"
|
ShapeClass = "class"
|
||||||
ShapeSQLTable = "sql_table"
|
ShapeSQLTable = "sql_table"
|
||||||
ShapeImage = "image"
|
ShapeImage = "image"
|
||||||
|
ShapeSequenceDiagram = "sequence_diagram"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Shapes = []string{
|
var Shapes = []string{
|
||||||
|
|
@ -302,6 +303,7 @@ var Shapes = []string{
|
||||||
ShapeClass,
|
ShapeClass,
|
||||||
ShapeSQLTable,
|
ShapeSQLTable,
|
||||||
ShapeImage,
|
ShapeImage,
|
||||||
|
ShapeSequenceDiagram,
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsShape(s string) bool {
|
func IsShape(s string) bool {
|
||||||
|
|
@ -345,29 +347,30 @@ func (text MText) GetColor(theme *d2themes.Theme, isItalic bool) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var DSL_SHAPE_TO_SHAPE_TYPE = map[string]string{
|
var DSL_SHAPE_TO_SHAPE_TYPE = map[string]string{
|
||||||
"": shape.SQUARE_TYPE,
|
"": shape.SQUARE_TYPE,
|
||||||
ShapeRectangle: shape.SQUARE_TYPE,
|
ShapeRectangle: shape.SQUARE_TYPE,
|
||||||
ShapeSquare: shape.REAL_SQUARE_TYPE,
|
ShapeSquare: shape.REAL_SQUARE_TYPE,
|
||||||
ShapePage: shape.PAGE_TYPE,
|
ShapePage: shape.PAGE_TYPE,
|
||||||
ShapeParallelogram: shape.PARALLELOGRAM_TYPE,
|
ShapeParallelogram: shape.PARALLELOGRAM_TYPE,
|
||||||
ShapeDocument: shape.DOCUMENT_TYPE,
|
ShapeDocument: shape.DOCUMENT_TYPE,
|
||||||
ShapeCylinder: shape.CYLINDER_TYPE,
|
ShapeCylinder: shape.CYLINDER_TYPE,
|
||||||
ShapeQueue: shape.QUEUE_TYPE,
|
ShapeQueue: shape.QUEUE_TYPE,
|
||||||
ShapePackage: shape.PACKAGE_TYPE,
|
ShapePackage: shape.PACKAGE_TYPE,
|
||||||
ShapeStep: shape.STEP_TYPE,
|
ShapeStep: shape.STEP_TYPE,
|
||||||
ShapeCallout: shape.CALLOUT_TYPE,
|
ShapeCallout: shape.CALLOUT_TYPE,
|
||||||
ShapeStoredData: shape.STORED_DATA_TYPE,
|
ShapeStoredData: shape.STORED_DATA_TYPE,
|
||||||
ShapePerson: shape.PERSON_TYPE,
|
ShapePerson: shape.PERSON_TYPE,
|
||||||
ShapeDiamond: shape.DIAMOND_TYPE,
|
ShapeDiamond: shape.DIAMOND_TYPE,
|
||||||
ShapeOval: shape.OVAL_TYPE,
|
ShapeOval: shape.OVAL_TYPE,
|
||||||
ShapeCircle: shape.CIRCLE_TYPE,
|
ShapeCircle: shape.CIRCLE_TYPE,
|
||||||
ShapeHexagon: shape.HEXAGON_TYPE,
|
ShapeHexagon: shape.HEXAGON_TYPE,
|
||||||
ShapeCloud: shape.CLOUD_TYPE,
|
ShapeCloud: shape.CLOUD_TYPE,
|
||||||
ShapeText: shape.TEXT_TYPE,
|
ShapeText: shape.TEXT_TYPE,
|
||||||
ShapeCode: shape.CODE_TYPE,
|
ShapeCode: shape.CODE_TYPE,
|
||||||
ShapeClass: shape.CLASS_TYPE,
|
ShapeClass: shape.CLASS_TYPE,
|
||||||
ShapeSQLTable: shape.TABLE_TYPE,
|
ShapeSQLTable: shape.TABLE_TYPE,
|
||||||
ShapeImage: shape.IMAGE_TYPE,
|
ShapeImage: shape.IMAGE_TYPE,
|
||||||
|
ShapeSequenceDiagram: shape.SQUARE_TYPE,
|
||||||
}
|
}
|
||||||
|
|
||||||
var SHAPE_TYPE_TO_DSL_SHAPE map[string]string
|
var SHAPE_TYPE_TO_DSL_SHAPE map[string]string
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,13 @@ The simplified D2 flow at a package level looks like:
|
||||||
|
|
||||||
## Logistics
|
## Logistics
|
||||||
|
|
||||||
|
- **Important**: Contributions to D2 require a CLA. We will never relicense D2, but
|
||||||
|
Hashicorp has a good explanation of why a CLA has benefits for all parties (contributor,
|
||||||
|
community, us): [https://www.hashicorp.com/cla](https://www.hashicorp.com/cla). Please
|
||||||
|
email cla@terrastruct.com with your name and Github username stating that you agree to
|
||||||
|
[Terrastruct's
|
||||||
|
CLA](https://terrastruct-site-assets.s3.us-west-1.amazonaws.com/documents/terrastruct_cla.pdf).
|
||||||
|
You only have to do this the first time you contribute.
|
||||||
- D2 uses Issues as TODOs. No auto-closing on staleness.
|
- D2 uses Issues as TODOs. No auto-closing on staleness.
|
||||||
- Branch off `master`.
|
- Branch off `master`.
|
||||||
- Prefix pull request titles with a short descriptor of the domain, e.g. `d2renderer: Add
|
- Prefix pull request titles with a short descriptor of the domain, e.g. `d2renderer: Add
|
||||||
|
|
|
||||||
|
|
@ -932,7 +932,7 @@ x -> y: {
|
||||||
script: `
|
script: `
|
||||||
markdown: {
|
markdown: {
|
||||||
md: |md
|
md: |md
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, ` + `
|
||||||
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
|
|
|
|
||||||
}
|
}
|
||||||
|
|
@ -961,6 +961,31 @@ beta: {
|
||||||
alpha -> beta: gamma {
|
alpha -> beta: gamma {
|
||||||
style.font-color: green
|
style.font-color: green
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "latex",
|
||||||
|
script: `a: |latex
|
||||||
|
\\Huge{\\frac{\\alpha g^2}{\\omega^5} e^{[ -0.74\\bigl\\{\\frac{\\omega U_\\omega 19.5}{g}\\bigr\\}^{\\!-4}\\,]}}
|
||||||
|
|
|
||||||
|
|
||||||
|
b: |latex
|
||||||
|
e = mc^2
|
||||||
|
|
|
||||||
|
|
||||||
|
z: |latex
|
||||||
|
gibberish\\; math:\\sum_{i=0}^\\infty i^2
|
||||||
|
|
|
||||||
|
|
||||||
|
z -> a
|
||||||
|
z -> b
|
||||||
|
|
||||||
|
a -> c
|
||||||
|
b -> c
|
||||||
|
sugar -> c
|
||||||
|
c: mixed together
|
||||||
|
|
||||||
|
c -> solution: we get
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
514
e2etests/testdata/stable/latex/dagre/board.exp.json
generated
vendored
Normal file
514
e2etests/testdata/stable/latex/dagre/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,514 @@
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"shapes": [
|
||||||
|
{
|
||||||
|
"id": "a",
|
||||||
|
"type": "text",
|
||||||
|
"pos": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 164
|
||||||
|
},
|
||||||
|
"width": 382,
|
||||||
|
"height": 101,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#FFFFFF",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "\\\\Huge{\\\\frac{\\\\alpha g^2}{\\\\omega^5} e^{[ -0.74\\\\bigl\\\\{\\\\frac{\\\\omega U_\\\\omega 19.5}{g}\\\\bigr\\\\}^{\\\\!-4}\\\\,]}}",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "latex",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 382,
|
||||||
|
"labelHeight": 101
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b",
|
||||||
|
"type": "text",
|
||||||
|
"pos": {
|
||||||
|
"x": 442,
|
||||||
|
"y": 205
|
||||||
|
},
|
||||||
|
"width": 65,
|
||||||
|
"height": 18,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#FFFFFF",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "e = mc^2",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "latex",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 65,
|
||||||
|
"labelHeight": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "z",
|
||||||
|
"type": "text",
|
||||||
|
"pos": {
|
||||||
|
"x": 243,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"width": 179,
|
||||||
|
"height": 51,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#FFFFFF",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "gibberish\\\\; math:\\\\sum_{i=0}^\\\\infty i^2",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "latex",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 179,
|
||||||
|
"labelHeight": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c",
|
||||||
|
"type": "",
|
||||||
|
"pos": {
|
||||||
|
"x": 368,
|
||||||
|
"y": 377
|
||||||
|
},
|
||||||
|
"width": 214,
|
||||||
|
"height": 126,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#F7F8FE",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "mixed together",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 114,
|
||||||
|
"labelHeight": 26,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "sugar",
|
||||||
|
"type": "",
|
||||||
|
"pos": {
|
||||||
|
"x": 567,
|
||||||
|
"y": 151
|
||||||
|
},
|
||||||
|
"width": 146,
|
||||||
|
"height": 126,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#F7F8FE",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "sugar",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 46,
|
||||||
|
"labelHeight": 26,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "solution",
|
||||||
|
"type": "",
|
||||||
|
"pos": {
|
||||||
|
"x": 393,
|
||||||
|
"y": 603
|
||||||
|
},
|
||||||
|
"width": 164,
|
||||||
|
"height": 126,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#F7F8FE",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "solution",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 64,
|
||||||
|
"labelHeight": 26,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"id": "(z -> a)[0]",
|
||||||
|
"src": "z",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "a",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 284.87417218543044,
|
||||||
|
"y": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 209.7748344370861,
|
||||||
|
"y": 91
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 191,
|
||||||
|
"y": 113.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 191,
|
||||||
|
"y": 163.5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isCurve": true,
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(z -> b)[0]",
|
||||||
|
"src": "z",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "b",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 380.62582781456956,
|
||||||
|
"y": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 455.7251655629139,
|
||||||
|
"y": 91
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 121.8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 205
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isCurve": true,
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(a -> c)[0]",
|
||||||
|
"src": "a",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "c",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 191,
|
||||||
|
"y": 265.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 191,
|
||||||
|
"y": 314.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 226.3,
|
||||||
|
"y": 341.0701940035273
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 367.5,
|
||||||
|
"y": 397.35097001763666
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isCurve": true,
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(b -> c)[0]",
|
||||||
|
"src": "b",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "c",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 223
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 306.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 337
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 377
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isCurve": true,
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(sugar -> c)[0]",
|
||||||
|
"src": "sugar",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "c",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 640,
|
||||||
|
"y": 277
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 640,
|
||||||
|
"y": 317
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 625.4,
|
||||||
|
"y": 337
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 567,
|
||||||
|
"y": 377
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isCurve": true,
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(c -> solution)[0]",
|
||||||
|
"src": "c",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "solution",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "we get",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 44,
|
||||||
|
"labelHeight": 21,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 503
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 543
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 563
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 474.5,
|
||||||
|
"y": 603
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isCurve": true,
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
790
e2etests/testdata/stable/latex/dagre/sketch.exp.svg
vendored
Normal file
790
e2etests/testdata/stable/latex/dagre/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 506 KiB |
484
e2etests/testdata/stable/latex/elk/board.exp.json
generated
vendored
Normal file
484
e2etests/testdata/stable/latex/elk/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,484 @@
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"shapes": [
|
||||||
|
{
|
||||||
|
"id": "a",
|
||||||
|
"type": "text",
|
||||||
|
"pos": {
|
||||||
|
"x": 291,
|
||||||
|
"y": 196
|
||||||
|
},
|
||||||
|
"width": 382,
|
||||||
|
"height": 101,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#FFFFFF",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "\\\\Huge{\\\\frac{\\\\alpha g^2}{\\\\omega^5} e^{[ -0.74\\\\bigl\\\\{\\\\frac{\\\\omega U_\\\\omega 19.5}{g}\\\\bigr\\\\}^{\\\\!-4}\\\\,]}}",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "latex",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 382,
|
||||||
|
"labelHeight": 101
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b",
|
||||||
|
"type": "text",
|
||||||
|
"pos": {
|
||||||
|
"x": 450,
|
||||||
|
"y": 158
|
||||||
|
},
|
||||||
|
"width": 65,
|
||||||
|
"height": 18,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#FFFFFF",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "e = mc^2",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "latex",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 65,
|
||||||
|
"labelHeight": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "z",
|
||||||
|
"type": "text",
|
||||||
|
"pos": {
|
||||||
|
"x": 12,
|
||||||
|
"y": 150
|
||||||
|
},
|
||||||
|
"width": 179,
|
||||||
|
"height": 51,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#FFFFFF",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "gibberish\\\\; math:\\\\sum_{i=0}^\\\\infty i^2",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "latex",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 179,
|
||||||
|
"labelHeight": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c",
|
||||||
|
"type": "",
|
||||||
|
"pos": {
|
||||||
|
"x": 773,
|
||||||
|
"y": 104
|
||||||
|
},
|
||||||
|
"width": 214,
|
||||||
|
"height": 126,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#F7F8FE",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "mixed together",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 114,
|
||||||
|
"labelHeight": 26,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "sugar",
|
||||||
|
"type": "",
|
||||||
|
"pos": {
|
||||||
|
"x": 527,
|
||||||
|
"y": 12
|
||||||
|
},
|
||||||
|
"width": 146,
|
||||||
|
"height": 126,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#F7F8FE",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "sugar",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 46,
|
||||||
|
"labelHeight": 26,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "solution",
|
||||||
|
"type": "",
|
||||||
|
"pos": {
|
||||||
|
"x": 1231,
|
||||||
|
"y": 104
|
||||||
|
},
|
||||||
|
"width": 164,
|
||||||
|
"height": 126,
|
||||||
|
"level": 1,
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"borderRadius": 0,
|
||||||
|
"fill": "#F7F8FE",
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"shadow": false,
|
||||||
|
"3d": false,
|
||||||
|
"multiple": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"link": "",
|
||||||
|
"icon": null,
|
||||||
|
"iconPosition": "",
|
||||||
|
"fields": null,
|
||||||
|
"methods": null,
|
||||||
|
"columns": null,
|
||||||
|
"label": "solution",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#0A0F25",
|
||||||
|
"italic": false,
|
||||||
|
"bold": true,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 64,
|
||||||
|
"labelHeight": 26,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"id": "(z -> a)[0]",
|
||||||
|
"src": "z",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "a",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 191,
|
||||||
|
"y": 184
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 241,
|
||||||
|
"y": 184
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 241,
|
||||||
|
"y": 246.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 291,
|
||||||
|
"y": 246.5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(z -> b)[0]",
|
||||||
|
"src": "z",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "b",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 191,
|
||||||
|
"y": 167
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 449.5,
|
||||||
|
"y": 167
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(a -> c)[0]",
|
||||||
|
"src": "a",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "c",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 673,
|
||||||
|
"y": 246.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 723,
|
||||||
|
"y": 246.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 723,
|
||||||
|
"y": 198.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 773,
|
||||||
|
"y": 198.5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(b -> c)[0]",
|
||||||
|
"src": "b",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "c",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 514.5,
|
||||||
|
"y": 167
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 773,
|
||||||
|
"y": 167
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(sugar -> c)[0]",
|
||||||
|
"src": "sugar",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "c",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 0,
|
||||||
|
"labelHeight": 0,
|
||||||
|
"labelPosition": "",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 673,
|
||||||
|
"y": 75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 723,
|
||||||
|
"y": 75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 723,
|
||||||
|
"y": 135.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 773,
|
||||||
|
"y": 135.5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "(c -> solution)[0]",
|
||||||
|
"src": "c",
|
||||||
|
"srcArrow": "none",
|
||||||
|
"srcLabel": "",
|
||||||
|
"dst": "solution",
|
||||||
|
"dstArrow": "triangle",
|
||||||
|
"dstLabel": "",
|
||||||
|
"opacity": 1,
|
||||||
|
"strokeDash": 0,
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"stroke": "#0D32B2",
|
||||||
|
"label": "we get",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontFamily": "DEFAULT",
|
||||||
|
"language": "",
|
||||||
|
"color": "#676C7E",
|
||||||
|
"italic": true,
|
||||||
|
"bold": false,
|
||||||
|
"underline": false,
|
||||||
|
"labelWidth": 44,
|
||||||
|
"labelHeight": 21,
|
||||||
|
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||||
|
"labelPercentage": 0,
|
||||||
|
"route": [
|
||||||
|
{
|
||||||
|
"x": 987,
|
||||||
|
"y": 167
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1231,
|
||||||
|
"y": 167
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"animated": false,
|
||||||
|
"tooltip": "",
|
||||||
|
"icon": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
790
e2etests/testdata/stable/latex/elk/sketch.exp.svg
vendored
Normal file
790
e2etests/testdata/stable/latex/elk/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 506 KiB |
19
install.sh
19
install.sh
|
|
@ -68,7 +68,7 @@ should_color() {
|
||||||
_COLOR=1
|
_COLOR=1
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
printf '$COLOR must be 0, 1, false or true but got %s' "$COLOR" >&2
|
printf '$COLOR must be 0, 1, false or true but got %s\n' "$COLOR" >&2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -225,8 +225,9 @@ header() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bigheader() {
|
bigheader() {
|
||||||
|
set -- "$(echo "$*" | sed "s/^/ * /")"
|
||||||
logp "/**
|
logp "/**
|
||||||
* $1
|
$*
|
||||||
**/"
|
**/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,7 +479,7 @@ help() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
usage: $arg0 [--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local]
|
usage: $arg0 [-d|--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local]
|
||||||
[--tala latest] [--force] [--uninstall]
|
[--tala latest] [--force] [--uninstall]
|
||||||
|
|
||||||
install.sh automates the installation of D2 onto your system. It currently only supports
|
install.sh automates the installation of D2 onto your system. It currently only supports
|
||||||
|
|
@ -490,7 +491,7 @@ If you pass --edge, it will clone the source, build a release and install from i
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
|
||||||
--dry-run
|
-d, --dry-run
|
||||||
Pass to have install.sh show the install method and flags that will be used to install
|
Pass to have install.sh show the install method and flags that will be used to install
|
||||||
without executing them. Very useful to understand what changes it will make to your system.
|
without executing them. Very useful to understand what changes it will make to your system.
|
||||||
|
|
||||||
|
|
@ -565,7 +566,7 @@ main() {
|
||||||
help
|
help
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
dry-run)
|
d|dry-run)
|
||||||
flag_noarg && shift "$FLAGSHIFT"
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
DRY_RUN=1
|
DRY_RUN=1
|
||||||
;;
|
;;
|
||||||
|
|
@ -652,12 +653,16 @@ main() {
|
||||||
if [ -n "${UNINSTALL-}" ]; then
|
if [ -n "${UNINSTALL-}" ]; then
|
||||||
uninstall
|
uninstall
|
||||||
if [ -n "${DRY_RUN-}" ]; then
|
if [ -n "${DRY_RUN-}" ]; then
|
||||||
log "Rerun without --dry-run to execute printed commands and perform uninstall."
|
FGCOLOR=3 bigheader "***********
|
||||||
|
Rerun without --dry-run to execute printed commands and perform install.
|
||||||
|
***********"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
install
|
install
|
||||||
if [ -n "${DRY_RUN-}" ]; then
|
if [ -n "${DRY_RUN-}" ]; then
|
||||||
log "Rerun without --dry-run to execute printed commands and perform install."
|
FGCOLOR=3 bigheader "***********
|
||||||
|
Rerun without --dry-run to execute printed commands and perform install.
|
||||||
|
***********"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
||||||
133
testdata/d2compiler/TestCompile/basic_sequence.exp.json
generated
vendored
Normal file
133
testdata/d2compiler/TestCompile/basic_sequence.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
{
|
||||||
|
"graph": {
|
||||||
|
"ast": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,0:0:0-3:0:33",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,0:0:0-2:1:32",
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,0:0:0-0:1:1",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,0:0:0-0:1:1",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "x",
|
||||||
|
"raw_string": "x"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"map": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,0:3:3-2:0:31",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,1:2:7-1:25:30",
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,1:2:7-1:7:12",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,1:2:7-1:7:12",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "shape",
|
||||||
|
"raw_string": "shape"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,1:9:14-1:25:30",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "sequence_diagram",
|
||||||
|
"raw_string": "sequence_diagram"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"id": "",
|
||||||
|
"id_val": "",
|
||||||
|
"label_dimensions": {
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
},
|
||||||
|
"attributes": {
|
||||||
|
"label": {
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"style": {},
|
||||||
|
"near_key": null,
|
||||||
|
"shape": {
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edges": null,
|
||||||
|
"objects": [
|
||||||
|
{
|
||||||
|
"id": "x",
|
||||||
|
"id_val": "x",
|
||||||
|
"label_dimensions": {
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
},
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,0:0:0-0:1:1",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/basic_sequence.d2,0:0:0-0:1:1",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "x",
|
||||||
|
"raw_string": "x"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"key_path_index": 0,
|
||||||
|
"map_key_edge_index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"attributes": {
|
||||||
|
"label": {
|
||||||
|
"value": "x"
|
||||||
|
},
|
||||||
|
"style": {},
|
||||||
|
"near_key": null,
|
||||||
|
"shape": {
|
||||||
|
"value": "sequence_diagram"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"err": null
|
||||||
|
}
|
||||||
63
testdata/d2compiler/TestCompile/root_sequence.exp.json
generated
vendored
Normal file
63
testdata/d2compiler/TestCompile/root_sequence.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
{
|
||||||
|
"graph": {
|
||||||
|
"ast": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/root_sequence.d2,0:0:0-1:0:24",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/root_sequence.d2,0:0:0-0:23:23",
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/root_sequence.d2,0:0:0-0:5:5",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/root_sequence.d2,0:0:0-0:5:5",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "shape",
|
||||||
|
"raw_string": "shape"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/root_sequence.d2,0:7:7-0:23:23",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "sequence_diagram",
|
||||||
|
"raw_string": "sequence_diagram"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"id": "",
|
||||||
|
"id_val": "",
|
||||||
|
"label_dimensions": {
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
},
|
||||||
|
"attributes": {
|
||||||
|
"label": {
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"style": {},
|
||||||
|
"near_key": null,
|
||||||
|
"shape": {
|
||||||
|
"value": "sequence_diagram"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edges": null,
|
||||||
|
"objects": null
|
||||||
|
},
|
||||||
|
"err": null
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue