Skip to content

Commit 0c4104a

Browse files
committed
Add a script to convert HTML to PDF
This could be used, for example, to render a PDF version of the shiny new Git Cheat Sheet. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 8a7ebd0 commit 0c4104a

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

script/html-to-pdf.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require('fs')
4+
const path = require('path')
5+
const { chromium } = require('playwright')
6+
7+
const htmlToPDF = async (htmlPath, options) => {
8+
if (!htmlPath.endsWith('.html')) {
9+
throw new Error(`Input file must have the '.html' extension: ${htmlPath}`)
10+
}
11+
if (!fs.existsSync(htmlPath)) {
12+
throw new Error(`Input file does not exist: ${htmlPath}`)
13+
}
14+
const outputPath = htmlPath.replace(/\.html$/, '.pdf')
15+
if (!options.force && fs.existsSync(outputPath)) {
16+
throw new Error(`Output file already exists: ${outputPath}`)
17+
}
18+
19+
const browser = await chromium.launch({ channel: 'chrome' })
20+
const page = await browser.newPage()
21+
22+
await page.goto(
23+
`file://${path.isAbsolute(htmlPath) ? htmlPath : path.join(process.cwd(), htmlPath)}`, {
24+
waitUntil: 'load'
25+
}
26+
)
27+
await page.pdf({
28+
path: outputPath,
29+
format: 'A4',
30+
margin: { top: '1cm', bottom: '1cm', left: '1cm', right: '1cm' },
31+
})
32+
await browser.close()
33+
}
34+
35+
const args = process.argv.slice(2)
36+
const options = {}
37+
while (args?.[0].startsWith('-')) {
38+
const arg = args.shift()
39+
if (arg === '--force' || arg === '-f') options.force = true
40+
else throw new Error(`Unknown argument: ${arg}`)
41+
}
42+
43+
if (args.length !== 1) {
44+
process.stderr.write('Usage: html-to-pdf.js [--force] <input-file.html>\n')
45+
process.exit(1)
46+
}
47+
48+
htmlToPDF(args[0], options).catch(e => {
49+
process.stderr.write(`${e.stack}\n`)
50+
process.exit(1)
51+
})

0 commit comments

Comments
 (0)