Add basic fragment support
This commit is contained in:
parent
c0dd006177
commit
2c9f1388c3
29
fragments.py
Normal file
29
fragments.py
Normal file
@ -0,0 +1,29 @@
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
|
||||
from lxml import etree
|
||||
|
||||
FRAGMENT_PREFIX = "in"
|
||||
FRAGMENT_TAG = "^%s" % FRAGMENT_PREFIX
|
||||
FRAGMENT_CLASS = "fragment"
|
||||
|
||||
# Search and delete the FRAGMENT_TAG anywhere in the given HTML
|
||||
# while adding the FRAGMENT_CLASS as an attribute
|
||||
# @returns the HTML with all FRAGMENT_TAG instances shifted to an attribute
|
||||
def defragmentize(html):
|
||||
dom = etree.fromstring(html)
|
||||
fragments = dom.xpath("//*[contains(text(), '%s')]" % FRAGMENT_TAG)
|
||||
|
||||
for fragment in fragments:
|
||||
class_list = fragment.get('class')
|
||||
if class_list == None:
|
||||
class_list = FRAGMENT_CLASS
|
||||
else:
|
||||
class_list += " %s" % FRAGMENT_CLASS
|
||||
|
||||
fragment.set('class', class_list)
|
||||
fragment.text = re.sub(r"\W*\^%s\W*" % FRAGMENT_PREFIX, '', fragment.text).strip()
|
||||
|
||||
return etree.tostring(dom, method='html', encoding='utf-8',
|
||||
pretty_print=True).decode('utf-8')
|
||||
17
main.py
17
main.py
@ -6,6 +6,7 @@ import pypandoc
|
||||
import re
|
||||
import sys
|
||||
import yaml
|
||||
import fragments
|
||||
|
||||
root = ""
|
||||
lang = "de"
|
||||
@ -20,6 +21,7 @@ def compile(directory, language='en'):
|
||||
wrapper = open(os.path.join(root, 'layouts/root.html'), 'r').read()
|
||||
wrapper = wrapper.replace('@slides', compile_chapters())
|
||||
wrapper = insert_metadata(wrapper, lang=lang)
|
||||
wrapper = fragments.defragmentize(wrapper)
|
||||
with open(os.path.join(root, 'slides.' + lang + '.html'), 'w+') as output:
|
||||
output.write(wrapper)
|
||||
print('done')
|
||||
@ -31,7 +33,7 @@ def insert_metadata(content, lang=None):
|
||||
for key, value in metadata.items():
|
||||
placeholder = '@' + key
|
||||
filler = value[lang]
|
||||
print('replace', placeholder, 'with', filler)
|
||||
# print('replace', placeholder, 'with', filler)
|
||||
if '@' + key in content:
|
||||
content = content.replace(placeholder, filler)
|
||||
return content
|
||||
@ -72,7 +74,7 @@ def compile_slide(slide):
|
||||
for key, value in slide_data.items():
|
||||
placeholder = '@' + key
|
||||
filler = convert_slide_content(value)
|
||||
print('replace', placeholder, 'with', filler)
|
||||
# print('replace', placeholder, 'with', filler)
|
||||
if '@' + key in slide:
|
||||
slide = slide.replace(placeholder, filler)
|
||||
# very unelegant attempt at inline elements
|
||||
@ -112,7 +114,16 @@ def get_slide_layout(layout_name):
|
||||
# Calls the pandoc converter to convert a given Markdown string to HTML.
|
||||
# Returns an HTML string.
|
||||
def convert_slide_content(content):
|
||||
return pypandoc.convert_text(content, 'html', format='md')
|
||||
filters = []
|
||||
pdoc_args = [
|
||||
'--mathjax', # Preparing formulas
|
||||
'--smart' # Smart typography (dashes, ellipses, …)
|
||||
]
|
||||
return pypandoc.convert_text(
|
||||
content, 'html',
|
||||
format='md',
|
||||
extra_args=pdoc_args,
|
||||
filters=filters)
|
||||
|
||||
# Calls a YAML parser for the given relative path inside the presentation root
|
||||
# directory. Returns a dictionary with the YAML content.
|
||||
|
||||
@ -1 +1,2 @@
|
||||
pypandoc==1.4
|
||||
lxml==4.5.0
|
||||
54
slidify.js
54
slidify.js
@ -8,10 +8,19 @@ function init() {
|
||||
for (let i = 0; i < slides.length; i++) {
|
||||
slides[i].id = `slide${i}`;
|
||||
}
|
||||
goToSlide(0);
|
||||
resumeOrGoToStart();
|
||||
document.addEventListener('keydown', onKeyPressed);
|
||||
}
|
||||
|
||||
function resumeOrGoToStart() {
|
||||
let urlParts = window.location.href.split('#');
|
||||
if (urlParts.length > 1) {
|
||||
goToSlide(parseInt(urlParts[1].replace('slide', '')))
|
||||
} else {
|
||||
goToSlide(0)
|
||||
}
|
||||
}
|
||||
|
||||
function goToSlide(index) {
|
||||
if (index >= 0 && index < slides.length) {
|
||||
currentSlide = index;
|
||||
@ -20,11 +29,15 @@ function goToSlide(index) {
|
||||
}
|
||||
|
||||
function goToPreviousSlide() {
|
||||
goToSlide(currentSlide - 1);
|
||||
if (!showPreviousFragment()) {
|
||||
goToSlide(currentSlide - 1);
|
||||
}
|
||||
}
|
||||
|
||||
function goToNextSlide() {
|
||||
goToSlide(currentSlide + 1);
|
||||
if (!showNextFragment()) {
|
||||
goToSlide(currentSlide + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function goToFirstSlide() {
|
||||
@ -39,23 +52,42 @@ function onKeyPressed(event) {
|
||||
switch (event.keyCode) {
|
||||
case 34: // page down
|
||||
case 40: // arrow down
|
||||
case 39:
|
||||
// arrow right
|
||||
case 39: // arrow right
|
||||
goToNextSlide();
|
||||
break;
|
||||
case 33: // page up
|
||||
case 38: // arrow up
|
||||
case 37:
|
||||
// arrow left
|
||||
case 37: // arrow left
|
||||
goToPreviousSlide();
|
||||
break;
|
||||
case 36:
|
||||
// pos1
|
||||
case 36: // pos1
|
||||
goToFirstSlide();
|
||||
break;
|
||||
case 35:
|
||||
// end
|
||||
case 35: // end
|
||||
goToLastSlide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function showNextFragment() {
|
||||
let fragments = [... slides[currentSlide].querySelectorAll('.fragment')]
|
||||
let visible = [... slides[currentSlide].querySelectorAll('.fragment.visible')]
|
||||
|
||||
if (fragments.length == visible.length) {
|
||||
return false;
|
||||
} else {
|
||||
fragments[visible.length].classList.add('visible')
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function showPreviousFragment() {
|
||||
let visible = [...slides[currentSlide].querySelectorAll('.fragment.visible')]
|
||||
|
||||
if (visible.length == 0) {
|
||||
return false;
|
||||
} else {
|
||||
visible[visible.length - 1].classList.remove('visible')
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
window.addEventListener('load', init)
|
||||
|
||||
let slides
|
||||
let currentSlide
|
||||
|
||||
function init() {
|
||||
slides = Array.from(document.querySelectorAll('article'))
|
||||
for (let i=0; i<slides.length; i++) {
|
||||
slides[i].id = `slide${i}`
|
||||
}
|
||||
goToSlide(0)
|
||||
document.addEventListener('keydown', onKeyPressed)
|
||||
}
|
||||
|
||||
function goToSlide(index) {
|
||||
if (index >= 0 && index < slides.length) {
|
||||
currentSlide = index
|
||||
window.location.href = window.location.href.split('#')[0] + `#slide${index}`
|
||||
}
|
||||
}
|
||||
|
||||
function goToPreviousSlide() {
|
||||
goToSlide(currentSlide - 1)
|
||||
}
|
||||
|
||||
function goToNextSlide() {
|
||||
goToSlide(currentSlide + 1)
|
||||
}
|
||||
|
||||
function goToFirstSlide() {
|
||||
goToSlide(0)
|
||||
}
|
||||
|
||||
function goToLastSlide() {
|
||||
goToSlide(slides.length - 1)
|
||||
}
|
||||
|
||||
function onKeyPressed(event) {
|
||||
switch (event.keyCode) {
|
||||
case 34: // page down
|
||||
case 40: // arrow down
|
||||
case 39: // arrow right
|
||||
goToNextSlide()
|
||||
break
|
||||
case 33: // page up
|
||||
case 38: // arrow up
|
||||
case 37: // arrow left
|
||||
goToPreviousSlide()
|
||||
break
|
||||
case 36: // pos1
|
||||
goToFirstSlide()
|
||||
break
|
||||
case 35: // end
|
||||
goToLastSlide()
|
||||
break
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user