# Deleting and replacing text

What insertText, delete, clear and Replace leave behind: the last paragraph, a paragraph's whole range and edits across paragraph marks.

`insertText` takes the locations Word takes for its receiver, `Replace` included, and `delete` and `clear` remove text and paragraphs by Word for the web's rules. Deleting the document's last paragraph, for one, empties it and leaves it in the list:

```js
await Word.run(async context => {
  context.document.body.insertParagraph('first', 'End');
  context.document.body.insertParagraph('last', 'End');
  await context.sync();
});
await Word.run(async context => {
  const paragraphs = context.document.body.paragraphs;
  paragraphs.load('items/text');
  await context.sync();
  paragraphs.items[paragraphs.items.length - 1].delete();
  await context.sync();
  const after = context.document.body.getRange('Whole').paragraphs;
  after.load('items/text');
  await context.sync();
  // after.items.map(p => p.text) -> ["", "first", ""]
});
```

### `Replace` writes unformatted text

Inserted text takes its formatting by where it goes:

| Insertion | Its text's formatting |
|---|---|
| `insertText(…, 'Replace')`, tracked or not | none of its own, whatever the text it replaces had |
| at `Start`, `End`, `Before` or `After` | the formatting of the text beside it |
| untracked, through a paragraph's or the body's `End`, at a paragraph mark with formatting of its own | the mark's |

So replacing a bold phrase writes the new phrase plain. Text typed at the end of a paragraph whose mark is bold comes out bold.

An edit at the end of a paragraph's text gives its mark the formatting of the paragraph's last run. That includes a delete or `Replace` that runs from there into the next paragraph, and the last run may be the one a delete took. With tracking on, only a mark with no formatting of its own takes it.

**Differs from Word for the web:** through a span from a search hit made in a sync that only read, Word's delete or `Replace` across a mark leaves the mark's run properties as they were. The simulator gives the mark the last run's formatting, as above.

`insertParagraph` on the body gives the new paragraph:

- the alignment, style and numbering of the paragraph beside it;
- that paragraph's run formatting, on its text;
- no formatting of its own, on its mark.

At `Start`, the first paragraph's mark stays as it was. At `End`, the last paragraph's mark is left with none either.

### Deleting the last paragraph empties it

`delete()` on the document's last paragraph, or on a table cell's, takes only its text. `body.paragraphs` still lists the paragraph, empty, and the document still ends in it.

| Paragraph | After `delete()` |
|---|---|
| the document's last | gives way to a new empty one; the one you deleted throws `ItemNotFound` for the rest of the run, as any deleted paragraph does |
| a table cell's last | stays and reads empty |
| any other | is removed, with any comment anchored in it |

Tracked, the text is marked deleted and the paragraph mark is not. The mark that stays takes the formatting of the last run deleted, so text typed there afterwards takes it too. That holds for the document's last paragraph, tracked or not, and for a cell's, untracked.

### Deleting a paragraph's whole range removes it

With tracking off, `delete()` on a range that holds a paragraph whole, its text and its mark, removes the paragraph as the paragraph's own `delete()` does. `paragraph.getRange('Whole')` is such a range. So:

- the document's last paragraph and a table cell's last only empty;
- a block content control's only paragraph takes the control with it;
- a range a `search` or `getRange` made inside the paragraph, in an earlier `context.sync()` that only read, throws `ItemNotFound`.

A range over several paragraphs removes each one it holds whole. It leaves those it holds only part of, unjoined, even when it takes the block content controls between them. `body.getRange('Whole').delete()` leaves one empty paragraph, as `body.clear()` does. The range you deleted reads empty where it started, or at the start of the next cell after emptying a cell's last paragraph.

Tracked, every paragraph stays, its text and mark marked deleted, except the mark that ends the document or a cell. A range that ran through the document's last mark throws `ItemNotFound` afterwards.

### `body.clear()` and the body's `Replace` keep the last paragraph

With tracking off, `body.clear()` and `body.insertText(…, 'Replace')` remove every paragraph but the document's last. That one stays, emptied, and a `Replace` writes its new text there. `body.paragraphs` reached before lists the others, empty, and reading one of them throws `ItemNotFound`.

A range made before the edit then reads as follows:

- **Made by `search` or `getRange` in an earlier `context.sync()` that only read, in a paragraph that went:** throws `ItemNotFound`. The body's `getRange('Start')`, `Content` and `Whole` count as such ranges.
- **Made the same way, in the last paragraph:** keeps its offsets and reads what sits there. That is empty after `clear()`, and the new text at its offsets after a `Replace`.
- **Any other range:** collapses to the start of the paragraph that stays. After `clear()`, it reads empty, and text inserted at it lands there. After a `Replace`, one from the last paragraph reads empty after the new text.
- **Any other range, from a paragraph that went, after a `Replace`:** reads the new text, with its start past the new text and its end before it.

So for that last range:

- text inserted at its `Start` lands after the new text, and at its `End` before it;
- a `Replace` through it writes after the new text;
- its `search` finds nothing, and its `delete` takes nothing;
- its `getOoxml` throws `GeneralException`.

The body's `getRange('Whole')` keeps the final mark and reads `\r`.

### An `insertText` `Replace` across paragraphs deletes first

With tracking off, `insertText(…, 'Replace')` over a range across a paragraph mark first deletes as `delete()` does. Block content controls between, of any kind, go whole, and the paragraphs either side stay apart. It then writes its text where the range collapsed. Take a range from `fore.` in `Before.` to `Aft` in `After.`, around a control or a paragraph. Replacing it with `X` leaves `BeX` and `er.`.

**Differs from Word for the web:** through a span from a search hit made in a sync that only read, Word's delete or `Replace` across a mark keeps a block control. The simulator handles such a span as one from a sync that wrote.

A paragraph mark the range ends just past stays. A range through a paragraph's `Whole`, or to the next paragraph's start, ends that way, and it leaves that paragraph empty. When the range holds the block content control that mark ends, from the control's start, the control goes and the paragraph stays. Over one paragraph, such as a control's only paragraph's `Whole`, the text goes in its place.

With tracking on, the range's text is marked deleted, and the new text goes by what the deletion crosses:

| The deletion | The new text goes |
|---|---|
| crosses a paragraph mark | after the deleted text, in the paragraph the range ends in, a table cell's too |
| crosses a mark, but the range starts inside a paragraph's text and ends just past an empty paragraph's mark | before the deleted text |
| crosses no mark, as for a range from `fore.` to the next paragraph's start | before the deleted text, as within one paragraph |

---

Source: https://www.rystic.ai/docs/simulators/word/features/editing-text · Markdown: https://www.rystic.ai/docs/simulators/word/features/editing-text.md
