-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
156 lines (136 loc) · 4.92 KB
/
index.js
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
"use strict";
const HSEP = "---";
const VSEP = "===";
/**
* MarkdownIt plugin to generate revealjs friendly markup.
*
* Use "---" to transition to a new horizontal slide.
* Use "===" to transition to a vertical child slide.
*
* @param {*} md
* @param {*} options
*/
module.exports = function revealjs_plugin(md, options) {
function isVSep(token) {
return token.type === "inline" && token.content === VSEP;
}
function isHSep(token) {
return token.type === "hr" && token.markup === HSEP;
}
function isSep(token) {
return isHSep(token) || isVSep(token);
}
function renderOpening(tokens, idx, options, env, slf) {
var token = tokens[idx];
return `<${tokens[idx].tag}${slf.renderAttrs(tokens[idx])}>`;
};
function renderClosing(tokens, idx, options, env, slf) {
var token = tokens[idx];
return `</${tokens[idx].tag}>`;
};
md.renderer.rules.pres_open = renderOpening;
md.renderer.rules.pres_close = renderClosing;
md.renderer.rules.slide_open = renderOpening;
md.renderer.rules.slide_close = renderClosing;
function nextDivider(tokens, start) {
for (let i = start; i < tokens.length; i++) {
if (isSep(tokens[i])) {
return i;
}
}
return -1;
}
function previousSlideOpen(tokens, before) {
for (let i = before - 1; i >= 0; i--) {
if (tokens[i].type === "slide_open") {
return i;
}
}
return -1;
}
var openSlides = 0;
function presentationOpen(state) {
var token = new state.Token("pres_open", "section", 1);
token.block = true;
token.attrs = [
["class", "reveal"]
];
return token;
}
function presentationClose(state) {
return new state.Token("pres_close", "section", -1);
}
function slidesOpen(state) {
var token = new state.Token("slides_open", "div", 1);
token.block = true;
token.attrs = [
["class", "slides"]
];
return token;
}
function slidesClose(state) {
return new state.Token("slides_close", "div", -1);
}
function slideOpen(state) {
openSlides++;
return new state.Token("slide_open", "section", 1);
}
function slideClose(state) {
openSlides--;
return new state.Token("slide_close", "section", -1);
}
md.core.ruler.push("revealjs", function(state) {
let divIdx = 0;
while (true) {
divIdx = nextDivider(state.tokens, divIdx);
if (divIdx === -1) {
break;
}
let divider = state.tokens[divIdx];
if (isSep(divider) && openSlides === 0) {
state.tokens.unshift(slideOpen(state));
divIdx++; // we added a token at the beginning, we need to update divIdx
}
let tags = [];
if (isHSep(divider)) {
while (openSlides > 0) {
tags.push(slideClose(state));
}
tags.push(slideOpen(state));
// because "---" is hijacked from plain markdown, it translates
// to one token which we remove
state.tokens.splice(divIdx, 1, ...tags);
} else if (isVSep(divider)) {
// if it is a vertical separator, we need to wrap the current slide
// in it's own section
if (openSlides === 1) {
let slideOpenIdx = previousSlideOpen(state.tokens, divIdx);
state.tokens.splice(slideOpenIdx, 1,
state.tokens[slideOpenIdx], // reuse it to avoid increasing openSlides
slideOpen(state)
);
divIdx++; // we added a token before the divider, we need to update divIdx
}
// if the current slide is already a vertical child, we need to close
// it; this will be indicated by a nesting level of two:
// <section horizontal-parent>
// <section current-vertical-child>
// <!-- this is where we are right now -->
if (openSlides === 2) {
tags.push(slideClose(state));
}
tags.push(slideOpen(state));
// because this is a custom token, it is first wrapped by the processor
// in a paragraph, so we need to replace para_open, sep, para_close
state.tokens.splice(divIdx - 1, 3, ...tags);
}
}
while (openSlides > 0) {
state.tokens.push(slideClose(state));
}
state.tokens.unshift(slidesOpen(state));
state.tokens.unshift(presentationOpen(state));
state.tokens.push(slidesClose(state));
state.tokens.push(presentationClose(state));
});
};