-
Notifications
You must be signed in to change notification settings - Fork 432
Expand file tree
/
Copy pathself-contained.ts
More file actions
85 lines (77 loc) · 2.34 KB
/
self-contained.ts
File metadata and controls
85 lines (77 loc) · 2.34 KB
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
/*
* self-contained.ts
*
* Copyright (C) 2020-2023 Posit Software, PBC
*/
import { basename, dirname, join } from "../../deno_ral/path.ts";
import { formatResourcePath, pandocBinaryPath } from "../../core/resources.ts";
import { execProcess } from "../../core/process.ts";
import { parseHtml } from "../deno-dom.ts";
import { Element, HTMLDocument } from "deno_dom/deno-dom-wasm-noinit.ts";
import { esbuildCompile } from "../esbuild.ts";
import { asDataUrl } from "../data-url.ts";
const bundleModules = async (dom: HTMLDocument, workingDir: string) => {
const modules = dom.querySelectorAll("script[type='module']");
for (const module of modules) {
const src = (module as Element).getAttribute("src");
if (src) {
const srcName = join(workingDir, src);
const srcDir = dirname(srcName);
const jsSource = await esbuildCompile(
Deno.readTextFileSync(srcName),
srcDir,
[],
"esm",
);
(module as Element).setAttribute(
"src",
asDataUrl(jsSource!, "application/javascript"),
);
}
}
};
export const pandocIngestSelfContainedContent = async (
file: string,
resourcePath?: string[],
) => {
const filename = basename(file);
const workingDir = dirname(file);
// The template
const template = formatResourcePath(
"html",
"pandoc-selfcontained/selfcontained.html",
);
// The raw html contents
const contents = Deno.readTextFileSync(file);
const doctypeMatch = contents.match(/^<!DOCTYPE.*?>/);
const dom = await parseHtml(contents);
await bundleModules(dom, workingDir);
const input: string[] = [];
input.push("````````{=html}");
if (doctypeMatch) {
input.push(doctypeMatch[0]);
}
input.push(dom.documentElement!.outerHTML);
input.push("````````");
// Run pandoc to suck in dependencies
const cmd = [pandocBinaryPath()];
cmd.push("--to", "html");
cmd.push("--from", "markdown");
cmd.push("--template", template);
cmd.push("--output", filename);
cmd.push("--metadata", "title=placeholder");
cmd.push("--embed-resources");
if (resourcePath && resourcePath.length) {
cmd.push("--resource-path", resourcePath.join(":"));
}
const result = await execProcess({
cmd,
stdout: "piped",
cwd: workingDir,
}, input.join("\n"));
if (result.success) {
return result.stdout;
} else {
throw new Error();
}
};