Part of NEURA Office: native Word, PowerPoint and Excel for Open WebUI.
A Open WebUI Tool that generates
native Word (.docx) documents from Markdown (with YAML frontmatter) or a JSON
spec produced by the model. It doesn't export HTML or PDF: it builds the document
directly with python-docx, with a coherent design system — cover pages, numbered
headings with rules, styled tables, callouts, code blocks, signatures, TOC and a
running header/footer.
The resulting file is saved through Open WebUI's Files API (with a /cache/files
fallback) and a clickable download link appears in the chat.
License: MIT · Author: IANUSTEC
Left: client brand (examples/brand.md → examples/demo_brand.docx). Right: examples/report.md → examples/demo_report.docx.
- Native, editable .docx (text, tables and styles are editable in Word / Pages / LibreOffice).
- Dual input, auto-detected: Markdown-with-frontmatter (preferred) or JSON — same output.
- 7 templates with a coherent palette derived from a single
accentcolor:report,whitepaper,proposal,letter,memo,minutes,blank. - Cover pages:
band(accent panel),rule(editorial) orplain. - Numbered headings (1, 1.1, 1.1.1) with H1/H2 accent rules — auto-strips any manual number.
- Rich tables: filled accent header, zebra rows, automatic right-alignment of numeric/currency columns.
- Callouts:
info,success,warning,danger(colored bar + tint). - Lists (bullets, ordered, checklists), blockquotes, code blocks, signatures, TOC, page breaks.
==highlight==maps to accent-colored emphasis; smart quotes; typographic spacing.- Header / footer with 3 zones (
left/center/right) and live page numbers ({{page}}/{{pages}}). - Human-readable filename derived from the title (e.g.
Q3 Board Report.docx). - Optional images from Unsplash (with a key) or generated via Open WebUI.
- Single-file: one self-contained
.py, ready to paste into the Tools registry. - Client brand:
brand: <preset>(or an inline map with name, logos and two colours) gives a full-page branded cover with a grid ofcover.metafields, a running header with the logo and a "Page X of Y" footer. - Tidy structure: a
---right before a heading is dropped (the heading already draws its rule); with a cover, a single#wrapping the whole document becomes the cover subtitle and the sections move up one level. - Word-exact output: table grids match the cells, column widths follow the content, and every property element is written in schema order (Word, unlike LibreOffice, ignores out-of-order cell margins).
- Company letterhead: set
letterhead: "Filename.docx"(.dotxaccepted). Resolved from chat attachments first, then from/mnt/uploads(and the Open WebUI upload dir). Header, footer and margins are kept; only the body is rewritten.
- Open WebUI
>= 0.4.0 - Python:
python-docx,Pillow,markdown-it-py,mdit-py-plugins,PyYAML,lxml(declared in the frontmatter → Open WebUI installs them automatically) - Optional:
httpx(fetch images from URL / Unsplash)
- Open the tool page on the Open WebUI community site.
- Click Get / Import to your instance.
- In your Open WebUI instance go to Workspace → Tools → +.
- Paste the contents of
generate_documents.py. - Save. The declared dependencies are installed on first use.
- Enable the tool for the model (or chat) that should use it.
The model calls generate_document(content), where content is either
Markdown-with-frontmatter (preferred) or a JSON string.
---
template: report
title: "Digital Transformation Program — FY 2026"
subtitle: "Strategic plan, roadmap and budget"
author: "Northwind Analytics"
cover: auto
header:
left: "Northwind Analytics — Confidential"
right: "Rev. 1.0"
footer:
center: "Page {{page}} of {{pages}}"
styles:
accent: "#1B6B93"
---
# Executive Summary
Revenue grew **24%** year over year.
::: callout type="success" title="Highlight"
Operating margin expanded by ==6 pp==.
:::
| Objective | KPI target | Priority |
|-----------|-----------|----------|
| Process automation | 80% of flows | ==High== |See the full example in examples/report.md.
- Attach a letterhead or sample
.docx/.dotxin the chat, or place it under/mnt/uploads. - Tell the model which file to use, or put it in the frontmatter:
---
template: blank
letterhead: "Carta_Rossi.docx"
title: "Quote Q3"
---
# Scope of work
...Aliases: sample, base_docx. Matching is by basename (exact, case-insensitive, or stem).
Open WebUI uuid-prefixed upload names (<uuid>_Filename.dotx) are matched too.
If the name is missing, the tool lists chat attachments and the files found in the scanned dirs.
Do not use a programmatic cover together with a letterhead (it would fight the company header).
See also examples/letterhead.md.
Install a preset as <brands_dir>/<name>.json (default /app/backend/data/brands) with the logo files next to it:
{ "name": "IANUSTEC S.r.l.", "logo": "ianustec_logo.png", "logo_header": "ianustec_wordmark.png",
"primary": "#000000", "secondary": "#333333", "prepared_by": "NEURA | IANUSTEC" }Then in the frontmatter:
---
template: report
title: "Tender analysis"
brand: ianustec
lang: en
cover:
kicker: "Tender analysis"
meta:
Client: "City of X"
Tender ID: "AB12345678"
---brand also accepts the map itself. Its logo can be the name of an image attached in chat (pasted, uploaded, or saved to the user's Open Terminal when chat_uploads is filesystem), a path in the user's terminal, a URL or a data URI; without logo the image attached in chat is used. An unknown preset name returns the list of installed ones. A black or grey brand colour gets a light cover band instead of a solid dark one.
{
"template": "report",
"title": "FY 2026 Report",
"cover": "auto",
"styles": { "accent": "#1B6B93" },
"blocks": [
{ "type": "heading", "level": 1, "text": "Executive Summary" },
{ "type": "paragraph", "text": "Revenue grew 24% YoY." },
{ "type": "callout", "kind": "success", "title": "Highlight", "text": "Margin +6pp." }
]
}report · whitepaper · proposal · letter · memo · minutes · blank.
Every template derives its full palette from a single accent color, so
styles: { accent: "#C0392B" } re-themes the whole document.
| Block | Syntax |
|---|---|
| Headings | # H1 … #### H4 (auto-numbered in report/whitepaper) |
| Emphasis | **bold**, *italic*, `code`, ==highlight== |
| Lists | - bullet, 1. ordered, - [ ] checklist |
| Table | standard Markdown pipe table (numeric columns auto right-aligned) |
| Callout | ::: callout type="info|success|warning|danger" title="..." … ::: |
| Quote | > quoted text |
| Code | fenced ``` block |
| Signature | ::: signature name="..." role="..." date="..." … ::: |
| TOC | [[toc]] |
| Page break | \newpage |
| Cover | Content |
|---|---|
![]() |
![]() |
| Callouts & tables | Risk matrix & signatures |
![]() |
![]() |
| Client brand: cover | Client brand: header and footer |
![]() |
![]() |
| Valve | Default | Description |
|---|---|---|
default_template |
blank |
Template used when the spec doesn't set one |
unsplash_access_key |
"" |
Unsplash key for stock images (optional) |
image_generation_url |
"" |
OpenAI-compatible image endpoint (optional) |
image_generation_api_key |
"" |
Bearer token for image_generation_url |
docx_export_dir |
/app/backend/data/cache/files |
Fallback directory for saving |
emit_status |
true |
Emit status events in chat |
brands_dir |
/app/backend/data/brands |
Brand presets for brand: <name> |
language |
it |
Labels written by the tool (cover date, page X of Y): it or en; frontmatter lang overrides |
- The model produces Markdown (or JSON) and calls
generate_document. - The parser normalizes both formats into one spec, merges it with the template defaults, and resolves the accent palette.
- Each block is written as native OOXML (paragraphs, tables, shading, borders, fields).
- The
.docxis saved via the Files API (fallback/cache/files) and the link is returned in chat.
Requires python-docx, markdown-it-py, mdit-py-plugins, PyYAML (and optionally pillow/httpx):
pip install python-docx pillow httpx markdown-it-py mdit-py-plugins PyYAML
python examples/build.py # → examples/demo_report.docx, examples/demo_brand.docxThe file is designed to run inside Open WebUI: the open_webui.* imports are optional
and the tool degrades gracefully when they're missing (handy for isolated render tests).
Issues and PRs welcome. Please keep the file single-file and free of mandatory network dependencies for the core features.
MIT © IANUSTEC






