txt2pdf
is a tool to convert a plaintext file to PDF. By default, it uses Courier 10 point font, which can fit about 78 characters across a line and 56 lines on a page. The command works by:
- paginating the input using the
pr
command. This also inserts the file’s creation timestamp, the filename, and the page number in the header - expanding tabs to spaces (width 8)
- appending the
.br
troff directive to each newline withsed
1 - converting to troff and then postscript and then pdf using
troff | grops | ps2pdf
You can find the txt2pdf
command at github.com/ughe/txt2pdf. Here is the full command:
#!/usr/bin/env bash
# Converts plaintext to PDF. Courier 10 point font. 78 cols x 56 rows
set -o pipefail
if [ $# -lt 1 ]; then
>&2 echo "usage: $0 [-p12] [-n] [-2] abc.txt > abc.pdf"; exit 1; fi
PS=10 # Default font size
if echo "$@" | grep -q -- '^ *-p[0-9][0-9]* '; then # -p12 must be 1st
PS=`echo "$@" | sed -nr 's/^ *-p([0-9]+) .*/\1/gp'`; shift; fi
# Format: 1) font size $PS 2) .br every newline 3) delete last line
FMT='1s/^/.ps '${PS}'\n/;s/$/\n.br/g;s/\\/\\\\/g;$ d'
pr "${@}" | expand | sed "$FMT" | troff -Tps -fC | grops | ps2pdf - -
We can use txt2pdf
to convert itself to PDF using the following invocation:
./txt2pdf -n -h "txt2pdf" ./txt2pdf > txt2pdf.pdf
And here is the resulting txt2pdf.pdf
that was outputted:
Additional Examples
In addition to converting itself, txt2pdf
has three more examples in the repository:
- Comparing C and Rust “hello world” assembly output on x86-64 (intel)
- Generating a table of arithmetic problems (multiplication) and answers
- Printing out poems in 12 point font with line numbers (“Kubla Khan” and “Ulysses”)2
We will discuss the C vs. Rust example, which prints the assembly output of their respective hello world programs side by side. The lines are truncated after about 30 characters, which makes assembly a good example since often source code or poems are longer than 30 characters wide.
Here are the hello world files for C and Rust3:
hello_c.c
#include <stdio.h> int main(int argc, char* argv[]) { printf("hello, world\n"); return 0; }
hello_rs.rs
fn main() { print!("hello, world\n"); }
After compiling (with -O3
) to assembly using the Makefile here, we run txt2pdf
with the -m
flag and both *.S
assembly files. C is on the left and Rust is on the right. Here is the output:
Compiler Versions
See the Makefile used in examples/hello
for the full methodology. Here are the versions used:
$ gcc --version
Apple clang version 13.1.6 (clang-1316.0.21.2)
Target: x86_64-apple-darwin21.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ rustc --version
rustc 1.56.1
Conclusion
txt2pdf
is a handy tool for converting plaintext to PDF without installing more powerful commands.
-
Simplification. We also: 1) insert the font size
.ps
directive at the start of the file; 2) Escape all backslashes by replacing them with two backslashes; and 3) Remove the last line (which is always empty and was introduced bypr
) ↩ -
Public domain poems sourced from Project Gutenberg ↩
-
Note: the actual hello_rs.rs file has more variations attempting to generate fewer asm lines. ↩