python-pptx icon indicating copy to clipboard operation
python-pptx copied to clipboard

feature: Slide.is_hidden

Open BarbianiM opened this issue 7 years ago • 14 comments

Guys,

any tips on how to add a hidden slide to a presentation or make one of its slides become hidden. Is it possible to do that with python-pptx, or do I have to go COM or some other lib?

Btw, great job! Been using python-pptx for a month now with awsome results.

BarbianiM avatar Sep 20 '17 17:09 BarbianiM

I'm not sure what a hidden slide is. Could you elaborate?

scanny avatar Sep 20 '17 19:09 scanny

From Microsoft (https://support.office.com/en-us/article/Hide-or-show-a-slide-8313e1ec-3e20-4464-952f-387931554d69):

If there is a slide that you need in your presentation, but you do not want it to appear in the slide show, you can hide the slide.

This is particularly useful when you have added slides to a presentation that provide different levels of detail on the subject matter, perhaps for different audiences. You can mark these slides as hidden so that they are not displayed in your main slide show, but you can still access them if you need to.

BarbianiM avatar Sep 21 '17 12:09 BarbianiM

Ah, interesting. I wasn't aware of that feature. PowerPoint is still the source of surprises after all these years :)

There's no API support for this yet.

If you wanted to develop a workaround function for it, the first step would be to discover how it's implemented in the XML. You could do a diff between a before an after presentation using opc-diag, or you could just inspect the XML in suspected areas. My first thought would be that there's something in the presentation.xml part that identifies hidden slides by slide-id. The other possibility is that there is something like a <p:hide val=true/> element toward the top of the slide{N}.xml part. If I didn't find it there I'd look in the app.xml or other settings parts.

opc-diag is good for that kind of casual inspection. I usually use the command:

opc browse my-presentation.pptx presentation.xml | vim -

Which feeds it right into my editor with code folding. Your mileage may vary depending on your editor's capability.

The diff command on opc-diag neccesarily picks up a fair number of "noise" diffs. To reduce those, create a minimal presentation (one empty slide) and save it. Then hide the slide and save it as the "after" version. This should reduce the noise enough to pick out the operative change in the XML.

opc-diag is here: https://github.com/python-openxml/opc-diag

There's a link to the docs on the GitHub home page and you can install it from PyPI using pip.

scanny avatar Sep 21 '17 20:09 scanny

Ty for the reply.

I used opc diff on a single blank slide presentation as you seggested and got this (noise cut out):

--- before/docProps/app.xml
+++ after/docProps/app.xml

@@ -10,7 +10,7 @@
-  <HiddenSlides>0</HiddenSlides>
+  <HiddenSlides>1</HiddenSlides>
   
--- before/ppt/slides/slide1.xml
+++ after/ppt/slides/slide1.xml

@@ -3,6 +3,7 @@
     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"
+    show="0"

Just an update on the hidden slides count @ app.xml and a simple show="0" @ slideN.xml

Would it be easy to include this feature on the API? If there is interest I guess that I could do it myself (with some pointers!)

BarbianiM avatar Sep 22 '17 16:09 BarbianiM

Hmm, interesting. I expect the show attribute is what gets it done. I suspect the <HiddenSlides/> element is only there to allow reporting of presentation status (like last save, this many slides, etc.) without having to completely load the deck.

So I think this code snippet will get the job done:

prs = Presentation('my-pres.pptx')
slide = prs.slides[0]  # or however you get the slide you want to hide
sld = slide._element  # the lxml element object for the `<p:sld>` XML element
sld.set('show', '0')

It's certainly worth a try.

As far as adding it to the API, I'll leave this issue open and we'll see if we can slip this in on a future release. Your feedback as to what behaviors this produces will be important to that effort.

scanny avatar Sep 22 '17 19:09 scanny

Implementation note: MS API protocol for this operation is:

Slide.SlideShowTransition.Hidden = True/False

There are eight other slide transition properties on the SlideShowTransition object such as AdvanceOnClick and SoundEffect.

scanny avatar Sep 22 '17 19:09 scanny

slide._element.set('show', '0') worked like a charm!

Thanks for the fast and very usefull replys. I hope this gets into a future release, or maybe a mention in the docs (example at the element section maybe?).

BarbianiM avatar Sep 25 '17 13:09 BarbianiM

Glad you got it working Barbiani :)

scanny avatar Sep 25 '17 20:09 scanny

I would really love to see this implemented as an attribute we could at least query.,

iraytrace avatar Mar 02 '21 13:03 iraytrace

Just FYI. I have the inverse problem, to check if a slide is hidden. Thanks for your suggestion, if the "show" attribute is "0" the slide is hidden. if it is None or, I think, "1" not. Thanks! mario

crystalfp avatar Apr 24 '21 05:04 crystalfp

Hi @crystalfp and @scanny Thank you for resolving this - I have a syntax question - I just need to check if a slide is hidden and delete it if so. I've been trying to access the show attribute but without success. Thanks!

Figured it out finally :) See code below

prs = Presentation('my-pres.pptx')
slide = prs.slides[0]  # or however you get the slide you want to hide
sld = slide._element  # the lxml element object for the `<p:sld>` XML element
sld.element.get("show")

0 maps to hidden, everything else (None or 1) is visible.

2sls avatar Jan 03 '23 17:01 2sls

Hi @2sls ! Looking at my old code, I found that to find if a slide is hidden, I used the following test:

        h = presentation.Slides(n).SlideShowTransition.Hidden
        if h:
               print("Is hidden")

Hope it helps mario

crystalfp avatar Jan 04 '23 08:01 crystalfp

This thread has been life-saving for my current project. I'm using the method of @2sls and it works very well – thank you! I would suggest that this goes into the official API. There are also questions on SO for this.

dcbbdc avatar Jun 27 '24 05:06 dcbbdc

I've actually coded this as something that can be controlled on a slide-by-slide basis in md2pptx now. Will release soon and push to GitHub sooner.

MartinPacker avatar Jun 29 '24 15:06 MartinPacker