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: ^0.12.2
- pdftoolkit/pdf-reader: ^0.8.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- pdftoolkit/pdf-codecs: ^0.1
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.0
Suggests
- pdftoolkit/pdf-codecs: Optional pure PHP decoding for JPEG, JPEG 2000 and JBIG2 images when no compatible native Reader engine is available.
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. Copy preserved in this repository. Version 0.8.3 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.8"
The core is installed under its canonical Composer name pdftoolkit/pdf:^0.12.2.
If your application directly requires roukmoute/pdf, replace that requirement
with pdftoolkit/pdf:^0.12.2 and update the lock with Composer.
PHP namespaces and APIs are unchanged.
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.8.3 requires Reader ^0.8.1 and stable core pdftoolkit/pdf:^0.12.2.
Since version 0.6, Reader 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.
Image decoding uses Reader’s compatible native engine first, then the optional
PHP library when installed: composer require pdftoolkit/pdf-codecs:^0.1.
No package is installed automatically. Decoded images
retain sample precision, colour profiles and supported opacity in PNG; other
representations keep an explicit rendering diagnostic and the original source.
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.
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.
MathML retains its native mathematical layout. Version 0.5.1 corrects the
automatic Layout-to-CSS mapping that could emit display:inline on MathML.
Inline <math> uses its native default; block Placement uses the MathML
display="block" attribute when no explicit MathML display is supplied.
Source-authored CSS remains explicit and can override browser defaults.
See MathML placement and browser integration
for attribute precedence, shared classes and rendering limits.
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.
Version 0.6.0 adds ContentAppearanceRenderer to reuse that explicit rendering
engine for widget appearances, with normal/down/rollover states fitted to the
annotation rectangle. Native CSS implements the PDF highlighting modes while
preserving actual form controls and author-style precedence.
Signed fields expose a native HTML popover with an explanation. Inject
ReadPdfSource(signatureValidation: $provider) to validate the original PDF
through an explicit SignatureValidationProvider. The supplied
SignatureOutputValidation adapter checks signature mathematics against a chosen
certificate and reports integrity-verified; it does not decide certificate
trust, revocation or whether later revisions were permitted. The derived HTML
remains unsigned. See the signature guide.
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.
- Signatures: source-bound validation, status UI and PKI boundaries.
- 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.