Seamless PDF
Convert HTML, Markdown, and DOCX documents into continuous, single-page PDFs -- no page breaks.
Standard PDF converters split your content across fixed-size pages. Seamless PDF renders the entire document onto a single continuous page perfectly sized to the content's width and height. Ideal for long-form reports, documentation snapshots, newsletters and any workflow where page breaks get in the way or you want to retain the original content viewing experience i.e it retains original table of contents.
Features
| Feature | Description |
|---|---|
| Single-Page Output | One continuous PDF sized exactly to your content |
| Multi-Format Input | Supports .html, .md, .markdown, and .docx files |
| CLI & Python API | Use from the terminal or integrate directly into your code |
| Markdown Rendering | GitHub-flavored Markdown with syntax highlighting via Pygments |
| Theme Selection | Render output with light or dark theme via API/CLI |
| Page Width Control (v1.0.0) | Option to enforce a maximum page width (e.g., 800px) |
| Custom Margins (v1.0.0) | Added --margin-top, --margin-right, --margin-bottom, and --margin-left arguments |
| PDF Outlines / Bookmarks (v1.0.0) | Automatically extracts headers (<h1> to <h6>) and maps them into native PDF bookmarks |
Installation
pip install seamless-pdf
python -m playwright install chromium
playwright install
[!IMPORTANT] Playwright uses a headless Chromium browser under the hood to render documents. The standard
pip installdoes not download the browser binary automatically. For first-time installs or updates, you must download the Chromium browser by runningpython -m playwright install chromiumfollowed byplaywright install.
Quick Start
Command Line
seamless-pdf input.html -o output.pdf
seamless-pdf README.md -o README.pdf
seamless-pdf report.docx -o report.pdf
seamless-pdf README.md -o README-dark.pdf --theme dark
# Width and Margin control
seamless-pdf README.md -o README-custom.pdf --width 1000px --margin-top 50px --margin-bottom 50px
Python API
from seamless_pdf import convert
convert("input.html", "output.pdf")
convert("README.md", "readme.pdf")
convert("report.docx", "report.pdf")
# Theming, width, and margin overrides
convert(
"README.md",
"readme-custom.pdf",
theme="dark",
width="1000px",
margin_top="50px"
)
Usage
The convert function automatically detects the input format from the file extension (.html, .htm, .md, .markdown, .docx). You can also specify the format explicitly:
from seamless_pdf import convert
# Auto-detected as Markdown
convert("docs/notes.md", "notes.pdf")
# Explicit input type override
convert("docs/notes.txt", "notes.pdf", input_type="markdown")
# Optional render theme (light or dark)
convert("docs/notes.md", "notes-dark.pdf", theme="dark")
CLI Options
# Explicit input type override
seamless-pdf docs/notes.txt -o notes.pdf --input-type markdown
# Dark theme rendering
seamless-pdf docs/notes.md -o notes-dark.pdf --theme dark
# Custom page width and margins
seamless-pdf docs/notes.md -o notes.pdf --width 800px --margin-left 20px --margin-right 20px
Notes on Dark Mode
[!NOTE] Dark mode behavior depends on the input type:
- Markdown / DOCX inputs: Seamless PDF generates HTML and injects the selected theme styles. Using
--theme darkis guaranteed to produce dark-themed output consistently.- HTML inputs: Seamless PDF respects the source HTML/CSS. If the source HTML is not dark-aware (no dark styles or
prefers-color-scheme), dark output is best effort and cannot be guaranteed. Provide dark-ready HTML for the best results!
Supported Input Types
| Extension | Type Keyword |
|---|---|
.html, .htm |
html |
.md, .markdown |
markdown |
.docx |
docx |
Requirements
| Dependency | Version |
|---|---|
| Python | 3.10, 3.11, 3.12, 3.13 |
| Playwright (Chromium) | >= 1.40.0 |
| markdown | >= 3.10.1 |
| Pygments | >= 2.17.0 |
| pymdown-extensions | >= 10.0 |
| mammoth | >= 1.6.0 |
| pypdf | >= 3.17.0 |
Roadmap
- PDF-to-PDF re-rendering (merge & reflow existing PDFs)
- Broader PDF manipulation toolset
What's New in V1.0.1 / V1.0.0
- Fixed an issue where fractional pixel rounding in Chromium caused a blank second page to render for certain documents.
- Fixed
pypdfnot installing automatically withpip install seamless-pdf. - Added Page Width Control via the
--widthCLI argument or API parameter to bound extremely wide documents. - Added Custom Margins / Padding (
--margin-top,--margin-right,--margin-bottom,--margin-left) to let text breathe. - Added PDF Outlines (Bookmarks). Seamless PDF now automatically parses headers (
<h1>to<h6>) and injects them hierarchically into the final continuous PDF! - Hardened unit tests, stabilized edge cases, and expanded CLI/API configuration consistency.
see changelog.md for more
Cloning for your purposes...
git clone https://github.com/SleepyPandas/Document-to-ContinuousPDF.git
cd Document-to-ContinuousPDF
pip install -e ".[dev]"
pytest
License
This project is licensed under the MIT License -- see the LICENSE file for details.
Metadata
Release files for seamless-pdf 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| seamless_pdf-1.0.3.tar.gz | 21.1 kB | With provenance | Details for seamless_pdf-1.0.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| seamless_pdf-1.0.3-py3-none-any.whl | Python 3 | none | any | Details for seamless_pdf-1.0.3-py3-none-any.whl |
Total release size: 38.3 kB
Release files / seamless_pdf-1.0.3.tar.gz
| Download URL | seamless_pdf-1.0.3.tar.gz |
|---|---|
| Size | 21.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f4fe8b903d231f6aaf53f53208bc4b32ae0531febb373cce50748912c2d5887e
|
|
BLAKE2b-256 checksum How to use checksums |
92be8a74e71082d94281c4040324cad15a710b93431b91b487caef325d2bb198
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 21, 2026.
Transparency logRelease files / seamless_pdf-1.0.3-py3-none-any.whl
| Download URL | seamless_pdf-1.0.3-py3-none-any.whl |
|---|---|
| Size | 17.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b38377b1b403c956eb7e61cbaa15bc61758c13405d6e3abdda7fb685d194c519
|
|
BLAKE2b-256 checksum How to use checksums |
7fa282a9cdac439c7dd9b3e6be71eec41bbf283a4b4b72b957e7fe09946b8d77
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 21, 2026.
Transparency logSecurity for seamless-pdf 1.0.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for seamless_pdf-1.0.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.