Compare commits
No commits in common. "254b0cd76c36b010403f7e57bbb9424cc45a848d" and "b87940ccd5a37829fa00d7b5994d6a53dd611f7b" have entirely different histories.
254b0cd76c
...
b87940ccd5
@ -6,7 +6,7 @@ This program is meant to be used as a git submodule of your actual presentation
|
|||||||
|
|
||||||
$ git submodule add -b release git@path-to-onpoint.git
|
$ git submodule add -b release git@path-to-onpoint.git
|
||||||
|
|
||||||
Make sure to have python3 and pandoc (the same version for all developers!) installed.
|
Make sure to have python3 and pandoc installed.
|
||||||
Next, we can install all requirements:
|
Next, we can install all requirements:
|
||||||
|
|
||||||
$ cd onpoint
|
$ cd onpoint
|
||||||
@ -25,7 +25,6 @@ We recommend you to structure your project directory like this:
|
|||||||
├── onpoint
|
├── onpoint
|
||||||
│ ├── autocompile.sh
|
│ ├── autocompile.sh
|
||||||
│ ├── main.py
|
│ ├── main.py
|
||||||
│ ├── ….py
|
|
||||||
│ ├── README.md
|
│ ├── README.md
|
||||||
│ └── requirements.txt
|
│ └── requirements.txt
|
||||||
├── slides
|
├── slides
|
||||||
|
|||||||
191
onpoint.js
191
onpoint.js
@ -35,15 +35,12 @@ function goToSlide(index) {
|
|||||||
currentSlide = index;
|
currentSlide = index;
|
||||||
window.location.href = window.location.href.split('#')[0] + `#slide${index}`;
|
window.location.href = window.location.href.split('#')[0] + `#slide${index}`;
|
||||||
|
|
||||||
let oldActiveTopicLinks = topicList.querySelectorAll(`.${activeTopicLinkClass}`);
|
let oldActiveTopicLink = topicList.querySelector(`.${activeTopicLinkClass}`);
|
||||||
[...oldActiveTopicLinks].forEach(link => {
|
if (oldActiveTopicLink != null) {
|
||||||
link.classList.remove(activeTopicLinkClass);
|
oldActiveTopicLink.classList.remove(activeTopicLinkClass);
|
||||||
});
|
}
|
||||||
|
let newActiveTopicLink = topicList.querySelector(`[data-slide="slide${index}"]`);
|
||||||
let newActiveTopicLinks = topicList.querySelectorAll(`[data-slide*=";slide${index};"]`);
|
newActiveTopicLink.classList.add(activeTopicLinkClass);
|
||||||
[...newActiveTopicLinks].forEach(link => {
|
|
||||||
link.classList.add(activeTopicLinkClass);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,184 +114,36 @@ function showPreviousFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Store for the headline nodes of each chapter.
|
|
||||||
*/
|
|
||||||
class HeadlineStore {
|
|
||||||
constructor() {
|
|
||||||
this.topLevelChildren = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new root node, i.e. the headline of a new chapter.
|
|
||||||
* @param {Node} node the level-1 headline node
|
|
||||||
*/
|
|
||||||
add(node) {
|
|
||||||
this.topLevelChildren.push(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a HTML list of all headline nodes stored in this structure.
|
|
||||||
*/
|
|
||||||
getHTML() {
|
|
||||||
let resultHTML = '<ul>'
|
|
||||||
|
|
||||||
resultHTML += this.topLevelChildren
|
|
||||||
.map(root => root.getHTML())
|
|
||||||
.join('');
|
|
||||||
|
|
||||||
return resultHTML + '</ul>'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data structure storing all headlines for the topic list.
|
|
||||||
* Each node knows its parents and children.
|
|
||||||
*/
|
|
||||||
class Node {
|
|
||||||
constructor(title, level, father, slide) {
|
|
||||||
this.children = [];
|
|
||||||
this.slidesWithSameTitle = [];
|
|
||||||
this.title = title;
|
|
||||||
this.level = level;
|
|
||||||
this.father = father;
|
|
||||||
this.slide = slide;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the child that was added last among all childen.
|
|
||||||
*/
|
|
||||||
getLastChild() {
|
|
||||||
return this.children[this.children.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a child node to this headline if the title of the new child node is
|
|
||||||
* different from the title of the node that was added last.
|
|
||||||
* This way, headlines are not added twice if they appear consecutively.
|
|
||||||
* @param {Node} node a subtitle node
|
|
||||||
* @return true, if the node was added, false otherwise
|
|
||||||
*/
|
|
||||||
addChildNode(node) {
|
|
||||||
if (!this.lastChildHasTitle(node.title)) {
|
|
||||||
this.children.push(node);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Each headline can have more than one slide related to it.
|
|
||||||
* Consecutive headlines appear only ones in a dictionary, but they are still
|
|
||||||
* related to all slides. If there are three slides with title »Example« in a
|
|
||||||
* row, the node will have slide1 as its child and slide2 and slide3 as
|
|
||||||
* entries to the slidesWithSameTitle array.
|
|
||||||
* The goal of this is to ultimately highlight the node in the topic list not
|
|
||||||
* only when slide1 is active, but also for slide2 and slide3.
|
|
||||||
* @param {Integer} slide the ID of a related slide
|
|
||||||
*/
|
|
||||||
addSlideWithSameTitle(slide) {
|
|
||||||
this.slidesWithSameTitle.push(slide);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not this node's last child has the given title.
|
|
||||||
* @param {String} title the slide's title
|
|
||||||
*/
|
|
||||||
lastChildHasTitle(title) {
|
|
||||||
let len = this.children.length;
|
|
||||||
return len > 0 && this.children[len - 1].title == title;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the HTML anchor content for this node (without any children).
|
|
||||||
*/
|
|
||||||
getLinkHTML() {
|
|
||||||
return `<a data-slide=";slide${this.slide};${
|
|
||||||
// Slide IDs have to be surrounded by »;«, otherwise slide10 and slide100
|
|
||||||
// would both be highlighted when slide10 is active.
|
|
||||||
this.slidesWithSameTitle.map(slide => `slide${slide}`).join(';')
|
|
||||||
};" href="javascript:goToSlide(${this.slide})" class="topic-link">${this.title}</a>`
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a list item for the topic list with a sublist of all child nodes.
|
|
||||||
*/
|
|
||||||
getHTML() {
|
|
||||||
let resultHTML = `<li>${this.getLinkHTML()}`;
|
|
||||||
|
|
||||||
if (this.children.length > 0) {
|
|
||||||
resultHTML +=
|
|
||||||
`<ul>${this.children.map(child => child.getHTML()).join('')}</ul>`
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultHTML + '</li>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTopicListContent() {
|
function getTopicListContent() {
|
||||||
let results = [...document.querySelectorAll('h1, h2, h3, h4, h5, h6')];
|
let results = [...document.querySelectorAll('h1, h2, h3, h4, h5, h6')];
|
||||||
let resultHTML = `<input type="text" class="${topicListSearchClass}"/>`;
|
let resultHtml = `<input type="text" class="${topicListSearchClass}"/><ul>`;
|
||||||
let currentLevel = 1;
|
let currentLevel = 1;
|
||||||
|
|
||||||
headlineStore = new HeadlineStore();
|
|
||||||
currentNode = null;
|
|
||||||
|
|
||||||
results.forEach(element => {
|
results.forEach(element => {
|
||||||
let node = element.nodeName;
|
let node = element.nodeName;
|
||||||
let level = parseInt(node[node.length - 1]);
|
let level = parseInt(node[node.length - 1]);
|
||||||
let title = element.textContent;
|
|
||||||
|
|
||||||
let parentElement = element.parentElement
|
let parentElement = element.parentElement
|
||||||
while (parentElement.nodeName.toLowerCase() != 'article') {
|
while (parentElement.nodeName.toLowerCase() != 'article') {
|
||||||
parentElement = parentElement.parentElement;
|
parentElement = parentElement.parentElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
let slide = parseInt(parentElement.id.replace('slide', ''));
|
let parentSlide = parentElement.id;
|
||||||
|
let parentSlideID = parseInt(parentSlide.replace('slide', ''));
|
||||||
if (level == 1) {
|
let linkHtml = `<a data-slide="${parentSlide}" href="javascript:goToSlide(${parentSlideID})" class="topic-link">${element.textContent}</a>`
|
||||||
// first chapter
|
|
||||||
let rootNode = new Node(title, level, null, slide);
|
|
||||||
headlineStore.add(rootNode)
|
|
||||||
currentNode = rootNode;
|
|
||||||
} else if (level > currentLevel) {
|
|
||||||
// one or more levels down
|
|
||||||
let childNode = new Node(title, level, currentNode, slide);
|
|
||||||
if (currentNode.addChildNode(childNode)) {
|
|
||||||
currentNode = childNode;
|
|
||||||
} else {
|
|
||||||
currentNode = currentNode.getLastChild();
|
|
||||||
currentNode.addSlideWithSameTitle(slide)
|
|
||||||
}
|
|
||||||
} else if (level == currentLevel) {
|
|
||||||
// same level
|
|
||||||
let parentNode = currentNode.father;
|
|
||||||
let siblingNode = new Node(title, level, parentNode, slide);
|
|
||||||
if (parentNode.addChildNode(siblingNode)) {
|
|
||||||
currentNode = siblingNode;
|
|
||||||
} else {
|
|
||||||
currentNode = parentNode.getLastChild();
|
|
||||||
currentNode.addSlideWithSameTitle(slide)
|
|
||||||
}
|
|
||||||
} else if (level < currentLevel) {
|
|
||||||
// one or more levels up
|
|
||||||
let parentNode = currentNode
|
|
||||||
while (parentNode.level >= level) {
|
|
||||||
parentNode = parentNode.father;
|
|
||||||
}
|
|
||||||
let siblingNode = new Node(title, level, parentNode, slide);
|
|
||||||
if (parentNode.addChildNode(siblingNode)) {
|
|
||||||
currentNode = siblingNode;
|
|
||||||
} else {
|
|
||||||
currentNode = parentNode.getLastChild();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (level > currentLevel) {
|
||||||
|
resultHtml += `<ul><li>${linkHtml}</li>`;
|
||||||
currentLevel = level;
|
currentLevel = level;
|
||||||
});
|
} else if (level < currentLevel) {
|
||||||
|
resultHtml += `</ul></li><li>${linkHtml}</li></li>`;
|
||||||
|
currentLevel = level;
|
||||||
|
} else {
|
||||||
|
resultHtml += `<li>${linkHtml}</a>`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return resultHTML + headlineStore.getHTML();
|
return resultHtml + '</ul>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTopicList() {
|
function createTopicList() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user