Documentation
¶
Overview ¶
Package render parses awf section markers and renders templates with per-project overlays via text/template.
Index ¶
- Constants
- func Assemble(segs []Segment, plan map[string]SectionPlan) (string, map[string]string)
- func CheckResidualMarkers(assembled string) error
- func CheckSectionDefaultStubs(segs []Segment, plan map[string]SectionPlan) error
- func Execute(assembled string, data map[string]any, parts map[string]string, name string) (string, error)
- func ExpandIncludes(src string, partialFS fs.FS) (string, error)
- func HasMarkerLine(body string) bool
- func HasStubMarker(body string) bool
- func PlaceholderVarRefs(body string) []string
- func ReferencedDataKeys(src string) []string
- func ReferencedVars(src string) []string
- func ReferencesBareData(src string) bool
- func ReferencesBareVars(src string) bool
- func ReferencesInvariantMarkerPlaceholder(body string) bool
- func ReferencesInvariantMarkers(src string) bool
- func ReferencesScopePlaceholder(body string) bool
- func ReferencesScopes(src string) bool
- func ReferencesSkills(src string) bool
- func StubSections(segs []Segment, plan map[string]SectionPlan) (defaults, parts []string)
- type SectionPlan
- type Segment
Constants ¶
const SectionDefaultSentinel = "\x00awf:section-default\x00"
SectionDefaultSentinel is the brace-free, NUL-delimited token the project layer substitutes for the {{=awf:sectionDefault}} placeholder (ADR-0072). Assemble splits a part body at each occurrence and splices the section's raw default source between the verbatim fragments, so Execute renders the default in place. Brace-free (inert to the template parser) and NUL-delimited (cannot collide with template or markdown text).
Variables ¶
This section is empty.
Functions ¶
func Assemble ¶
Assemble applies the per-section plan to the parsed segments and returns the template skeleton plus a sentinel→raw-body map. Literal segments pass through verbatim; each non-dropped section is prefixed with its awf:edit pointer, then either a sentinel standing in for its part body (restored after Execute) or the template default. Section markers are consumed here and never written. invariant: no-section-marker-leak
func CheckResidualMarkers ¶ added in v0.10.0
CheckResidualMarkers hard-errors when an assembled skeleton still contains a marker-shaped awf:section/awf:end token — a malformed marker (unknown attribute, missing name) that ParseSections could not consume and that would otherwise leak verbatim into rendered output. It runs pre-Execute: part bodies are NUL sentinels and data is uninterpolated, so parts and data that quote the full comment form stay out of scope. invariant: no-residual-section-marker
func CheckSectionDefaultStubs ¶ added in v0.11.0
func CheckSectionDefaultStubs(segs []Segment, plan map[string]SectionPlan) error
CheckSectionDefaultStubs hard-errors when a part re-injects the default of a stub-attributed section (ADR-0072 Decision 4): a stub default is an authoring prompt, not shippable prose, so there is nothing valid to re-inject and the section must stay in must-author state. Runs pre-Assemble on the same segs+plan StubSections consumes; it scans the substituted part body for the render-layer sentinel, since planSections has already replaced the {{=awf:sectionDefault}} token. invariant: section-default-stub-error
func Execute ¶
func Execute(assembled string, data map[string]any, parts map[string]string, name string) (string, error)
Execute runs text/template over the awf-owned skeleton (part bodies stood in by sentinels) under missingkey=zero, then restores each raw part body verbatim — so a convention part is never parsed or executed as a template. name labels parse and execute errors with the target rather than a hardcoded literal. invariant: parts-raw
func ExpandIncludes ¶ added in v0.6.2
ExpandIncludes replaces each `<!-- awf:include NAME -->` directive line in src with the verbatim body of the awf-owned partial `partials/NAME.md`, read from partialFS. Expansion runs before section parsing, so spliced content is thereafter indistinguishable from inline template text. Three conditions are hard errors: a missing partial, a partial that itself contains an awf:include (nested includes are unsupported), and a partial that contains an awf:section/awf:end marker (overlay across a splice boundary is unspecified). invariant: include-splice invariant: include-missing-fails invariant: include-no-nested invariant: include-no-sections
func HasMarkerLine ¶ added in v0.12.0
HasMarkerLine reports whether body contains a line that, after trimming, begins with a marker-shaped `awf:section`/`awf:end` comment opener — the ADR-0083 whole-line detection behind the part-marker advisory. The prefix anchor covers the exact closed marker, an unclosed opener, and a marker with trailing text: none has a legitimate quoter, since prose quoting the form always precedes it on the line. Inline quoting never fires; the awf:stub part marker is out of scope by construction (the pattern names only section/end). Callers exclude fenced code before the scan. invariant: part-marker-advisory
func HasStubMarker ¶ added in v0.10.0
HasStubMarker reports whether a part body contains a line that is exactly the awf:stub marker (modulo surrounding whitespace). Detection never mutates the body — parts render byte-for-byte verbatim, marker included (ADR-0034, ADR-0070). invariant: stub-part-verbatim
func PlaceholderVarRefs ¶ added in v0.13.0
PlaceholderVarRefs returns the config vars a raw convention-part body consumes through {{=awf:key}} placeholders — gateCmd and checkCmd are the only registry keys that read vars (see project.placeholderRegistry). Scanned on the on-disk bytes: substitution has already replaced the tokens in the assembled output, so this is the one consumption channel the assembled-source scan cannot see (ADR-0086 Decision 3). A backslash-escaped token (ADR-0058) renders literally and reads no var, so it is stripped before matching.
func ReferencedDataKeys ¶ added in v0.13.0
ReferencedDataKeys returns the sorted, de-duplicated list of top-level sidecar data keys referenced via {{ .data.K }} patterns in src (ADR-0086). Nested access (.data.a.b) claims its top-level key.
func ReferencedVars ¶
ReferencedVars returns the sorted, de-duplicated list of variable names referenced via {{ .vars.X }} patterns in src.
func ReferencesBareData ¶ added in v0.13.0
ReferencesBareData reports whether src reads .data without a key selector (range/with/index or a whole-map reference). Key-level extraction cannot see through such access, so it conservatively marks every data key consumed (ADR-0086 Decision 4). No shipped template uses the form; this is the future-proofing escape.
func ReferencesBareVars ¶ added in v0.13.0
ReferencesBareVars mirrors ReferencesBareData for the vars namespace (ADR-0086 Decision 3).
func ReferencesInvariantMarkerPlaceholder ¶ added in v0.9.0
ReferencesInvariantMarkerPlaceholder reports whether a raw convention-part body uses a {{=awf:invariantMarker*}} placeholder (ADR-0064, mirroring ReferencesScopePlaceholder).
func ReferencesInvariantMarkers ¶ added in v0.9.0
ReferencesInvariantMarkers reports whether src reads the .invariantMarkers render context, so the artifact folds invariants.sources into its config hash (ADR-0064, mirroring ReferencesScopes).
func ReferencesScopePlaceholder ¶ added in v0.8.0
ReferencesScopePlaceholder reports whether a raw convention-part body uses a {{=awf:commitScope*}} sandbox placeholder (ADR-0057), so the artifact folds the resolved scope list into its config hash and reflags on a scopes edit.
func ReferencesScopes ¶ added in v0.6.0
ReferencesScopes reports whether src reads the resolved commit-scope render context (any {{ … .commitScopes … }} action) — such templates fold the resolved scope list into their config hash (ADR-0051, mirroring ADR-0046's ReferencesSkills).
func ReferencesSkills ¶ added in v0.6.0
ReferencesSkills reports whether src reads the enabled-skills render context (any {{ … .skills… }} action) — such templates fold the effective skills set into their config hash (ADR-0046).
func StubSections ¶ added in v0.10.0
func StubSections(segs []Segment, plan map[string]SectionPlan) (defaults, parts []string)
StubSections reports a parsed template's unauthored stub content under a plan (ADR-0070): defaults = stub-attributed sections rendering their template default; parts = sections whose convention part carries the awf:stub marker. Dropped sections report nothing.
Types ¶
type SectionPlan ¶
type SectionPlan struct {
Drop bool
HasPart bool
PartBody string
// PartStub marks a part body carrying the whole-line awf:stub marker —
// declared-unauthored starter content (ADR-0070). Set by the project layer,
// which reads part bodies; consumed by StubSections.
PartStub bool
// PartMarker marks a part whose raw, fence-excluded body carries a
// whole-line section-marker residue (ADR-0083). Set by the project layer
// over the on-disk bytes — pre placeholder substitution, whose multi-line
// values must never create or mask a match; consumed part-keyed by the
// marker advisory.
PartMarker bool
// PartVarRefs lists the config vars the raw part body consumes via
// {{=awf:key}} placeholders (ADR-0086). Set by the project layer over
// the on-disk bytes; consumed by the unused-var union, which cannot see
// part bodies in the assembled source (they are sentinel-substituted raw).
PartVarRefs []string
EditPath string
}
SectionPlan is the project layer's per-section resolution handed to Assemble. Exactly one of Drop / HasPart / (neither) holds: Drop omits the section, HasPart substitutes PartBody, neither renders the template default. EditPath is the project-relative convention part path named by the awf:edit pointer.
type Segment ¶
type Segment struct {
IsSection bool
Name string
Text string
// Stub marks a section whose template default is a must-replace authoring
// prompt, declared by the `stub` marker attribute (ADR-0070).
Stub bool
}
func ParseSections ¶
ParseSections splits src into ordered literal and section segments. Marker lines are consumed; a section segment's Text is the inner body.