pdftoolkit / pdf-to-html
Semantic HTML from tagged PDF with explicit objects, source PDF MAC policy and authenticated permissions for PHP 8.3+
Requires
- php: ^8.3
- php-64bit: *
- ext-dom: *
- ext-mbstring: *
- pdftoolkit/pdf-reader: ^0.6
- roukmoute/pdf: ^0.9 || ^0.10 || ^0.11
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Derive semantic HTML from tagged PDF using explicit PHP objects, following Deriving HTML from PDF 1.2 (PDF Association, September 2026).
This repository was created specifically to implement the rules in Deriving_HTML_from_PDF_1-2.pdf. Version 0.5.0 implements the reference's derivation mechanisms with explicit security profiles, native password/public-key/MAC authentication and application-supplied rendering. The coverage guide and clause ledger record the concrete behavior, executable evidence and integration boundaries.
This optional package keeps derivation outside the PDF core. It exploits logical structure and Unicode content rather than guessing reading order from character positions. It does not reproduce page layout or promise conversion of every PDF.
Install
composer require "pdftoolkit/pdf-to-html:^0.5"
Requires 64-bit PHP 8.3+ with DOM and mbstring. CI checks PHP 8.3, 8.4 and 8.5. Composer installs the PDF core and reader as dependencies; installing the core alone does not install this module.
Version 0.5.0 accepts reader ^0.6 and core ^0.9 || ^0.10 || ^0.11.
Reader 0.6 additionally supports explicitly selected public-key authentication with normalized historical s3 permissions.
The reader verifies indicated
ISO/TS 32004 source MACs before content interpretation. Explicit
SourceIntegrityPolicy::RequirePdfMac rejects unprotected input as well.
Read, derive, then write
The application supplies bytes and chooses where to write the result. Reading, semantic derivation and filesystem operations remain separate:
use PDF\Html\HtmlDeriver; use PDF\Html\Reading\ReadPdfSource; use PDF\Reading\DocumentReader; use PDF\Reading\FileBytes; $document = (new DocumentReader())->read(new FileBytes($pdfBytes)); $source = (new ReadPdfSource())->read($document, 'document.pdf'); $result = (new HtmlDeriver())->derive($source); $html = $result->html;
PdfToHtml can coordinate these same stages without hiding file access:
$result = (new \PDF\Html\PdfToHtml())->convert( new FileBytes($pdfBytes), 'document.pdf', );
Its constructor accepts the reader, source adapter, deriver and an optional authentication provider as explicit objects. Conversion still receives bytes; the source filename is descriptive and is not opened implicitly.
For encrypted tagged files, inject a DocumentReader configured with
StandardPasswordAuthentication, or PublicKeyAuthentication with reader 0.6.
The native adapter exports the authenticated effective permissions to data-pdf-perms; a wrong password fails
before derivation. The existing authentication port remains available. Read the
authentication guide for credential encodings and
explicit security-handler, PDF MAC and viewer-enforcement boundaries. Version
0.4's authentication port returns ReadDocument for the exact supplied bytes,
with effective permissions and the requested integrity policy preserved before
source adaptation. The guide documents the port migration and
example 04. Source authentication
does not authenticate the resulting HTML or establish certificate trust.
The default source adapter inherits the deriver's policy and limits. Associated
Alternative/Supplement content is selected before decoding the PDF content it
replaces, with the same policy used for HTML output. When wiring the stages
manually, pass the same policy to ReadPdfSource and HtmlDeriver.
Native reading validates inverse ParentTree associations in permissive mode,
returning diagnostics for inconsistencies. Use
StructureValidationMode::Strict on ReadPdfSource to reject those inconsistencies.
This is a structure-association check, not WTPDF/PDF/UA certification.
Choose rendering and form capabilities
Logical text, Unicode mappings, structure, tables, labels, links, image XObjects
and supported inline-image encodings are read directly. Native graphics retain
the original instruction programs, state, resource graph and source context.
GraphicPdfExporter creates an isolated PDF containing selected paint operations;
RasterContentRenderer hands that document to an explicitly supplied
GraphicsRasterizer. The library does not install or launch a renderer.
The export retains the source's effective PDF version, transparency and optional
content context. Page programs use the physical CropBox; standalone Form object
references retain the Form XObject and its transformed bounds, clipping, matrix,
transparency and optional content. A structure BBox or explicit page-coordinate
viewport can override the output bounds. No painted-pixel crop is inferred.
See the graphics guide for the executable integration example.
ResetForm uses the PDF default value /DV, including its absence, and honors
field selection, parent names and exclusion. SubmitForm has explicit HTML export,
selection and mapping-name behavior. Both need FormActionPolicy permission;
the library-owned form runtime can be enabled without exporting PDF scripts:
$policy = new \PDF\Html\DerivationPolicy( formActions: new \PDF\Html\Forms\FormActionPolicy(allowReset: true), ); $converter = new \PDF\Html\PdfToHtml(deriver: new HtmlDeriver($policy)); $result = $converter->convert(new FileBytes($pdfBytes), 'document.pdf');
PDF ECMAScript and remote resources have separate opt-ins. See policies before enabling them or serving returned assets.
DerivationResult returns HTML, CSS, assets and diagnostics explicitly. Inspect
them before publishing the result. Write every asset beside the HTML, using its
returned filename, or remap its URLs consistently. When trusted scripts are
enabled, ScriptAssetEmitter returns external pdf-script-<sha256>.js files;
the HTML depends on those files. The immutable source model can also be built
directly by an application, independently of file parsing.
Run the real PDF example:
php examples/01-derive-tagged-pdf.php tests/Fixtures/tagged.pdf _build/derived.html
The script receives explicit input/output paths, writes HTML and every returned asset to the output directory, and prints hashes and diagnostics as JSON. The central tutorial provides the input PDF, rendered pages, executable PHP and actual HTML result.
Understand the boundaries
- Architecture: source objects, roles and serialization.
- Coverage: reference scope and file-adapter boundaries.
- Clause ledger: numbered rules, decisions and evidence.
- Policies: shared profiles, forms, scripts and rendering.
- Security: budgets, HTML/CSS/URL validation and active content.
- Authentication: native credentials and effective user/owner permissions.
- Retained reference: original PDF, license and fingerprint.
- Complete API and guides.
The library does not execute scripts or implicitly fetch external resources. The reference's ECMAScript rules must be read alongside the explicit security policy, not as a promise to emulate Acrobat's JavaScript API. Semantic HTML does not certify accessibility or PDF/UA.
Develop
composer install composer check
Follow the release procedure for exact-candidate CI, independent validation and stable-consumer verification. Code is MIT licensed; the retained PDF Association publication has its own CC-BY-4.0 license.