navbar on pdfs
This commit is contained in:
parent
00ed4ca75b
commit
6f18b232b9
2 changed files with 46 additions and 17 deletions
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"oss.terrastruct.com/d2/lib/background"
|
"oss.terrastruct.com/d2/lib/background"
|
||||||
"oss.terrastruct.com/d2/lib/imgbundler"
|
"oss.terrastruct.com/d2/lib/imgbundler"
|
||||||
ctxlog "oss.terrastruct.com/d2/lib/log"
|
ctxlog "oss.terrastruct.com/d2/lib/log"
|
||||||
|
"oss.terrastruct.com/d2/lib/pdf"
|
||||||
pdflib "oss.terrastruct.com/d2/lib/pdf"
|
pdflib "oss.terrastruct.com/d2/lib/pdf"
|
||||||
"oss.terrastruct.com/d2/lib/png"
|
"oss.terrastruct.com/d2/lib/png"
|
||||||
"oss.terrastruct.com/d2/lib/pptx"
|
"oss.terrastruct.com/d2/lib/pptx"
|
||||||
|
|
@ -353,7 +354,7 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende
|
||||||
switch filepath.Ext(outputPath) {
|
switch filepath.Ext(outputPath) {
|
||||||
case ".pdf":
|
case ".pdf":
|
||||||
pageMap := buildBoardIDToIndex(diagram, nil, nil)
|
pageMap := buildBoardIDToIndex(diagram, nil, nil)
|
||||||
pdf, err := renderPDF(ctx, ms, plugin, renderOpts, outputPath, page, ruler, diagram, nil, nil, pageMap)
|
pdf, err := renderPDF(ctx, ms, plugin, renderOpts, outputPath, page, ruler, diagram, nil, nil, "", pageMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pdf, false, err
|
return pdf, false, err
|
||||||
}
|
}
|
||||||
|
|
@ -684,19 +685,26 @@ func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts
|
||||||
return svg, nil
|
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, pdf *pdflib.GoFPDF, boardPath []string, pageMap map[string]int) (svg []byte, err error) {
|
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, pdf *pdflib.GoFPDF, boardPath []pdf.BoardTitle, boardType string, pageMap map[string]int) (svg []byte, err error) {
|
||||||
var isRoot bool
|
var isRoot bool
|
||||||
if pdf == nil {
|
if pdf == nil {
|
||||||
pdf = pdflib.Init()
|
pdf = pdflib.Init()
|
||||||
isRoot = true
|
isRoot = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var currBoardPath []string
|
var currBoardPath []pdflib.BoardTitle
|
||||||
// Root board doesn't have a name, so we use the output filename
|
// Root board doesn't have a name, so we use the output filename
|
||||||
if diagram.Name == "" {
|
if diagram.Name == "" {
|
||||||
currBoardPath = append(boardPath, "root")
|
currBoardPath = append(boardPath, pdflib.BoardTitle{
|
||||||
|
Name: "root",
|
||||||
|
BoardID: "root",
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
currBoardPath = append(boardPath, diagram.Name)
|
prev := boardPath[len(boardPath)-1]
|
||||||
|
currBoardPath = append(boardPath, pdflib.BoardTitle{
|
||||||
|
Name: diagram.Name,
|
||||||
|
BoardID: strings.Join([]string{prev.BoardID, boardType, diagram.Name}, "."),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if !diagram.IsFolderOnly {
|
if !diagram.IsFolderOnly {
|
||||||
|
|
@ -749,19 +757,19 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dl := range diagram.Layers {
|
for _, dl := range diagram.Layers {
|
||||||
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, pdf, currBoardPath, pageMap)
|
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, pdf, currBoardPath, "layers", pageMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, dl := range diagram.Scenarios {
|
for _, dl := range diagram.Scenarios {
|
||||||
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, pdf, currBoardPath, pageMap)
|
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, pdf, currBoardPath, "scenarios", pageMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, dl := range diagram.Steps {
|
for _, dl := range diagram.Steps {
|
||||||
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, pdf, currBoardPath, pageMap)
|
_, err := renderPDF(ctx, ms, plugin, opts, "", page, ruler, dl, pdf, currBoardPath, "steps", pageMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,17 @@ import (
|
||||||
"oss.terrastruct.com/d2/lib/color"
|
"oss.terrastruct.com/d2/lib/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const TITLE_SEP = " / "
|
||||||
|
|
||||||
type GoFPDF struct {
|
type GoFPDF struct {
|
||||||
pdf *gofpdf.Fpdf
|
pdf *gofpdf.Fpdf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BoardTitle struct {
|
||||||
|
Name string
|
||||||
|
BoardID string
|
||||||
|
}
|
||||||
|
|
||||||
func Init() *GoFPDF {
|
func Init() *GoFPDF {
|
||||||
newGofPDF := gofpdf.NewCustom(&gofpdf.InitType{
|
newGofPDF := gofpdf.NewCustom(&gofpdf.InitType{
|
||||||
UnitStr: "pt",
|
UnitStr: "pt",
|
||||||
|
|
@ -59,9 +66,13 @@ func (g *GoFPDF) GetFillRGB(themeID int64, fill string) (color.RGB, error) {
|
||||||
return color.Hex2RGB(fill)
|
return color.Hex2RGB(fill)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill string, shapes []d2target.Shape, pad int64, viewboxX, viewboxY float64, pageMap map[string]int) error {
|
func (g *GoFPDF) AddPDFPage(png []byte, titlePath []BoardTitle, themeID int64, fill string, shapes []d2target.Shape, pad int64, viewboxX, viewboxY float64, pageMap map[string]int) error {
|
||||||
var opt gofpdf.ImageOptions
|
var opt gofpdf.ImageOptions
|
||||||
opt.ImageType = "png"
|
opt.ImageType = "png"
|
||||||
|
boardPath := make([]string, len(titlePath))
|
||||||
|
for i, t := range titlePath {
|
||||||
|
boardPath[i] = t.Name
|
||||||
|
}
|
||||||
imageInfo := g.pdf.RegisterImageOptionsReader(strings.Join(boardPath, "/"), opt, bytes.NewReader(png))
|
imageInfo := g.pdf.RegisterImageOptionsReader(strings.Join(boardPath, "/"), opt, bytes.NewReader(png))
|
||||||
if g.pdf.Err() {
|
if g.pdf.Err() {
|
||||||
return g.pdf.Error()
|
return g.pdf.Error()
|
||||||
|
|
@ -102,20 +113,30 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill
|
||||||
g.pdf.SetFont("source", "", 14)
|
g.pdf.SetFont("source", "", 14)
|
||||||
|
|
||||||
// Draw board path prefix
|
// Draw board path prefix
|
||||||
var prefixWidth float64
|
prefixWidth := headerMargin
|
||||||
prefixPath := boardPath[:len(boardPath)-1]
|
if len(titlePath) > 1 {
|
||||||
if len(prefixPath) > 0 {
|
for _, t := range titlePath[:len(titlePath)-1] {
|
||||||
prefix := strings.Join(boardPath[:len(boardPath)-1], " / ") + " / "
|
g.pdf.SetXY(prefixWidth, 0)
|
||||||
prefixWidth = g.pdf.GetStringWidth(prefix)
|
w := g.pdf.GetStringWidth(t.Name)
|
||||||
|
var linkID int
|
||||||
|
if pageNum, ok := pageMap[t.BoardID]; ok {
|
||||||
|
linkID = g.pdf.AddLink()
|
||||||
|
g.pdf.SetLink(linkID, 0, pageNum+1)
|
||||||
|
}
|
||||||
|
g.pdf.CellFormat(w, headerHeight, t.Name, "", 0, "", false, linkID, "")
|
||||||
|
prefixWidth += w
|
||||||
|
|
||||||
g.pdf.SetXY(headerMargin, 0)
|
g.pdf.SetXY(prefixWidth, 0)
|
||||||
g.pdf.CellFormat(prefixWidth, headerHeight, prefix, "", 0, "", false, 0, "")
|
w = g.pdf.GetStringWidth(TITLE_SEP)
|
||||||
|
g.pdf.CellFormat(prefixWidth, headerHeight, TITLE_SEP, "", 0, "", false, 0, "")
|
||||||
|
prefixWidth += w
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw board name
|
// Draw board name
|
||||||
boardName := boardPath[len(boardPath)-1]
|
boardName := boardPath[len(boardPath)-1]
|
||||||
g.pdf.SetFont("source", "B", 14)
|
g.pdf.SetFont("source", "B", 14)
|
||||||
g.pdf.SetXY(prefixWidth+headerMargin, 0)
|
g.pdf.SetXY(prefixWidth, 0)
|
||||||
g.pdf.CellFormat(pageWidth-prefixWidth-headerMargin, headerHeight, boardName, "", 0, "", false, 0, "")
|
g.pdf.CellFormat(pageWidth-prefixWidth-headerMargin, headerHeight, boardName, "", 0, "", false, 0, "")
|
||||||
|
|
||||||
// Draw image
|
// Draw image
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue