msds-tds/scripts/add-page-numbers.py
2026-07-08 13:12:20 +00:00

74 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""Generate SDS PDF with proper page numbering via two-pass process."""
from weasyprint import HTML
import pikepdf
import io
def add_page_numbers(pdf_path):
"""Post-process a PDF to add 'Page X of Y' at bottom center of each page."""
src = pikepdf.Pdf.open(pdf_path)
total = len(src.pages)
if total <= 1:
src.save(pdf_path)
return total
for i, page in enumerate(src.pages, 1):
text = f"Page {i} of {total}"
mediabox = page.mediabox
w = float(mediabox[2])
bottom = 50 # ~1.4cm from bottom in points
# Build raw PDF content stream for page number text
stream_data = (
f"BT\n"
f"/Helvetica 7 Tf\n"
f"{w/2:.0f} {bottom} Td\n"
f"0.357 0.400 0.435 rg\n"
f"({text}) Tj\n"
f"ET\n"
).encode('latin-1')
# Add as new content stream to page
new_stream = pikepdf.Stream(src, stream_data)
page.contents_add(new_stream)
src.save(pdf_path)
return total
def generate_sds(html, output_path):
"""Generate SDS PDF with page numbering."""
buf = io.BytesIO()
HTML(string=html).write_pdf(buf)
buf.seek(0)
with open(output_path, 'wb') as f:
f.write(buf.read())
n = add_page_numbers(output_path)
return n
if __name__ == '__main__':
# Test with 3 pages
test = """<html><body>
<style>
@page { size: A4; margin: 2cm; }
body { font-family: sans-serif; font-size: 12pt; }
</style>
<p>Content page 1</p>
<p>Content page 2</p>
<p>Content page 3</p>
</body></html>"""
n = generate_sds(test, '/tmp/test_numbered.pdf')
print(f'Generated {n} pages')
# Verify
with pikepdf.Pdf.open('/tmp/test_numbered.pdf') as pdf:
for i, page in enumerate(pdf.pages, 1):
content_streams = list(page.contents)
print(f'Page {i}: {len(content_streams)} content stream(s)')