michael.eichberg@dhbw.de, Raum 149B
This slide set primarily serves as a testbed for various features of the LectureDoc2 system. It also demonstrates how to use the system to create slides for a lecture.
You first have to enter the master password (press M and then enter Demo!) to see the presenter notes.
This is additional information that is not shown in the main text.
Some more text.
This is some more additional information that is not shown in the main text.
Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled. Just a long text to demonstrate that the supplemental information is not immediately shown on the slide and that it can be scrolled.
A deck is a collection of cards.
Where each card "replaces" the previous cards during the presentation belonging to the same deck.
Note
This is a simple note.
This card contains a simple note. Where the height of the deck as a whole is determined by the tallest card.
The Tallest One
Above the crowd, I stand so high, A bridge between the ground and sky. I see the world in a broader frame, Yet hear the jokes—they’re all the same.
—Jan. 2025 ChatGPT (Prompt: I need a short poem about being the tallest one.)
Decks can be nested and can overlay each other!
However, a card with a nested deck is not allowed to also use floating elements (e.g. notes). In general, the use of floating elements in combination with overlays is discouraged.
The first sentence of the first card in the nested deck. The last sentence of the first card in the nested deck.
T A sentence in between. T
Hint
Note
This is another simple note.
This is the last meaningful card in the nested deck. The next two ones are a technical detail.
_------ ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------_
xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx
Hint
This is the last card in the top-level deck.
Stories are used for content that should appear in a stepwise manner and which may scroll content out of the view.
This is the first step.
This is the second step.
This is the third step.
This is the fourth step.
This is the fifth step.
This is the sixth step.
This is the seventh step.
This is the eighth step.
This is the ninth step.
This is the tenth step.
This is the eleventh step.
This is the twelfth step.
This is the thirteenth step.
This is the fourteenth step.
This is the fifteenth step.
Some monospaced text.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
print("Hello, World!")
fn main() {
println!("Hello, World!");
}
const std = @import("std");
pub fn main() void {
std.debug.print("Hello, World!\n", .{});
}
A scrollable is a container whose content does not fit into the available space of a slide. During the presentation the content can be scrolled by the presenter and scrolling is relayed in secondary windows.
1/* A small library to encrypt and decrypt strings using AES-GCM and PBKDF2.
2*
3* Based on code found at: https://github.com/themikefuller/Web-Cryptography
4*
5* License: BSD-3-Clause
6*/
7export {
8decrypt as decryptAESGCMPBKDF,
9encrypt as encryptASEGCMPBKDF
10}
1112
async function encrypt(plaintext, password, iterations) {
1314
const encodedPlaintext = new TextEncoder().encode(plaintext);
15const encodedPassword = new TextEncoder().encode(password);
1617
const pass = await crypto.subtle.importKey(
18'raw',
19encodedPassword,
20{ "name": "PBKDF2" },
21false,
22['deriveBits']);
2324
const salt = crypto.getRandomValues(new Uint8Array(32));
25const iv = crypto.getRandomValues(new Uint8Array(12));
2627
const keyBits = await crypto.subtle.deriveBits(
28{
29"name": "PBKDF2",
30"salt": salt,
31"iterations": iterations,
32"hash": { "name": "SHA-256" }
33},
34pass,
35256);
3637
const key = await crypto.subtle.importKey(
38'raw',
39keyBits, { "name": "AES-GCM" },
40false,
41['encrypt']);
4243
const enc = await crypto.subtle.encrypt(
44{
45"name": "AES-GCM",
46"iv": iv
47},
48key,
49encodedPlaintext);
5051
const iterationsB64 = btoa(rounds.toString());
5253
const saltB64 = btoa(Array.from(new Uint8Array(salt)).map(val => {
54return String.fromCharCode(val)
55}).join(''));
5657
const ivB64 = btoa(Array.from(new Uint8Array(iv)).map(val => {
58return String.fromCharCode(val)
59}).join(''));
6061
const encB64 = btoa(Array.from(new Uint8Array(enc)).map(val => {
62return String.fromCharCode(val)
63}).join(''));
6465
return iterationsB64 + ':' + saltB64 + ':' + ivB64 + ':' + encB64;
66};
6768
async function decrypt(encrypted, password) {
6970
const parts = encrypted.split(':');
71const rounds = parseInt(atob(parts[0]));
7273
const salt = new Uint8Array(atob(parts[1]).split('').map(val => {
74return val.charCodeAt(0);
75}));
7677
const iv = new Uint8Array(atob(parts[2]).split('').map(val => {
78return val.charCodeAt(0);
79}));
8081
const enc = new Uint8Array(atob(parts[3]).split('').map(val => {
82return val.charCodeAt(0);
83}));
8485
const encodedPassword = new TextEncoder().encode(password);
86const pass = await crypto.subtle.importKey(
87'raw',
88encodedPassword,
89{ "name": "PBKDF2" },
90false,
91['deriveBits']);
9293
const keyBits = await crypto.subtle.deriveBits(
94{
95"name": "PBKDF2",
96"salt": salt,
97"iterations": rounds,
98"hash": {
99"name": "SHA-256"
100}
101},
102pass,
103256);
104105
let key = await crypto.subtle.importKey(
106'raw',
107keyBits, { "name": "AES-GCM" },
108false,
109['decrypt']);
110111
let dec = await crypto.subtle.decrypt(
112{
113"name": "AES-GCM",
114"iv": iv
115},
116key,
117enc);
118119
return (new TextDecoder().decode(dec));
120};
A scrollable can have an explicit height that will be used for the slide view.
1/**
2* Adds an event listener to the scrollable element that fires when the element
3* is scrolled. In that case, the event is sent to the specified channel to
4* make secondary windows aware of the scrolling event in the primary window.
5*
6* The data is sent using the {@link postMessage} method where the msg is the event title
7* and the data is a two element array where the first element is the id of the
8* element that is being scrolled and the second element is the current scrollTop.
9*
10* The primary window is always the window that user interacts with. The secondary
11* is every other window showing the same site.
12*
13* @param {Channel} channel - The channel that will be used to send the event.
14* @param {string} eventTitle - The title of the event that will be sent to the channel. The
15* title has to be unique w.r.t. to the channel.
16* @param {HTMLElement} scrollableElement - The element that is being scrolled.
17* @param {string} id - The id of the element that is being scrolled.
18*/
19export function addScrollingEventListener(channel, eventTitle, scrollableElement, id) {
20// We will relay a scroll event to a secondary window, when there was no
21// more scrolling for at least TIMEOUTms. Additionally, if there is already an
22// event handler scheduled, we will not schedule another one.
23//
24// If we would directly relay the event, it may be possible that it will
25// result in all kinds of strange behaviors, because we cannot easily
26// distinguish between a programmatic and a user initiated scroll event.
27// (Using window blur and focus events didn't work reliably.)
28// This could result in a nasty ping-pong effect where scrolling between
29// two different position would happen indefinitely.
30const TIMEOUT = 50;
31let lastEvent = undefined;
32let eventHandlerScheduled = false;
33scrollableElement.addEventListener("scroll", (event) => {
34lastEvent = new Date().getTime();
35function scheduleEventHandler(timeout) {
36setTimeout(() => {
37const currentTime = new Date().getTime();
38if (currentTime - lastEvent < TIMEOUT) {
39scheduleEventHandler(TIMEOUT - (currentTime - lastEvent));
40return;
41}
42postMessage(channel, eventTitle, [id, event.target.scrollTop]);
43// console.log(eventTitle + " " + id + " " + event.target.scrollTop);
44eventHandlerScheduled = false;
45}, timeout);
46};
47if(!eventHandlerScheduled) {
48eventHandlerScheduled = true;
49scheduleEventHandler(TIMEOUT);
50}
51},{passive: true});
52}
This is a scrollable that extends to the bottom of the slide -100px to leave some space for the footer.
1export function getTopAndBottomMargin(e) {
2const style = window.getComputedStyle(e);
3return parseInt(style.marginTop) + parseInt(style.marginBottom);
4}
5export function getLeftAndRightMargin(e) {
6const style = window.getComputedStyle(e);
7return parseInt(style.marginLeft) + parseInt(style.marginRight);
8}
9export function getLeftAndRightPadding(e) {
10const style = window.getComputedStyle(e);
11return parseInt(style.paddingLeft) + parseInt(style.paddingRight);
12}
13export function getLeftAndRightMarginAndPadding(e) {
14return getLeftAndRightMargin(e) + getLeftAndRightPadding(e);
15}
1617
export function postMessage(channel, msg, data) {
18channel.postMessage([msg, data]);
19}
One way to create a very simple multi-column layout consists of a list with the class columns.
Example
Default layout:
This first column.
a nested list.
The second column.
a nested list.
Left-aligned layout:
This first column.
a nested list.
The second column.
a nested list.
Evenly-spaced layout:
This first column.
a nested list.
The second column.
a nested list.
Using Grids it is possible to design advanced slide layouts.
When you don't specify a specific layout for a grid a simple multi-column layout is used.
1.. grid::
2:class: very-light-gray-background
34
.. cell::
56
Using Grids it is possible to
7design advanced slide layouts.
89
.. cell::
1011
.. code:: rst
12:class: copy-to-clipboard
1314
**The Code**
Adding math (e.g. \(a^2+b^2=c^2\)) to a slide is done using the math directive or role.
Poor Man's Math: e = mc².
Example
Adding math (e.g. :math:`a^2+b^2=c^2`)
to a slide is done using the math
directive or role.
.. math::
e = mc^2
.highlight-identical-cells-on-hover
r |
s |
t |
u |
v |
w |
x |
y |
z |
|
---|---|---|---|---|---|---|---|---|---|
a |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
b |
4 |
5 |
6 |
7 |
8 |
9 |
1 |
2 |
3 |
c |
7 |
8 |
9 |
1 |
2 |
3 |
4 |
5 |
6 |
.highlight-row-on-hover
r |
s |
t |
u |
v |
w |
x |
y |
z |
|
---|---|---|---|---|---|---|---|---|---|
a |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
b |
4 |
5 |
6 |
7 |
8 |
9 |
1 |
2 |
3 |