onpoint/slides.py
2020-03-11 12:15:08 +01:00

68 lines
2.4 KiB
Python

import os
import pypandoc
import re
root = ""
# Compiles a single slide by splitting it up into single metadata and data
# attributes, loading them into the corresponding template, and returning the
# result.
def compile_slide(slide, root_directory):
global root
root = root_directory
slide = slide.strip()
slide_metadata = get_slide_metadata(slide)
slide_data = get_slide_data(slide)
slide = get_slide_layout(slide_metadata['layout'])
for key, value in slide_data.items():
placeholder = '@' + key
filler = convert_slide_content(value)
# print('replace', placeholder, 'with', filler)
if '@' + key in slide:
slide = slide.replace(placeholder, filler)
# very unelegant attempt at inline elements
slide = re.sub(r"<p>(.+?)</p>\n\(inline\)", r"\1", slide)
return slide
# Parses the metadata passage of a given slide and returns the metadata as a
# dictionary. For some items, default values are used if the slide does not
# contain them.
def get_slide_metadata(slide):
metadata = { 'layout': 'default' }
metadata_attributes = re.search('^@slide\((.+)\)', slide.splitlines()[0])
if metadata_attributes:
metadata_attributes = metadata_attributes.group(1).split(' ')
for attribute in metadata_attributes:
metadata[attribute.split('=')[0]] = attribute.split('=')[1]
return metadata
# Parses the data part of a given slide and returns dictionary of field names
# and corresponding raw values.
def get_slide_data(slide):
if slide.startswith('@slide'):
slide = slide[slide.find('\n')+1:] # cut off @slide declaration
slide_data = slide.strip().split('\n\n@')
slide_data = { item.split()[0].strip('@') : "\n".join(item.splitlines()[1:]) for item in slide_data }
return slide_data
# Reads the layout file for a given layout name and returns its content as a
# string.
def get_slide_layout(layout_name):
global root
try:
return open(os.path.join(root, 'layouts/' + layout_name + '.html'), 'r').read()
except FileNotFoundError:
raise Exception('Layout ' + layout_name + ' not found!')
# Calls the pandoc converter to convert a given Markdown string to HTML.
# Returns an HTML string.
def convert_slide_content(content):
filters = []
pdoc_args = [
'--mathjax' # Preparing formulas
]
return pypandoc.convert_text(
content, 'html',
format='md',
extra_args=pdoc_args,
filters=filters)