I've always found it amusing from a "bootstrapping" perspective that the PDF spec is itself a PDF.
That said, if you're only writing and not reading existing ones, it's as straightforward or as complex as you want to make it. I wrote a little program many years ago to convert plaintext to PDF in <1kLoC of C --- and its output was actually often many times smaller than what the commercial PDF-generators do, because I just used the defaults and bare-minimum necessary. I wrote it after being confronted with a requirement to use PDF, and the output of contemporary generators seemed rather bloated in comparison. The spec has an example of a bare-minimum; it's quite easy to programmatically generate.