write_pdf.py

Die Python-Datei des Beispiels „Ein minimales PDF“. Zwei identische Seiten, die die Struktur einer Rechnung mit Linien und Rechtecken zeichnen, ohne ein Wort Text: Die Datei hat etwa ein Dutzend Kilobyte und bettet keine Schrift ein.

Python 73 Zeilen

Wofür dieses Beispiel da ist

Öffnen Sie dieses zuerst. Zwei gleiche Seiten, jede mit dem Gerüst einer Rechnung — ein farbiges Band oben, ein Rahmen um alles und zwei Dutzend leere Rechtecke, wo die Zeilen einer Tabelle hinkämen — und auf keiner ein Wort Text. Mehr braucht ein Dokument nicht, um zu existieren: Seiten und Markierungen darauf. Es sind zwei statt einer, weil das Hinzufügen der zweiten eine einzige Anweisung kostet, und das lohnt sich gleich zu Beginn zu sehen. Alles andere auf dieser Website baut darauf auf, nie an seiner Stelle.

Was dieses Beispiel zeigt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
"""Writes a small PDF to disk, so that real reading software can be pointed at it.

The Python twin of the `write_pdf` example in Rust: the same document, through
the binding rather than through the library directly.

Unit tests can only check that the bytes look right to us. Whether the file is
actually a PDF is a question only reading software can answer, which is what
`scripts/check_pdf_validity.sh` uses this for.

No licence is set unless `--licensed` is passed, so what this writes is an
evaluation copy, watermarked on every page.

Usage: python examples/write_pdf.py [out.pdf] [--licensed]
"""

from __future__ import annotations

import sys

import _licence
import _out

import hqf_pdf


def invoice_page() -> hqf_pdf.Page:
    """A page of an invoice: a header block, a frame, and a run of table rules."""
    content = hqf_pdf.Content()
    content.save_state()

    content.set_fill(hqf_pdf.Rgb(0.20, 0.40, 0.80))
    content.rect(50.0, 700.0, 495.0, 90.0)
    content.fill()

    content.set_stroke(hqf_pdf.Rgb(0.0, 0.0, 0.0))
    content.set_line_width(1.0)
    content.rect(50.0, 50.0, 495.0, 742.0)
    content.stroke()

    content.set_line_width(0.4)
    for row in range(24):
        content.rect(50.0, 640.0 - row * 22.0, 495.0, 22.0)
        content.stroke()
    content.restore_state()

    page = hqf_pdf.Page.a4()
    page.set_content(content)
    return page


def main() -> None:
    licensed = "--licensed" in sys.argv
    sys.argv = [arg for arg in sys.argv if arg != "--licensed"]
    out = _out.output_path("out")

    document = hqf_pdf.Document()
    if licensed:
        document.set_license(_licence.licensed())
    document.set_info("Title", "hqf-pdf sample invoice")
    document.set_info("Creator", "hqf-pdf")

    document.add_page(invoice_page())
    document.add_page(invoice_page())

    written = document.write(out)
    print(
        f"wrote {out}: {written} bytes, {document.page_count} pages, "
        f"{'licensed' if licensed else 'evaluation'}"
    )


if __name__ == "__main__":
    main()