Semantic search over a Markdown knowledge base, served over MCP.
Until this record the .docx parser decided a heading from the spelling of the
style ID a paragraph names: <w:pStyle w:val="Heading1">, lowercased, had to
start with heading and end in a number. A style ID is an identifier the
writing application picks for each document, not a name. Word with a Japanese
interface writes its built-in headings under the IDs 1 .. 6 and names them
heading 1 .. heading 6 in word/styles.xml, so a document written that way
had none of its headings recognised and was indexed as a single chunk. The
test documents had no word/styles.xml and used Heading1-style IDs, which is
why nothing showed it.
The question is what decides that a paragraph is a heading, and what a document without usable styles gets.
Heading1, with or
without a styles part) splits the same way.heading N is a heading. Rejected: a custom style based on a heading
style is not, and to its author it is a heading.w:basedOn chain, with an outline level of 9 on a
derived style cancelling the heading (pandoc’s rule, plus the
cancellation). Taken.Heading... — two rules.docProps/core.xml. Rejected: a document
indexed today would drop out of the index for a part it can do without.word/styles.xml is read at a fixed path after docProps/core.xml, under
the same decompression budget, through ooxml::read_optional_zip_part: a
part that would take the document past the budget is skipped, never fatal,
and is inflated only up to what is left of it.w:type="paragraph", or no
w:type) that are direct children of the root w:styles, keyed by style ID
with entities resolved and compared byte for byte. The first definition of
an ID wins, whatever its type. A style without a usable w:name is named by
its ID.w:basedOn from that style
for at most 16 styles. The first style named heading N — read by the same
function that reads the spelling: lowercased, heading, trimmed, a number
from 1 to 255 — gives the level, unless the first style before it that sets
an outline level sets 9. No heading within 16 styles, a cycle included, is
body text.read_zip_part always has.get_document parse through the same function, each under its
own budget. Nothing new is configured.Heading1 named heading 1) split exactly as before.get_document’s content for the documents this
changes, as it already did for Heading1-style documents; full-text search
still finds it in the chunk’s heading.TOC Heading does.word/styles.xml is broken stays one chunk; the warning
names it.[index].max_decompressed_size can hold a
.docx near the limit that the index splits by styles while get_document
reads it by spelling, or the other way round, because reads keep the
default budget. Only whether heading text appears in content differs.w:basedOn reaches: an outline level
alone, or a localised name.grooveseek/src/parser/docx.rs (the table, the walk, the
fallback, the budget), grooveseek/src/parser/ooxml.rs (the optional read),
grooveseek/src/server.rs (the read side) and
grooveseek/tests/index_docx_heading_policy.rs (the binary and its stderr).style, §17.7.4.9 name, §17.7.4.3
basedOn, §17.3.1.20 outlineLvl.basedOn); docling issue #4106
(outline levels on body styles).