Ability to toggle bullet point formatting on run or paragraph
It would be nice to be able to change the bullet point formatting on a run or paragraph level. I would like to be able to have select text on a slide be bullet pointed while other text not. Also see the google group discussion for a similar request.
https://groups.google.com/d/topic/python-pptx/HhNBrUeqw_w/discussion
This would be very, very useful! Even being to toggle bullets for an entire textbox would be welcome.
:+1:
+1 Is there anyway to insert a bullet-point text-frame into an existing slide? The only way I can find to create a bullet point text frame is with a new bullet slide layout
I don't believe there is.
There would be two general ways to go about it:
- use a placeholder that was pre-configured to use bullet points
- configure a new text box to use bullet points
Either one would require some work with internals. If you could manage it, like if you were generating presentations from scratch, the best way might be to create a custom slide layout in your starting template .pptx that was laid out the way you wanted.
+1 - it would really be awesome to be able - in easy matter - to select the type of bullet. This would complete this really nice python package.
Great work !
My 2cts, since I have a similar problem domain: I want to have a text-box that uses bullet points - but I want to add a paragraph that does not use bullets in between; like a sub-heading. As recommended above, I use a placeholder that was pre-configured to use bullet points.
How to make a single paragraph not use bullets? I created an example in Powerpoint manually and looked at the XML source. It seems all is needed is the presence of a <a:buNone/> tag inside the paragraph (<a:pPr>).
python-pptx does not provide any method to do this, but I experimentally added a single line to https://github.com/scanny/python-pptx/blob/master/pptx/oxml/text.py#L462 (updated, thanks to @julienforgeat's comment below)
buNone = ZeroOrOne('a:buNone', successors=_tag_seq[11:])
This then allows me to do stuff like the following (target is the text_frame of my shape, the placeholder that is defined to use bullets):
p = target.add_paragraph()
p._pPr._add_buNone()
p.text = "I don't do bullets"
In Powerpoint, all paragraphs I add and do p._pPr._add_buNone() on are not bulleted, the rest are (default).
I don't know the intricacies of Powerpoint and neither this package/xmlchemy so well as to understand if my "fix" is legitimate or completely brain-dead. I can only see that for the use-case described above, it seems to work (and 2355 tests are still passing).
@pysailor thanks for the pointer! I've drafted a patch that allows setting a bullet property on paragraphs and seems to work (with LibreOffice Impress). (I'll pull request it later after writing tests and docs.) Example usage:
import pptx
prs = pptx.Presentation()
prs.slides.add_slide(prs.slide_layouts[1])
_, body, *_ = prs.slides[0].shapes.placeholders
p = body.text_frame.paragraphs[0]
p.text = "Hello Bullet World" # has a bullet (because of the default style)
prs.save("test1.pptx") # save off a "control" presentation
p.bullet = False # no bullet
prs.save("test2.pptx")
p.bullet = "★" # bullet is star character
prs.save("test3.pptx")
Any updates on this?
Um. I'm still intending to put together a proper pull request "when I have time." I fear that ascertainment of exactly how credible my mere "intent" is, must be left to the reader. :cold_sweat: :crying_cat_face: :skull_and_crossbones:
I am having similar need and I used @pysailor 's quick fix to make it work. Only thing is that now the code should be inserted at https://github.com/scanny/python-pptx/blob/master/pptx/oxml/text.py#L462
@pysailor , maybe you can edit your message too as I suspect I am not the only one ending up on this page. Unless there is a better fix now of course, anyway, thanks!
For anyone that is stuck with a template that forces bullets I figured out a quick workaround that can be used until python-pptx supports shutting off bullets.
from lxml import etree
# Get or create your paragraph object
p._pPr.insert(0, etree.Element("{http://schemas.openxmlformats.org/drawingml/2006/main}buNone"))
I realize it's ugly and I wished I had the time to build the feature properly and provide a pull request, but I don't.
@pysailor thanks for the pointer! I've drafted a patch that allows setting a
bulletproperty on paragraphs and seems to work (with LibreOffice Impress). (I'll pull request it later after writing tests and docs.) Example usage:感谢您的指点!我起草了一个补丁,允许在段落上设置bullet属性,并且似乎可以工作(使用 LibreOffice Impress)。(我稍后会在编写测试和文档后拉取请求。用法示例:import pptx prs = pptx.Presentation() prs.slides.add_slide(prs.slide_layouts[1]) _, body, *_ = prs.slides[0].shapes.placeholders p = body.text_frame.paragraphs[0] p.text = "Hello Bullet World" # has a bullet (because of the default style) prs.save("test1.pptx") # save off a "control" presentation p.bullet = False # no bullet prs.save("test2.pptx") p.bullet = "★" # bullet is star character prs.save("test3.pptx")
zackmdavis's solution was great, but I found that sometimes it doesn't work because lacking of buFont(bullet font) element inside the a:pPr try use this to detect and insert buFont
@bullet.setter
def bullet(self, value):
pPr = self._p.get_or_add_pPr()
if (
pPr.find(
"a:buFont",
namespaces={
"a": "http://schemas.openxmlformats.org/drawingml/2006/main"
},
)
is None
):
buFont = etree.Element(
"{http://schemas.openxmlformats.org/drawingml/2006/main}buFont",
typeface="Wingdings",
pitchFamily="2",
charset="2",
panose="05000000000000000000",
)
pPr.insert(0, buFont)
pPr.bullet = value
I added a pull request that implements this functionality. It's based on @zackmdavis's implementation but the paragraph.bullet takes a new class (currently) called BulletStyle. The reason for changing the interface is that we cannot be certain what the slide's default bullet looks like. This needs to be passed explicitly. However, it's still possible to toggle the bullet in the case brought up by @zoeesilcock:
p = text_frame.add_paragraph() # Has bullet if this is the default
p.bullet = BulletStyle.NO_BULLET # Now the bullet is explicitly turned off
p.bullet = BulletStyle.DEFAULT # Now the bullet is back, if this was the default
As a bonus, I have also implemented setting the paragraph to be part of a numbered list.
# Set to a numbered list
p.bullet = BulletStyle.numbered(MSO_NUMBERED_BULLET_STYLE.ARABIC_PERIOD)
# Set bullet to an "x" character
p.bullet = BulletStyle.custom("x")
Happy for any feedback! There is certainly room for improvement.