cli: resolve local icon paths relative to d2 file
This commit is contained in:
parent
939a684819
commit
15b4717323
3 changed files with 41 additions and 32 deletions
|
|
@ -1,3 +1,7 @@
|
|||
Hotfix for 0.6.4 breaking plugins, along with 2 other compiler bugfixes.
|
||||
#### Features 🚀
|
||||
|
||||
#### Improvements 🧹
|
||||
|
||||
#### Bugfixes ⛑️
|
||||
|
||||
- Local relative icons are relative to the d2 file instead of CLI invoke path [#1924](https://github.com/terrastruct/d2/pull/1924)
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, fs
|
|||
ext := getExportExtension(outputPath)
|
||||
switch ext {
|
||||
case GIF:
|
||||
svg, pngs, err := renderPNGsForGIF(ctx, ms, plugin, renderOpts, ruler, page, diagram)
|
||||
svg, pngs, err := renderPNGsForGIF(ctx, ms, plugin, renderOpts, ruler, page, inputPath, diagram)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
|
@ -553,7 +553,7 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, fs
|
|||
path := []pdf.BoardTitle{
|
||||
{Name: diagram.Root.Label, BoardID: "root"},
|
||||
}
|
||||
pdf, err := renderPDF(ctx, ms, plugin, renderOpts, outputPath, page, ruler, diagram, nil, path, pageMap, diagram.Root.Label != "")
|
||||
pdf, err := renderPDF(ctx, ms, plugin, renderOpts, inputPath, outputPath, page, ruler, diagram, nil, path, pageMap, diagram.Root.Label != "")
|
||||
if err != nil {
|
||||
return pdf, false, err
|
||||
}
|
||||
|
|
@ -574,7 +574,7 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, fs
|
|||
path := []pptx.BoardTitle{
|
||||
{Name: "root", BoardID: "root", LinkToSlide: boardIdToIndex["root"] + 1},
|
||||
}
|
||||
svg, err := renderPPTX(ctx, ms, p, plugin, renderOpts, ruler, outputPath, page, diagram, path, boardIdToIndex)
|
||||
svg, err := renderPPTX(ctx, ms, p, plugin, renderOpts, ruler, inputPath, outputPath, page, diagram, path, boardIdToIndex)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
|
@ -808,7 +808,7 @@ func render(ctx context.Context, ms *xmain.State, compileDur time.Duration, plug
|
|||
|
||||
if !diagram.IsFolderOnly {
|
||||
start := time.Now()
|
||||
out, err := _render(ctx, ms, plugin, opts, boardOutputPath, bundle, forceAppendix, page, ruler, diagram)
|
||||
out, err := _render(ctx, ms, plugin, opts, inputPath, boardOutputPath, bundle, forceAppendix, page, ruler, diagram)
|
||||
if err != nil {
|
||||
return boards, err
|
||||
}
|
||||
|
|
@ -824,7 +824,7 @@ func render(ctx context.Context, ms *xmain.State, compileDur time.Duration, plug
|
|||
|
||||
func renderSingle(ctx context.Context, ms *xmain.State, compileDur time.Duration, plugin d2plugin.Plugin, opts d2svg.RenderOpts, inputPath, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([][]byte, error) {
|
||||
start := time.Now()
|
||||
out, err := _render(ctx, ms, plugin, opts, outputPath, bundle, forceAppendix, page, ruler, diagram)
|
||||
out, err := _render(ctx, ms, plugin, opts, inputPath, outputPath, bundle, forceAppendix, page, ruler, diagram)
|
||||
if err != nil {
|
||||
return [][]byte{}, err
|
||||
}
|
||||
|
|
@ -835,7 +835,7 @@ func renderSingle(ctx context.Context, ms *xmain.State, compileDur time.Duration
|
|||
return [][]byte{out}, nil
|
||||
}
|
||||
|
||||
func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([]byte, error) {
|
||||
func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, inputPath, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([]byte, error) {
|
||||
toPNG := getExportExtension(outputPath) == PNG
|
||||
var scale *float64
|
||||
if opts.Scale != nil {
|
||||
|
|
@ -865,7 +865,7 @@ func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts
|
|||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, inputPath, svg, cacheImages)
|
||||
if bundle {
|
||||
var bundleErr2 error
|
||||
svg, bundleErr2 = imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
|
|
@ -915,7 +915,7 @@ func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts
|
|||
return svg, nil
|
||||
}
|
||||
|
||||
func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, outputPath string, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram, doc *pdf.GoFPDF, boardPath []pdf.BoardTitle, pageMap map[string]int, includeNav bool) (svg []byte, err error) {
|
||||
func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, inputPath, outputPath string, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram, doc *pdf.GoFPDF, boardPath []pdf.BoardTitle, pageMap map[string]int, includeNav bool) (svg []byte, err error) {
|
||||
var isRoot bool
|
||||
if doc == nil {
|
||||
doc = pdf.Init()
|
||||
|
|
@ -953,7 +953,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
|||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, inputPath, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
if bundleErr != nil {
|
||||
|
|
@ -986,7 +986,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
|||
Name: dl.Root.Label,
|
||||
BoardID: strings.Join([]string{boardPath[len(boardPath)-1].BoardID, LAYERS, dl.Name}, "."),
|
||||
})
|
||||
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, doc, path, pageMap, includeNav)
|
||||
_, err := renderPDF(ctx, ms, plugin, opts, inputPath, "", page, ruler, dl, doc, path, pageMap, includeNav)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -996,7 +996,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
|||
Name: dl.Root.Label,
|
||||
BoardID: strings.Join([]string{boardPath[len(boardPath)-1].BoardID, SCENARIOS, dl.Name}, "."),
|
||||
})
|
||||
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, doc, path, pageMap, includeNav)
|
||||
_, err := renderPDF(ctx, ms, plugin, opts, inputPath, "", page, ruler, dl, doc, path, pageMap, includeNav)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1006,7 +1006,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
|||
Name: dl.Root.Label,
|
||||
BoardID: strings.Join([]string{boardPath[len(boardPath)-1].BoardID, STEPS, dl.Name}, "."),
|
||||
})
|
||||
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, doc, path, pageMap, includeNav)
|
||||
_, err := renderPDF(ctx, ms, plugin, opts, inputPath, "", page, ruler, dl, doc, path, pageMap, includeNav)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1022,7 +1022,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
|||
return svg, nil
|
||||
}
|
||||
|
||||
func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Presentation, plugin d2plugin.Plugin, opts d2svg.RenderOpts, ruler *textmeasure.Ruler, outputPath string, page playwright.Page, diagram *d2target.Diagram, boardPath []pptx.BoardTitle, boardIDToIndex map[string]int) ([]byte, error) {
|
||||
func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Presentation, plugin d2plugin.Plugin, opts d2svg.RenderOpts, ruler *textmeasure.Ruler, inputPath, outputPath string, page playwright.Page, diagram *d2target.Diagram, boardPath []pptx.BoardTitle, boardIDToIndex map[string]int) ([]byte, error) {
|
||||
var svg []byte
|
||||
if !diagram.IsFolderOnly {
|
||||
// gofpdf will print the png img with a slight filter
|
||||
|
|
@ -1055,7 +1055,7 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, inputPath, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
if bundleErr != nil {
|
||||
|
|
@ -1120,7 +1120,7 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
BoardID: boardID,
|
||||
LinkToSlide: boardIDToIndex[boardID] + 1,
|
||||
})
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, path, boardIDToIndex)
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, inputPath, "", page, dl, path, boardIDToIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1132,7 +1132,7 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
BoardID: boardID,
|
||||
LinkToSlide: boardIDToIndex[boardID] + 1,
|
||||
})
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, path, boardIDToIndex)
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, inputPath, "", page, dl, path, boardIDToIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1144,7 +1144,7 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
BoardID: boardID,
|
||||
LinkToSlide: boardIDToIndex[boardID] + 1,
|
||||
})
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, path, boardIDToIndex)
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, inputPath, "", page, dl, path, boardIDToIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1276,7 +1276,7 @@ func buildBoardIDToIndex(diagram *d2target.Diagram, dictionary map[string]int, p
|
|||
return dictionary
|
||||
}
|
||||
|
||||
func renderPNGsForGIF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, ruler *textmeasure.Ruler, page playwright.Page, diagram *d2target.Diagram) (svg []byte, pngs [][]byte, err error) {
|
||||
func renderPNGsForGIF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, ruler *textmeasure.Ruler, page playwright.Page, inputPath string, diagram *d2target.Diagram) (svg []byte, pngs [][]byte, err error) {
|
||||
if !diagram.IsFolderOnly {
|
||||
|
||||
var scale *float64
|
||||
|
|
@ -1302,7 +1302,7 @@ func renderPNGsForGIF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plug
|
|||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, inputPath, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
if bundleErr != nil {
|
||||
|
|
@ -1319,21 +1319,21 @@ func renderPNGsForGIF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plug
|
|||
}
|
||||
|
||||
for _, dl := range diagram.Layers {
|
||||
_, layerPNGs, err := renderPNGsForGIF(ctx, ms, plugin, opts, ruler, page, dl)
|
||||
_, layerPNGs, err := renderPNGsForGIF(ctx, ms, plugin, opts, ruler, page, inputPath, dl)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pngs = append(pngs, layerPNGs...)
|
||||
}
|
||||
for _, dl := range diagram.Scenarios {
|
||||
_, scenarioPNGs, err := renderPNGsForGIF(ctx, ms, plugin, opts, ruler, page, dl)
|
||||
_, scenarioPNGs, err := renderPNGsForGIF(ctx, ms, plugin, opts, ruler, page, inputPath, dl)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pngs = append(pngs, scenarioPNGs...)
|
||||
}
|
||||
for _, dl := range diagram.Steps {
|
||||
_, stepsPNGs, err := renderPNGsForGIF(ctx, ms, plugin, opts, ruler, page, dl)
|
||||
_, stepsPNGs, err := renderPNGsForGIF(ctx, ms, plugin, opts, ruler, page, inputPath, dl)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
|
@ -29,12 +30,12 @@ const maxImageSize int64 = 1 << 25 // 33_554_432
|
|||
|
||||
var imageRegex = regexp.MustCompile(`<image href="([^"]+)"`)
|
||||
|
||||
func BundleLocal(ctx context.Context, l simplelog.Logger, in []byte, cacheImages bool) ([]byte, error) {
|
||||
return bundle(ctx, l, in, false, cacheImages)
|
||||
func BundleLocal(ctx context.Context, l simplelog.Logger, inputPath string, in []byte, cacheImages bool) ([]byte, error) {
|
||||
return bundle(ctx, l, inputPath, in, false, cacheImages)
|
||||
}
|
||||
|
||||
func BundleRemote(ctx context.Context, l simplelog.Logger, in []byte, cacheImages bool) ([]byte, error) {
|
||||
return bundle(ctx, l, in, true, cacheImages)
|
||||
return bundle(ctx, l, "", in, true, cacheImages)
|
||||
}
|
||||
|
||||
type repl struct {
|
||||
|
|
@ -42,7 +43,7 @@ type repl struct {
|
|||
to []byte
|
||||
}
|
||||
|
||||
func bundle(ctx context.Context, l simplelog.Logger, svg []byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
func bundle(ctx context.Context, l simplelog.Logger, inputPath string, svg []byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
if isRemote {
|
||||
defer xdefer.Errorf(&err, "failed to bundle remote images")
|
||||
} else {
|
||||
|
|
@ -54,7 +55,7 @@ func bundle(ctx context.Context, l simplelog.Logger, svg []byte, isRemote, cache
|
|||
ctx, cancel := context.WithTimeout(ctx, time.Minute*5)
|
||||
defer cancel()
|
||||
|
||||
return runWorkers(ctx, l, svg, imgs, isRemote, cacheImages)
|
||||
return runWorkers(ctx, l, inputPath, svg, imgs, isRemote, cacheImages)
|
||||
}
|
||||
|
||||
// filterImageElements finds all unique image elements in imgs that are
|
||||
|
|
@ -84,7 +85,7 @@ func filterImageElements(imgs [][][]byte, isRemote bool) [][][]byte {
|
|||
return imgs2
|
||||
}
|
||||
|
||||
func runWorkers(ctx context.Context, l simplelog.Logger, svg []byte, imgs [][][]byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
func runWorkers(ctx context.Context, l simplelog.Logger, inputPath string, svg []byte, imgs [][][]byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
var wg sync.WaitGroup
|
||||
replc := make(chan repl)
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ func runWorkers(ctx context.Context, l simplelog.Logger, svg []byte, imgs [][][]
|
|||
<-sema
|
||||
}()
|
||||
|
||||
bundledImage, err := worker(ctx, l, img[1], isRemote, cacheImages)
|
||||
bundledImage, err := worker(ctx, l, inputPath, img[1], isRemote, cacheImages)
|
||||
if err != nil {
|
||||
l.Error(fmt.Sprintf("failed to bundle %s: %v", img[1], err))
|
||||
errhrefsMu.Lock()
|
||||
|
|
@ -150,7 +151,7 @@ func runWorkers(ctx context.Context, l simplelog.Logger, svg []byte, imgs [][][]
|
|||
}
|
||||
}
|
||||
|
||||
func worker(ctx context.Context, l simplelog.Logger, href []byte, isRemote, cacheImages bool) ([]byte, error) {
|
||||
func worker(ctx context.Context, l simplelog.Logger, inputPath string, href []byte, isRemote, cacheImages bool) ([]byte, error) {
|
||||
if cacheImages {
|
||||
if hit, ok := imgCache.Load(string(href)); ok {
|
||||
return hit.([]byte), nil
|
||||
|
|
@ -164,7 +165,11 @@ func worker(ctx context.Context, l simplelog.Logger, href []byte, isRemote, cach
|
|||
buf, mimeType, err = httpGet(ctx, html.UnescapeString(string(href)))
|
||||
} else {
|
||||
l.Debug(fmt.Sprintf("reading %s from disk", string(href)))
|
||||
buf, err = os.ReadFile(html.UnescapeString(string(href)))
|
||||
path := html.UnescapeString(string(href))
|
||||
if inputPath != "-" && !filepath.IsAbs(path) {
|
||||
path = filepath.Join(filepath.Dir(inputPath), path)
|
||||
}
|
||||
buf, err = os.ReadFile(path)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
Loading…
Reference in a new issue