Repository navigation
v2.4.1
PDF Craft v2.4.1
PDF Craft 2.4.1 completes the public workflows around reusable PCEX translations,
translated PDF output, and Vendor OCR image delivery. Applications can translate one
extraction into independently selectable versions, render or patch a chosen version,
and decide how page images reach their OCR provider.
PCEX translation as one fixed pipeline
translate_extraction() now accepts an XMLTranslator directly. Narrative text and
document metadata always pass through the standard translation pipeline;
with_anchored and with_furniture independently enable image/table fields and page
furniture without changing the translation algorithm.
Stored PCEX translations contain pure replacement text, so this API has no submit
parameter. Replacement and bilingual presentation remain rendering choices through
RenderMode.
from pdf_craft import RenderMode
translated = craft.translate_extraction(
"book.pcex",
"book.zh.pcex",
xml_translator,
window=4,
with_anchored=True,
with_furniture=True,
translation_id="zh-main",
target_language="zh",
)
craft.render_epub(
translated,
"book.zh.epub",
mode=RenderMode.BILINGUAL,
translation_id="zh-main",
)The public narrative adapter is NarrativeXMLTransformer. Chapter layout protocols
remain internal, keeping the high-level API independent from PCEX chapter mechanics.
See #498.
Patch a selected translation back into PDF
patch_pdf_with_extraction() now accepts translation_id. It selects the matching
narrative, metadata, coverage, and translated furniture from the PCEX and writes that
version onto the original PDF. When a selected version has no furniture translation,
source furniture remains available as layout context.
craft.patch_pdf_with_extraction(
"book.pdf",
"book.zh.pcex",
"book.zh.pdf",
translation_id="zh-main",
)translate_pdf() uses the same XMLTranslator pipeline for narrative and optional
furniture. Anchored image and table text is excluded because PCEX does not retain the
field-level PDF geometry required to place it back on a fixed page.
The PDF path is covered end to end from public PCEX translation through explicit
version selection, metadata resolution, furniture resolution, and real PDF text-layer
output.
See #498.
Choose how Vendor OCR receives page images
PDFOptions.ocr_image_url_resolver accepts a synchronous or asynchronous callable
that turns a rendered page image path into an HTTP(S) URL or a Base64 image Data URL.
This lets an application use its own object storage, signed-URL service, proxy, or
other image-delivery policy without coupling pdf-craft to that infrastructure.
from pathlib import Path
from pdf_craft import PDFCraft, PDFOptions
def resolve_ocr_image(image_path: Path) -> str:
# application_storage belongs to the integrating application.
return application_storage.upload(image_path).url
craft = PDFCraft(pdf=PDFOptions(
ocr=vendor_ocr,
ocr_executor=ocr_executor,
ocr_image_url_resolver=resolve_ocr_image,
))The default resolver encodes the image as a Base64 Data URL. Resolution happens once
per OCR operation and the result is reused across
transport retries. Invalid resolver results and resolver failures participate in the
normal page-error and fallback flow, while cancellation remains immediate.
See #496.
More responsive asynchronous extraction
Filesystem work that can block the caller's event loop now runs in the I/O execution
domain. This includes temporary-workspace creation and cleanup, extraction output
checks, Vendor OCR resume-state discovery, and the default Base64 image resolver.
Cancellation waits for started filesystem work and then cleans temporary resources,
so interrupted async extraction does not leak workspaces or publish incomplete output.
PDF rendering and OCR-specific CPU work keep their existing execution boundaries.
See #497.
Additional fixes
- Preserve the required empty narrative coverage node when a valid translation has no
narrative units. - Keep unselected anchored and furniture content unchanged while composing a stored
translation. - Use the selected translation's own furniture and metadata during PDF patching, with
source fallback for fields the translation does not replace. - Align the synchronous and asynchronous API references, PDF translation guide, PCEX
format reference, and localized READMEs with the final public API.
Full Changelog: v2.4.0...v2.4.1