-
Notifications
You must be signed in to change notification settings - Fork 2
/
pdf.js
91 lines (81 loc) · 3.35 KB
/
pdf.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
const puppeteer = require("puppeteer");
const { exec } = require("child_process");
const fs = require("fs");
const url = require("url");
module.exports = async function (name, _variant, meta, force) {
if (!force) {
const stylesDir = `${__dirname}/../docs/${name}/styles`;
const htmlFile = `${__dirname}/../docs/${name}/${name}.html`;
const pdfFile = `${__dirname}/../docs/${name}/${name}.pdf`;
const sources = `${htmlFile} ${stylesDir}`;
let sourcesChanged = await commitTime(sources);
let pdfChanged = await commitTime(pdfFile);
const sourceDiffs = await hasDiffs(sources);
if (sourceDiffs) {
const htmlStat = fs.statSync(htmlFile, { throwIfNoEntry: false });
if (htmlStat?.mtime > sourcesChanged) sourcesChanged = htmlStat?.mtime;
// get maximum modified timestamp of html and styles
fs.readdirSync(stylesDir, { withFileTypes: true }).forEach((doc) => {
const stat = fs.statSync(`${stylesDir}/${doc.name}`);
if (stat.mtime > sourcesChanged) sourcesChanged = stat.mtime;
});
}
const pdfDiffs = await hasDiffs(pdfFile);
if (pdfDiffs) {
const pdfStat = fs.statSync(pdfFile, { throwIfNoEntry: false });
if (pdfStat === undefined) pdfChanged = undefined;
else if (pdfStat?.mtime > pdfChanged) pdfChanged = pdfStat?.mtime;
}
if (pdfChanged === undefined || sourcesChanged > pdfChanged) force = true;
}
if (force) {
const browser = await puppeteer.launch({
headless: "shell",
});
const page = await browser.newPage();
const htmlUrl = url.pathToFileURL(
`${__dirname}/../docs/${name}/${name}.html`,
).href;
await page.goto(htmlUrl, {
waitUntil: "networkidle2",
});
await page.pdf({
path: `${__dirname}/../docs/${name}/${name}.pdf`,
format: "letter",
printBackground: true,
displayHeaderFooter: true,
headerTemplate: `<div style='font-family: LiberationSans, "Liberation Sans", Arial, Helvetica, sans-serif; font-size: 10px; width: 100%; text-align: center;'>Standards Track Work Product</div>`,
footerTemplate: `<div style='font-family: LiberationSans, "Liberation Sans", Arial, Helvetica, sans-serif; font-size: 8px; width: 90%; margin: auto; margin-top: 40px; display:flex; flex-flow:row wrap;'>
<span style="text-align: left; width: 30%;">${meta.filename}</span>
<span style="text-align: center; width: 40%;">Copyright ${meta.copyright}. All Rights Reserved.</span>
<span style="text-align: right; width: 30%;">${meta.pubdate} - Page <span class="pageNumber"></span> of <span class="totalPages"></span>
</span></div>`,
outline: true,
margin: { top: 50, bottom: 60, left: 0, right: 0 },
scale: 0.88,
});
await browser.close();
return true;
}
};
async function commitTime(filenames) {
const res = await git(["log -1 --format=%cI --", filenames]);
const len = res.stdout.length;
return len === 0 ? undefined : new Date(res.stdout.substring(0, len - 1));
}
async function hasDiffs(filenames) {
const res = await git(["diff --quiet HEAD --", filenames]);
return res.code !== 0;
}
function git(args, cwd) {
return new Promise((resolve) => {
exec(`git ${args.join(" ")}`, { cwd }, (error, stdout, stderr) => {
resolve({
code: error && error.code ? error.code : 0,
error,
stdout,
stderr,
});
});
});
}