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, andDocxStyle.- 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 whenDocxFieldRefreshOptionsis 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:
docxtplpython-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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff71bb5877a6e6a121b884d02d585ea293559c402f667f25f10da53ef37cef19
|
|
| MD5 |
cfd28186895aacbed0a59ea1885537bd
|
|
| BLAKE2b-256 |
4ff61b2de9a1daf2d225eca6db0a03223ef38479d9204f5902a4b7051b6f6a8b
|
Provenance
The following attestation bundles were made for docxrender-0.1.0.tar.gz:
Publisher:
publish.yml on FuqingZh/docxrender
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docxrender-0.1.0.tar.gz -
Subject digest:
ff71bb5877a6e6a121b884d02d585ea293559c402f667f25f10da53ef37cef19 - Sigstore transparency entry: 1961270755
- Sigstore integration time:
-
Permalink:
FuqingZh/docxrender@59fc5b3b6ab3295051abb865156937aa0e8d577e -
Branch / Tag:
refs/tags/0.0.1 - Owner: https://github.com/FuqingZh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@59fc5b3b6ab3295051abb865156937aa0e8d577e -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65e912442379adcffa70b5b6bbd6d6772ed333d1578aad52121ff7fc4c52195a
|
|
| MD5 |
3833e016eab764bdbbfe8fd7f44d4206
|
|
| BLAKE2b-256 |
3d061c53b73e5bd7ce8244731efc36fcbd4406151bbab08d1e88699e90dab942
|
Provenance
The following attestation bundles were made for docxrender-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on FuqingZh/docxrender
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docxrender-0.1.0-py3-none-any.whl -
Subject digest:
65e912442379adcffa70b5b6bbd6d6772ed333d1578aad52121ff7fc4c52195a - Sigstore transparency entry: 1961270828
- Sigstore integration time:
-
Permalink:
FuqingZh/docxrender@59fc5b3b6ab3295051abb865156937aa0e8d577e -
Branch / Tag:
refs/tags/0.0.1 - Owner: https://github.com/FuqingZh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@59fc5b3b6ab3295051abb865156937aa0e8d577e -
Trigger Event:
push
-
Statement type: