/** * Markup Compatibility and Extensibility (MCE, ECMA-376 Part 3) — reading * helpers only, strictly NON-DESTRUCTIVE. * * OOXML files carry markup for multiple generations of consumers via * `mc:AlternateContent` (Choice/Fallback), `mc:Ignorable`, and * `mc:ProcessContent`. This module lets readers see the view a consumer * with a given set of understood namespaces would see — WITHOUT mutating * the tree. Writing keeps original markup untouched: the preservation * guarantee is that MCE processing never strips anything from the DOM. * * All namespace matching uses resolved namespace URIs (in-scope * resolution via the xml module), never raw prefixes. Prefix tokens inside * mc:* attribute values (`Ignorable`, `ProcessContent`, `MustUnderstand`) * and inside `Requires` resolve against the declarations in scope at the * element where the attribute sits. * * Decisions recorded (CONTRACTS.md §4): * - The view functions (`selectAlternateContent`, `visibleChildren`, * `visibleAttributes`, `isIgnorable`, …) are tolerant: they never throw * on malformed MCE markup (unresolvable `Requires` prefix ⇒ that Choice * does not match; a Choice with a missing/empty `Requires` is treated the * same way — strictly it is invalid, so the universally readable Fallback * wins) and they never enforce `mc:MustUnderstand` (§4.6). * - Strict consumption is opt-in: {@link checkMustUnderstand} and * {@link resolveForReading} throw — and are the ONLY throwers on * MustUnderstand violations. `resolveForReading` enforces MustUnderstand * over the logical view only: markup discarded by the same resolution * (unselected Choice branches, dropped ignorable subtrees) cannot * trigger a violation, matching how a real consumer processes a file. */ import { type XmlAttribute, type XmlElement, type XmlNode } from '../xml/index.js'; /** The Markup Compatibility namespace URI. */ export declare const MC_NAMESPACE_URI = "http://schemas.openxmlformats.org/markup-compatibility/2006"; /** * Select the winning branch of an `mc:AlternateContent` element. * * Per ECMA-376 Part 3: the first `mc:Choice` (in document order) whose * `Requires` prefix list resolves entirely to namespaces in `understood` * wins; otherwise `mc:Fallback` wins; returns null when no Choice matches * and there is no Fallback. * * Tolerance (documented decisions): an unresolvable prefix in `Requires` * means that Choice does not match (per Office behavior, no throw); a * Choice missing `Requires`, or with an empty list, is invalid per Part 3 * and likewise does not match, so the Fallback wins. * * Returns the chosen branch's child nodes. The tree is not modified — * returned nodes remain children of their Choice/Fallback element. * * Throws `Error` when `element` is not an mc:AlternateContent element. */ export declare function selectAlternateContent(element: XmlElement, understood: ReadonlySet): readonly XmlNode[] | null; /** * The set of namespace URIs declared ignorable at `element` — the union * of all in-scope `mc:Ignorable` prefix lists (element and ancestors), * each prefix resolved against the declarations in scope where its * Ignorable attribute appears. Unresolvable prefixes are skipped * (tolerant). */ export declare function ignorableNamespaces(element: XmlElement): ReadonlySet; /** * True when `element` would be skipped by a reader understanding * `understood`: its namespace is non-null, not in `understood`, and * in-scope ignorable. * * Note: an element in an *unknown but not ignorable* namespace is NOT * ignorable — strict consumers reject such content; our readers surface * it (preservation-first) and leave policy to callers. */ export declare function isIgnorable(element: XmlElement, understood: ReadonlySet): boolean; /** * True when `attribute` (owned by `owner`) would be skipped by a reader * understanding `understood`: it is a prefixed attribute whose namespace * resolves to a non-understood, in-scope-ignorable namespace. Unprefixed * attributes (no namespace), xmlns declarations, and xml:* attributes are * never ignorable; the mc:* control attributes are control markup, not * ignorable content (see {@link visibleAttributes} for how they are * filtered from views). */ export declare function isIgnorableAttribute(owner: XmlElement, attribute: XmlAttribute, understood: ReadonlySet): boolean; /** * The reading view of `element`'s children for a consumer understanding * `understood`. Non-destructive expansion, in document order: * * - An `mc:AlternateContent` child is replaced in the view by its selected * branch's children (recursively processed). * - An ignorable child element (see {@link isIgnorable}) is skipped — * unless an in-scope `mc:ProcessContent` names it, in which case its * children are promoted into the view (recursively processed). * - All other nodes appear as-is. * * The underlying tree is never modified; returned nodes keep their real * parents. */ export declare function visibleChildren(element: XmlElement, understood: ReadonlySet): readonly XmlNode[]; /** * The reading view of `element`'s attributes: attributes in ignorable, * not-understood namespaces are skipped, as are the mc:* control * attributes themselves (Ignorable, ProcessContent, MustUnderstand, * PreserveElements, PreserveAttributes). Order otherwise preserved. * Namespace declarations and xml:* attributes always pass through. */ export declare function visibleAttributes(element: XmlElement, understood: ReadonlySet): readonly XmlAttribute[]; /** * The set of namespace URIs that `mc:MustUnderstand` declarations in scope * at `element` (element and ancestors) require a consumer to understand; * each prefix token resolves where its attribute sits. * * Throws `Error` when a MustUnderstand prefix is not bound to any * namespace in scope — a namespace that cannot be identified cannot * possibly be understood, which is itself a MustUnderstand violation. */ export declare function mustUnderstandNamespaces(element: XmlElement): ReadonlySet; /** * Throw when any `mc:MustUnderstand` declaration in scope at `element` * (element and ancestors) names a namespace outside `understood`. * Descendants are NOT checked — use {@link resolveForReading} for * view-scoped deep enforcement. */ export declare function checkMustUnderstand(element: XmlElement, understood: ReadonlySet): void; /** * The logical reading view of a single element: the element itself, its * {@link visibleAttributes}, and its {@link visibleChildren}. Everything * references live nodes of the underlying tree — nothing is copied. */ export interface MceView { /** The underlying element (never a copy). */ readonly element: XmlElement; /** Its attributes as filtered by {@link visibleAttributes}. */ readonly attributes: readonly XmlAttribute[]; /** Its children as expanded by {@link visibleChildren}. */ readonly children: readonly XmlNode[]; } /** * Resolve `element` into the logical view a consumer understanding * `understood` would read: `mc:AlternateContent` collapsed to its winning * Choice/Fallback branch, ignorable content dropped (or promoted per * `mc:ProcessContent`), and mc:* control attributes plus ignorable * attributes hidden. * * This is the strict entry point: it enforces `mc:MustUnderstand` — over * the in-scope declarations (element and ancestors) and over the entire * logical view of the subtree — and throws `Error` on any violation. * Markup the same resolution discards (unselected Choice branches, * dropped ignorable subtrees) cannot trigger a violation. No other error * is possible and the tree is never mutated. */ export declare function resolveForReading(element: XmlElement, understood: ReadonlySet): MceView; //# sourceMappingURL=index.d.ts.map