Merge pull request #290 from nhooyr/nocmd-326c

Move d2 cmd to repo root and update library examples
This commit is contained in:
Anmol Sethi 2022-12-01 01:57:23 -05:00 committed by GitHub
commit 7797839f9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 175 additions and 71 deletions

View file

@ -35,12 +35,13 @@
- [Related](#related)
* [VSCode extension](#vscode-extension)
* [Vim extension](#vim-extension)
* [Language docs](#language-docs)
* [Misc](#misc)
- [FAQ](#faq)
<!-- tocstop -->
# What does D2 look like?
## What does D2 look like?
```d2
# Actors
@ -111,56 +112,7 @@ For detailed installation docs, with alternative methods and examples for each O
In addition to being a runnable CLI tool, D2 can also be used to produce diagrams from
Go programs.
```go
import (
"context"
"io/ioutil"
"path/filepath"
"strings"
"oss.terrastruct.com/d2/d2compiler"
"oss.terrastruct.com/d2/d2exporter"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
"oss.terrastruct.com/d2/d2renderers/d2svg"
"oss.terrastruct.com/d2/d2renderers/textmeasure"
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
)
func main() {
graph, _ := d2compiler.Compile("", strings.NewReader("x -> y"), &d2compiler.CompileOptions{UTF16: true})
ruler, _ := textmeasure.NewRuler()
graph.SetDimensions(nil, ruler)
d2dagrelayout.Layout(context.Background(), graph)
diagram, _ := d2exporter.Export(context.Background(), graph, d2themescatalog.NeutralDefault.ID)
out, _ := d2svg.Render(diagram)
ioutil.WriteFile(filepath.Join("out.svg"), out, 0600)
}
```
D2 is built to be hackable -- the language has an API built on top of it to make edits
programmatically. Modifying the above diagram:
```go
import (
"oss.terrastruct.com/d2/d2renderers/textmeasure"
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
)
// Create a shape with the ID, "meow"
graph, _, _ = d2oracle.Create(graph, "meow")
// Style the shape green
color := "green"
graph, _ = d2oracle.Set(graph, "meow.style.fill", nil, &color)
// Create a shape with the ID, "cat"
graph, _, _ = d2oracle.Create(graph, "cat")
// Move the shape "meow" inside the container "cat"
graph, _ = d2oracle.Move(graph, "meow", "cat.meow")
// Prints formatted D2 script
println(d2format.Format(graph.AST))
```
This makes it easy to build functionality on top of D2. Terrastruct uses the above API to
implement editing of D2 from mouse actions in a visual interface.
For examples, see [./docs/examples/lib](./docs/examples/lib).
## Themes

View file

@ -14,7 +14,7 @@ export GOOS=$(goos "$OS")
export GOARCH="$ARCH"
sh_c mkdir -p "$HW_BUILD_DIR/bin"
sh_c go build -ldflags "'-X oss.terrastruct.com/d2/lib/version.Version=$VERSION'" \
-o "$HW_BUILD_DIR/bin/d2" ./cmd/d2
-o "$HW_BUILD_DIR/bin/d2" .
ARCHIVE=$PWD/$ARCHIVE
cd "$(dirname "$HW_BUILD_DIR")"

View file

@ -23,6 +23,10 @@
[#251](https://github.com/terrastruct/d2/pull/251)
- [install.sh](./install.sh) prints the dry run message more visibly.
[#266](https://github.com/terrastruct/d2/pull/266)
- `d2` now lives in the root folder of the repository instead of as a subcommand.
So you can run `go install oss.terrastruct.com/d2@latest` to install from source
now.
[#290](https://github.com/terrastruct/d2/pull/290)
#### Bugfixes 🔴

View file

@ -66,7 +66,7 @@ should_color() {
fi
fi
if [ -t 1 ]; then
if [ -t 1 -a "${TERM-}" != dumb ]; then
_COLOR=1
return 0
else
@ -89,7 +89,8 @@ _echo() {
get_rand_color() {
# 1-6 are regular and 9-14 are bright.
# 1,2 and 9,10 are red and green but we use those for success and failure.
pick "$*" 3 4 5 6 11 12 13 14
pick "$*" 1 2 3 4 5 6 \
9 10 11 12 13 14
}
echop() {

2
ci/sub

@ -1 +1 @@
Subproject commit 28fb67e3bf11d7df2be9ad57b67b78a1733a7f2d
Subproject commit 0dacc9c6cee5b8d901f22f57e9dc7f9acf640cbc

View file

@ -1,6 +1,6 @@
//go:build cgo
package d2
package d2lib
import "oss.terrastruct.com/d2/d2layouts/d2dagrelayout"

View file

@ -1,4 +1,4 @@
package d2
package d2lib
import (
"context"
@ -22,7 +22,7 @@ type CompileOptions struct {
ThemeID int64
}
func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target.Diagram, error) {
func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target.Diagram, *d2graph.Graph, error) {
if opts == nil {
opts = &CompileOptions{}
}
@ -31,12 +31,12 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target
UTF16: opts.UTF16,
})
if err != nil {
return nil, err
return nil, nil, err
}
err = g.SetDimensions(opts.MeasuredTexts, opts.Ruler)
if err != nil {
return nil, err
return nil, nil, err
}
if opts.Layout != nil {
@ -47,11 +47,11 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target
err = errors.New("no available layout")
}
if err != nil {
return nil, err
return nil, nil, err
}
diagram, err := d2exporter.Export(ctx, g, opts.ThemeID)
return diagram, err
return diagram, g, err
}
// See c.go

View file

@ -83,7 +83,7 @@ know where the release directory is for easy uninstall.
You can always install from source:
```sh
go install oss.terrastruct.com/d2/cmd/d2@latest
go install oss.terrastruct.com/d2@latest
```
## Coming soon

1
docs/examples/lib/1-d2lib/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
out.svg

View file

@ -0,0 +1,25 @@
package main
import (
"context"
"io/ioutil"
"path/filepath"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/d2/d2renderers/d2svg"
"oss.terrastruct.com/d2/d2renderers/textmeasure"
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
)
// Remember to add if err != nil checks in production.
func main() {
ruler, _ := textmeasure.NewRuler()
diagram, _, _ := d2lib.Compile(context.Background(), "x -> y", &d2lib.CompileOptions{
Layout: d2dagrelayout.Layout,
Ruler: ruler,
ThemeID: d2themescatalog.GrapeSoda.ID,
})
out, _ := d2svg.Render(diagram)
_ = ioutil.WriteFile(filepath.Join("out.svg"), out, 0600)
}

View file

@ -0,0 +1,9 @@
package main
import (
"testing"
)
func TestMain_(t *testing.T) {
main()
}

View file

@ -0,0 +1,36 @@
package main
import (
"context"
"fmt"
"oss.terrastruct.com/d2/d2format"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/d2/d2oracle"
"oss.terrastruct.com/d2/d2renderers/textmeasure"
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
)
// Remember to add if err != nil checks in production.
func main() {
// From one.go
ruler, _ := textmeasure.NewRuler()
_, graph, _ := d2lib.Compile(context.Background(), "x -> y", &d2lib.CompileOptions{
Layout: d2dagrelayout.Layout,
Ruler: ruler,
ThemeID: d2themescatalog.GrapeSoda.ID,
})
// Create a shape with the ID, "meow"
graph, _, _ = d2oracle.Create(graph, "meow")
// Style the shape green
color := "green"
graph, _ = d2oracle.Set(graph, "meow.style.fill", nil, &color)
// Create a shape with the ID, "cat"
graph, _, _ = d2oracle.Create(graph, "cat")
// Move the shape "meow" inside the container "cat"
graph, _ = d2oracle.Move(graph, "meow", "cat.meow")
// Prints formatted D2 script
fmt.Print(d2format.Format(graph.AST))
}

View file

@ -0,0 +1,9 @@
package main
import (
"testing"
)
func TestMain_(t *testing.T) {
main()
}

View file

@ -0,0 +1 @@
out.svg

View file

@ -0,0 +1,26 @@
package main
import (
"context"
"io/ioutil"
"path/filepath"
"strings"
"oss.terrastruct.com/d2/d2compiler"
"oss.terrastruct.com/d2/d2exporter"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
"oss.terrastruct.com/d2/d2renderers/d2svg"
"oss.terrastruct.com/d2/d2renderers/textmeasure"
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
)
// Remember to add if err != nil checks in production.
func main() {
graph, _ := d2compiler.Compile("", strings.NewReader("x -> y"), nil)
ruler, _ := textmeasure.NewRuler()
_ = graph.SetDimensions(nil, ruler)
_ = d2dagrelayout.Layout(context.Background(), graph)
diagram, _ := d2exporter.Export(context.Background(), graph, d2themescatalog.NeutralDefault.ID)
out, _ := d2svg.Render(diagram)
_ = ioutil.WriteFile(filepath.Join("out.svg"), out, 0600)
}

View file

@ -0,0 +1,9 @@
package main
import (
"testing"
)
func TestMain_(t *testing.T) {
main()
}

View file

@ -0,0 +1,30 @@
# D2 library examples
We have a few examples in this directory on how to use the D2 library to turn D2 scripts
into rendered svg diagrams and more.
Each example is runnable though does not include error handling for readability.
### [./1-d2lib](./1-d2lib)
A minimal example showing you how to compile the diagram `x -> y` into an svg.
### [./2-d2oracle](./2-d2oracle)
D2 is built to be hackable -- the language has an API built on top of it to make edits
programmatically.
Modifying the previous example, this example demonstrates how
[d2oracle](../../../d2oracle) can be used to create a new shape, style it programatically
and then output the modified d2 script.
This makes it easy to build functionality on top of D2. Terrastruct uses the
[d2oracle](../../../d2oracle) API to implement editing of D2 from mouse actions in a
visual interface.
### [./3-lowlevel](./3-lowlevel)
`d2lib` from the first example is just a wrapper around the lower level APIs. They
can be used directly and this example demonstrates such usage.
This shouldn't be necessary for most usecases.

View file

@ -16,10 +16,10 @@ import (
"oss.terrastruct.com/diff"
"oss.terrastruct.com/d2"
"oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
"oss.terrastruct.com/d2/d2layouts/d2elklayout"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/d2/d2renderers/d2svg"
"oss.terrastruct.com/d2/d2renderers/textmeasure"
"oss.terrastruct.com/d2/d2target"
@ -104,7 +104,7 @@ func run(t *testing.T, tc testCase) {
} else if layoutName == "elk" {
layout = d2elklayout.Layout
}
diagram, err := d2.Compile(ctx, tc.script, &d2.CompileOptions{
diagram, _, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{
UTF16: true,
Ruler: ruler,
ThemeID: 0,

View file

@ -22,7 +22,7 @@ It defaults to file.svg if an output path is not provided.
Use - to have d2 read from stdin or write to stdout.
See man %[1]s for more detailed docs.
See man d2 for more detailed docs.
Flags:
%s

View file

@ -72,7 +72,7 @@ should_color() {
fi
fi
if [ -t 1 ]; then
if [ -t 1 -a "${TERM-}" != dumb ]; then
_COLOR=1
return 0
else
@ -95,7 +95,8 @@ _echo() {
get_rand_color() {
# 1-6 are regular and 9-14 are bright.
# 1,2 and 9,10 are red and green but we use those for success and failure.
pick "$*" 3 4 5 6 11 12 13 14
pick "$*" 1 2 3 4 5 6 \
9 10 11 12 13 14
}
echop() {

View file

@ -14,8 +14,8 @@ import (
"github.com/spf13/pflag"
"go.uber.org/multierr"
"oss.terrastruct.com/d2"
"oss.terrastruct.com/d2/d2layouts/d2sequence"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/d2/d2plugin"
"oss.terrastruct.com/d2/d2renderers/d2svg"
"oss.terrastruct.com/d2/d2renderers/textmeasure"
@ -196,7 +196,7 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, theme
if os.Getenv("D2_SEQUENCE") == "1" {
layout = d2sequence.Layout
}
d, err := d2.Compile(ctx, string(input), &d2.CompileOptions{
diagram, _, err := d2lib.Compile(ctx, string(input), &d2lib.CompileOptions{
Layout: layout,
Ruler: ruler,
ThemeID: themeID,
@ -205,7 +205,7 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, theme
return nil, false, err
}
svg, err := d2svg.Render(d)
svg, err := d2svg.Render(diagram)
if err != nil {
return nil, false, err
}