Compare commits

...

5 Commits

Author SHA1 Message Date
241f54f7d3 Simplify example 2020-02-07 21:36:08 +01:00
fa0cf86fa0 Fix language retrieval 2020-02-07 21:33:20 +01:00
dba005e8c1 Add basic styles 2020-02-07 21:33:12 +01:00
2c9f1388c3 Add basic fragment support 2020-02-07 21:32:57 +01:00
c0dd006177 Fix missing tag ends 2020-02-07 21:29:31 +01:00
10 changed files with 152 additions and 125 deletions

29
fragments.py Normal file
View 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')

25
main.py
View File

@ -6,6 +6,7 @@ import pypandoc
import re import re
import sys import sys
import yaml import yaml
import fragments
root = "" root = ""
lang = "de" lang = "de"
@ -20,6 +21,7 @@ def compile(directory, language='en'):
wrapper = open(os.path.join(root, 'layouts/root.html'), 'r').read() wrapper = open(os.path.join(root, 'layouts/root.html'), 'r').read()
wrapper = wrapper.replace('@slides', compile_chapters()) wrapper = wrapper.replace('@slides', compile_chapters())
wrapper = insert_metadata(wrapper, lang=lang) wrapper = insert_metadata(wrapper, lang=lang)
wrapper = fragments.defragmentize(wrapper)
with open(os.path.join(root, 'slides.' + lang + '.html'), 'w+') as output: with open(os.path.join(root, 'slides.' + lang + '.html'), 'w+') as output:
output.write(wrapper) output.write(wrapper)
print('done') print('done')
@ -31,7 +33,7 @@ def insert_metadata(content, lang=None):
for key, value in metadata.items(): for key, value in metadata.items():
placeholder = '@' + key placeholder = '@' + key
filler = value[lang] filler = value[lang]
print('replace', placeholder, 'with', filler) # print('replace', placeholder, 'with', filler)
if '@' + key in content: if '@' + key in content:
content = content.replace(placeholder, filler) content = content.replace(placeholder, filler)
return content return content
@ -72,7 +74,7 @@ def compile_slide(slide):
for key, value in slide_data.items(): for key, value in slide_data.items():
placeholder = '@' + key placeholder = '@' + key
filler = convert_slide_content(value) filler = convert_slide_content(value)
print('replace', placeholder, 'with', filler) # print('replace', placeholder, 'with', filler)
if '@' + key in slide: if '@' + key in slide:
slide = slide.replace(placeholder, filler) slide = slide.replace(placeholder, filler)
# very unelegant attempt at inline elements # 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. # Calls the pandoc converter to convert a given Markdown string to HTML.
# Returns an HTML string. # Returns an HTML string.
def convert_slide_content(content): 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 # Calls a YAML parser for the given relative path inside the presentation root
# directory. Returns a dictionary with the YAML content. # directory. Returns a dictionary with the YAML content.
@ -124,9 +135,9 @@ def read_yaml(path):
except yaml.YAMLError as exc: except yaml.YAMLError as exc:
print(exc) print(exc)
# # Retrieve the available languages as stated in the meta.yml (key: language).
def get_available_languages(): def get_available_languages(root):
return read_yaml('./meta.yml')['language'] return read_yaml(os.path.join(root, 'meta.yml'))['language']
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -136,7 +147,7 @@ if __name__ == '__main__':
args = parser.parse_args() args = parser.parse_args()
if args.language == "all": if args.language == "all":
for language in get_available_languages(): for language in get_available_languages(args.rootdirectory):
compile(args.rootdirectory, language=language) compile(args.rootdirectory, language=language)
else: else:
compile(args.rootdirectory, language=args.language) compile(args.rootdirectory, language=args.language)

View File

@ -1 +1,2 @@
pypandoc==1.4 pypandoc==1.4
lxml==4.5.0

View File

