fix conflicts
This commit is contained in:
parent
ac0c9105ff
commit
8322261d24
6 changed files with 154 additions and 85 deletions
|
|
@ -368,13 +368,9 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende
|
|||
rootName := getFileName(outputPath)
|
||||
// version must be only numbers to avoid issues with PowerPoint
|
||||
p := pptx.NewPresentation(rootName, description, rootName, username, version.OnlyNumbers())
|
||||
<<<<<<< HEAD
|
||||
|
||||
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, outputPath, page, diagram, nil)
|
||||
>>>>>>> gh-821-ppt
|
||||
svg, err := renderPPTX(ctx, ms, p, plugin, renderOpts, ruler, outputPath, page, diagram, nil, boardIdToIndex)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
|
@ -763,11 +759,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
|||
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) 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
|
||||
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) {
|
||||
var currBoardPath []string
|
||||
// Root board doesn't have a name, so we use the output filename
|
||||
if diagram.Name == "" {
|
||||
|
|
@ -814,7 +806,7 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
return nil, err
|
||||
}
|
||||
|
||||
slide, err := presentation.AddSlide(pngImg, diagram, currBoardPath)
|
||||
slide, err := presentation.AddSlide(pngImg, currBoardPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -822,11 +814,11 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
viewboxSlice := appendix.FindViewboxSlice(svg)
|
||||
viewboxX, err := strconv.ParseFloat(viewboxSlice[0], 64)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
viewboxY, err := strconv.ParseFloat(viewboxSlice[1], 64)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Draw links
|
||||
|
|
@ -859,31 +851,19 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
}
|
||||
|
||||
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, "", page, dl, currBoardPath)
|
||||
>>>>>>> gh-821-ppt
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
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, "", page, dl, currBoardPath)
|
||||
>>>>>>> gh-821-ppt
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
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, "", page, dl, currBoardPath)
|
||||
>>>>>>> gh-821-ppt
|
||||
_, err := renderPPTX(ctx, ms, presentation, plugin, opts, ruler, "", page, dl, currBoardPath, boardIdToIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,7 +249,9 @@ layers: {
|
|||
name: "how_to_solve_problems_pptx",
|
||||
skipCI: true,
|
||||
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: {
|
||||
1: {
|
||||
w: write down the problem
|
||||
|
|
@ -261,6 +263,9 @@ steps: {
|
|||
3: {
|
||||
t -> w2
|
||||
w2: write down the solution
|
||||
w2: {
|
||||
link: https://d2lang.com
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
|
|
|||
101
lib/pptx/pptx.go
101
lib/pptx/pptx.go
|
|
@ -32,14 +32,38 @@ type Presentation struct {
|
|||
|
||||
Slides []*Slide
|
||||
}
|
||||
|
||||
type Slide struct {
|
||||
BoardPath []string
|
||||
Links []*Link
|
||||
Image []byte
|
||||
ImageId string
|
||||
ImageWidth 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 {
|
||||
|
|
@ -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))
|
||||
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
|
||||
|
|
@ -99,22 +123,24 @@ func (p *Presentation) AddSlide(pngContent []byte, boardPath []string) error {
|
|||
height = IMAGE_HEIGHT
|
||||
width = int(float64(height) * (srcWidth / srcHeight))
|
||||
}
|
||||
top := (IMAGE_HEIGHT - height) / 2
|
||||
top := HEADER_HEIGHT + ((IMAGE_HEIGHT - height) / 2)
|
||||
left := (SLIDE_WIDTH - width) / 2
|
||||
|
||||
slide := &Slide{
|
||||
BoardPath: make([]string, len(boardPath)),
|
||||
ImageId: fmt.Sprintf("slide%dImage", len(p.Slides)+1),
|
||||
Image: pngContent,
|
||||
ImageWidth: width,
|
||||
ImageHeight: height,
|
||||
ImageTop: top,
|
||||
ImageLeft: left,
|
||||
ImageScaleFactor: float64(width) / srcWidth,
|
||||
}
|
||||
// it must copy the board path to avoid slice reference issues
|
||||
copy(slide.BoardPath, boardPath)
|
||||
|
||||
p.Slides = append(p.Slides, slide)
|
||||
return nil
|
||||
return slide, nil
|
||||
}
|
||||
|
||||
func (p *Presentation) SaveTo(filePath string) error {
|
||||
|
|
@ -145,10 +171,7 @@ func (p *Presentation) SaveTo(filePath string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = addFileFromTemplate(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), RELS_SLIDE_XML, RelsSlideXmlContent{
|
||||
FileName: imageID,
|
||||
RelationshipID: imageID,
|
||||
})
|
||||
err = addFileFromTemplate(zipWriter, fmt.Sprintf("ppt/slides/_rels/%s.xml.rels", slideFileName), RELS_SLIDE_XML, getSlideXmlRelsContent(imageID, slide))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -242,14 +265,49 @@ func copyPptxTemplateTo(w *zip.Writer) error {
|
|||
//go:embed templates/slide.xml.rels
|
||||
var RELS_SLIDE_XML string
|
||||
|
||||
type RelsSlideXmlLinkContent struct {
|
||||
RelationshipID string
|
||||
ExternalUrl string
|
||||
SlideIndex int
|
||||
}
|
||||
|
||||
type RelsSlideXmlContent struct {
|
||||
FileName 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
|
||||
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 {
|
||||
Title string
|
||||
TitlePrefix string
|
||||
|
|
@ -260,6 +318,8 @@ type SlideXmlContent struct {
|
|||
ImageTop int
|
||||
ImageWidth int
|
||||
ImageHeight int
|
||||
|
||||
Links []SlideLinkXmlContent
|
||||
}
|
||||
|
||||
func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent {
|
||||
|
|
@ -270,17 +330,36 @@ func getSlideXmlContent(imageID string, slide *Slide) SlideXmlContent {
|
|||
if len(prefixPath) > 0 {
|
||||
prefix = strings.Join(prefixPath, " / ") + " / "
|
||||
}
|
||||
return SlideXmlContent{
|
||||
content := SlideXmlContent{
|
||||
Title: boardName,
|
||||
TitlePrefix: prefix,
|
||||
Description: strings.Join(boardPath, " / "),
|
||||
HeaderHeight: HEADER_HEIGHT,
|
||||
ImageID: imageID,
|
||||
ImageLeft: slide.ImageLeft,
|
||||
ImageTop: slide.ImageTop + HEADER_HEIGHT,
|
||||
ImageTop: slide.ImageTop,
|
||||
ImageWidth: slide.ImageWidth,
|
||||
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
|
||||
|
|
|
|||
|
|
@ -75,19 +75,44 @@
|
|||
<a:defRPr sz="2400" />
|
||||
</a:lvl1pPr>
|
||||
</a:lstStyle>
|
||||
<a:p>
|
||||
{{if .TitlePrefix}}
|
||||
<a:r>
|
||||
<a:p> {{if .TitlePrefix}} <a:r>
|
||||
<a:t>{{.TitlePrefix}}</a:t>
|
||||
</a:r>
|
||||
{{end}}
|
||||
<a:r>
|
||||
</a:r> {{end}} <a:r>
|
||||
<a:rPr b="1" />
|
||||
<a:t>{{.Title}}</a:t>
|
||||
</a:r>
|
||||
</a:p>
|
||||
</p:txBody>
|
||||
</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:cSld>
|
||||
<p:clrMapOvr>
|
||||
|
|
|
|||
|
|
@ -6,4 +6,11 @@
|
|||
<Relationship Id="{{.RelationshipID}}"
|
||||
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
|
||||
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>
|
||||
|
|
@ -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>
|
||||
Loading…
Reference in a new issue