Skip to main content

High-level block-based abstraction over python-docx for building dynamic Word documents in code.

Project description

docxblocks

🧱 High-level, block-based abstraction for python-docx.

🚀 Why docxblocks?

Unlike templating libraries like docxtpl, docxblocks keeps all logic in Python, not in .docx files. Build dynamic Word reports from structured block objects inside your codebase.

✨ Key Features

  • Block types: text, heading, table, bullets, image, page_break
  • Inline text by default - consecutive text blocks stay on the same line
  • Smart newline handling - \n\n creates new paragraphs with blank lines
  • Style control via consistent style dictionaries
  • Graceful fallback for missing data
  • Declarative, testable, version-controlled
  • No logic inside Word templates

📦 Installation

pip install docxblocks

📘 See the Style Guide for all supported style keys, color formats, and alignment options.

📄 Creating Word Templates

Important: Placeholder Requirements

Each placeholder MUST be in its own paragraph. This is crucial for proper document generation.

Correct Template Structure:

Paragraph 1: {{main}}
Paragraph 2: (empty or other content)
Paragraph 3: {{header}}

Incorrect Template Structure:

Paragraph 1: Some text {{main}} more text
Paragraph 2: {{header}} and other content

How to Create Templates:

  1. Open Microsoft Word and create a new document
  2. Add placeholders by typing them in separate paragraphs:
    • Type {{main}} and press Enter
    • Type {{header}} and press Enter
    • Each placeholder gets its own paragraph
  3. Save as .docx format
  4. Use in your code with DocxBuilder("template.docx")

Template Example:

Document Title

{{header}}

{{main}}

{{footer}}

🧱 Block-Based API (Core Concept)

Each piece of content is a block:

{
  "type": "text",
  "text": "All systems operational.",
  "style": {
    "bold": True,
    "italic": False,
    "font_color": "007700",
    "align": "center",
    "style": "Normal"
  }
}

Text Block Newline Behavior

Text blocks have intelligent newline handling:

  • Single \n: Remains as literal newline character (inline)
  • Double \n\n: Creates a new paragraph with a blank line before it
  • Mixed usage: Works seamlessly with both patterns
{"type": "text", "text": "Line 1\nLine 2\n\nNew paragraph with blank line above."}

Table Cell Newline Behavior

Table cells also support the same intelligent newline handling:

  • Single \n: Remains as literal newline character within the cell
  • Double \n\n: Creates new paragraphs with blank lines within the cell
  • Works in headers and data cells: Both header and row content support newline processing
{
    "type": "table",
    "content": {
        "headers": ["Name", "Description\n\nDetails"],
        "rows": [
            ["Item 1", "First paragraph.\n\nSecond paragraph with blank line."],
            ["Item 2", "Line 1\nLine 2\n\nNew paragraph."]
        ]
    }
}

Block types:

Type Required Keys Optional Keys
text text new_paragraph
heading text, level
table content
image path
bullets items (list)
page_break (none)

Image Resizing

Images support automatic resizing with max_width and max_height constraints:

{
    "type": "image", 
    "path": "chart.png",
    "style": {
        "max_width": "4in",
        "max_height": "3in"
    }
}

Features:

  • Upscaling: Small images can be scaled up to meet size constraints
  • Downscaling: Large images are scaled down to fit within constraints
  • Aspect ratio preservation: Images maintain their original proportions
  • Flexible constraints: Use either max_width, max_height, or both
  • Multiple units: Supports inches ("4in") and pixels ("300px")

🧪 Example

from docxblocks import DocxBuilder

builder = DocxBuilder("template.docx")
builder.insert("{{main}}", [
    {"type": "heading", "text": "Summary", "level": 2},
    {"type": "text", "text": "This report provides status."},
    {
        "type": "table",
        "content": {
            "headers": ["Service", "Status"],
            "rows": [["API", "OK"], ["DB", "OK"]]
        },
        "style": {
            "header_styles": {"bold": True, "bg_color": "f2f2f2"},
            "column_widths": [0.5, 0.5]
        }
    },
    {"type": "page_break"},
    {"type": "image", "path": "chart.png", "style": {"max_width": "4in"}}
])
builder.save("output.docx")

