Move the variable-bag contract (PlaceholderMap, MissingPlaceholderFn,
DefaultMissingMarker) up to the pkg/docforge root (placeholder.go) — it is
format-neutral, consumed by the resolver layer and any future exporter.
The {{key}} substitution grammar (placeholderRegex, PUA preview sentinels,
replacePlaceholders) stays in pkg/docforge/docx: it is the .docx renderer's
own machinery, not a root concern.
New at the root (vars.go):
- VariableResolver{Namespace() string; Populate(bag PlaceholderMap)} —
a PUSH interface, deliberately not pull Resolve(key): some namespaces
emit a data-dependent key set (parties.claimant.0.name, .1.name, … one
per party) that a fixed key-by-key pull can't enumerate.
- ResolverSet + BuildBag() — composes resolvers into one bag, replacing
the hard-coded addFooVars-then-addBarVars sequencing in Build.
paliad side (submission_vars_resolvers.go): seven resolver types wrap the
UNCHANGED addXxxVars push-builders (firm/today/user/procedural_event/
project/parties/deadline), each capturing the entity it needs. The builder
bodies are byte-for-byte untouched, so the bag is identical by
construction; SubmissionVarsService.Build now wires the applicable
resolvers and calls ResolverSet.BuildBag(). Resolvers stay in paliad
because they read paliad's domain model; a second docforge consumer plugs
its own resolvers into a ResolverSet the same way.
Keys()/Catalogue() (the static key list that will data-drive the authoring
palette + kill the hardcoded VARIABLE_GROUPS in submission-draft.ts) is
deferred to the UI slice that consumes it, sourced from the frontend's
existing labels — building it now, ahead of its consumer, would be
speculative (PRD §4 B3 principle).
Verification: go build ./... clean, go vet clean, full module test green.
Alias-parity (procedural_event ≡ rule) and party-form tests pass unchanged
= bag byte-identical.
m/paliad#157
67 lines
3.0 KiB
Go
67 lines
3.0 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"
|
|
"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. The
|
|
// canonical type lives in the docforge root (the format-neutral
|
|
// variable-bag contract).
|
|
type PlaceholderMap = docforge.PlaceholderMap
|
|
|
|
// MissingPlaceholderFn translates an unbound placeholder key into the
|
|
// in-document marker token.
|
|
type MissingPlaceholderFn = docforge.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 docforge.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) }
|