Skip to content

Latest commit

 

History

History
118 lines (95 loc) · 5.13 KB

File metadata and controls

118 lines (95 loc) · 5.13 KB

Canonical Office selectors

office.selector/1 is the format-explicit, parseable address model shared by the unified Office facade. It describes addresses only. Parsing a selector does not claim that a command can resolve, query, or mutate the addressed content.

Grammar

selector      = "/" format "/" segment ("/" segment)*
format        = "docx" | "xlsx"
segment       = name [selection]
selection     = "[" positive-index "]"
              | "[" key "=" json-string "]"
name          = lower-alpha (lower-alpha | digit | "-" | "_")*
key           = lower-alpha (lower-alpha | digit | "-" | "_")*

JSON strings are used deliberately: quotes, backslashes, control characters, slashes, brackets, equals signs, and Unicode round-trip through one familiar escaping rule. Rendered selectors always use the compact canonical JSON string form.

DOCX selectors begin with a story segment:

/docx/body/p[1]/r[2]
/docx/header[1]/p[1]
/docx/footer[1]/tbl[1]/tr[2]/tc[1]/p[1]
/docx/footnotes/note[id="7"]/p[1]
/docx/comments/comment[id="review/one]=\"ready\""]

body, footnotes, endnotes, and comments are unselected story roots. header and footer require a 1-based positional selector. Descendant segment names remain visible in the typed AST so format adapters can validate allowed child kinds without parsing the path again. DOCX named selectors use the id key; arbitrary XPath predicates, regexes, and expressions are not part of this grammar.

XLSX selectors address the workbook singleton or a sheet by stable name or snapshot-relative position. Sheet selectors may end in a typed A1 coordinate:

/xlsx/workbook
/xlsx/sheet[name="Data"]/cell[A1]
/xlsx/sheet[name="O'Brien / Q1"]/range[A1:C12]
/xlsx/sheet[2]

Cell columns are canonical uppercase A through XFD; rows are 1 through 1048576. Range endpoints are normalized to top-left then bottom-right. $ absolute markers, whole-row/whole-column references, formulas, unions, and cross-sheet formula syntax are intentionally outside selector syntax.

Stability

Every parsed selector reports one of two address classes:

  • Stable: it contains only singleton roots and named keys. For example, /docx/comments/comment[id="7"] and /xlsx/sheet[name="Data"].
  • SnapshotRelative: it contains any positional selector or A1 coordinate. Inserts, deletes, reordering, or sheet edits can move the addressed content.

The classification describes the address, not the lifetime of the underlying object: a stable key can still disappear or be renamed.

Resource limits and diagnostics

Parsing is total and bounded:

  • input length: 2048 Unicode scalar values;
  • depth: 32 segments after the format root;
  • selector count: 32;
  • segment/key length: 32 characters;
  • positional index width: 9 digits;
  • named value length: 256 Unicode scalar values.

Failures use a structured error code, a zero-based Unicode-scalar offset, a bounded input echo, and a bounded message. Cross-format shapes are rejected by their explicit root and cannot silently fall through to the other format's rules. Input and decoded JSON values must contain well-formed UTF-16; isolated surrogates fail before an AST is created or UTF-8 encoding is attempted.

Adapter and capability boundary

selector_from_docx_projection_path converts the existing /body/..., /header[n]/..., and annotation paths emitted by the DOCX tools. The selector_for_xlsx_workbook, selector_for_xlsx_sheet, selector_for_xlsx_cell, and selector_for_xlsx_range construct the canonical XLSX shapes, quote worksheet names, and validate A1 coordinates. These helpers adapt syntax only: they do not open a package or establish that an addressed object exists.

Format records in office help --json expose the selector schema, root, examples, and the resolver status for that format. Both DOCX and XLSX are read-resolved: office outline, get, text, and query dispatch from the validated package format and resolve the applicable bounded projection. A selector with the other format's root fails with a format-specific mismatch; it never falls through to the other resolver.

The DOCX resolver covers body, header, footer, footnote, endnote, and comment stories plus paragraphs, runs, tables, rows, cells, hyperlinks, and images. Unique non-empty note/comment ids within selector limits emit stable note[id="..."] / comment[id="..."] paths. Missing, duplicate, or unrepresentable ids emit positional paths and a bounded warning instead; asking for a duplicated stable id fails as ambiguous. Every descendant of an annotation item remains snapshot-relative because it contains positional segments.

The XLSX resolver covers the workbook singleton, worksheets, chart sheets, and worksheet cell/range coordinates. A positional sheet selector such as /xlsx/sheet[2] is accepted as snapshot-relative input, but successful output uses the stable name-keyed sheet path. Coordinate endpoints are normalized to canonical uppercase A1 form; their paths remain snapshot-relative. Chart sheets can be resolved and inspected as sheets, but reject cell/range descendants. See office-xlsx-read.md for scan ordering, query predicates, and resource limits.