🛠️ Philosophy

Keep the logic in your code — not in your Word template.

  • Fully programmatic document generation
  • No fragile embedded logic ({{ if x }}) in .docx
  • Declarative, JSON-like format ideal for automation and templating
  • Built for dynamic, testable, repeatable reports

🧪 Development

Setup

# Clone the repository
git clone https://github.com/frank-895/docxblocks.git
cd docxblocks

# Run the development setup script
./scripts/setup_dev.sh

Testing

# Run all tests
PYTHONPATH=. pytest tests

# Run tests with verbose output
PYTHONPATH=. pytest tests -v

# Run specific test file
PYTHONPATH=. pytest tests/test_text_block.py

Examples

# Run individual examples
cd examples
python text_block_example.py
python table_block_example.py
python image_block_example.py
python combined_example.py
python inline_text_example.py  # Inline text functionality
python page_break_example.py   # Page break functionality
python newline_example.py      # Newline handling in text and tables

Continuous Integration

GitHub Actions automatically runs tests on:

  • Every push to main and develop branches
  • Every pull request to main
  • Multiple Python versions (3.9, 3.10, 3.11)

Note: Tests run automatically in CI, so you can push your changes and see the results on GitHub.

📄 License

MIT - LICENSE

Paragraph and Inline Text Rules

  • Consecutive text blocks are grouped inline by default (in the same paragraph).
  • Any \n in a text block always starts a new paragraph (splits the text into multiple paragraphs).
  • new_paragraph: True always starts a new paragraph (and resets inline grouping).
  • After a new paragraph (from either \n or new_paragraph: True), the next inline block starts a new paragraph group.
  • Table cells and headers behave the same way as text blocks: every \n creates a new paragraph, and consecutive cell blocks are grouped inline unless \n or new_paragraph: True is used.
  • spacing parameter only applies to blocks with new_paragraph: True (adds extra blank paragraphs after that block). For inline text, spacing is ignored.

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

docxblocks-1.3.3.tar.gz (22.2 kB view details)

Uploaded Source

Built Distribution

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

docxblocks-1.3.3-py3-none-any.whl (21.0 kB view details)

Uploaded Python 3

File details

Details for the file docxblocks-1.3.3.tar.gz.

File metadata

  • Download URL: docxblocks-1.3.3.tar.gz
  • Upload date:
  • Size: 22.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for docxblocks-1.3.3.tar.gz
Algorithm Hash digest
SHA256 fa3cf843e59bc018c2d39d6d28594c61592626aa3d46454c81ca679c926952b7
MD5 324ad00d2813ead854c54f157ae8b888
BLAKE2b-256 0a075b4f3f699a94faa27e62f2338588e40d4bc7f1c9edc69bcd6a6f9f0762c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for docxblocks-1.3.3.tar.gz:

Publisher: release.yml on frank-895/docxblocks

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

File details

Details for the file docxblocks-1.3.3-py3-none-any.whl.

File metadata

  • Download URL: docxblocks-1.3.3-py3-none-any.whl
  • Upload date:
  • Size: 21.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for docxblocks-1.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 9f23371ee47acfc6f3abdb160b8c856b0559a330c65c4b95f340ccee7ec40681
MD5 04045af18fd58f9bc55a51360e3cd275
BLAKE2b-256 9541bbacd983938415f2ec5f734e04b36a33c5b73d98636e641c68a1baeaefd9

See more details on using hashes here.

Provenance

The following attestation bundles were made for docxblocks-1.3.3-py3-none-any.whl:

Publisher: release.yml on frank-895/docxblocks

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