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) - [Related](#related)
* [VSCode extension](#vscode-extension) * [VSCode extension](#vscode-extension)
* [Vim extension](#vim-extension) * [Vim extension](#vim-extension)
* [Language docs](#language-docs)
* [Misc](#misc) * [Misc](#misc)
- [FAQ](#faq) - [FAQ](#faq)
<!-- tocstop --> <!-- tocstop -->
# What does D2 look like? ## What does D2 look like?
```d2 ```d2
# Actors # 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 In addition to being a runnable CLI tool, D2 can also be used to produce diagrams from
Go programs. Go programs.
```go For examples, see [./docs/examples/lib](./docs/examples/lib).
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.
## Themes ## Themes

View file

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

View file

@ -23,6 +23,10 @@
[#251](https://github.com/terrastruct/d2/pull/251) [#251](https://github.com/terrastruct/d2/pull/251)
- [install.sh](./install.sh) prints the dry run message more visibly. - [install.sh](./install.sh) prints the dry run message more visibly.
[#266](https://github.com/terrastruct/d2/pull/266) [#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 🔴 #### Bugfixes 🔴

View file

@ -66,7 +66,7 @@ should_color() {
fi fi
fi fi
if [ -t 1 ]; then if [ -t 1 -a "${TERM-}" != dumb ]; then
_COLOR=1 _COLOR=1
return 0 return 0
else else
@ -89,7 +89,8 @@ _echo() {
get_rand_color() { get_rand_color() {
# 1-6 are regular and 9-14 are bright. # 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. # 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() { echop() {

2
ci/sub

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

View file

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

View file

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

View file

@ -83,7 +83,7 @@ know where the release directory is for easy uninstall.
You can always install from source: You can always install from source:
```sh ```sh
go install oss.terrastruct.com/d2/cmd/d2@latest go install oss.terrastruct.com/d2@latest
``` ```
## Coming soon ## 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/diff"
"oss.terrastruct.com/d2"
"oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
"oss.terrastruct.com/d2/d2layouts/d2elklayout" "oss.terrastruct.com/d2/d2layouts/d2elklayout"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/d2/d2renderers/d2svg" "oss.terrastruct.com/d2/d2renderers/d2svg"
"oss.terrastruct.com/d2/d2renderers/textmeasure" "oss.terrastruct.com/d2/d2renderers/textmeasure"
"oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/d2target"
@ -104,7 +104,7 @@ func run(t *testing.T, tc testCase) {
} else if layoutName == "elk" { } else if layoutName == "elk" {
layout = d2elklayout.Layout layout = d2elklayout.Layout
} }
diagram, err := d2.Compile(ctx, tc.script, &d2.CompileOptions{ diagram, _, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{
UTF16: true, UTF16: true,
Ruler: ruler, Ruler: ruler,
ThemeID: 0, 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. 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: Flags:
%s %s

View file

@ -72,7 +72,7 @@ should_color() {
fi fi
fi fi
if [ -t 1 ]; then if [ -t 1 -a "${TERM-}" != dumb ]; then
_COLOR=1 _COLOR=1
return 0 return 0
else else
@ -95,7 +95,8 @@ _echo() {
get_rand_color() { get_rand_color() {
# 1-6 are regular and 9-14 are bright. # 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. # 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() { echop() {

View file

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