Skip to main content

Minimal DOCX rendering core for template, markdown, field refresh, and PDF conversion workflows

Project description

docxrender

docxrender is a small Python package for Word-first DOCX rendering.

Its core boundary is intentionally narrow:

file_template + context + markdown_body + DocxStyle -> DOCX -> PDF

The package owns technical rendering mechanics: DOCX template rendering, markdown body insertion, Word style application, DOCX field handling, and eventual LibreOffice-based PDF conversion. Product repositories own report content, workflow resource layout, section rendering, manifest schemas, figure selection, captions, and delivery directory semantics.

Status

Current implementation:

  • Public style/options/result dataclasses are available.
  • write_docx(...) can create a minimal DOCX from a DOCX template, context, markdown body, image assets, and DocxStyle.
  • Markdown support currently covers headings, paragraphs, hard line breaks, ordered lists, tables, images, page breaks, and spacers.
  • Basic Word styling is applied from caller-provided DocxStyle.
  • DOCX field update/freeze behavior is implemented through DOCX XML rewriting.
  • write_docx(...) can optionally refresh TOC/page fields through LibreOffice UNO when DocxFieldRefreshOptions is provided.
  • convert_docx_to_pdf(...) converts through LibreOffice UNO when the external LibreOffice/UNO runtime is available.

Install For Local Development

pdm install

Runtime dependencies are declared in pyproject.toml:

  • docxtpl
  • python-docx

PDF conversion and DOCX field refresh are optional runtime features. They do not require extra Python packages from docxrender, but they do require an external LibreOffice/UNO runtime.

libreoffice --headless --version
python -c "import uno"

On Debian or Ubuntu, that runtime is typically installed outside Python:

sudo apt install libreoffice python3-uno

docxrender intentionally does not provide a docxrender[pdf] extra. Installing a Python package should not silently install system software or require administrator privileges. Base DOCX writing with field_refresh=None does not import UNO and works without LibreOffice.

Public API

The stable public API is exported from the package root. Product repositories should prefer from docxrender import ...; implementation modules such as docxrender.markdown and docxrender.docx are technical layers and are not compatibility-stable public contracts.

from docxrender import (
    DocxWriter,
    DocxFieldRefreshOptions,
    DocxFontStyle,
    DocxParagraphStyle,
    DocxSizeStyle,
    DocxStyle,
    DocxTableStyle,
    DocxWriteOptions,
    write_docx,
)

DocxFieldRefreshOptions is optional. Use it only when the caller has provided a LibreOffice/UNO runtime and wants a DOCX whose TOC, page fields, or other Word fields have been refreshed by LibreOffice:

DocxWriteOptions(
    ...,
    field_refresh=DocxFieldRefreshOptions(
        exe_libreoffice=Path("/usr/bin/libreoffice"),
        dir_user_profile=Path("tmp/lo-profile"),
        should_require_toc=True,
        should_freeze_fields=True,
    ),
)

Minimal fluent DOCX write example:

from pathlib import Path

from docxrender import DocxWriter

result = (
    DocxWriter()
    .with_fonts(
        font_name_latin="Times New Roman",
        font_name_body_east_asia="宋体",
        font_name_heading_east_asia="宋体",
    )
    .with_sizes(
        pt_title_page_title=36.0,
        pt_title_page_meta=18.0,
        pt_title_page_compiler=15.0,
        pt_body=12.0,
        pt_caption=10.5,
        pt_table=12.0,
        pt_heading_by_level={1: 16.0, 2: 14.0, 3: 12.0},
    )
    .with_table(
        border_color="000000",
        stripe_fill_color="D9D9D9",
        border_size_main="12",
        border_size_header="6",
        line_spacing=1.5,
    )
    .with_paragraph(
        line_spacing_body=1.5,
        line_spacing_note=1.2,
        first_line_indent_cm=0.74,
    )
    .write_docx(
        file_template=Path("template.docx"),
        file_out_docx=Path("report.docx"),
        context={"report_title": "Example Report"},
        markdown_body="# Summary\n\nBody text.",
        dir_base=Path("."),
    )
)
print(result.file_docx)

