Last active
August 29, 2022 14:39
-
-
Save lelegard/050c31b7d7dea03ad9db0521d7aa7ccb to your computer and use it in GitHub Desktop.
Create a one-page blank PDF file, optionally with same page size as an existing reference PDF file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Create a one-page blank PDF file. | |
# Optionally with same page size as an existing reference PDF file (default size: A4). | |
SCRIPT=$(basename "$0") | |
usage() { echo >&2 "usage: $SCRIPT output-file [reference-file]"; exit 1; } | |
error() { echo >&2 "$SCRIPT: error: $*"; exit 1; } | |
warning() { echo >&2 "$SCRIPT: warning: $*"; } | |
# Find various tools. | |
STAT=$(which stat 2>/dev/null) | |
[[ -z $STAT ]] && error "stat command not found" | |
SED=$(which gsed 2>/dev/null) | |
[[ -z $SED ]] && SED=$(which sed 2>/dev/null) | |
[[ -z $SED ]] && error "sed command not found" | |
PDFINFO=$(which pdfinfo 2>/dev/null) | |
QPDF=$(which qpdf 2>/dev/null) | |
JQ=$(which jq 2>/dev/null) | |
[[ ( -z $PDFINFO || -z $SED ) && ( -z $QPDF || -z $JQ ) ]] && warning "commands pdfinfo/sed and qpdf/jq not found, using A4 size by default" | |
# Get file size in bytes of a file. | |
file-size() | |
{ | |
$STAT -c %s "$1" | |
} | |
# Get page "width height" of a PDF file, in points. | |
pdf-page-size() | |
{ | |
local a4="595 842" | |
local file="$1" | |
local size= | |
if [[ -z $file ]]; then | |
# No file provided, use A4 as default. | |
size="$a4" | |
fi | |
if [[ -z $size && -n $PDFINFO && -n $SED ]]; then | |
# Command pdfinfo available, try it. | |
size=$($PDFINFO "$file" | $SED -e '/^Page size:/!d' -e 's/^Page size:[[:space:]]*//' -e 's/ *pts.*$//' -e 's/ *x */ /' | head -1) | |
fi | |
if [[ -z $size && -n $QPDF && -n $JQ ]]; then | |
# Command qpdf available, try it. | |
size=$($QPDF "$file" --json | $JQ -j 'first(.objects[] | select(."/MediaBox") | ."/MediaBox") | .[2]," ",.[3]' 2>/dev/null) | |
fi | |
if [[ -z $size ]]; then | |
# Size not found, use A4 as default. | |
size="$a4" | |
fi | |
echo $size | |
} | |
# Create a blank PDF file, with optional reference PDF file for page size. | |
create-blank-pdf() | |
{ | |
local outfile="$1" | |
local reffile="$2" | |
local size=$(pdf-page-size "$reffile") | |
echo '%PDF-1.4' >"$outfile" | |
local obj1=$(file-size "$outfile") | |
echo '1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj' >>"$outfile" | |
local obj2=$(file-size "$outfile") | |
echo '2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj' >>"$outfile" | |
local obj3=$(file-size "$outfile") | |
printf '3 0 obj<</Type/Page/MediaBox[0 0 %s]/Parent 2 0 R/Resources<<>>>>endobj\n' "$size" >>"$outfile" | |
local xref=$(file-size "$outfile") | |
echo 'xref' >>"$outfile" | |
echo '0 4' >>"$outfile" | |
echo '0000000000 65535 f' >>"$outfile" | |
printf '%010d 00000 n\n' $obj1 >>"$outfile" | |
printf '%010d 00000 n\n' $obj2 >>"$outfile" | |
printf '%010d 00000 n\n' $obj3 >>"$outfile" | |
echo 'trailer<</Size 4/Root 1 0 R>>' >>"$outfile" | |
echo 'startxref' >>"$outfile" | |
printf '%d\n' $xref >>"$outfile" | |
echo '%%EOF' >>"$outfile" | |
} | |
[[ -z $1 ]] && usage | |
create-blank-pdf "$1" "$2" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment