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) => {
|
|
|
|
const { type, lang, text } = token;
|
|
|
|
|
2025-08-15 03:38:24 +02:00
|
|
|
if (type === "html") {
|
|
|
|
token.text = token.text.replace(/&/g, "&")
|
|
|
|
token.text = token.text.replace(/</g, "<")
|
|
|
|
token.text = token.text.replace(/>/g, ">")
|
|
|
|
|
|
|
|
return;
|
|
|
|
} else if (type !== "code") {
|
2025-08-09 21:16:24 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let code;
|
|
|
|
|
|
|
|
if (lang && hljs.getLanguage(lang)) {
|
2025-08-09 22:58:17 +02:00
|
|
|
code = hljs.highlight(text.trim(), {
|
2025-08-09 21:16:24 +02:00
|
|
|
language: lang,
|
|
|
|
});
|
|
|
|
} else {
|
2025-08-09 22:58:17 +02:00
|
|
|
code = hljs.highlightAuto(text.trim());
|
2025-08-09 21:16:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
token.escaped = true;
|
2025-08-09 22:58:17 +02:00
|
|
|
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);
|
|
|
|
};
|
|
|
|
})();
|