-
Notifications
You must be signed in to change notification settings - Fork 0
/
slider.py
155 lines (139 loc) · 5.45 KB
/
slider.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Blueprint, render_template, url_for,redirect
import shutil
import markdown
from collections import defaultdict
import codecs
import re, os
from mdx_mathjax import MathJaxExtension
slide = Blueprint('slide', __name__, url_prefix='/slides',static_folder='static')
DECK_SETTINGS_RE = {
'thankyou': u'^%\s*thankyou:(.*)$',
'thankyou_details': u'^%\s*thankyou_details:(.*)$',
'title': u'^%\s*title:(.*)$',
'subtitle': u'^%\s*subtitle:(.*)$',
'author': u'^%\s*author:(.*)$',
'contact': u'^%\s*contact:(.*)$',
'favicon': u'^%\s*favicon:(.*)$',
}
SLIDE_DIR = './content/slides/'
SLIDE_EXT = ".md"
def file_walk(dir):
slide_arr = []
for name in os.listdir(dir):
slid_dic = {}
full_name = os.path.join(dir, name)
if os.path.isdir(full_name):
pass
elif name.endswith(SLIDE_EXT):
_, settings = parse_deck_settings(codecs.open(full_name, encoding='utf8').read())
slid_dic['title'] = settings['title']
slid_dic['path'] = full_name
slide_arr.append(slid_dic)
return slide_arr
def parse_deck_settings(md):
"""Parse global settings for the slide deck, such as the author and
contact information.
Parameters
----------
md : unicode
The full markdown source of the slides
Returns
-------
md : unicode
The markdown source, after the settings have been removed, such
that they don't get actually put into the slides directly
settings : dict
A dict containing the settings. The keys wil be the set of keys
in DECK_SETTINGS_RE, modulo the keys that were actually parsed
from the document.
"""
settings = defaultdict(lambda: [])
for key, value in DECK_SETTINGS_RE.items():
found = True
while found:
m = re.search(value, md, re.MULTILINE)
if m:
settings[key].append(m.group(1))
md = md.replace(m.group(0), '')
else:
found = False
# if a setting is repeated, we join them together with a <br/> tag
# in between.
settings = {k: '<br/>'.join(v) for k, v in settings.items()}
print("Parsed slide deck settings, and found setting for: {:s}.".format(', '.join(settings.keys())))
# strip off the newline characters at the beginning and end of the document
# that might have been left
md = md.strip()
md = '\n'+md
return md, settings
def parse_metadata(section):
"""Given the first part of a slide, returns metadata associated with it."""
metadata = {}
metadata_lines = section.split('\n')
for line in metadata_lines:
colon_index = line.find(':')
if colon_index != -1:
key = line[:colon_index].strip()
val = line[colon_index + 1:].strip()
metadata[key] = val
return metadata
def postprocess_html(html, metadata):
"""Returns processed HTML to fit into the slide template format."""
if metadata.get('build_lists') and metadata['build_lists'] == 'true':
html = html.replace('<ul>', '<ul class="build">')
html = html.replace('<ol>', '<ol class="build">')
return html
def render_slides(md):
md, settings = parse_deck_settings(md)
md = md.replace('\r\n', '\n').replace('\n\r','\n')
md_slides = md.split('\n---\n')
#print("Compiled {:d} slides.".format(len(md_slides)))
slides = []
# Process each slide separately.
for md_slide in md_slides:
slide = {}
sections = md_slide.split('\n\n')
# Extract metadata at the beginning of the slide (look for key: value)
# pairs.
metadata_section = sections[0]
metadata = parse_metadata(metadata_section)
slide.update(metadata)
remainder_index = metadata and 1 or 0
# Get the content from the rest of the slide.
content_section = '\n\n'.join(sections[remainder_index:])
html = markdown.markdown(content_section, extensions=[MathJaxExtension(), 'markdown.extensions.tables'])
slide['content'] = postprocess_html(html, metadata)
slides.append(slide)
return settings,slides
@slide.route('/figures/<file>')
def home(file):
return redirect(url_for('static', filename='figures/'+file))
@slide.route('/')
def all_slides():
slide_arr = file_walk(SLIDE_DIR)
#pagination = Pagination(page=page, bs_version=3,total=len(g.all), per_page=PER_PAGE, record_name='posts')
#return render_template('ppt.html', slides=slide_arr, pagination=pagination)
return render_template('ppt.html', slides=slide_arr)
@slide.route('/<user_url_slug>')
def one_slide(user_url_slug=None):
# 做些处理
#print "here", user_url_slug
#return "hello "+ user_url_slug
if not user_url_slug:
markdown_fn = './slides.md'
else:
markdown_fn = u'{}/{}'.format(SLIDE_DIR, user_url_slug)
#markdown_fn ='./slides.md'
if not os.path.exists(markdown_fn):
raise OSError('The markdown file "%s" could not be found.' % markdown_fn)
md = codecs.open(markdown_fn, encoding='utf8').read()
settings, slides = render_slides(md)
return render_template('base_slide.html', slides=slides, settings=settings)
if __name__ == '__main__':
markdown_fn = './slides.md'
if not os.path.exists(markdown_fn):
raise OSError('The markdown file "%s" could not be found.' % markdown_fn)
md = codecs.open(markdown_fn, encoding='utf8').read()
render_slides(md)