-
Notifications
You must be signed in to change notification settings - Fork 0
/
boredown.js
115 lines (103 loc) · 3.45 KB
/
boredown.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
/*! boredown.js v1.0.0 | License MIT | https://github.com/LIGMATV/boredown */
const fetching = [
"https://cdn.jsdelivr.net/npm/marked/marked.min.js",
"https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js",
"https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css",
"template.js"
];
function parseFrontmatter(content) {
const frontmatterRegex = /^---\n([\s\S]+?)\n---/;
const match = content.match(frontmatterRegex);
let frontmatter = {};
let markdown = content;
if (match) {
frontmatter = match[1].split('\n').reduce((acc, line) => {
const [key, value] = line.split(':').map(s => s.trim());
acc[key] = value;
return acc;
}, {});
markdown = content.slice(match[0].length);
}
return {
frontmatter,
markdown
};
}
function addIdToHeadings() {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
headings.forEach(heading => {
const id = heading.textContent.toLowerCase().replace(/\s+/g, '-').replace(/[^\w\-]+/g, '');
heading.id = id;
const anchor = document.createElement('a');
anchor.className = 'heading-anchor';
anchor.href = `#${id}`;
anchor.ariaLabel = 'Permalink anchor for heading'
heading.appendChild(anchor);
});
}
function renderTemplate() {
const markdownContent = document.querySelector('textarea').value;
const {
frontmatter,
markdown
} = parseFrontmatter(markdownContent);
let htmlContent = marked.parse(markdown);
htmlContent = htmlContent.replace(/\$\$(.*?)\$\$/g, (_, tex) =>
katex.renderToString(tex, {
displayMode: true,
output: "mathml",
strict: true
})
).replace(/\$(.*?)\$/g, (_, tex) =>
katex.renderToString(tex, {
displayMode: false,
output: "mathml",
strict: true
})
);
const template = generateTemplate(frontmatter, htmlContent);
document.documentElement.innerHTML = template;
addIdToHeadings();
if (window.MathJax) {
MathJax.typesetPromise();
}
}
function loadScripts(sources, inOrder = false) {
const head = document.head;
if (inOrder) {
return sources.reduce((p, src) =>
p.then(() => new Promise((res, rej) => {
const s = Object.assign(document.createElement(src.endsWith(".css") ? "link" : "script"),
src.endsWith(".css") ? {
href: src,
rel: "stylesheet",
onload: res,
onerror: rej
} : {
src,
async: false,
onload: res,
onerror: rej
}
);
head.appendChild(s);
})), Promise.resolve());
} else {
sources.forEach(src => {
const s = Object.assign(document.createElement(src.endsWith(".css") ? "link" : "script"),
src.endsWith(".css") ? {
href: src,
rel: "stylesheet"
} : {
src,
async: true
}
);
head.appendChild(s);
});
return Promise.resolve();
}
}
document.addEventListener("DOMContentLoaded", () => {
loadScripts(fetching, true).then(renderTemplate);
});