...
1
2
3 package d2plugin
4
5 import (
6 "context"
7 "encoding/json"
8 "fmt"
9 "sync"
10
11 "oss.terrastruct.com/d2/d2graph"
12 "oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
13 "oss.terrastruct.com/util-go/xmain"
14 )
15
16 var DagrePlugin = dagrePlugin{}
17
18 func init() {
19 plugins = append(plugins, &DagrePlugin)
20 }
21
22 type dagrePlugin struct {
23 mu sync.Mutex
24 opts *d2dagrelayout.ConfigurableOpts
25 }
26
27 func (p *dagrePlugin) Flags(context.Context) ([]PluginSpecificFlag, error) {
28 return []PluginSpecificFlag{
29 {
30 Name: "dagre-nodesep",
31 Type: "int64",
32 Default: int64(d2dagrelayout.DefaultOpts.NodeSep),
33 Usage: "number of pixels that separate nodes horizontally.",
34 Tag: "nodesep",
35 },
36 {
37 Name: "dagre-edgesep",
38 Type: "int64",
39 Default: int64(d2dagrelayout.DefaultOpts.EdgeSep),
40 Usage: "number of pixels that separate edges horizontally.",
41 Tag: "edgesep",
42 },
43 }, nil
44 }
45
46 func (p *dagrePlugin) HydrateOpts(opts []byte) error {
47 p.mu.Lock()
48 defer p.mu.Unlock()
49 if opts != nil {
50 var dagreOpts d2dagrelayout.ConfigurableOpts
51 err := json.Unmarshal(opts, &dagreOpts)
52 if err != nil {
53 return xmain.UsageErrorf("non-dagre layout options given for dagre")
54 }
55
56 p.opts = &dagreOpts
57 }
58 return nil
59 }
60
61 func (p *dagrePlugin) Info(ctx context.Context) (*PluginInfo, error) {
62 p.mu.Lock()
63 defer p.mu.Unlock()
64 opts := xmain.NewOpts(nil, nil)
65 flags, err := p.Flags(ctx)
66 if err != nil {
67 return nil, err
68 }
69 for _, f := range flags {
70 f.AddToOpts(opts)
71 }
72
73 return &PluginInfo{
74 Name: "dagre",
75 Type: "bundled",
76 Features: []PluginFeature{},
77 ShortHelp: "The directed graph layout library Dagre",
78 LongHelp: fmt.Sprintf(`dagre is a directed graph layout library for JavaScript.
79 See https://d2lang.com/tour/dagre for more.
80
81 Flags correspond to ones found at https://github.com/dagrejs/dagre/wiki.
82
83 Flags:
84 %s
85 `, opts.Defaults()),
86 }, nil
87 }
88
89 func (p *dagrePlugin) Layout(ctx context.Context, g *d2graph.Graph) error {
90 p.mu.Lock()
91 optsCopy := *p.opts
92 p.mu.Unlock()
93 return d2dagrelayout.Layout(ctx, g, &optsCopy)
94 }
95
96 func (p *dagrePlugin) PostProcess(ctx context.Context, in []byte) ([]byte, error) {
97 return in, nil
98 }
99
View as plain text