search_document
Regex-search a .docx and get back the matching blocks, ready to edit — WITHOUT pulling the whole document into the conversation.
Use this to locate text in a document that is too large to read_document whole, or to jump
straight to the passages you care about before editing. The document is converted to the SAME
HTML representation read_document returns, and pattern is matched against BOTH that HTML and
the text a reader sees in it — so a phrase Word split across runs, or spelled with a
non-breaking space, still matches when typed plainly, AND a pattern naming markup (a class, an
, a tag) still works. If the pattern only matches with a relaxation (case, or a repeated
space), that is applied and note says so.
pattern is a Python regular expression, e.g.:
"Effective Date" -> literal text
"termination|terminate" -> either word
"(?i)confidential" -> case-insensitive
"$[0-9,]+(?:.[0-9]{2})?" -> dollar amounts
.matches newlines (DOTALL), so a pattern can span lines.
Each match is a COMPLETE BLOCK — verbatim HTML for the whole ///heading the match
sits in, tags and all, with nothing cut off. For a content-only edit of that
block, COPY match_text STRAIGHT INTO edit_document AS old; it needs no
trimming. For an insertion or structural edit, first treat match_text as a
locator. If it is not the nearest same-role structure the new content should
resemble, read the reported page and expand old to include that structural
example plus the insertion boundary. A match also carries:
matched— what your pattern actually matched inside the block, so you can see why it hit.page— the 1-based page it falls on, the SAME numbering read_document uses, so you can read_document(start_page=...) if you want the surrounding context.unique— false when that block's text appears elsewhere in the document too, so pasting it asoldwould be ambiguous. Add a neighbouring block from the same page to pin it down (see edit_document's MAKE 'old' UNIQUE).
When a match sits inside a semantic list item, match_text is the complete nearest
<li>...</li> rather than its inner paragraph or the surrounding <ol>/<ul>. That item is
enough for a one-item content edit. Before a structural list edit though, use read_document on the
reported page to inspect the parent list's type/start, sibling items, and nesting.
total_matches is how many spots match in the WHOLE document; the blocks returned in one call
fit a bounded budget, so has_more tells you some are still waiting and you get them with
start_at (1-based index of the first match you want, e.g. start_at=9 after eight came back).
note states all of this in one line — read it. Nothing is silently dropped, so you never have
to narrow a pattern just to see the rest of its matches.
Two spots that read identically (a running footer, a repeated placeholder) are two matches with
the same match_text, both marked unique: false — not a mistake, and not a reason to search
again. They differ by page, which is how you pick the one you want.
Only the document's CONTENT is searched, never the stylesheet in its , so a pattern naming a CSS class finds the blocks carrying that class and not the rule that defines it.
Comment markup is searchable too. <aside finds comment threads, while <article finds
individual comments and replies; each result returns its complete <aside> thread so it remains
a valid edit anchor. Consequently, the total for <article\b is the document's comment count,
whereas <aside\b is the thread count.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Regex to run over the document's HTML projection. | |
| start_at | No | 1-based index of the first match to return. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||