package docforge // The neutral document model — the format-independent representation an // importer produces and an exporter consumes (PRD §3.2). A Markdown // importer parses source into a Document; the .docx exporter renders a // Document into OOXML; a future PDF/HTML exporter renders the same // Document differently. The model carries editable content only — // placeholders ({{key}}) ride through as literal span text and are // substituted later by the format exporter's merge pass, exactly as in // the pre-model pipeline. // // Slice 8 (t-paliad-349) lands this model with two real consumers: the // Markdown importer (pkg/docforge/markdown) and the .docx renderer // (pkg/docforge/docx), which the shipped submission walker now routes // through — so there is one parser, not two. // BlockKind is the logical kind of a block. Its string values are the // stylemap keys a format exporter looks up (paragraph, heading_1, …), so // the docx exporter maps Kind → Word paragraph style directly. type BlockKind string const ( KindParagraph BlockKind = "paragraph" KindHeading1 BlockKind = "heading_1" KindHeading2 BlockKind = "heading_2" KindHeading3 BlockKind = "heading_3" KindListBullet BlockKind = "list_bullet" KindListNumbered BlockKind = "list_numbered" KindBlockquote BlockKind = "blockquote" ) // Document is a sequence of blocks — the whole editable content. type Document struct { Blocks []Block } // Block is one paragraph-level unit. Spans is its inline content; an empty // Spans slice is an intentional empty paragraph (vertical spacing). type Block struct { Kind BlockKind Spans []InlineSpan } // InlineSpan is one run of inline content. A span is either: // - literal text with optional bold/italic (Link == "", Children nil), or // - a hyperlink (Link != "") whose label is the Children spans. // // Modelling a link as a span with Children (rather than a per-span Link // flag) preserves link boundaries: two adjacent links to the same URL stay // two distinct hyperlink spans, so the exporter emits them byte-identically // to the pre-model walker. type InlineSpan struct { Text string Bold bool Italic bool Link string // non-empty → this span is a hyperlink to Link Children []InlineSpan // hyperlink label content (only when Link != "") }