콘텐츠로 이동

생태계 연동

pylopdf는 조판, PDF/A 생성, 디지털 서명을 의도적으로 다시 구현하지 않습니다. 각 기능은 검증된 라이브러리와 조합해 해결하며, 아래의 모든 사용법은 tests/test_interop.py의 통합 테스트로 보호됩니다.

조판과 새 문서 — typst

typsttypst-py로 보고서를 조판하고, 생성된 바이트를 pylopdf에 바로 전달할 수 있습니다.

import typst
import pylopdf

pdf_bytes = typst.compile("report.typ")   # 조판: typst
doc = pylopdf.open(stream=pdf_bytes)      # 편집 / 추출 / 병합: pylopdf

새 문서의 PDF/A — typst

typst의 PDF 백엔드(krilla)는 검증된 PDF/A-1b…4 및 PDF/UA-1 출력을 지원합니다.

pdf_a: bytes = typst.compile("report.typ", pdf_standards="a-2b")
pylopdf.open(stream=pdf_a).get_pdfa_claim()   # (2, "B")

기존 PDF의 변환이나 검증은 다른 문제입니다. veraPDF(Java)가 사실상의 표준 검증 도구이며, Document.get_pdfa_claim()은 문서가 스스로 선언한 정보만 읽습니다.

CJK 워터마크와 헤더 — typst × show_pdf_page

Standard-14 글꼴로는 CJK 문자를 그릴 수 없습니다. 대신 typst로 한 페이지짜리 스탬프를 조판하고(글꼴은 부분 집합으로 포함됨), 각 페이지에 벡터로 합성합니다.

from pylopdf_fonts_cjk import sans_path  # pip install pylopdf[cjk]

stamp_typ = """
#set page(width: 595pt, height: 842pt, fill: none)
#set text(font: "Noto Sans JP", size: 48pt, fill: rgb(255, 0, 0, 40%))
#align(center + horizon)[대외비]
"""
stamp = pylopdf.open(stream=typst.compile(stamp_typ.encode(), font_paths=[str(sans_path().parent)]))
for page in doc:
    page.show_pdf_page((0, 0, page.rect.width, page.rect.height), stamp)

합성 후에도 스탬프는 추출 가능한 텍스트로 남아 page.get_text()에서 대외비를 찾을 수 있습니다.

디지털 서명(PAdES) — pyHanko

pyHanko(MIT)는 증분 업데이트 방식으로 서명합니다. 따라서 pylopdf가 생성한 바이트는 서명된 파일의 접두부로 그대로 유지되며, 이 동작은 테스트에서 바이트 단위로 검증합니다.

import io
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import signers

signer = signers.SimpleSigner.load("key.pem", "cert.pem")
out = signers.sign_pdf(
    IncrementalPdfFileWriter(io.BytesIO(doc.tobytes())),
    signers.PdfSignatureMetadata(field_name="Signature1"),
    signer=signer,
)
signed_pdf: bytes = out.getvalue()

pylopdf 자체의 서명 필드 API는 서명 필드를 채우지 않으며, 대신 이 방법을 안내하도록 설계되었습니다.

OCR — 원하는 엔진 사용

Page.insert_ocr_text_layer(words)는 클라우드 API, Tesseract 등 (x0, y0, x1, y1, text)를 생성하는 어떤 OCR 결과든 보이지 않는 텍스트 레이어로 기록합니다. 글꼴을 포함하지 않아 크기 증가가 거의 없고, 스캔 PDF를 검색 가능하게 만듭니다. 이후 스캔 문서에도 to_markdown()을 사용할 수 있습니다.