68 lines
2.4 KiB
Python
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) |