markdown_body is the already-rendered Markdown body to insert into the DOCX template. dir_base is the base directory used to resolve relative image paths inside that Markdown body.

Explicit dataclass DOCX write example:

from pathlib import Path

from docxrender import (
    DocxFontStyle,
    DocxParagraphStyle,
    DocxSizeStyle,
    DocxStyle,
    DocxTableStyle,
    DocxWriteOptions,
    write_docx,
)

style = DocxStyle(
    fonts=DocxFontStyle(
        font_name_latin="Times New Roman",
        font_name_body_east_asia="宋体",
        font_name_heading_east_asia="宋体",
    ),
    sizes=DocxSizeStyle(
        pt_title_page_title=36.0,
        pt_title_page_meta=18.0,
        pt_title_page_compiler=15.0,
        pt_body=12.0,
        pt_caption=10.5,
        pt_table=12.0,
        pt_heading_by_level={1: 16.0, 2: 14.0, 3: 12.0},
    ),
    table=DocxTableStyle(
        border_color="000000",
        stripe_fill_color="D9D9D9",
        border_size_main="12",
        border_size_header="6",
        line_spacing=1.5,
    ),
    paragraph=DocxParagraphStyle(
        line_spacing_body=1.5,
        line_spacing_note=1.2,
        first_line_indent_cm=0.74,
    ),
)

result = write_docx(
    DocxWriteOptions(
        file_template=Path("template.docx"),
        file_out_docx=Path("report.docx"),
        context={"report_title": "Example Report"},
        markdown_body="# Summary\n\nBody text.",
        dir_base=Path("."),
        style=style,
    )
)
print(result.file_docx)

The template should contain a paragraph whose text is the body anchor token:

{{ body_anchor }}

docxrender sets body_anchor in the template context when the caller does not provide it.

Style Configuration

docxrender does not read TOML, JSON, YAML, or any other config file in its public API. Callers convert their own configuration into DocxStyle.

The initial style model is based on:

/home/fqzhang/project/workflows/resources/common/report/style.toml

That file is a reference for fields and defaults, not a runtime dependency of the package.

Non-Goals

docxrender does not own:

  • report manifest schemas
  • workflow resource layout
  • Jinja section discovery
  • product-specific context builders
  • figure registries or captions
  • Result/... delivery path semantics
  • 结果目录 text generation
  • style config file readers

Tests

Run the current test suite:

pdm run python -m pytest -v

ty is available as an advisory type checker beside pyright:

pdm run ty check .

Pyright remains the primary type gate.

The suite currently covers public API construction, minimal DOCX writing, markdown body insertion, basic style application, and the boundary that docxrender does not import product repositories.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

docxrender-0.1.0.tar.gz (26.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

docxrender-0.1.0-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

File details

Details for the file docxrender-0.1.0.tar.gz.

File metadata

  • Download URL: docxrender-0.1.0.tar.gz
  • Upload date:
  • Size: 26.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for docxrender-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ff71bb5877a6e6a121b884d02d585ea293559c402f667f25f10da53ef37cef19
MD5 cfd28186895aacbed0a59ea1885537bd
BLAKE2b-256 4ff61b2de9a1daf2d225eca6db0a03223ef38479d9204f5902a4b7051b6f6a8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for docxrender-0.1.0.tar.gz:

Publisher: publish.yml on FuqingZh/docxrender

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file docxrender-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: docxrender-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for docxrender-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 65e912442379adcffa70b5b6bbd6d6772ed333d1578aad52121ff7fc4c52195a
MD5 3833e016eab764bdbbfe8fd7f44d4206
BLAKE2b-256 3d061c53b73e5bd7ce8244731efc36fcbd4406151bbab08d1e88699e90dab942

See more details on using hashes here.

Provenance

The following attestation bundles were made for docxrender-0.1.0-py3-none-any.whl:

Publisher: publish.yml on FuqingZh/docxrender

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page