Python library Version 1.0.2

Define the document once.
Render it everywhere.

SoulDoc is a format-independent document layout and rendering engine for Python. Give it structured content or already calculated geometry, and export the same document to printable HTML, SVG, PDF, editable DOCX, visual XLSX, or JSON.

pip install souldoc
SoulDoc icon

The short explanation

SoulDoc is the layer between your data and document formats

Most document libraries start with one file format. SoulDoc starts with the document itself: its content, structure, pages, geometry, styles, resources, and reading order. Renderers then translate that neutral model into the closest native objects each output format can provide.

What goes in?

  • High-level components such as text, images, tables, rows, columns, and grids
  • Explicit Markdown content, including PyCells MD(...) records
  • TenTags table formulas converted into a neutral table model
  • Positioned boxes when your application already knows exact coordinates
  • Metadata and application-resolved image resources

What comes out?

  • Automatically measured, wrapped, and paginated pages
  • Printable, self-contained HTML and geometry-reference SVG
  • PDF printed from the same HTML representation
  • Editable Word content and visually close Excel workbooks
  • A versioned JSON contract for storage and service boundaries

One pipeline, two document levels

Use automatic layout or provide exact geometry

SoulDoc separates layout decisions from file-format rendering. This keeps the document model understandable and prevents each renderer from calculating a different layout.

1 Data and content Text, Markdown, images, tables, templates
2 SoulLayoutDocument High-level flow components and shared styles
3 SoulDocument Pages and boxes with final millimetre geometry
4 Renderers HTML, SVG, PDF, DOCX, XLSX, JSON

Measurement and wrapping

SoulDoc estimates text size, wraps lines to the available width, and can use application-provided Pillow font metrics when precise fonts are available.

Automatic pagination

Flow content moves across pages, tables split by row, and repeated document headers and footers remain part of the same layout pass.

Stable geometry

Positioned boxes use millimetres, giving browsers, PDF, Word, and spreadsheets one shared physical coordinate system.

Versioned document IR

The positioned document can be serialized to JSON, passed between services, stored, validated, and rendered later without repeating layout decisions.

One model, multiple outputs

Each renderer uses the closest practical native representation

HTML

Printable web document

Self-contained, paginated HTML with fixed page geometry and print CSS.

SVG

Geometry reference

One SVG per page for inspecting calculated positions and physical dimensions.

PDF

Consistent print output

The printable HTML is rendered by offline Chromium with HTTP requests blocked.

DOCX

Editable Word content

Native tables and editable text, with positioned text boxes where appropriate.

XLSX

Visual editable workbook

Cells, merged ranges, text-box shapes, drawings, images, and configured print areas.

JSON

Portable document contract

A versioned envelope containing pages, positioned boxes, resources, and metadata.

Practical uses

Built for documents produced from application data

  • Invoices and quotations: customer data, line items, totals, and branding
  • Business reports: headings, narrative text, KPI tables, and page headers
  • Contracts and forms: precise fields combined with flowing clauses
  • Certificates and labels: exact placement on known page sizes
  • Web application exports: preview in HTML, download as PDF, Word, or Excel
  • Document editors: store a neutral IR instead of coupling the editor to DOCX XML

Python examples

Start with flow components

The high-level model is the simplest choice when SoulDoc should calculate dimensions, wrap content, and create pages.

Automatic layout and export
from souldoc import (
    Column,
    SoulLayoutDocument,
    SoulStyle,
    Table,
    Text,
    save_document,
)

document = SoulLayoutDocument(
    name="Quarterly report",
    children=[
        Column(
            gap_mm=5,
            children=[
                Text(
                    "Quarterly report",
                    style=SoulStyle(
                        font_size_pt=24,
                        font_weight="bold",
                        text_align="center",
                    ),
                ),
                Text("One model can produce every supported format."),
                Table(
                    rows=[
                        ["Product", "Quantity", "Amount"],
                        ["Service A", "12", "$1,200"],
                        ["Service B", "8", "$960"],
                    ],
                    header_rows=1,
                ),
            ],
        )
    ],
)

