@lexbuild/core 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -91,7 +91,7 @@ import { USLM_NS, XHTML_NS, LEVEL_ELEMENTS, CONTENT_ELEMENTS } from "@lexbuild/c
91
91
 
92
92
  ## Documentation
93
93
 
94
- - [Monorepo README](https://github.com/chris-c-thomas/lexbuild#readme)
94
+ - [LexBuild Monorepo](https://github.com/chris-c-thomas/lexbuild)
95
95
  - [Architecture](https://github.com/chris-c-thomas/lexbuild/blob/main/docs/architecture.md)
96
96
  - [Output Format](https://github.com/chris-c-thomas/lexbuild/blob/main/docs/output-format.md)
97
97
  - [XML Element Reference](https://github.com/chris-c-thomas/lexbuild/blob/main/docs/xml-element-reference.md)
package/dist/index.d.ts CHANGED
@@ -298,10 +298,10 @@ interface FrontmatterData {
298
298
  part_number?: string | undefined;
299
299
  /** Part name */
300
300
  part_name?: string | undefined;
301
- /** Section number (string — can be alphanumeric like "7801") */
302
- section_number: string;
303
- /** Section name */
304
- section_name: string;
301
+ /** Section number (string — can be alphanumeric like "7801"). Omitted for title-level output. */
302
+ section_number?: string | undefined;
303
+ /** Section name. Omitted for title-level output. */
304
+ section_name?: string | undefined;
305
305
  /** Whether this title is positive law */
306
306
  positive_law: boolean;
307
307
  /** Full source credit text */
@@ -312,6 +312,12 @@ interface FrontmatterData {
312
312
  last_updated: string;
313
313
  /** Section status (e.g., "repealed", "transferred") */
314
314
  status?: string | undefined;
315
+ /** Number of chapters (title-level granularity only) */
316
+ chapter_count?: number | undefined;
317
+ /** Number of sections (title-level granularity only) */
318
+ section_count?: number | undefined;
319
+ /** Total estimated tokens (title-level granularity only) */
320
+ total_token_estimate?: number | undefined;
315
321
  }
316
322
 
317
323
  /**
package/dist/index.js CHANGED
@@ -1164,10 +1164,14 @@ function generateFrontmatter(data) {
1164
1164
  identifier: data.identifier,
1165
1165
  title: data.title,
1166
1166
  title_number: data.title_number,
1167
- title_name: data.title_name,
1168
- section_number: data.section_number,
1169
- section_name: data.section_name
1167
+ title_name: data.title_name
1170
1168
  };
1169
+ if (data.section_number !== void 0) {
1170
+ fm["section_number"] = data.section_number;
1171
+ }
1172
+ if (data.section_name !== void 0) {
1173
+ fm["section_name"] = data.section_name;
1174
+ }
1171
1175
  if (data.chapter_number !== void 0) {
1172
1176
  fm["chapter_number"] = data.chapter_number;
1173
1177
  }
@@ -1197,6 +1201,15 @@ function generateFrontmatter(data) {
1197
1201
  if (data.status !== void 0) {
1198
1202
  fm["status"] = data.status;
1199
1203
  }
1204
+ if (data.chapter_count !== void 0) {
1205
+ fm["chapter_count"] = data.chapter_count;
1206
+ }
1207
+ if (data.section_count !== void 0) {
1208
+ fm["section_count"] = data.section_count;
1209
+ }
1210
+ if (data.total_token_estimate !== void 0) {
1211
+ fm["total_token_estimate"] = data.total_token_estimate;
1212
+ }
1200
1213
  const yamlStr = stringify(fm, {
1201
1214
  lineWidth: 0,
1202
1215
  // Don't wrap long lines
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/xml/parser.ts","../src/xml/namespace.ts","../src/ast/types.ts","../src/ast/builder.ts","../src/markdown/frontmatter.ts","../src/markdown/renderer.ts","../src/markdown/links.ts"],"sourcesContent":["/**\n * Streaming XML parser wrapping saxes with typed events and namespace normalization.\n */\n\nimport { SaxesParser } from \"saxes\";\nimport type { SaxesAttributeNS, SaxesOptions } from \"saxes\";\nimport type { Readable } from \"node:stream\";\nimport { USLM_NS, NAMESPACE_PREFIXES } from \"./namespace.js\";\n\n/** saxes options type for namespace-aware parsing */\ntype NSParserOptions = SaxesOptions & { xmlns: true };\n\n/** Normalized attributes: a flat record of name → value */\nexport type Attributes = Record<string, string>;\n\n/** Events emitted by the XML parser */\nexport interface ParserEvents {\n /** An element was opened */\n openElement: (name: string, attrs: Attributes, ns: string) => void;\n /** An element was closed */\n closeElement: (name: string, ns: string) => void;\n /** Text content was encountered */\n text: (content: string) => void;\n /** An error occurred during parsing */\n error: (err: Error) => void;\n /** Parsing is complete */\n end: () => void;\n}\n\n/** Configuration for the XML parser */\nexport interface XMLParserOptions {\n /** Namespace URI to treat as default (elements in this NS emit bare names) */\n defaultNamespace?: string | undefined;\n /** Additional namespace prefix mappings beyond the built-in ones */\n namespacePrefixes?: Readonly<Record<string, string>> | undefined;\n}\n\ntype EventName = keyof ParserEvents;\ntype EventHandler<K extends EventName> = ParserEvents[K];\n\n/**\n * Streaming XML parser that normalizes namespace-prefixed element names.\n *\n * Elements in the default namespace emit bare names (e.g., \"section\").\n * Elements in other recognized namespaces emit prefixed names (e.g., \"xhtml:table\").\n * Elements in unrecognized namespaces emit the full URI-prefixed name.\n */\nexport class XMLParser {\n private readonly saxParser: SaxesParser<NSParserOptions>;\n private readonly defaultNs: string;\n private readonly prefixMap: Readonly<Record<string, string>>;\n private readonly listeners: Map<EventName, Array<(...args: unknown[]) => void>> = new Map();\n\n constructor(options?: XMLParserOptions) {\n this.defaultNs = options?.defaultNamespace ?? USLM_NS;\n this.prefixMap = {\n ...NAMESPACE_PREFIXES,\n ...options?.namespacePrefixes,\n };\n\n this.saxParser = new SaxesParser<NSParserOptions>({ xmlns: true, position: true });\n\n this.saxParser.on(\"opentag\", (node) => {\n const ns = node.uri;\n const localName = node.local;\n const normalizedName = this.normalizeName(localName, ns);\n const attrs = this.normalizeAttributes(node.attributes as Record<string, SaxesAttributeNS>);\n this.emit(\"openElement\", normalizedName, attrs, ns);\n });\n\n this.saxParser.on(\"closetag\", (node) => {\n const ns = node.uri;\n const localName = node.local;\n const normalizedName = this.normalizeName(localName, ns);\n this.emit(\"closeElement\", normalizedName, ns);\n });\n\n this.saxParser.on(\"text\", (text) => {\n this.emit(\"text\", text);\n });\n\n this.saxParser.on(\"error\", (err) => {\n this.emit(\"error\", err);\n });\n\n this.saxParser.on(\"end\", () => {\n this.emit(\"end\");\n });\n }\n\n /**\n * Register an event listener.\n */\n on<K extends EventName>(event: K, handler: EventHandler<K>): this {\n let handlers = this.listeners.get(event);\n if (!handlers) {\n handlers = [];\n this.listeners.set(event, handlers);\n }\n handlers.push(handler as (...args: unknown[]) => void);\n return this;\n }\n\n /**\n * Parse a complete XML string.\n */\n parseString(xml: string): void {\n this.saxParser.write(xml);\n this.saxParser.close();\n }\n\n /**\n * Parse from a readable stream (e.g., fs.createReadStream).\n * Returns a promise that resolves when parsing is complete.\n */\n parseStream(stream: Readable): Promise<void> {\n return new Promise((resolve, reject) => {\n stream.on(\"data\", (chunk: Buffer | string) => {\n try {\n this.saxParser.write(typeof chunk === \"string\" ? chunk : chunk.toString(\"utf-8\"));\n } catch (err) {\n reject(err);\n }\n });\n\n stream.on(\"end\", () => {\n try {\n this.saxParser.close();\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n\n stream.on(\"error\", (err) => {\n reject(err);\n });\n });\n }\n\n /**\n * Normalize an element name based on its namespace.\n * Default namespace elements get bare names; others get prefixed.\n */\n private normalizeName(localName: string, ns: string): string {\n if (ns === this.defaultNs || ns === \"\") {\n return localName;\n }\n const prefix = this.prefixMap[ns];\n if (prefix) {\n return `${prefix}:${localName}`;\n }\n // Unknown namespace: use full URI\n return `{${ns}}${localName}`;\n }\n\n /**\n * Normalize saxes namespace-aware attributes to a flat record.\n * Strips namespace prefixes from attribute names for simplicity,\n * except for xmlns declarations which are dropped entirely.\n */\n private normalizeAttributes(saxAttrs: Record<string, SaxesAttributeNS>): Attributes {\n const attrs: Attributes = {};\n for (const [, attr] of Object.entries(saxAttrs)) {\n // Skip xmlns declarations\n if (attr.prefix === \"xmlns\" || attr.local === \"xmlns\") {\n continue;\n }\n // Use local name for most attributes\n const name = attr.prefix && attr.prefix !== \"\" ? `${attr.prefix}:${attr.local}` : attr.local;\n attrs[name] = attr.value;\n }\n return attrs;\n }\n\n /**\n * Emit an event to all registered listeners.\n */\n private emit(event: EventName, ...args: unknown[]): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n for (const handler of handlers) {\n handler(...args);\n }\n }\n }\n}\n","/**\n * USLM XML namespace constants and element classification utilities.\n */\n\n/** USLM 1.0 default namespace */\nexport const USLM_NS = \"http://xml.house.gov/schemas/uslm/1.0\";\n\n/** XHTML namespace (used for tables) */\nexport const XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n\n/** Dublin Core elements namespace */\nexport const DC_NS = \"http://purl.org/dc/elements/1.1/\";\n\n/** Dublin Core terms namespace */\nexport const DCTERMS_NS = \"http://purl.org/dc/terms/\";\n\n/** XML Schema Instance namespace */\nexport const XSI_NS = \"http://www.w3.org/2001/XMLSchema-instance\";\n\n/**\n * Prefix map for recognized non-default namespaces.\n * Elements in these namespaces will be emitted with the prefix (e.g., \"dc:title\").\n */\nexport const NAMESPACE_PREFIXES: Readonly<Record<string, string>> = {\n [XHTML_NS]: \"xhtml\",\n [DC_NS]: \"dc\",\n [DCTERMS_NS]: \"dcterms\",\n [XSI_NS]: \"xsi\",\n};\n\n/** USLM elements that represent hierarchical levels */\nexport const LEVEL_ELEMENTS = new Set([\n \"title\",\n \"subtitle\",\n \"chapter\",\n \"subchapter\",\n \"article\",\n \"subarticle\",\n \"part\",\n \"subpart\",\n \"division\",\n \"subdivision\",\n \"preliminary\",\n \"section\",\n \"subsection\",\n \"paragraph\",\n \"subparagraph\",\n \"clause\",\n \"subclause\",\n \"item\",\n \"subitem\",\n \"subsubitem\",\n // Appendix-level elements\n \"appendix\",\n \"compiledAct\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n \"courtRules\",\n \"courtRule\",\n]);\n\n/** USLM elements that represent content blocks */\nexport const CONTENT_ELEMENTS = new Set([\n \"content\",\n \"chapeau\",\n \"continuation\",\n \"proviso\",\n]);\n\n/** USLM elements that represent inline formatting */\nexport const INLINE_ELEMENTS = new Set([\n \"b\",\n \"i\",\n \"sub\",\n \"sup\",\n \"ref\",\n \"date\",\n \"term\",\n \"inline\",\n \"shortTitle\",\n \"del\",\n \"ins\",\n]);\n\n/** USLM note-related elements */\nexport const NOTE_ELEMENTS = new Set([\n \"note\",\n \"notes\",\n \"sourceCredit\",\n \"statutoryNote\",\n \"editorialNote\",\n \"changeNote\",\n]);\n\n/** USLM elements that act as levels in appendix contexts */\nexport const APPENDIX_LEVEL_ELEMENTS = new Set([\n \"compiledAct\",\n \"courtRules\",\n \"courtRule\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n]);\n\n/** USLM metadata elements inside <meta> */\nexport const META_ELEMENTS = new Set([\n \"meta\",\n \"docNumber\",\n \"docPublicationName\",\n \"docReleasePoint\",\n \"property\",\n]);\n\n/** Structural container elements (no direct content) */\nexport const CONTAINER_ELEMENTS = new Set([\n \"uscDoc\",\n \"main\",\n \"meta\",\n \"toc\",\n \"layout\",\n \"header\",\n \"row\",\n \"column\",\n \"tocItem\",\n]);\n","/**\n * @lexbuild/core AST node types\n *\n * The intermediate AST is a semantic representation of parsed USLM XML.\n * It is NOT a 1:1 mapping — it has been partially interpreted to simplify rendering.\n */\n\n/** All hierarchical levels in the USLM schema, ordered big → small */\nexport const LEVEL_TYPES = [\n // Big levels (above section)\n \"title\",\n \"appendix\",\n \"subtitle\",\n \"chapter\",\n \"subchapter\",\n \"compiledAct\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n \"courtRules\",\n \"courtRule\",\n \"article\",\n \"subarticle\",\n \"part\",\n \"subpart\",\n \"division\",\n \"subdivision\",\n \"preliminary\",\n // Primary level\n \"section\",\n // Small levels (below section)\n \"subsection\",\n \"paragraph\",\n \"subparagraph\",\n \"clause\",\n \"subclause\",\n \"item\",\n \"subitem\",\n \"subsubitem\",\n] as const;\n\n/** A USLM hierarchical level type */\nexport type LevelType = (typeof LEVEL_TYPES)[number];\n\n/** Big levels: above section in the hierarchy */\nexport const BIG_LEVELS = new Set<LevelType>([\n \"title\",\n \"appendix\",\n \"subtitle\",\n \"chapter\",\n \"subchapter\",\n \"compiledAct\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n \"courtRules\",\n \"courtRule\",\n \"article\",\n \"subarticle\",\n \"part\",\n \"subpart\",\n \"division\",\n \"subdivision\",\n \"preliminary\",\n]);\n\n/** Small levels: below section in the hierarchy */\nexport const SMALL_LEVELS = new Set<LevelType>([\n \"subsection\",\n \"paragraph\",\n \"subparagraph\",\n \"clause\",\n \"subclause\",\n \"item\",\n \"subitem\",\n \"subsubitem\",\n]);\n\n/** Base node all AST nodes extend */\nexport interface BaseNode {\n /** Discriminator for the node type */\n readonly type: string;\n /** USLM identifier if present (e.g., \"/us/usc/t1/s1\") */\n identifier?: string | undefined;\n /** Source XML element name for debugging */\n sourceElement?: string | undefined;\n}\n\n/** A hierarchical level (title, chapter, section, subsection, etc.) */\nexport interface LevelNode extends BaseNode {\n readonly type: \"level\";\n /** Which level in the USLM hierarchy */\n levelType: LevelType;\n /** Display text of the number (e.g., \"§ 1.\", \"(a)\", \"CHAPTER 1—\") */\n num?: string | undefined;\n /** Normalized value of the number (e.g., \"1\", \"a\") */\n numValue?: string | undefined;\n /** Heading text (e.g., \"Words denoting number, gender, and so forth\") */\n heading?: string | undefined;\n /** Legal status of this element (e.g., \"repealed\", \"transferred\") */\n status?: string | undefined;\n /** Child nodes */\n children: ASTNode[];\n}\n\n/** Variant of a content block */\nexport type ContentVariant = \"content\" | \"chapeau\" | \"continuation\" | \"proviso\";\n\n/** A block of text content */\nexport interface ContentNode extends BaseNode {\n readonly type: \"content\";\n /** What kind of content block this is */\n variant: ContentVariant;\n /** Inline children (text, formatting, refs) */\n children: InlineNode[];\n}\n\n/** Discriminator for inline node types */\nexport type InlineType =\n | \"text\"\n | \"bold\"\n | \"italic\"\n | \"ref\"\n | \"date\"\n | \"term\"\n | \"quoted\"\n | \"sup\"\n | \"sub\"\n | \"footnoteRef\";\n\n/** Inline text or formatting */\nexport interface InlineNode extends BaseNode {\n readonly type: \"inline\";\n /** What kind of inline this is */\n inlineType: InlineType;\n /** Text content (for leaf text nodes) */\n text?: string | undefined;\n /** Link target (for ref nodes) */\n href?: string | undefined;\n /** Footnote target ID (for footnoteRef nodes) */\n idref?: string | undefined;\n /** Nested inline children */\n children?: InlineNode[] | undefined;\n}\n\n/** A note (editorial, statutory, amendment, etc.) */\nexport interface NoteNode extends BaseNode {\n readonly type: \"note\";\n /** Semantic category (e.g., \"amendments\", \"codification\") */\n topic?: string | undefined;\n /** Role refinement (e.g., \"crossHeading\") */\n role?: string | undefined;\n /** Note placement type (e.g., \"uscNote\", \"footnote\") */\n noteType?: string | undefined;\n /** Heading text of the note */\n heading?: string | undefined;\n /** Child nodes */\n children: ASTNode[];\n}\n\n/** Source credit annotation */\nexport interface SourceCreditNode extends BaseNode {\n readonly type: \"sourceCredit\";\n /** The full source credit text, including inline formatting */\n children: InlineNode[];\n}\n\n/** Table (either XHTML or USLM layout-based) */\nexport interface TableNode extends BaseNode {\n readonly type: \"table\";\n /** Which table model */\n variant: \"xhtml\" | \"layout\";\n /** Header rows (each row is an array of cell strings) */\n headers: string[][];\n /** Body rows */\n rows: string[][];\n /** Raw HTML for complex tables that can't be simplified to rows/columns */\n rawHtml?: string | undefined;\n}\n\n/** A single TOC entry */\nexport interface TOCItemNode extends BaseNode {\n readonly type: \"tocItem\";\n /** Section/chapter number */\n number?: string | undefined;\n /** Title or heading text */\n title?: string | undefined;\n /** Link target identifier */\n href?: string | undefined;\n}\n\n/** Table of contents */\nexport interface TOCNode extends BaseNode {\n readonly type: \"toc\";\n /** TOC entries */\n items: TOCItemNode[];\n}\n\n/** Container for notes (wraps <notes type=\"uscNote\">) */\nexport interface NotesContainerNode extends BaseNode {\n readonly type: \"notesContainer\";\n /** The notes type attribute (e.g., \"uscNote\") */\n notesType?: string | undefined;\n /** Child note nodes */\n children: (NoteNode | ASTNode)[];\n}\n\n/** Quoted content (blockquote) */\nexport interface QuotedContentNode extends BaseNode {\n readonly type: \"quotedContent\";\n /** Where the quote originates from */\n origin?: string | undefined;\n /** Content of the quotation */\n children: ASTNode[];\n}\n\n/** Union of all AST node types */\nexport type ASTNode =\n | LevelNode\n | ContentNode\n | InlineNode\n | NoteNode\n | SourceCreditNode\n | TableNode\n | TOCNode\n | TOCItemNode\n | NotesContainerNode\n | QuotedContentNode;\n\n// ---------------------------------------------------------------------------\n// Context types used during AST building and rendering\n// ---------------------------------------------------------------------------\n\n/** Info about an ancestor level in the hierarchy */\nexport interface AncestorInfo {\n /** The level type (e.g., \"title\", \"chapter\") */\n levelType: LevelType;\n /** Normalized number value */\n numValue?: string | undefined;\n /** Heading text */\n heading?: string | undefined;\n /** USLM identifier */\n identifier?: string | undefined;\n}\n\n/** Document-level metadata extracted from the <meta> block */\nexport interface DocumentMeta {\n /** dc:title — display title (e.g., \"Title 1\") */\n dcTitle?: string | undefined;\n /** dc:type — document type (e.g., \"USCTitle\") */\n dcType?: string | undefined;\n /** docNumber — numeric designation (e.g., \"1\") */\n docNumber?: string | undefined;\n /** docPublicationName — publication name */\n docPublicationName?: string | undefined;\n /** Release point identifier (e.g., \"119-73\") */\n releasePoint?: string | undefined;\n /** Whether this is positive law */\n positivelaw?: boolean | undefined;\n /** dc:publisher */\n publisher?: string | undefined;\n /** dcterms:created — ISO timestamp */\n created?: string | undefined;\n /** dc:creator — generator tool name */\n creator?: string | undefined;\n /** The root document identifier (e.g., \"/us/usc/t1\") */\n identifier?: string | undefined;\n}\n\n/** Context provided when a completed section/chapter is emitted */\nexport interface EmitContext {\n /** Ancestor chain from document root to the emitted node's parent */\n ancestors: AncestorInfo[];\n /** Document-level metadata from the <meta> block */\n documentMeta: DocumentMeta;\n}\n\n// ---------------------------------------------------------------------------\n// Frontmatter types\n// ---------------------------------------------------------------------------\n\n/** Data used to generate YAML frontmatter for a section file */\nexport interface FrontmatterData {\n /** USLM canonical identifier (e.g., \"/us/usc/t1/s1\") */\n identifier: string;\n /** Human-readable display title (e.g., \"1 USC § 1 - Words denoting...\") */\n title: string;\n /** Title number (integer) */\n title_number: number;\n /** Title name (e.g., \"General Provisions\") */\n title_name: string;\n /** Chapter number (integer, omitted if not applicable) */\n chapter_number?: number | undefined;\n /** Chapter name */\n chapter_name?: string | undefined;\n /** Subchapter identifier (often Roman numerals) */\n subchapter_number?: string | undefined;\n /** Subchapter name */\n subchapter_name?: string | undefined;\n /** Part identifier */\n part_number?: string | undefined;\n /** Part name */\n part_name?: string | undefined;\n /** Section number (string — can be alphanumeric like \"7801\") */\n section_number: string;\n /** Section name */\n section_name: string;\n /** Whether this title is positive law */\n positive_law: boolean;\n /** Full source credit text */\n source_credit?: string | undefined;\n /** Release point identifier (e.g., \"119-73\") */\n currency: string;\n /** ISO date from XML generation timestamp */\n last_updated: string;\n /** Section status (e.g., \"repealed\", \"transferred\") */\n status?: string | undefined;\n}\n","/**\n * AST Builder — converts XML parser events into an AST tree.\n *\n * Implements the section-emit pattern: when a section (or other configured level)\n * close tag is encountered, the completed LevelNode is emitted via callback\n * and its subtree is released from memory.\n */\n\nimport type { Attributes } from \"../xml/parser.js\";\nimport { LEVEL_ELEMENTS, CONTENT_ELEMENTS, INLINE_ELEMENTS } from \"../xml/namespace.js\";\nimport { LEVEL_TYPES } from \"./types.js\";\nimport type {\n LevelType,\n LevelNode,\n ContentNode,\n ContentVariant,\n InlineNode,\n InlineType,\n NoteNode,\n SourceCreditNode,\n TableNode,\n NotesContainerNode,\n QuotedContentNode,\n ASTNode,\n AncestorInfo,\n DocumentMeta,\n EmitContext,\n} from \"./types.js\";\n\n/** Options for configuring the AST builder */\nexport interface ASTBuilderOptions {\n /** Emit completed nodes at this level instead of accumulating */\n emitAt: LevelType;\n /** Callback when a completed node is ready */\n onEmit: (node: LevelNode, context: EmitContext) => void | Promise<void>;\n}\n\n/** Map from inline XML element names to InlineType discriminators */\nconst INLINE_TYPE_MAP: Readonly<Record<string, InlineType>> = {\n b: \"bold\",\n i: \"italic\",\n sub: \"sub\",\n sup: \"sup\",\n ref: \"ref\",\n date: \"date\",\n term: \"term\",\n inline: \"text\",\n shortTitle: \"text\",\n del: \"text\",\n ins: \"text\",\n};\n\n/**\n * Internal representation of a frame on the builder stack.\n * Each open XML element that we care about pushes a frame.\n */\ninterface StackFrame {\n /** What kind of frame this is */\n kind:\n | \"level\"\n | \"content\"\n | \"inline\"\n | \"note\"\n | \"sourceCredit\"\n | \"notesContainer\"\n | \"quotedContent\"\n | \"meta\"\n | \"ignore\";\n /** The AST node being constructed (null for meta/ignore frames) */\n node: ASTNode | null;\n /** The XML element name that opened this frame */\n elementName: string;\n /** Accumulated text for simple text-collecting frames (meta fields, etc.) */\n textBuffer: string;\n}\n\n/** State for collecting an XHTML table */\ninterface TableCollector {\n /** Header rows (from thead) */\n headers: string[][];\n /** Body rows (from tbody or bare tr) */\n rows: string[][];\n /** Current row being built */\n currentRow: string[];\n /** Current cell text accumulator */\n cellText: string;\n /** Whether we're currently inside thead */\n inHead: boolean;\n /** Whether we're currently inside a cell (th or td) */\n inCell: boolean;\n /** Whether this table has colspan or rowspan (complex) */\n isComplex: boolean;\n /** Nesting depth for sub-elements inside cells */\n cellDepth: number;\n}\n\n/**\n * Builds an AST from XML parser events, emitting completed subtrees at the configured level.\n */\nexport class ASTBuilder {\n private readonly options: ASTBuilderOptions;\n private readonly stack: StackFrame[] = [];\n private readonly ancestors: AncestorInfo[] = [];\n private readonly documentMeta: DocumentMeta = {};\n\n /** Whether we are currently inside the <meta> block */\n private inMeta = false;\n /** Nesting depth inside <quotedContent> — levels inside quotes are not emitted */\n private quotedContentDepth = 0;\n /** Active XHTML table collector (null when not inside a table) */\n private tableCollector: TableCollector | null = null;\n /** Active USLM layout collector (null when not inside a layout) */\n private layoutCollector: TableCollector | null = null;\n /** Nesting depth inside <toc> — elements inside toc are handled by layout collector only */\n private tocDepth = 0;\n /** Current meta field being collected (e.g., \"dc:title\", \"docNumber\") */\n private metaField: string | null = null;\n /** Attributes of the current meta property element */\n private metaPropertyAttrs: Attributes | null = null;\n\n constructor(options: ASTBuilderOptions) {\n this.options = options;\n }\n\n /** Returns the document metadata collected so far */\n getDocumentMeta(): DocumentMeta {\n return this.documentMeta;\n }\n\n /**\n * Handle an openElement event from the parser.\n */\n onOpenElement(name: string, attrs: Attributes): void {\n // Handle meta block\n if (name === \"meta\") {\n this.inMeta = true;\n this.stack.push({ kind: \"meta\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n if (this.inMeta) {\n this.handleMetaOpen(name, attrs);\n return;\n }\n\n // Handle uscDoc root — extract identifier\n if (name === \"uscDoc\") {\n if (attrs[\"identifier\"]) {\n this.documentMeta.identifier = attrs[\"identifier\"];\n }\n return;\n }\n\n // Skip structural containers that don't produce AST nodes\n if (name === \"main\") {\n return;\n }\n\n // --- Collector zones: checked BEFORE normal element handlers ---\n\n if (name === \"xhtml:table\") {\n this.tableCollector = {\n headers: [],\n rows: [],\n currentRow: [],\n cellText: \"\",\n inHead: false,\n inCell: false,\n isComplex: false,\n cellDepth: 0,\n };\n return;\n }\n if (this.tableCollector) {\n this.handleTableOpen(name, attrs);\n return;\n }\n\n if (name === \"layout\") {\n this.layoutCollector = {\n headers: [],\n rows: [],\n currentRow: [],\n cellText: \"\",\n inHead: false,\n inCell: false,\n isComplex: false,\n cellDepth: 0,\n };\n return;\n }\n if (this.layoutCollector) {\n this.handleLayoutOpen(name, attrs);\n return;\n }\n\n if (name === \"toc\") {\n this.tocDepth++;\n return;\n }\n if (this.tocDepth > 0) {\n return;\n }\n\n // --- Normal element handlers ---\n\n // Handle level elements (title, chapter, section, subsection, etc.)\n if (LEVEL_ELEMENTS.has(name)) {\n this.openLevel(name as LevelType, attrs);\n return;\n }\n\n // Handle content block elements\n if (CONTENT_ELEMENTS.has(name)) {\n this.openContent(name as ContentVariant, attrs);\n return;\n }\n\n // Handle inline elements\n if (INLINE_ELEMENTS.has(name)) {\n this.openInline(name, attrs);\n return;\n }\n\n // Handle note-related elements\n if (name === \"notes\") {\n this.openNotesContainer(attrs);\n return;\n }\n\n if (\n name === \"note\" ||\n name === \"statutoryNote\" ||\n name === \"editorialNote\" ||\n name === \"changeNote\"\n ) {\n this.openNote(name, attrs);\n return;\n }\n\n if (name === \"sourceCredit\") {\n this.openSourceCredit();\n return;\n }\n\n if (name === \"quotedContent\") {\n this.openQuotedContent(attrs);\n return;\n }\n\n // Handle elements that collect text within a parent\n if (name === \"num\") {\n // Immediately set numValue from the value attribute on the parent level\n const parentFrame = this.findParentFrame(\"level\");\n if (parentFrame && attrs[\"value\"]) {\n (parentFrame.node as LevelNode).numValue = attrs[\"value\"];\n }\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n if (name === \"heading\") {\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n // Handle <p> elements — they're content-like within their parent\n if (name === \"p\") {\n // p elements don't create separate AST nodes; their text flows\n // into the parent content/note node. We push a frame to collect text.\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n // Remaining unhandled elements — push ignore frame so close events balance\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n }\n\n /**\n * Handle a closeElement event from the parser.\n */\n onCloseElement(name: string): void {\n // Handle meta block close\n if (name === \"meta\") {\n this.inMeta = false;\n this.popFrame(\"meta\");\n return;\n }\n\n if (this.inMeta) {\n this.handleMetaClose(name);\n return;\n }\n\n // Skip structural containers\n if (name === \"uscDoc\" || name === \"main\") {\n return;\n }\n\n // Handle XHTML table close\n if (name === \"xhtml:table\" && this.tableCollector) {\n this.finishTable();\n return;\n }\n\n if (this.tableCollector) {\n this.handleTableClose(name);\n return;\n }\n\n // Handle </toc> close\n if (name === \"toc\") {\n this.tocDepth = Math.max(0, this.tocDepth - 1);\n return;\n }\n\n // Handle USLM layout close\n if (name === \"layout\" && this.layoutCollector) {\n this.finishLayout();\n return;\n }\n\n if (this.layoutCollector) {\n this.handleLayoutClose(name);\n return;\n }\n\n // Skip elements inside toc that aren't in a layout\n if (this.tocDepth > 0) {\n return;\n }\n\n // Handle <num> — set on parent level node\n if (name === \"num\" || name === \"heading\") {\n const frame = this.peekFrame();\n if (frame?.elementName === name) {\n this.handleNumOrHeadingClose(name, frame);\n this.stack.pop();\n return;\n }\n }\n\n // Handle <p> close\n if (name === \"p\") {\n const frame = this.peekFrame();\n if (frame?.elementName === \"p\") {\n this.handlePClose(frame);\n this.stack.pop();\n return;\n }\n }\n\n // Handle level close\n if (LEVEL_ELEMENTS.has(name)) {\n this.closeLevel(name as LevelType);\n return;\n }\n\n // Handle content block close\n if (CONTENT_ELEMENTS.has(name)) {\n this.closeContent();\n return;\n }\n\n // Handle inline close\n if (INLINE_ELEMENTS.has(name)) {\n this.closeInline();\n return;\n }\n\n // Handle notes container close\n if (name === \"notes\") {\n this.closeNotesContainer();\n return;\n }\n\n // Handle note close\n if (\n name === \"note\" ||\n name === \"statutoryNote\" ||\n name === \"editorialNote\" ||\n name === \"changeNote\"\n ) {\n this.closeNote();\n return;\n }\n\n // Handle sourceCredit close\n if (name === \"sourceCredit\") {\n this.closeSourceCredit();\n return;\n }\n\n // Handle quotedContent close\n if (name === \"quotedContent\") {\n this.closeQuotedContent();\n return;\n }\n\n // Pop ignore frames\n const frame = this.peekFrame();\n if (frame?.kind === \"ignore\" && frame.elementName === name) {\n this.stack.pop();\n }\n }\n\n /**\n * Handle a text event from the parser.\n */\n onText(text: string): void {\n // Collect text inside XHTML table cells\n if (this.tableCollector?.inCell) {\n this.tableCollector.cellText += text;\n return;\n }\n\n // Skip all text inside tables but outside cells (whitespace between elements)\n if (this.tableCollector) {\n return;\n }\n\n // Collect text inside layout cells\n if (this.layoutCollector?.inCell) {\n this.layoutCollector.cellText += text;\n return;\n }\n\n // Skip text inside layout but outside cells\n if (this.layoutCollector) {\n return;\n }\n\n // Skip text inside toc but outside layout\n if (this.tocDepth > 0) {\n return;\n }\n\n if (this.inMeta) {\n // Accumulate text for meta fields\n const frame = this.peekFrame();\n if (frame) {\n frame.textBuffer += text;\n }\n return;\n }\n\n // Find the nearest frame that can accept text\n const frame = this.peekFrame();\n if (!frame) return;\n\n if (frame.kind === \"ignore\") {\n // Accumulate in text buffer (for num, heading, p)\n frame.textBuffer += text;\n return;\n }\n\n if (frame.kind === \"inline\") {\n // Append text to the inline node\n const inlineNode = frame.node as InlineNode;\n const textChild: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n if (!inlineNode.children) {\n inlineNode.children = [];\n }\n inlineNode.children.push(textChild);\n\n // Also bubble text up to any heading/num ignore frame below this inline\n // (handles <heading><b>Editorial Notes</b></heading> pattern)\n this.bubbleTextToCollector(text);\n return;\n }\n\n if (frame.kind === \"content\" || frame.kind === \"sourceCredit\") {\n // Skip whitespace-only text between <p> elements (XML formatting noise)\n if (!text.trim()) return;\n // Create a text inline node and append to parent\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const parent = frame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as InlineNode[]).push(textNode);\n }\n return;\n }\n\n if (frame.kind === \"note\" || frame.kind === \"quotedContent\") {\n // Text directly inside a note or quotedContent — wrap in a content node\n const trimmed = text.trim();\n if (trimmed) {\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const contentNode: ContentNode = {\n type: \"content\",\n variant: \"content\",\n children: [textNode],\n };\n const parent = frame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as ASTNode[]).push(contentNode);\n }\n }\n return;\n }\n\n if (frame.kind === \"level\") {\n // Text directly inside a level (unusual but possible) — same as note\n const trimmed = text.trim();\n if (trimmed) {\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const contentNode: ContentNode = {\n type: \"content\",\n variant: \"content\",\n children: [textNode],\n };\n (frame.node as LevelNode).children.push(contentNode);\n }\n return;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Meta handling\n // ---------------------------------------------------------------------------\n\n private handleMetaOpen(name: string, attrs: Attributes): void {\n this.metaField = name;\n this.metaPropertyAttrs = attrs;\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n }\n\n private handleMetaClose(name: string): void {\n const frame = this.peekFrame();\n if (frame?.elementName !== name) return;\n\n const text = frame.textBuffer.trim();\n this.stack.pop();\n\n switch (this.metaField) {\n case \"dc:title\":\n this.documentMeta.dcTitle = text;\n break;\n case \"dc:type\":\n this.documentMeta.dcType = text;\n break;\n case \"docNumber\":\n this.documentMeta.docNumber = text;\n break;\n case \"docPublicationName\":\n this.documentMeta.docPublicationName = text;\n break;\n case \"docReleasePoint\":\n this.documentMeta.releasePoint = text;\n break;\n case \"dc:publisher\":\n this.documentMeta.publisher = text;\n break;\n case \"dcterms:created\":\n this.documentMeta.created = text;\n break;\n case \"dc:creator\":\n this.documentMeta.creator = text;\n break;\n case \"property\":\n if (this.metaPropertyAttrs?.[\"role\"] === \"is-positive-law\") {\n this.documentMeta.positivelaw = text.toLowerCase() === \"yes\";\n }\n break;\n }\n\n this.metaField = null;\n this.metaPropertyAttrs = null;\n }\n\n // ---------------------------------------------------------------------------\n // Level handling\n // ---------------------------------------------------------------------------\n\n private openLevel(levelType: LevelType, attrs: Attributes): void {\n const node: LevelNode = {\n type: \"level\",\n levelType,\n identifier: attrs[\"identifier\"],\n status: attrs[\"status\"],\n sourceElement: levelType,\n children: [],\n };\n\n // If this is a big level (above the emit level) and we're NOT inside quotedContent,\n // push an ancestor placeholder. The heading and numValue will be filled in later.\n const emitIndex = LEVEL_TYPES_ARRAY.indexOf(this.options.emitAt);\n const thisIndex = LEVEL_TYPES_ARRAY.indexOf(levelType);\n if (thisIndex >= 0 && thisIndex < emitIndex && this.quotedContentDepth === 0) {\n this.ancestors.push({\n levelType,\n identifier: attrs[\"identifier\"],\n });\n }\n\n this.stack.push({ kind: \"level\", node, elementName: levelType, textBuffer: \"\" });\n }\n\n private closeLevel(levelType: LevelType): void {\n const frame = this.popFrame(\"level\");\n if (!frame) return;\n\n const node = frame.node as LevelNode;\n\n // If we're inside a quotedContent, don't emit — treat as a child node\n if (this.quotedContentDepth > 0) {\n this.addToParent(node);\n return;\n }\n\n // Should we emit this node?\n if (levelType === this.options.emitAt) {\n const context: EmitContext = {\n ancestors: [...this.ancestors],\n documentMeta: { ...this.documentMeta },\n };\n this.options.onEmit(node, context);\n return;\n }\n\n // Is this an ancestor level above the emit level?\n // If so, track it in the ancestors array but don't add to parent\n const emitIndex = LEVEL_TYPES_ARRAY.indexOf(this.options.emitAt);\n const thisIndex = LEVEL_TYPES_ARRAY.indexOf(levelType);\n\n if (thisIndex < emitIndex) {\n // Closing a big level — remove from ancestors\n this.ancestors.pop();\n return;\n }\n\n // Small level below emit level — add to parent as a child\n this.addToParent(node);\n }\n\n // ---------------------------------------------------------------------------\n // Content handling\n // ---------------------------------------------------------------------------\n\n private openContent(variant: ContentVariant, _attrs: Attributes): void {\n const node: ContentNode = {\n type: \"content\",\n variant,\n sourceElement: variant,\n children: [],\n };\n this.stack.push({ kind: \"content\", node, elementName: variant, textBuffer: \"\" });\n }\n\n private closeContent(): void {\n const frame = this.popFrame(\"content\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n // ---------------------------------------------------------------------------\n // Inline handling\n // ---------------------------------------------------------------------------\n\n private openInline(name: string, attrs: Attributes): void {\n const inlineType = INLINE_TYPE_MAP[name] ?? \"text\";\n\n const node: InlineNode = {\n type: \"inline\",\n inlineType,\n sourceElement: name,\n };\n\n // Handle ref-specific attributes\n if (name === \"ref\") {\n if (attrs[\"href\"]) {\n node.href = attrs[\"href\"];\n }\n if (attrs[\"class\"] === \"footnoteRef\") {\n node.inlineType = \"footnoteRef\";\n node.idref = attrs[\"idref\"];\n }\n }\n\n // Handle date attribute\n if (name === \"date\" && attrs[\"date\"]) {\n node.href = attrs[\"date\"]; // Store ISO date in href for convenience\n }\n\n this.stack.push({ kind: \"inline\", node, elementName: name, textBuffer: \"\" });\n }\n\n private closeInline(): void {\n const frame = this.popFrame(\"inline\");\n if (!frame) return;\n\n const node = frame.node as InlineNode;\n\n // If this inline has no children but has accumulated text in parent, that's fine\n // The text was added as children by onText\n\n // If there's only one text child, flatten it\n const firstChild = node.children?.[0];\n if (node.children?.length === 1 && firstChild?.inlineType === \"text\" && !firstChild.children) {\n node.text = firstChild.text;\n node.children = undefined;\n }\n\n this.addInlineToParent(node);\n }\n\n // ---------------------------------------------------------------------------\n // Note handling\n // ---------------------------------------------------------------------------\n\n private openNotesContainer(attrs: Attributes): void {\n const node: NotesContainerNode = {\n type: \"notesContainer\",\n notesType: attrs[\"type\"],\n children: [],\n };\n this.stack.push({ kind: \"notesContainer\", node, elementName: \"notes\", textBuffer: \"\" });\n }\n\n private closeNotesContainer(): void {\n const frame = this.popFrame(\"notesContainer\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n private openNote(name: string, attrs: Attributes): void {\n const node: NoteNode = {\n type: \"note\",\n topic: attrs[\"topic\"],\n role: attrs[\"role\"],\n sourceElement: name,\n children: [],\n };\n this.stack.push({ kind: \"note\", node, elementName: name, textBuffer: \"\" });\n }\n\n private closeNote(): void {\n const frame = this.popFrame(\"note\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n // ---------------------------------------------------------------------------\n // SourceCredit handling\n // ---------------------------------------------------------------------------\n\n private openSourceCredit(): void {\n const node: SourceCreditNode = {\n type: \"sourceCredit\",\n children: [],\n };\n this.stack.push({ kind: \"sourceCredit\", node, elementName: \"sourceCredit\", textBuffer: \"\" });\n }\n\n private closeSourceCredit(): void {\n const frame = this.popFrame(\"sourceCredit\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n // ---------------------------------------------------------------------------\n // QuotedContent handling\n // ---------------------------------------------------------------------------\n\n private openQuotedContent(attrs: Attributes): void {\n this.quotedContentDepth++;\n const node: QuotedContentNode = {\n type: \"quotedContent\",\n origin: attrs[\"origin\"],\n children: [],\n };\n this.stack.push({ kind: \"quotedContent\", node, elementName: \"quotedContent\", textBuffer: \"\" });\n }\n\n private closeQuotedContent(): void {\n this.quotedContentDepth--;\n const frame = this.popFrame(\"quotedContent\");\n if (!frame) return;\n\n // Add as inline \"quoted\" node if parent is content/inline,\n // or as block node if parent is note/level\n const parentFrame = this.peekFrame();\n if (\n parentFrame &&\n (parentFrame.kind === \"content\" ||\n parentFrame.kind === \"inline\" ||\n parentFrame.kind === \"sourceCredit\")\n ) {\n // Flatten to inline quoted text\n const qNode: InlineNode = {\n type: \"inline\",\n inlineType: \"quoted\",\n text: this.extractText(frame.node as QuotedContentNode),\n };\n this.addInlineToParent(qNode);\n } else {\n if (frame.node) this.addToParent(frame.node);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Num/Heading/P helpers\n // ---------------------------------------------------------------------------\n\n private handleNumOrHeadingClose(name: string, frame: StackFrame): void {\n const text = frame.textBuffer.trim();\n\n // First check if parent is a note (heading inside note)\n const noteFrame = this.findParentFrame(\"note\");\n const levelFrame = this.findParentFrame(\"level\");\n\n // Heading inside a note takes priority\n if (\n name === \"heading\" &&\n noteFrame &&\n (!levelFrame || this.stack.indexOf(noteFrame) > this.stack.indexOf(levelFrame))\n ) {\n (noteFrame.node as NoteNode).heading = text;\n return;\n }\n\n // Otherwise, apply to parent level\n if (!levelFrame) return;\n const levelNode = levelFrame.node as LevelNode;\n\n if (name === \"num\") {\n levelNode.num = text;\n // numValue was already set from the value attribute in onOpenElement\n } else if (name === \"heading\") {\n levelNode.heading = text;\n }\n\n // Update ancestor entry if this is a big level\n const ancestor = this.ancestors.find(\n (a) => a.levelType === levelNode.levelType && a.identifier === levelNode.identifier,\n );\n if (ancestor) {\n if (name === \"num\") {\n ancestor.numValue = levelNode.numValue;\n } else if (name === \"heading\") {\n ancestor.heading = text;\n }\n }\n }\n\n private handlePClose(frame: StackFrame): void {\n const text = frame.textBuffer;\n if (!text) return;\n\n // Find the nearest parent that accepts content\n const parentFrame = this.peekFrameAbove(frame);\n if (!parentFrame) return;\n\n if (parentFrame.kind === \"content\" || parentFrame.kind === \"sourceCredit\") {\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const parent = parentFrame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n const children = parent.children as InlineNode[];\n // Add paragraph break before this <p>'s text if there are prior children\n if (children.length > 0) {\n children.push({ type: \"inline\", inlineType: \"text\", text: \"\\n\\n\" });\n }\n children.push(textNode);\n }\n } else if (\n parentFrame.kind === \"note\" ||\n parentFrame.kind === \"level\" ||\n parentFrame.kind === \"quotedContent\"\n ) {\n // Wrap in a ContentNode\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const contentNode: ContentNode = {\n type: \"content\",\n variant: \"content\",\n children: [textNode],\n };\n const parent = parentFrame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as ASTNode[]).push(contentNode);\n }\n }\n }\n\n /**\n * Bubble text content up to the nearest heading/num ignore frame on the stack.\n * This handles patterns like <heading><b>Editorial Notes</b></heading>\n * where the text is inside an inline child but needs to be collected by the heading frame.\n */\n // ---------------------------------------------------------------------------\n // XHTML table handling\n // ---------------------------------------------------------------------------\n\n private handleTableOpen(name: string, attrs: Attributes): void {\n const tc = this.tableCollector;\n if (!tc) return;\n\n switch (name) {\n case \"xhtml:thead\":\n tc.inHead = true;\n break;\n case \"xhtml:tbody\":\n tc.inHead = false;\n break;\n case \"xhtml:tr\":\n tc.currentRow = [];\n break;\n case \"xhtml:th\":\n case \"xhtml:td\":\n tc.inCell = true;\n tc.cellText = \"\";\n tc.cellDepth = 0;\n // Detect complex tables\n if (attrs[\"colspan\"] && attrs[\"colspan\"] !== \"1\") {\n tc.isComplex = true;\n }\n if (attrs[\"rowspan\"] && attrs[\"rowspan\"] !== \"1\") {\n tc.isComplex = true;\n }\n break;\n // Sub-elements inside cells (p, span, i, a, etc.) — track depth\n default:\n if (tc.inCell) {\n tc.cellDepth++;\n }\n break;\n }\n }\n\n private handleTableClose(name: string): void {\n const tc = this.tableCollector;\n if (!tc) return;\n\n switch (name) {\n case \"xhtml:thead\":\n tc.inHead = false;\n break;\n case \"xhtml:tbody\":\n break;\n case \"xhtml:tr\":\n if (tc.inHead) {\n tc.headers.push(tc.currentRow);\n } else {\n tc.rows.push(tc.currentRow);\n }\n tc.currentRow = [];\n break;\n case \"xhtml:th\":\n case \"xhtml:td\":\n tc.currentRow.push(tc.cellText.trim());\n tc.inCell = false;\n tc.cellText = \"\";\n break;\n default:\n if (tc.inCell) {\n tc.cellDepth = Math.max(0, tc.cellDepth - 1);\n }\n break;\n }\n }\n\n private finishTable(): void {\n const tc = this.tableCollector;\n if (!tc) return;\n\n this.tableCollector = null;\n\n const node: TableNode = {\n type: \"table\",\n variant: \"xhtml\",\n headers: tc.headers,\n rows: tc.rows,\n };\n\n this.addToParent(node);\n }\n\n // ---------------------------------------------------------------------------\n // USLM layout handling\n // ---------------------------------------------------------------------------\n\n private handleLayoutOpen(name: string, _attrs: Attributes): void {\n const lc = this.layoutCollector;\n if (!lc) return;\n\n switch (name) {\n case \"header\":\n lc.inHead = true;\n lc.currentRow = [];\n break;\n case \"tocItem\":\n case \"row\":\n lc.currentRow = [];\n break;\n case \"column\":\n lc.inCell = true;\n lc.cellText = \"\";\n break;\n default:\n // Sub-elements inside column (ref, etc.) — just collect text\n break;\n }\n }\n\n private handleLayoutClose(name: string): void {\n const lc = this.layoutCollector;\n if (!lc) return;\n\n switch (name) {\n case \"header\":\n lc.headers.push(lc.currentRow);\n lc.currentRow = [];\n lc.inHead = false;\n break;\n case \"tocItem\":\n case \"row\":\n lc.rows.push(lc.currentRow);\n lc.currentRow = [];\n break;\n case \"column\":\n lc.currentRow.push(lc.cellText.trim());\n lc.inCell = false;\n lc.cellText = \"\";\n break;\n default:\n break;\n }\n }\n\n private finishLayout(): void {\n const lc = this.layoutCollector;\n if (!lc) return;\n\n this.layoutCollector = null;\n\n // Only emit a table if there are actual data rows\n if (lc.rows.length === 0 && lc.headers.length === 0) return;\n\n const node: TableNode = {\n type: \"table\",\n variant: \"layout\",\n headers: lc.headers,\n rows: lc.rows,\n };\n\n this.addToParent(node);\n }\n\n private bubbleTextToCollector(text: string): void {\n for (let i = this.stack.length - 2; i >= 0; i--) {\n const f = this.stack[i];\n if (f?.kind === \"ignore\" && (f.elementName === \"heading\" || f.elementName === \"num\")) {\n f.textBuffer += text;\n return;\n }\n // Stop bubbling if we hit a non-inline, non-ignore frame\n if (f && f.kind !== \"inline\" && f.kind !== \"ignore\") {\n return;\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Stack utilities\n // ---------------------------------------------------------------------------\n\n private peekFrame(): StackFrame | undefined {\n return this.stack[this.stack.length - 1];\n }\n\n private peekFrameAbove(belowFrame: StackFrame): StackFrame | undefined {\n const idx = this.stack.lastIndexOf(belowFrame);\n if (idx > 0) {\n return this.stack[idx - 1];\n }\n return undefined;\n }\n\n private popFrame(expectedKind: string): StackFrame | undefined {\n const frame = this.stack[this.stack.length - 1];\n if (frame?.kind === expectedKind) {\n this.stack.pop();\n return frame;\n }\n // Try to find and remove the frame (in case of nesting mismatches)\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const f = this.stack[i];\n if (f?.kind === expectedKind) {\n return this.stack.splice(i, 1)[0];\n }\n }\n return undefined;\n }\n\n private findParentFrame(kind: string): StackFrame | undefined {\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const f = this.stack[i];\n if (f?.kind === kind) {\n return f;\n }\n }\n return undefined;\n }\n\n /**\n * Add a block-level AST node to the nearest parent that accepts children.\n */\n private addToParent(node: ASTNode): void {\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const frame = this.stack[i];\n if (!frame) continue;\n if (frame.kind === \"level\") {\n (frame.node as LevelNode).children.push(node);\n return;\n }\n if (frame.kind === \"note\") {\n (frame.node as NoteNode).children.push(node);\n return;\n }\n if (frame.kind === \"notesContainer\") {\n (frame.node as NotesContainerNode).children.push(node);\n return;\n }\n if (frame.kind === \"quotedContent\") {\n (frame.node as QuotedContentNode).children.push(node);\n return;\n }\n }\n }\n\n /**\n * Add an inline AST node to the nearest parent that accepts inline children.\n */\n private addInlineToParent(node: InlineNode): void {\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const frame = this.stack[i];\n if (!frame) continue;\n if (frame.kind === \"inline\") {\n const parent = frame.node as InlineNode;\n if (!parent.children) {\n parent.children = [];\n }\n parent.children.push(node);\n return;\n }\n if (frame.kind === \"content\" || frame.kind === \"sourceCredit\") {\n const parent = frame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as InlineNode[]).push(node);\n }\n return;\n }\n }\n }\n\n /**\n * Extract plain text from a node tree (for flattening quotedContent).\n */\n private extractText(node: QuotedContentNode): string {\n let result = \"\";\n for (const child of node.children) {\n if (child.type === \"inline\") {\n result += this.extractInlineText(child);\n } else if (child.type === \"content\") {\n for (const inline of child.children) {\n result += this.extractInlineText(inline);\n }\n }\n }\n return result;\n }\n\n private extractInlineText(node: InlineNode): string {\n if (node.text) return node.text;\n if (node.children) {\n return node.children.map((c) => this.extractInlineText(c)).join(\"\");\n }\n return \"\";\n }\n}\n\n// Re-use LEVEL_TYPES for index lookups (cast to string[] for indexOf)\nconst LEVEL_TYPES_ARRAY: readonly string[] = LEVEL_TYPES;\n","/**\n * YAML frontmatter generator for section Markdown files.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { stringify } from \"yaml\";\nimport type { FrontmatterData } from \"../ast/types.js\";\n\n/** Resolve package.json version at module load time */\nfunction readPackageVersion(): string {\n try {\n const dir = dirname(fileURLToPath(import.meta.url));\n // Works from both src/markdown/ (dev) and dist/ (built)\n const pkgPath = resolve(dir, \"..\", \"..\", \"package.json\");\n const raw = readFileSync(pkgPath, \"utf-8\");\n return (JSON.parse(raw) as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n}\n\n/** Output format version */\nexport const FORMAT_VERSION = \"1.0.0\";\n\n/** Generator identifier (reads version from package.json) */\nexport const GENERATOR = `lexbuild@${readPackageVersion()}`;\n\n/**\n * Generate a YAML frontmatter string from section metadata.\n *\n * Returns a complete frontmatter block including the `---` delimiters.\n */\nexport function generateFrontmatter(data: FrontmatterData): string {\n // Build the frontmatter object with fields in the specified order.\n // We construct it manually to control field ordering.\n const fm: Record<string, unknown> = {\n identifier: data.identifier,\n title: data.title,\n title_number: data.title_number,\n title_name: data.title_name,\n section_number: data.section_number,\n section_name: data.section_name,\n };\n\n // Context fields (only include if present)\n if (data.chapter_number !== undefined) {\n fm[\"chapter_number\"] = data.chapter_number;\n }\n if (data.chapter_name !== undefined) {\n fm[\"chapter_name\"] = data.chapter_name;\n }\n if (data.subchapter_number !== undefined) {\n fm[\"subchapter_number\"] = data.subchapter_number;\n }\n if (data.subchapter_name !== undefined) {\n fm[\"subchapter_name\"] = data.subchapter_name;\n }\n if (data.part_number !== undefined) {\n fm[\"part_number\"] = data.part_number;\n }\n if (data.part_name !== undefined) {\n fm[\"part_name\"] = data.part_name;\n }\n\n // Metadata\n fm[\"positive_law\"] = data.positive_law;\n fm[\"currency\"] = data.currency;\n fm[\"last_updated\"] = data.last_updated;\n fm[\"format_version\"] = FORMAT_VERSION;\n fm[\"generator\"] = GENERATOR;\n\n // Optional fields\n if (data.source_credit !== undefined) {\n fm[\"source_credit\"] = data.source_credit;\n }\n if (data.status !== undefined) {\n fm[\"status\"] = data.status;\n }\n\n const yamlStr = stringify(fm, {\n lineWidth: 0, // Don't wrap long lines\n defaultStringType: \"QUOTE_DOUBLE\",\n defaultKeyType: \"PLAIN\",\n });\n\n return `---\\n${yamlStr}---`;\n}\n","/**\n * Markdown renderer — converts AST nodes to Markdown strings.\n *\n * Stateless and pure: no side effects, no file I/O.\n */\n\nimport type {\n ASTNode,\n LevelNode,\n ContentNode,\n InlineNode,\n NoteNode,\n SourceCreditNode,\n TableNode,\n NotesContainerNode,\n QuotedContentNode,\n FrontmatterData,\n} from \"../ast/types.js\";\nimport { SMALL_LEVELS } from \"../ast/types.js\";\nimport { generateFrontmatter } from \"./frontmatter.js\";\n\n/** Notes filtering configuration */\nexport interface NotesFilter {\n /** Include editorial notes (codification, dispositionOfSections, etc.) */\n editorial: boolean;\n /** Include statutory notes (changeOfName, regulations, miscellaneous, repeals, etc.) */\n statutory: boolean;\n /** Include amendment history (amendments, effectiveDateOfAmendment) */\n amendments: boolean;\n}\n\n/** Options for controlling Markdown rendering */\nexport interface RenderOptions {\n /** Heading level offset (0 = section is H1, 1 = section is H2) */\n headingOffset: number;\n /** How to render cross-references */\n linkStyle: \"relative\" | \"canonical\" | \"plaintext\";\n /** Function to resolve a USLM identifier to a relative file path (for linkStyle \"relative\") */\n resolveLink?: ((identifier: string) => string | null) | undefined;\n /** Notes filtering. Undefined = include all notes. */\n notesFilter?: NotesFilter | undefined;\n}\n\n/** Default render options */\nexport const DEFAULT_RENDER_OPTIONS: RenderOptions = {\n headingOffset: 0,\n linkStyle: \"plaintext\",\n};\n\n/**\n * Render a complete section document: frontmatter + Markdown content.\n */\nexport function renderDocument(\n sectionNode: LevelNode,\n frontmatter: FrontmatterData,\n options: RenderOptions = DEFAULT_RENDER_OPTIONS,\n): string {\n const fm = generateFrontmatter(frontmatter);\n const content = renderSection(sectionNode, options);\n return `${fm}\\n\\n${content}\\n`;\n}\n\n/**\n * Render a section-level node to Markdown.\n */\nexport function renderSection(\n node: LevelNode,\n options: RenderOptions = DEFAULT_RENDER_OPTIONS,\n): string {\n const parts: string[] = [];\n\n // Section heading: # § {number}. {heading}\n const headingLevel = 1 + options.headingOffset;\n const prefix = \"#\".repeat(headingLevel);\n const numDisplay = node.num ?? \"\";\n const heading = node.heading ? ` ${node.heading}` : \"\";\n parts.push(`${prefix} ${numDisplay}${heading}`);\n\n // Render children\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n/**\n * Render any AST node to Markdown.\n */\nexport function renderNode(node: ASTNode, options: RenderOptions = DEFAULT_RENDER_OPTIONS): string {\n switch (node.type) {\n case \"level\":\n return renderLevel(node, options);\n case \"content\":\n return renderContent(node);\n case \"inline\":\n return renderInline(node, options);\n case \"sourceCredit\":\n return renderSourceCredit(node, options);\n case \"note\":\n return renderNote(node, options);\n case \"notesContainer\":\n return renderNotesContainer(node, options);\n case \"quotedContent\":\n return renderQuotedContent(node, options);\n case \"table\":\n return renderTable(node);\n case \"toc\":\n case \"tocItem\":\n return \"\";\n default:\n return \"\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Level rendering (subsection, paragraph, etc.)\n// ---------------------------------------------------------------------------\n\n/**\n * Render a sub-section level (subsection, paragraph, clause, etc.)\n * These use bold inline numbering, NOT Markdown headings.\n */\nfunction renderLevel(node: LevelNode, options: RenderOptions): string {\n // Small levels use bold inline numbering\n if (SMALL_LEVELS.has(node.levelType)) {\n return renderSmallLevel(node, options);\n }\n\n // Big levels within a section (unusual, but handle gracefully)\n const parts: string[] = [];\n if (node.num ?? node.heading) {\n const numDisplay = node.num ?? \"\";\n const heading = node.heading ? ` ${node.heading}` : \"\";\n parts.push(`**${numDisplay}${heading}**`);\n }\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n return parts.join(\"\\n\\n\");\n}\n\n/**\n * Render a small level (subsection through subsubitem) with bold inline numbering.\n *\n * Format: **(a)** **Heading.** — Content text...\n * Or just: **(a)** Content text...\n */\nfunction renderSmallLevel(node: LevelNode, options: RenderOptions): string {\n const parts: string[] = [];\n\n // Build the prefix: **(a)** or **(1)** etc.\n const numDisplay = node.num ?? (node.numValue ? `(${node.numValue})` : \"\");\n let prefix = numDisplay ? `**${numDisplay}**` : \"\";\n\n // If there's a heading, add it after the num\n if (node.heading) {\n prefix += ` **${node.heading}**`;\n }\n\n // Collect content and child levels\n const contentParts: string[] = [];\n const childParts: string[] = [];\n\n for (const child of node.children) {\n if (child.type === \"content\") {\n contentParts.push(renderContent(child));\n } else if (child.type === \"level\") {\n childParts.push(renderNode(child, options));\n } else {\n const rendered = renderNode(child, options);\n if (rendered) {\n childParts.push(rendered);\n }\n }\n }\n\n // Combine prefix with first content block on the same line\n if (contentParts.length > 0) {\n const firstContent = contentParts[0] ?? \"\";\n if (prefix) {\n parts.push(`${prefix} ${firstContent}`);\n } else {\n parts.push(firstContent);\n }\n // Additional content blocks as separate paragraphs\n for (let i = 1; i < contentParts.length; i++) {\n parts.push(contentParts[i] ?? \"\");\n }\n } else if (prefix) {\n parts.push(prefix);\n }\n\n // Child levels as separate paragraphs\n for (const child of childParts) {\n parts.push(child);\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Content rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a content block (content, chapeau, continuation, proviso).\n * Normalizes whitespace: collapses runs of whitespace between paragraphs\n * into clean double-newline paragraph breaks, and trims edges.\n */\nfunction renderContent(node: ContentNode): string {\n const raw = renderInlineChildren(node.children);\n return normalizeWhitespace(raw);\n}\n\n/**\n * Render a list of inline nodes to a string.\n */\nfunction renderInlineChildren(children: InlineNode[], options?: RenderOptions): string {\n return children.map((child) => renderInline(child, options)).join(\"\");\n}\n\n/**\n * Normalize whitespace in rendered text:\n * - Trim leading/trailing whitespace\n * - Collapse 2+ consecutive newlines (with optional spaces) into double-newline\n */\nfunction normalizeWhitespace(text: string): string {\n return text.trim().replace(/\\n\\s*\\n/g, \"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Inline rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render an inline node to a Markdown string.\n */\nfunction renderInline(node: InlineNode, options?: RenderOptions): string {\n switch (node.inlineType) {\n case \"text\":\n return node.text ?? renderInlineChildren(node.children ?? [], options);\n\n case \"bold\":\n return `**${getInlineText(node, options)}**`;\n\n case \"italic\":\n return `*${getInlineText(node, options)}*`;\n\n case \"ref\":\n return renderRef(node, options);\n\n case \"date\":\n return getInlineText(node, options);\n\n case \"term\":\n return `**${getInlineText(node, options)}**`;\n\n case \"quoted\":\n return `\"${node.text ?? getInlineText(node, options)}\"`;\n\n case \"sup\":\n return `<sup>${getInlineText(node, options)}</sup>`;\n\n case \"sub\":\n return `<sub>${getInlineText(node, options)}</sub>`;\n\n case \"footnoteRef\":\n return `[^${getInlineText(node, options)}]`;\n\n default:\n return getInlineText(node, options);\n }\n}\n\n/**\n * Get the text content of an inline node (recursing into children if needed).\n */\nfunction getInlineText(node: InlineNode, options?: RenderOptions): string {\n if (node.text) return node.text;\n if (node.children) return renderInlineChildren(node.children, options);\n return \"\";\n}\n\n/**\n * Render a cross-reference link.\n */\nfunction renderRef(node: InlineNode, options?: RenderOptions): string {\n const text = getInlineText(node, options);\n const href = node.href;\n\n if (!href) {\n return text;\n }\n\n const style = options?.linkStyle ?? \"plaintext\";\n\n if (style === \"plaintext\") {\n return text;\n }\n\n if (style === \"relative\" && options?.resolveLink) {\n const resolved = options.resolveLink(href);\n if (resolved) {\n return `[${text}](${resolved})`;\n }\n }\n\n // For USC references, generate OLRC fallback URL\n if (href.startsWith(\"/us/usc/\")) {\n const olrcUrl = buildOlrcUrl(href);\n return `[${text}](${olrcUrl})`;\n }\n\n // Non-USC references (stat, pl, act) — just render as text\n return text;\n}\n\n/**\n * Build an OLRC website URL from a USLM identifier.\n */\nfunction buildOlrcUrl(identifier: string): string {\n // /us/usc/t{N}/s{N} → granuleid:USC-prelim-title{N}-section{N}\n const match = /^\\/us\\/usc\\/t(\\d+)(?:\\/s(.+?))?(?:\\/|$)/.exec(identifier);\n if (match) {\n const titleNum = match[1];\n const sectionNum = match[2];\n if (sectionNum) {\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${titleNum}-section${sectionNum}`;\n }\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${titleNum}`;\n }\n return `https://uscode.house.gov/view.xhtml?req=${encodeURIComponent(identifier)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Table rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a table node to Markdown.\n * Simple tables (no colspan/rowspan) → Markdown pipe table.\n * Complex tables → skipped with a placeholder comment.\n */\nfunction renderTable(node: TableNode): string {\n // Determine column count from the widest row\n const allRows = [...node.headers, ...node.rows];\n if (allRows.length === 0) return \"\";\n\n let colCount = 0;\n for (const row of allRows) {\n if (row.length > colCount) colCount = row.length;\n }\n\n if (colCount === 0) return \"\";\n\n // Build the Markdown table\n const lines: string[] = [];\n\n // Use the last header row as the actual column headers (skip title rows with colspan)\n // If no usable header rows, use the first body row as implicit header\n let headerRow: string[] | undefined;\n for (let i = node.headers.length - 1; i >= 0; i--) {\n const row = node.headers[i];\n if (row && row.length === colCount) {\n headerRow = row;\n break;\n }\n }\n\n if (!headerRow) {\n // No header row matching column count — use empty headers\n headerRow = Array.from({ length: colCount }, () => \"\");\n }\n\n // Header line\n lines.push(`| ${headerRow.map((cell) => cell.replace(/\\|/g, \"\\\\|\")).join(\" | \")} |`);\n\n // Separator line\n lines.push(`| ${Array.from({ length: colCount }, () => \"---\").join(\" | \")} |`);\n\n // Body rows\n for (const row of node.rows) {\n // Pad row to column count if needed\n const paddedRow = Array.from({ length: colCount }, (_, i) => row[i] ?? \"\");\n lines.push(`| ${paddedRow.map((cell) => cell.replace(/\\|/g, \"\\\\|\")).join(\" | \")} |`);\n }\n\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Source credit rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a source credit node.\n * Format: horizontal rule, then bold label with text.\n */\nfunction renderSourceCredit(node: SourceCreditNode, options: RenderOptions): string {\n const text = renderInlineChildren(node.children, options);\n return `---\\n\\n**Source Credit**: ${text}`;\n}\n\n// ---------------------------------------------------------------------------\n// Notes rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a notes container (<notes type=\"uscNote\">).\n */\nfunction renderNotesContainer(node: NotesContainerNode, options: RenderOptions): string {\n const filter = options.notesFilter;\n\n // No filter = include everything (default behavior)\n if (!filter) {\n const parts: string[] = [];\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n return parts.join(\"\\n\\n\");\n }\n\n // Filter notes by category\n const parts: string[] = [];\n let currentCategory: \"editorial\" | \"statutory\" | \"unknown\" = \"unknown\";\n\n for (const child of node.children) {\n if (child.type !== \"note\") {\n const rendered = renderNode(child, options);\n if (rendered) parts.push(rendered);\n continue;\n }\n\n // Cross-heading notes set the category\n if (child.role === \"crossHeading\") {\n if (child.topic === \"editorialNotes\") {\n currentCategory = \"editorial\";\n } else if (child.topic === \"statutoryNotes\") {\n currentCategory = \"statutory\";\n }\n // Only render the heading if we'll include notes in this category\n if (shouldIncludeCategory(currentCategory, filter)) {\n const rendered = renderNode(child, options);\n if (rendered) parts.push(rendered);\n }\n continue;\n }\n\n // Regular notes — check if their topic/category passes the filter\n if (shouldIncludeNote(child, currentCategory, filter)) {\n const rendered = renderNode(child, options);\n if (rendered) parts.push(rendered);\n }\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n/** Amendment-related topics */\nconst AMENDMENT_TOPICS = new Set([\n \"amendments\",\n \"effectiveDateOfAmendment\",\n \"shortTitleOfAmendment\",\n]);\n\n/** Editorial-specific topics */\nconst EDITORIAL_TOPICS = new Set([\"codification\", \"dispositionOfSections\"]);\n\n/** Statutory-specific topics */\nconst STATUTORY_TOPICS = new Set([\n \"changeOfName\",\n \"regulations\",\n \"miscellaneous\",\n \"repeals\",\n \"separability\",\n \"crossReferences\",\n]);\n\n/**\n * Check if a category of notes should be included based on the filter.\n */\nfunction shouldIncludeCategory(\n category: \"editorial\" | \"statutory\" | \"unknown\",\n filter: NotesFilter,\n): boolean {\n if (category === \"editorial\") return filter.editorial || filter.amendments;\n if (category === \"statutory\") return filter.statutory || filter.amendments;\n // Unknown category — include if any filter is enabled\n return filter.editorial || filter.statutory || filter.amendments;\n}\n\n/**\n * Check if an individual note should be included based on its topic and category.\n */\nfunction shouldIncludeNote(\n node: NoteNode,\n currentCategory: \"editorial\" | \"statutory\" | \"unknown\",\n filter: NotesFilter,\n): boolean {\n const topic = node.topic ?? \"\";\n\n // Amendment topics included by amendments filter\n if (AMENDMENT_TOPICS.has(topic)) return filter.amendments;\n\n // Topic-specific classification takes precedence over category\n if (EDITORIAL_TOPICS.has(topic)) return filter.editorial;\n if (STATUTORY_TOPICS.has(topic)) return filter.statutory;\n\n // Fall back to category from cross-heading\n if (currentCategory === \"editorial\") return filter.editorial;\n if (currentCategory === \"statutory\") return filter.statutory;\n\n // Unknown — include if any filter is active\n return filter.editorial || filter.statutory || filter.amendments;\n}\n\n/**\n * Render a note node.\n */\nfunction renderNote(node: NoteNode, options: RenderOptions): string {\n const parts: string[] = [];\n\n // Cross-heading notes become H2 headings\n if (node.role === \"crossHeading\" && node.heading) {\n parts.push(`## ${node.heading}`);\n return parts.join(\"\\n\\n\");\n }\n\n // Regular notes with a heading become H3\n if (node.heading) {\n parts.push(`### ${node.heading}`);\n }\n\n // Render note children\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Quoted content rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render quoted content as a Markdown blockquote.\n */\nfunction renderQuotedContent(node: QuotedContentNode, options: RenderOptions): string {\n const parts: string[] = [];\n\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n\n const inner = parts.join(\"\\n\\n\");\n // Prefix each line with > for blockquote\n return inner\n .split(\"\\n\")\n .map((line) => `> ${line}`)\n .join(\"\\n\");\n}\n","/**\n * Cross-reference link resolver.\n *\n * Resolves USLM identifier URIs to relative Markdown file paths within\n * the output tree, or falls back to OLRC website URLs.\n */\n\nimport { relative, dirname } from \"node:path\";\n\n/** Parsed components of a USLM identifier */\nexport interface ParsedIdentifier {\n /** Jurisdiction (e.g., \"us\") */\n jurisdiction: string;\n /** Code (e.g., \"usc\") */\n code: string;\n /** Title number (e.g., \"1\", \"26\") */\n titleNum?: string | undefined;\n /** Section number (e.g., \"1\", \"7801\", \"106a\") */\n sectionNum?: string | undefined;\n /** Subsection path (e.g., \"a/2\") */\n subPath?: string | undefined;\n}\n\n/**\n * Parse a USLM identifier into its components.\n *\n * Handles: /us/usc/t{N}, /us/usc/t{N}/s{N}, /us/usc/t{N}/s{N}/{sub}\n * Returns null for non-USC identifiers (stat, pl, act).\n */\nexport function parseIdentifier(identifier: string): ParsedIdentifier | null {\n // Match: /us/usc/t{title}[/s{section}[/subpath]]\n const match = /^\\/(\\w+)\\/(\\w+)\\/t(\\w+)(?:\\/s([^/]+)(?:\\/(.+))?)?$/.exec(identifier);\n if (!match) return null;\n\n return {\n jurisdiction: match[1] ?? \"\",\n code: match[2] ?? \"\",\n titleNum: match[3],\n sectionNum: match[4],\n subPath: match[5],\n };\n}\n\n/**\n * Resolve a USLM identifier to an expected output file path.\n *\n * Given a section identifier like \"/us/usc/t2/s285b\", returns a path like\n * \"usc/title-02/section-285b.md\". The chapter is unknown without a registry,\n * so this returns null unless the identifier is registered.\n */\nexport interface LinkResolver {\n /**\n * Given a USLM identifier and the current file's path in the output tree,\n * return a relative Markdown link path or null if unresolvable.\n */\n resolve(identifier: string, fromFile: string): string | null;\n\n /**\n * Register a converted file so future cross-references can resolve to it.\n */\n register(identifier: string, filePath: string): void;\n\n /**\n * Build the fallback OLRC website URL for identifiers not in the output corpus.\n */\n fallbackUrl(identifier: string): string | null;\n}\n\n/**\n * Create a new LinkResolver instance.\n */\nexport function createLinkResolver(): LinkResolver {\n /** Map of USLM identifier → output file path (relative to output root) */\n const registry = new Map<string, string>();\n\n return {\n register(identifier: string, filePath: string): void {\n registry.set(identifier, filePath);\n },\n\n resolve(identifier: string, fromFile: string): string | null {\n const targetPath = registry.get(identifier);\n if (!targetPath) {\n // Try resolving just the section (strip subsection path)\n const parsed = parseIdentifier(identifier);\n if (parsed?.sectionNum && parsed.titleNum) {\n const sectionId = `/us/usc/t${parsed.titleNum}/s${parsed.sectionNum}`;\n const sectionPath = registry.get(sectionId);\n if (sectionPath) {\n return relative(dirname(fromFile), sectionPath);\n }\n }\n return null;\n }\n return relative(dirname(fromFile), targetPath);\n },\n\n fallbackUrl(identifier: string): string | null {\n const parsed = parseIdentifier(identifier);\n if (!parsed || parsed.code !== \"usc\") return null;\n\n if (parsed.sectionNum) {\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${parsed.titleNum}-section${parsed.sectionNum}`;\n }\n if (parsed.titleNum) {\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${parsed.titleNum}`;\n }\n return null;\n },\n };\n}\n"],"mappings":"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","names":["resolve","frame","parts","dirname"]}
1
+ {"version":3,"sources":["../src/xml/parser.ts","../src/xml/namespace.ts","../src/ast/types.ts","../src/ast/builder.ts","../src/markdown/frontmatter.ts","../src/markdown/renderer.ts","../src/markdown/links.ts"],"sourcesContent":["/**\n * Streaming XML parser wrapping saxes with typed events and namespace normalization.\n */\n\nimport { SaxesParser } from \"saxes\";\nimport type { SaxesAttributeNS, SaxesOptions } from \"saxes\";\nimport type { Readable } from \"node:stream\";\nimport { USLM_NS, NAMESPACE_PREFIXES } from \"./namespace.js\";\n\n/** saxes options type for namespace-aware parsing */\ntype NSParserOptions = SaxesOptions & { xmlns: true };\n\n/** Normalized attributes: a flat record of name → value */\nexport type Attributes = Record<string, string>;\n\n/** Events emitted by the XML parser */\nexport interface ParserEvents {\n /** An element was opened */\n openElement: (name: string, attrs: Attributes, ns: string) => void;\n /** An element was closed */\n closeElement: (name: string, ns: string) => void;\n /** Text content was encountered */\n text: (content: string) => void;\n /** An error occurred during parsing */\n error: (err: Error) => void;\n /** Parsing is complete */\n end: () => void;\n}\n\n/** Configuration for the XML parser */\nexport interface XMLParserOptions {\n /** Namespace URI to treat as default (elements in this NS emit bare names) */\n defaultNamespace?: string | undefined;\n /** Additional namespace prefix mappings beyond the built-in ones */\n namespacePrefixes?: Readonly<Record<string, string>> | undefined;\n}\n\ntype EventName = keyof ParserEvents;\ntype EventHandler<K extends EventName> = ParserEvents[K];\n\n/**\n * Streaming XML parser that normalizes namespace-prefixed element names.\n *\n * Elements in the default namespace emit bare names (e.g., \"section\").\n * Elements in other recognized namespaces emit prefixed names (e.g., \"xhtml:table\").\n * Elements in unrecognized namespaces emit the full URI-prefixed name.\n */\nexport class XMLParser {\n private readonly saxParser: SaxesParser<NSParserOptions>;\n private readonly defaultNs: string;\n private readonly prefixMap: Readonly<Record<string, string>>;\n private readonly listeners: Map<EventName, Array<(...args: unknown[]) => void>> = new Map();\n\n constructor(options?: XMLParserOptions) {\n this.defaultNs = options?.defaultNamespace ?? USLM_NS;\n this.prefixMap = {\n ...NAMESPACE_PREFIXES,\n ...options?.namespacePrefixes,\n };\n\n this.saxParser = new SaxesParser<NSParserOptions>({ xmlns: true, position: true });\n\n this.saxParser.on(\"opentag\", (node) => {\n const ns = node.uri;\n const localName = node.local;\n const normalizedName = this.normalizeName(localName, ns);\n const attrs = this.normalizeAttributes(node.attributes as Record<string, SaxesAttributeNS>);\n this.emit(\"openElement\", normalizedName, attrs, ns);\n });\n\n this.saxParser.on(\"closetag\", (node) => {\n const ns = node.uri;\n const localName = node.local;\n const normalizedName = this.normalizeName(localName, ns);\n this.emit(\"closeElement\", normalizedName, ns);\n });\n\n this.saxParser.on(\"text\", (text) => {\n this.emit(\"text\", text);\n });\n\n this.saxParser.on(\"error\", (err) => {\n this.emit(\"error\", err);\n });\n\n this.saxParser.on(\"end\", () => {\n this.emit(\"end\");\n });\n }\n\n /**\n * Register an event listener.\n */\n on<K extends EventName>(event: K, handler: EventHandler<K>): this {\n let handlers = this.listeners.get(event);\n if (!handlers) {\n handlers = [];\n this.listeners.set(event, handlers);\n }\n handlers.push(handler as (...args: unknown[]) => void);\n return this;\n }\n\n /**\n * Parse a complete XML string.\n */\n parseString(xml: string): void {\n this.saxParser.write(xml);\n this.saxParser.close();\n }\n\n /**\n * Parse from a readable stream (e.g., fs.createReadStream).\n * Returns a promise that resolves when parsing is complete.\n */\n parseStream(stream: Readable): Promise<void> {\n return new Promise((resolve, reject) => {\n stream.on(\"data\", (chunk: Buffer | string) => {\n try {\n this.saxParser.write(typeof chunk === \"string\" ? chunk : chunk.toString(\"utf-8\"));\n } catch (err) {\n reject(err);\n }\n });\n\n stream.on(\"end\", () => {\n try {\n this.saxParser.close();\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n\n stream.on(\"error\", (err) => {\n reject(err);\n });\n });\n }\n\n /**\n * Normalize an element name based on its namespace.\n * Default namespace elements get bare names; others get prefixed.\n */\n private normalizeName(localName: string, ns: string): string {\n if (ns === this.defaultNs || ns === \"\") {\n return localName;\n }\n const prefix = this.prefixMap[ns];\n if (prefix) {\n return `${prefix}:${localName}`;\n }\n // Unknown namespace: use full URI\n return `{${ns}}${localName}`;\n }\n\n /**\n * Normalize saxes namespace-aware attributes to a flat record.\n * Strips namespace prefixes from attribute names for simplicity,\n * except for xmlns declarations which are dropped entirely.\n */\n private normalizeAttributes(saxAttrs: Record<string, SaxesAttributeNS>): Attributes {\n const attrs: Attributes = {};\n for (const [, attr] of Object.entries(saxAttrs)) {\n // Skip xmlns declarations\n if (attr.prefix === \"xmlns\" || attr.local === \"xmlns\") {\n continue;\n }\n // Use local name for most attributes\n const name = attr.prefix && attr.prefix !== \"\" ? `${attr.prefix}:${attr.local}` : attr.local;\n attrs[name] = attr.value;\n }\n return attrs;\n }\n\n /**\n * Emit an event to all registered listeners.\n */\n private emit(event: EventName, ...args: unknown[]): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n for (const handler of handlers) {\n handler(...args);\n }\n }\n }\n}\n","/**\n * USLM XML namespace constants and element classification utilities.\n */\n\n/** USLM 1.0 default namespace */\nexport const USLM_NS = \"http://xml.house.gov/schemas/uslm/1.0\";\n\n/** XHTML namespace (used for tables) */\nexport const XHTML_NS = \"http://www.w3.org/1999/xhtml\";\n\n/** Dublin Core elements namespace */\nexport const DC_NS = \"http://purl.org/dc/elements/1.1/\";\n\n/** Dublin Core terms namespace */\nexport const DCTERMS_NS = \"http://purl.org/dc/terms/\";\n\n/** XML Schema Instance namespace */\nexport const XSI_NS = \"http://www.w3.org/2001/XMLSchema-instance\";\n\n/**\n * Prefix map for recognized non-default namespaces.\n * Elements in these namespaces will be emitted with the prefix (e.g., \"dc:title\").\n */\nexport const NAMESPACE_PREFIXES: Readonly<Record<string, string>> = {\n [XHTML_NS]: \"xhtml\",\n [DC_NS]: \"dc\",\n [DCTERMS_NS]: \"dcterms\",\n [XSI_NS]: \"xsi\",\n};\n\n/** USLM elements that represent hierarchical levels */\nexport const LEVEL_ELEMENTS = new Set([\n \"title\",\n \"subtitle\",\n \"chapter\",\n \"subchapter\",\n \"article\",\n \"subarticle\",\n \"part\",\n \"subpart\",\n \"division\",\n \"subdivision\",\n \"preliminary\",\n \"section\",\n \"subsection\",\n \"paragraph\",\n \"subparagraph\",\n \"clause\",\n \"subclause\",\n \"item\",\n \"subitem\",\n \"subsubitem\",\n // Appendix-level elements\n \"appendix\",\n \"compiledAct\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n \"courtRules\",\n \"courtRule\",\n]);\n\n/** USLM elements that represent content blocks */\nexport const CONTENT_ELEMENTS = new Set([\n \"content\",\n \"chapeau\",\n \"continuation\",\n \"proviso\",\n]);\n\n/** USLM elements that represent inline formatting */\nexport const INLINE_ELEMENTS = new Set([\n \"b\",\n \"i\",\n \"sub\",\n \"sup\",\n \"ref\",\n \"date\",\n \"term\",\n \"inline\",\n \"shortTitle\",\n \"del\",\n \"ins\",\n]);\n\n/** USLM note-related elements */\nexport const NOTE_ELEMENTS = new Set([\n \"note\",\n \"notes\",\n \"sourceCredit\",\n \"statutoryNote\",\n \"editorialNote\",\n \"changeNote\",\n]);\n\n/** USLM elements that act as levels in appendix contexts */\nexport const APPENDIX_LEVEL_ELEMENTS = new Set([\n \"compiledAct\",\n \"courtRules\",\n \"courtRule\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n]);\n\n/** USLM metadata elements inside <meta> */\nexport const META_ELEMENTS = new Set([\n \"meta\",\n \"docNumber\",\n \"docPublicationName\",\n \"docReleasePoint\",\n \"property\",\n]);\n\n/** Structural container elements (no direct content) */\nexport const CONTAINER_ELEMENTS = new Set([\n \"uscDoc\",\n \"main\",\n \"meta\",\n \"toc\",\n \"layout\",\n \"header\",\n \"row\",\n \"column\",\n \"tocItem\",\n]);\n","/**\n * @lexbuild/core AST node types\n *\n * The intermediate AST is a semantic representation of parsed USLM XML.\n * It is NOT a 1:1 mapping — it has been partially interpreted to simplify rendering.\n */\n\n/** All hierarchical levels in the USLM schema, ordered big → small */\nexport const LEVEL_TYPES = [\n // Big levels (above section)\n \"title\",\n \"appendix\",\n \"subtitle\",\n \"chapter\",\n \"subchapter\",\n \"compiledAct\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n \"courtRules\",\n \"courtRule\",\n \"article\",\n \"subarticle\",\n \"part\",\n \"subpart\",\n \"division\",\n \"subdivision\",\n \"preliminary\",\n // Primary level\n \"section\",\n // Small levels (below section)\n \"subsection\",\n \"paragraph\",\n \"subparagraph\",\n \"clause\",\n \"subclause\",\n \"item\",\n \"subitem\",\n \"subsubitem\",\n] as const;\n\n/** A USLM hierarchical level type */\nexport type LevelType = (typeof LEVEL_TYPES)[number];\n\n/** Big levels: above section in the hierarchy */\nexport const BIG_LEVELS = new Set<LevelType>([\n \"title\",\n \"appendix\",\n \"subtitle\",\n \"chapter\",\n \"subchapter\",\n \"compiledAct\",\n \"reorganizationPlans\",\n \"reorganizationPlan\",\n \"courtRules\",\n \"courtRule\",\n \"article\",\n \"subarticle\",\n \"part\",\n \"subpart\",\n \"division\",\n \"subdivision\",\n \"preliminary\",\n]);\n\n/** Small levels: below section in the hierarchy */\nexport const SMALL_LEVELS = new Set<LevelType>([\n \"subsection\",\n \"paragraph\",\n \"subparagraph\",\n \"clause\",\n \"subclause\",\n \"item\",\n \"subitem\",\n \"subsubitem\",\n]);\n\n/** Base node all AST nodes extend */\nexport interface BaseNode {\n /** Discriminator for the node type */\n readonly type: string;\n /** USLM identifier if present (e.g., \"/us/usc/t1/s1\") */\n identifier?: string | undefined;\n /** Source XML element name for debugging */\n sourceElement?: string | undefined;\n}\n\n/** A hierarchical level (title, chapter, section, subsection, etc.) */\nexport interface LevelNode extends BaseNode {\n readonly type: \"level\";\n /** Which level in the USLM hierarchy */\n levelType: LevelType;\n /** Display text of the number (e.g., \"§ 1.\", \"(a)\", \"CHAPTER 1—\") */\n num?: string | undefined;\n /** Normalized value of the number (e.g., \"1\", \"a\") */\n numValue?: string | undefined;\n /** Heading text (e.g., \"Words denoting number, gender, and so forth\") */\n heading?: string | undefined;\n /** Legal status of this element (e.g., \"repealed\", \"transferred\") */\n status?: string | undefined;\n /** Child nodes */\n children: ASTNode[];\n}\n\n/** Variant of a content block */\nexport type ContentVariant = \"content\" | \"chapeau\" | \"continuation\" | \"proviso\";\n\n/** A block of text content */\nexport interface ContentNode extends BaseNode {\n readonly type: \"content\";\n /** What kind of content block this is */\n variant: ContentVariant;\n /** Inline children (text, formatting, refs) */\n children: InlineNode[];\n}\n\n/** Discriminator for inline node types */\nexport type InlineType =\n | \"text\"\n | \"bold\"\n | \"italic\"\n | \"ref\"\n | \"date\"\n | \"term\"\n | \"quoted\"\n | \"sup\"\n | \"sub\"\n | \"footnoteRef\";\n\n/** Inline text or formatting */\nexport interface InlineNode extends BaseNode {\n readonly type: \"inline\";\n /** What kind of inline this is */\n inlineType: InlineType;\n /** Text content (for leaf text nodes) */\n text?: string | undefined;\n /** Link target (for ref nodes) */\n href?: string | undefined;\n /** Footnote target ID (for footnoteRef nodes) */\n idref?: string | undefined;\n /** Nested inline children */\n children?: InlineNode[] | undefined;\n}\n\n/** A note (editorial, statutory, amendment, etc.) */\nexport interface NoteNode extends BaseNode {\n readonly type: \"note\";\n /** Semantic category (e.g., \"amendments\", \"codification\") */\n topic?: string | undefined;\n /** Role refinement (e.g., \"crossHeading\") */\n role?: string | undefined;\n /** Note placement type (e.g., \"uscNote\", \"footnote\") */\n noteType?: string | undefined;\n /** Heading text of the note */\n heading?: string | undefined;\n /** Child nodes */\n children: ASTNode[];\n}\n\n/** Source credit annotation */\nexport interface SourceCreditNode extends BaseNode {\n readonly type: \"sourceCredit\";\n /** The full source credit text, including inline formatting */\n children: InlineNode[];\n}\n\n/** Table (either XHTML or USLM layout-based) */\nexport interface TableNode extends BaseNode {\n readonly type: \"table\";\n /** Which table model */\n variant: \"xhtml\" | \"layout\";\n /** Header rows (each row is an array of cell strings) */\n headers: string[][];\n /** Body rows */\n rows: string[][];\n /** Raw HTML for complex tables that can't be simplified to rows/columns */\n rawHtml?: string | undefined;\n}\n\n/** A single TOC entry */\nexport interface TOCItemNode extends BaseNode {\n readonly type: \"tocItem\";\n /** Section/chapter number */\n number?: string | undefined;\n /** Title or heading text */\n title?: string | undefined;\n /** Link target identifier */\n href?: string | undefined;\n}\n\n/** Table of contents */\nexport interface TOCNode extends BaseNode {\n readonly type: \"toc\";\n /** TOC entries */\n items: TOCItemNode[];\n}\n\n/** Container for notes (wraps <notes type=\"uscNote\">) */\nexport interface NotesContainerNode extends BaseNode {\n readonly type: \"notesContainer\";\n /** The notes type attribute (e.g., \"uscNote\") */\n notesType?: string | undefined;\n /** Child note nodes */\n children: (NoteNode | ASTNode)[];\n}\n\n/** Quoted content (blockquote) */\nexport interface QuotedContentNode extends BaseNode {\n readonly type: \"quotedContent\";\n /** Where the quote originates from */\n origin?: string | undefined;\n /** Content of the quotation */\n children: ASTNode[];\n}\n\n/** Union of all AST node types */\nexport type ASTNode =\n | LevelNode\n | ContentNode\n | InlineNode\n | NoteNode\n | SourceCreditNode\n | TableNode\n | TOCNode\n | TOCItemNode\n | NotesContainerNode\n | QuotedContentNode;\n\n// ---------------------------------------------------------------------------\n// Context types used during AST building and rendering\n// ---------------------------------------------------------------------------\n\n/** Info about an ancestor level in the hierarchy */\nexport interface AncestorInfo {\n /** The level type (e.g., \"title\", \"chapter\") */\n levelType: LevelType;\n /** Normalized number value */\n numValue?: string | undefined;\n /** Heading text */\n heading?: string | undefined;\n /** USLM identifier */\n identifier?: string | undefined;\n}\n\n/** Document-level metadata extracted from the <meta> block */\nexport interface DocumentMeta {\n /** dc:title — display title (e.g., \"Title 1\") */\n dcTitle?: string | undefined;\n /** dc:type — document type (e.g., \"USCTitle\") */\n dcType?: string | undefined;\n /** docNumber — numeric designation (e.g., \"1\") */\n docNumber?: string | undefined;\n /** docPublicationName — publication name */\n docPublicationName?: string | undefined;\n /** Release point identifier (e.g., \"119-73\") */\n releasePoint?: string | undefined;\n /** Whether this is positive law */\n positivelaw?: boolean | undefined;\n /** dc:publisher */\n publisher?: string | undefined;\n /** dcterms:created — ISO timestamp */\n created?: string | undefined;\n /** dc:creator — generator tool name */\n creator?: string | undefined;\n /** The root document identifier (e.g., \"/us/usc/t1\") */\n identifier?: string | undefined;\n}\n\n/** Context provided when a completed section/chapter is emitted */\nexport interface EmitContext {\n /** Ancestor chain from document root to the emitted node's parent */\n ancestors: AncestorInfo[];\n /** Document-level metadata from the <meta> block */\n documentMeta: DocumentMeta;\n}\n\n// ---------------------------------------------------------------------------\n// Frontmatter types\n// ---------------------------------------------------------------------------\n\n/** Data used to generate YAML frontmatter for a section file */\nexport interface FrontmatterData {\n /** USLM canonical identifier (e.g., \"/us/usc/t1/s1\") */\n identifier: string;\n /** Human-readable display title (e.g., \"1 USC § 1 - Words denoting...\") */\n title: string;\n /** Title number (integer) */\n title_number: number;\n /** Title name (e.g., \"General Provisions\") */\n title_name: string;\n /** Chapter number (integer, omitted if not applicable) */\n chapter_number?: number | undefined;\n /** Chapter name */\n chapter_name?: string | undefined;\n /** Subchapter identifier (often Roman numerals) */\n subchapter_number?: string | undefined;\n /** Subchapter name */\n subchapter_name?: string | undefined;\n /** Part identifier */\n part_number?: string | undefined;\n /** Part name */\n part_name?: string | undefined;\n /** Section number (string — can be alphanumeric like \"7801\"). Omitted for title-level output. */\n section_number?: string | undefined;\n /** Section name. Omitted for title-level output. */\n section_name?: string | undefined;\n /** Whether this title is positive law */\n positive_law: boolean;\n /** Full source credit text */\n source_credit?: string | undefined;\n /** Release point identifier (e.g., \"119-73\") */\n currency: string;\n /** ISO date from XML generation timestamp */\n last_updated: string;\n /** Section status (e.g., \"repealed\", \"transferred\") */\n status?: string | undefined;\n /** Number of chapters (title-level granularity only) */\n chapter_count?: number | undefined;\n /** Number of sections (title-level granularity only) */\n section_count?: number | undefined;\n /** Total estimated tokens (title-level granularity only) */\n total_token_estimate?: number | undefined;\n}\n","/**\n * AST Builder — converts XML parser events into an AST tree.\n *\n * Implements the section-emit pattern: when a section (or other configured level)\n * close tag is encountered, the completed LevelNode is emitted via callback\n * and its subtree is released from memory.\n */\n\nimport type { Attributes } from \"../xml/parser.js\";\nimport { LEVEL_ELEMENTS, CONTENT_ELEMENTS, INLINE_ELEMENTS } from \"../xml/namespace.js\";\nimport { LEVEL_TYPES } from \"./types.js\";\nimport type {\n LevelType,\n LevelNode,\n ContentNode,\n ContentVariant,\n InlineNode,\n InlineType,\n NoteNode,\n SourceCreditNode,\n TableNode,\n NotesContainerNode,\n QuotedContentNode,\n ASTNode,\n AncestorInfo,\n DocumentMeta,\n EmitContext,\n} from \"./types.js\";\n\n/** Options for configuring the AST builder */\nexport interface ASTBuilderOptions {\n /** Emit completed nodes at this level instead of accumulating */\n emitAt: LevelType;\n /** Callback when a completed node is ready */\n onEmit: (node: LevelNode, context: EmitContext) => void | Promise<void>;\n}\n\n/** Map from inline XML element names to InlineType discriminators */\nconst INLINE_TYPE_MAP: Readonly<Record<string, InlineType>> = {\n b: \"bold\",\n i: \"italic\",\n sub: \"sub\",\n sup: \"sup\",\n ref: \"ref\",\n date: \"date\",\n term: \"term\",\n inline: \"text\",\n shortTitle: \"text\",\n del: \"text\",\n ins: \"text\",\n};\n\n/**\n * Internal representation of a frame on the builder stack.\n * Each open XML element that we care about pushes a frame.\n */\ninterface StackFrame {\n /** What kind of frame this is */\n kind:\n | \"level\"\n | \"content\"\n | \"inline\"\n | \"note\"\n | \"sourceCredit\"\n | \"notesContainer\"\n | \"quotedContent\"\n | \"meta\"\n | \"ignore\";\n /** The AST node being constructed (null for meta/ignore frames) */\n node: ASTNode | null;\n /** The XML element name that opened this frame */\n elementName: string;\n /** Accumulated text for simple text-collecting frames (meta fields, etc.) */\n textBuffer: string;\n}\n\n/** State for collecting an XHTML table */\ninterface TableCollector {\n /** Header rows (from thead) */\n headers: string[][];\n /** Body rows (from tbody or bare tr) */\n rows: string[][];\n /** Current row being built */\n currentRow: string[];\n /** Current cell text accumulator */\n cellText: string;\n /** Whether we're currently inside thead */\n inHead: boolean;\n /** Whether we're currently inside a cell (th or td) */\n inCell: boolean;\n /** Whether this table has colspan or rowspan (complex) */\n isComplex: boolean;\n /** Nesting depth for sub-elements inside cells */\n cellDepth: number;\n}\n\n/**\n * Builds an AST from XML parser events, emitting completed subtrees at the configured level.\n */\nexport class ASTBuilder {\n private readonly options: ASTBuilderOptions;\n private readonly stack: StackFrame[] = [];\n private readonly ancestors: AncestorInfo[] = [];\n private readonly documentMeta: DocumentMeta = {};\n\n /** Whether we are currently inside the <meta> block */\n private inMeta = false;\n /** Nesting depth inside <quotedContent> — levels inside quotes are not emitted */\n private quotedContentDepth = 0;\n /** Active XHTML table collector (null when not inside a table) */\n private tableCollector: TableCollector | null = null;\n /** Active USLM layout collector (null when not inside a layout) */\n private layoutCollector: TableCollector | null = null;\n /** Nesting depth inside <toc> — elements inside toc are handled by layout collector only */\n private tocDepth = 0;\n /** Current meta field being collected (e.g., \"dc:title\", \"docNumber\") */\n private metaField: string | null = null;\n /** Attributes of the current meta property element */\n private metaPropertyAttrs: Attributes | null = null;\n\n constructor(options: ASTBuilderOptions) {\n this.options = options;\n }\n\n /** Returns the document metadata collected so far */\n getDocumentMeta(): DocumentMeta {\n return this.documentMeta;\n }\n\n /**\n * Handle an openElement event from the parser.\n */\n onOpenElement(name: string, attrs: Attributes): void {\n // Handle meta block\n if (name === \"meta\") {\n this.inMeta = true;\n this.stack.push({ kind: \"meta\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n if (this.inMeta) {\n this.handleMetaOpen(name, attrs);\n return;\n }\n\n // Handle uscDoc root — extract identifier\n if (name === \"uscDoc\") {\n if (attrs[\"identifier\"]) {\n this.documentMeta.identifier = attrs[\"identifier\"];\n }\n return;\n }\n\n // Skip structural containers that don't produce AST nodes\n if (name === \"main\") {\n return;\n }\n\n // --- Collector zones: checked BEFORE normal element handlers ---\n\n if (name === \"xhtml:table\") {\n this.tableCollector = {\n headers: [],\n rows: [],\n currentRow: [],\n cellText: \"\",\n inHead: false,\n inCell: false,\n isComplex: false,\n cellDepth: 0,\n };\n return;\n }\n if (this.tableCollector) {\n this.handleTableOpen(name, attrs);\n return;\n }\n\n if (name === \"layout\") {\n this.layoutCollector = {\n headers: [],\n rows: [],\n currentRow: [],\n cellText: \"\",\n inHead: false,\n inCell: false,\n isComplex: false,\n cellDepth: 0,\n };\n return;\n }\n if (this.layoutCollector) {\n this.handleLayoutOpen(name, attrs);\n return;\n }\n\n if (name === \"toc\") {\n this.tocDepth++;\n return;\n }\n if (this.tocDepth > 0) {\n return;\n }\n\n // --- Normal element handlers ---\n\n // Handle level elements (title, chapter, section, subsection, etc.)\n if (LEVEL_ELEMENTS.has(name)) {\n this.openLevel(name as LevelType, attrs);\n return;\n }\n\n // Handle content block elements\n if (CONTENT_ELEMENTS.has(name)) {\n this.openContent(name as ContentVariant, attrs);\n return;\n }\n\n // Handle inline elements\n if (INLINE_ELEMENTS.has(name)) {\n this.openInline(name, attrs);\n return;\n }\n\n // Handle note-related elements\n if (name === \"notes\") {\n this.openNotesContainer(attrs);\n return;\n }\n\n if (\n name === \"note\" ||\n name === \"statutoryNote\" ||\n name === \"editorialNote\" ||\n name === \"changeNote\"\n ) {\n this.openNote(name, attrs);\n return;\n }\n\n if (name === \"sourceCredit\") {\n this.openSourceCredit();\n return;\n }\n\n if (name === \"quotedContent\") {\n this.openQuotedContent(attrs);\n return;\n }\n\n // Handle elements that collect text within a parent\n if (name === \"num\") {\n // Immediately set numValue from the value attribute on the parent level\n const parentFrame = this.findParentFrame(\"level\");\n if (parentFrame && attrs[\"value\"]) {\n (parentFrame.node as LevelNode).numValue = attrs[\"value\"];\n }\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n if (name === \"heading\") {\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n // Handle <p> elements — they're content-like within their parent\n if (name === \"p\") {\n // p elements don't create separate AST nodes; their text flows\n // into the parent content/note node. We push a frame to collect text.\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n return;\n }\n\n // Remaining unhandled elements — push ignore frame so close events balance\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n }\n\n /**\n * Handle a closeElement event from the parser.\n */\n onCloseElement(name: string): void {\n // Handle meta block close\n if (name === \"meta\") {\n this.inMeta = false;\n this.popFrame(\"meta\");\n return;\n }\n\n if (this.inMeta) {\n this.handleMetaClose(name);\n return;\n }\n\n // Skip structural containers\n if (name === \"uscDoc\" || name === \"main\") {\n return;\n }\n\n // Handle XHTML table close\n if (name === \"xhtml:table\" && this.tableCollector) {\n this.finishTable();\n return;\n }\n\n if (this.tableCollector) {\n this.handleTableClose(name);\n return;\n }\n\n // Handle </toc> close\n if (name === \"toc\") {\n this.tocDepth = Math.max(0, this.tocDepth - 1);\n return;\n }\n\n // Handle USLM layout close\n if (name === \"layout\" && this.layoutCollector) {\n this.finishLayout();\n return;\n }\n\n if (this.layoutCollector) {\n this.handleLayoutClose(name);\n return;\n }\n\n // Skip elements inside toc that aren't in a layout\n if (this.tocDepth > 0) {\n return;\n }\n\n // Handle <num> — set on parent level node\n if (name === \"num\" || name === \"heading\") {\n const frame = this.peekFrame();\n if (frame?.elementName === name) {\n this.handleNumOrHeadingClose(name, frame);\n this.stack.pop();\n return;\n }\n }\n\n // Handle <p> close\n if (name === \"p\") {\n const frame = this.peekFrame();\n if (frame?.elementName === \"p\") {\n this.handlePClose(frame);\n this.stack.pop();\n return;\n }\n }\n\n // Handle level close\n if (LEVEL_ELEMENTS.has(name)) {\n this.closeLevel(name as LevelType);\n return;\n }\n\n // Handle content block close\n if (CONTENT_ELEMENTS.has(name)) {\n this.closeContent();\n return;\n }\n\n // Handle inline close\n if (INLINE_ELEMENTS.has(name)) {\n this.closeInline();\n return;\n }\n\n // Handle notes container close\n if (name === \"notes\") {\n this.closeNotesContainer();\n return;\n }\n\n // Handle note close\n if (\n name === \"note\" ||\n name === \"statutoryNote\" ||\n name === \"editorialNote\" ||\n name === \"changeNote\"\n ) {\n this.closeNote();\n return;\n }\n\n // Handle sourceCredit close\n if (name === \"sourceCredit\") {\n this.closeSourceCredit();\n return;\n }\n\n // Handle quotedContent close\n if (name === \"quotedContent\") {\n this.closeQuotedContent();\n return;\n }\n\n // Pop ignore frames\n const frame = this.peekFrame();\n if (frame?.kind === \"ignore\" && frame.elementName === name) {\n this.stack.pop();\n }\n }\n\n /**\n * Handle a text event from the parser.\n */\n onText(text: string): void {\n // Collect text inside XHTML table cells\n if (this.tableCollector?.inCell) {\n this.tableCollector.cellText += text;\n return;\n }\n\n // Skip all text inside tables but outside cells (whitespace between elements)\n if (this.tableCollector) {\n return;\n }\n\n // Collect text inside layout cells\n if (this.layoutCollector?.inCell) {\n this.layoutCollector.cellText += text;\n return;\n }\n\n // Skip text inside layout but outside cells\n if (this.layoutCollector) {\n return;\n }\n\n // Skip text inside toc but outside layout\n if (this.tocDepth > 0) {\n return;\n }\n\n if (this.inMeta) {\n // Accumulate text for meta fields\n const frame = this.peekFrame();\n if (frame) {\n frame.textBuffer += text;\n }\n return;\n }\n\n // Find the nearest frame that can accept text\n const frame = this.peekFrame();\n if (!frame) return;\n\n if (frame.kind === \"ignore\") {\n // Accumulate in text buffer (for num, heading, p)\n frame.textBuffer += text;\n return;\n }\n\n if (frame.kind === \"inline\") {\n // Append text to the inline node\n const inlineNode = frame.node as InlineNode;\n const textChild: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n if (!inlineNode.children) {\n inlineNode.children = [];\n }\n inlineNode.children.push(textChild);\n\n // Also bubble text up to any heading/num ignore frame below this inline\n // (handles <heading><b>Editorial Notes</b></heading> pattern)\n this.bubbleTextToCollector(text);\n return;\n }\n\n if (frame.kind === \"content\" || frame.kind === \"sourceCredit\") {\n // Skip whitespace-only text between <p> elements (XML formatting noise)\n if (!text.trim()) return;\n // Create a text inline node and append to parent\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const parent = frame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as InlineNode[]).push(textNode);\n }\n return;\n }\n\n if (frame.kind === \"note\" || frame.kind === \"quotedContent\") {\n // Text directly inside a note or quotedContent — wrap in a content node\n const trimmed = text.trim();\n if (trimmed) {\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const contentNode: ContentNode = {\n type: \"content\",\n variant: \"content\",\n children: [textNode],\n };\n const parent = frame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as ASTNode[]).push(contentNode);\n }\n }\n return;\n }\n\n if (frame.kind === \"level\") {\n // Text directly inside a level (unusual but possible) — same as note\n const trimmed = text.trim();\n if (trimmed) {\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const contentNode: ContentNode = {\n type: \"content\",\n variant: \"content\",\n children: [textNode],\n };\n (frame.node as LevelNode).children.push(contentNode);\n }\n return;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Meta handling\n // ---------------------------------------------------------------------------\n\n private handleMetaOpen(name: string, attrs: Attributes): void {\n this.metaField = name;\n this.metaPropertyAttrs = attrs;\n this.stack.push({ kind: \"ignore\", node: null, elementName: name, textBuffer: \"\" });\n }\n\n private handleMetaClose(name: string): void {\n const frame = this.peekFrame();\n if (frame?.elementName !== name) return;\n\n const text = frame.textBuffer.trim();\n this.stack.pop();\n\n switch (this.metaField) {\n case \"dc:title\":\n this.documentMeta.dcTitle = text;\n break;\n case \"dc:type\":\n this.documentMeta.dcType = text;\n break;\n case \"docNumber\":\n this.documentMeta.docNumber = text;\n break;\n case \"docPublicationName\":\n this.documentMeta.docPublicationName = text;\n break;\n case \"docReleasePoint\":\n this.documentMeta.releasePoint = text;\n break;\n case \"dc:publisher\":\n this.documentMeta.publisher = text;\n break;\n case \"dcterms:created\":\n this.documentMeta.created = text;\n break;\n case \"dc:creator\":\n this.documentMeta.creator = text;\n break;\n case \"property\":\n if (this.metaPropertyAttrs?.[\"role\"] === \"is-positive-law\") {\n this.documentMeta.positivelaw = text.toLowerCase() === \"yes\";\n }\n break;\n }\n\n this.metaField = null;\n this.metaPropertyAttrs = null;\n }\n\n // ---------------------------------------------------------------------------\n // Level handling\n // ---------------------------------------------------------------------------\n\n private openLevel(levelType: LevelType, attrs: Attributes): void {\n const node: LevelNode = {\n type: \"level\",\n levelType,\n identifier: attrs[\"identifier\"],\n status: attrs[\"status\"],\n sourceElement: levelType,\n children: [],\n };\n\n // If this is a big level (above the emit level) and we're NOT inside quotedContent,\n // push an ancestor placeholder. The heading and numValue will be filled in later.\n const emitIndex = LEVEL_TYPES_ARRAY.indexOf(this.options.emitAt);\n const thisIndex = LEVEL_TYPES_ARRAY.indexOf(levelType);\n if (thisIndex >= 0 && thisIndex < emitIndex && this.quotedContentDepth === 0) {\n this.ancestors.push({\n levelType,\n identifier: attrs[\"identifier\"],\n });\n }\n\n this.stack.push({ kind: \"level\", node, elementName: levelType, textBuffer: \"\" });\n }\n\n private closeLevel(levelType: LevelType): void {\n const frame = this.popFrame(\"level\");\n if (!frame) return;\n\n const node = frame.node as LevelNode;\n\n // If we're inside a quotedContent, don't emit — treat as a child node\n if (this.quotedContentDepth > 0) {\n this.addToParent(node);\n return;\n }\n\n // Should we emit this node?\n if (levelType === this.options.emitAt) {\n const context: EmitContext = {\n ancestors: [...this.ancestors],\n documentMeta: { ...this.documentMeta },\n };\n this.options.onEmit(node, context);\n return;\n }\n\n // Is this an ancestor level above the emit level?\n // If so, track it in the ancestors array but don't add to parent\n const emitIndex = LEVEL_TYPES_ARRAY.indexOf(this.options.emitAt);\n const thisIndex = LEVEL_TYPES_ARRAY.indexOf(levelType);\n\n if (thisIndex < emitIndex) {\n // Closing a big level — remove from ancestors\n this.ancestors.pop();\n return;\n }\n\n // Small level below emit level — add to parent as a child\n this.addToParent(node);\n }\n\n // ---------------------------------------------------------------------------\n // Content handling\n // ---------------------------------------------------------------------------\n\n private openContent(variant: ContentVariant, _attrs: Attributes): void {\n const node: ContentNode = {\n type: \"content\",\n variant,\n sourceElement: variant,\n children: [],\n };\n this.stack.push({ kind: \"content\", node, elementName: variant, textBuffer: \"\" });\n }\n\n private closeContent(): void {\n const frame = this.popFrame(\"content\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n // ---------------------------------------------------------------------------\n // Inline handling\n // ---------------------------------------------------------------------------\n\n private openInline(name: string, attrs: Attributes): void {\n const inlineType = INLINE_TYPE_MAP[name] ?? \"text\";\n\n const node: InlineNode = {\n type: \"inline\",\n inlineType,\n sourceElement: name,\n };\n\n // Handle ref-specific attributes\n if (name === \"ref\") {\n if (attrs[\"href\"]) {\n node.href = attrs[\"href\"];\n }\n if (attrs[\"class\"] === \"footnoteRef\") {\n node.inlineType = \"footnoteRef\";\n node.idref = attrs[\"idref\"];\n }\n }\n\n // Handle date attribute\n if (name === \"date\" && attrs[\"date\"]) {\n node.href = attrs[\"date\"]; // Store ISO date in href for convenience\n }\n\n this.stack.push({ kind: \"inline\", node, elementName: name, textBuffer: \"\" });\n }\n\n private closeInline(): void {\n const frame = this.popFrame(\"inline\");\n if (!frame) return;\n\n const node = frame.node as InlineNode;\n\n // If this inline has no children but has accumulated text in parent, that's fine\n // The text was added as children by onText\n\n // If there's only one text child, flatten it\n const firstChild = node.children?.[0];\n if (node.children?.length === 1 && firstChild?.inlineType === \"text\" && !firstChild.children) {\n node.text = firstChild.text;\n node.children = undefined;\n }\n\n this.addInlineToParent(node);\n }\n\n // ---------------------------------------------------------------------------\n // Note handling\n // ---------------------------------------------------------------------------\n\n private openNotesContainer(attrs: Attributes): void {\n const node: NotesContainerNode = {\n type: \"notesContainer\",\n notesType: attrs[\"type\"],\n children: [],\n };\n this.stack.push({ kind: \"notesContainer\", node, elementName: \"notes\", textBuffer: \"\" });\n }\n\n private closeNotesContainer(): void {\n const frame = this.popFrame(\"notesContainer\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n private openNote(name: string, attrs: Attributes): void {\n const node: NoteNode = {\n type: \"note\",\n topic: attrs[\"topic\"],\n role: attrs[\"role\"],\n sourceElement: name,\n children: [],\n };\n this.stack.push({ kind: \"note\", node, elementName: name, textBuffer: \"\" });\n }\n\n private closeNote(): void {\n const frame = this.popFrame(\"note\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n // ---------------------------------------------------------------------------\n // SourceCredit handling\n // ---------------------------------------------------------------------------\n\n private openSourceCredit(): void {\n const node: SourceCreditNode = {\n type: \"sourceCredit\",\n children: [],\n };\n this.stack.push({ kind: \"sourceCredit\", node, elementName: \"sourceCredit\", textBuffer: \"\" });\n }\n\n private closeSourceCredit(): void {\n const frame = this.popFrame(\"sourceCredit\");\n if (!frame) return;\n if (frame.node) this.addToParent(frame.node);\n }\n\n // ---------------------------------------------------------------------------\n // QuotedContent handling\n // ---------------------------------------------------------------------------\n\n private openQuotedContent(attrs: Attributes): void {\n this.quotedContentDepth++;\n const node: QuotedContentNode = {\n type: \"quotedContent\",\n origin: attrs[\"origin\"],\n children: [],\n };\n this.stack.push({ kind: \"quotedContent\", node, elementName: \"quotedContent\", textBuffer: \"\" });\n }\n\n private closeQuotedContent(): void {\n this.quotedContentDepth--;\n const frame = this.popFrame(\"quotedContent\");\n if (!frame) return;\n\n // Add as inline \"quoted\" node if parent is content/inline,\n // or as block node if parent is note/level\n const parentFrame = this.peekFrame();\n if (\n parentFrame &&\n (parentFrame.kind === \"content\" ||\n parentFrame.kind === \"inline\" ||\n parentFrame.kind === \"sourceCredit\")\n ) {\n // Flatten to inline quoted text\n const qNode: InlineNode = {\n type: \"inline\",\n inlineType: \"quoted\",\n text: this.extractText(frame.node as QuotedContentNode),\n };\n this.addInlineToParent(qNode);\n } else {\n if (frame.node) this.addToParent(frame.node);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Num/Heading/P helpers\n // ---------------------------------------------------------------------------\n\n private handleNumOrHeadingClose(name: string, frame: StackFrame): void {\n const text = frame.textBuffer.trim();\n\n // First check if parent is a note (heading inside note)\n const noteFrame = this.findParentFrame(\"note\");\n const levelFrame = this.findParentFrame(\"level\");\n\n // Heading inside a note takes priority\n if (\n name === \"heading\" &&\n noteFrame &&\n (!levelFrame || this.stack.indexOf(noteFrame) > this.stack.indexOf(levelFrame))\n ) {\n (noteFrame.node as NoteNode).heading = text;\n return;\n }\n\n // Otherwise, apply to parent level\n if (!levelFrame) return;\n const levelNode = levelFrame.node as LevelNode;\n\n if (name === \"num\") {\n levelNode.num = text;\n // numValue was already set from the value attribute in onOpenElement\n } else if (name === \"heading\") {\n levelNode.heading = text;\n }\n\n // Update ancestor entry if this is a big level\n const ancestor = this.ancestors.find(\n (a) => a.levelType === levelNode.levelType && a.identifier === levelNode.identifier,\n );\n if (ancestor) {\n if (name === \"num\") {\n ancestor.numValue = levelNode.numValue;\n } else if (name === \"heading\") {\n ancestor.heading = text;\n }\n }\n }\n\n private handlePClose(frame: StackFrame): void {\n const text = frame.textBuffer;\n if (!text) return;\n\n // Find the nearest parent that accepts content\n const parentFrame = this.peekFrameAbove(frame);\n if (!parentFrame) return;\n\n if (parentFrame.kind === \"content\" || parentFrame.kind === \"sourceCredit\") {\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const parent = parentFrame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n const children = parent.children as InlineNode[];\n // Add paragraph break before this <p>'s text if there are prior children\n if (children.length > 0) {\n children.push({ type: \"inline\", inlineType: \"text\", text: \"\\n\\n\" });\n }\n children.push(textNode);\n }\n } else if (\n parentFrame.kind === \"note\" ||\n parentFrame.kind === \"level\" ||\n parentFrame.kind === \"quotedContent\"\n ) {\n // Wrap in a ContentNode\n const textNode: InlineNode = { type: \"inline\", inlineType: \"text\", text };\n const contentNode: ContentNode = {\n type: \"content\",\n variant: \"content\",\n children: [textNode],\n };\n const parent = parentFrame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as ASTNode[]).push(contentNode);\n }\n }\n }\n\n /**\n * Bubble text content up to the nearest heading/num ignore frame on the stack.\n * This handles patterns like <heading><b>Editorial Notes</b></heading>\n * where the text is inside an inline child but needs to be collected by the heading frame.\n */\n // ---------------------------------------------------------------------------\n // XHTML table handling\n // ---------------------------------------------------------------------------\n\n private handleTableOpen(name: string, attrs: Attributes): void {\n const tc = this.tableCollector;\n if (!tc) return;\n\n switch (name) {\n case \"xhtml:thead\":\n tc.inHead = true;\n break;\n case \"xhtml:tbody\":\n tc.inHead = false;\n break;\n case \"xhtml:tr\":\n tc.currentRow = [];\n break;\n case \"xhtml:th\":\n case \"xhtml:td\":\n tc.inCell = true;\n tc.cellText = \"\";\n tc.cellDepth = 0;\n // Detect complex tables\n if (attrs[\"colspan\"] && attrs[\"colspan\"] !== \"1\") {\n tc.isComplex = true;\n }\n if (attrs[\"rowspan\"] && attrs[\"rowspan\"] !== \"1\") {\n tc.isComplex = true;\n }\n break;\n // Sub-elements inside cells (p, span, i, a, etc.) — track depth\n default:\n if (tc.inCell) {\n tc.cellDepth++;\n }\n break;\n }\n }\n\n private handleTableClose(name: string): void {\n const tc = this.tableCollector;\n if (!tc) return;\n\n switch (name) {\n case \"xhtml:thead\":\n tc.inHead = false;\n break;\n case \"xhtml:tbody\":\n break;\n case \"xhtml:tr\":\n if (tc.inHead) {\n tc.headers.push(tc.currentRow);\n } else {\n tc.rows.push(tc.currentRow);\n }\n tc.currentRow = [];\n break;\n case \"xhtml:th\":\n case \"xhtml:td\":\n tc.currentRow.push(tc.cellText.trim());\n tc.inCell = false;\n tc.cellText = \"\";\n break;\n default:\n if (tc.inCell) {\n tc.cellDepth = Math.max(0, tc.cellDepth - 1);\n }\n break;\n }\n }\n\n private finishTable(): void {\n const tc = this.tableCollector;\n if (!tc) return;\n\n this.tableCollector = null;\n\n const node: TableNode = {\n type: \"table\",\n variant: \"xhtml\",\n headers: tc.headers,\n rows: tc.rows,\n };\n\n this.addToParent(node);\n }\n\n // ---------------------------------------------------------------------------\n // USLM layout handling\n // ---------------------------------------------------------------------------\n\n private handleLayoutOpen(name: string, _attrs: Attributes): void {\n const lc = this.layoutCollector;\n if (!lc) return;\n\n switch (name) {\n case \"header\":\n lc.inHead = true;\n lc.currentRow = [];\n break;\n case \"tocItem\":\n case \"row\":\n lc.currentRow = [];\n break;\n case \"column\":\n lc.inCell = true;\n lc.cellText = \"\";\n break;\n default:\n // Sub-elements inside column (ref, etc.) — just collect text\n break;\n }\n }\n\n private handleLayoutClose(name: string): void {\n const lc = this.layoutCollector;\n if (!lc) return;\n\n switch (name) {\n case \"header\":\n lc.headers.push(lc.currentRow);\n lc.currentRow = [];\n lc.inHead = false;\n break;\n case \"tocItem\":\n case \"row\":\n lc.rows.push(lc.currentRow);\n lc.currentRow = [];\n break;\n case \"column\":\n lc.currentRow.push(lc.cellText.trim());\n lc.inCell = false;\n lc.cellText = \"\";\n break;\n default:\n break;\n }\n }\n\n private finishLayout(): void {\n const lc = this.layoutCollector;\n if (!lc) return;\n\n this.layoutCollector = null;\n\n // Only emit a table if there are actual data rows\n if (lc.rows.length === 0 && lc.headers.length === 0) return;\n\n const node: TableNode = {\n type: \"table\",\n variant: \"layout\",\n headers: lc.headers,\n rows: lc.rows,\n };\n\n this.addToParent(node);\n }\n\n private bubbleTextToCollector(text: string): void {\n for (let i = this.stack.length - 2; i >= 0; i--) {\n const f = this.stack[i];\n if (f?.kind === \"ignore\" && (f.elementName === \"heading\" || f.elementName === \"num\")) {\n f.textBuffer += text;\n return;\n }\n // Stop bubbling if we hit a non-inline, non-ignore frame\n if (f && f.kind !== \"inline\" && f.kind !== \"ignore\") {\n return;\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Stack utilities\n // ---------------------------------------------------------------------------\n\n private peekFrame(): StackFrame | undefined {\n return this.stack[this.stack.length - 1];\n }\n\n private peekFrameAbove(belowFrame: StackFrame): StackFrame | undefined {\n const idx = this.stack.lastIndexOf(belowFrame);\n if (idx > 0) {\n return this.stack[idx - 1];\n }\n return undefined;\n }\n\n private popFrame(expectedKind: string): StackFrame | undefined {\n const frame = this.stack[this.stack.length - 1];\n if (frame?.kind === expectedKind) {\n this.stack.pop();\n return frame;\n }\n // Try to find and remove the frame (in case of nesting mismatches)\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const f = this.stack[i];\n if (f?.kind === expectedKind) {\n return this.stack.splice(i, 1)[0];\n }\n }\n return undefined;\n }\n\n private findParentFrame(kind: string): StackFrame | undefined {\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const f = this.stack[i];\n if (f?.kind === kind) {\n return f;\n }\n }\n return undefined;\n }\n\n /**\n * Add a block-level AST node to the nearest parent that accepts children.\n */\n private addToParent(node: ASTNode): void {\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const frame = this.stack[i];\n if (!frame) continue;\n if (frame.kind === \"level\") {\n (frame.node as LevelNode).children.push(node);\n return;\n }\n if (frame.kind === \"note\") {\n (frame.node as NoteNode).children.push(node);\n return;\n }\n if (frame.kind === \"notesContainer\") {\n (frame.node as NotesContainerNode).children.push(node);\n return;\n }\n if (frame.kind === \"quotedContent\") {\n (frame.node as QuotedContentNode).children.push(node);\n return;\n }\n }\n }\n\n /**\n * Add an inline AST node to the nearest parent that accepts inline children.\n */\n private addInlineToParent(node: InlineNode): void {\n for (let i = this.stack.length - 1; i >= 0; i--) {\n const frame = this.stack[i];\n if (!frame) continue;\n if (frame.kind === \"inline\") {\n const parent = frame.node as InlineNode;\n if (!parent.children) {\n parent.children = [];\n }\n parent.children.push(node);\n return;\n }\n if (frame.kind === \"content\" || frame.kind === \"sourceCredit\") {\n const parent = frame.node;\n if (parent && \"children\" in parent && Array.isArray(parent.children)) {\n (parent.children as InlineNode[]).push(node);\n }\n return;\n }\n }\n }\n\n /**\n * Extract plain text from a node tree (for flattening quotedContent).\n */\n private extractText(node: QuotedContentNode): string {\n let result = \"\";\n for (const child of node.children) {\n if (child.type === \"inline\") {\n result += this.extractInlineText(child);\n } else if (child.type === \"content\") {\n for (const inline of child.children) {\n result += this.extractInlineText(inline);\n }\n }\n }\n return result;\n }\n\n private extractInlineText(node: InlineNode): string {\n if (node.text) return node.text;\n if (node.children) {\n return node.children.map((c) => this.extractInlineText(c)).join(\"\");\n }\n return \"\";\n }\n}\n\n// Re-use LEVEL_TYPES for index lookups (cast to string[] for indexOf)\nconst LEVEL_TYPES_ARRAY: readonly string[] = LEVEL_TYPES;\n","/**\n * YAML frontmatter generator for section Markdown files.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { stringify } from \"yaml\";\nimport type { FrontmatterData } from \"../ast/types.js\";\n\n/** Resolve package.json version at module load time */\nfunction readPackageVersion(): string {\n try {\n const dir = dirname(fileURLToPath(import.meta.url));\n // Works from both src/markdown/ (dev) and dist/ (built)\n const pkgPath = resolve(dir, \"..\", \"..\", \"package.json\");\n const raw = readFileSync(pkgPath, \"utf-8\");\n return (JSON.parse(raw) as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n}\n\n/** Output format version */\nexport const FORMAT_VERSION = \"1.0.0\";\n\n/** Generator identifier (reads version from package.json) */\nexport const GENERATOR = `lexbuild@${readPackageVersion()}`;\n\n/**\n * Generate a YAML frontmatter string from section metadata.\n *\n * Returns a complete frontmatter block including the `---` delimiters.\n */\nexport function generateFrontmatter(data: FrontmatterData): string {\n // Build the frontmatter object with fields in the specified order.\n // We construct it manually to control field ordering.\n const fm: Record<string, unknown> = {\n identifier: data.identifier,\n title: data.title,\n title_number: data.title_number,\n title_name: data.title_name,\n };\n\n if (data.section_number !== undefined) {\n fm[\"section_number\"] = data.section_number;\n }\n if (data.section_name !== undefined) {\n fm[\"section_name\"] = data.section_name;\n }\n\n // Context fields (only include if present)\n if (data.chapter_number !== undefined) {\n fm[\"chapter_number\"] = data.chapter_number;\n }\n if (data.chapter_name !== undefined) {\n fm[\"chapter_name\"] = data.chapter_name;\n }\n if (data.subchapter_number !== undefined) {\n fm[\"subchapter_number\"] = data.subchapter_number;\n }\n if (data.subchapter_name !== undefined) {\n fm[\"subchapter_name\"] = data.subchapter_name;\n }\n if (data.part_number !== undefined) {\n fm[\"part_number\"] = data.part_number;\n }\n if (data.part_name !== undefined) {\n fm[\"part_name\"] = data.part_name;\n }\n\n // Metadata\n fm[\"positive_law\"] = data.positive_law;\n fm[\"currency\"] = data.currency;\n fm[\"last_updated\"] = data.last_updated;\n fm[\"format_version\"] = FORMAT_VERSION;\n fm[\"generator\"] = GENERATOR;\n\n // Optional fields\n if (data.source_credit !== undefined) {\n fm[\"source_credit\"] = data.source_credit;\n }\n if (data.status !== undefined) {\n fm[\"status\"] = data.status;\n }\n if (data.chapter_count !== undefined) {\n fm[\"chapter_count\"] = data.chapter_count;\n }\n if (data.section_count !== undefined) {\n fm[\"section_count\"] = data.section_count;\n }\n if (data.total_token_estimate !== undefined) {\n fm[\"total_token_estimate\"] = data.total_token_estimate;\n }\n\n const yamlStr = stringify(fm, {\n lineWidth: 0, // Don't wrap long lines\n defaultStringType: \"QUOTE_DOUBLE\",\n defaultKeyType: \"PLAIN\",\n });\n\n return `---\\n${yamlStr}---`;\n}\n","/**\n * Markdown renderer — converts AST nodes to Markdown strings.\n *\n * Stateless and pure: no side effects, no file I/O.\n */\n\nimport type {\n ASTNode,\n LevelNode,\n ContentNode,\n InlineNode,\n NoteNode,\n SourceCreditNode,\n TableNode,\n NotesContainerNode,\n QuotedContentNode,\n FrontmatterData,\n} from \"../ast/types.js\";\nimport { SMALL_LEVELS } from \"../ast/types.js\";\nimport { generateFrontmatter } from \"./frontmatter.js\";\n\n/** Notes filtering configuration */\nexport interface NotesFilter {\n /** Include editorial notes (codification, dispositionOfSections, etc.) */\n editorial: boolean;\n /** Include statutory notes (changeOfName, regulations, miscellaneous, repeals, etc.) */\n statutory: boolean;\n /** Include amendment history (amendments, effectiveDateOfAmendment) */\n amendments: boolean;\n}\n\n/** Options for controlling Markdown rendering */\nexport interface RenderOptions {\n /** Heading level offset (0 = section is H1, 1 = section is H2) */\n headingOffset: number;\n /** How to render cross-references */\n linkStyle: \"relative\" | \"canonical\" | \"plaintext\";\n /** Function to resolve a USLM identifier to a relative file path (for linkStyle \"relative\") */\n resolveLink?: ((identifier: string) => string | null) | undefined;\n /** Notes filtering. Undefined = include all notes. */\n notesFilter?: NotesFilter | undefined;\n}\n\n/** Default render options */\nexport const DEFAULT_RENDER_OPTIONS: RenderOptions = {\n headingOffset: 0,\n linkStyle: \"plaintext\",\n};\n\n/**\n * Render a complete section document: frontmatter + Markdown content.\n */\nexport function renderDocument(\n sectionNode: LevelNode,\n frontmatter: FrontmatterData,\n options: RenderOptions = DEFAULT_RENDER_OPTIONS,\n): string {\n const fm = generateFrontmatter(frontmatter);\n const content = renderSection(sectionNode, options);\n return `${fm}\\n\\n${content}\\n`;\n}\n\n/**\n * Render a section-level node to Markdown.\n */\nexport function renderSection(\n node: LevelNode,\n options: RenderOptions = DEFAULT_RENDER_OPTIONS,\n): string {\n const parts: string[] = [];\n\n // Section heading: # § {number}. {heading}\n const headingLevel = 1 + options.headingOffset;\n const prefix = \"#\".repeat(headingLevel);\n const numDisplay = node.num ?? \"\";\n const heading = node.heading ? ` ${node.heading}` : \"\";\n parts.push(`${prefix} ${numDisplay}${heading}`);\n\n // Render children\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n/**\n * Render any AST node to Markdown.\n */\nexport function renderNode(node: ASTNode, options: RenderOptions = DEFAULT_RENDER_OPTIONS): string {\n switch (node.type) {\n case \"level\":\n return renderLevel(node, options);\n case \"content\":\n return renderContent(node);\n case \"inline\":\n return renderInline(node, options);\n case \"sourceCredit\":\n return renderSourceCredit(node, options);\n case \"note\":\n return renderNote(node, options);\n case \"notesContainer\":\n return renderNotesContainer(node, options);\n case \"quotedContent\":\n return renderQuotedContent(node, options);\n case \"table\":\n return renderTable(node);\n case \"toc\":\n case \"tocItem\":\n return \"\";\n default:\n return \"\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Level rendering (subsection, paragraph, etc.)\n// ---------------------------------------------------------------------------\n\n/**\n * Render a sub-section level (subsection, paragraph, clause, etc.)\n * These use bold inline numbering, NOT Markdown headings.\n */\nfunction renderLevel(node: LevelNode, options: RenderOptions): string {\n // Small levels use bold inline numbering\n if (SMALL_LEVELS.has(node.levelType)) {\n return renderSmallLevel(node, options);\n }\n\n // Big levels within a section (unusual, but handle gracefully)\n const parts: string[] = [];\n if (node.num ?? node.heading) {\n const numDisplay = node.num ?? \"\";\n const heading = node.heading ? ` ${node.heading}` : \"\";\n parts.push(`**${numDisplay}${heading}**`);\n }\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n return parts.join(\"\\n\\n\");\n}\n\n/**\n * Render a small level (subsection through subsubitem) with bold inline numbering.\n *\n * Format: **(a)** **Heading.** — Content text...\n * Or just: **(a)** Content text...\n */\nfunction renderSmallLevel(node: LevelNode, options: RenderOptions): string {\n const parts: string[] = [];\n\n // Build the prefix: **(a)** or **(1)** etc.\n const numDisplay = node.num ?? (node.numValue ? `(${node.numValue})` : \"\");\n let prefix = numDisplay ? `**${numDisplay}**` : \"\";\n\n // If there's a heading, add it after the num\n if (node.heading) {\n prefix += ` **${node.heading}**`;\n }\n\n // Collect content and child levels\n const contentParts: string[] = [];\n const childParts: string[] = [];\n\n for (const child of node.children) {\n if (child.type === \"content\") {\n contentParts.push(renderContent(child));\n } else if (child.type === \"level\") {\n childParts.push(renderNode(child, options));\n } else {\n const rendered = renderNode(child, options);\n if (rendered) {\n childParts.push(rendered);\n }\n }\n }\n\n // Combine prefix with first content block on the same line\n if (contentParts.length > 0) {\n const firstContent = contentParts[0] ?? \"\";\n if (prefix) {\n parts.push(`${prefix} ${firstContent}`);\n } else {\n parts.push(firstContent);\n }\n // Additional content blocks as separate paragraphs\n for (let i = 1; i < contentParts.length; i++) {\n parts.push(contentParts[i] ?? \"\");\n }\n } else if (prefix) {\n parts.push(prefix);\n }\n\n // Child levels as separate paragraphs\n for (const child of childParts) {\n parts.push(child);\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Content rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a content block (content, chapeau, continuation, proviso).\n * Normalizes whitespace: collapses runs of whitespace between paragraphs\n * into clean double-newline paragraph breaks, and trims edges.\n */\nfunction renderContent(node: ContentNode): string {\n const raw = renderInlineChildren(node.children);\n return normalizeWhitespace(raw);\n}\n\n/**\n * Render a list of inline nodes to a string.\n */\nfunction renderInlineChildren(children: InlineNode[], options?: RenderOptions): string {\n return children.map((child) => renderInline(child, options)).join(\"\");\n}\n\n/**\n * Normalize whitespace in rendered text:\n * - Trim leading/trailing whitespace\n * - Collapse 2+ consecutive newlines (with optional spaces) into double-newline\n */\nfunction normalizeWhitespace(text: string): string {\n return text.trim().replace(/\\n\\s*\\n/g, \"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Inline rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render an inline node to a Markdown string.\n */\nfunction renderInline(node: InlineNode, options?: RenderOptions): string {\n switch (node.inlineType) {\n case \"text\":\n return node.text ?? renderInlineChildren(node.children ?? [], options);\n\n case \"bold\":\n return `**${getInlineText(node, options)}**`;\n\n case \"italic\":\n return `*${getInlineText(node, options)}*`;\n\n case \"ref\":\n return renderRef(node, options);\n\n case \"date\":\n return getInlineText(node, options);\n\n case \"term\":\n return `**${getInlineText(node, options)}**`;\n\n case \"quoted\":\n return `\"${node.text ?? getInlineText(node, options)}\"`;\n\n case \"sup\":\n return `<sup>${getInlineText(node, options)}</sup>`;\n\n case \"sub\":\n return `<sub>${getInlineText(node, options)}</sub>`;\n\n case \"footnoteRef\":\n return `[^${getInlineText(node, options)}]`;\n\n default:\n return getInlineText(node, options);\n }\n}\n\n/**\n * Get the text content of an inline node (recursing into children if needed).\n */\nfunction getInlineText(node: InlineNode, options?: RenderOptions): string {\n if (node.text) return node.text;\n if (node.children) return renderInlineChildren(node.children, options);\n return \"\";\n}\n\n/**\n * Render a cross-reference link.\n */\nfunction renderRef(node: InlineNode, options?: RenderOptions): string {\n const text = getInlineText(node, options);\n const href = node.href;\n\n if (!href) {\n return text;\n }\n\n const style = options?.linkStyle ?? \"plaintext\";\n\n if (style === \"plaintext\") {\n return text;\n }\n\n if (style === \"relative\" && options?.resolveLink) {\n const resolved = options.resolveLink(href);\n if (resolved) {\n return `[${text}](${resolved})`;\n }\n }\n\n // For USC references, generate OLRC fallback URL\n if (href.startsWith(\"/us/usc/\")) {\n const olrcUrl = buildOlrcUrl(href);\n return `[${text}](${olrcUrl})`;\n }\n\n // Non-USC references (stat, pl, act) — just render as text\n return text;\n}\n\n/**\n * Build an OLRC website URL from a USLM identifier.\n */\nfunction buildOlrcUrl(identifier: string): string {\n // /us/usc/t{N}/s{N} → granuleid:USC-prelim-title{N}-section{N}\n const match = /^\\/us\\/usc\\/t(\\d+)(?:\\/s(.+?))?(?:\\/|$)/.exec(identifier);\n if (match) {\n const titleNum = match[1];\n const sectionNum = match[2];\n if (sectionNum) {\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${titleNum}-section${sectionNum}`;\n }\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${titleNum}`;\n }\n return `https://uscode.house.gov/view.xhtml?req=${encodeURIComponent(identifier)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Table rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a table node to Markdown.\n * Simple tables (no colspan/rowspan) → Markdown pipe table.\n * Complex tables → skipped with a placeholder comment.\n */\nfunction renderTable(node: TableNode): string {\n // Determine column count from the widest row\n const allRows = [...node.headers, ...node.rows];\n if (allRows.length === 0) return \"\";\n\n let colCount = 0;\n for (const row of allRows) {\n if (row.length > colCount) colCount = row.length;\n }\n\n if (colCount === 0) return \"\";\n\n // Build the Markdown table\n const lines: string[] = [];\n\n // Use the last header row as the actual column headers (skip title rows with colspan)\n // If no usable header rows, use the first body row as implicit header\n let headerRow: string[] | undefined;\n for (let i = node.headers.length - 1; i >= 0; i--) {\n const row = node.headers[i];\n if (row && row.length === colCount) {\n headerRow = row;\n break;\n }\n }\n\n if (!headerRow) {\n // No header row matching column count — use empty headers\n headerRow = Array.from({ length: colCount }, () => \"\");\n }\n\n // Header line\n lines.push(`| ${headerRow.map((cell) => cell.replace(/\\|/g, \"\\\\|\")).join(\" | \")} |`);\n\n // Separator line\n lines.push(`| ${Array.from({ length: colCount }, () => \"---\").join(\" | \")} |`);\n\n // Body rows\n for (const row of node.rows) {\n // Pad row to column count if needed\n const paddedRow = Array.from({ length: colCount }, (_, i) => row[i] ?? \"\");\n lines.push(`| ${paddedRow.map((cell) => cell.replace(/\\|/g, \"\\\\|\")).join(\" | \")} |`);\n }\n\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Source credit rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a source credit node.\n * Format: horizontal rule, then bold label with text.\n */\nfunction renderSourceCredit(node: SourceCreditNode, options: RenderOptions): string {\n const text = renderInlineChildren(node.children, options);\n return `---\\n\\n**Source Credit**: ${text}`;\n}\n\n// ---------------------------------------------------------------------------\n// Notes rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render a notes container (<notes type=\"uscNote\">).\n */\nfunction renderNotesContainer(node: NotesContainerNode, options: RenderOptions): string {\n const filter = options.notesFilter;\n\n // No filter = include everything (default behavior)\n if (!filter) {\n const parts: string[] = [];\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n return parts.join(\"\\n\\n\");\n }\n\n // Filter notes by category\n const parts: string[] = [];\n let currentCategory: \"editorial\" | \"statutory\" | \"unknown\" = \"unknown\";\n\n for (const child of node.children) {\n if (child.type !== \"note\") {\n const rendered = renderNode(child, options);\n if (rendered) parts.push(rendered);\n continue;\n }\n\n // Cross-heading notes set the category\n if (child.role === \"crossHeading\") {\n if (child.topic === \"editorialNotes\") {\n currentCategory = \"editorial\";\n } else if (child.topic === \"statutoryNotes\") {\n currentCategory = \"statutory\";\n }\n // Only render the heading if we'll include notes in this category\n if (shouldIncludeCategory(currentCategory, filter)) {\n const rendered = renderNode(child, options);\n if (rendered) parts.push(rendered);\n }\n continue;\n }\n\n // Regular notes — check if their topic/category passes the filter\n if (shouldIncludeNote(child, currentCategory, filter)) {\n const rendered = renderNode(child, options);\n if (rendered) parts.push(rendered);\n }\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n/** Amendment-related topics */\nconst AMENDMENT_TOPICS = new Set([\n \"amendments\",\n \"effectiveDateOfAmendment\",\n \"shortTitleOfAmendment\",\n]);\n\n/** Editorial-specific topics */\nconst EDITORIAL_TOPICS = new Set([\"codification\", \"dispositionOfSections\"]);\n\n/** Statutory-specific topics */\nconst STATUTORY_TOPICS = new Set([\n \"changeOfName\",\n \"regulations\",\n \"miscellaneous\",\n \"repeals\",\n \"separability\",\n \"crossReferences\",\n]);\n\n/**\n * Check if a category of notes should be included based on the filter.\n */\nfunction shouldIncludeCategory(\n category: \"editorial\" | \"statutory\" | \"unknown\",\n filter: NotesFilter,\n): boolean {\n if (category === \"editorial\") return filter.editorial || filter.amendments;\n if (category === \"statutory\") return filter.statutory || filter.amendments;\n // Unknown category — include if any filter is enabled\n return filter.editorial || filter.statutory || filter.amendments;\n}\n\n/**\n * Check if an individual note should be included based on its topic and category.\n */\nfunction shouldIncludeNote(\n node: NoteNode,\n currentCategory: \"editorial\" | \"statutory\" | \"unknown\",\n filter: NotesFilter,\n): boolean {\n const topic = node.topic ?? \"\";\n\n // Amendment topics included by amendments filter\n if (AMENDMENT_TOPICS.has(topic)) return filter.amendments;\n\n // Topic-specific classification takes precedence over category\n if (EDITORIAL_TOPICS.has(topic)) return filter.editorial;\n if (STATUTORY_TOPICS.has(topic)) return filter.statutory;\n\n // Fall back to category from cross-heading\n if (currentCategory === \"editorial\") return filter.editorial;\n if (currentCategory === \"statutory\") return filter.statutory;\n\n // Unknown — include if any filter is active\n return filter.editorial || filter.statutory || filter.amendments;\n}\n\n/**\n * Render a note node.\n */\nfunction renderNote(node: NoteNode, options: RenderOptions): string {\n const parts: string[] = [];\n\n // Cross-heading notes become H2 headings\n if (node.role === \"crossHeading\" && node.heading) {\n parts.push(`## ${node.heading}`);\n return parts.join(\"\\n\\n\");\n }\n\n // Regular notes with a heading become H3\n if (node.heading) {\n parts.push(`### ${node.heading}`);\n }\n\n // Render note children\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n\n return parts.join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Quoted content rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Render quoted content as a Markdown blockquote.\n */\nfunction renderQuotedContent(node: QuotedContentNode, options: RenderOptions): string {\n const parts: string[] = [];\n\n for (const child of node.children) {\n const rendered = renderNode(child, options);\n if (rendered) {\n parts.push(rendered);\n }\n }\n\n const inner = parts.join(\"\\n\\n\");\n // Prefix each line with > for blockquote\n return inner\n .split(\"\\n\")\n .map((line) => `> ${line}`)\n .join(\"\\n\");\n}\n","/**\n * Cross-reference link resolver.\n *\n * Resolves USLM identifier URIs to relative Markdown file paths within\n * the output tree, or falls back to OLRC website URLs.\n */\n\nimport { relative, dirname } from \"node:path\";\n\n/** Parsed components of a USLM identifier */\nexport interface ParsedIdentifier {\n /** Jurisdiction (e.g., \"us\") */\n jurisdiction: string;\n /** Code (e.g., \"usc\") */\n code: string;\n /** Title number (e.g., \"1\", \"26\") */\n titleNum?: string | undefined;\n /** Section number (e.g., \"1\", \"7801\", \"106a\") */\n sectionNum?: string | undefined;\n /** Subsection path (e.g., \"a/2\") */\n subPath?: string | undefined;\n}\n\n/**\n * Parse a USLM identifier into its components.\n *\n * Handles: /us/usc/t{N}, /us/usc/t{N}/s{N}, /us/usc/t{N}/s{N}/{sub}\n * Returns null for non-USC identifiers (stat, pl, act).\n */\nexport function parseIdentifier(identifier: string): ParsedIdentifier | null {\n // Match: /us/usc/t{title}[/s{section}[/subpath]]\n const match = /^\\/(\\w+)\\/(\\w+)\\/t(\\w+)(?:\\/s([^/]+)(?:\\/(.+))?)?$/.exec(identifier);\n if (!match) return null;\n\n return {\n jurisdiction: match[1] ?? \"\",\n code: match[2] ?? \"\",\n titleNum: match[3],\n sectionNum: match[4],\n subPath: match[5],\n };\n}\n\n/**\n * Resolve a USLM identifier to an expected output file path.\n *\n * Given a section identifier like \"/us/usc/t2/s285b\", returns a path like\n * \"usc/title-02/section-285b.md\". The chapter is unknown without a registry,\n * so this returns null unless the identifier is registered.\n */\nexport interface LinkResolver {\n /**\n * Given a USLM identifier and the current file's path in the output tree,\n * return a relative Markdown link path or null if unresolvable.\n */\n resolve(identifier: string, fromFile: string): string | null;\n\n /**\n * Register a converted file so future cross-references can resolve to it.\n */\n register(identifier: string, filePath: string): void;\n\n /**\n * Build the fallback OLRC website URL for identifiers not in the output corpus.\n */\n fallbackUrl(identifier: string): string | null;\n}\n\n/**\n * Create a new LinkResolver instance.\n */\nexport function createLinkResolver(): LinkResolver {\n /** Map of USLM identifier → output file path (relative to output root) */\n const registry = new Map<string, string>();\n\n return {\n register(identifier: string, filePath: string): void {\n registry.set(identifier, filePath);\n },\n\n resolve(identifier: string, fromFile: string): string | null {\n const targetPath = registry.get(identifier);\n if (!targetPath) {\n // Try resolving just the section (strip subsection path)\n const parsed = parseIdentifier(identifier);\n if (parsed?.sectionNum && parsed.titleNum) {\n const sectionId = `/us/usc/t${parsed.titleNum}/s${parsed.sectionNum}`;\n const sectionPath = registry.get(sectionId);\n if (sectionPath) {\n return relative(dirname(fromFile), sectionPath);\n }\n }\n return null;\n }\n return relative(dirname(fromFile), targetPath);\n },\n\n fallbackUrl(identifier: string): string | null {\n const parsed = parseIdentifier(identifier);\n if (!parsed || parsed.code !== \"usc\") return null;\n\n if (parsed.sectionNum) {\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${parsed.titleNum}-section${parsed.sectionNum}`;\n }\n if (parsed.titleNum) {\n return `https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title${parsed.titleNum}`;\n }\n return null;\n },\n };\n}\n"],"mappings":"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","names":["resolve","frame","parts","dirname"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lexbuild/core",
3
- "version": "1.0.5",
4
- "description": "Core AST definitions, parsing infrastructure, and format-agnostic renderers for the lexbuild ecosystem.",
3
+ "version": "1.1.0",
4
+ "description": "Core AST definitions, parsing infrastructure, and format-agnostic renderers for the LexBuild ecosystem.",
5
5
  "author": "Chris Thomas",
6
6
  "license": "MIT",
7
7
  "repository": {