Skip to content

Instantly share code, notes, and snippets.

@navhaxs
Last active July 18, 2020 10:25
Show Gist options
  • Save navhaxs/7670e01f34ae609a1772f7271c5c49c8 to your computer and use it in GitHub Desktop.
Save navhaxs/7670e01f34ae609a1772f7271c5c49c8 to your computer and use it in GitHub Desktop.
A python script to convert pro6 to pptx slides
#!/usr/bin/env python3
import xml.etree.ElementTree as ET
import base64
import sys
import os
from pptx import Presentation
# Disclaimer: Also add your CCLI number to the copyright text if using output slides for a service!
# Pre-requisites: template.pptx should be an empty presentation with no slides, but with a customised master slide template
#################################################
# Usage: python pro6-to-pptx.py Hosanna.pro6
# Output: Hosanna.pptx (will overwrite existing file!)
#################################################
def insert_slides_for_group(group_uuid):
if group_uuid in groups:
list = groups[group_uuid]
for s in list:
slide_layout = prs.slide_layouts[1]
slide = prs.slides.add_slide(slide_layout)
shapes = slide.shapes
body_shape = shapes.placeholders[1]
tf = body_shape.text_frame
tf.level = None
#tf.text = os.linesep.join([sx for sx in s.splitlines() if sx])
tf.text = '\x0A'.join([sx for sx in s.splitlines() if sx])
# page number (does not work)
slide_number_placeholder = slide_layout.placeholders.get(12)
slide.shapes.clone_placeholder(slide_number_placeholder)
input = 'You Hold Me Now.pro6'
if len(sys.argv) == 2:
input = sys.argv[1]
tree = ET.parse(input)
root = tree.getroot()
if (root.attrib['category'] != "Song" and len(root.attrib['CCLISongNumber'])>0):
print("Skipped (not a Song/no CCLISongNumber)")
sys.exit()
songtitle = root.attrib['CCLISongTitle']
# copyright = root.attrib['CCLIAuthor'] + "\n\n" + root.attrib['CCLIPublisher'] + root.attrib['CCLICopyrightYear'] #+ " CCLI License #000000"
copyright = root.attrib['CCLIPublisher'] + " " + root.attrib['CCLICopyrightYear'] #+ " CCLI License #000000"
groups = {}
# XPath
for slides in tree.findall('.//RVSlideGrouping'):
if (slides.attrib['name'].lower() != "title"):
uuid = slides.attrib['uuid']
list = []
for slide in slides.findall('.//RVDisplaySlide'):
if slide.attrib['enabled'] != 'false':
for text_element in slide.findall('.//RVTextElement'):
# grab all text on the slide:
for string_part in text_element.findall('.//NSString'):
if (string_part.attrib['rvXMLIvarName'] == 'PlainText'):
slide_text = base64.b64decode(string_part.text).decode('UTF-8')
list.append(slide_text)
# exclude 'title' slides - i.e. if the entire slide's text literally matches the song title
# (could be bad if the slide is actually intended to be there)
#if (len(list) > 0 and list[0] == songtitle):
# list = list[1:]
groups[uuid] = list
# prs = Presentation()
prs = Presentation('template.pptx')
prs.core_properties.title = songtitle
title_slide_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_slide_layout)
title = slide.shapes.title
subtitle = slide.placeholders[1]
title.text = songtitle
subtitle.text = copyright
arrangements = tree.findall('.//RVSongArrangement')
if (len(arrangements) > 0):
# select just the first arrangement
arrangement = arrangements[0]
for group in arrangement.findall('.//NSString'):
insert_slides_for_group(group.text)
else:
for group in groups:
insert_slides_for_group(group)
blank_slide_layout = prs.slide_layouts[2]
final_blank_slide = prs.slides.add_slide(blank_slide_layout)
prs.save(input.replace('pro6','pptx'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment