From f7f2c8efaac8a7131f7ebd3e8f93de96aa1e346c Mon Sep 17 00:00:00 2001 From: David Revay Date: Fri, 30 Dec 2022 14:22:57 +1100 Subject: [PATCH 01/67] docs: add ros2 exporter --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 045cc18fa..34940600e 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,7 @@ let us know and we'll be happy to include it here! - **Postgres importer**: [https://github.com/zekenie/d2-erd-from-postgres](https://github.com/zekenie/d2-erd-from-postgres) - **Structurizr to D2 exporter**: [https://github.com/goto1134/structurizr-d2-exporter](https://github.com/goto1134/structurizr-d2-exporter) - **MdBook preprocessor**: [https://github.com/danieleades/mdbook-d2](https://github.com/danieleades/mdbook-d2) +- **ROS2 D2 Exporter**: [https://github.com/Greenroom-Robotics/ros-d2](https://github.com/Greenroom-Robotics/ros-d2) - **D2 org-mode support**: [https://github.com/xcapaldi/ob-d2](https://github.com/xcapaldi/ob-d2) ### Misc From 590caa243c63e2ac9e65174efa93e7c8566aca4f Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 29 Dec 2022 21:09:53 -0800 Subject: [PATCH 02/67] works --- d2layouts/d2dagrelayout/layout.go | 15 +++++++++++-- d2layouts/d2elklayout/layout.go | 14 ++++++++++++- d2lib/c.go | 7 ------- d2lib/d2.go | 11 +++++----- d2plugin/exec.go | 14 +++++++++++++ d2plugin/plugin.go | 2 ++ d2plugin/plugin_dagre.go | 21 ++++++++++++++++--- d2plugin/plugin_elk.go | 19 +++++++++++++++-- main.go | 35 +++++++++++++++++++++++++++++++ 9 files changed, 118 insertions(+), 20 deletions(-) delete mode 100644 d2lib/c.go diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index 68d8ec0f6..18709c1bf 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -30,6 +30,14 @@ var setupJS string //go:embed dagre.js var dagreJS string +type Opts struct { + NodeSep int +} + +var DefaultOpts = Opts{ + NodeSep: 60, +} + type DagreNode struct { ID string `json:"id"` X float64 `json:"x"` @@ -51,7 +59,10 @@ type dagreGraphAttrs struct { rankdir string } -func Layout(ctx context.Context, g *d2graph.Graph) (err error) { +func Layout(ctx context.Context, g *d2graph.Graph, opts *Opts) (err error) { + if opts == nil { + opts = &DefaultOpts + } defer xdefer.Errorf(&err, "failed to dagre layout") debugJS := false @@ -65,7 +76,7 @@ func Layout(ctx context.Context, g *d2graph.Graph) (err error) { rootAttrs := dagreGraphAttrs{ edgesep: 40, - nodesep: 60, + nodesep: opts.NodeSep, } isHorizontal := false switch g.Root.Attributes.Direction.Value { diff --git a/d2layouts/d2elklayout/layout.go b/d2layouts/d2elklayout/layout.go index 6dd37f828..610a74572 100644 --- a/d2layouts/d2elklayout/layout.go +++ b/d2layouts/d2elklayout/layout.go @@ -77,6 +77,15 @@ type ELKGraph struct { Edges []*ELKEdge `json:"edges,omitempty"` } +var DefaultOpts = ELKLayoutOptions{ + Algorithm: "layered", + HierarchyHandling: "INCLUDE_CHILDREN", + NodeSpacing: 100.0, + EdgeNodeSpacing: 50.0, + SelfLoopSpacing: 50.0, + ConsiderModelOrder: "NODES_AND_EDGES", +} + type ELKLayoutOptions struct { Algorithm string `json:"elk.algorithm,omitempty"` HierarchyHandling string `json:"elk.hierarchyHandling,omitempty"` @@ -90,7 +99,10 @@ type ELKLayoutOptions struct { ForceNodeModelOrder bool `json:"elk.layered.crossingMinimization.forceNodeModelOrder,omitempty"` } -func Layout(ctx context.Context, g *d2graph.Graph) (err error) { +func Layout(ctx context.Context, g *d2graph.Graph, opts *ELKLayoutOptions) (err error) { + if opts == nil { + opts = &DefaultOpts + } defer xdefer.Errorf(&err, "failed to ELK layout") vm := goja.New() diff --git a/d2lib/c.go b/d2lib/c.go deleted file mode 100644 index c62ef79ae..000000000 --- a/d2lib/c.go +++ /dev/null @@ -1,7 +0,0 @@ -package d2lib - -import "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" - -func init() { - dagreLayout = d2dagrelayout.Layout -} diff --git a/d2lib/d2.go b/d2lib/d2.go index 936124b9f..bfe9713a9 100644 --- a/d2lib/d2.go +++ b/d2lib/d2.go @@ -9,6 +9,7 @@ import ( "oss.terrastruct.com/d2/d2compiler" "oss.terrastruct.com/d2/d2exporter" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2layouts/d2near" "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2renderers/d2fonts" @@ -74,12 +75,12 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target func getLayout(opts *CompileOptions) (func(context.Context, *d2graph.Graph) error, error) { if opts.Layout != nil { return opts.Layout, nil - } else if os.Getenv("D2_LAYOUT") == "dagre" && dagreLayout != nil { - return dagreLayout, nil + } else if os.Getenv("D2_LAYOUT") == "dagre" { + defaultLayout := func(ctx context.Context, g *d2graph.Graph) error { + return d2dagrelayout.Layout(ctx, g, nil) + } + return defaultLayout, nil } else { return nil, errors.New("no available layout") } } - -// See c.go -var dagreLayout func(context.Context, *d2graph.Graph) error diff --git a/d2plugin/exec.go b/d2plugin/exec.go index b4929dcc2..b15ac7a5f 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -10,6 +10,7 @@ import ( "time" "oss.terrastruct.com/util-go/xdefer" + "oss.terrastruct.com/util-go/xmain" "oss.terrastruct.com/d2/d2graph" ) @@ -37,6 +38,19 @@ import ( // the error to stderr. type execPlugin struct { path string + opts map[string]string +} + +func (p execPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { + if opts != nil { + execOpts, ok := opts.(map[string]string) + if !ok { + return xmain.UsageErrorf("non-exec layout options given for exec") + } + + p.opts = execOpts + } + return nil } func (p execPlugin) Info(ctx context.Context) (_ *PluginInfo, err error) { diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index 56798c88f..2e538f4c4 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -23,6 +23,8 @@ type Plugin interface { // Info returns the current info information of the plugin. Info(context.Context) (*PluginInfo, error) + HydrateOpts(context.Context, interface{}) error + // Layout runs the plugin's autolayout algorithm on the input graph // and returns a new graph with the computed placements. Layout(context.Context, *d2graph.Graph) error diff --git a/d2plugin/plugin_dagre.go b/d2plugin/plugin_dagre.go index 228011ac0..b4d75688b 100644 --- a/d2plugin/plugin_dagre.go +++ b/d2plugin/plugin_dagre.go @@ -7,15 +7,30 @@ import ( "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" + "oss.terrastruct.com/util-go/xmain" ) var DagrePlugin = dagrePlugin{} func init() { - plugins = append(plugins, DagrePlugin) + plugins = append(plugins, &DagrePlugin) } -type dagrePlugin struct{} +type dagrePlugin struct { + opts *d2dagrelayout.Opts +} + +func (p *dagrePlugin) HydrateOpts(ctx context.Context, opts interface{}) error { + if opts != nil { + dagreOpts, ok := opts.(d2dagrelayout.Opts) + if !ok { + return xmain.UsageErrorf("non-dagre layout options given for dagre") + } + + p.opts = &dagreOpts + } + return nil +} func (p dagrePlugin) Info(context.Context) (*PluginInfo, error) { return &PluginInfo{ @@ -33,7 +48,7 @@ note: dagre is the primary layout algorithm for text to diagram generator Mermai } func (p dagrePlugin) Layout(ctx context.Context, g *d2graph.Graph) error { - return d2dagrelayout.Layout(ctx, g) + return d2dagrelayout.Layout(ctx, g, p.opts) } func (p dagrePlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index 6a8567f5e..5bdc018e1 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -7,6 +7,7 @@ import ( "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2elklayout" + "oss.terrastruct.com/util-go/xmain" ) var ELKPlugin = elkPlugin{} @@ -15,7 +16,21 @@ func init() { plugins = append(plugins, ELKPlugin) } -type elkPlugin struct{} +type elkPlugin struct { + opts *d2elklayout.ELKLayoutOptions +} + +func (p elkPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { + if opts != nil { + elkOpts, ok := opts.(d2elklayout.ELKLayoutOptions) + if !ok { + return xmain.UsageErrorf("non-dagre layout options given for dagre") + } + + p.opts = &elkOpts + } + return nil +} func (p elkPlugin) Info(context.Context) (*PluginInfo, error) { return &PluginInfo{ @@ -28,7 +43,7 @@ See https://github.com/kieler/elkjs for more.`, } func (p elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { - return d2elklayout.Layout(ctx, g) + return d2elklayout.Layout(ctx, g, p.opts) } func (p elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { diff --git a/main.go b/main.go index 0377ac538..83ccef354 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ import ( "oss.terrastruct.com/util-go/go2" "oss.terrastruct.com/util-go/xmain" + "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2plugin" "oss.terrastruct.com/d2/d2renderers/d2fonts" @@ -75,6 +76,11 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } + err = populateLayoutOpts(ms) + if err != nil { + return err + } + err = ms.Opts.Flags.Parse(ms.Opts.Args) if !errors.Is(err, pflag.ErrHelp) && err != nil { return xmain.UsageErrorf("failed to parse flags: %v", err) @@ -144,6 +150,16 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } + layoutOpts, err := parseLayoutOpts(ms, *layoutFlag) + if err != nil { + return err + } + + err = plugin.HydrateOpts(ctx, layoutOpts) + if err != nil { + return err + } + pluginLocation := "bundled" if path != "" { pluginLocation = fmt.Sprintf("executable plugin at %s", humanPath(path)) @@ -288,3 +304,22 @@ func renameExt(fp string, newExt string) string { func DiscardSlog(ctx context.Context) context.Context { return ctxlog.With(ctx, slog.Make(sloghuman.Sink(io.Discard))) } + +func populateLayoutOpts(ms *xmain.State) error { + _, err := ms.Opts.Int64("", "dagre-nodesep", "", int64(d2dagrelayout.DefaultOpts.NodeSep), "number of pixels that separate nodes horizontally in the layout.") + if err != nil { + return err + } + return nil +} + +func parseLayoutOpts(ms *xmain.State, layout string) (interface{}, error) { + if layout == "dagre" { + nodesep, _ := ms.Opts.Flags.GetInt64("dagre-nodesep") + return d2dagrelayout.Opts{ + NodeSep: int(nodesep), + }, nil + } + + return nil, fmt.Errorf("unexpected error, layout not found for parsing opts") +} From eccec7afddd51dc2f547b4ae3490a9dcab6865e0 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 29 Dec 2022 22:43:01 -0800 Subject: [PATCH 03/67] elk --- d2layouts/d2dagrelayout/layout.go | 4 ++- d2layouts/d2elklayout/layout.go | 49 ++++++++++++++++--------------- d2plugin/plugin_elk.go | 14 ++++----- main.go | 41 ++++++++++++++++++++++++-- 4 files changed, 75 insertions(+), 33 deletions(-) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index 18709c1bf..ee86e9599 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -32,10 +32,12 @@ var dagreJS string type Opts struct { NodeSep int + EdgeSep int } var DefaultOpts = Opts{ NodeSep: 60, + EdgeSep: 40, } type DagreNode struct { @@ -75,7 +77,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *Opts) (err error) { } rootAttrs := dagreGraphAttrs{ - edgesep: 40, + edgesep: opts.EdgeSep, nodesep: opts.NodeSep, } isHorizontal := false diff --git a/d2layouts/d2elklayout/layout.go b/d2layouts/d2elklayout/layout.go index 610a74572..f46e19004 100644 --- a/d2layouts/d2elklayout/layout.go +++ b/d2layouts/d2elklayout/layout.go @@ -77,29 +77,33 @@ type ELKGraph struct { Edges []*ELKEdge `json:"edges,omitempty"` } -var DefaultOpts = ELKLayoutOptions{ - Algorithm: "layered", - HierarchyHandling: "INCLUDE_CHILDREN", - NodeSpacing: 100.0, - EdgeNodeSpacing: 50.0, - SelfLoopSpacing: 50.0, - ConsiderModelOrder: "NODES_AND_EDGES", +var DefaultOpts = ConfigurableOpts{ + Algorithm: "layered", + NodeSpacing: 100.0, + Padding: "[top=75,left=75,bottom=75,right=75]", + EdgeNodeSpacing: 50.0, + SelfLoopSpacing: 50.0, +} + +type ConfigurableOpts struct { + Algorithm string `json:"elk.algorithm,omitempty"` + NodeSpacing int `json:"spacing.nodeNodeBetweenLayers,omitempty"` + Padding string `json:"elk.padding,omitempty"` + EdgeNodeSpacing int `json:"spacing.edgeNodeBetweenLayers,omitempty"` + SelfLoopSpacing int `json:"elk.spacing.nodeSelfLoop"` } type ELKLayoutOptions struct { - Algorithm string `json:"elk.algorithm,omitempty"` - HierarchyHandling string `json:"elk.hierarchyHandling,omitempty"` - NodeSpacing float64 `json:"spacing.nodeNodeBetweenLayers,omitempty"` - Padding string `json:"elk.padding,omitempty"` - EdgeNodeSpacing float64 `json:"spacing.edgeNodeBetweenLayers,omitempty"` - Direction string `json:"elk.direction"` - SelfLoopSpacing float64 `json:"elk.spacing.nodeSelfLoop"` - InlineEdgeLabels bool `json:"elk.edgeLabels.inline,omitempty"` - ConsiderModelOrder string `json:"elk.layered.considerModelOrder.strategy,omitempty"` - ForceNodeModelOrder bool `json:"elk.layered.crossingMinimization.forceNodeModelOrder,omitempty"` + Direction string `json:"elk.direction"` + HierarchyHandling string `json:"elk.hierarchyHandling,omitempty"` + InlineEdgeLabels bool `json:"elk.edgeLabels.inline,omitempty"` + ForceNodeModelOrder bool `json:"elk.layered.crossingMinimization.forceNodeModelOrder,omitempty"` + ConsiderModelOrder string `json:"elk.layered.considerModelOrder.strategy,omitempty"` + + ConfigurableOpts } -func Layout(ctx context.Context, g *d2graph.Graph, opts *ELKLayoutOptions) (err error) { +func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err error) { if opts == nil { opts = &DefaultOpts } @@ -122,12 +126,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ELKLayoutOptions) (err elkGraph := &ELKGraph{ ID: "root", LayoutOptions: &ELKLayoutOptions{ - Algorithm: "layered", HierarchyHandling: "INCLUDE_CHILDREN", - NodeSpacing: 100.0, - EdgeNodeSpacing: 50.0, - SelfLoopSpacing: 50.0, ConsiderModelOrder: "NODES_AND_EDGES", + ConfigurableOpts: *opts, }, } switch g.Root.Attributes.Direction.Value { @@ -171,8 +172,10 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ELKLayoutOptions) (err if len(obj.ChildrenArray) > 0 { n.LayoutOptions = &ELKLayoutOptions{ - Padding: "[top=75,left=75,bottom=75,right=75]", ForceNodeModelOrder: true, + ConfigurableOpts: ConfigurableOpts{ + Padding: opts.Padding, + }, } } diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index 5bdc018e1..da0ee3a5e 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -13,16 +13,16 @@ import ( var ELKPlugin = elkPlugin{} func init() { - plugins = append(plugins, ELKPlugin) + plugins = append(plugins, &ELKPlugin) } type elkPlugin struct { - opts *d2elklayout.ELKLayoutOptions + opts *d2elklayout.ConfigurableOpts } -func (p elkPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { +func (p *elkPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { if opts != nil { - elkOpts, ok := opts.(d2elklayout.ELKLayoutOptions) + elkOpts, ok := opts.(d2elklayout.ConfigurableOpts) if !ok { return xmain.UsageErrorf("non-dagre layout options given for dagre") } @@ -32,7 +32,7 @@ func (p elkPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { return nil } -func (p elkPlugin) Info(context.Context) (*PluginInfo, error) { +func (p *elkPlugin) Info(context.Context) (*PluginInfo, error) { return &PluginInfo{ Name: "elk", ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.", @@ -42,10 +42,10 @@ See https://github.com/kieler/elkjs for more.`, }, nil } -func (p elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { +func (p *elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { return d2elklayout.Layout(ctx, g, p.opts) } -func (p elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { +func (p *elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { return in, nil } diff --git a/main.go b/main.go index 83ccef354..28ef74ea2 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( "oss.terrastruct.com/util-go/xmain" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" + "oss.terrastruct.com/d2/d2layouts/d2elklayout" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2plugin" "oss.terrastruct.com/d2/d2renderers/d2fonts" @@ -306,18 +307,54 @@ func DiscardSlog(ctx context.Context) context.Context { } func populateLayoutOpts(ms *xmain.State) error { - _, err := ms.Opts.Int64("", "dagre-nodesep", "", int64(d2dagrelayout.DefaultOpts.NodeSep), "number of pixels that separate nodes horizontally in the layout.") + _, err := ms.Opts.Int64("", "dagre-nodesep", "", int64(d2dagrelayout.DefaultOpts.NodeSep), "number of pixels that separate nodes horizontally.") if err != nil { return err } + _, err = ms.Opts.Int64("", "dagre-edgesep", "", int64(d2dagrelayout.DefaultOpts.EdgeSep), "number of pixels that separate edges horizontally.") + if err != nil { + return err + } + + ms.Opts.String("", "elk-algorithm", "", d2elklayout.DefaultOpts.Algorithm, "number of pixels that separate nodes horizontally.") + _, err = ms.Opts.Int64("", "elk-nodeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.NodeSpacing), "number of pixels that separate edges horizontally.") + if err != nil { + return err + } + ms.Opts.String("", "elk-padding", "", d2elklayout.DefaultOpts.Padding, "number of pixels that separate nodes horizontally.") + _, err = ms.Opts.Int64("", "elk-edgeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.EdgeNodeSpacing), "number of pixels that separate edges horizontally.") + if err != nil { + return err + } + _, err = ms.Opts.Int64("", "elk-nodeSelfLoop", "", int64(d2elklayout.DefaultOpts.SelfLoopSpacing), "number of pixels that separate edges horizontally.") + if err != nil { + return err + } + return nil } func parseLayoutOpts(ms *xmain.State, layout string) (interface{}, error) { - if layout == "dagre" { + switch layout { + case "dagre": nodesep, _ := ms.Opts.Flags.GetInt64("dagre-nodesep") + edgesep, _ := ms.Opts.Flags.GetInt64("dagre-edgesep") return d2dagrelayout.Opts{ NodeSep: int(nodesep), + EdgeSep: int(edgesep), + }, nil + case "elk": + algorithm, _ := ms.Opts.Flags.GetString("elk-algorithm") + nodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeNodeBetweenLayers") + padding, _ := ms.Opts.Flags.GetString("elk-padding") + edgeNodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-edgeNodeSpacing") + selfLoopSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeSelfLoop") + return d2elklayout.ConfigurableOpts{ + Algorithm: algorithm, + NodeSpacing: int(nodeSpacing), + Padding: padding, + EdgeNodeSpacing: int(edgeNodeSpacing), + SelfLoopSpacing: int(selfLoopSpacing), }, nil } From 35ccc05d3965f1637f245384dbbc4c65a7fcc9cb Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 00:09:28 -0800 Subject: [PATCH 04/67] refactor --- d2plugin/exec.go | 12 +++-- d2plugin/plugin.go | 21 +++++++- d2plugin/plugin_dagre.go | 27 ++++++++-- d2plugin/plugin_elk.go | 41 ++++++++++++--- main.go | 107 ++++++++++++++++++++------------------- 5 files changed, 143 insertions(+), 65 deletions(-) diff --git a/d2plugin/exec.go b/d2plugin/exec.go index b15ac7a5f..0a348c0c9 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -41,10 +41,16 @@ type execPlugin struct { opts map[string]string } -func (p execPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { +func (p execPlugin) Flags() []PluginSpecificFlag { + // TODO + return nil +} + +func (p *execPlugin) HydrateOpts(opts []byte) error { if opts != nil { - execOpts, ok := opts.(map[string]string) - if !ok { + var execOpts map[string]string + err := json.Unmarshal(opts, &execOpts) + if err != nil { return xmain.UsageErrorf("non-exec layout options given for exec") } diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index 2e538f4c4..b4524cdad 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -19,11 +19,22 @@ import ( // See plugin_* files for the plugins available for bundling. var plugins []Plugin +type PluginSpecificFlag struct { + Name string + Type string + Default interface{} + Usage string + // Must match the tag in the opt + Tag string +} + type Plugin interface { // Info returns the current info information of the plugin. Info(context.Context) (*PluginInfo, error) - HydrateOpts(context.Context, interface{}) error + Flags() []PluginSpecificFlag + + HydrateOpts([]byte) error // Layout runs the plugin's autolayout algorithm on the input graph // and returns a new graph with the computed placements. @@ -111,3 +122,11 @@ func FindPlugin(ctx context.Context, name string) (Plugin, string, error) { return &execPlugin{path: path}, path, nil } + +func ListPluginFlags() []PluginSpecificFlag { + var out []PluginSpecificFlag + for _, p := range plugins { + out = append(out, p.Flags()...) + } + return out +} diff --git a/d2plugin/plugin_dagre.go b/d2plugin/plugin_dagre.go index b4d75688b..e78629481 100644 --- a/d2plugin/plugin_dagre.go +++ b/d2plugin/plugin_dagre.go @@ -4,6 +4,7 @@ package d2plugin import ( "context" + "encoding/json" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" @@ -20,10 +21,30 @@ type dagrePlugin struct { opts *d2dagrelayout.Opts } -func (p *dagrePlugin) HydrateOpts(ctx context.Context, opts interface{}) error { +func (p dagrePlugin) Flags() []PluginSpecificFlag { + return []PluginSpecificFlag{ + { + Name: "dagre-nodesep", + Type: "int64", + Default: int64(d2dagrelayout.DefaultOpts.NodeSep), + Usage: "number of pixels that separate nodes horizontally.", + Tag: "nodesep", + }, + { + Name: "dagre-edgesep", + Type: "int64", + Default: int64(d2dagrelayout.DefaultOpts.EdgeSep), + Usage: "number of pixels that separate edges horizontally.", + Tag: "edgesep", + }, + } +} + +func (p *dagrePlugin) HydrateOpts(opts []byte) error { if opts != nil { - dagreOpts, ok := opts.(d2dagrelayout.Opts) - if !ok { + var dagreOpts d2dagrelayout.Opts + err := json.Unmarshal(opts, &dagreOpts) + if err != nil { return xmain.UsageErrorf("non-dagre layout options given for dagre") } diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index da0ee3a5e..b07db9c37 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -4,6 +4,7 @@ package d2plugin import ( "context" + "encoding/json" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2elklayout" @@ -20,10 +21,38 @@ type elkPlugin struct { opts *d2elklayout.ConfigurableOpts } -func (p *elkPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { +func (p elkPlugin) Flags() []PluginSpecificFlag { + // ms.Opts.String("", "elk-algorithm", "", d2elklayout.DefaultOpts.Algorithm, "number of pixels that separate nodes horizontally.") + // _, err = ms.Opts.Int64("", "elk-nodeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.NodeSpacing), "number of pixels that separate edges horizontally.") + // if err != nil { + // return err + // } + // ms.Opts.String("", "elk-padding", "", d2elklayout.DefaultOpts.Padding, "number of pixels that separate nodes horizontally.") + // _, err = ms.Opts.Int64("", "elk-edgeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.EdgeNodeSpacing), "number of pixels that separate edges horizontally.") + // if err != nil { + // return err + // } + // _, err = ms.Opts.Int64("", "elk-nodeSelfLoop", "", int64(d2elklayout.DefaultOpts.SelfLoopSpacing), "number of pixels that separate edges horizontally.") + // if err != nil { + // return err + // } + return []PluginSpecificFlag{ + { + Name: "elk-algorithm", + Type: "string", + Default: d2elklayout.DefaultOpts.Algorithm, + Usage: "number of pixels that separate nodes horizontally.", + Tag: "elk.algorithm", + }, + } +} + +func (p *elkPlugin) HydrateOpts(opts []byte) error { if opts != nil { - elkOpts, ok := opts.(d2elklayout.ConfigurableOpts) - if !ok { + var elkOpts d2elklayout.ConfigurableOpts + err := json.Unmarshal(opts, &elkOpts) + if err != nil { + // TODO not right return xmain.UsageErrorf("non-dagre layout options given for dagre") } @@ -32,7 +61,7 @@ func (p *elkPlugin) HydrateOpts(ctx context.Context, opts interface{}) error { return nil } -func (p *elkPlugin) Info(context.Context) (*PluginInfo, error) { +func (p elkPlugin) Info(context.Context) (*PluginInfo, error) { return &PluginInfo{ Name: "elk", ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.", @@ -42,10 +71,10 @@ See https://github.com/kieler/elkjs for more.`, }, nil } -func (p *elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { +func (p elkPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { return d2elklayout.Layout(ctx, g, p.opts) } -func (p *elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { +func (p elkPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { return in, nil } diff --git a/main.go b/main.go index 28ef74ea2..d536bdaed 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/json" "errors" "fmt" "io" @@ -17,8 +18,6 @@ import ( "oss.terrastruct.com/util-go/go2" "oss.terrastruct.com/util-go/xmain" - "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" - "oss.terrastruct.com/d2/d2layouts/d2elklayout" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2plugin" "oss.terrastruct.com/d2/d2renderers/d2fonts" @@ -151,12 +150,7 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } - layoutOpts, err := parseLayoutOpts(ms, *layoutFlag) - if err != nil { - return err - } - - err = plugin.HydrateOpts(ctx, layoutOpts) + err = parseLayoutOpts(ms, plugin) if err != nil { return err } @@ -307,56 +301,65 @@ func DiscardSlog(ctx context.Context) context.Context { } func populateLayoutOpts(ms *xmain.State) error { - _, err := ms.Opts.Int64("", "dagre-nodesep", "", int64(d2dagrelayout.DefaultOpts.NodeSep), "number of pixels that separate nodes horizontally.") - if err != nil { - return err - } - _, err = ms.Opts.Int64("", "dagre-edgesep", "", int64(d2dagrelayout.DefaultOpts.EdgeSep), "number of pixels that separate edges horizontally.") - if err != nil { - return err - } + pluginFlags := d2plugin.ListPluginFlags() - ms.Opts.String("", "elk-algorithm", "", d2elklayout.DefaultOpts.Algorithm, "number of pixels that separate nodes horizontally.") - _, err = ms.Opts.Int64("", "elk-nodeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.NodeSpacing), "number of pixels that separate edges horizontally.") - if err != nil { - return err - } - ms.Opts.String("", "elk-padding", "", d2elklayout.DefaultOpts.Padding, "number of pixels that separate nodes horizontally.") - _, err = ms.Opts.Int64("", "elk-edgeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.EdgeNodeSpacing), "number of pixels that separate edges horizontally.") - if err != nil { - return err - } - _, err = ms.Opts.Int64("", "elk-nodeSelfLoop", "", int64(d2elklayout.DefaultOpts.SelfLoopSpacing), "number of pixels that separate edges horizontally.") - if err != nil { - return err + for _, f := range pluginFlags { + switch f.Type { + case "string": + ms.Opts.String("", f.Name, "", f.Default.(string), f.Usage) + case "int64": + ms.Opts.Int64("", f.Name, "", f.Default.(int64), f.Usage) + } } return nil } -func parseLayoutOpts(ms *xmain.State, layout string) (interface{}, error) { - switch layout { - case "dagre": - nodesep, _ := ms.Opts.Flags.GetInt64("dagre-nodesep") - edgesep, _ := ms.Opts.Flags.GetInt64("dagre-edgesep") - return d2dagrelayout.Opts{ - NodeSep: int(nodesep), - EdgeSep: int(edgesep), - }, nil - case "elk": - algorithm, _ := ms.Opts.Flags.GetString("elk-algorithm") - nodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeNodeBetweenLayers") - padding, _ := ms.Opts.Flags.GetString("elk-padding") - edgeNodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-edgeNodeSpacing") - selfLoopSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeSelfLoop") - return d2elklayout.ConfigurableOpts{ - Algorithm: algorithm, - NodeSpacing: int(nodeSpacing), - Padding: padding, - EdgeNodeSpacing: int(edgeNodeSpacing), - SelfLoopSpacing: int(selfLoopSpacing), - }, nil +func parseLayoutOpts(ms *xmain.State, plugin d2plugin.Plugin) error { + opts := make(map[string]interface{}) + for _, f := range plugin.Flags() { + switch f.Type { + case "string": + val, _ := ms.Opts.Flags.GetString(f.Name) + opts[f.Tag] = val + case "int64": + val, _ := ms.Opts.Flags.GetInt64(f.Name) + opts[f.Tag] = val + } } - return nil, fmt.Errorf("unexpected error, layout not found for parsing opts") + b, err := json.Marshal(opts) + if err != nil { + return err + } + + err = plugin.HydrateOpts(b) + return err + + // switch layout { + // case "dagre": + // nodesep, _ := ms.Opts.Flags.GetInt64("dagre-nodesep") + // edgesep, _ := ms.Opts.Flags.GetInt64("dagre-edgesep") + // return d2dagrelayout.Opts{ + // NodeSep: int(nodesep), + // EdgeSep: int(edgesep), + // }, nil + // case "elk": + // algorithm, _ := ms.Opts.Flags.GetString("elk-algorithm") + // nodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeNodeBetweenLayers") + // padding, _ := ms.Opts.Flags.GetString("elk-padding") + // edgeNodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-edgeNodeSpacing") + // selfLoopSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeSelfLoop") + // return d2elklayout.ConfigurableOpts{ + // Algorithm: algorithm, + // NodeSpacing: int(nodeSpacing), + // Padding: padding, + // EdgeNodeSpacing: int(edgeNodeSpacing), + // SelfLoopSpacing: int(selfLoopSpacing), + // }, nil + // default: + // + // } + // + // return nil, fmt.Errorf("unexpected error, layout not found for parsing opts") } From 9aca3e2c0bd1319d96b270333d18d75c9d3e3a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20C=C3=A9sar=20Batista?= Date: Fri, 30 Dec 2022 14:33:40 -0300 Subject: [PATCH 05/67] add line about test cases --- docs/CONTRIBUTING.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f5b08f6b1..6c607e01f 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -54,7 +54,7 @@ start work on an Issue, please leave a comment so others know that it's being wo ### Tests -All code changes must include tests. D2 mostly has functional tests, and uses +All code changes must include tests. D2 mostly has functional tests (see `e2etests` directory), and uses [diff](https://github.com/terrastruct/diff) as a framework that gives Git-style comparisons of expected vs actual output for each stage. There are ample examples in each package of this -- try changing some test and run it to see. @@ -82,6 +82,11 @@ Run: `./ci/test.sh` CI runs tests with `-race` to catch potential race conditions. It's much slower, but if your machine can run it locally, you can do so with `./make.sh race`. +If you had to change/add functional test cases (under `e2etests` directory), make sure +you updated them before opening a PR. + +Run: `TESTDATA_ACCEPT=1 ./ci/test.sh` or `TA=1 ./ci/test.sh` for a shorter version. + #### Chaos tests D2 has [chaos tests](https://en.wikipedia.org/wiki/Chaos_engineering) which produce random From 01742b7400592bd8d21b715edccf097c1d8816d1 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 10:04:43 -0800 Subject: [PATCH 06/67] update --- ci/sub | 2 +- docs/CONTRIBUTING.md | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ci/sub b/ci/sub index 79b9dadce..b1ec0a8d4 160000 --- a/ci/sub +++ b/ci/sub @@ -1 +1 @@ -Subproject commit 79b9dadce090a95b5a50d32f9ea3927845e5cce1 +Subproject commit b1ec0a8d430a62b7556211ed8bcd7b6e41e2362c diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 6c607e01f..784636109 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -22,6 +22,20 @@ Most of D2's CI is open sourced in its own workflows. E.g. run `./make.sh fmt` to run the formatter. Please make sure all CI is passing for any PRs. +Most of the CI scripts rely on a submodule shared between many D2 repositories: +[https://github.com/terrastruct/ci](https://github.com/terrastruct/ci). You should fetch +the submodule whenever it differs: + +```sh +git submodule update --recursive +``` + +If running for the first time for a repo (e.g. new clone), add `--init`: + +```sh +git submodule update --init --recursive +``` + ## Flow The simplified D2 flow at a package level looks like: @@ -54,7 +68,7 @@ start work on an Issue, please leave a comment so others know that it's being wo ### Tests -All code changes must include tests. D2 mostly has functional tests (see `e2etests` directory), and uses +All code changes must include tests. D2 mostly has functional tests, and uses [diff](https://github.com/terrastruct/diff) as a framework that gives Git-style comparisons of expected vs actual output for each stage. There are ample examples in each package of this -- try changing some test and run it to see. @@ -82,11 +96,6 @@ Run: `./ci/test.sh` CI runs tests with `-race` to catch potential race conditions. It's much slower, but if your machine can run it locally, you can do so with `./make.sh race`. -If you had to change/add functional test cases (under `e2etests` directory), make sure -you updated them before opening a PR. - -Run: `TESTDATA_ACCEPT=1 ./ci/test.sh` or `TA=1 ./ci/test.sh` for a shorter version. - #### Chaos tests D2 has [chaos tests](https://en.wikipedia.org/wiki/Chaos_engineering) which produce random From fafcd67e058a650549cae146e0d8de2adc39f3e8 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 10:06:43 -0800 Subject: [PATCH 07/67] update ci --- ci/sub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/sub b/ci/sub index b1ec0a8d4..9a29d9ea6 160000 --- a/ci/sub +++ b/ci/sub @@ -1 +1 @@ -Subproject commit b1ec0a8d430a62b7556211ed8bcd7b6e41e2362c +Subproject commit 9a29d9ea640834905c4010c0b3d14b7301ebb6d8 From fc5f58323c6a4e669869a827aec9af8100792feb Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 11:33:32 -0800 Subject: [PATCH 08/67] add ctx, implement exec --- d2plugin/exec.go | 26 +++++++++++++++++++++++--- d2plugin/plugin.go | 12 ++++++++---- d2plugin/plugin_dagre.go | 4 ++-- d2plugin/plugin_elk.go | 4 ++-- main.go | 19 +++++++++++++------ 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/d2plugin/exec.go b/d2plugin/exec.go index 0a348c0c9..0a186c908 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -41,9 +41,29 @@ type execPlugin struct { opts map[string]string } -func (p execPlugin) Flags() []PluginSpecificFlag { - // TODO - return nil +func (p execPlugin) Flags(ctx context.Context) (_ []PluginSpecificFlag, err error) { + ctx, cancel := context.WithTimeout(ctx, time.Second*10) + defer cancel() + cmd := exec.CommandContext(ctx, p.path, "flags") + defer xdefer.Errorf(&err, "failed to run %v", cmd.Args) + + stdout, err := cmd.Output() + if err != nil { + ee := &exec.ExitError{} + if errors.As(err, &ee) && len(ee.Stderr) > 0 { + return nil, fmt.Errorf("%v\nstderr:\n%s", ee, ee.Stderr) + } + return nil, err + } + + var flags []PluginSpecificFlag + + err = json.Unmarshal(stdout, &flags) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal json: %w", err) + } + + return flags, nil } func (p *execPlugin) HydrateOpts(opts []byte) error { diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index b4524cdad..0b7288a75 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -32,7 +32,7 @@ type Plugin interface { // Info returns the current info information of the plugin. Info(context.Context) (*PluginInfo, error) - Flags() []PluginSpecificFlag + Flags(context.Context) ([]PluginSpecificFlag, error) HydrateOpts([]byte) error @@ -123,10 +123,14 @@ func FindPlugin(ctx context.Context, name string) (Plugin, string, error) { return &execPlugin{path: path}, path, nil } -func ListPluginFlags() []PluginSpecificFlag { +func ListPluginFlags(ctx context.Context) ([]PluginSpecificFlag, error) { var out []PluginSpecificFlag for _, p := range plugins { - out = append(out, p.Flags()...) + flags, err := p.Flags(ctx) + if err != nil { + return nil, err + } + out = append(out, flags...) } - return out + return out, nil } diff --git a/d2plugin/plugin_dagre.go b/d2plugin/plugin_dagre.go index e78629481..2e23e0db6 100644 --- a/d2plugin/plugin_dagre.go +++ b/d2plugin/plugin_dagre.go @@ -21,7 +21,7 @@ type dagrePlugin struct { opts *d2dagrelayout.Opts } -func (p dagrePlugin) Flags() []PluginSpecificFlag { +func (p dagrePlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { return []PluginSpecificFlag{ { Name: "dagre-nodesep", @@ -37,7 +37,7 @@ func (p dagrePlugin) Flags() []PluginSpecificFlag { Usage: "number of pixels that separate edges horizontally.", Tag: "edgesep", }, - } + }, nil } func (p *dagrePlugin) HydrateOpts(opts []byte) error { diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index b07db9c37..c3ab55544 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -21,7 +21,7 @@ type elkPlugin struct { opts *d2elklayout.ConfigurableOpts } -func (p elkPlugin) Flags() []PluginSpecificFlag { +func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { // ms.Opts.String("", "elk-algorithm", "", d2elklayout.DefaultOpts.Algorithm, "number of pixels that separate nodes horizontally.") // _, err = ms.Opts.Int64("", "elk-nodeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.NodeSpacing), "number of pixels that separate edges horizontally.") // if err != nil { @@ -44,7 +44,7 @@ func (p elkPlugin) Flags() []PluginSpecificFlag { Usage: "number of pixels that separate nodes horizontally.", Tag: "elk.algorithm", }, - } + }, nil } func (p *elkPlugin) HydrateOpts(opts []byte) error { diff --git a/main.go b/main.go index d536bdaed..727761ed5 100644 --- a/main.go +++ b/main.go @@ -76,7 +76,7 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } - err = populateLayoutOpts(ms) + err = populateLayoutOpts(ctx, ms) if err != nil { return err } @@ -150,7 +150,7 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } - err = parseLayoutOpts(ms, plugin) + err = parseLayoutOpts(ctx, ms, plugin) if err != nil { return err } @@ -300,8 +300,11 @@ func DiscardSlog(ctx context.Context) context.Context { return ctxlog.With(ctx, slog.Make(sloghuman.Sink(io.Discard))) } -func populateLayoutOpts(ms *xmain.State) error { - pluginFlags := d2plugin.ListPluginFlags() +func populateLayoutOpts(ctx context.Context, ms *xmain.State) error { + pluginFlags, err := d2plugin.ListPluginFlags(ctx) + if err != nil { + return err + } for _, f := range pluginFlags { switch f.Type { @@ -315,9 +318,13 @@ func populateLayoutOpts(ms *xmain.State) error { return nil } -func parseLayoutOpts(ms *xmain.State, plugin d2plugin.Plugin) error { +func parseLayoutOpts(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin) error { opts := make(map[string]interface{}) - for _, f := range plugin.Flags() { + flags, err := plugin.Flags(ctx) + if err != nil { + return err + } + for _, f := range flags { switch f.Type { case "string": val, _ := ms.Opts.Flags.GetString(f.Name) From e6f9779e49783cb6597099ad28e33f33187aaa60 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 11:33:56 -0800 Subject: [PATCH 09/67] clean --- main.go | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/main.go b/main.go index 727761ed5..bbfdff7b1 100644 --- a/main.go +++ b/main.go @@ -342,31 +342,4 @@ func parseLayoutOpts(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugi err = plugin.HydrateOpts(b) return err - - // switch layout { - // case "dagre": - // nodesep, _ := ms.Opts.Flags.GetInt64("dagre-nodesep") - // edgesep, _ := ms.Opts.Flags.GetInt64("dagre-edgesep") - // return d2dagrelayout.Opts{ - // NodeSep: int(nodesep), - // EdgeSep: int(edgesep), - // }, nil - // case "elk": - // algorithm, _ := ms.Opts.Flags.GetString("elk-algorithm") - // nodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeNodeBetweenLayers") - // padding, _ := ms.Opts.Flags.GetString("elk-padding") - // edgeNodeSpacing, _ := ms.Opts.Flags.GetInt64("elk-edgeNodeSpacing") - // selfLoopSpacing, _ := ms.Opts.Flags.GetInt64("elk-nodeSelfLoop") - // return d2elklayout.ConfigurableOpts{ - // Algorithm: algorithm, - // NodeSpacing: int(nodeSpacing), - // Padding: padding, - // EdgeNodeSpacing: int(edgeNodeSpacing), - // SelfLoopSpacing: int(selfLoopSpacing), - // }, nil - // default: - // - // } - // - // return nil, fmt.Errorf("unexpected error, layout not found for parsing opts") } From 85d102204f2e2635bf25ba51b01f4b2eda451e03 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 12:06:40 -0800 Subject: [PATCH 10/67] add args to exec --- d2plugin/exec.go | 6 +++++- d2plugin/serve.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/d2plugin/exec.go b/d2plugin/exec.go index 0a186c908..cce95b5db 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -113,7 +113,11 @@ func (p execPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { return err } - cmd := exec.CommandContext(ctx, p.path, "layout") + args := []string{"layout"} + for k, v := range p.opts { + args = append(args, k, v) + } + cmd := exec.CommandContext(ctx, p.path, args...) buffer := bytes.Buffer{} buffer.Write(graphBytes) diff --git a/d2plugin/serve.go b/d2plugin/serve.go index b13680746..cf857b3ee 100644 --- a/d2plugin/serve.go +++ b/d2plugin/serve.go @@ -38,6 +38,8 @@ func Serve(p Plugin) xmain.RunFunc { switch subcmd { case "info": return info(ctx, p, ms) + case "flags": + return flags(ctx, p, ms) case "layout": return layout(ctx, p, ms) case "postprocess": @@ -64,6 +66,22 @@ func info(ctx context.Context, p Plugin, ms *xmain.State) error { return nil } +func flags(ctx context.Context, p Plugin, ms *xmain.State) error { + flags, err := p.Flags(ctx) + if err != nil { + return err + } + b, err := json.Marshal(flags) + if err != nil { + return err + } + _, err = ms.Stdout.Write(b) + if err != nil { + return err + } + return nil +} + func layout(ctx context.Context, p Plugin, ms *xmain.State) error { in, err := io.ReadAll(ms.Stdin) if err != nil { From cab3aedfe22932704f379d36ac121511bdd1a147 Mon Sep 17 00:00:00 2001 From: nekikara Date: Fri, 30 Dec 2022 21:12:04 +0100 Subject: [PATCH 11/67] fix typo --- d2renderers/d2sketch/rough.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2renderers/d2sketch/rough.js b/d2renderers/d2sketch/rough.js index 04eabe71a..b19e8c7d7 100644 --- a/d2renderers/d2sketch/rough.js +++ b/d2renderers/d2sketch/rough.js @@ -1261,7 +1261,7 @@ class B { n = []; if (!t) return this._drawable("path", n, s); const i = (function (t, e) { - t = (t || "").replace(/\n/g, " ").replace(/(-\s)/g, "-").replace("/(ss)/g", " "); + t = (t || "").replace(/\n/g, " ").replace(/(-\s)/g, "-").replace("/(\s\s)/g", " "); let s = new o(t); if (e.simplification) { const t = new r(s.linearPoints, s.closed).fit(e.simplification); From b5a9880cd1c2fc1fef943164f2860ec464d25258 Mon Sep 17 00:00:00 2001 From: nekikara Date: Fri, 30 Dec 2022 21:12:52 +0100 Subject: [PATCH 12/67] Add rough.js to .prettierignore --- .prettierignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.prettierignore b/.prettierignore index d7226ae8f..6b44e5f0b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,4 +3,5 @@ d2layouts/d2elklayout/setup.js d2renderers/d2latex/mathjax.js d2renderers/d2latex/polyfills.js d2renderers/d2latex/setup.js +d2renderers/d2sketch/rough.js lib/png/generate_png.js From 4b99bc30a70633e1c1706c62d0f1587edad5eb52 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 12:25:33 -0800 Subject: [PATCH 13/67] elk/dagre name consistency --- d2layouts/d2dagrelayout/layout.go | 26 +++++++------- d2layouts/d2elklayout/layout.go | 60 +++++++++++++++---------------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index ee86e9599..6d2a5f91b 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -30,12 +30,12 @@ var setupJS string //go:embed dagre.js var dagreJS string -type Opts struct { +type ConfigurableOpts struct { NodeSep int EdgeSep int } -var DefaultOpts = Opts{ +var DefaultOpts = ConfigurableOpts{ NodeSep: 60, EdgeSep: 40, } @@ -52,16 +52,16 @@ type DagreEdge struct { Points []*geo.Point `json:"points"` } -type dagreGraphAttrs struct { +type dagreOpts struct { // for a top to bottom graph: ranksep is y spacing, nodesep is x spacing, edgesep is x spacing ranksep int - edgesep int - nodesep int // graph direction: tb (top to bottom)| bt | lr | rl rankdir string + + ConfigurableOpts } -func Layout(ctx context.Context, g *d2graph.Graph, opts *Opts) (err error) { +func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err error) { if opts == nil { opts = &DefaultOpts } @@ -76,9 +76,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *Opts) (err error) { return err } - rootAttrs := dagreGraphAttrs{ - edgesep: opts.EdgeSep, - nodesep: opts.NodeSep, + rootAttrs := dagreOpts{ + ConfigurableOpts: ConfigurableOpts{ + EdgeSep: opts.EdgeSep, + NodeSep: opts.NodeSep, + }, } isHorizontal := false switch g.Root.Attributes.Direction.Value { @@ -279,7 +281,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *Opts) (err error) { return nil } -func setGraphAttrs(attrs dagreGraphAttrs) string { +func setGraphAttrs(attrs dagreOpts) string { return fmt.Sprintf(`g.setGraph({ ranksep: %d, edgesep: %d, @@ -288,8 +290,8 @@ func setGraphAttrs(attrs dagreGraphAttrs) string { }); `, attrs.ranksep, - attrs.edgesep, - attrs.nodesep, + attrs.ConfigurableOpts.EdgeSep, + attrs.ConfigurableOpts.NodeSep, attrs.rankdir, ) } diff --git a/d2layouts/d2elklayout/layout.go b/d2layouts/d2elklayout/layout.go index f46e19004..384d877e5 100644 --- a/d2layouts/d2elklayout/layout.go +++ b/d2layouts/d2elklayout/layout.go @@ -31,23 +31,23 @@ var elkJS string var setupJS string type ELKNode struct { - ID string `json:"id"` - X float64 `json:"x"` - Y float64 `json:"y"` - Width float64 `json:"width"` - Height float64 `json:"height"` - Children []*ELKNode `json:"children,omitempty"` - Labels []*ELKLabel `json:"labels,omitempty"` - LayoutOptions *ELKLayoutOptions `json:"layoutOptions,omitempty"` + ID string `json:"id"` + X float64 `json:"x"` + Y float64 `json:"y"` + Width float64 `json:"width"` + Height float64 `json:"height"` + Children []*ELKNode `json:"children,omitempty"` + Labels []*ELKLabel `json:"labels,omitempty"` + LayoutOptions *elkOpts `json:"layoutOptions,omitempty"` } type ELKLabel struct { - Text string `json:"text"` - X float64 `json:"x"` - Y float64 `json:"y"` - Width float64 `json:"width"` - Height float64 `json:"height"` - LayoutOptions *ELKLayoutOptions `json:"layoutOptions,omitempty"` + Text string `json:"text"` + X float64 `json:"x"` + Y float64 `json:"y"` + Width float64 `json:"width"` + Height float64 `json:"height"` + LayoutOptions *elkOpts `json:"layoutOptions,omitempty"` } type ELKPoint struct { @@ -71,18 +71,10 @@ type ELKEdge struct { } type ELKGraph struct { - ID string `json:"id"` - LayoutOptions *ELKLayoutOptions `json:"layoutOptions"` - Children []*ELKNode `json:"children,omitempty"` - Edges []*ELKEdge `json:"edges,omitempty"` -} - -var DefaultOpts = ConfigurableOpts{ - Algorithm: "layered", - NodeSpacing: 100.0, - Padding: "[top=75,left=75,bottom=75,right=75]", - EdgeNodeSpacing: 50.0, - SelfLoopSpacing: 50.0, + ID string `json:"id"` + LayoutOptions *elkOpts `json:"layoutOptions"` + Children []*ELKNode `json:"children,omitempty"` + Edges []*ELKEdge `json:"edges,omitempty"` } type ConfigurableOpts struct { @@ -93,7 +85,15 @@ type ConfigurableOpts struct { SelfLoopSpacing int `json:"elk.spacing.nodeSelfLoop"` } -type ELKLayoutOptions struct { +var DefaultOpts = ConfigurableOpts{ + Algorithm: "layered", + NodeSpacing: 100.0, + Padding: "[top=75,left=75,bottom=75,right=75]", + EdgeNodeSpacing: 50.0, + SelfLoopSpacing: 50.0, +} + +type elkOpts struct { Direction string `json:"elk.direction"` HierarchyHandling string `json:"elk.hierarchyHandling,omitempty"` InlineEdgeLabels bool `json:"elk.edgeLabels.inline,omitempty"` @@ -125,7 +125,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err elkGraph := &ELKGraph{ ID: "root", - LayoutOptions: &ELKLayoutOptions{ + LayoutOptions: &elkOpts{ HierarchyHandling: "INCLUDE_CHILDREN", ConsiderModelOrder: "NODES_AND_EDGES", ConfigurableOpts: *opts, @@ -171,7 +171,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } if len(obj.ChildrenArray) > 0 { - n.LayoutOptions = &ELKLayoutOptions{ + n.LayoutOptions = &elkOpts{ ForceNodeModelOrder: true, ConfigurableOpts: ConfigurableOpts{ Padding: opts.Padding, @@ -206,7 +206,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err Text: edge.Attributes.Label.Value, Width: float64(edge.LabelDimensions.Width), Height: float64(edge.LabelDimensions.Height), - LayoutOptions: &ELKLayoutOptions{ + LayoutOptions: &elkOpts{ InlineEdgeLabels: true, }, }) From 761d399d3abc83a4406b191194836fdc4254a66d Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 12:34:25 -0800 Subject: [PATCH 14/67] elk options --- d2plugin/plugin_elk.go | 44 ++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index c3ab55544..3667c7154 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -22,28 +22,42 @@ type elkPlugin struct { } func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { - // ms.Opts.String("", "elk-algorithm", "", d2elklayout.DefaultOpts.Algorithm, "number of pixels that separate nodes horizontally.") - // _, err = ms.Opts.Int64("", "elk-nodeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.NodeSpacing), "number of pixels that separate edges horizontally.") - // if err != nil { - // return err - // } - // ms.Opts.String("", "elk-padding", "", d2elklayout.DefaultOpts.Padding, "number of pixels that separate nodes horizontally.") - // _, err = ms.Opts.Int64("", "elk-edgeNodeBetweenLayers", "", int64(d2elklayout.DefaultOpts.EdgeNodeSpacing), "number of pixels that separate edges horizontally.") - // if err != nil { - // return err - // } - // _, err = ms.Opts.Int64("", "elk-nodeSelfLoop", "", int64(d2elklayout.DefaultOpts.SelfLoopSpacing), "number of pixels that separate edges horizontally.") - // if err != nil { - // return err - // } return []PluginSpecificFlag{ { Name: "elk-algorithm", Type: "string", Default: d2elklayout.DefaultOpts.Algorithm, - Usage: "number of pixels that separate nodes horizontally.", + Usage: "layout algorithm. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-algorithm.html", Tag: "elk.algorithm", }, + { + Name: "elk-nodeNodeBetweenLayers", + Type: "int64", + Default: d2elklayout.DefaultOpts.NodeSpacing, + Usage: "the spacing to be preserved between any pair of nodes of two adjacent layers. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-nodeNodeBetweenLayers.html", + Tag: "spacing.nodeNodeBetweenLayers", + }, + { + Name: "elk-padding", + Type: "string", + Default: d2elklayout.DefaultOpts.Padding, + Usage: "the padding to be left to a parent element’s border when placing child elements. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-padding.html", + Tag: "elk.padding", + }, + { + Name: "elk-edgeNodeBetweenLayers", + Type: "int64", + Default: d2elklayout.DefaultOpts.EdgeNodeSpacing, + Usage: "the spacing to be preserved between nodes and edges that are routed next to the node’s layer. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-edgeNodeBetweenLayers.html", + Tag: "spacing.edgeNodeBetweenLayers", + }, + { + Name: "elk-nodeSelfLoop", + Type: "int64", + Default: d2elklayout.DefaultOpts.SelfLoopSpacing, + Usage: "spacing to be preserved between a node and its self loops. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-spacing-nodeSelfLoop.html", + Tag: "elk.spacing.nodeSelfLoop", + }, }, nil } From 3f540809ac9412a658fef4390265872302d7ee41 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 12:40:52 -0800 Subject: [PATCH 15/67] save --- d2plugin/plugin_dagre.go | 4 ++-- d2plugin/plugin_elk.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/d2plugin/plugin_dagre.go b/d2plugin/plugin_dagre.go index 2e23e0db6..cfdca3b77 100644 --- a/d2plugin/plugin_dagre.go +++ b/d2plugin/plugin_dagre.go @@ -18,7 +18,7 @@ func init() { } type dagrePlugin struct { - opts *d2dagrelayout.Opts + opts *d2dagrelayout.ConfigurableOpts } func (p dagrePlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { @@ -42,7 +42,7 @@ func (p dagrePlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { func (p *dagrePlugin) HydrateOpts(opts []byte) error { if opts != nil { - var dagreOpts d2dagrelayout.Opts + var dagreOpts d2dagrelayout.ConfigurableOpts err := json.Unmarshal(opts, &dagreOpts) if err != nil { return xmain.UsageErrorf("non-dagre layout options given for dagre") diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index 3667c7154..2d4619bf8 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -33,7 +33,7 @@ func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { { Name: "elk-nodeNodeBetweenLayers", Type: "int64", - Default: d2elklayout.DefaultOpts.NodeSpacing, + Default: int64(d2elklayout.DefaultOpts.NodeSpacing), Usage: "the spacing to be preserved between any pair of nodes of two adjacent layers. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-nodeNodeBetweenLayers.html", Tag: "spacing.nodeNodeBetweenLayers", }, @@ -47,14 +47,14 @@ func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { { Name: "elk-edgeNodeBetweenLayers", Type: "int64", - Default: d2elklayout.DefaultOpts.EdgeNodeSpacing, + Default: int64(d2elklayout.DefaultOpts.EdgeNodeSpacing), Usage: "the spacing to be preserved between nodes and edges that are routed next to the node’s layer. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-edgeNodeBetweenLayers.html", Tag: "spacing.edgeNodeBetweenLayers", }, { Name: "elk-nodeSelfLoop", Type: "int64", - Default: d2elklayout.DefaultOpts.SelfLoopSpacing, + Default: int64(d2elklayout.DefaultOpts.SelfLoopSpacing), Usage: "spacing to be preserved between a node and its self loops. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-spacing-nodeSelfLoop.html", Tag: "elk.spacing.nodeSelfLoop", }, From 85e87c8c2c42311eb963baaf28b1f9fa61a86571 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 13:19:48 -0800 Subject: [PATCH 16/67] add help --- d2plugin/plugin.go | 10 ++++++++++ d2plugin/plugin_dagre.go | 24 +++++++++++++++++------- d2plugin/plugin_elk.go | 31 +++++++++++++++++++++++-------- main.go | 9 +++------ 4 files changed, 53 insertions(+), 21 deletions(-) diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index 0b7288a75..765d9f60e 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -10,6 +10,7 @@ import ( "os/exec" "oss.terrastruct.com/util-go/xexec" + "oss.terrastruct.com/util-go/xmain" "oss.terrastruct.com/d2/d2graph" ) @@ -28,6 +29,15 @@ type PluginSpecificFlag struct { Tag string } +func (f *PluginSpecificFlag) AddToOpts(opts *xmain.Opts) { + switch f.Type { + case "string": + opts.String("", f.Name, "", f.Default.(string), f.Usage) + case "int64": + opts.Int64("", f.Name, "", f.Default.(int64), f.Usage) + } +} + type Plugin interface { // Info returns the current info information of the plugin. Info(context.Context) (*PluginInfo, error) diff --git a/d2plugin/plugin_dagre.go b/d2plugin/plugin_dagre.go index cfdca3b77..c3f16a8f1 100644 --- a/d2plugin/plugin_dagre.go +++ b/d2plugin/plugin_dagre.go @@ -5,6 +5,7 @@ package d2plugin import ( "context" "encoding/json" + "fmt" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" @@ -53,18 +54,27 @@ func (p *dagrePlugin) HydrateOpts(opts []byte) error { return nil } -func (p dagrePlugin) Info(context.Context) (*PluginInfo, error) { +func (p dagrePlugin) Info(ctx context.Context) (*PluginInfo, error) { + opts := xmain.NewOpts(nil, nil, nil) + flags, err := p.Flags(ctx) + if err != nil { + return nil, err + } + for _, f := range flags { + f.AddToOpts(opts) + } + return &PluginInfo{ Name: "dagre", ShortHelp: "The directed graph layout library Dagre", - LongHelp: `dagre is a directed graph layout library for JavaScript. + LongHelp: fmt.Sprintf(`dagre is a directed graph layout library for JavaScript. See https://github.com/dagrejs/dagre -The implementation of this plugin is at: https://github.com/terrastruct/d2/tree/master/d2plugin/d2dagrelayout -note: dagre is the primary layout algorithm for text to diagram generator Mermaid.js. - See https://github.com/mermaid-js/mermaid - We have a useful comparison at https://text-to-diagram.com/?example=basic&a=d2&b=mermaid -`, +Flags correspond to ones found at https://github.com/dagrejs/dagre/wiki. See dagre's reference for more on each. + +Flags: +%s +`, opts.Defaults()), }, nil } diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index 2d4619bf8..c5033d4e3 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -5,6 +5,7 @@ package d2plugin import ( "context" "encoding/json" + "fmt" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2elklayout" @@ -27,35 +28,35 @@ func (p elkPlugin) Flags(context.Context) ([]PluginSpecificFlag, error) { Name: "elk-algorithm", Type: "string", Default: d2elklayout.DefaultOpts.Algorithm, - Usage: "layout algorithm. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-algorithm.html", + Usage: "layout algorithm", Tag: "elk.algorithm", }, { Name: "elk-nodeNodeBetweenLayers", Type: "int64", Default: int64(d2elklayout.DefaultOpts.NodeSpacing), - Usage: "the spacing to be preserved between any pair of nodes of two adjacent layers. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-nodeNodeBetweenLayers.html", + Usage: "the spacing to be preserved between any pair of nodes of two adjacent layers", Tag: "spacing.nodeNodeBetweenLayers", }, { Name: "elk-padding", Type: "string", Default: d2elklayout.DefaultOpts.Padding, - Usage: "the padding to be left to a parent element’s border when placing child elements. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-padding.html", + Usage: "the padding to be left to a parent element’s border when placing child elements", Tag: "elk.padding", }, { Name: "elk-edgeNodeBetweenLayers", Type: "int64", Default: int64(d2elklayout.DefaultOpts.EdgeNodeSpacing), - Usage: "the spacing to be preserved between nodes and edges that are routed next to the node’s layer. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-layered-spacing-edgeNodeBetweenLayers.html", + Usage: "the spacing to be preserved between nodes and edges that are routed next to the node’s layer", Tag: "spacing.edgeNodeBetweenLayers", }, { Name: "elk-nodeSelfLoop", Type: "int64", Default: int64(d2elklayout.DefaultOpts.SelfLoopSpacing), - Usage: "spacing to be preserved between a node and its self loops. https://www.eclipse.org/elk/reference/options/org-eclipse-elk-spacing-nodeSelfLoop.html", + Usage: "spacing to be preserved between a node and its self loops", Tag: "elk.spacing.nodeSelfLoop", }, }, nil @@ -75,13 +76,27 @@ func (p *elkPlugin) HydrateOpts(opts []byte) error { return nil } -func (p elkPlugin) Info(context.Context) (*PluginInfo, error) { +func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) { + opts := xmain.NewOpts(nil, nil, nil) + flags, err := p.Flags(ctx) + if err != nil { + return nil, err + } + for _, f := range flags { + f.AddToOpts(opts) + } return &PluginInfo{ Name: "elk", ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.", - LongHelp: `ELK is a layout engine offered by Eclipse. + LongHelp: fmt.Sprintf(`ELK is a layout engine offered by Eclipse. Originally written in Java, it has been ported to Javascript and cross-compiled into D2. -See https://github.com/kieler/elkjs for more.`, +See https://github.com/kieler/elkjs for more. + +Flags correspond to ones found in https://www.eclipse.org/elk/reference.html. See ELK's reference for more on each. + +Flags: +%s +`, opts.Defaults()), }, nil } diff --git a/main.go b/main.go index bbfdff7b1..d9c5655b4 100644 --- a/main.go +++ b/main.go @@ -307,12 +307,9 @@ func populateLayoutOpts(ctx context.Context, ms *xmain.State) error { } for _, f := range pluginFlags { - switch f.Type { - case "string": - ms.Opts.String("", f.Name, "", f.Default.(string), f.Usage) - case "int64": - ms.Opts.Int64("", f.Name, "", f.Default.(int64), f.Usage) - } + f.AddToOpts(ms.Opts) + // Don't pollute the main d2 flagset with these. It'll be a lot + ms.Opts.Flags.MarkHidden(f.Name) } return nil From 09ca0c5b03d5fc029a33841a922fcb8ad9c5b909 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 13:22:45 -0800 Subject: [PATCH 17/67] modify --- ci/release/template/man/d2.1 | 2 +- help.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/release/template/man/d2.1 b/ci/release/template/man/d2.1 index a484ebe8f..b1bcb709c 100644 --- a/ci/release/template/man/d2.1 +++ b/ci/release/template/man/d2.1 @@ -82,7 +82,7 @@ Print version information and exit. .It Ar layout Lists available layout engine options with short help. .It Ar layout Op Ar name -Display long help for a particular layout engine. +Display long help for a particular layout engine, including its configuration options. .It Ar fmt Ar file.d2 Format .Ar file.d2 diff --git a/help.go b/help.go index bd6b455d0..27f9bc22c 100644 --- a/help.go +++ b/help.go @@ -32,7 +32,7 @@ Flags: Subcommands: %[1]s layout - Lists available layout engine options with short help - %[1]s layout [name] - Display long help for a particular layout engine + %[1]s layout [name] - Display long help for a particular layout engine, including its configuration options %[1]s fmt file.d2 - Format file.d2 See more docs and the source code at https://oss.terrastruct.com/d2 @@ -75,7 +75,7 @@ Example: D2_LAYOUT=dagre d2 in.d2 out.svg Subcommands: - %s layout [layout name] - Display long help for a particular layout engine + %s layout [layout name] - Display long help for a particular layout engine, including its configuration options See more docs at https://oss.terrastruct.com/d2 `, strings.Join(pluginLines, "\n"), ms.Name) From 1831af5308da8bf53b93e782b79f8d19a7f4fd6d Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 13:26:01 -0800 Subject: [PATCH 18/67] add tags to dagre --- d2layouts/d2dagrelayout/layout.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index 6d2a5f91b..a6cb68e84 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -31,8 +31,8 @@ var setupJS string var dagreJS string type ConfigurableOpts struct { - NodeSep int - EdgeSep int + NodeSep int `json:"nodesep"` + EdgeSep int `json:"edgesep"` } var DefaultOpts = ConfigurableOpts{ From 97078e53aee53d8d0cc9bf4bc49be929c4d19d25 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 13:29:16 -0800 Subject: [PATCH 19/67] ok --- d2plugin/plugin_elk.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index c5033d4e3..9ef2c5847 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -92,7 +92,7 @@ func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) { Originally written in Java, it has been ported to Javascript and cross-compiled into D2. See https://github.com/kieler/elkjs for more. -Flags correspond to ones found in https://www.eclipse.org/elk/reference.html. See ELK's reference for more on each. +Flags correspond to ones found at https://www.eclipse.org/elk/reference.html. See ELK's reference for more on each. Flags: %s From 115d6e41477e029463eebf341f0e3ea9c717e134 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 13:36:49 -0800 Subject: [PATCH 20/67] default layouts --- cmd/d2plugin-dagre/main.go | 2 +- d2chaos/d2chaos_test.go | 2 +- d2exporter/export_test.go | 2 +- d2layouts/d2dagrelayout/layout.go | 4 ++++ d2layouts/d2elklayout/layout.go | 4 ++++ d2renderers/d2sketch/sketch_test.go | 2 +- d2renderers/d2svg/appendix/appendix_test.go | 2 +- docs/examples/lib/1-d2lib/d2lib.go | 6 +++++- docs/examples/lib/2-d2oracle/d2oracle.go | 2 +- docs/examples/lib/3-lowlevel/lowlevel.go | 2 +- e2etests/e2e_test.go | 4 ++-- 11 files changed, 22 insertions(+), 10 deletions(-) diff --git a/cmd/d2plugin-dagre/main.go b/cmd/d2plugin-dagre/main.go index 5dbed2235..96130300e 100644 --- a/cmd/d2plugin-dagre/main.go +++ b/cmd/d2plugin-dagre/main.go @@ -9,5 +9,5 @@ import ( ) func main() { - xmain.Main(d2plugin.Serve(d2plugin.DagrePlugin)) + xmain.Main(d2plugin.Serve(&d2plugin.DagrePlugin)) } diff --git a/d2chaos/d2chaos_test.go b/d2chaos/d2chaos_test.go index d5ac6a17d..8b73e4e82 100644 --- a/d2chaos/d2chaos_test.go +++ b/d2chaos/d2chaos_test.go @@ -123,7 +123,7 @@ func test(t *testing.T, textPath, text string) { err = g.SetDimensions(nil, ruler, nil) assert.Nil(t, err) - err = d2dagrelayout.Layout(ctx, g) + err = d2dagrelayout.DefaultLayout(ctx, g) if err != nil { t.Fatal(err) } diff --git a/d2exporter/export_test.go b/d2exporter/export_test.go index ca813d2b1..613090be5 100644 --- a/d2exporter/export_test.go +++ b/d2exporter/export_test.go @@ -239,7 +239,7 @@ func run(t *testing.T, tc testCase) { err = g.SetDimensions(nil, ruler, nil) assert.JSON(t, nil, err) - err = d2sequence.Layout(ctx, g, d2dagrelayout.Layout) + err = d2sequence.Layout(ctx, g, d2dagrelayout.DefaultLayout) if err != nil { t.Fatal(err) } diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index a6cb68e84..9969d2080 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -61,6 +61,10 @@ type dagreOpts struct { ConfigurableOpts } +func DefaultLayout(ctx context.Context, g *d2graph.Graph) (err error) { + return Layout(ctx, g, nil) +} + func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err error) { if opts == nil { opts = &DefaultOpts diff --git a/d2layouts/d2elklayout/layout.go b/d2layouts/d2elklayout/layout.go index 384d877e5..253310c61 100644 --- a/d2layouts/d2elklayout/layout.go +++ b/d2layouts/d2elklayout/layout.go @@ -103,6 +103,10 @@ type elkOpts struct { ConfigurableOpts } +func DefaultLayout(ctx context.Context, g *d2graph.Graph) (err error) { + return Layout(ctx, g, nil) +} + func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err error) { if opts == nil { opts = &DefaultOpts diff --git a/d2renderers/d2sketch/sketch_test.go b/d2renderers/d2sketch/sketch_test.go index e033bedfe..c2b8dadea 100644 --- a/d2renderers/d2sketch/sketch_test.go +++ b/d2renderers/d2sketch/sketch_test.go @@ -314,7 +314,7 @@ func run(t *testing.T, tc testCase) { diagram, _, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{ Ruler: ruler, ThemeID: 0, - Layout: d2dagrelayout.Layout, + Layout: d2dagrelayout.DefaultLayout, FontFamily: go2.Pointer(d2fonts.HandDrawn), }) if !tassert.Nil(t, err) { diff --git a/d2renderers/d2svg/appendix/appendix_test.go b/d2renderers/d2svg/appendix/appendix_test.go index a4105c38e..74a6f327f 100644 --- a/d2renderers/d2svg/appendix/appendix_test.go +++ b/d2renderers/d2svg/appendix/appendix_test.go @@ -121,7 +121,7 @@ func run(t *testing.T, tc testCase) { diagram, _, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{ Ruler: ruler, ThemeID: 0, - Layout: d2dagrelayout.Layout, + Layout: d2dagrelayout.DefaultLayout, }) if !tassert.Nil(t, err) { return diff --git a/docs/examples/lib/1-d2lib/d2lib.go b/docs/examples/lib/1-d2lib/d2lib.go index 3b0114c88..af2b98674 100644 --- a/docs/examples/lib/1-d2lib/d2lib.go +++ b/docs/examples/lib/1-d2lib/d2lib.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "path/filepath" + "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2renderers/d2svg" @@ -15,8 +16,11 @@ import ( // Remember to add if err != nil checks in production. func main() { ruler, _ := textmeasure.NewRuler() + defaultLayout := func(ctx context.Context, g *d2graph.Graph) error { + return d2dagrelayout.Layout(ctx, g, nil) + } diagram, _, _ := d2lib.Compile(context.Background(), "x -> y", &d2lib.CompileOptions{ - Layout: d2dagrelayout.Layout, + Layout: defaultLayout, Ruler: ruler, ThemeID: d2themescatalog.GrapeSoda.ID, }) diff --git a/docs/examples/lib/2-d2oracle/d2oracle.go b/docs/examples/lib/2-d2oracle/d2oracle.go index 1f265a05e..617943e15 100644 --- a/docs/examples/lib/2-d2oracle/d2oracle.go +++ b/docs/examples/lib/2-d2oracle/d2oracle.go @@ -17,7 +17,7 @@ func main() { // From one.go ruler, _ := textmeasure.NewRuler() _, graph, _ := d2lib.Compile(context.Background(), "x -> y", &d2lib.CompileOptions{ - Layout: d2dagrelayout.Layout, + Layout: d2dagrelayout.DefaultLayout, Ruler: ruler, ThemeID: d2themescatalog.GrapeSoda.ID, }) diff --git a/docs/examples/lib/3-lowlevel/lowlevel.go b/docs/examples/lib/3-lowlevel/lowlevel.go index 1ad6443b0..1912137f4 100644 --- a/docs/examples/lib/3-lowlevel/lowlevel.go +++ b/docs/examples/lib/3-lowlevel/lowlevel.go @@ -19,7 +19,7 @@ func main() { graph, _ := d2compiler.Compile("", strings.NewReader("x -> y"), nil) ruler, _ := textmeasure.NewRuler() _ = graph.SetDimensions(nil, ruler, nil) - _ = d2dagrelayout.Layout(context.Background(), graph) + _ = d2dagrelayout.Layout(context.Background(), graph, nil) diagram, _ := d2exporter.Export(context.Background(), graph, d2themescatalog.NeutralDefault.ID, nil) out, _ := d2svg.Render(diagram, &d2svg.RenderOpts{ Pad: d2svg.DEFAULT_PADDING, diff --git a/e2etests/e2e_test.go b/e2etests/e2e_test.go index 994770426..dcca4bba2 100644 --- a/e2etests/e2e_test.go +++ b/e2etests/e2e_test.go @@ -130,9 +130,9 @@ func run(t *testing.T, tc testCase) { for _, layoutName := range layoutsTested { var layout func(context.Context, *d2graph.Graph) error if layoutName == "dagre" { - layout = d2dagrelayout.Layout + layout = d2dagrelayout.DefaultLayout } else if layoutName == "elk" { - layout = d2elklayout.Layout + layout = d2elklayout.DefaultLayout } diagram, _, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{ Ruler: ruler, From 4e1ac0876e092f45e65cf8594c121f17fc004328 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 13:39:21 -0800 Subject: [PATCH 21/67] remove a todo --- d2plugin/plugin_elk.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index 9ef2c5847..631e953ba 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -67,8 +67,7 @@ func (p *elkPlugin) HydrateOpts(opts []byte) error { var elkOpts d2elklayout.ConfigurableOpts err := json.Unmarshal(opts, &elkOpts) if err != nil { - // TODO not right - return xmain.UsageErrorf("non-dagre layout options given for dagre") + return xmain.UsageErrorf("non-ELK layout options given for ELK") } p.opts = &elkOpts From 26be278934fa6109eafa2ef8616f2fe40ed81286 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 14:28:52 -0800 Subject: [PATCH 22/67] fix elk --- d2layouts/d2elklayout/layout.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/d2layouts/d2elklayout/layout.go b/d2layouts/d2elklayout/layout.go index 253310c61..89ad6e50a 100644 --- a/d2layouts/d2elklayout/layout.go +++ b/d2layouts/d2elklayout/layout.go @@ -132,7 +132,12 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err LayoutOptions: &elkOpts{ HierarchyHandling: "INCLUDE_CHILDREN", ConsiderModelOrder: "NODES_AND_EDGES", - ConfigurableOpts: *opts, + ConfigurableOpts: ConfigurableOpts{ + Algorithm: opts.Algorithm, + NodeSpacing: opts.NodeSpacing, + EdgeNodeSpacing: opts.EdgeNodeSpacing, + SelfLoopSpacing: opts.SelfLoopSpacing, + }, }, } switch g.Root.Attributes.Direction.Value { From 7a4d2e6e372c52aeb57d1383343a87ad86b72876 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 15:12:58 -0800 Subject: [PATCH 23/67] update exec hydrate opts --- d2plugin/exec.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/d2plugin/exec.go b/d2plugin/exec.go index cce95b5db..b004b5aff 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "os/exec" + "strconv" "time" "oss.terrastruct.com/util-go/xdefer" @@ -68,13 +69,23 @@ func (p execPlugin) Flags(ctx context.Context) (_ []PluginSpecificFlag, err erro func (p *execPlugin) HydrateOpts(opts []byte) error { if opts != nil { - var execOpts map[string]string + var execOpts map[string]interface{} err := json.Unmarshal(opts, &execOpts) if err != nil { return xmain.UsageErrorf("non-exec layout options given for exec") } - p.opts = execOpts + allString := make(map[string]string) + for k, v := range execOpts { + switch vt := v.(type) { + case string: + allString[k] = vt + case int64: + allString[k] = strconv.Itoa(int(vt)) + } + } + + p.opts = allString } return nil } From fdcba4565e96671e5ba617d035fdbbe5fd09d073 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 16:07:50 -0800 Subject: [PATCH 24/67] include binary plugins in flag search --- d2plugin/plugin.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index 765d9f60e..38eade4a9 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -142,5 +142,19 @@ func ListPluginFlags(ctx context.Context) ([]PluginSpecificFlag, error) { } out = append(out, flags...) } + + matches, err := xexec.SearchPath(binaryPrefix) + if err != nil { + return nil, err + } + for _, path := range matches { + p := &execPlugin{path: path} + flags, err := p.Flags(ctx) + if err != nil { + return nil, err + } + out = append(out, flags...) + } + return out, nil } From a92e7211a76908891d3f9a36e83c74a6bf0cadf5 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 16:16:29 -0800 Subject: [PATCH 25/67] unmarshal float64 --- d2plugin/plugin.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index 38eade4a9..a8c894333 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -34,7 +34,15 @@ func (f *PluginSpecificFlag) AddToOpts(opts *xmain.Opts) { case "string": opts.String("", f.Name, "", f.Default.(string), f.Usage) case "int64": - opts.Int64("", f.Name, "", f.Default.(int64), f.Usage) + var val int64 + switch defaultType := f.Default.(type) { + case int64: + val = defaultType + case float64: + // json unmarshals numbers to float64 + val = int64(defaultType) + } + opts.Int64("", f.Name, "", val, f.Usage) } } From 4c7398ba111e74bf3227ec4ba4c0a1036f06769e Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 16:22:40 -0800 Subject: [PATCH 26/67] plugins parse flags --- d2plugin/serve.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/d2plugin/serve.go b/d2plugin/serve.go index cf857b3ee..2e8da78f0 100644 --- a/d2plugin/serve.go +++ b/d2plugin/serve.go @@ -21,6 +21,13 @@ import ( // Also see execPlugin in exec.go for the d2 binary plugin protocol. func Serve(p Plugin) xmain.RunFunc { return func(ctx context.Context, ms *xmain.State) (err error) { + fs, err := p.Flags(ctx) + if err != nil { + return err + } + for _, f := range fs { + f.AddToOpts(ms.Opts) + } err = ms.Opts.Flags.Parse(ms.Opts.Args) if !errors.Is(err, pflag.ErrHelp) && err != nil { return xmain.UsageErrorf("failed to parse flags: %v", err) From 005b27d4648797658c33c8554f8df655962e2ca7 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 16:25:51 -0800 Subject: [PATCH 27/67] exec correctly --- d2plugin/exec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2plugin/exec.go b/d2plugin/exec.go index b004b5aff..acb8a9618 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -126,7 +126,7 @@ func (p execPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { args := []string{"layout"} for k, v := range p.opts { - args = append(args, k, v) + args = append(args, fmt.Sprintf("--%s", k), v) } cmd := exec.CommandContext(ctx, p.path, args...) From 5a88f9d3310dc66e90ec51ea75a11d8f6cde1822 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 17:08:14 -0800 Subject: [PATCH 28/67] [ci-force] missed case --- d2plugin/exec.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/d2plugin/exec.go b/d2plugin/exec.go index acb8a9618..efbfcd970 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -82,6 +82,8 @@ func (p *execPlugin) HydrateOpts(opts []byte) error { allString[k] = vt case int64: allString[k] = strconv.Itoa(int(vt)) + case float64: + allString[k] = strconv.Itoa(int(vt)) } } From c0eefc9447dca5ac39b108f6ec421cfabde2054c Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 17:28:21 -0800 Subject: [PATCH 29/67] ok --- d2plugin/serve.go | 31 +++++++++++++++++++++++++++++++ main.go | 29 +---------------------------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/d2plugin/serve.go b/d2plugin/serve.go index 2e8da78f0..888a6abfe 100644 --- a/d2plugin/serve.go +++ b/d2plugin/serve.go @@ -41,6 +41,11 @@ func Serve(p Plugin) xmain.RunFunc { return xmain.UsageErrorf("expected first argument to be subcmd name") } + err = ParsePluginOpts(ctx, ms, p) + if err != nil { + return err + } + subcmd := ms.Opts.Flags.Arg(0) switch subcmd { case "info": @@ -130,3 +135,29 @@ func postProcess(ctx context.Context, p Plugin, ms *xmain.State) error { } return nil } + +func ParsePluginOpts(ctx context.Context, ms *xmain.State, plugin Plugin) error { + opts := make(map[string]interface{}) + flags, err := plugin.Flags(ctx) + if err != nil { + return err + } + for _, f := range flags { + switch f.Type { + case "string": + val, _ := ms.Opts.Flags.GetString(f.Name) + opts[f.Tag] = val + case "int64": + val, _ := ms.Opts.Flags.GetInt64(f.Name) + opts[f.Tag] = val + } + } + + b, err := json.Marshal(opts) + if err != nil { + return err + } + + err = plugin.HydrateOpts(b) + return err +} diff --git a/main.go b/main.go index d9c5655b4..1ef9d1478 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "encoding/json" "errors" "fmt" "io" @@ -150,7 +149,7 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } - err = parseLayoutOpts(ctx, ms, plugin) + err = d2plugin.ParsePluginOpts(ctx, ms, plugin) if err != nil { return err } @@ -314,29 +313,3 @@ func populateLayoutOpts(ctx context.Context, ms *xmain.State) error { return nil } - -func parseLayoutOpts(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin) error { - opts := make(map[string]interface{}) - flags, err := plugin.Flags(ctx) - if err != nil { - return err - } - for _, f := range flags { - switch f.Type { - case "string": - val, _ := ms.Opts.Flags.GetString(f.Name) - opts[f.Tag] = val - case "int64": - val, _ := ms.Opts.Flags.GetInt64(f.Name) - opts[f.Tag] = val - } - } - - b, err := json.Marshal(opts) - if err != nil { - return err - } - - err = plugin.HydrateOpts(b) - return err -} From f10c7cfb5c22870b5252b5662dbe997e59e57e4d Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 17:30:25 -0800 Subject: [PATCH 30/67] ok --- d2plugin/plugin.go | 26 ++++++++++++++++++++++++++ d2plugin/serve.go | 28 +--------------------------- main.go | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index a8c894333..25eee8d08 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -7,6 +7,7 @@ package d2plugin import ( "context" + "encoding/json" "os/exec" "oss.terrastruct.com/util-go/xexec" @@ -166,3 +167,28 @@ func ListPluginFlags(ctx context.Context) ([]PluginSpecificFlag, error) { return out, nil } + +func HydratePluginOpts(ctx context.Context, ms *xmain.State, plugin Plugin) error { + opts := make(map[string]interface{}) + flags, err := plugin.Flags(ctx) + if err != nil { + return err + } + for _, f := range flags { + switch f.Type { + case "string": + val, _ := ms.Opts.Flags.GetString(f.Name) + opts[f.Tag] = val + case "int64": + val, _ := ms.Opts.Flags.GetInt64(f.Name) + opts[f.Tag] = val + } + } + + b, err := json.Marshal(opts) + if err != nil { + return err + } + + return plugin.HydrateOpts(b) +} diff --git a/d2plugin/serve.go b/d2plugin/serve.go index 888a6abfe..acc697a96 100644 --- a/d2plugin/serve.go +++ b/d2plugin/serve.go @@ -41,7 +41,7 @@ func Serve(p Plugin) xmain.RunFunc { return xmain.UsageErrorf("expected first argument to be subcmd name") } - err = ParsePluginOpts(ctx, ms, p) + err = HydratePluginOpts(ctx, ms, p) if err != nil { return err } @@ -135,29 +135,3 @@ func postProcess(ctx context.Context, p Plugin, ms *xmain.State) error { } return nil } - -func ParsePluginOpts(ctx context.Context, ms *xmain.State, plugin Plugin) error { - opts := make(map[string]interface{}) - flags, err := plugin.Flags(ctx) - if err != nil { - return err - } - for _, f := range flags { - switch f.Type { - case "string": - val, _ := ms.Opts.Flags.GetString(f.Name) - opts[f.Tag] = val - case "int64": - val, _ := ms.Opts.Flags.GetInt64(f.Name) - opts[f.Tag] = val - } - } - - b, err := json.Marshal(opts) - if err != nil { - return err - } - - err = plugin.HydrateOpts(b) - return err -} diff --git a/main.go b/main.go index 1ef9d1478..78041b71e 100644 --- a/main.go +++ b/main.go @@ -149,7 +149,7 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } - err = d2plugin.ParsePluginOpts(ctx, ms, plugin) + err = d2plugin.HydratePluginOpts(ctx, ms, plugin) if err != nil { return err } From 86e45e9e708d2a422ad74a92b2b8ac3a9432c9df Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 18:26:52 -0800 Subject: [PATCH 31/67] changelog --- ci/release/changelogs/next.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 6d0e821af..bfae5d068 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,16 +1,25 @@ +This release marks the introduction of interactive diagrams. Namely, `tooltip` and `link` can now be set, which allows you to hover to see more or click to go to an external link. This small change enables many possibilities, including richer integrations like internal wiki's that can be linked together through diagrams. + +Since interactive features obviously won't work on static export formats like PNG, they will be included automatically in an appendix when exporting to those formats, like so: + +placeholder + +This release also gives more power to configure layouts. `width` and `height` are D2 keywords which previouslly only worked on images, but now work on any non-containers. Additionally, all the layout engines have configurations exposed. D2 sets sensible defaults to each layout engine without any input, so this is meant to be an advanced feature for users who want that extra control. + #### Features 🚀 - Tooltips can be set on shapes. See [https://d2lang.com/tour/tooltips](https://d2lang.com/tour/interactive). [#548](https://github.com/terrastruct/d2/pull/548) - Links can be set on shapes. See [https://d2lang.com/tour/tooltips](https://d2lang.com/tour/interactive). [#548](https://github.com/terrastruct/d2/pull/548) - The `width` and `height` attributes are no longer restricted to images and can be applied to non-container shapes. [#498](https://github.com/terrastruct/d2/pull/498) +- Layout engine options are exposed and configurable. See individual layout pages on [https://d2lang.com/tour/layouts](https://d2lang.com/tour/layouts) for list of configurations. [#563](https://github.com/terrastruct/d2/pull/563) #### Improvements 🧹 -- Watch mode now renders fit to screen. [#560](https://github.com/terrastruct/d2/pull/560) +- Watch mode renders fit to screen. [#560](https://github.com/terrastruct/d2/pull/560) #### Bugfixes ⛑️ +- Fixes rendering `class` and `table` with empty headers. [#498](https://github.com/terrastruct/d2/pull/498) +- Fixes rendering of `sql_table` with no columns. [#553](https://github.com/terrastruct/d2/pull/553) - Restricts where `near` key constant values can be used, with good error messages, instead of erroring (e.g. setting `near: top-center` on a container would cause bad layouts or error). [#538](https://github.com/terrastruct/d2/pull/538) -- Fixes an error during ELK layout when images had empty labels. [#555](https://github.com/terrastruct/d2/pull/555) -- Fixes rendering classes and tables with empty headers. [#498](https://github.com/terrastruct/d2/pull/498) -- Fixes rendering sql tables with no columns. [#553](https://github.com/terrastruct/d2/pull/553) +- Fixes panic when images with empty labels are rendered with ELK. [#555](https://github.com/terrastruct/d2/pull/555) From 141d6c571290aefa7c88b45405a73d5b9cec13dd Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 18:31:47 -0800 Subject: [PATCH 32/67] update breaking change --- ci/release/changelogs/next.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index bfae5d068..f7e94cca0 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -23,3 +23,8 @@ This release also gives more power to configure layouts. `width` and `height` ar - Fixes rendering of `sql_table` with no columns. [#553](https://github.com/terrastruct/d2/pull/553) - Restricts where `near` key constant values can be used, with good error messages, instead of erroring (e.g. setting `near: top-center` on a container would cause bad layouts or error). [#538](https://github.com/terrastruct/d2/pull/538) - Fixes panic when images with empty labels are rendered with ELK. [#555](https://github.com/terrastruct/d2/pull/555) + +#### Breaking changes + +- For usages of D2 as a library, `d2dagrelayout.Layout` and `d2elklayout.Layout` now accept a third parameter for options. If you would like to keep the defaults, change your code to call `dagrelayout.DefaultLayout` and `d2elklayout.DefaultLayout` respectively. + From 0676c124d3e95963484e17c9db00718450aa9580 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 18:50:00 -0800 Subject: [PATCH 33/67] Update next.md --- ci/release/changelogs/next.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f7e94cca0..629b706f0 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,11 +1,15 @@ -This release marks the introduction of interactive diagrams. Namely, `tooltip` and `link` can now be set, which allows you to hover to see more or click to go to an external link. This small change enables many possibilities, including richer integrations like internal wiki's that can be linked together through diagrams. +This release marks the introduction of interactive diagrams. Namely, `tooltip` and `link` can now be set, which allows you to hover to see more or click to go to an external link. This small change enables many possibilities, including richer integrations like internal wiki's that can be linked together through diagrams. An icon will indicate that a shape has a tooltip that can be hovered over for more information, or a link. + +Screen Shot 2022-12-30 at 6 47 45 PM Since interactive features obviously won't work on static export formats like PNG, they will be included automatically in an appendix when exporting to those formats, like so: -placeholder +![tooltip](https://user-images.githubusercontent.com/3120367/210122793-582d3fc7-8e09-46f1-bb78-5dcc6cf1de55.png) This release also gives more power to configure layouts. `width` and `height` are D2 keywords which previouslly only worked on images, but now work on any non-containers. Additionally, all the layout engines have configurations exposed. D2 sets sensible defaults to each layout engine without any input, so this is meant to be an advanced feature for users who want that extra control. +Happy new years! + #### Features 🚀 - Tooltips can be set on shapes. See [https://d2lang.com/tour/tooltips](https://d2lang.com/tour/interactive). [#548](https://github.com/terrastruct/d2/pull/548) @@ -26,5 +30,5 @@ This release also gives more power to configure layouts. `width` and `height` ar #### Breaking changes -- For usages of D2 as a library, `d2dagrelayout.Layout` and `d2elklayout.Layout` now accept a third parameter for options. If you would like to keep the defaults, change your code to call `dagrelayout.DefaultLayout` and `d2elklayout.DefaultLayout` respectively. +- For usages of D2 as a library, `d2dagrelayout.Layout` and `d2elklayout.Layout` now accept a third parameter for options. If you would like to keep the defaults, please change your code to call `dagrelayout.DefaultLayout` and `d2elklayout.DefaultLayout` respectively. From 510c10227eefacf11a9133eedda48761cea4f870 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 20:49:49 -0800 Subject: [PATCH 34/67] fix bounding boxes --- ci/release/changelogs/next.md | 4 ++-- d2renderers/d2svg/appendix/appendix.go | 3 ++- d2target/d2target.go | 14 ++++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f7e94cca0..f6b3aaea6 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -8,8 +8,8 @@ This release also gives more power to configure layouts. `width` and `height` ar #### Features 🚀 -- Tooltips can be set on shapes. See [https://d2lang.com/tour/tooltips](https://d2lang.com/tour/interactive). [#548](https://github.com/terrastruct/d2/pull/548) -- Links can be set on shapes. See [https://d2lang.com/tour/tooltips](https://d2lang.com/tour/interactive). [#548](https://github.com/terrastruct/d2/pull/548) +- Tooltips can be set on shapes. See [https://d2lang.com/tour/interactive](https://d2lang.com/tour/interactive). [#548](https://github.com/terrastruct/d2/pull/548) +- Links can be set on shapes. See [https://d2lang.com/tour/interactive](https://d2lang.com/tour/interactive). [#548](https://github.com/terrastruct/d2/pull/548) - The `width` and `height` attributes are no longer restricted to images and can be applied to non-container shapes. [#498](https://github.com/terrastruct/d2/pull/498) - Layout engine options are exposed and configurable. See individual layout pages on [https://d2lang.com/tour/layouts](https://d2lang.com/tour/layouts) for list of configurations. [#563](https://github.com/terrastruct/d2/pull/563) diff --git a/d2renderers/d2svg/appendix/appendix.go b/d2renderers/d2svg/appendix/appendix.go index f25dc1c02..47e7a7ba1 100644 --- a/d2renderers/d2svg/appendix/appendix.go +++ b/d2renderers/d2svg/appendix/appendix.go @@ -153,6 +153,7 @@ func generateAppendix(diagram *d2target.Diagram, ruler *textmeasure.Ruler, svg s } } } + totalHeight += SPACER return fmt.Sprintf(`%s `, tl.X, br.Y, (br.X - tl.X), strings.Join(lines, "\n")), maxWidth, totalHeight @@ -182,5 +183,5 @@ func generateLine(i, y int, text string, ruler *textmeasure.Ruler) (string, int, line += fmt.Sprintf(`%s`, ICON_RADIUS*3, y, FONT_SIZE, d2svg.RenderText(text, ICON_RADIUS*3, float64(dims.Height))) - return line, dims.Width + ICON_RADIUS*3, dims.Height + return line, dims.Width + ICON_RADIUS*3, go2.IntMax(dims.Height, ICON_RADIUS*2) } diff --git a/d2target/d2target.go b/d2target/d2target.go index 90974c7f1..ea54ee52f 100644 --- a/d2target/d2target.go +++ b/d2target/d2target.go @@ -55,10 +55,16 @@ func (diagram Diagram) BoundingBox() (topLeft, bottomRight Point) { y2 := int(math.MinInt32) for _, targetShape := range diagram.Shapes { - x1 = go2.Min(x1, targetShape.Pos.X) - y1 = go2.Min(y1, targetShape.Pos.Y) - x2 = go2.Max(x2, targetShape.Pos.X+targetShape.Width) - y2 = go2.Max(y2, targetShape.Pos.Y+targetShape.Height) + x1 = go2.Min(x1, targetShape.Pos.X-targetShape.StrokeWidth) + y1 = go2.Min(y1, targetShape.Pos.Y-targetShape.StrokeWidth) + x2 = go2.Max(x2, targetShape.Pos.X+targetShape.Width+targetShape.StrokeWidth) + y2 = go2.Max(y2, targetShape.Pos.Y+targetShape.Height+targetShape.StrokeWidth) + + if targetShape.Tooltip != "" || targetShape.Link != "" { + // 16 is the icon radius + y1 = go2.Min(y1, targetShape.Pos.Y-targetShape.StrokeWidth-16) + x2 = go2.Max(x2, targetShape.Pos.X+targetShape.StrokeWidth+targetShape.Width+16) + } if targetShape.Label != "" { labelPosition := label.Position(targetShape.LabelPosition) From 4afa226aa8c2d56dd2830b82bb6b751200ee8594 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 20:50:55 -0800 Subject: [PATCH 35/67] changelog --- ci/release/changelogs/next.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f6b3aaea6..f0abf708c 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -21,6 +21,7 @@ This release also gives more power to configure layouts. `width` and `height` ar - Fixes rendering `class` and `table` with empty headers. [#498](https://github.com/terrastruct/d2/pull/498) - Fixes rendering of `sql_table` with no columns. [#553](https://github.com/terrastruct/d2/pull/553) +- Diagram bounding boxes now account for stroke widths. [#574](https://github.com/terrastruct/d2/pull/574) - Restricts where `near` key constant values can be used, with good error messages, instead of erroring (e.g. setting `near: top-center` on a container would cause bad layouts or error). [#538](https://github.com/terrastruct/d2/pull/538) - Fixes panic when images with empty labels are rendered with ELK. [#555](https://github.com/terrastruct/d2/pull/555) From 5195dfc5cde2adce0e27dfd355b61e5d4fb64742 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 20:52:00 -0800 Subject: [PATCH 36/67] typo --- ci/release/changelogs/next.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f0abf708c..1ce1b4606 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -21,7 +21,7 @@ This release also gives more power to configure layouts. `width` and `height` ar - Fixes rendering `class` and `table` with empty headers. [#498](https://github.com/terrastruct/d2/pull/498) - Fixes rendering of `sql_table` with no columns. [#553](https://github.com/terrastruct/d2/pull/553) -- Diagram bounding boxes now account for stroke widths. [#574](https://github.com/terrastruct/d2/pull/574) +- Diagram bounding boxes account for stroke widths. [#574](https://github.com/terrastruct/d2/pull/574) - Restricts where `near` key constant values can be used, with good error messages, instead of erroring (e.g. setting `near: top-center` on a container would cause bad layouts or error). [#538](https://github.com/terrastruct/d2/pull/538) - Fixes panic when images with empty labels are rendered with ELK. [#555](https://github.com/terrastruct/d2/pull/555) From e8a897530cfffa546e9975e3db674cc10271f939 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 30 Dec 2022 21:00:34 -0800 Subject: [PATCH 37/67] update tests --- .../d2sketch/testdata/all_shapes/sketch.exp.svg | 6 +++--- d2renderers/d2sketch/testdata/basic/sketch.exp.svg | 6 +++--- .../d2sketch/testdata/child_to_child/sketch.exp.svg | 6 +++--- d2renderers/d2sketch/testdata/class/sketch.exp.svg | 6 +++--- .../testdata/connection_label/sketch.exp.svg | 6 +++--- .../d2sketch/testdata/sql_tables/sketch.exp.svg | 6 +++--- d2renderers/d2sketch/testdata/twitter/sketch.exp.svg | 6 +++--- .../diagram_wider_than_tooltip/sketch.exp.svg | 10 +++++----- .../d2svg/appendix/testdata/links/sketch.exp.svg | 12 ++++++------ .../tooltip_wider_than_diagram/sketch.exp.svg | 10 +++++----- .../dagre_edge_label_spacing/dagre/sketch.exp.svg | 6 +++--- .../dagre_edge_label_spacing/elk/sketch.exp.svg | 6 +++--- .../dagre_special_ids/dagre/sketch.exp.svg | 6 +++--- .../regression/dagre_special_ids/elk/sketch.exp.svg | 6 +++--- .../regression/elk_alignment/dagre/sketch.exp.svg | 6 +++--- .../regression/elk_alignment/elk/sketch.exp.svg | 6 +++--- .../elk_img_empty_label_panic/dagre/sketch.exp.svg | 6 +++--- .../elk_img_empty_label_panic/elk/sketch.exp.svg | 6 +++--- .../regression/elk_order/dagre/sketch.exp.svg | 6 +++--- .../testdata/regression/elk_order/elk/sketch.exp.svg | 6 +++--- .../only_header_class_table/dagre/sketch.exp.svg | 6 +++--- .../only_header_class_table/elk/sketch.exp.svg | 6 +++--- .../query_param_escape/dagre/sketch.exp.svg | 6 +++--- .../regression/query_param_escape/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_no_message/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_no_message/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_span_cover/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_span_cover/elk/sketch.exp.svg | 6 +++--- .../sql_table_overflow/dagre/sketch.exp.svg | 6 +++--- .../regression/sql_table_overflow/elk/sketch.exp.svg | 6 +++--- .../unnamed_class_table_code/dagre/sketch.exp.svg | 6 +++--- .../unnamed_class_table_code/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/sanity/1_to_2/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/sanity/basic/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/sanity/basic/elk/sketch.exp.svg | 6 +++--- .../sanity/child_to_child/dagre/sketch.exp.svg | 6 +++--- .../sanity/child_to_child/elk/sketch.exp.svg | 6 +++--- .../sanity/connection_label/dagre/sketch.exp.svg | 6 +++--- .../sanity/connection_label/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/all_shapes/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/all_shapes/elk/sketch.exp.svg | 6 +++--- .../stable/all_shapes_multiple/dagre/sketch.exp.svg | 6 +++--- .../stable/all_shapes_multiple/elk/sketch.exp.svg | 6 +++--- .../stable/all_shapes_shadow/dagre/sketch.exp.svg | 6 +++--- .../stable/all_shapes_shadow/elk/sketch.exp.svg | 6 +++--- .../stable/arrowhead_adjustment/dagre/sketch.exp.svg | 6 +++--- .../stable/arrowhead_adjustment/elk/sketch.exp.svg | 6 +++--- .../stable/arrowhead_labels/dagre/sketch.exp.svg | 6 +++--- .../stable/arrowhead_labels/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/binary_tree/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/binary_tree/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/chaos1/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/chaos1/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/chaos2/elk/sketch.exp.svg | 6 +++--- .../stable/child_parent_edges/dagre/sketch.exp.svg | 6 +++--- .../stable/child_parent_edges/elk/sketch.exp.svg | 6 +++--- .../stable/circular_dependency/dagre/sketch.exp.svg | 6 +++--- .../stable/circular_dependency/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/class/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/class/elk/sketch.exp.svg | 6 +++--- .../stable/code_snippet/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/code_snippet/elk/sketch.exp.svg | 6 +++--- .../stable/connected_container/dagre/sketch.exp.svg | 6 +++--- .../stable/connected_container/elk/sketch.exp.svg | 6 +++--- .../stable/constant_near_stress/dagre/sketch.exp.svg | 6 +++--- .../stable/constant_near_stress/elk/sketch.exp.svg | 6 +++--- .../stable/constant_near_title/dagre/sketch.exp.svg | 6 +++--- .../stable/constant_near_title/elk/sketch.exp.svg | 6 +++--- .../stable/container_edges/dagre/sketch.exp.svg | 6 +++--- .../stable/container_edges/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/dense/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/dense/elk/sketch.exp.svg | 6 +++--- .../stable/different_subgraphs/dagre/sketch.exp.svg | 6 +++--- .../stable/different_subgraphs/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/direction/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/direction/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/font_colors/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/font_colors/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/font_sizes/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/font_sizes/elk/sketch.exp.svg | 6 +++--- .../stable/giant_markdown_test/dagre/sketch.exp.svg | 6 +++--- .../stable/giant_markdown_test/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/hr/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/hr/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/icon-label/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/icon-label/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/images/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/images/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/investigate/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/investigate/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/large_arch/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/large_arch/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/latex/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/latex/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li1/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li1/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li2/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li2/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li3/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li3/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li4/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/li4/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/links/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/links/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/lone_h1/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/markdown/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/markdown/elk/sketch.exp.svg | 6 +++--- .../stable/markdown_stroke_fill/dagre/sketch.exp.svg | 6 +++--- .../stable/markdown_stroke_fill/elk/sketch.exp.svg | 6 +++--- .../stable/md_2space_newline/dagre/sketch.exp.svg | 6 +++--- .../stable/md_2space_newline/elk/sketch.exp.svg | 6 +++--- .../stable/md_backslash_newline/dagre/sketch.exp.svg | 6 +++--- .../stable/md_backslash_newline/elk/sketch.exp.svg | 6 +++--- .../stable/md_code_block_fenced/dagre/sketch.exp.svg | 6 +++--- .../stable/md_code_block_fenced/elk/sketch.exp.svg | 6 +++--- .../md_code_block_indented/dagre/sketch.exp.svg | 6 +++--- .../stable/md_code_block_indented/elk/sketch.exp.svg | 6 +++--- .../stable/md_code_inline/dagre/sketch.exp.svg | 6 +++--- .../stable/md_code_inline/elk/sketch.exp.svg | 6 +++--- .../stable/multiline_text/dagre/sketch.exp.svg | 6 +++--- .../stable/multiline_text/elk/sketch.exp.svg | 6 +++--- .../stable/multiple_trees/dagre/sketch.exp.svg | 6 +++--- .../stable/multiple_trees/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/n22_e32/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/n22_e32/elk/sketch.exp.svg | 6 +++--- .../stable/number_connections/dagre/sketch.exp.svg | 6 +++--- .../stable/number_connections/elk/sketch.exp.svg | 6 +++--- .../stable/one_container_loop/dagre/sketch.exp.svg | 6 +++--- .../stable/one_container_loop/elk/sketch.exp.svg | 6 +++--- .../one_three_one_container/dagre/sketch.exp.svg | 6 +++--- .../one_three_one_container/elk/sketch.exp.svg | 6 +++--- .../dagre/sketch.exp.svg | 6 +++--- .../elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/p/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/p/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/pre/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/pre/elk/sketch.exp.svg | 6 +++--- .../stable/self-referencing/dagre/sketch.exp.svg | 6 +++--- .../stable/self-referencing/elk/sketch.exp.svg | 6 +++--- .../dagre/sketch.exp.svg | 6 +++--- .../elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_all_shapes/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_all_shapes/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_distance/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_distance/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_groups/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_groups/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_long_note/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_long_note/elk/sketch.exp.svg | 6 +++--- .../dagre/sketch.exp.svg | 6 +++--- .../elk/sketch.exp.svg | 6 +++--- .../dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_nested_span/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_note/dagre/sketch.exp.svg | 6 +++--- .../stable/sequence_diagram_note/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_self_edges/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_self_edges/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_simple/dagre/sketch.exp.svg | 6 +++--- .../sequence_diagram_simple/elk/sketch.exp.svg | 6 +++--- .../sequence_diagram_span/dagre/sketch.exp.svg | 6 +++--- .../stable/sequence_diagram_span/elk/sketch.exp.svg | 6 +++--- .../stable/sequence_diagrams/dagre/sketch.exp.svg | 6 +++--- .../stable/sequence_diagrams/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/sql_tables/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/sql_tables/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/square_3d/dagre/sketch.exp.svg | 6 +++--- .../testdata/stable/square_3d/elk/sketch.exp.svg | 6 +++--- .../dagre/sketch.exp.svg | 6 +++--- .../straight_hierarchy_container/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/stylish/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/stylish/elk/sketch.exp.svg | 6 +++--- .../stable/text_font_sizes/dagre/sketch.exp.svg | 6 +++--- .../stable/text_font_sizes/elk/sketch.exp.svg | 6 +++--- .../testdata/stable/tooltips/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/tooltips/elk/sketch.exp.svg | 6 +++--- .../stable/transparent_3d/dagre/sketch.exp.svg | 6 +++--- .../stable/transparent_3d/elk/sketch.exp.svg | 6 +++--- .../stable/unnamed_only_height/dagre/sketch.exp.svg | 6 +++--- .../stable/unnamed_only_height/elk/sketch.exp.svg | 6 +++--- .../stable/unnamed_only_width/dagre/sketch.exp.svg | 6 +++--- .../stable/unnamed_only_width/elk/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/us_map/dagre/sketch.exp.svg | 6 +++--- e2etests/testdata/stable/us_map/elk/sketch.exp.svg | 6 +++--- .../todo/container_child_edge/dagre/sketch.exp.svg | 6 +++--- .../todo/container_child_edge/elk/sketch.exp.svg | 6 +++--- .../font_sizes_containers_large/dagre/sketch.exp.svg | 6 +++--- .../font_sizes_containers_large/elk/sketch.exp.svg | 6 +++--- .../todo/font_sizes_large/dagre/sketch.exp.svg | 6 +++--- .../todo/font_sizes_large/elk/sketch.exp.svg | 6 +++--- .../dagre/sketch.exp.svg | 6 +++--- .../elk/sketch.exp.svg | 6 +++--- .../todo/shape_set_width_height/dagre/sketch.exp.svg | 6 +++--- .../todo/shape_set_width_height/elk/sketch.exp.svg | 6 +++--- .../todo/tall_edge_label/dagre/sketch.exp.svg | 6 +++--- .../testdata/todo/tall_edge_label/elk/sketch.exp.svg | 6 +++--- 198 files changed, 601 insertions(+), 601 deletions(-) diff --git a/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg b/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg index 5b8429973..5b2e6de56 100644 --- a/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg @@ -2,7 +2,7 @@ customerissuerstore1Like starbucks or somethingacquirer2I'm not sure what this isnetworkcustomer bankstore bankinitial transactionpayment processor behind the scenessimplified 1 banana please$10 dollarsthinking: wow, inflationchecks bank accountSavings: $11I can do that, here's my cardRun this cardProcess to card issuerProcess this payment$10 debit$10 creditAn error in judgement is about to occur + @@ -51,8 +51,8 @@ width="1959" height="2297" viewBox="-175 -47 1959 2297">1Like starbucks or something -2I'm not sure what this is +}]]>1Like starbucks or something +2I'm not sure what this is x1y2Gee, I feel kind of LIGHT in the head now, -knowing I can't make my satellite dish PAYMENTS!3 - +knowing I can't make my satellite dish PAYMENTS!3 + 1https://d2lang.com -2Gee, I feel kind of LIGHT in the head now,knowing I can't make my satellite dish PAYMENTS! -3https://terrastruct.com +}]]>1https://d2lang.com +2Gee, I feel kind of LIGHT in the head now,knowing I can't make my satellite dish PAYMENTS! +3https://terrastruct.com x1Total abstinence is easier than perfect moderationy2Gee, I feel kind of LIGHT in the head now, -knowing I can't make my satellite dish PAYMENTS! - +knowing I can't make my satellite dish PAYMENTS! + 1Total abstinence is easier than perfect moderation -2Gee, I feel kind of LIGHT in the head now,knowing I can't make my satellite dish PAYMENTS! +}]]>1Total abstinence is easier than perfect moderation +2Gee, I feel kind of LIGHT in the head now,knowing I can't make my satellite dish PAYMENTS! lambda-build.yamlPush to main branchGitHub ActionsS3TerraformAWS TriggersBuilds zip & pushes it Pulls zip to deployChanges the live lambdas - +lambda-build.yamlPush to main branchGitHub ActionsS3TerraformAWS TriggersBuilds zip & pushes it Pulls zip to deployChanges the live lambdas + diff --git a/e2etests/testdata/regression/dagre_edge_label_spacing/elk/sketch.exp.svg b/e2etests/testdata/regression/dagre_edge_label_spacing/elk/sketch.exp.svg index 814c60100..f6b7a4730 100644 --- a/e2etests/testdata/regression/dagre_edge_label_spacing/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/dagre_edge_label_spacing/elk/sketch.exp.svg @@ -2,7 +2,7 @@ lambda-build.yamlPush to main branchGitHub ActionsS3TerraformAWS TriggersBuilds zip & pushes it Pulls zip to deployChanges the live lambdas + diff --git a/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg b/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg index d5d44ead7..2ff433a1f 100644 --- a/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/dagre_special_ids/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ ninetynineeighty eightseventy sevena\yodetherea\"odea\node + ninetynineeighty eightseventy sevena\yodetherea\"odea\node - +ninetynineeighty eightseventy sevena\yodetherea\"odea\node + lambda-build.yamllambda-deploy.yamlapollo-deploy.yamlPush to main branchGitHub ActionsS3TerraformAWSManual TriggerGitHub ActionsAWSApollo RepoGitHub ActionsAWS TriggersBuilds zip and pushes it Pulls zip to deployChanges live lambdasLaunchesBuilds zippushes them to S3. Deploys lambdasusing TerraformTriggered manually/push to master test test test test test test testtest - +lambda-build.yamllambda-deploy.yamlapollo-deploy.yamlPush to main branchGitHub ActionsS3TerraformAWSManual TriggerGitHub ActionsAWSApollo RepoGitHub ActionsAWS TriggersBuilds zip and pushes it Pulls zip to deployChanges live lambdasLaunchesBuilds zippushes them to S3. Deploys lambdasusing TerraformTriggered manually/push to master test test test test test test testtest + diff --git a/e2etests/testdata/regression/elk_alignment/elk/sketch.exp.svg b/e2etests/testdata/regression/elk_alignment/elk/sketch.exp.svg index 593ff3bb8..f1e943e74 100644 --- a/e2etests/testdata/regression/elk_alignment/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_alignment/elk/sketch.exp.svg @@ -2,7 +2,7 @@ lambda-build.yamllambda-deploy.yamlapollo-deploy.yamlPush to main branchGitHub ActionsS3TerraformAWSManual TriggerGitHub ActionsAWSApollo RepoGitHub ActionsAWS TriggersBuilds zip and pushes it Pulls zip to deployChanges live lambdasLaunchesBuilds zippushes them to S3. Deploys lambdasusing TerraformTriggered manually/push to master test test test test test test testtest + diff --git a/e2etests/testdata/regression/elk_img_empty_label_panic/dagre/sketch.exp.svg b/e2etests/testdata/regression/elk_img_empty_label_panic/dagre/sketch.exp.svg index 3726c5c2d..b3d4e44ed 100644 --- a/e2etests/testdata/regression/elk_img_empty_label_panic/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_img_empty_label_panic/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ + \ No newline at end of file diff --git a/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg b/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg index 81e2051b4..2f96851de 100644 --- a/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_img_empty_label_panic/elk/sketch.exp.svg @@ -2,7 +2,7 @@ + \ No newline at end of file diff --git a/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg b/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg index 64e3079f2..7fedf0258 100644 --- a/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ my network + my network - +my network + AB - +AB + AB - +AB + b - +b + b - +b + abc - +abc + abc - +abc + ab - +ab + ab - +ab + acbd - +acbd + acbd - +acbd + ab hello - +ab hello + ab hello - +ab hello + rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud - +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud + rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud - +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud + rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud - +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud + rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud - +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud + cba * - +cba * + cba * - +cba * + ab To err is human, to moo bovine1* - +ab To err is human, to moo bovine1* + ab To err is human, to moo bovine1* - +ab To err is human, to moo bovine1* + abcdefghijklmno - +abcdefghijklmno + abcdefghijklmno - +abcdefghijklmno + aaadddeeebbbccc111 222 - +aaadddeeebbbccc111 222 + aaadddeeebbbccc111 222 - +aaadddeeebbbccc111 222 + abcd - +abcd + abcd - +abcd + abc - +abc + abc - +abc + acfbdhg - +acfbdhg + acfbdhg - +acfbdhg + agdfbhec - +agdfbhec + agdfbhec - +agdfbhec + abcdefghijklmnopq - +abcdefghijklmnopq + abcdefghijklmnopq - +abcdefghijklmnopq + finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot - +finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot + finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot - +finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot + bacde21345abcde - +bacde21345abcde + bacde21345abcde - +bacde21345abcde + alphabeta gamma - +alphabeta gamma + alphabeta gamma - +alphabeta gamma + size XSsize Ssize Msize Lsize XLsize XXLsize XXXLcustom 8custom 12custom 18custom 21custom 64 custom 10custom 15custom 48 - +size XSsize Ssize Msize Lsize XLsize XXLsize XXXLcustom 8custom 12custom 18custom 21custom 64 custom 10custom 15custom 48 + diff --git a/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg b/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg index f8f67a3b1..e3c27605a 100644 --- a/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg @@ -2,7 +2,7 @@ size XSsize Ssize Msize Lsize XLsize XXLsize XXXLcustom 8custom 12custom 18custom 21custom 64 custom 10custom 15custom 48 + diff --git a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg index b257f8591..4029b4315 100644 --- a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ hello + hello - +hello + ab - +ab + ab - +ab + aabbccddllffwwyynniijjkkssuurmeemmmmgghhzzooppqqrrttvvxxabac 123456 - +aabbccddllffwwyynniijjkkssuurmeemmmmgghhzzooppqqrrttvvxxabac 123456 + diff --git a/e2etests/testdata/stable/investigate/elk/sketch.exp.svg b/e2etests/testdata/stable/investigate/elk/sketch.exp.svg index 81797bd00..749518466 100644 --- a/e2etests/testdata/stable/investigate/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/investigate/elk/sketch.exp.svg @@ -2,7 +2,7 @@ aabbccddllffwwyynniijjkkssuurmeemmmmgghhzzooppqqrrttvvxxabac 123456 + diff --git a/e2etests/testdata/stable/large_arch/dagre/sketch.exp.svg b/e2etests/testdata/stable/large_arch/dagre/sketch.exp.svg index 482b251d0..43b23554c 100644 --- a/e2etests/testdata/stable/large_arch/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/large_arch/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ abcdefghiqrjmnoszaabbeeffggklptuwxyccddv + abcdefghiqrjmnoszaabbeeffggklptuwxyccddv - +abcdefghiqrjmnoszaabbeeffggklptuwxyccddv + thisgoesmultiple lines - +thisgoesmultiple lines + thisgoesmultiple lines - +thisgoesmultiple lines + abcdefghijklmnopqrstuvw - +abcdefghijklmnopqrstuvw + abcdefghijklmnopqrstuvw - +abcdefghijklmnopqrstuvw + abcdefghijklmnopqrstu - +abcdefghijklmnopqrstu + abcdefghijklmnopqrstu - +abcdefghijklmnopqrstu + Foo Baz12hello - +Foo Baz12hello + Foo Baz12hello - +Foo Baz12hello + acdefgbh - +acdefgbh + acdefgbh - +acdefgbh + topabcbottomstartend - +topabcbottomstartend + topabcbottomstartend - +topabcbottomstartend + rootcontainerrootleftrightrootinnerrootinnerleftrightleftright to inner leftto inner rightto inner leftto inner rightto left container rootto right container root - +rootcontainerrootleftrightrootinnerrootinnerleftrightleftright to inner leftto inner rightto inner leftto inner rightto left container rootto right container root + diff --git a/e2etests/testdata/stable/overlapping_image_container_labels/elk/sketch.exp.svg b/e2etests/testdata/stable/overlapping_image_container_labels/elk/sketch.exp.svg index 9505c6dec..137f8af63 100644 --- a/e2etests/testdata/stable/overlapping_image_container_labels/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/overlapping_image_container_labels/elk/sketch.exp.svg @@ -2,7 +2,7 @@ rootcontainerrootleftrightrootinnerrootinnerleftrightleftright to inner leftto inner rightto inner leftto inner rightto left container rootto right container root + diff --git a/e2etests/testdata/stable/p/dagre/sketch.exp.svg b/e2etests/testdata/stable/p/dagre/sketch.exp.svg index 6aba7026c..88d53bc02 100644 --- a/e2etests/testdata/stable/p/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/p/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ xyz hello + xyz hello - +xyz hello + an actor with a really long label that will break everythinganactorwithareallylonglabelthatwillbreakeverythingsimplea short onefar awaywhat if there were no labels between this actor and the previous one shortlong label for testing purposes and it must be really, really longshortthis should span many actors lifelines so we know how it will look like when redering a long label over many actorslong label for testing purposes and it must be really, really long - +an actor with a really long label that will break everythinganactorwithareallylonglabelthatwillbreakeverythingsimplea short onefar awaywhat if there were no labels between this actor and the previous one shortlong label for testing purposes and it must be really, really longshortthis should span many actors lifelines so we know how it will look like when redering a long label over many actorslong label for testing purposes and it must be really, really long + diff --git a/e2etests/testdata/stable/sequence_diagram_actor_distance/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_actor_distance/elk/sketch.exp.svg index f0302fd8e..ede5133f7 100644 --- a/e2etests/testdata/stable/sequence_diagram_actor_distance/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_actor_distance/elk/sketch.exp.svg @@ -2,7 +2,7 @@ an actor with a really long label that will break everythinganactorwithareallylonglabelthatwillbreakeverythingsimplea short onefar awaywhat if there were no labels between this actor and the previous one shortlong label for testing purposes and it must be really, really longshortthis should span many actors lifelines so we know how it will look like when redering a long label over many actorslong label for testing purposes and it must be really, really long + diff --git a/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg index 2b86d5324..27909bcdd 100644 --- a/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ alicebob what does it mean to be well-adjustedThe ability to play bridge or golf as if they were games + alicebob what does it mean to be well-adjustedThe ability to play bridge or golf as if they were games - +alicebob what does it mean to be well-adjustedThe ability to play bridge or golf as if they were games + abcdggggroup 1group bchoonested guy lalaeyokayokaywhat would arnold saythis note - +abcdggggroup 1group bchoonested guy lalaeyokayokaywhat would arnold saythis note + diff --git a/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg index d3ed45a1a..5d32f66da 100644 --- a/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg @@ -2,7 +2,7 @@ abcdggggroup 1group bchoonested guy lalaeyokayokaywhat would arnold saythis note + diff --git a/e2etests/testdata/stable/sequence_diagram_long_note/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_long_note/dagre/sketch.exp.svg index 8cc670b3d..a74340c58 100644 --- a/e2etests/testdata/stable/sequence_diagram_long_note/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_long_note/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ ba a note here to remember that padding must consider notes toojustalongnotehere + ba a note here to remember that padding must consider notes toojustalongnotehere - +ba a note here to remember that padding must consider notes toojustalongnotehere + abjust an actorthis is a message groupaltand this is a nested message groupcase 1case 2case 3case 4what about more nestingcrazy townwhoa a notea note here to remember that padding must consider notes toojustalongnotehere - +abjust an actorthis is a message groupaltand this is a nested message groupcase 1case 2case 3case 4what about more nestingcrazy townwhoa a notea note here to remember that padding must consider notes toojustalongnotehere + diff --git a/e2etests/testdata/stable/sequence_diagram_nested_groups/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_nested_groups/elk/sketch.exp.svg index 48b328e86..ac5400e06 100644 --- a/e2etests/testdata/stable/sequence_diagram_nested_groups/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_nested_groups/elk/sketch.exp.svg @@ -2,7 +2,7 @@ abjust an actorthis is a message groupaltand this is a nested message groupcase 1case 2case 3case 4what about more nestingcrazy townwhoa a notea note here to remember that padding must consider notes toojustalongnotehere + diff --git a/e2etests/testdata/stable/sequence_diagram_nested_span/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_nested_span/dagre/sketch.exp.svg index 9fb361e64..33458b35f 100644 --- a/e2etests/testdata/stable/sequence_diagram_nested_span/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_nested_span/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ scoreritemResponseitemessayRubricconceptitemOutcome + scoreritemResponseitemessayRubricconceptitemOutcome - +scoreritemResponseitemessayRubricconceptitemOutcome + abcd okayexplanationanother explanationSome one who believes imaginary things appear right before your i's.The earth is like a tiny grain of sand, only much, much heavier - +abcd okayexplanationanother explanationSome one who believes imaginary things appear right before your i's.The earth is like a tiny grain of sand, only much, much heavier + abcd okayexplanationanother explanationSome one who believes imaginary things appear right before your i's.The earth is like a tiny grain of sand, only much, much heavier - +abcd okayexplanationanother explanationSome one who believes imaginary things appear right before your i's.The earth is like a tiny grain of sand, only much, much heavier + ab a self edge herebetween actorsto descendantto deeper descendantto parentactor - +ab a self edge herebetween actorsto descendantto deeper descendantto parentactor + diff --git a/e2etests/testdata/stable/sequence_diagram_self_edges/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_self_edges/elk/sketch.exp.svg index f947663cd..05991a5af 100644 --- a/e2etests/testdata/stable/sequence_diagram_self_edges/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_self_edges/elk/sketch.exp.svg @@ -2,7 +2,7 @@ ab a self edge herebetween actorsto descendantto deeper descendantto parentactor + diff --git a/e2etests/testdata/stable/sequence_diagram_simple/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_simple/dagre/sketch.exp.svg index d0e6006a2..721c2e0cc 100644 --- a/e2etests/testdata/stable/sequence_diagram_simple/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_simple/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ AlicelinebreakerBobdbqueueanoddservicewithanameinmultiple lines Authentication Requestmake request for something that is quite far away and requires a really long label to take all the space between the objectsvalidate credentialsAuthentication ResponseAnother authentication Requestdo it later storedAnother authentication Response + diff --git a/e2etests/testdata/stable/sequence_diagram_simple/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_simple/elk/sketch.exp.svg index d0e6006a2..721c2e0cc 100644 --- a/e2etests/testdata/stable/sequence_diagram_simple/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_simple/elk/sketch.exp.svg @@ -2,7 +2,7 @@ AlicelinebreakerBobdbqueueanoddservicewithanameinmultiple lines Authentication Requestmake request for something that is quite far away and requires a really long label to take all the space between the objectsvalidate credentialsAuthentication ResponseAnother authentication Requestdo it later storedAnother authentication Response + diff --git a/e2etests/testdata/stable/sequence_diagram_span/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_span/dagre/sketch.exp.svg index aa3321ec2..5051557e6 100644 --- a/e2etests/testdata/stable/sequence_diagram_span/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_span/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ scoreritemResponseitemessayRubricconceptitemOutcome getItem() itemgetRubric()rubricapplyTo(essayResp)match(essayResponse)scorenewgetNormalMinimum()getNormalMaximum()setScore(score)setFeedback(missingConcepts) + diff --git a/e2etests/testdata/stable/sequence_diagram_span/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_span/elk/sketch.exp.svg index aa3321ec2..5051557e6 100644 --- a/e2etests/testdata/stable/sequence_diagram_span/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagram_span/elk/sketch.exp.svg @@ -2,7 +2,7 @@ scoreritemResponseitemessayRubricconceptitemOutcome getItem() itemgetRubric()rubricapplyTo(essayResp)match(essayResponse)scorenewgetNormalMinimum()getNormalMaximum()setScore(score)setFeedback(missingConcepts) + diff --git a/e2etests/testdata/stable/sequence_diagrams/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagrams/dagre/sketch.exp.svg index db69a01ce..9a99476af 100644 --- a/e2etests/testdata/stable/sequence_diagrams/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagrams/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ a_shapea_sequenceanotherfinallysequencesequencesequencescoreritemResponseitemessayRubricconceptitemOutcomescorerconceptessayRubricitemitemOutcomeitemResponsescoreritemResponseitemessayRubricconceptitemOutcome getItem()itemgetRubric()rubricapplyTo(essayResp)match(essayResponse)scorenewgetNormalMinimum()getNormalMaximum()setScore(score)setFeedback(missingConcepts)getItem()itemgetRubric()rubricapplyTo(essayResp)match(essayResponse)scorenewgetNormalMinimum()getNormalMaximum()setScore(score)setFeedback(missingConcepts) + diff --git a/e2etests/testdata/stable/sequence_diagrams/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagrams/elk/sketch.exp.svg index 7d5445201..88ed06650 100644 --- a/e2etests/testdata/stable/sequence_diagrams/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sequence_diagrams/elk/sketch.exp.svg @@ -2,7 +2,7 @@ a_shapea_sequenceanotherfinallysequencesequencesequencescoreritemResponseitemessayRubricconceptitemOutcomescorerconceptessayRubricitemitemOutcomeitemResponsescoreritemResponseitemessayRubricconceptitemOutcome getItem()itemgetRubric()rubricapplyTo(essayResp)match(essayResponse)scorenewgetNormalMinimum()getNormalMaximum()setScore(score)setFeedback(missingConcepts)getItem()itemgetRubric()rubricapplyTo(essayResp)match(essayResponse)scorenewgetNormalMinimum()getNormalMaximum()setScore(score)setFeedback(missingConcepts) + diff --git a/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg b/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg index 8b78b0f66..07e5d089c 100644 --- a/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ acbl1l2c1l2c3l2c2l3c1l3c2l4bacacbabcc1c2c3abc + acbl1l2c1l2c3l2c2l3c1l3c2l4bacacbabcc1c2c3abc - +acbl1l2c1l2c3l2c2l3c1l3c2l4bacacbabcc1c2c3abc + -cube - +cube + -cube - +cube + AKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTND - +AKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTND + AKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTND - +AKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTND + containerfirstsecond 1->2c->2 - +containerfirstsecond 1->2c->2 + containerfirstsecond 1->2c->2 - +containerfirstsecond 1->2c->2 + ninety ninesixty fourthirty twosixteeneight - +ninety ninesixty fourthirty twosixteeneight + ninety ninesixty fourthirty twosixteeneight - +ninety ninesixty fourthirty twosixteeneight + eightsixteenthirty twosixty fourninety nine twelvetwenty fourforty eighteighty one - +eightsixteenthirty twosixty fourninety nine twelvetwenty fourforty eighteighty one + diff --git a/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg b/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg index f1d7952c3..c6f123554 100644 --- a/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg +++ b/e2etests/testdata/todo/font_sizes_large/elk/sketch.exp.svg @@ -2,7 +2,7 @@ eightsixteenthirty twosixty fourninety nine twelvetwenty fourforty eighteighty one + diff --git a/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg b/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg index 5bcd47f78..532a8245a 100644 --- a/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg +++ b/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ bacthis is a message groupand this is a nested message groupwhat about more nestingyoyo + diff --git a/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/elk/sketch.exp.svg b/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/elk/sketch.exp.svg index 5bcd47f78..532a8245a 100644 --- a/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/elk/sketch.exp.svg +++ b/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/elk/sketch.exp.svg @@ -2,7 +2,7 @@ bacthis is a message groupand this is a nested message groupwhat about more nestingyoyo + diff --git a/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg b/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg index c63fc847c..b6fa3ca79 100644 --- a/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg +++ b/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ ab Thereoncewasaverytalledgelabel + ab Thereoncewasaverytalledgelabel - +ab Thereoncewasaverytalledgelabel + abcdghef + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/crow_foot_arrowhead/elk/board.exp.json b/e2etests/testdata/stable/crow_foot_arrowhead/elk/board.exp.json new file mode 100644 index 000000000..f4b918447 --- /dev/null +++ b/e2etests/testdata/stable/crow_foot_arrowhead/elk/board.exp.json @@ -0,0 +1,484 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "", + "pos": { + "x": 12, + "y": 12 + }, + "width": 113, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "", + "pos": { + "x": 12, + "y": 238 + }, + "width": 113, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "", + "pos": { + "x": 145, + "y": 12 + }, + "width": 113, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "d", + "type": "", + "pos": { + "x": 145, + "y": 238 + }, + "width": 114, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 14, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "g", + "type": "", + "pos": { + "x": 278, + "y": 12 + }, + "width": 114, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "g", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 14, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "h", + "type": "", + "pos": { + "x": 279, + "y": 238 + }, + "width": 113, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "h", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "", + "pos": { + "x": 412, + "y": 12 + }, + "width": 113, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "e", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "", + "pos": { + "x": 413, + "y": 238 + }, + "width": 111, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "f", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 11, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a <-> b)[0]", + "src": "a", + "srcArrow": "cf-many", + "srcLabel": "", + "dst": "b", + "dstArrow": "cf-many", + "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": 68.5, + "y": 138 + }, + { + "x": 68.5, + "y": 238 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c <-> d)[0]", + "src": "c", + "srcArrow": "cf-many-required", + "srcLabel": "", + "dst": "d", + "dstArrow": "cf-many-required", + "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": 202, + "y": 138 + }, + { + "x": 202, + "y": 238 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(g <-> h)[0]", + "src": "g", + "srcArrow": "cf-one", + "srcLabel": "", + "dst": "h", + "dstArrow": "cf-one", + "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": 335.5, + "y": 138 + }, + { + "x": 335.5, + "y": 238 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e <-> f)[0]", + "src": "e", + "srcArrow": "cf-one-required", + "srcLabel": "", + "dst": "f", + "dstArrow": "cf-one-required", + "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": 469, + "y": 138 + }, + { + "x": 469, + "y": 238 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/stable/crow_foot_arrowhead/elk/sketch.exp.svg b/e2etests/testdata/stable/crow_foot_arrowhead/elk/sketch.exp.svg new file mode 100644 index 000000000..083eed231 --- /dev/null +++ b/e2etests/testdata/stable/crow_foot_arrowhead/elk/sketch.exp.svg @@ -0,0 +1,31 @@ + +abcdghef + + + \ No newline at end of file From 405fdbe57f65ca419167226576f73139053dc355 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sat, 31 Dec 2022 12:17:05 -0800 Subject: [PATCH 44/67] don't add appendix seperator without appendix --- d2renderers/d2svg/appendix/appendix.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/d2renderers/d2svg/appendix/appendix.go b/d2renderers/d2svg/appendix/appendix.go index 47e7a7ba1..7237075ab 100644 --- a/d2renderers/d2svg/appendix/appendix.go +++ b/d2renderers/d2svg/appendix/appendix.go @@ -153,6 +153,9 @@ func generateAppendix(diagram *d2target.Diagram, ruler *textmeasure.Ruler, svg s } } } + if len(lines) == 0 { + return "", 0, 0 + } totalHeight += SPACER return fmt.Sprintf(`%s From 2b2c9120802b358eb637cd0b27f47a51519ea272 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sat, 31 Dec 2022 12:17:52 -0800 Subject: [PATCH 45/67] changelog --- ci/release/changelogs/next.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f3c0d2a77..dc555bd02 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -3,3 +3,5 @@ #### Improvements 🧹 #### Bugfixes ⛑️ + +- Appendix seperator line no longer added to PNG export when appendix doesn't exist. [#582](https://github.com/terrastruct/d2/pull/582) From e2c8b19af9f356846a9d4f1485f13fbb4debcc63 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sat, 31 Dec 2022 15:21:37 -0800 Subject: [PATCH 46/67] ignore empty text --- d2graph/d2graph.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 7bd59ec6a..5ecb1b7ad 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -980,6 +980,9 @@ func (e *Edge) initIndex() { } func findMeasured(mtexts []*d2target.MText, t1 *d2target.MText) *d2target.TextDimensions { + if strings.TrimSpace(t1.Text) == "" { + return d2target.NewTextDimensions(0, 0) + } for i, t2 := range mtexts { if t1.Text != t2.Text { continue From de0cf47016492f9334f1a50b7dd9ba55d996b35a Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sat, 31 Dec 2022 15:50:42 -0800 Subject: [PATCH 47/67] default size for no text --- d2graph/d2graph.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 5ecb1b7ad..d0d965f7e 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -981,7 +981,7 @@ func (e *Edge) initIndex() { func findMeasured(mtexts []*d2target.MText, t1 *d2target.MText) *d2target.TextDimensions { if strings.TrimSpace(t1.Text) == "" { - return d2target.NewTextDimensions(0, 0) + return d2target.NewTextDimensions(100, 100) } for i, t2 := range mtexts { if t1.Text != t2.Text { From e8a56bda519a0af3f0cdd6b096dc2f49f7aca207 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sat, 31 Dec 2022 15:54:50 -0800 Subject: [PATCH 48/67] move --- d2graph/d2graph.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index d0d965f7e..61ebbb722 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -980,9 +980,6 @@ func (e *Edge) initIndex() { } func findMeasured(mtexts []*d2target.MText, t1 *d2target.MText) *d2target.TextDimensions { - if strings.TrimSpace(t1.Text) == "" { - return d2target.NewTextDimensions(100, 100) - } for i, t2 := range mtexts { if t1.Text != t2.Text { continue @@ -1001,6 +998,9 @@ func findMeasured(mtexts []*d2target.MText, t1 *d2target.MText) *d2target.TextDi } return &mtexts[i].Dimensions } + if strings.TrimSpace(t1.Text) == "" { + return d2target.NewTextDimensions(100, 100) + } return nil } From c04fcc920fc9c1d630310d5744e21a0a24dfb57a Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sat, 31 Dec 2022 15:59:07 -0800 Subject: [PATCH 49/67] update --- d2graph/d2graph.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 61ebbb722..3b8491e75 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -998,9 +998,6 @@ func findMeasured(mtexts []*d2target.MText, t1 *d2target.MText) *d2target.TextDi } return &mtexts[i].Dimensions } - if strings.TrimSpace(t1.Text) == "" { - return d2target.NewTextDimensions(100, 100) - } return nil } @@ -1017,6 +1014,10 @@ func getMarkdownDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler, t return d2target.NewTextDimensions(width, height), nil } + if strings.TrimSpace(t.Text) == "" { + return d2target.NewTextDimensions(100, 100), nil + } + return nil, fmt.Errorf("text not pre-measured and no ruler provided") } From 87f0cc0cfef8be00e9645500e9c66e364f233980 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 1 Jan 2023 01:34:03 -0800 Subject: [PATCH 50/67] fix --- d2graph/d2graph.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 3b8491e75..10e43dcdf 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1014,10 +1014,6 @@ func getMarkdownDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler, t return d2target.NewTextDimensions(width, height), nil } - if strings.TrimSpace(t.Text) == "" { - return d2target.NewTextDimensions(100, 100), nil - } - return nil, fmt.Errorf("text not pre-measured and no ruler provided") } @@ -1071,6 +1067,19 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler if obj.Attributes.Height != nil { desiredHeight, _ = strconv.Atoi(obj.Attributes.Height.Value) } + + if obj.Attributes.Label.Value == "" && obj.Attributes.Shape.Value != d2target.ShapeImage { + obj.Width = DEFAULT_SHAPE_PADDING + obj.Height = DEFAULT_SHAPE_PADDING + if desiredWidth != 0 { + obj.Width = float64(desiredWidth) + } + if desiredHeight != 0 { + obj.Height = float64(desiredHeight) + } + continue + } + shapeType := strings.ToLower(obj.Attributes.Shape.Value) labelDims, err := obj.GetLabelSize(mtexts, ruler, fontFamily) From e4bbd3200a1dfd967598e61504b1ab09d07fffdf Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 1 Jan 2023 01:39:58 -0800 Subject: [PATCH 51/67] test --- .../dagre/board.exp.json | 94 +++++++++---------- .../dagre/sketch.exp.svg | 52 +++++----- .../elk/board.exp.json | 78 +++++++-------- .../elk/sketch.exp.svg | 52 +++++----- .../unnamed_only_height/dagre/board.exp.json | 90 +++++++++--------- .../unnamed_only_height/dagre/sketch.exp.svg | 52 +++++----- .../unnamed_only_height/elk/board.exp.json | 74 +++++++-------- .../unnamed_only_height/elk/sketch.exp.svg | 52 +++++----- .../unnamed_only_width/dagre/board.exp.json | 88 ++++++++--------- .../unnamed_only_width/dagre/sketch.exp.svg | 52 +++++----- .../unnamed_only_width/elk/board.exp.json | 72 +++++++------- .../unnamed_only_width/elk/sketch.exp.svg | 52 +++++----- 12 files changed, 404 insertions(+), 404 deletions(-) diff --git a/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json b/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json index 2d10adc2e..c01b08b63 100644 --- a/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json +++ b/e2etests/testdata/regression/unnamed_class_table_code/dagre/board.exp.json @@ -6,11 +6,11 @@ "id": "class", "type": "class", "pos": { - "x": 0, + "x": 48, "y": 0 }, - "width": 422, - "height": 368, + "width": 100, + "height": 100, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -80,11 +80,11 @@ "id": "users", "type": "sql_table", "pos": { - "x": 107, - "y": 468 + "x": 48, + "y": 200 }, - "width": 208, - "height": 186, + "width": 100, + "height": 100, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -112,8 +112,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 15, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "type": { "label": "int", @@ -124,8 +124,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 23, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "constraint": "", "reference": "" @@ -140,8 +140,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 47, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "type": { "label": "string", @@ -152,8 +152,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 48, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "constraint": "", "reference": "" @@ -168,8 +168,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 47, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "type": { "label": "string", @@ -180,8 +180,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 48, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "constraint": "", "reference": "" @@ -196,8 +196,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 80, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "type": { "label": "string", @@ -208,8 +208,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 48, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "constraint": "", "reference": "" @@ -224,8 +224,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 81, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "type": { "label": "datetime", @@ -236,8 +236,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 77, - "labelHeight": 26 + "labelWidth": 0, + "labelHeight": 0 }, "constraint": "", "reference": "" @@ -251,8 +251,8 @@ "italic": false, "bold": true, "underline": false, - "labelWidth": 59, - "labelHeight": 31, + "labelWidth": 0, + "labelHeight": 0, "zIndex": 0, "level": 1, "primaryAccentColor": "#0D32B2", @@ -263,8 +263,8 @@ "id": "code", "type": "code", "pos": { - "x": 113, - "y": 754 + "x": 0, + "y": 400 }, "width": 196, "height": 70, @@ -326,20 +326,20 @@ "labelPercentage": 0, "route": [ { - "x": 211, - "y": 368 + "x": 98, + "y": 100 }, { - "x": 211, - "y": 408 + "x": 98, + "y": 140 }, { - "x": 211, - "y": 428 + "x": 98, + "y": 160 }, { - "x": 211, - "y": 468 + "x": 98, + "y": 200 } ], "isCurve": true, @@ -374,20 +374,20 @@ "labelPercentage": 0, "route": [ { - "x": 211, - "y": 654 + "x": 98, + "y": 300 }, { - "x": 211, - "y": 694 + "x": 98, + "y": 340 }, { - "x": 211, - "y": 714 + "x": 98, + "y": 360 }, { - "x": 211, - "y": 754 + "x": 98, + "y": 400 } ], "isCurve": true, diff --git a/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg b/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg index 0c32095a8..426680010 100644 --- a/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ - +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + - -num -int- -timeout -int- -pid -+ -getStatus() -Enum+ -getJobs() -Job[]+ -setTimeout(seconds int) -voidid -int -name -string -email -string -password -string -last_login -datetime -:= 5 +- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +voidid +int +name +string +email +string +password +string +last_login +datetime +:= 5 := a + 7 -fmt.Printf("%d", b) - +fmt.Printf("%d", b) + abcdghef - +abcdfghe + abcdghef - +abcdfghe + `) } +//go:embed fitToScreen.js +var fitToScreenScript string + // TODO minify output at end func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { var sketchRunner *d2sketch.Runner @@ -1124,6 +1127,8 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { ]]> `, styleCSS, styleCSS2)) + buf.WriteString(fmt.Sprintf(``, fitToScreenScript)) + hasMarkdown := false for _, s := range diagram.Shapes { if s.Label != "" && s.Type == d2target.ShapeText { diff --git a/d2renderers/d2svg/fitToScreen.js b/d2renderers/d2svg/fitToScreen.js new file mode 100644 index 000000000..98a3272bd --- /dev/null +++ b/d2renderers/d2svg/fitToScreen.js @@ -0,0 +1,19 @@ +window.addEventListener("DOMContentLoaded", () => { + const svgEl = document.querySelector("svg"); + let width = parseInt(svgEl.getAttribute("width"), 10); + let height = parseInt(svgEl.getAttribute("height"), 10); + let ratio; + if (width > height) { + if (width > window.innerWidth) { + ratio = window.innerWidth / width; + } + } else if (height > window.innerHeight) { + ratio = window.innerHeight / height; + } + // Scale svg fit to zoom + if (ratio) { + // body padding is 8px + svgEl.setAttribute("width", width * ratio - 16); + svgEl.setAttribute("height", height * ratio - 16); + } +}); diff --git a/static/watch.js b/static/watch.js index 0ebeddeeb..0034b2fe3 100644 --- a/static/watch.js +++ b/static/watch.js @@ -11,6 +11,7 @@ function init(reconnectDelay) { const ws = new WebSocket( `ws://${window.location.host}${window.location.pathname}watch` ); + let isInit = true; ws.onopen = () => { reconnectDelay = 1000; console.info("watch websocket opened"); @@ -32,22 +33,25 @@ function init(reconnectDelay) { // out the width, height and viewbox out of the top level SVG tag and update those manually. d2SVG.innerHTML = msg.svg; - const svgEl = d2SVG.querySelector("svg"); - let width = parseInt(svgEl.getAttribute("width"), 10); - let height = parseInt(svgEl.getAttribute("height"), 10); - let ratio; - if (width > height) { - if (width > window.innerWidth) { - ratio = window.innerWidth / width; + if (isInit) { + const svgEl = d2SVG.querySelector("svg"); + let width = parseInt(svgEl.getAttribute("width"), 10); + let height = parseInt(svgEl.getAttribute("height"), 10); + let ratio; + if (width > height) { + if (width > window.innerWidth) { + ratio = window.innerWidth / width; + } + } else if (height > window.innerHeight) { + ratio = window.innerHeight / height; } - } else if (height > window.innerHeight) { - ratio = window.innerHeight / height; - } - // Scale svg fit to zoom - if (ratio) { - // body padding is 8px - svgEl.setAttribute("width", width * ratio - 16); - svgEl.setAttribute("height", height * ratio - 16); + // Scale svg fit to zoom + if (ratio) { + // body padding is 8px + svgEl.setAttribute("width", width * ratio - 16); + svgEl.setAttribute("height", height * ratio - 16); + } + isInit = false; } d2ErrDiv.style.display = "none"; From 421b22c10657140cdfe3f2023f6de5a5240071f0 Mon Sep 17 00:00:00 2001 From: Bernard Xie Date: Tue, 3 Jan 2023 11:29:06 -0800 Subject: [PATCH 57/67] add to changelog --- ci/release/changelogs/next.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 272cd726b..27eb33bdc 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,10 +1,11 @@ #### Features 🚀 - Crow foot notation is now supported. [#578](https://github.com/terrastruct/d2/pull/578) +- Exported SVGs also fit to screen on open. [#601](https://github.com/terrastruct/d2/pull/601) #### Improvements 🧹 #### Bugfixes ⛑️ - Appendix seperator line no longer added to PNG export when appendix doesn't exist. [#582](https://github.com/terrastruct/d2/pull/582) -- Watch mode only fits to screen on initial load. [#582](https://github.com/terrastruct/d2/pull/582) +- Watch mode only fits to screen on initial load. [#601](https://github.com/terrastruct/d2/pull/601) From 1dc45b64a6b10c4a8dfd2a8f867779e58e44b116 Mon Sep 17 00:00:00 2001 From: Bernard Xie Date: Tue, 3 Jan 2023 11:45:16 -0800 Subject: [PATCH 58/67] preserve ratio on subsequent renders --- static/watch.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/static/watch.js b/static/watch.js index 0034b2fe3..6f89b7ac4 100644 --- a/static/watch.js +++ b/static/watch.js @@ -12,6 +12,7 @@ function init(reconnectDelay) { `ws://${window.location.host}${window.location.pathname}watch` ); let isInit = true; + let ratio; ws.onopen = () => { reconnectDelay = 1000; console.info("watch websocket opened"); @@ -33,11 +34,10 @@ function init(reconnectDelay) { // out the width, height and viewbox out of the top level SVG tag and update those manually. d2SVG.innerHTML = msg.svg; + const svgEl = d2SVG.querySelector("svg"); + let width = parseInt(svgEl.getAttribute("width"), 10); + let height = parseInt(svgEl.getAttribute("height"), 10); if (isInit) { - const svgEl = d2SVG.querySelector("svg"); - let width = parseInt(svgEl.getAttribute("width"), 10); - let height = parseInt(svgEl.getAttribute("height"), 10); - let ratio; if (width > height) { if (width > window.innerWidth) { ratio = window.innerWidth / width; @@ -46,13 +46,13 @@ function init(reconnectDelay) { ratio = window.innerHeight / height; } // Scale svg fit to zoom - if (ratio) { - // body padding is 8px - svgEl.setAttribute("width", width * ratio - 16); - svgEl.setAttribute("height", height * ratio - 16); - } isInit = false; } + if (ratio) { + // body padding is 8px + svgEl.setAttribute("width", width * ratio - 16); + svgEl.setAttribute("height", height * ratio - 16); + } d2ErrDiv.style.display = "none"; } From 296b6407e9af8c9201edfca8be9264c5c077858b Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Tue, 3 Jan 2023 14:13:29 -0800 Subject: [PATCH 59/67] lib/version/version.go: Update --- lib/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version/version.go b/lib/version/version.go index e53cd0de2..3eabc3238 100644 --- a/lib/version/version.go +++ b/lib/version/version.go @@ -1,4 +1,4 @@ package version // Pre-built binaries will have version set correctly during build time. -var Version = "v0.1.2-HEAD" +var Version = "v0.1.4-HEAD" From 070b50a6e22de5c0460622794b8ccedffcef7be2 Mon Sep 17 00:00:00 2001 From: Bernard Xie Date: Tue, 3 Jan 2023 14:44:36 -0800 Subject: [PATCH 60/67] add check to only run script on root svg --- d2renderers/d2svg/fitToScreen.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/d2renderers/d2svg/fitToScreen.js b/d2renderers/d2svg/fitToScreen.js index 98a3272bd..d753cf163 100644 --- a/d2renderers/d2svg/fitToScreen.js +++ b/d2renderers/d2svg/fitToScreen.js @@ -1,5 +1,10 @@ window.addEventListener("DOMContentLoaded", () => { const svgEl = document.querySelector("svg"); + const svgID = "d2-svg"; + svgEl.setAttribute("id", svgID); + if (document.documentElement.getAttribute("id") !== svgID) { + return; + } let width = parseInt(svgEl.getAttribute("width"), 10); let height = parseInt(svgEl.getAttribute("height"), 10); let ratio; @@ -10,9 +15,7 @@ window.addEventListener("DOMContentLoaded", () => { } else if (height > window.innerHeight) { ratio = window.innerHeight / height; } - // Scale svg fit to zoom if (ratio) { - // body padding is 8px svgEl.setAttribute("width", width * ratio - 16); svgEl.setAttribute("height", height * ratio - 16); } From 5b4a20a6c67a2695af1e81cbe88b54ba64ccae1d Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Tue, 3 Jan 2023 14:48:23 -0800 Subject: [PATCH 61/67] d2plugin: Dedup plugins array Closes #590 --- d2plugin/exec.go | 14 +++++--- d2plugin/plugin.go | 83 +++++++++++++++++++++++----------------------- help.go | 62 ++++++++++++++++++---------------- main.go | 33 +++++++++++------- 4 files changed, 106 insertions(+), 86 deletions(-) diff --git a/d2plugin/exec.go b/d2plugin/exec.go index efbfcd970..b76a802d0 100644 --- a/d2plugin/exec.go +++ b/d2plugin/exec.go @@ -40,9 +40,10 @@ import ( type execPlugin struct { path string opts map[string]string + info *PluginInfo } -func (p execPlugin) Flags(ctx context.Context) (_ []PluginSpecificFlag, err error) { +func (p *execPlugin) Flags(ctx context.Context) (_ []PluginSpecificFlag, err error) { ctx, cancel := context.WithTimeout(ctx, time.Second*10) defer cancel() cmd := exec.CommandContext(ctx, p.path, "flags") @@ -92,7 +93,11 @@ func (p *execPlugin) HydrateOpts(opts []byte) error { return nil } -func (p execPlugin) Info(ctx context.Context) (_ *PluginInfo, err error) { +func (p *execPlugin) Info(ctx context.Context) (_ *PluginInfo, err error) { + if p.info != nil { + return p.info, nil + } + ctx, cancel := context.WithTimeout(ctx, time.Second*10) defer cancel() cmd := exec.CommandContext(ctx, p.path, "info") @@ -114,10 +119,11 @@ func (p execPlugin) Info(ctx context.Context) (_ *PluginInfo, err error) { return nil, fmt.Errorf("failed to unmarshal json: %w", err) } + p.info = &info return &info, nil } -func (p execPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { +func (p *execPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() @@ -152,7 +158,7 @@ func (p execPlugin) Layout(ctx context.Context, g *d2graph.Graph) error { return nil } -func (p execPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { +func (p *execPlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) { ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() diff --git a/d2plugin/plugin.go b/d2plugin/plugin.go index 25eee8d08..a6eefdf7e 100644 --- a/d2plugin/plugin.go +++ b/d2plugin/plugin.go @@ -80,36 +80,54 @@ type PluginInfo struct { const binaryPrefix = "d2plugin-" -func ListPlugins(ctx context.Context) ([]*PluginInfo, error) { +func ListPlugins(ctx context.Context) ([]Plugin, error) { // 1. Run Info on all bundled plugins in the global plugins array. // - set Type for each bundled plugin to "bundled". // 2. Iterate through directories in $PATH and look for executables within these // directories with the prefix d2plugin-* // 3. Run each plugin binary with the argument info. e.g. d2plugin-dagre info - var infoSlice []*PluginInfo - - for _, p := range plugins { - info, err := p.Info(ctx) - if err != nil { - return nil, err - } - info.Type = "bundled" - infoSlice = append(infoSlice, info) - } + var ps []Plugin + ps = append(ps, plugins...) matches, err := xexec.SearchPath(binaryPrefix) if err != nil { return nil, err } +BINARY_PLUGINS_LOOP: for _, path := range matches { p := &execPlugin{path: path} info, err := p.Info(ctx) if err != nil { return nil, err } - info.Type = "binary" - info.Path = path + for _, p2 := range ps { + info2, err := p2.Info(ctx) + if err != nil { + return nil, err + } + if info.Name == info2.Name { + continue BINARY_PLUGINS_LOOP + } + } + ps = append(ps, p) + } + return ps, nil +} + +func ListPluginInfos(ctx context.Context, ps []Plugin) ([]*PluginInfo, error) { + var infoSlice []*PluginInfo + for _, p := range ps { + info, err := p.Info(ctx) + if err != nil { + return nil, err + } + if ep, ok := p.(*execPlugin); ok { + info.Type = "binary" + info.Path = ep.path + } else { + info.Type = "bundled" + } infoSlice = append(infoSlice, info) } @@ -123,41 +141,22 @@ func ListPlugins(ctx context.Context) ([]*PluginInfo, error) { // **NOTE** When D2 upgrades to go 1.19, remember to ignore exec.ErrDot // 3. If such a binary is found, it builds an execPlugin in exec.go // to get a plugin implementation around the binary and returns it. -func FindPlugin(ctx context.Context, name string) (Plugin, string, error) { - for _, p := range plugins { +func FindPlugin(ctx context.Context, ps []Plugin, name string) (Plugin, error) { + for _, p := range ps { info, err := p.Info(ctx) - if err != nil { - return nil, "", err - } - if info.Name == name { - return p, "", nil - } - } - - path, err := exec.LookPath(binaryPrefix + name) - if err != nil { - return nil, "", err - } - - return &execPlugin{path: path}, path, nil -} - -func ListPluginFlags(ctx context.Context) ([]PluginSpecificFlag, error) { - var out []PluginSpecificFlag - for _, p := range plugins { - flags, err := p.Flags(ctx) if err != nil { return nil, err } - out = append(out, flags...) + if info.Name == name { + return p, nil + } } + return nil, exec.ErrNotFound +} - matches, err := xexec.SearchPath(binaryPrefix) - if err != nil { - return nil, err - } - for _, path := range matches { - p := &execPlugin{path: path} +func ListPluginFlags(ctx context.Context, ps []Plugin) ([]PluginSpecificFlag, error) { + var out []PluginSpecificFlag + for _, p := range ps { flags, err := p.Flags(ctx) if err != nil { return nil, err diff --git a/help.go b/help.go index 27f9bc22c..3efa76b02 100644 --- a/help.go +++ b/help.go @@ -39,23 +39,23 @@ See more docs and the source code at https://oss.terrastruct.com/d2 `, filepath.Base(ms.Name), ms.Opts.Defaults()) } -func layoutCmd(ctx context.Context, ms *xmain.State) error { +func layoutCmd(ctx context.Context, ms *xmain.State, ps []d2plugin.Plugin) error { if len(ms.Opts.Flags.Args()) == 1 { - return shortLayoutHelp(ctx, ms) + return shortLayoutHelp(ctx, ms, ps) } else if len(ms.Opts.Flags.Args()) == 2 { - return longLayoutHelp(ctx, ms) + return longLayoutHelp(ctx, ms, ps) } else { - return pluginSubcommand(ctx, ms) + return pluginSubcommand(ctx, ms, ps) } } -func shortLayoutHelp(ctx context.Context, ms *xmain.State) error { +func shortLayoutHelp(ctx context.Context, ms *xmain.State, ps []d2plugin.Plugin) error { var pluginLines []string - plugins, err := d2plugin.ListPlugins(ctx) + pinfos, err := d2plugin.ListPluginInfos(ctx, ps) if err != nil { return err } - for _, p := range plugins { + for _, p := range pinfos { var l string if p.Type == "bundled" { l = fmt.Sprintf("%s (bundled) - %s", p.Name, p.ShortHelp) @@ -82,40 +82,43 @@ See more docs at https://oss.terrastruct.com/d2 return nil } -func longLayoutHelp(ctx context.Context, ms *xmain.State) error { +func longLayoutHelp(ctx context.Context, ms *xmain.State, ps []d2plugin.Plugin) error { layout := ms.Opts.Flags.Arg(1) - plugin, path, err := d2plugin.FindPlugin(ctx, layout) - if errors.Is(err, exec.ErrNotFound) { - return layoutNotFound(ctx, layout) + plugin, err := d2plugin.FindPlugin(ctx, ps, layout) + if err != nil { + if errors.Is(err, exec.ErrNotFound) { + return layoutNotFound(ctx, ps, layout) + } + return err } - pluginLocation := "bundled" - if path != "" { - pluginLocation = fmt.Sprintf("executable plugin at %s", humanPath(path)) - } - - pluginInfo, err := plugin.Info(ctx) + pinfo, err := plugin.Info(ctx) if err != nil { return err } - if !strings.HasSuffix(pluginInfo.LongHelp, "\n") { - pluginInfo.LongHelp += "\n" + plocation := pinfo.Type + if pinfo.Type == "binary" { + plocation = fmt.Sprintf("executable plugin at %s", humanPath(pinfo.Path)) + } + + if !strings.HasSuffix(pinfo.LongHelp, "\n") { + pinfo.LongHelp += "\n" } fmt.Fprintf(ms.Stdout, `%s (%s): -%s`, pluginInfo.Name, pluginLocation, pluginInfo.LongHelp) +%s`, pinfo.Name, plocation, pinfo.LongHelp) return nil } -func layoutNotFound(ctx context.Context, layout string) error { - var names []string - plugins, err := d2plugin.ListPlugins(ctx) +func layoutNotFound(ctx context.Context, ps []d2plugin.Plugin, layout string) error { + pinfos, err := d2plugin.ListPluginInfos(ctx, ps) if err != nil { return err } - for _, p := range plugins { + var names []string + for _, p := range pinfos { names = append(names, p.Name) } @@ -126,11 +129,14 @@ For more information on setup, please visit https://github.com/terrastruct/d2.`, layout, strings.Join(names, ", ")) } -func pluginSubcommand(ctx context.Context, ms *xmain.State) error { +func pluginSubcommand(ctx context.Context, ms *xmain.State, ps []d2plugin.Plugin) error { layout := ms.Opts.Flags.Arg(1) - plugin, _, err := d2plugin.FindPlugin(ctx, layout) - if errors.Is(err, exec.ErrNotFound) { - return layoutNotFound(ctx, layout) + plugin, err := d2plugin.FindPlugin(ctx, ps, layout) + if err != nil { + if errors.Is(err, exec.ErrNotFound) { + return layoutNotFound(ctx, ps, layout) + } + return err } ms.Opts.Args = ms.Opts.Flags.Args()[2:] diff --git a/main.go b/main.go index 78041b71e..646b8c994 100644 --- a/main.go +++ b/main.go @@ -75,7 +75,11 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } - err = populateLayoutOpts(ctx, ms) + ps, err := d2plugin.ListPlugins(ctx) + if err != nil { + return err + } + err = populateLayoutOpts(ctx, ms, ps) if err != nil { return err } @@ -93,7 +97,7 @@ func run(ctx context.Context, ms *xmain.State) (err error) { if len(ms.Opts.Flags.Args()) > 0 { switch ms.Opts.Flags.Arg(0) { case "layout": - return layoutCmd(ctx, ms) + return layoutCmd(ctx, ms, ps) case "fmt": return fmtCmd(ctx, ms) case "version": @@ -142,10 +146,11 @@ func run(ctx context.Context, ms *xmain.State) (err error) { } ms.Log.Debug.Printf("using theme %s (ID: %d)", match.Name, *themeFlag) - plugin, path, err := d2plugin.FindPlugin(ctx, *layoutFlag) - if errors.Is(err, exec.ErrNotFound) { - return layoutNotFound(ctx, *layoutFlag) - } else if err != nil { + plugin, err := d2plugin.FindPlugin(ctx, ps, *layoutFlag) + if err != nil { + if errors.Is(err, exec.ErrNotFound) { + return layoutNotFound(ctx, ps, *layoutFlag) + } return err } @@ -154,11 +159,15 @@ func run(ctx context.Context, ms *xmain.State) (err error) { return err } - pluginLocation := "bundled" - if path != "" { - pluginLocation = fmt.Sprintf("executable plugin at %s", humanPath(path)) + pinfo, err := plugin.Info(ctx) + if err != nil { + return err } - ms.Log.Debug.Printf("using layout plugin %s (%s)", *layoutFlag, pluginLocation) + plocation := pinfo.Type + if pinfo.Type == "binary" { + plocation = fmt.Sprintf("executable plugin at %s", humanPath(pinfo.Path)) + } + ms.Log.Debug.Printf("using layout plugin %s (%s)", *layoutFlag, plocation) var pw png.Playwright if filepath.Ext(outputPath) == ".png" { @@ -299,8 +308,8 @@ func DiscardSlog(ctx context.Context) context.Context { return ctxlog.With(ctx, slog.Make(sloghuman.Sink(io.Discard))) } -func populateLayoutOpts(ctx context.Context, ms *xmain.State) error { - pluginFlags, err := d2plugin.ListPluginFlags(ctx) +func populateLayoutOpts(ctx context.Context, ms *xmain.State, ps []d2plugin.Plugin) error { + pluginFlags, err := d2plugin.ListPluginFlags(ctx, ps) if err != nil { return err } From dfd66232fc0a67388516d2168ac92b45faa0151c Mon Sep 17 00:00:00 2001 From: Bernard Xie Date: Tue, 3 Jan 2023 15:01:21 -0800 Subject: [PATCH 62/67] add d2-svg id on generation --- d2renderers/d2svg/d2svg.go | 1 + d2renderers/d2svg/fitToScreen.js | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 9f5dddbe2..1d9855e9a 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -74,6 +74,7 @@ func setViewbox(writer io.Writer, diagram *d2target.Diagram, pad int) (width int // TODO background stuff. e.g. dotted, grid, colors fmt.Fprintf(writer, ` `, w, h, tl.X-pad, tl.Y-pad, w, h) diff --git a/d2renderers/d2svg/fitToScreen.js b/d2renderers/d2svg/fitToScreen.js index d753cf163..51e6d6ea4 100644 --- a/d2renderers/d2svg/fitToScreen.js +++ b/d2renderers/d2svg/fitToScreen.js @@ -1,10 +1,8 @@ window.addEventListener("DOMContentLoaded", () => { - const svgEl = document.querySelector("svg"); - const svgID = "d2-svg"; - svgEl.setAttribute("id", svgID); - if (document.documentElement.getAttribute("id") !== svgID) { + if (document.documentElement.getAttribute("id") !== "d2-svg") { return; } + const svgEl = document.documentElement; let width = parseInt(svgEl.getAttribute("width"), 10); let height = parseInt(svgEl.getAttribute("height"), 10); let ratio; From 6b3634ec4c6fb683b3bf3ea22115c82558df38d5 Mon Sep 17 00:00:00 2001 From: Bernard Xie Date: Tue, 3 Jan 2023 15:28:51 -0800 Subject: [PATCH 63/67] use different ids --- static/watch.js | 4 ++-- watch.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/static/watch.js b/static/watch.js index 6f89b7ac4..44fff3821 100644 --- a/static/watch.js +++ b/static/watch.js @@ -5,7 +5,7 @@ window.addEventListener("DOMContentLoaded", () => { function init(reconnectDelay) { const d2ErrDiv = window.document.querySelector("#d2-err"); - const d2SVG = window.document.querySelector("#d2-svg"); + const d2SVG = window.document.querySelector("#d2-svg-container"); const devMode = document.body.dataset.d2DevMode === "true"; const ws = new WebSocket( @@ -34,7 +34,7 @@ function init(reconnectDelay) { // out the width, height and viewbox out of the top level SVG tag and update those manually. d2SVG.innerHTML = msg.svg; - const svgEl = d2SVG.querySelector("svg"); + const svgEl = d2SVG.querySelector("#d2-svg"); let width = parseInt(svgEl.getAttribute("width"), 10); let height = parseInt(svgEl.getAttribute("height"), 10); if (isInit) { diff --git a/watch.go b/watch.go index 5bc99e5e3..9263ccfba 100644 --- a/watch.go +++ b/watch.go @@ -430,7 +430,7 @@ func (w *watcher) handleRoot(hw http.ResponseWriter, r *http.Request) { -
+
`, w.outputPath, w.devMode) } From 510e7be5932ca1cdd3cf6f7bd7846731dbcaadf8 Mon Sep 17 00:00:00 2001 From: Bernard Xie Date: Tue, 3 Jan 2023 15:32:31 -0800 Subject: [PATCH 64/67] Add comment --- d2renderers/d2svg/d2svg.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 1d9855e9a..678f0c2ae 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -1128,6 +1128,8 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { ]]> `, styleCSS, styleCSS2)) + // this script won't run in --watch mode because script tags are ignored when added via el.innerHTML = element + // https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML buf.WriteString(fmt.Sprintf(``, fitToScreenScript)) hasMarkdown := false From 35c1a1633f3451385caa32c9cbea40c239068e5a Mon Sep 17 00:00:00 2001 From: Bernard Xie Date: Tue, 3 Jan 2023 16:42:39 -0800 Subject: [PATCH 65/67] add script to tests --- .../testdata/all_shapes/sketch.exp.svg | 23 ++++++++++++++++++- .../d2sketch/testdata/basic/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/child_to_child/sketch.exp.svg | 23 ++++++++++++++++++- .../d2sketch/testdata/class/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/connection_label/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/sql_tables/sketch.exp.svg | 23 ++++++++++++++++++- .../d2sketch/testdata/twitter/sketch.exp.svg | 23 ++++++++++++++++++- .../diagram_wider_than_tooltip/sketch.exp.svg | 23 ++++++++++++++++++- .../appendix/testdata/links/sketch.exp.svg | 23 ++++++++++++++++++- .../tooltip_wider_than_diagram/sketch.exp.svg | 23 ++++++++++++++++++- docs/assets/flow.svg | 1 + docs/examples/chess/dia.svg | 1 + .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre_special_ids/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre_special_ids/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../elk_alignment/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk_alignment/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../regression/elk_order/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../regression/elk_order/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../empty_sequence/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../empty_sequence/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../query_param_escape/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../query_param_escape/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../sql_table_overflow/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../sql_table_overflow/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../sanity/1_to_2/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/sanity/1_to_2/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../sanity/basic/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/sanity/basic/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../child_to_child/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../sanity/child_to_child/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../connection_label/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../connection_label/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../sanity/empty/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/sanity/empty/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/all_shapes/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/all_shapes/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../all_shapes_multiple/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../all_shapes_multiple/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../all_shapes_shadow/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../all_shapes_shadow/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../arrowhead_adjustment/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../arrowhead_adjustment/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../arrowhead_labels/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../arrowhead_labels/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/binary_tree/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/binary_tree/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/chaos1/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/chaos1/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/chaos2/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/chaos2/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../child_parent_edges/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../child_parent_edges/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../circular_dependency/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../circular_dependency/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/class/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/class/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/code_snippet/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/code_snippet/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../connected_container/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../connected_container/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../constant_near_stress/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../constant_near_stress/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../constant_near_title/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../constant_near_title/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../container_edges/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/container_edges/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../crow_foot_arrowhead/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../crow_foot_arrowhead/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/dense/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/dense/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../different_subgraphs/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../different_subgraphs/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/direction/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/direction/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/font_colors/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/font_colors/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/font_sizes/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/font_sizes/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../giant_markdown_test/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../giant_markdown_test/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/hr/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/hr/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/icon-label/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/icon-label/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/images/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/images/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/investigate/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/investigate/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/large_arch/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/large_arch/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/latex/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/latex/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li1/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li1/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li2/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li2/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li3/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li3/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li4/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/li4/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/links/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/links/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/lone_h1/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/lone_h1/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/markdown/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/markdown/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../markdown_stroke_fill/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../markdown_stroke_fill/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../md_2space_newline/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../md_2space_newline/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../md_backslash_newline/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../md_backslash_newline/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../md_code_block_fenced/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../md_code_block_fenced/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../md_code_block_indented/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../md_code_inline/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/md_code_inline/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../multiline_text/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/multiline_text/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../multiple_trees/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/multiple_trees/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/n22_e32/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/n22_e32/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../number_connections/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../number_connections/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../one_container_loop/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../one_container_loop/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/p/dagre/sketch.exp.svg | 23 ++++++++++++++++++- e2etests/testdata/stable/p/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/pre/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/pre/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../self-referencing/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../self-referencing/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../sequence_diagram_note/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../sequence_diagram_real/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../sequence_diagram_span/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../sequence_diagrams/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../sequence_diagrams/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/sql_tables/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/sql_tables/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/square_3d/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/square_3d/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/stylish/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/stylish/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../text_font_sizes/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/text_font_sizes/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/tooltips/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/tooltips/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../transparent_3d/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/transparent_3d/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../unnamed_only_height/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../unnamed_only_height/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../unnamed_only_width/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../unnamed_only_width/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../stable/us_map/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../testdata/stable/us_map/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../container_child_edge/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../container_child_edge/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../font_sizes_large/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../todo/font_sizes_large/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../elk/sketch.exp.svg | 23 ++++++++++++++++++- .../dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../shape_set_width_height/elk/sketch.exp.svg | 23 ++++++++++++++++++- .../todo/tall_edge_label/dagre/sketch.exp.svg | 23 ++++++++++++++++++- .../todo/tall_edge_label/elk/sketch.exp.svg | 23 ++++++++++++++++++- lib/imgbundler/imgbundler_test.go | 2 ++ 211 files changed, 4580 insertions(+), 208 deletions(-) diff --git a/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg b/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg index 5b2e6de56..efb2c8aba 100644 --- a/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/all_shapes/sketch.exp.svg @@ -1,5 +1,6 @@ diff --git a/d2renderers/d2sketch/testdata/basic/sketch.exp.svg b/d2renderers/d2sketch/testdata/basic/sketch.exp.svg index 64dcdfce3..fa9cb40e1 100644 --- a/d2renderers/d2sketch/testdata/basic/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/basic/sketch.exp.svg @@ -1,5 +1,6 @@ diff --git a/d2renderers/d2sketch/testdata/child_to_child/sketch.exp.svg b/d2renderers/d2sketch/testdata/child_to_child/sketch.exp.svg index aefb722c2..c2cd49cfc 100644 --- a/d2renderers/d2sketch/testdata/child_to_child/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/child_to_child/sketch.exp.svg @@ -1,5 +1,6 @@ diff --git a/d2renderers/d2sketch/testdata/class/sketch.exp.svg b/d2renderers/d2sketch/testdata/class/sketch.exp.svg index cd594c963..013a036f7 100644 --- a/d2renderers/d2sketch/testdata/class/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/class/sketch.exp.svg @@ -1,5 +1,6 @@ diff --git a/d2renderers/d2sketch/testdata/connection_label/sketch.exp.svg b/d2renderers/d2sketch/testdata/connection_label/sketch.exp.svg index 87e3a7763..5bc3c0273 100644 --- a/d2renderers/d2sketch/testdata/connection_label/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/connection_label/sketch.exp.svg @@ -1,5 +1,6 @@ diff --git a/d2renderers/d2sketch/testdata/sql_tables/sketch.exp.svg b/d2renderers/d2sketch/testdata/sql_tables/sketch.exp.svg index 809406b67..faf736cb5 100644 --- a/d2renderers/d2sketch/testdata/sql_tables/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/sql_tables/sketch.exp.svg @@ -1,5 +1,6 @@ diff --git a/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg b/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg index ec449734e..3988c521e 100644 --- a/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg @@ -1,5 +1,6 @@ AB AB +AB b +b b +b sql_table_overflowshort +sql_table_overflowshort loooooooooooooooooooong loooooooooooooooooooong short diff --git a/e2etests/testdata/regression/sql_table_overflow/elk/sketch.exp.svg b/e2etests/testdata/regression/sql_table_overflow/elk/sketch.exp.svg index 7693f399d..64d4c4cbd 100644 --- a/e2etests/testdata/regression/sql_table_overflow/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/sql_table_overflow/elk/sketch.exp.svg @@ -1,5 +1,6 @@ sql_table_overflowshort loooooooooooooooooooong loooooooooooooooooooong short diff --git a/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg b/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg index 0c32095a8..fafa910ca 100644 --- a/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/unnamed_class_table_code/dagre/sketch.exp.svg @@ -1,5 +1,6 @@ - num int- timeout diff --git a/e2etests/testdata/regression/unnamed_class_table_code/elk/sketch.exp.svg b/e2etests/testdata/regression/unnamed_class_table_code/elk/sketch.exp.svg index d219cbe58..66bf10875 100644 --- a/e2etests/testdata/regression/unnamed_class_table_code/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/unnamed_class_table_code/elk/sketch.exp.svg @@ -1,5 +1,6 @@ - num int- timeout diff --git a/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg b/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg index 9cd22a917..42f38a32d 100644 --- a/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg +++ b/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg @@ -1,5 +1,6 @@ abc abc +abc ab +ab ab +ab acbd +acbd acbd +acbd ab hello +ab hello ab hello +ab hello + \ No newline at end of file diff --git a/e2etests/testdata/sanity/empty/elk/sketch.exp.svg b/e2etests/testdata/sanity/empty/elk/sketch.exp.svg index 243722dc6..5169c50f1 100644 --- a/e2etests/testdata/sanity/empty/elk/sketch.exp.svg +++ b/e2etests/testdata/sanity/empty/elk/sketch.exp.svg @@ -1,5 +1,6 @@ \ No newline at end of file diff --git a/e2etests/testdata/stable/all_shapes/dagre/sketch.exp.svg b/e2etests/testdata/stable/all_shapes/dagre/sketch.exp.svg index bbd89890d..da44f0f40 100644 --- a/e2etests/testdata/stable/all_shapes/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/all_shapes/dagre/sketch.exp.svg @@ -1,5 +1,6 @@ rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud + diff --git a/e2etests/testdata/stable/all_shapes_shadow/elk/sketch.exp.svg b/e2etests/testdata/stable/all_shapes_shadow/elk/sketch.exp.svg index e015571a5..79f60ba91 100644 --- a/e2etests/testdata/stable/all_shapes_shadow/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/all_shapes_shadow/elk/sketch.exp.svg @@ -1,5 +1,6 @@ diff --git a/e2etests/testdata/stable/arrowhead_adjustment/dagre/sketch.exp.svg b/e2etests/testdata/stable/arrowhead_adjustment/dagre/sketch.exp.svg index 24154ebe5..90796e221 100644 --- a/e2etests/testdata/stable/arrowhead_adjustment/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/arrowhead_adjustment/dagre/sketch.exp.svg @@ -1,5 +1,6 @@ cba * cba * +cba * ab To err is human, to moo bovine1* +ab To err is human, to moo bovine1* ab To err is human, to moo bovine1* +ab To err is human, to moo bovine1* abcdefghijklmno +abcdefghijklmno abcdefghijklmno +abcdefghijklmno aaadddeeebbbccc111 222 +aaadddeeebbbccc111 222 diff --git a/e2etests/testdata/stable/chaos1/elk/sketch.exp.svg b/e2etests/testdata/stable/chaos1/elk/sketch.exp.svg index 70ef81d17..92bf02fae 100644 --- a/e2etests/testdata/stable/chaos1/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/chaos1/elk/sketch.exp.svg @@ -1,5 +1,6 @@ aaadddeeebbbccc111 222 diff --git a/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg b/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg index f7e38128e..ed520ab12 100644 --- a/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/chaos2/dagre/sketch.exp.svg @@ -1,5 +1,6 @@ BatchManager- num int- timeout diff --git a/e2etests/testdata/stable/class/elk/sketch.exp.svg b/e2etests/testdata/stable/class/elk/sketch.exp.svg index c01f11c1f..09edba75b 100644 --- a/e2etests/testdata/stable/class/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/class/elk/sketch.exp.svg @@ -1,5 +1,6 @@ BatchManager- num int- timeout diff --git a/e2etests/testdata/stable/code_snippet/dagre/sketch.exp.svg b/e2etests/testdata/stable/code_snippet/dagre/sketch.exp.svg index 3b5403dde..92e56e53a 100644 --- a/e2etests/testdata/stable/code_snippet/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/code_snippet/dagre/sketch.exp.svg @@ -1,5 +1,6 @@ // RegisterHash registers a function that returns a new instance of the given // hash function. This is intended to be called from the init function in // packages that implement hash functions. func RegisterHash(h Hash, f func() hash.Hash) { diff --git a/e2etests/testdata/stable/code_snippet/elk/sketch.exp.svg b/e2etests/testdata/stable/code_snippet/elk/sketch.exp.svg index 65e487b3b..f26b7ba4a 100644 --- a/e2etests/testdata/stable/code_snippet/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/code_snippet/elk/sketch.exp.svg @@ -1,5 +1,6 @@ // RegisterHash registers a function that returns a new instance of the given // hash function. This is intended to be called from the init function in // packages that implement hash functions. func RegisterHash(h Hash, f func() hash.Hash) { diff --git a/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg b/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg index abf42e09c..7db73b331 100644 --- a/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/connected_container/dagre/sketch.exp.svg @@ -1,5 +1,6 @@ acfbdhg acfbdhg +acfbdhg finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot bacde21345abcde +bacde21345abcde bacde21345abcde +bacde21345abcde alphabeta gamma +alphabeta gamma alphabeta gamma +alphabeta gamma size XSsize Ssize Msize Lsize XLsize XXLsize XXXLcustom 8custom 12custom 18custom 21custom 64 custom 10custom 15custom 48 +size XSsize Ssize Msize Lsize XLsize XXLsize XXXLcustom 8custom 12custom 18custom 21custom 64 custom 10custom 15custom 48 diff --git a/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg b/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg index e3c27605a..2d5f2fe91 100644 --- a/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/font_sizes/elk/sketch.exp.svg @@ -1,5 +1,6 @@ size XSsize Ssize Msize Lsize XLsize XXLsize XXXLcustom 8custom 12custom 18custom 21custom 64 custom 10custom 15custom 48 diff --git a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg index 4029b4315..0072c98ec 100644 --- a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg @@ -1,5 +1,6 @@