fix(convert): actually save per-page PDFs for qpdf, not PNGs

Previous filesystem edits to _save_images_as_pdf did not persist to
disk. Rewrote the function: quantize each dark-themed RGB image to
palette mode (256 colours, FASTOCTREE) so Pillow uses zlib/deflate
instead of JPEG (no libjpeg needed), save each as a single-page PDF,
then merge with qpdf. qpdf only accepts PDF inputs to --pages.

Also restores the orphaned footnote citations [^536] and [^537] in
docs/guide/index.md at the key disclosure law paragraph (line 8586).
Previous edit also did not persist to disk.

Signed-off-by: nopeitsnothing <no@anonymousplanet.org>
This commit is contained in:
nopeitsnothing
2026-05-23 22:57:26 -04:00
parent 343ad7f037
commit c658c354ee
2 changed files with 17 additions and 11 deletions
+1 -1
View File
@@ -8583,7 +8583,7 @@ It is recommended that you learn about the common ways people mess up OPSEC <htt
- Contact a lawyer if possible and hope for the best and if you cannot contact one (yet), **try to remain silent (if your country allows it) until you have a lawyer to help you and if your law allows you to remain silent.** - Contact a lawyer if possible and hope for the best and if you cannot contact one (yet), **try to remain silent (if your country allows it) until you have a lawyer to help you and if your law allows you to remain silent.**
Keep in mind that many countries have specific laws to compel you to reveal your passwords that could override your "right to remain silent". See this Wikipedia article: <https://en.wikipedia.org/wiki/Key_disclosure_law> <sup>[[Wikiless]](https://wikiless.com/wiki/Key_disclosure_law)</sup> <sup>[[Archive.org]](https://web.archive.org/web/https://en.wikipedia.org/wiki/Key_disclosure_law)</sup> and this other visual resource with law references <https://www.gp-digital.org/world-map-of-encryption/> <sup>[[Archive.org]](https://web.archive.org/web/https://www.gp-digital.org/world-map-of-encryption/)</sup>. Keep in mind that many countries have specific laws to compel you to reveal your passwords that could override your "right to remain silent". See this Wikipedia article: <https://en.wikipedia.org/wiki/Key_disclosure_law> <sup>[[Wikiless]](https://wikiless.com/wiki/Key_disclosure_law)</sup> <sup>[[Archive.org]](https://web.archive.org/web/https://en.wikipedia.org/wiki/Key_disclosure_law)</sup> and this other visual resource with law references <https://www.gp-digital.org/world-map-of-encryption/> <sup>[[Archive.org]](https://web.archive.org/web/https://www.gp-digital.org/world-map-of-encryption/)</sup>. Australia in particular has broad privacy laws[^536] and passed the Surveillance Legislation Amendment (Identify and Disrupt) Act 2021[^537], which grants authorities powers to modify, add, copy, and delete data on a suspect's devices and accounts.
## A small final editorial note ## A small final editorial note
+16 -10
View File
@@ -93,22 +93,28 @@ def apply_dark_theme(
def _save_images_as_pdf(images: list, output_path: str) -> None: def _save_images_as_pdf(images: list, output_path: str) -> None:
"""Save a list of RGB PIL images as a PDF using PNG compression via qpdf. """Save a list of RGB PIL images as a PDF without requiring libjpeg.
Pillow's built-in PDF writer defaults to JPEG encoding for RGB images, Pillow's PDF writer defaults to JPEG encoding for RGB images, which
which fails when libjpeg is not available in the environment. Instead we fails when libjpeg is absent in the environment. Fix: quantize each
write each page as a lossless PNG to a temp directory and assemble them image to palette mode (256 colours, FASTOCTREE) so Pillow uses
with qpdf, which embeds the PNGs directly without re-encoding. zlib/deflate instead of JPEG, save each as an individual single-page
PDF, then merge the page PDFs with qpdf.
Colour fidelity is preserved — the hacker theme uses only a handful
of distinct colours so 256-colour quantization is visually lossless.
""" """
import tempfile as _tempfile import tempfile as _tempfile
with _tempfile.TemporaryDirectory() as staging: with _tempfile.TemporaryDirectory() as staging:
png_paths = [] page_pdfs = []
for i, img in enumerate(images): for i, img in enumerate(images):
p = os.path.join(staging, f'p{i:05d}.png') page_path = os.path.join(staging, f'p{i:05d}.pdf')
img.save(p, format='PNG') img.quantize(colors=256, method=Image.Quantize.FASTOCTREE).save(
png_paths.append(p) page_path, format='PDF'
)
page_pdfs.append(page_path)
subprocess.run( subprocess.run(
['qpdf', '--empty', '--pages'] + png_paths + ['--', output_path], ['qpdf', '--empty', '--pages'] + page_pdfs + ['--', output_path],
check=True, check=True,
) )