-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathembed-code.js
130 lines (105 loc) · 5.31 KB
/
embed-code.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
const EmbedCode = {
id: 'externalCode',
init: (reveal) => {
return Promise.all([...document.querySelectorAll('code[data-url]')].map((el) => {
const url = el.getAttribute('data-url').trim();
if (url === '') {
return;
}
function showError(error, showInline = true) {
if (showInline) {
el.innerHTML = error;
}
console.error(error);
}
return fetch(url)
.then((r) => {
if (r.ok !== true) {
showError(`code could not be loaded from ${url}: status ${r.status} returned`);
return;
}
return r.text();
}).then((t) => {
let lines = t.split('\n');
let lineStart = el.getAttribute('data-line-start');
const lineStartDelimiter = el.getAttribute('data-line-start-delimiter') ?? '';
let lineEnd = el.getAttribute('data-line-end');
const lineEndDelimiter = el.getAttribute('data-line-end-delimiter') ?? '';
const beautify = !el.hasAttribute('data-no-beautify');
const includeDelimiters = el.hasAttribute('data-include-delimiters');
function getLineNumberThatContains(text) {
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes(text)) {
// add 1 as we're using line numbers, not indices
return i + 1;
}
}
// none found
return -1;
}
if (lineStartDelimiter !== '') {
// search for start delimiter and set it's line (plus offset) as the line start
lineStart = getLineNumberThatContains(lineStartDelimiter);
if (lineStart > 0 && !includeDelimiters) {
lineStart++;
}
}
if (lineEndDelimiter !== '') {
// search for end delimiter and set it's line (plus offset) as the line end
lineEnd = getLineNumberThatContains(lineEndDelimiter);
if (lineEnd > 0 && !includeDelimiters) {
lineEnd--;
}
}
if (lineEnd !== null) {
lineEnd = parseInt(lineEnd);
if(isNaN(lineEnd) || lineEnd > lines.length || lineEnd < 0) {
showError(`invalid line end specified: ${lineEnd}`, false);
}
// end at line end
lines.splice(lineEnd, lines.length - lineEnd);
}
if (lineStart !== null) {
lineStart = parseInt(lineStart);
if(isNaN(lineStart) || lineStart < 0 || lineStart > lines.length || (lineEnd !== null && lineStart > lineEnd)) {
showError(`invalid line start specified: ${lineStart}`, false);
}
// start at line start
lines.splice(0, lineStart - 1);
}
if (beautify) {
// beautify loaded code
// e.g. remove similar indentation
const reg = new RegExp("^\\s+");
let minIndentation = Infinity;
for (let line of lines) {
if (line === '') {
// skip empty lines as these have no indentation but still allow beautifying
continue;
}
let matches = line.match(reg);
if (null === matches || matches.length === 0) {
// some line does not have any indentation, therefore cannot beautify
minIndentation = 0;
break;
}
if (matches[0].length < minIndentation) {
minIndentation = matches[0].length;
}
}
if (minIndentation > 0) {
// remove common indentation from all lines
lines = lines.map((l) => l.substring(minIndentation));
}
}
// join lines again
t = lines.join('\n');
el.textContent = t;
})
.catch((e) => {
// todo: add git url
showError(`code could not be loaded from ${url} as an exception occurred: ${e}\n\nCould it be that you're not loading the presentation via a (local) server?\nOtherwise, contact the developer or open an issue at https://github.com/befocken/revealjs-embed-code.`);
});
}));
},
};