PR comments

This commit is contained in:
Júlio César Batista 2023-04-10 11:45:04 -03:00
parent 38cafc9d40
commit 6993c0e557
No known key found for this signature in database
GPG key ID: 10C4B861BF314878
3 changed files with 49 additions and 26 deletions

View file

@ -364,8 +364,9 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende
if user, err := user.Current(); err == nil {
username = user.Username
}
description := "Presentation auto-generated by D2 - https://d2lang.com/"
description := "Presentation generated with D2 - https://d2lang.com/"
rootName := getFileName(outputPath)
// version must be only numbers to avoid issues with PowerPoint
p := pptx.NewPresentation(rootName, description, rootName, username, version.OnlyNumbers())
err := renderPPTX(ctx, ms, p, plugin, renderOpts, outputPath, page, diagram, nil)
if err != nil {
@ -838,9 +839,7 @@ func renameExt(fp string, newExt string) string {
func getFileName(path string) string {
ext := filepath.Ext(path)
trimmedPath := strings.TrimSuffix(path, ext)
splitPath := strings.Split(trimmedPath, "/")
return splitPath[len(splitPath)-1]
return strings.TrimSuffix(filepath.Base(path), ext)
}
// TODO: remove after removing slog

View file

@ -9,7 +9,19 @@ import (
"time"
)
// Measurements in OOXML are made in English Metric Units (EMUs) where 1 inch = 914,400 EMUs
// The intent is to have a measurement unit that doesn't require floating points when dealing with centimeters, inches, points (DPI).
// Office Open XML (OOXML) http://officeopenxml.com/prPresentation.php
// https://startbigthinksmall.wordpress.com/2010/01/04/points-inches-and-emus-measuring-units-in-office-open-xml/
const SLIDE_WIDTH = 9_144_000
const SLIDE_HEIGHT = 5_143_500
const HEADER_HEIGHT = 392_471
const IMAGE_HEIGHT = SLIDE_HEIGHT - HEADER_HEIGHT
// keep the right aspect ratio: SLIDE_WIDTH / SLIDE_HEIGHT = IMAGE_WIDTH / IMAGE_HEIGHT
const IMAGE_WIDTH = 8_446_273
const IMAGE_ASPECT_RATIO = float64(IMAGE_WIDTH) / float64(IMAGE_HEIGHT)
//go:embed template.pptx
var pptx_template []byte
@ -38,26 +50,15 @@ func addFile(zipFile *zip.Writer, filePath, content string) error {
return nil
}
// https://startbigthinksmall.wordpress.com/2010/01/04/points-inches-and-emus-measuring-units-in-office-open-xml/
const SLIDE_WIDTH = 9_144_000
const SLIDE_HEIGHT = 5_143_500
const HEADER_HEIGHT = 392_471
const IMAGE_HEIGHT = SLIDE_HEIGHT - HEADER_HEIGHT
// keep the right aspect ratio: SLIDE_WIDTH / SLIDE_HEIGHT = IMAGE_WIDTH / IMAGE_HEIGHT
const IMAGE_WIDTH = 8_446_273
const IMAGE_ASPECT_RATIO = float64(IMAGE_WIDTH) / float64(IMAGE_HEIGHT)
const RELS_SLIDE_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout7.xml" /><Relationship Id="%s" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/%s.png" /></Relationships>`
func getRelsSlideXml(imageId string) string {
return fmt.Sprintf(RELS_SLIDE_XML, imageId, imageId)
func getRelsSlideXml(imageID string) string {
return fmt.Sprintf(RELS_SLIDE_XML, imageID, imageID)
}
const SLIDE_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><p:cSld><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name="" /><p:cNvGrpSpPr /><p:nvPr /></p:nvGrpSpPr><p:grpSpPr><a:xfrm><a:off x="0" y="0" /><a:ext cx="0" cy="0" /><a:chOff x="0" y="0" /><a:chExt cx="0" cy="0" /></a:xfrm></p:grpSpPr><p:pic><p:nvPicPr><p:cNvPr id="2" name="%s" descr="%s" /><p:cNvPicPr><a:picLocks noChangeAspect="1" /></p:cNvPicPr><p:nvPr /></p:nvPicPr><p:blipFill><a:blip r:embed="%s" /><a:stretch><a:fillRect /></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="%d" y="%d" /><a:ext cx="%d" cy="%d" /></a:xfrm><a:prstGeom prst="rect"><a:avLst /></a:prstGeom></p:spPr></p:pic><p:sp><p:nvSpPr><p:cNvPr id="95" name="%s" /><p:cNvSpPr txBox="1" /><p:nvPr /></p:nvSpPr><p:spPr><a:xfrm><a:off x="4001" y="6239" /><a:ext cx="9135998" cy="%d" /></a:xfrm><a:prstGeom prst="rect"><a:avLst /></a:prstGeom><a:ln w="12700"><a:miter lim="400000" /></a:ln><a:extLst><a:ext uri="{C572A759-6A51-4108-AA02-DFA0A04FC94B}"><ma14:wrappingTextBoxFlag xmlns:ma14="http://schemas.microsoft.com/office/mac/drawingml/2011/main" xmlns="" val="1" /></a:ext></a:extLst></p:spPr><p:txBody><a:bodyPr lIns="45719" rIns="45719"><a:spAutoFit /></a:bodyPr><a:lstStyle><a:lvl1pPr><a:defRPr sz="2400" /></a:lvl1pPr></a:lstStyle><a:p>%s</a:p></p:txBody></p:sp></p:spTree></p:cSld><p:clrMapOvr><a:masterClrMapping /></p:clrMapOvr></p:sld>`
func getSlideXml(boardPath []string, imageId string, top, left, width, height int) string {
func getSlideXml(boardPath []string, imageID string, top, left, width, height int) string {
var slideTitle string
boardName := boardPath[len(boardPath)-1]
prefixPath := boardPath[:len(boardPath)-1]
@ -69,7 +70,7 @@ func getSlideXml(boardPath []string, imageId string, top, left, width, height in
}
slideDescription := strings.Join(boardPath, " / ")
top += HEADER_HEIGHT
return fmt.Sprintf(SLIDE_XML, slideDescription, slideDescription, imageId, left, top, width, height, slideDescription, HEADER_HEIGHT, slideTitle)
return fmt.Sprintf(SLIDE_XML, slideDescription, slideDescription, imageID, left, top, width, height, slideDescription, HEADER_HEIGHT, slideTitle)
}
func getPresentationXmlRels(slideFileNames []string) string {

View file

@ -23,7 +23,9 @@ type Presentation struct {
Description string
Subject string
Creator string
D2Version string
// D2Version can't have letters, only numbers (`[0-9]`) and `.`
// Otherwise, it may fail to open in PowerPoint
D2Version string
Slides []*Slide
}
@ -60,16 +62,37 @@ func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) error {
// compute the size and position to fit the slide
// if the image is wider than taller and its aspect ratio is, at least, the same as the available image space aspect ratio
// then, set the image width to the available space and compute the height
// ┌──────────────────────────────────────────────────┐ ─┬─
// │ HEADER │ │
// ├──┬────────────────────────────────────────────┬──┤ │ ─┬─
// │ │ │ │ │ │
// │ │ │ │ SLIDE │
// │ │ │ │ HEIGHT │
// │ │ │ │ │ IMAGE
// │ │ │ │ │ HEIGHT
// │ │ │ │ │ │
// │ │ │ │ │ │
// │ │ │ │ │ │
// │ │ │ │ │ │
// └──┴────────────────────────────────────────────┴──┘ ─┴─ ─┴─
// ├────────────────────SLIDE WIDTH───────────────────┤
// ├─────────────────IMAGE WIDTH────────────────┤
if srcWidth/srcHeight >= IMAGE_ASPECT_RATIO {
// here, the image aspect ratio is, at least, equal to the slide aspect ratio
// so, it makes sense to expand the image horizontally to use as much as space as possible
width = SLIDE_WIDTH
height = int(float64(width) * (srcHeight / srcWidth))
// first, try to make the image as wide as the slide
// but, if this results in a tall image, use only the
// image adjusted width to avoid overlapping with the header
if height > IMAGE_HEIGHT {
// this would overflow with the title, so we need to adjust to use only IMAGE_WIDTH
width = IMAGE_WIDTH
height = int(float64(width) * (srcHeight / srcWidth))
}
} else {
// otherwise, this image could overflow the slide height/header
// here, the aspect ratio could be 4x3, in which the image is still wider than taller,
// but expanding horizontally would result in an overflow
// so, we expand to make it fit the available vertical space
height = IMAGE_HEIGHT
width = int(float64(height) * (srcWidth / srcHeight))
}
@ -106,11 +129,11 @@ func (p *Presentation) SaveTo(filePath string) error {
var slideFileNames []string
for i, slide := range p.Slides {
imageId := fmt.Sprintf("slide%dImage", i+1)
imageID := fmt.Sprintf("slide%dImage", i+1)
slideFileName := fmt.Sprintf("slide%d", i+1)
slideFileNames = append(slideFileNames, slideFileName)
imageWriter, err := zipWriter.Create(fmt.Sprintf("ppt/media/%s.png", imageId))
imageWriter, err := zipWriter.Create(fmt.Sprintf("ppt/media/%s.png", imageID))
if err != nil {
return err
}
@ -119,7 +142,7 @@ func (p *Presentation) SaveTo(filePath string) error {
return err
}
err = addFile(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), getRelsSlideXml(imageId))
err = addFile(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), getRelsSlideXml(imageID))
if err != nil {
return err
}
@ -127,7 +150,7 @@ func (p *Presentation) SaveTo(filePath string) error {
err = addFile(
zipWriter,
fmt.Sprintf("ppt/slides/%s.xml", slideFileName),
getSlideXml(slide.BoardPath, imageId, slide.ImageTop, slide.ImageLeft, slide.ImageWidth, slide.ImageHeight),
getSlideXml(slide.BoardPath, imageID, slide.ImageTop, slide.ImageLeft, slide.ImageWidth, slide.ImageHeight),
)
if err != nil {
return err