1
0
mirror of https://github.com/coalaura/whiskr.git synced 2025-09-09 09:19:54 +00:00
Files
whiskr/static/js/markdown.js

81 lines
1.6 KiB
JavaScript
Raw Normal View History

2025-08-09 21:16:24 +02:00
(() => {
2025-08-10 15:53:30 +02:00
const timeouts = new WeakMap();
2025-08-09 21:16:24 +02:00
marked.use({
async: false,
breaks: false,
gfm: true,
pedantic: false,
walkTokens: (token) => {
2025-08-23 16:17:01 +02:00
const { type, text } = token;
2025-08-09 21:16:24 +02:00
2025-08-15 03:38:24 +02:00
if (type === "html") {
token.text = token.text.replace(/&/g, "&")
token.text = token.text.replace(/</g, "&lt;")
token.text = token.text.replace(/>/g, "&gt;")
return;
} else if (type !== "code") {
2025-08-09 21:16:24 +02:00
return;
}
2025-08-23 16:17:01 +02:00
const lang = token.lang || "plaintext";
2025-08-09 21:16:24 +02:00
let code;
if (lang && hljs.getLanguage(lang)) {
code = hljs.highlight(text.trim(), {
2025-08-09 21:16:24 +02:00
language: lang,
});
} else {
code = hljs.highlightAuto(text.trim());
2025-08-09 21:16:24 +02:00
}
token.escaped = true;
token.lang = code.language || "plaintext";
2025-08-09 21:16:24 +02:00
token.text = code.value;
},
renderer: {
code(code) {
const header = `<div class="pre-header">${escapeHtml(code.lang)}<button class="pre-copy" title="Copy code contents"></button></div>`;
return `<pre>${header}<code>${code.text}</code></pre>`;
},
2025-08-11 01:38:16 +02:00
link(link) {
return `<a href="${link.href}" target="_blank">${escapeHtml(link.text || link.href)}</a>`;
},
2025-08-09 21:16:24 +02:00
},
});
document.body.addEventListener("click", (event) => {
const button = event.target,
header = button.closest(".pre-header"),
pre = header?.closest("pre"),
code = pre?.querySelector("code");
if (!code) {
return;
}
clearTimeout(timeouts.get(pre));
navigator.clipboard.writeText(code.textContent.trim());
button.classList.add("copied");
timeouts.set(
pre,
setTimeout(() => {
button.classList.remove("copied");
}, 1000),
);
});
window.render = (markdown) => {
return marked.parse(markdown);
};
})();