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/d2elklayout/elk.js 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
|
||||
|
||||
jobs:
|
||||
assert-linear:
|
||||
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:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
@ -25,63 +15,7 @@ jobs:
|
|||
with:
|
||||
go-version-file: ./go.mod
|
||||
cache: true
|
||||
- run: COLOR=1 ./make.sh fmt
|
||||
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
|
||||
- run: COLOR=1 ./make.sh all race
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
|
@ -90,22 +24,3 @@ jobs:
|
|||
with:
|
||||
name: d2chaos-test
|
||||
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
|
||||
|
||||
jobs:
|
||||
all:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
with:
|
||||
go-version-file: ./go.mod
|
||||
cache: true
|
||||
- run: CI_ALL=1 COLOR=1 ./make.sh
|
||||
- run: COLOR=1 CI_FORCE=1 ./make.sh all race
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
|
|
|||
6
Makefile
6
Makefile
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
.PHONY: all
|
||||
all: fmt gen lint build test
|
||||
ifdef CI
|
||||
all: assert-linear
|
||||
endif
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
|
|
@ -24,6 +21,3 @@ test:
|
|||
.PHONY: race
|
||||
race:
|
||||
prefix "$@" ./ci/test.sh --race ./...
|
||||
.PHONY: assert-linear
|
||||
assert-linear:
|
||||
prefix "$@" ./ci/sub/assert_linear.sh
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ help() {
|
|||
fi
|
||||
|
||||
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]
|
||||
|
||||
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:
|
||||
|
||||
--dry-run
|
||||
-d, --dry-run
|
||||
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.
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ main() {
|
|||
help
|
||||
return 0
|
||||
;;
|
||||
dry-run)
|
||||
d|dry-run)
|
||||
flag_noarg && shift "$FLAGSHIFT"
|
||||
DRY_RUN=1
|
||||
;;
|
||||
|
|
@ -188,12 +188,16 @@ main() {
|
|||
if [ -n "${UNINSTALL-}" ]; then
|
||||
uninstall
|
||||
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
|
||||
else
|
||||
install
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,20 @@
|
|||
#### 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)
|
||||
- `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)
|
||||
- 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 🔧
|
||||
|
||||
- Local images can now be included, e.g. `icon: ./my_img.png`.
|
||||
[#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 🔴
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ should_color() {
|
|||
_COLOR=1
|
||||
return 0
|
||||
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
|
||||
|
||||
|
|
@ -219,8 +219,9 @@ header() {
|
|||
}
|
||||
|
||||
bigheader() {
|
||||
set -- "$(echo "$*" | sed "s/^/ * /")"
|
||||
logp "/**
|
||||
* $1
|
||||
$*
|
||||
**/"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/spf13/pflag"
|
||||
|
||||
"oss.terrastruct.com/d2"
|
||||
"oss.terrastruct.com/d2/d2layouts/d2sequence"
|
||||
"oss.terrastruct.com/d2/d2plugin"
|
||||
"oss.terrastruct.com/d2/d2renderers/d2svg"
|
||||
"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
|
||||
}
|
||||
|
||||
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{
|
||||
Layout: plugin.Layout,
|
||||
Layout: layout,
|
||||
Ruler: ruler,
|
||||
ThemeID: themeID,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -266,6 +266,8 @@ func (c *compiler) compileKey(obj *d2graph.Object, m *d2ast.Map, mk *d2ast.Key)
|
|||
}, unresolvedObj)
|
||||
} else if obj.Parent == nil {
|
||||
// Top level reserved key set on root.
|
||||
c.compileAttributes(&obj.Attributes, mk)
|
||||
c.applyScalar(&obj.Attributes, reserved, mk.Value.ScalarBox())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -377,7 +379,7 @@ func (c *compiler) applyScalar(attrs *d2graph.Attributes, reserved string, box d
|
|||
if ok {
|
||||
attrs.Language = fullTag
|
||||
}
|
||||
if attrs.Language == "markdown" {
|
||||
if attrs.Language == "markdown" || attrs.Language == "latex" {
|
||||
attrs.Shape.Value = d2target.ShapeText
|
||||
} else {
|
||||
attrs.Shape.Value = d2target.ShapeCode
|
||||
|
|
@ -549,6 +551,7 @@ func (c *compiler) compileFlatKey(k *d2ast.KeyPath) ([]string, string, bool) {
|
|||
// TODO add more, e.g. C, bash
|
||||
var ShortToFullLanguageAliases = map[string]string{
|
||||
"md": "markdown",
|
||||
"tex": "latex",
|
||||
"js": "javascript",
|
||||
"go": "golang",
|
||||
"py": "python",
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"oss.terrastruct.com/d2/d2format"
|
||||
"oss.terrastruct.com/d2/d2parser"
|
||||
"oss.terrastruct.com/d2/d2renderers/d2fonts"
|
||||
"oss.terrastruct.com/d2/d2renderers/d2latex"
|
||||
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
||||
"oss.terrastruct.com/d2/d2target"
|
||||
"oss.terrastruct.com/d2/d2themes"
|
||||
|
|
@ -833,11 +834,19 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
|
|||
var dims *d2target.TextDimensions
|
||||
var innerLabelPadding = 5
|
||||
if obj.Attributes.Shape.Value == d2target.ShapeText {
|
||||
if obj.Attributes.Language == "latex" {
|
||||
width, height, err := d2latex.Measure(obj.Text().Text)
|
||||
if err != nil {
|
||||
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
|
||||
} else {
|
||||
dims = getTextDimensions(mtexts, ruler, obj.Text())
|
||||
|
|
|
|||
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",
|
||||
text: `
|
||||
--: meow]]]
|
||||
meow][: ok
|
||||
ok: "dmsadmakls" dsamkldkmsa
|
||||
|
||||
s.shape: orochimaru
|
||||
x.shape: dasdasdas
|
||||
--: meow]]] ` + `
|
||||
meow][: ok ` + `
|
||||
ok: "dmsadmakls" dsamkldkmsa ` + `
|
||||
` + `
|
||||
s.shape: orochimaru ` + `
|
||||
x.shape: dasdasdas ` + `
|
||||
|
||||
wow:
|
||||
|
||||
:
|
||||
|
||||
: ` + `
|
||||
` + `
|
||||
[]
|
||||
|
||||
{}
|
||||
|
|
@ -214,7 +214,7 @@ meow
|
|||
{
|
||||
name: "trailing_whitespace",
|
||||
text: `
|
||||
s.shape: orochimaru
|
||||
s.shape: orochimaru ` + `
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
|
@ -334,16 +334,16 @@ a: | hello |
|
|||
name: "block_trailing_space",
|
||||
text: `
|
||||
x: |
|
||||
meow
|
||||
meow ` + `
|
||||
|
|
||||
""" hello
|
||||
""" hello ` + `
|
||||
"""
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "block_edge_case",
|
||||
text: `
|
||||
x: | meow
|
||||
x: | meow ` + `
|
||||
hello
|
||||
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"
|
||||
|
||||
"oss.terrastruct.com/d2/d2renderers/d2fonts"
|
||||
"oss.terrastruct.com/d2/d2renderers/d2latex"
|
||||
"oss.terrastruct.com/d2/d2renderers/textmeasure"
|
||||
"oss.terrastruct.com/d2/d2target"
|
||||
"oss.terrastruct.com/d2/lib/color"
|
||||
|
|
@ -701,6 +702,15 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
|
|||
}
|
||||
fmt.Fprintf(writer, "</g></g>")
|
||||
case d2target.ShapeText:
|
||||
if targetShape.Language == "latex" {
|
||||
render, err := d2latex.Render(targetShape.Label)
|
||||
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
|
||||
|
|
@ -712,6 +722,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
|
|||
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:
|
||||
fontColor := "black"
|
||||
if targetShape.Color != "" {
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ const (
|
|||
ShapeClass = "class"
|
||||
ShapeSQLTable = "sql_table"
|
||||
ShapeImage = "image"
|
||||
ShapeSequenceDiagram = "sequence_diagram"
|
||||
)
|
||||
|
||||
var Shapes = []string{
|
||||
|
|
@ -302,6 +303,7 @@ var Shapes = []string{
|
|||
ShapeClass,
|
||||
ShapeSQLTable,
|
||||
ShapeImage,
|
||||
ShapeSequenceDiagram,
|
||||
}
|
||||
|
||||
func IsShape(s string) bool {
|
||||
|
|
@ -368,6 +370,7 @@ var DSL_SHAPE_TO_SHAPE_TYPE = map[string]string{
|
|||
ShapeClass: shape.CLASS_TYPE,
|
||||
ShapeSQLTable: shape.TABLE_TYPE,
|
||||
ShapeImage: shape.IMAGE_TYPE,
|
||||
ShapeSequenceDiagram: shape.SQUARE_TYPE,
|
||||
}
|
||||
|
||||
var SHAPE_TYPE_TO_DSL_SHAPE map[string]string
|
||||
|
|
|
|||
|
|
@ -30,6 +30,13 @@ The simplified D2 flow at a package level looks like:
|
|||
|
||||
## 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.
|
||||
- Branch off `master`.
|
||||
- Prefix pull request titles with a short descriptor of the domain, e.g. `d2renderer: Add
|
||||
|
|
|
|||
|
|
@ -932,7 +932,7 @@ x -> y: {
|
|||
script: `
|
||||
markdown: {
|
||||
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.
|
||||
|
|
||||
}
|
||||
|
|
@ -961,6 +961,31 @@ beta: {
|
|||
alpha -> beta: gamma {
|
||||
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
|
||||
return 0
|
||||
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
|
||||
|
||||
|
|
@ -225,8 +225,9 @@ header() {
|
|||
}
|
||||
|
||||
bigheader() {
|
||||
set -- "$(echo "$*" | sed "s/^/ * /")"
|
||||
logp "/**
|
||||
* $1
|
||||
$*
|
||||
**/"
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +479,7 @@ help() {
|
|||
fi
|
||||
|
||||
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]
|
||||
|
||||
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:
|
||||
|
||||
--dry-run
|
||||
-d, --dry-run
|
||||
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.
|
||||
|
||||
|
|
@ -565,7 +566,7 @@ main() {
|
|||
help
|
||||
return 0
|
||||
;;
|
||||
dry-run)
|
||||
d|dry-run)
|
||||
flag_noarg && shift "$FLAGSHIFT"
|
||||
DRY_RUN=1
|
||||
;;
|
||||
|
|
@ -652,12 +653,16 @@ main() {
|
|||
if [ -n "${UNINSTALL-}" ]; then
|
||||
uninstall
|
||||
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
|
||||
else
|
||||
install
|
||||
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
|
||||
}
|
||||
|
|
|
|||
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