mirror of
https://github.com/byoungd/up.git
synced 2026-10-20 05:59:56 +08:00
46 lines
1.6 KiB
JavaScript
46 lines
1.6 KiB
JavaScript
// VitePress's fenced-code renderer emits Vue directives and a copy button that
|
|
// depend on the website runtime. EPUB content must remain usable without it.
|
|
export function configureEpubMarkdown(markdown) {
|
|
markdown.renderer.rules.fence = (tokens, index) =>
|
|
`<pre><code>${markdown.utils.escapeHtml(tokens[index].content)}</code></pre>\n`;
|
|
markdown.renderer.rules.code_block = markdown.renderer.rules.fence;
|
|
markdown.renderer.rules.th_open = (tokens, index, options, env, renderer) => {
|
|
tokens[index].attrSet("scope", "col");
|
|
return renderer.renderToken(tokens, index, options, env);
|
|
};
|
|
}
|
|
|
|
export function escapeXml(value) {
|
|
return String(value)
|
|
.replaceAll("&", "&")
|
|
.replaceAll("<", "<")
|
|
.replaceAll(">", ">")
|
|
.replaceAll('"', """)
|
|
.replaceAll("'", "'");
|
|
}
|
|
|
|
export function makeXhtml({ lang, title, body, epubType = "chapter" }) {
|
|
const safeBody = body
|
|
.replace(/<a\b[^>]*class="header-anchor"[^>]*>[\s\S]*?<\/a>/gi, "")
|
|
.replace(/\s+tabindex=(['"])-?\d+\1/gi, "")
|
|
.replace(/ /g, " ")
|
|
.replace(/​/g, "​")
|
|
.replace(/&(?!(?:amp|lt|gt|quot|apos|#\d+|#x[0-9a-f]+);)/gi, "&")
|
|
.replace(/<(img|br|hr)(\b[^>]*?)(?<!\/)\s*>/gi, "<$1$2 />");
|
|
return `<?xml version="1.0" encoding="utf-8"?>
|
|
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="${lang}" xml:lang="${lang}">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>${escapeXml(title)}</title>
|
|
<link rel="stylesheet" type="text/css" href="../styles/book.css" />
|
|
</head>
|
|
<body epub:type="${epubType}">
|
|
<main>
|
|
${safeBody}
|
|
</main>
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|