Skip to content

docx://

Status: ✅ Native authoring + read/convert. docx:// is a Helix-native surface for Microsoft Word .docx (Office Open XML) documents.

Powered by the pure-Go github.com/ZeroHawkeye/wordZero library (MIT). No cgo, no external service — the core engine is dependency-free; the Markdown path pulls goldmark.

docx:// complements docling:// (which reads Office documents into Markdown/JSON but cannot write one): docx:// is the authoring half — it creates, converts and fills .docx files.

URI shape

docx:///abs/path/to/file.docx?op=extract_text
docx://relative/out.docx?op=create
docx://?file=/tmp/out.docx&op=from_markdown
docx://?op=render&template=/tpl/invoice.docx&file=/out/invoice.docx

The path may be inside the authority (docx://out.docx), absolute (docx:///abs/out.docx), or supplied via file= or the HelixDocxFile header (per-message override).

Operations (op=)

op input body output notes
extract_text (default) — plain text Self-contained OOXML walk; works on any .docx. Aliases: read, parse.
create structured document model writes .docx The authoring op. Alias: write. See Document model below.
from_markdown Markdown string writes .docx Renders Markdown (headings, lists, tables, emphasis) via goldmark.
to_markdown — Markdown string Exports a .docx back to Markdown (bidirectional).
render data object writes .docx Mail-merge: fills a ?template= .docx. Alias: fill_template. See Templates.
info — map[string]any Metadata: footnotes, endnotes, headings, elements, sizeBytes.

Write ops (create/from_markdown/render) stamp HelixDocxFileWritten (absolute path). Read ops stamp HelixDocxFilePath / HelixDocxFileName.

Document model (op=create)

The body is a JSON/Starlang object the producer walks. The block array may be keyed blocks or body (both accepted). Top-level pageSize (A4|Letter|Legal|A3|A5) and orientation (portrait|landscape) are optional, as is page (margins, mm) and headers/footers/toc.

- set-body:
    starlang: |
      {
        pageSize: "Letter",
        headers: [ { type: "default", text: "ACME — Confidential" } ],
        body: [
          { type: "heading", text: "Quarterly Report", level: 1 },
          { type: "paragraph", text: "Prepared for the board.", italic: true },
          { type: "paragraph", runs: [
              { text: "Status: " },
              { text: "APPROVED", bold: true, color: "008000" } ] },
          { type: "table",
            widths: [4680, 4680],
            rows: [ ["Metric", "Value"], ["Revenue growth", "15 percent"] ] },
          { type: "list", ordered: true, items: ["Reviewed", "Approved"] },
          { type: "footnote", text: "source", note: "Figures are unaudited." }
        ]
      }
- target: "docx://x?op=create"

Block types

type fields maps to
paragraph (p) text or runs[]; align, bold, italic, underline, color, fontSize, fontFamily, highlight paragraph + run formatting
heading (h) text, level (1–9), + paragraph formatting styled heading
table rows[][] (first row auto-styled as header), optional headers[], widths[] (per-col twips), width table
list items[], ordered (bullet vs numbered), level bullet / numbered list
image (img) path or data (base64) + format (png\|jpeg\|gif), imgWidth, imgHeight inline image
footnote / endnote text (anchor), note (body) foot/endnote (see caveat)
pagebreak — page break
math latex OMML formula

A run is { text, bold, italic, underline, strike, fontSize, color, fontFamily, highlight }.

Footnotes render as proper linked references in Word. wordZero's own footnote support is incomplete (it emits a literal [N] marker instead of a <w:footnoteReference>, omits the document→footnotes relationship, and leaks footnotes across documents via a process-global manager), so Helix post-processes every saved .docx to inject the real reference + missing relationship and to drop any leaked notes the document does not reference.

Templates (op=render)

Point template= (or HelixDocxTemplate) at a .docx whose text uses {{name}} variables, {{#if flag}}…{{/if}} conditions and {{#each list}}…{{/each}} loops. The body is the data object; keys are classified automatically — scalars → variables, arrays → lists, booleans → conditions — or given explicitly as { variables, lists, conditions }.

- set-header: { name: HelixDocxTemplate, constant: /templates/invoice.docx }
- set-body:
    starlang: '{ customer: payload.customer, total: payload.total, paid: payload.paid, items: payload.items }'
- target: "docx://x?op=render"

URI parameters

name type default description
file string — Target (write) / source (read) .docx. Also via URI path or HelixDocxFile.
op enum extract_text extract_text \| create \| from_markdown \| to_markdown \| render \| fill_template \| info.
template string — Template .docx for op=render. Also via HelixDocxTemplate.

Headers

Per-message overrides (in): HelixDocxFile, HelixDocxOp, HelixDocxTemplate.

Producer outputs (out): HelixDocxFileWritten (write ops), HelixDocxFilePath / HelixDocxFileName (read ops), HelixDocxTextLength (extract_text), HelixDocxParagraphCount / HelixDocxFootnoteCount / HelixDocxEndnoteCount (info).

Example routes

Author a report at the end of an HTTP request:

workflows:
  - id: generate-report
    trigger:
      uri: http-server://0.0.0.0:8091/report
    steps:
      - set-header:
          name: HelixDocxFile
          starlang: payload.path
      - set-body:
          starlang: '{ body: [ { type: "heading", text: "Report", level: 1 } ] }'
      - target: "docx://x?op=create"

Turn agent-authored Markdown into a Word document:

workflows:
  - id: markdown-to-word
    trigger:
      uri: seda://md-export
    steps:
      - set-header: { name: HelixDocxFile, starlang: 'headers["out-path"]' }
      - target: "docx://x?op=from_markdown"   # body is the Markdown string

Extract text from dropped .docx files for RAG / search:

workflows:
  - id: ingest-word
    trigger:
      uri: "file:///var/data/inbox?include=.*\\.docx$&recursive=true&delay=2s&noop=false"
    steps:
      - set-header: { name: HelixDocxFile, starlang: 'headers["HelixFilePath"]' }
      - target: "docx://x?op=extract_text"
      - target: seda://index-document
surface purpose
docx:// (this component) Create / convert / fill / read .docx
docling:// Read .docx/.pptx/.pdf/html/image → Markdown/JSON (external docling-serve)
xlsx:// Read/write Excel workbooks
pdf:// PDF extract / form-fill / split / rotate
rag/ingest.DOCXParser Plain-text extraction for RAG ingest