PPTX.jl icon indicating copy to clipboard operation
PPTX.jl copied to clipboard

Add layout support via GridLayoutBase

Open DrChainsaw opened this issue 7 months ago • 2 comments

This adds support for layouting slides using GridLayoutBase as suggested in #48 with the big disclaimer that I don't think I'm even close to groking everything the package is capable of.

Fwiw, I asked if using GridLayoutBase outside of Makie here and got a reply from the maintainer.

I have tried to make as few changes as possible to existing codebase to make reviewing easier for now.

The API is basically identical to the suggestion in https://github.com/ASML-Labs/PPTX.jl/issues/48#issuecomment-2230149847.

Example
 sl = ShapeLayout(Slide(;title="Layout Test"))

 sl[1,1] = TextBox("Upper left")
 sl[2,2] = TextBox("Lower right")
 sl12 = sl[1,2] = ShapeLayout(sl)
 sl12[1,1] = TextBox("Upper right => Upper left"; size_x=80)
 sl12[1,2] = TextBox("Upper right => Upper right"; size_x=80)
 sl12[2,1] = TextBox("Upper right => Lower left"; size_x=80)
 sl12[2,2] = TextBox("Upper right => Lower right"; size_x=80)

 sl21 = sl[2,1] = ShapeLayout(sl)
 sl21[1,1] = TextBox("Lower left => Upper left"; size_x=80)
 sl21[1,2] = TextBox("Lower left => Upper right"; size_x=80)
 sl21[2,1] = TextBox("Lower left => Middle left"; size_x=80)
 sl21[2,2] = TextBox("Lower left => Middle right"; size_x=80)
 sl21[3,1] = TextBox("To be replaced and not seen in ppt"; size_x=80)
 sl21[3,1] = TextBox("Lower left => Lower left"; size_x=80)
 sl21[3,2] = TextBox("Lower left => Lower right"; size_x=80)

 pp = Presentation([sl.slide])
 PPTX.write("c:/temp/layouttest.pptx", pp, overwrite = true, open_ppt=true)

Produces the following slide: <IMG src="https://github.com/user-attachments/assets/dd40d1aa-c8d8-45f8-92c4-4e90fdf01e36" alt="image.png"/>

I would have preferred and API where the ShapeLayout does not implicitly modify the Slide and instead was added as just another shape.

The reason this does not fly here is that make_slide assumes that each element of shape is one single unique shape. Rewriting make_xml so it returns a next shape id and an array of arrays with xml would allow for the shapes in Slide.shapes to be a ShapeLayout (which may contain other ShapeLayouts).

I'm also not sure how much users are expected to interact with the GridLayout. The current implementation has some gottchas for such users, mainly that all units are in EMU (just to make things consistent with the rest of PPTX) and that top and bottom use negative values since the y-axis is pointing from top of the slide to the bottom in PPTX while GridLayoutBase assumes the opposite. This is somewhat protected against by wrapping the GridLayout in ShapeLayout so that accessing it becomes accessing package internals.

I realized when I was implementing that PPTX.jl does not seem to have functionality for importing/interpreting the slide layout integer given to power point. If it did, it would be much easier to give reasonable defaults for the ShapeLayout bounding box.

DrChainsaw avatar Jul 20 '24 00:07 DrChainsaw