#!/usr/bin/env bash
set -euo pipefail
# export_website.sh
# Usage:
# ./export_website.sh "https://www.heise.de" output.pdf
# ./export_website.sh ./page.html output.pdf
INPUT="${1:-}"
OUTPUT="${2:-8k-output.pdf}"
WIDTH_PX=7680
HEIGHT_PX=4320
# 7680 / 96 = 80in, 4320 / 96 = 45in
PAGE_WIDTH_IN="80in"
PAGE_HEIGHT_IN="45in"
if [[ -z "$INPUT" ]]; then
echo "Usage: $0 <url-or-html-file> [output.pdf]" >&2
exit 1
fi
if [[ "$INPUT" =~ ^https?:// ]]; then
TARGET="$INPUT"
else
TARGET="file://$(realpath "$INPUT")"
fi
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
cat > "$TMPDIR/export-pdf.js" <<'NODE'
const puppeteer = require('puppeteer-core');
(async () => {
const target = process.env.TARGET;
const output = process.env.OUTPUT;
const width = Number(process.env.WIDTH_PX);
const height = Number(process.env.HEIGHT_PX);
const pageWidth = process.env.PAGE_WIDTH_IN;
const pageHeight = process.env.PAGE_HEIGHT_IN;
const browser = await puppeteer.launch({
executablePath: '/usr/bin/chromium',
headless: 'new',
args: [
`--window-size=${width},${height}`,
'--force-device-scale-factor=1',
'--disable-dev-shm-usage',
'--no-sandbox'
]
});
const page = await browser.newPage();
await page.setViewport({
width,
height,
deviceScaleFactor: 1
});
await page.goto(target, {
waitUntil: 'networkidle0',
timeout: 120000
});
await page.emulateMediaType('screen');
await page.addStyleTag({
content: `
@page {
size: ${pageWidth} ${pageHeight};
margin: 0;
}
html, body {
width: ${width}px;
height: ${height}px;
margin: 0;
padding: 0;
overflow: hidden;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
`
});
await page.pdf({
path: output,
width: pageWidth,
height: pageHeight,
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0
},
printBackground: true,
preferCSSPageSize: true,
scale: 1
});
await browser.close();
})().catch((err) => {
console.error(err);
process.exit(1);
});
NODE
TARGET="$TARGET" \
OUTPUT="$(realpath "$OUTPUT")" \
WIDTH_PX="$WIDTH_PX" \
HEIGHT_PX="$HEIGHT_PX" \
PAGE_WIDTH_IN="$PAGE_WIDTH_IN" \
PAGE_HEIGHT_IN="$PAGE_HEIGHT_IN" \
NODE_PATH="$SCRIPT_DIR/node_modules" \
node "$TMPDIR/export-pdf.js"
echo "Exported: $OUTPUT"