Table of Contents

Namespace DocWright.Dom.Editing

Classes

BookmarkEditingExtensions

Finds bookmarks and edits the content they span.

BookmarkReference

A located bookmark: its two markers and the content they span.

The pair is what makes a bookmark editable. The markers are ordinary inlines, they need not sit in the same paragraph, and a bookmark whose markers are adjacent spans nothing at all — the degenerate case a naive "replace the content" implementation silently turns into a no-op or an exception.

ContentEditingExtensions

Fluent creation over the DOM primitives: every method appends one node to its natural host and returns the node it created, so calls chain.

Nothing is defaulted into a formatting bag. A paragraph appended here has an empty ParagraphFormat and its runs have no CharacterFormat at all unless one is supplied. That is not tidiness: the bags are sparse, null means "inherit from the style chain", and a helper that wrote a concrete default would both break inheritance and add markup to the saved package that the caller never asked for.

The DOM is not thread-safe and these methods do not make it so. One document is edited by one thread at a time.

DocumentMergeExtensions

Section-level merge and split.

Ownership. Everything the imported content needs is materialized during the call: image bytes are read into the destination, not referenced back into the source's package. The source document may be disposed immediately afterwards. If it has already been disposed, its media cannot be read and the merge fails with InvalidDocumentException rather than producing a document with empty pictures.

What is not carried across. A merge moves content, not the package. The destination keeps its own theme, settings and document defaults, and the source's opaque package parts — custom XML, document properties, embedded objects, the glossary — stay behind. Those describe a document, not the sections being imported, and there is no meaningful way to have two of them. COMPAT.md enumerates the loss.

DocumentRange

A contiguous span of sibling nodes — inlines inside one paragraph, or blocks inside one section, cell, header, footer or note — that can be copied, moved or deleted as a unit.

A range is a snapshot of positions, not a live cursor. It captures the nodes it spans when it is created; editing the document afterwards can leave it describing a span that no longer exists, and the operations then throw rather than silently doing something else.

Moving honors the model's one-parent invariant: a move detaches every node and re-adds it, and never produces a node reachable from two parents. Copying deep-clones, so the copy shares no mutable state with the original.

FindOptions

How a search treats case, word boundaries and pathological patterns.

FindReplaceExtensions

Plain and regular-expression find and replace over document text, preserving formatting.

What a match may cross. A match lives inside one paragraph and may span any number of runs, whatever their formatting — that is the whole point, since Word splits a sentence into runs for reasons that have nothing to do with its words. It may also cross bookmark markers, which are zero-width annotations. It may not cross a field character, field instruction text, a hyperlink boundary, a break, an image, a shape, a note reference, a content control or preserved unknown markup. Those carry a target, an instruction or content of their own, and text spliced across one of them would either change what the field or link means or be silently discarded the next time the field is updated.

Revisions. Searching sees the same text GetText(DomNode, RevisionView) reports for Final: deleted runs are not searchable, inserted runs are. A replacement inherits the revision mark of the run the match started in, so replacing inside tracked-inserted text stays tracked-inserted.

Ordering. Matches are returned in document order and never overlap: scanning resumes at the end of each match. Zero-length regular-expression matches are skipped — they identify no content to replace and would not terminate.

MergeOptions

How one document is merged into another.

PlaceholderExtensions

Fills {{name}} placeholders in document text from a set of values.

A placeholder is ordinary text, so this inherits everything FindReplaceExtensions guarantees: a placeholder may be split across any number of runs — which Word does routinely, for reasons that have nothing to do with its words — the substituted value inherits the placeholder's formatting and revision mark, and the surrounding runs are coalesced afterwards. It may not cross a field, hyperlink, content control or image boundary.

Scope is the root you call it on. These hang off DomNode, not WordDocument. Called on a document they reach the body, headers, footers, footnotes, endnotes and text inside shapes — so a letterhead header is filled too. Called on a Table, a TableRow or a TableCell they touch nothing outside it, which is how one table among many is filled.

One pass. Every placeholder is substituted in a single scan, so a value that itself contains something shaped like a placeholder is never substituted into. Filling key by key instead would make the output depend on the order the keys happened to be enumerated in.

A placeholder names at least one character, so an empty {{}} names nothing and is left alone by every action including Clear.

This is deliberately a flat substitution: no conditionals, no repetition, no nested records. A template that needs a region repeated per record wants DocWright.MailMerge, where that grammar already lives.

PlaceholderOptions

How placeholders are recognized and how their values are formatted.

PlaceholderResult

What a placeholder substitution did.

ReplaceOptions

How a replacement is formatted and how the document is tidied afterwards.

StyleEditingExtensions

Applies styles and direct formatting to paragraphs, runs and ranges.

Formatting is layered with the model's own OverlayOnto, which copies only the values a bag actually specifies. Applying new CharacterFormat { Bold = true } therefore sets bold and touches nothing else — it does not stamp the rest of the bag with defaults, and everything left null keeps inheriting from the style chain.

A style id is validated against the document's style table before it is written. A dangling reference is not a harmless no-op: the resolver reports DXP1002 and silently resolves without it, so the caller would see formatting that never arrives.

TextMatch

One match of a search.

Enums

BookmarkInsertPosition

Where content is inserted relative to a bookmark.

StyleConflictResolution

What happens when a style id exists in both documents being merged.

UnresolvedPlaceholderAction

What to do with a placeholder the data supplies no value for.