diff --git a/lib/pptx/pptx.go b/lib/pptx/pptx.go
index 349d09393..897720e75 100644
--- a/lib/pptx/pptx.go
+++ b/lib/pptx/pptx.go
@@ -6,7 +6,7 @@ import (
_ "embed"
"fmt"
"strings"
- "time"
+ "text/template"
)
// Measurements in OOXML are made in English Metric Units (EMUs) where 1 inch = 914,400 EMUs
@@ -41,111 +41,142 @@ func copyPptxTemplateTo(w *zip.Writer) error {
return nil
}
-func addFile(zipFile *zip.Writer, filePath, content string) error {
- w, err := zipFile.Create(filePath)
- if err != nil {
- return err
- }
- w.Write([]byte(content))
- return nil
-}
-
//go:embed templates/slide.xml.rels
var RELS_SLIDE_XML string
-func getRelsSlideXml(imageID string) string {
- return fmt.Sprintf(RELS_SLIDE_XML, imageID, imageID)
+type RelsSlideXmlContent struct {
+ FileName string
+ RelationshipID string
}
//go:embed templates/slide.xml
var SLIDE_XML string
-func getSlideXml(boardPath []string, imageID string, top, left, width, height int) string {
- var slideTitle string
+type SlideXmlContent struct {
+ Title string
+ TitlePrefix string
+ Description string
+ HeaderHeight int
+ ImageID string
+ ImageLeft int
+ ImageTop int
+ ImageWidth int
+ ImageHeight int
+}
+
+func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent {
+ boardPath := slide.BoardPath
boardName := boardPath[len(boardPath)-1]
prefixPath := boardPath[:len(boardPath)-1]
+ var prefix string
if len(prefixPath) > 0 {
- prefix := strings.Join(prefixPath, " / ") + " / "
- slideTitle = fmt.Sprintf(`%s%s`, prefix, boardName)
- } else {
- slideTitle = fmt.Sprintf(`%s`, boardName)
+ prefix = strings.Join(prefixPath, " / ") + " / "
+ }
+ return SlideXmlContent{
+ Title: boardName,
+ TitlePrefix: prefix,
+ Description: strings.Join(boardPath, " / "),
+ HeaderHeight: HEADER_HEIGHT,
+ ImageID: imageID,
+ ImageLeft: slide.ImageLeft,
+ ImageTop: slide.ImageTop + HEADER_HEIGHT,
+ ImageWidth: slide.ImageWidth,
+ ImageHeight: slide.ImageHeight,
}
- slideDescription := strings.Join(boardPath, " / ")
- top += HEADER_HEIGHT
- return fmt.Sprintf(SLIDE_XML, slideDescription, slideDescription, imageID, left, top, width, height, slideDescription, HEADER_HEIGHT, slideTitle)
}
//go:embed templates/rels_presentation.xml
var RELS_PRESENTATION_XML string
-func getPresentationXmlRels(slideFileNames []string) string {
- var builder strings.Builder
+type RelsPresentationSlideXmlContent struct {
+ RelationshipID string
+ FileName string
+}
+
+type RelsPresentationXmlContent struct {
+ Slides []RelsPresentationSlideXmlContent
+}
+
+func getRelsPresentationXmlContent(slideFileNames []string) RelsPresentationXmlContent {
+ var content RelsPresentationXmlContent
for _, name := range slideFileNames {
- builder.WriteString(fmt.Sprintf(
- ``, name, name,
- ))
+ content.Slides = append(content.Slides, RelsPresentationSlideXmlContent{
+ RelationshipID: name,
+ FileName: name,
+ })
}
- return fmt.Sprintf(RELS_PRESENTATION_XML, builder.String())
+ return content
}
//go:embed templates/content_types.xml
var CONTENT_TYPES_XML string
-func getContentTypesXml(slideFileNames []string) string {
- var builder strings.Builder
- for _, name := range slideFileNames {
- builder.WriteString(fmt.Sprintf(
- ``, name,
- ))
- }
-
- return fmt.Sprintf(CONTENT_TYPES_XML, builder.String())
+type ContentTypesXmlContent struct {
+ FileNames []string
}
//go:embed templates/presentation.xml
var PRESENTATION_XML string
-func getPresentationXml(slideFileNames []string) string {
- var builder strings.Builder
- for i, name := range slideFileNames {
- // in the exported presentation, the first slide ID was 256, so keeping it here for compatibility
- builder.WriteString(fmt.Sprintf(``, 256+i, name))
+type PresentationSlideXmlContent struct {
+ ID int
+ RelationshipID string
+}
+
+type PresentationXmlContent struct {
+ SlideWidth int
+ SlideHeight int
+ Slides []PresentationSlideXmlContent
+}
+
+func getPresentationXmlContent(slideFileNames []string) PresentationXmlContent {
+ content := PresentationXmlContent{
+ SlideWidth: SLIDE_WIDTH,
+ SlideHeight: SLIDE_HEIGHT,
}
- return fmt.Sprintf(PRESENTATION_XML, builder.String(), SLIDE_WIDTH, SLIDE_HEIGHT)
+ for i, name := range slideFileNames {
+ content.Slides = append(content.Slides, PresentationSlideXmlContent{
+ // in the exported presentation, the first slide ID was 256, so keeping it here for compatibility
+ ID: 256 + i,
+ RelationshipID: name,
+ })
+ }
+ return content
}
//go:embed templates/core.xml
var CORE_XML string
-func getCoreXml(title, subject, description, creator string) string {
- dateTime := time.Now().Format(time.RFC3339)
- return fmt.Sprintf(
- CORE_XML,
- title,
- subject,
- creator,
- description,
- creator,
- dateTime,
- dateTime,
- )
+type CoreXmlContent struct {
+ Title string
+ Subject string
+ Creator string
+ Description string
+ LastModifiedBy string
+ Created string
+ Modified string
}
//go:embed templates/app.xml
var APP_XML string
-func getAppXml(slides []*Slide, d2version string) string {
- var builder strings.Builder
- for _, slide := range slides {
- builder.WriteString(fmt.Sprintf(`%s`, strings.Join(slide.BoardPath, "/")))
- }
- return fmt.Sprintf(
- APP_XML,
- len(slides),
- len(slides),
- len(slides)+3, // number of entries, len(slides) + Office Theme + 2 Fonts
- builder.String(),
- d2version,
- )
+type AppXmlContent struct {
+ SlideCount int
+ TitlesOfPartsCount int
+ Titles []string
+ D2Version string
+}
+
+func addFileFromTemplate(zipFile *zip.Writer, filePath, templateContent string, templateData interface{}) error {
+ w, err := zipFile.Create(filePath)
+ if err != nil {
+ return err
+ }
+
+ tmpl, err := template.New(filePath).Parse(templateContent)
+ if err != nil {
+ return err
+ }
+ return tmpl.Execute(w, templateData)
}
diff --git a/lib/pptx/presentation.go b/lib/pptx/presentation.go
index fea845fd5..43f3522da 100644
--- a/lib/pptx/presentation.go
+++ b/lib/pptx/presentation.go
@@ -16,6 +16,8 @@ import (
"fmt"
"image/png"
"os"
+ "strings"
+ "time"
)
type Presentation struct {
@@ -142,42 +144,61 @@ func (p *Presentation) SaveTo(filePath string) error {
return err
}
- err = addFile(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), getRelsSlideXml(imageID))
+ err = addFileFromTemplate(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), RELS_SLIDE_XML, RelsSlideXmlContent{
+ FileName: imageID,
+ RelationshipID: imageID,
+ })
if err != nil {
return err
}
- err = addFile(
- zipWriter,
- fmt.Sprintf("ppt/slides/%s.xml", slideFileName),
- getSlideXml(slide.BoardPath, imageID, slide.ImageTop, slide.ImageLeft, slide.ImageWidth, slide.ImageHeight),
- )
+ err = addFileFromTemplate(zipWriter, fmt.Sprintf("ppt/slides/%s.xml", slideFileName), SLIDE_XML, getSlideXmlContent(imageID, slide))
if err != nil {
return err
}
}
- err = addFile(zipWriter, "[Content_Types].xml", getContentTypesXml(slideFileNames))
+ err = addFileFromTemplate(zipWriter, "[Content_Types].xml", CONTENT_TYPES_XML, ContentTypesXmlContent{
+ FileNames: slideFileNames,
+ })
if err != nil {
return err
}
- err = addFile(zipWriter, "ppt/_rels/presentation.xml.rels", getPresentationXmlRels(slideFileNames))
+ err = addFileFromTemplate(zipWriter, "ppt/_rels/presentation.xml.rels", RELS_PRESENTATION_XML, getRelsPresentationXmlContent(slideFileNames))
if err != nil {
return err
}
- err = addFile(zipWriter, "ppt/presentation.xml", getPresentationXml(slideFileNames))
+ err = addFileFromTemplate(zipWriter, "ppt/presentation.xml", PRESENTATION_XML, getPresentationXmlContent(slideFileNames))
if err != nil {
return err
}
- err = addFile(zipWriter, "docProps/core.xml", getCoreXml(p.Title, p.Subject, p.Description, p.Creator))
+ dateTime := time.Now().Format(time.RFC3339)
+ err = addFileFromTemplate(zipWriter, "docProps/core.xml", CORE_XML, CoreXmlContent{
+ Creator: p.Creator,
+ Subject: p.Subject,
+ Description: p.Description,
+ LastModifiedBy: p.Creator,
+ Title: p.Title,
+ Created: dateTime,
+ Modified: dateTime,
+ })
if err != nil {
return err
}
- err = addFile(zipWriter, "docProps/app.xml", getAppXml(p.Slides, p.D2Version))
+ titles := make([]string, 0, len(p.Slides))
+ for _, slide := range p.Slides {
+ titles = append(titles, strings.Join(slide.BoardPath, "/"))
+ }
+ err = addFileFromTemplate(zipWriter, "docProps/app.xml", APP_XML, AppXmlContent{
+ SlideCount: len(p.Slides),
+ TitlesOfPartsCount: len(p.Slides) + 3,
+ D2Version: p.D2Version,
+ Titles: titles,
+ })
if err != nil {
return err
}
diff --git a/lib/pptx/templates/app.xml b/lib/pptx/templates/app.xml
index 0400cf42f..ada0cf3db 100644
--- a/lib/pptx/templates/app.xml
+++ b/lib/pptx/templates/app.xml
@@ -4,9 +4,9 @@
1
0
D2
- On-screen Show (4:3)
+ On-screen Show (16:9)
0
- %d
+ {{.SlideCount}}
0
0
0
@@ -29,23 +29,23 @@
Slide Titles
- %d
+ {{.SlideCount}}
-
+
Arial
Calibri
Office Theme
- %s
+ {{range .Titles}}
+ {{.}}
+ {{end}}
-
-
false
false
false
- %s
+ {{.D2Version}}
\ No newline at end of file
diff --git a/lib/pptx/templates/content_types.xml b/lib/pptx/templates/content_types.xml
index 2a1b29ed7..6d6106c76 100644
--- a/lib/pptx/templates/content_types.xml
+++ b/lib/pptx/templates/content_types.xml
@@ -54,7 +54,9 @@
- %s
+ {{range .FileNames}}
+
+ {{end}}
- %s
- %s
- %s
+ {{.Title}}
+ {{.Subject}}
+ {{.Creator}}
- %s
- %s
+ {{.Description}}
+ {{.LastModifiedBy}}
1
- %s
- %s
+ {{.Created}}
+ {{.Modified}}
\ No newline at end of file
diff --git a/lib/pptx/templates/presentation.xml b/lib/pptx/templates/presentation.xml
index edd06d463..4f3b0e744 100644
--- a/lib/pptx/templates/presentation.xml
+++ b/lib/pptx/templates/presentation.xml
@@ -6,8 +6,12 @@
- %s
-
+
+ {{range .Slides}}
+
+ {{end}}
+
+
diff --git a/lib/pptx/templates/rels_presentation.xml b/lib/pptx/templates/rels_presentation.xml
index 6f85deb57..f7010c2c5 100644
--- a/lib/pptx/templates/rels_presentation.xml
+++ b/lib/pptx/templates/rels_presentation.xml
@@ -15,5 +15,7 @@
- %s
+ {{range .Slides}}
+
+ {{end}}
\ No newline at end of file
diff --git a/lib/pptx/templates/slide.xml b/lib/pptx/templates/slide.xml
index 6bdaa177c..2721068a1 100644
--- a/lib/pptx/templates/slide.xml
+++ b/lib/pptx/templates/slide.xml
@@ -19,22 +19,22 @@
-
+
-
+
-
-
+
+
@@ -43,14 +43,14 @@
-
+
-
+
@@ -75,7 +75,17 @@
- %s
+
+ {{if .TitlePrefix}}
+
+ {{.TitlePrefix}}
+
+ {{end}}
+
+
+ {{.Title}}
+
+
diff --git a/lib/pptx/templates/slide.xml.rels b/lib/pptx/templates/slide.xml.rels
index f7ea83ea6..92475c305 100644
--- a/lib/pptx/templates/slide.xml.rels
+++ b/lib/pptx/templates/slide.xml.rels
@@ -3,7 +3,7 @@
-
+ Target="../media/{{.FileName}}.png" />
\ No newline at end of file