docx_plus.revisions.mark¶
Author tracked insertions and deletions by wrapping run(s) already in the
document. mark_insertion wraps the target in <w:ins>; mark_deletion
wraps it in <w:del> and retags each <w:t> to <w:delText>. Both take
the same target shapes as comments.add_comment — a single run, a whole
paragraph, or a (start_run, end_run) range — but a range must lie within
one paragraph, since w:ins / w:del cannot span a paragraph boundary.
Runs wrapped in a revision are not visible through python-docx's
paragraph.runs; read them back with read_revisions.
docx_plus.revisions.mark ¶
Author tracked insertions and deletions — wrap existing runs.
python-docx writes runs but cannot mark them as tracked changes. This module wraps run(s) already present in the document in the revision container OOXML python-docx skips:
- :func:
mark_insertionwraps the target run(s) in<w:ins>— the text is shown as an inserted revision; accepting it makes the text permanent. - :func:
mark_deletionwraps the target run(s) in<w:del>and retags each<w:t>to<w:delText>— the text is shown struck-through; accepting the deletion removes it.
Both target a single run, a whole paragraph, or a (start_run, end_run)
range — the same target shapes as comments.add_comment. A range must
lie within one paragraph: w:ins / w:del are run-level containers
and cannot span a paragraph boundary.
Runs wrapped in w:ins / w:del are not visible through
python-docx's paragraph.runs (its CT_P descriptor only sees direct
w:r children); read them back with
:func:~docx_plus.revisions.read_revisions.
This module imports only from docx_plus.core and the sibling
docx_plus.revisions.registry (SPEC §9.1).
RevisionRef
dataclass
¶
Handle for an authored revision.
Attributes:
| Name | Type | Description |
|---|---|---|
revision_id |
int
|
The |
body_element |
_Element
|
The |
RevisionNotFoundError ¶
Bases: DocxPlusError, KeyError
Raised when no revision element with the requested w:id exists.
Subclasses :class:KeyError so existing except KeyError: clauses
still catch it; also :class:DocxPlusError per SPEC §9.7.
mark_insertion ¶
mark_insertion(
target: RevisionTarget,
*,
author: str = "",
date: datetime | None = None,
id_registry: RevisionIdRegistry | None = None,
) -> RevisionRef
Mark existing run(s) as a tracked insertion.
Wraps the target run(s) in <w:ins w:id w:author w:date>. The run
content (including each <w:t>) is preserved unchanged; only the
wrapping container is added.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
RevisionTarget
|
Where the insertion applies.
|
required |
author
|
str
|
Author recorded in |
''
|
date
|
datetime | None
|
Timestamp recorded in |
None
|
id_registry
|
RevisionIdRegistry | None
|
Pre-existing registry to share across an editing
session. A fresh :class: |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
RevisionRef
|
class: |
RevisionRef
|
element. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a paragraph target has no runs, or a range is reversed or spans more than one paragraph. |
TypeError
|
If |
Example
from docx import Document from docx_plus.revisions import mark_insertion doc = Document() p = doc.add_paragraph() run = p.add_run("freshly added") ref = mark_insertion(run, author="Reviewer")
Source code in docx_plus/revisions/mark.py
mark_deletion ¶
mark_deletion(
target: RevisionTarget,
*,
author: str = "",
date: datetime | None = None,
id_registry: RevisionIdRegistry | None = None,
) -> RevisionRef
Mark existing run(s) as a tracked deletion.
Wraps the target run(s) in <w:del w:id w:author w:date> and retags
every <w:t> in the span to <w:delText> (the OOXML element for
deleted run text). Word renders the span struck-through; accepting the
deletion removes it, rejecting it restores live <w:t>.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
RevisionTarget
|
Where the deletion applies — same shapes as
:func: |
required |
author
|
str
|
Author recorded in |
''
|
date
|
datetime | None
|
Timestamp recorded in |
None
|
id_registry
|
RevisionIdRegistry | None
|
Pre-existing registry to share across an editing
session. A fresh :class: |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
RevisionRef
|
class: |
RevisionRef
|
element. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a paragraph target has no runs, or a range is reversed or spans more than one paragraph. |
TypeError
|
If |