navbar on pptx
This commit is contained in:
parent
a15bc2d687
commit
7918f265d4
4 changed files with 73 additions and 30 deletions
|
|
@ -372,7 +372,7 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende
|
||||||
p := pptx.NewPresentation(rootName, description, rootName, username, version.OnlyNumbers())
|
p := pptx.NewPresentation(rootName, description, rootName, username, version.OnlyNumbers())
|
||||||
|
|
||||||
boardIdToIndex := buildBoardIDToIndex(diagram, nil, nil)
|
boardIdToIndex := buildBoardIDToIndex(diagram, nil, nil)
|
||||||
svg, err := renderPPTX(ctx, ms, p, plugin, renderOpts, ruler, outputPath, page, diagram, nil, boardIdToIndex)
|
svg, err := renderPPTX(ctx, ms, p, plugin, renderOpts, ruler, outputPath, page, diagram, nil, "", boardIdToIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
@ -785,14 +785,24 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
||||||
return svg, nil
|
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 []string, 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, outputPath string, page playwright.Page, diagram *d2target.Diagram, boardPath []pptx.BoardTitle, boardType string, boardIDToIndex map[string]int) ([]byte, error) {
|
||||||
var currBoardPath []string
|
var curr pptx.BoardTitle
|
||||||
// Root board doesn't have a name, so we use the output filename
|
|
||||||
if diagram.Name == "" {
|
if diagram.Name == "" {
|
||||||
currBoardPath = append(boardPath, "root")
|
curr = pptx.BoardTitle{
|
||||||
|
Name: "root",
|
||||||
|
BoardID: "root",
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
currBoardPath = append(boardPath, diagram.Name)
|
prev := boardPath[len(boardPath)-1]
|
||||||
|
curr = pptx.BoardTitle{
|
||||||
|
Name: diagram.Name,
|
||||||
|
BoardID: strings.Join([]string{prev.BoardID, boardType, diagram.Name}, "."),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if pageNum, ok := boardIDToIndex[curr.BoardID]; ok {
|
||||||
|
curr.LinkToSlide = pageNum + 1
|
||||||
|
}
|
||||||
|
currBoardPath := append(boardPath, curr)
|
||||||
|
|
||||||
var svg []byte
|
var svg []byte
|
||||||
if !diagram.IsFolderOnly {
|
if !diagram.IsFolderOnly {
|
||||||
|
|
@ -867,7 +877,7 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
||||||
if err != nil || key.Path[0].Unbox().ScalarString() != "root" {
|
if err != nil || key.Path[0].Unbox().ScalarString() != "root" {
|
||||||
// External link
|
// External link
|
||||||
link.ExternalUrl = shape.Link
|
link.ExternalUrl = shape.Link
|
||||||
} else if pageNum, ok := boardIdToIndex[shape.Link]; ok {
|
} else if pageNum, ok := boardIDToIndex[shape.Link]; ok {
|
||||||
// Internal link
|
// Internal link
|
||||||
link.SlideIndex = pageNum + 1
|
link.SlideIndex = pageNum + 1
|
||||||
}
|
}
|
||||||
|
|
@ -875,19 +885,19 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dl := range diagram.Layers {
|
for _, dl := range diagram.Layers {
|
||||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
|
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, LAYERS, boardIDToIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, dl := range diagram.Scenarios {
|
for _, dl := range diagram.Scenarios {
|
||||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
|
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, SCENARIOS, boardIDToIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, dl := range diagram.Steps {
|
for _, dl := range diagram.Steps {
|
||||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
|
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, STEPS, boardIDToIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,17 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/png"
|
"image/png"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type BoardTitle struct {
|
||||||
|
LinkID string
|
||||||
|
Name string
|
||||||
|
BoardID string
|
||||||
|
LinkToSlide int
|
||||||
|
}
|
||||||
|
|
||||||
type Presentation struct {
|
type Presentation struct {
|
||||||
Title string
|
Title string
|
||||||
Description string
|
Description string
|
||||||
|
|
@ -32,8 +38,9 @@ type Presentation struct {
|
||||||
|
|
||||||
Slides []*Slide
|
Slides []*Slide
|
||||||
}
|
}
|
||||||
|
|
||||||
type Slide struct {
|
type Slide struct {
|
||||||
BoardPath []string
|
BoardTitle []BoardTitle
|
||||||
Links []*Link
|
Links []*Link
|
||||||
Image []byte
|
Image []byte
|
||||||
ImageId string
|
ImageId string
|
||||||
|
|
@ -76,7 +83,7 @@ func NewPresentation(title, description, subject, creator, d2Version string) *Pr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) (*Slide, error) {
|
func (p *Presentation) AddSlide(pngContent []byte, titlePath []BoardTitle) (*Slide, error) {
|
||||||
src, err := png.Decode(bytes.NewReader(pngContent))
|
src, err := png.Decode(bytes.NewReader(pngContent))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error decoding PNG image: %v", err)
|
return nil, fmt.Errorf("error decoding PNG image: %v", err)
|
||||||
|
|
@ -127,7 +134,7 @@ func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) (*Slide,
|
||||||
left := (SLIDE_WIDTH - width) / 2
|
left := (SLIDE_WIDTH - width) / 2
|
||||||
|
|
||||||
slide := &Slide{
|
slide := &Slide{
|
||||||
BoardPath: make([]string, len(boardPath)),
|
BoardTitle: make([]BoardTitle, len(titlePath)),
|
||||||
ImageId: fmt.Sprintf("slide%dImage", len(p.Slides)+1),
|
ImageId: fmt.Sprintf("slide%dImage", len(p.Slides)+1),
|
||||||
Image: pngContent,
|
Image: pngContent,
|
||||||
ImageWidth: width,
|
ImageWidth: width,
|
||||||
|
|
@ -137,7 +144,10 @@ func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) (*Slide,
|
||||||
ImageScaleFactor: float64(width) / srcWidth,
|
ImageScaleFactor: float64(width) / srcWidth,
|
||||||
}
|
}
|
||||||
// it must copy the board path to avoid slice reference issues
|
// it must copy the board path to avoid slice reference issues
|
||||||
copy(slide.BoardPath, boardPath)
|
for i := 0; i < len(titlePath); i++ {
|
||||||
|
titlePath[i].LinkID = fmt.Sprintf("navLink%d", i)
|
||||||
|
slide.BoardTitle[i] = titlePath[i]
|
||||||
|
}
|
||||||
|
|
||||||
p.Slides = append(p.Slides, slide)
|
p.Slides = append(p.Slides, slide)
|
||||||
return slide, nil
|
return slide, nil
|
||||||
|
|
@ -215,11 +225,11 @@ func (p *Presentation) SaveTo(filePath string) error {
|
||||||
|
|
||||||
titles := make([]string, 0, len(p.Slides))
|
titles := make([]string, 0, len(p.Slides))
|
||||||
for _, slide := range p.Slides {
|
for _, slide := range p.Slides {
|
||||||
titles = append(titles, strings.Join(slide.BoardPath, "/"))
|
titles = append(titles, slide.BoardTitle[len(slide.BoardTitle)-1].BoardID)
|
||||||
}
|
}
|
||||||
err = addFileFromTemplate(zipWriter, "docProps/app.xml", APP_XML, AppXmlContent{
|
err = addFileFromTemplate(zipWriter, "docProps/app.xml", APP_XML, AppXmlContent{
|
||||||
SlideCount: len(p.Slides),
|
SlideCount: len(p.Slides),
|
||||||
TitlesOfPartsCount: len(p.Slides) + 3,
|
TitlesOfPartsCount: len(p.Slides) + 3, // + 3 for fonts and theme
|
||||||
D2Version: p.D2Version,
|
D2Version: p.D2Version,
|
||||||
Titles: titles,
|
Titles: titles,
|
||||||
})
|
})
|
||||||
|
|
@ -291,6 +301,13 @@ func getSlideXmlRelsContent(imageID string, slide *Slide) RelsSlideXmlContent {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, t := range slide.BoardTitle {
|
||||||
|
content.Links = append(content.Links, RelsSlideXmlLinkContent{
|
||||||
|
RelationshipID: t.LinkID,
|
||||||
|
SlideIndex: t.LinkToSlide,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,9 +325,14 @@ type SlideLinkXmlContent struct {
|
||||||
Height int
|
Height int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SlideXmlTitlePathContent struct {
|
||||||
|
Name string
|
||||||
|
RelationshipID string
|
||||||
|
}
|
||||||
|
|
||||||
type SlideXmlContent struct {
|
type SlideXmlContent struct {
|
||||||
Title string
|
Title string
|
||||||
TitlePrefix string
|
TitlePrefix []SlideXmlTitlePathContent
|
||||||
Description string
|
Description string
|
||||||
HeaderHeight int
|
HeaderHeight int
|
||||||
ImageID string
|
ImageID string
|
||||||
|
|
@ -323,17 +345,18 @@ type SlideXmlContent struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent {
|
func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent {
|
||||||
boardPath := slide.BoardPath
|
title := make([]SlideXmlTitlePathContent, len(slide.BoardTitle)-1)
|
||||||
boardName := boardPath[len(boardPath)-1]
|
for i := 0; i < len(slide.BoardTitle)-1; i++ {
|
||||||
prefixPath := boardPath[:len(boardPath)-1]
|
t := slide.BoardTitle[i]
|
||||||
var prefix string
|
title[i] = SlideXmlTitlePathContent{
|
||||||
if len(prefixPath) > 0 {
|
Name: t.Name,
|
||||||
prefix = strings.Join(prefixPath, " / ") + " / "
|
RelationshipID: t.LinkID,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
content := SlideXmlContent{
|
content := SlideXmlContent{
|
||||||
Title: boardName,
|
Title: slide.BoardTitle[len(slide.BoardTitle)-1].Name,
|
||||||
TitlePrefix: prefix,
|
TitlePrefix: title,
|
||||||
Description: strings.Join(boardPath, " / "),
|
Description: slide.BoardTitle[len(slide.BoardTitle)-1].BoardID,
|
||||||
HeaderHeight: HEADER_HEIGHT,
|
HeaderHeight: HEADER_HEIGHT,
|
||||||
ImageID: imageID,
|
ImageID: imageID,
|
||||||
ImageLeft: slide.ImageLeft,
|
ImageLeft: slide.ImageLeft,
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -75,9 +75,19 @@
|
||||||
<a:defRPr sz="2400" />
|
<a:defRPr sz="2400" />
|
||||||
</a:lvl1pPr>
|
</a:lvl1pPr>
|
||||||
</a:lstStyle>
|
</a:lstStyle>
|
||||||
<a:p> {{if .TitlePrefix}} <a:r>
|
<a:p>
|
||||||
<a:t>{{.TitlePrefix}}</a:t>
|
{{range .TitlePrefix}}
|
||||||
</a:r> {{end}} <a:r>
|
<a:r>
|
||||||
|
<a:rPr>
|
||||||
|
<a:hlinkClick r:id="{{.RelationshipID}}" invalidUrl=""
|
||||||
|
action="ppaction://hlinksldjump" tgtFrame="" tooltip=""
|
||||||
|
history="1" highlightClick="0" endSnd="0" />
|
||||||
|
</a:rPr>
|
||||||
|
<a:t>{{.Name}}</a:t>
|
||||||
|
</a:r>
|
||||||
|
<a:r><a:t> / </a:t></a:r>
|
||||||
|
{{end}}
|
||||||
|
<a:r>
|
||||||
<a:rPr b="1" />
|
<a:rPr b="1" />
|
||||||
<a:t>{{.Title}}</a:t>
|
<a:t>{{.Title}}</a:t>
|
||||||
</a:r>
|
</a:r>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue