Move the full compose pipeline (anchor-pair splicing, append-before-sectPr,
hyperlink-rels patching, zip split/repack, final placeholder pass) into
pkg/docforge/docx/compose.go, decoupled from paliad's DB row types. The
engine now owns the entire .docx assembly.
New neutral types in docx:
- Carrier{Bytes, Stylemap} — the opaque base .docx, preserved
byte-for-byte outside the spliced regions (the lossless docforge
carrier for .docx).
- Section{Key, OrderIndex, Included, ContentMDDE, ContentMDEN} — the
format-neutral content input.
- Composer / NewComposer / ComposeOptions on those neutral types.
internal/services keeps SubmissionComposer + ComposeOptions as a thin
mapping wrapper (SubmissionSection -> docx.Section, Base.SectionSpec.Stylemap
+ BaseBytes -> docx.Carrier). handlers + the comprehensive compose_test are
unchanged; the test drives the wrapper end-to-end and its byte-exact OOXML
assertions pass = behaviour preserved.
Retired the slice-1 docx.XMLAttrEscape wrapper + its services forwarder:
compose now calls the local xmlAttrEscape inside the docx package.
Sequencing note: the paragraph-level neutral model (Document/Block/Slot the
PRD §3.2 sketches) is deferred to slice 6, where the authoring importer +
format exporters consume it. Building it now, ahead of any consumer, would
be speculative and risk the byte-identical guarantee for no gain (PRD §4 B3
principle). Carrier is the part of the model that earns its keep this cycle.
Verification: go build ./... clean, go vet clean, full module test green.
m/paliad#157
60 lines
2.8 KiB
Go
60 lines
2.8 KiB
Go
package services
|
|
|
|
// Shims bridging the submission generator to the extracted docforge .docx
|
|
// adapter (pkg/docforge/docx). Slice 1 of the docforge train
|
|
// (t-paliad-349 / m/paliad#157) relocated the Markdown→OOXML walker, the
|
|
// placeholder substitution engine, and the .dotm→.docx converter into
|
|
// pkg/docforge/docx with no behaviour change. These type aliases and
|
|
// forwarders keep every existing caller in internal/services and
|
|
// internal/handlers compiling and behaving identically — the names,
|
|
// signatures, and semantics are unchanged; only the implementation moved.
|
|
//
|
|
// Later slices retire these shims as the submission services are
|
|
// refactored to call docforge directly through the neutral model and the
|
|
// VariableResolver interface.
|
|
|
|
import "mgit.msbls.de/m/paliad/pkg/docforge/docx"
|
|
|
|
// PlaceholderMap is the variable bag (dotted-key → substituted value),
|
|
// built by SubmissionVarsService and consumed by the renderer.
|
|
type PlaceholderMap = docx.PlaceholderMap
|
|
|
|
// MissingPlaceholderFn translates an unbound placeholder key into the
|
|
// in-document marker token.
|
|
type MissingPlaceholderFn = docx.MissingPlaceholderFn
|
|
|
|
// SubmissionRenderer renders a .docx template by substituting
|
|
// {{placeholder}} tokens. Stateless; safe for concurrent use.
|
|
type SubmissionRenderer = docx.SubmissionRenderer
|
|
|
|
// HyperlinkAllocator hands the Markdown walker a rId for each external
|
|
// URL it encounters in [label](url) inline links.
|
|
type HyperlinkAllocator = docx.HyperlinkAllocator
|
|
|
|
// NewSubmissionRenderer constructs the renderer.
|
|
func NewSubmissionRenderer() *SubmissionRenderer { return docx.NewSubmissionRenderer() }
|
|
|
|
// DefaultMissingMarker returns the standard missing-value marker for the
|
|
// given UI language ("[KEIN WERT: <key>]" / "[NO VALUE: <key>]").
|
|
func DefaultMissingMarker(lang string) MissingPlaceholderFn { return docx.DefaultMissingMarker(lang) }
|
|
|
|
// RenderMarkdownToOOXML renders Markdown source into OOXML paragraph
|
|
// elements using a single paragraph style.
|
|
func RenderMarkdownToOOXML(md, paragraphStyle string) string {
|
|
return docx.RenderMarkdownToOOXML(md, paragraphStyle)
|
|
}
|
|
|
|
// RenderMarkdownToOOXMLWithStyles is the full rich-prose entry point
|
|
// (headings, lists, blockquote, inline hyperlinks via the allocator).
|
|
func RenderMarkdownToOOXMLWithStyles(md string, stylemap map[string]string, links HyperlinkAllocator) string {
|
|
return docx.RenderMarkdownToOOXMLWithStyles(md, stylemap, links)
|
|
}
|
|
|
|
// ConvertDotmToDocx rewrites a .dotm/.docm/.dotx zip into a clean .docx
|
|
// zip. Idempotent on a zip that is already a plain .docx.
|
|
func ConvertDotmToDocx(dotmBytes []byte) ([]byte, error) { return docx.ConvertDotmToDocx(dotmBytes) }
|
|
|
|
// SanitiseSubmissionFileName cleans a string for use inside a download
|
|
// filename (strips path separators / quotes, ASCII-folds DE umlauts).
|
|
func SanitiseSubmissionFileName(s string) string { return docx.SanitiseSubmissionFileName(s) }
|