fix conflicts

This commit is contained in:
Júlio César Batista 2023-04-10 17:16:01 -03:00
parent ac0c9105ff
commit 8322261d24
No known key found for this signature in database
GPG key ID: 10C4B861BF314878
6 changed files with 154 additions and 85 deletions

View file

@ -368,13 +368,9 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende
rootName := getFileName(outputPath) rootName := getFileName(outputPath)
// version must be only numbers to avoid issues with PowerPoint // version must be only numbers to avoid issues with PowerPoint
p := pptx.NewPresentation(rootName, description, rootName, username, version.OnlyNumbers()) p := pptx.NewPresentation(rootName, description, rootName, username, version.OnlyNumbers())
<<<<<<< HEAD
boardIdToIndex := buildBoardIdToIndex(diagram, nil, nil) boardIdToIndex := buildBoardIdToIndex(diagram, nil, nil)
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)
=======
svg, err := renderPPTX(ctx, ms, p, plugin, renderOpts, outputPath, page, diagram, nil)
>>>>>>> gh-821-ppt
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }
@ -763,11 +759,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
return svg, nil return svg, nil
} }
<<<<<<< HEAD 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 []string, boardIdToIndex map[string]int) error {
=======
func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Presentation, plugin d2plugin.Plugin, opts d2svg.RenderOpts, outputPath string, page playwright.Page, diagram *d2target.Diagram, boardPath []string) ([]byte, error) {
>>>>>>> gh-821-ppt
var currBoardPath []string var currBoardPath []string
// 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 == "" {
@ -814,7 +806,7 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
return nil, err return nil, err
} }
slide, err := presentation.AddSlide(pngImg, diagram, currBoardPath) slide, err := presentation.AddSlide(pngImg, currBoardPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -822,11 +814,11 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
viewboxSlice := appendix.FindViewboxSlice(svg) viewboxSlice := appendix.FindViewboxSlice(svg)
viewboxX, err := strconv.ParseFloat(viewboxSlice[0], 64) viewboxX, err := strconv.ParseFloat(viewboxSlice[0], 64)
if err != nil { if err != nil {
return err return nil, err
} }
viewboxY, err := strconv.ParseFloat(viewboxSlice[1], 64) viewboxY, err := strconv.ParseFloat(viewboxSlice[1], 64)
if err != nil { if err != nil {
return err return nil, err
} }
// Draw links // Draw links
@ -859,31 +851,19 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
} }
for _, dl := range diagram.Layers { for _, dl := range diagram.Layers {
<<<<<<< HEAD _, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
=======
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, "", page, dl, currBoardPath)
>>>>>>> gh-821-ppt
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
for _, dl := range diagram.Scenarios { for _, dl := range diagram.Scenarios {
<<<<<<< HEAD _, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
=======
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, "", page, dl, currBoardPath)
>>>>>>> gh-821-ppt
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
for _, dl := range diagram.Steps { for _, dl := range diagram.Steps {
<<<<<<< HEAD _, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
=======
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, "", page, dl, currBoardPath)
>>>>>>> gh-821-ppt
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -249,7 +249,9 @@ layers: {
name: "how_to_solve_problems_pptx", name: "how_to_solve_problems_pptx",
skipCI: true, skipCI: true,
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "in.d2", `how to solve a hard problem? writeFile(t, dir, "in.d2", `how to solve a hard problem? {
link: steps.2
}
steps: { steps: {
1: { 1: {
w: write down the problem w: write down the problem
@ -261,6 +263,9 @@ steps: {
3: { 3: {
t -> w2 t -> w2
w2: write down the solution w2: write down the solution
w2: {
link: https://d2lang.com
}
} }
} }
`) `)

View file

@ -32,14 +32,38 @@ type Presentation struct {
Slides []*Slide Slides []*Slide
} }
type Slide struct { type Slide struct {
BoardPath []string BoardPath []string
Image []byte Links []*Link
ImageWidth int Image []byte
ImageHeight int ImageId string
ImageTop int ImageWidth int
ImageLeft int ImageHeight int
ImageTop int
ImageLeft int
ImageScaleFactor float64
}
func (s *Slide) AddLink(link *Link) {
link.Index = len(s.Links)
s.Links = append(s.Links, link)
link.ID = fmt.Sprintf("link%d", len(s.Links))
link.Height *= int(s.ImageScaleFactor)
link.Width *= int(s.ImageScaleFactor)
link.Top = s.ImageTop + int(float64(link.Top)*s.ImageScaleFactor)
link.Left = s.ImageLeft + int(float64(link.Left)*s.ImageScaleFactor)
}
type Link struct {
ID string
Index int
Top int
Left int
Width int
Height int
SlideIndex int
ExternalUrl string
Tooltip string
} }
func NewPresentation(title, description, subject, creator, d2Version string) *Presentation { func NewPresentation(title, description, subject, creator, d2Version string) *Presentation {
@ -52,10 +76,10 @@ func NewPresentation(title, description, subject, creator, d2Version string) *Pr
} }
} }
func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) error { func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) (*Slide, error) {
src, err := png.Decode(bytes.NewReader(pngContent)) src, err := png.Decode(bytes.NewReader(pngContent))
if err != nil { if err != nil {
return fmt.Errorf("error decoding PNG image: %v", err) return nil, fmt.Errorf("error decoding PNG image: %v", err)
} }
var width, height int var width, height int
@ -99,22 +123,24 @@ func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) error {
height = IMAGE_HEIGHT height = IMAGE_HEIGHT
width = int(float64(height) * (srcWidth / srcHeight)) width = int(float64(height) * (srcWidth / srcHeight))
} }
top := (IMAGE_HEIGHT - height) / 2 top := HEADER_HEIGHT + ((IMAGE_HEIGHT - height) / 2)
left := (SLIDE_WIDTH - width) / 2 left := (SLIDE_WIDTH - width) / 2
slide := &Slide{ slide := &Slide{
BoardPath: make([]string, len(boardPath)), BoardPath: make([]string, len(boardPath)),
Image: pngContent, ImageId: fmt.Sprintf("slide%dImage", len(p.Slides)+1),
ImageWidth: width, Image: pngContent,
ImageHeight: height, ImageWidth: width,
ImageTop: top, ImageHeight: height,
ImageLeft: left, ImageTop: top,
ImageLeft: left,
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) copy(slide.BoardPath, boardPath)
p.Slides = append(p.Slides, slide) p.Slides = append(p.Slides, slide)
return nil return slide, nil
} }
func (p *Presentation) SaveTo(filePath string) error { func (p *Presentation) SaveTo(filePath string) error {
@ -145,10 +171,7 @@ func (p *Presentation) SaveTo(filePath string) error {
return err return err
} }
err = addFileFromTemplate(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), RELS_SLIDE_XML, RelsSlideXmlContent{ err = addFileFromTemplate(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), RELS_SLIDE_XML, getSlideXmlRelsContent(imageID, slide))
FileName: imageID,
RelationshipID: imageID,
})
if err != nil { if err != nil {
return err return err
} }
@ -242,14 +265,49 @@ func copyPptxTemplateTo(w *zip.Writer) error {
//go:embed templates/slide.xml.rels //go:embed templates/slide.xml.rels
var RELS_SLIDE_XML string var RELS_SLIDE_XML string
type RelsSlideXmlLinkContent struct {
RelationshipID string
ExternalUrl string
SlideIndex int
}
type RelsSlideXmlContent struct { type RelsSlideXmlContent struct {
FileName string FileName string
RelationshipID string RelationshipID string
Links []RelsSlideXmlLinkContent
}
func getSlideXmlRelsContent(imageID string, slide *Slide) RelsSlideXmlContent {
content := RelsSlideXmlContent{
FileName: imageID,
RelationshipID: imageID,
}
for _, link := range slide.Links {
content.Links = append(content.Links, RelsSlideXmlLinkContent{
RelationshipID: link.ID,
ExternalUrl: link.ExternalUrl,
SlideIndex: link.SlideIndex,
})
}
return content
} }
//go:embed templates/slide.xml //go:embed templates/slide.xml
var SLIDE_XML string var SLIDE_XML string
type SlideLinkXmlContent struct {
ID int
RelationshipID string
Name string
Action string
Left int
Top int
Width int
Height int
}
type SlideXmlContent struct { type SlideXmlContent struct {
Title string Title string
TitlePrefix string TitlePrefix string
@ -260,6 +318,8 @@ type SlideXmlContent struct {
ImageTop int ImageTop int
ImageWidth int ImageWidth int
ImageHeight int ImageHeight int
Links []SlideLinkXmlContent
} }
func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent { func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent {
@ -270,17 +330,36 @@ func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent {
if len(prefixPath) > 0 { if len(prefixPath) > 0 {
prefix = strings.Join(prefixPath, " / ") + " / " prefix = strings.Join(prefixPath, " / ") + " / "
} }
return SlideXmlContent{ content := SlideXmlContent{
Title: boardName, Title: boardName,
TitlePrefix: prefix, TitlePrefix: prefix,
Description: strings.Join(boardPath, " / "), Description: strings.Join(boardPath, " / "),
HeaderHeight: HEADER_HEIGHT, HeaderHeight: HEADER_HEIGHT,
ImageID: imageID, ImageID: imageID,
ImageLeft: slide.ImageLeft, ImageLeft: slide.ImageLeft,
ImageTop: slide.ImageTop + HEADER_HEIGHT, ImageTop: slide.ImageTop,
ImageWidth: slide.ImageWidth, ImageWidth: slide.ImageWidth,
ImageHeight: slide.ImageHeight, ImageHeight: slide.ImageHeight,
} }
for _, link := range slide.Links {
var action string
if link.ExternalUrl == "" {
action = "ppaction://hlinksldjump"
}
content.Links = append(content.Links, SlideLinkXmlContent{
ID: link.Index,
RelationshipID: link.ID,
Name: link.Tooltip,
Action: action,
Left: link.Left,
Top: link.Top,
Width: link.Width,
Height: link.Height,
})
}
return content
} }
//go:embed templates/rels_presentation.xml //go:embed templates/rels_presentation.xml

View file

@ -75,19 +75,44 @@
<a:defRPr sz="2400" /> <a:defRPr sz="2400" />
</a:lvl1pPr> </a:lvl1pPr>
</a:lstStyle> </a:lstStyle>
<a:p> <a:p> {{if .TitlePrefix}} <a:r>
{{if .TitlePrefix}}
<a:r>
<a:t>{{.TitlePrefix}}</a:t> <a:t>{{.TitlePrefix}}</a:t>
</a:r> </a:r> {{end}} <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>
</a:p> </a:p>
</p:txBody> </p:txBody>
</p:sp> </p:sp>
{{range .Links}}
<p:sp>
<p:nvSpPr>
<p:cNvPr id="{{.ID}}" name="{{.Name}}">
<a:hlinkClick r:id="{{.RelationshipID}}" action="{{.Action}}" tooltip="{{.Name}}" history="1" invalidUrl=""
tgtFrame="" highlightClick="0" endSnd="0" />
</p:cNvPr>
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="{{.Left}}" y="{{.Top}}" />
<a:ext cx="{{.Width}}" cy="{{.Height}}" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
<a:solidFill>
<a:srgbClr val="FFFFFF">
<a:alpha val="0" />
</a:srgbClr>
</a:solidFill>
<a:ln w="12700">
<a:miter lim="400000" />
</a:ln>
</p:spPr>
</p:sp>
{{end}}
</p:spTree> </p:spTree>
</p:cSld> </p:cSld>
<p:clrMapOvr> <p:clrMapOvr>

View file

@ -6,4 +6,11 @@
<Relationship Id="{{.RelationshipID}}" <Relationship Id="{{.RelationshipID}}"
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
Target="../media/{{.FileName}}.png" /> Target="../media/{{.FileName}}.png" />
{{range .Links}}
{{if .ExternalUrl}}
<Relationship Id="{{.RelationshipID}}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="{{.ExternalUrl}}" TargetMode="External" />
{{else}}
<Relationship Id="{{.RelationshipID}}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slide{{.SlideIndex}}.xml" />
{{end}}
{{end}}
</Relationships> </Relationships>

View file

@ -1,27 +0,0 @@
<p:sp>
<p:nvSpPr>
<p:cNvPr id="%d" name="%s">
<a:hlinkClick r:id="%s" action="%s" tooltip="%s" history="1" invalidUrl="" tgtFrame=""
highlightClick="0" endSnd="0" />
</p:cNvPr>
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<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>
<a:solidFill>
<a:srgbClr val="FFFFFF">
<a:alpha val="0" />
</a:srgbClr>
</a:solidFill>
<a:ln w="12700">
<a:miter lim="400000" />
</a:ln>
</p:spPr>
</p:sp>