Files
paliad/pkg/docforge/exporter.go
mAi 8763ab013c feat(docforge): slice 8 — neutral model + Markdown importer + Exporter iface (t-paliad-349)
The final slice: land the format-neutral document model with REAL consumers
and unify the Markdown parser — no duplication, byte-identical output.

Neutral model (pkg/docforge/model.go): Document / Block / InlineSpan.
BlockKind values are the stylemap keys. A hyperlink is a span with Link set
+ Children (the label's spans), preserving link boundaries so adjacent
same-URL links stay distinct — byte-exact with the pre-model walker.

Markdown importer (pkg/docforge/markdown): Import(md) → Document. The SINGLE
Markdown parser for docforge — block split, marker detection, inline
bold/italic/link tokenisation, {{placeholder}} pass-through (the b78a984
fix). Relocated out of the docx walker.

docx renderer (pkg/docforge/docx/markdown.go): now RENDERS a Document →
OOXML (RenderDocumentToOOXML); RenderMarkdownToOOXML[WithStyles] = render(
markdown.Import(md)). The shipped submission walker routes through the model,
so there is one parser, not two. The comprehensive byte-exact render tests
(RenderMarkdownToOOXML_*) all PASS unchanged = output identical.

Exporter interface (pkg/docforge/exporter.go, PRD §4 B4): Exporter{Format,
MIMEType, RenderBody(Document)} with the .docx impl (pkg/docforge/docx/
exporter.go). The seam a future PDF/HTML exporter slots into.

Tests: parser tests relocated to the markdown pkg (parseSpans/detectBlockMarker)
+ new importer Document tests + exporter conformance test.

Verification: go build/vet clean; gofmt clean; full NO-DB test suite GREEN
(authoritative — proves no regression); docforge byte-exact render oracle
PASS; composer live test renders through the rewired walker (PASS); bun build
+ bun test 274/274. The shared-DB live run fails ~85 tests across unrelated
services from a harness pq-42P08 $1-type seeding quirk + a stale
deadline_rules test — systemic/environmental (the no-DB run is clean), not
this change.

docforge train complete: 8 slices, the engine extracted + cleaned + a working
author→generate→export loop on uploaded templates, plus the neutral model +
importer + exporter seam for future formats/consumers.

m/paliad#157
2026-05-29 18:10:16 +02:00

23 lines
1.0 KiB
Go

package docforge
// Exporter renders a neutral Document into a target format's body markup.
// docforge owns the interface; each format adapter implements it (the
// .docx adapter in pkg/docforge/docx today; .pdf/.html/.md are future
// siblings — PRD §4 B4: interface now, docx-only impl). Format-specific
// configuration (a stylemap, a hyperlink allocator for .docx) is baked into
// the concrete exporter at construction, so the interface stays
// format-neutral.
//
// "Body markup" is the renderable content fragment, not a complete file —
// for .docx it is the OOXML <w:p> run the composer splices into a carrier.
// Container concerns (MIME type, packaging) are described by Format /
// MIMEType and handled by the assembling layer.
type Exporter interface {
// Format is the short format id, e.g. "docx".
Format() string
// MIMEType is the container MIME type the assembled document carries.
MIMEType() string
// RenderBody renders the document to the format's body markup.
RenderBody(doc Document) ([]byte, error)
}