@ -8,10 +8,19 @@ function init() {
for (let i = 0; i < slides.length; i++) { for (let i = 0; i < slides.length; i++) {
slides[i].id = `slide${i}`; slides[i].id = `slide${i}`;
} }
goToSlide(0); resumeOrGoToStart();
document.addEventListener('keydown', onKeyPressed); 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) { function goToSlide(index) {
if (index >= 0 && index < slides.length) { if (index >= 0 && index < slides.length) {
currentSlide = index; currentSlide = index;
@ -20,11 +29,15 @@ function goToSlide(index) {
} }
function goToPreviousSlide() { function goToPreviousSlide() {
goToSlide(currentSlide - 1); if (!showPreviousFragment()) {
goToSlide(currentSlide - 1);
}
} }
function goToNextSlide() { function goToNextSlide() {
goToSlide(currentSlide + 1); if (!showNextFragment()) {
goToSlide(currentSlide + 1);
}
} }
function goToFirstSlide() { function goToFirstSlide() {
@ -39,23 +52,42 @@ function onKeyPressed(event) {
switch (event.keyCode) { switch (event.keyCode) {
case 34: // page down case 34: // page down
case 40: // arrow down case 40: // arrow down
case 39: case 39: // arrow right
// arrow right
goToNextSlide(); goToNextSlide();
break; break;
case 33: // page up case 33: // page up
case 38: // arrow up case 38: // arrow up
case 37: case 37: // arrow left
// arrow left
goToPreviousSlide(); goToPreviousSlide();
break; break;
case 36: case 36: // pos1
// pos1
goToFirstSlide(); goToFirstSlide();
break; break;
case 35: case 35: // end
// end
goToLastSlide(); goToLastSlide();
break; 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;
}
}

View File

@ -1,14 +1,14 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="@language"> <html lang="@language">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<link rel="stylesheet" href="styles/style.scss"> <link rel="stylesheet" href="styles/style.css"/>
<title>@title</title> <title>@title</title>
</head> </head>
<body> <body>
@slides <!-- reserved keyword --> @slides <!-- reserved keyword -->
<script src="scripts/slidify.js"></script> <script src="../slidify.js"></script>
</body> </body>
</html> </html>

View File

@ -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
}
}

View File

@ -6,11 +6,11 @@ Wirklich auf den Punkt!
@slide @slide
@title @title
Wirklich auf den Punkt! ^in Wirklich auf den Punkt!
@content @content
* Stichpunkt 1 * ^in Stichpunkt 1
* Stichpunkt 2 * ^in Stichpunkt 2
* Stichpunkt 3 * ^in Stichpunkt 3
* Stichpunkt 4 * ^in Stichpunkt 4

View File

@ -1,10 +1,4 @@
@slide(layout=titlepage) @slide(layout=titlepage)
@title @title
Wirklich auf den Punkt! Ende
@content
* Stichpunkt 1
* Stichpunkt 2
* Stichpunkt 3
* Stichpunkt 4

50
test/styles/style.css Normal file
View File

@ -0,0 +1,50 @@
* {
box-sizing: border-box;
}
html {
margin: 0;
padding: 0;
overflow: hidden;
font-size: 16pt;
}
h1 {
font-size: 2.4rem;
}
.fragment {
opacity: 0;
transition: .3s opacity ease-in-out;
}
.fragment.visible {
opacity: 1;
}
@media screen {
body {
background: black;
margin: 0;
padding: 0;
}
section {
display: contents;
}
article {
display: none;
align-items: center;
justify-content: center;
flex-direction: column;
background: white;
position: absolute;
width: 100vw;
height: 100vh;
}
article:target {
display: flex;
}
}

View File

@ -1,33 +0,0 @@
* {
box-sizing: border-box;
}
html {
margin: 0;
padding: 0;
overflow: hidden;
}
@media screen {
body {
background: black;
margin: 0;
padding: 0;
}
section {
display: contents;
}
article {
display: none;
background: white;
position: absolute;
border: 1px solid red;
}
article:target {
display: block;
}
}