for extension in ("html", "svg", "pdf", "docx", "xlsx"):
    save_document(document, f"report.{extension}")

Or render geometry your application already calculated

Use SoulDocument directly when a visual editor, database, or upstream service already provides page numbers, coordinates, and dimensions.

Positioned document IR
from souldoc import SoulBox, SoulContentKind, SoulDocument, SoulPage, save_document

document = SoulDocument(
    name="Contract",
    pages=[
        SoulPage(
            number=1,
            width_mm=210,
            height_mm=297,
            boxes=[
                SoulBox(
                    id="title",
                    page=1,
                    left_mm=20,
                    top_mm=15,
                    width_mm=170,
                    height_mm=20,
                    content="Contract",
                    content_kind=SoulContentKind.TEXT,
                    style="font-size:24pt;font-weight:bold;text-align:center;",
                )
            ],
        )
    ],
)

save_document(document, "contract.pdf")
save_document(document, "contract.docx")

Explicit Markdown

Use Markdown("# Heading") in layout documents or SoulContentKind.MARKDOWN in positioned records. Ordinary text is never interpreted as Markdown automatically.

PyCells MD(...)

When a record contains an =MD("...") formula, SoulDoc prefers its evaluated HTML value and provides a dependency-free Markdown fallback if the value is absent.

Controlled resources

External images are loaded only through an application-provided resolver. Optional SHA-256 metadata can be checked before bytes are embedded.

Related tools, different responsibilities

SoulDoc complements TenTags

TenTags is a compact declarative language and export engine for tables. SoulDoc is a complete document layout engine. Use them independently, or place TenTags tables inside a larger SoulDoc document.

Question TenTags SoulDoc
Primary job Describe and render styled tables Lay out and render complete documents
Typical input A compact table formula A component tree or positioned document IR
Geometry Rows, columns, cells, and merges Pages, flow, free positioning, and physical dimensions
Best used for Tables embedded in applications and templates Reports, contracts, invoices, forms, and full-page documents
Place a TenTags table in a SoulDoc layout
from souldoc import SoulLayoutDocument, save_document, tentags_table

document = SoulLayoutDocument(
    name="TenTags report",
    children=[
        tentags_table(
            "data(A1=<b>Name</b>;B1=Amount;"
            "A2=Service A;B2=1200)"
        )
    ],
)

save_document(document, "table-report.pdf")

Install only what you need

A dependency-free core with optional renderers

Core, HTML, SVG, and JSON

No runtime dependencies.

pip install souldoc

Editable DOCX

Installs Beautiful Soup and python-docx.

pip install "souldoc[docx]"

Visual XLSX

Installs Pillow and XlsxWriter.

pip install "souldoc[xlsx]"

PDF

Install the extra, then install Chromium once.

pip install "souldoc[pdf]" playwright install chromium

Every official renderer

DOCX, XLSX, PDF, font measurement, HTML, SVG, and JSON support.

pip install "souldoc[all]"

Important format notes

  • Default text measurement is deterministic and approximate; exact typography needs known font metrics.
  • SVG uses XHTML foreignObject to preserve rich, editable content.
  • PDF requires Playwright and a locally installed Chromium browser.
  • XLSX is a visual approximation because spreadsheets do not use a document page-layout model.
  • Mathematical content remains editable source text; native OMML is planned work.

PyPI package analytics

SoulDoc installations

Loading the latest archived statistics...

All installations
Last recorded day
-
Last 7 days
-
Last 30 days
-
Direct PyPI only
Last recorded day
-
Last 7 days
-
Last 30 days
-

Build documents once

Keep application logic independent from output formats

Start with the small core, add the renderers your project needs, and let every format consume the same calculated document.