revision
revision
¶
Custom element classes for tracked changes (revisions).
A revision is recorded in one of two shapes:
Content revisions wrap the content they affect. w:ins holds runs that were added,
w:del runs that were removed — with their text in w:delText rather than w:t, so a
consumer that does not understand deletions does not show it. w:moveTo and w:moveFrom
are the two halves of a move, and behave as an insertion and a deletion respectively:
<w:ins w:id="1" w:author="Ada" w:date="2026-01-02T10:00:00Z">
<w:r><w:t>added</w:t></w:r>
</w:ins>
<w:del w:id="2" w:author="Ada" w:date="2026-01-02T10:00:00Z">
<w:r><w:delText>removed</w:delText></w:r>
</w:del>
Property revisions record what the formatting used to be: w:rPrChange holds the
previous w:rPr, w:pPrChange the previous w:pPr, and so on. Accepting one means
dropping the record; rejecting it means putting the recorded properties back.
The same w:ins and w:del tag names are also used as empty markers — in w:pPr/w:rPr
they say the paragraph mark itself was inserted or deleted, which is how a paragraph
split or merge is tracked, and in w:trPr they say a table row was. lxml resolves an
element class by tag name alone, so one class serves every position; whether a given
w:ins wraps content is discovered from its children rather than declared.
CT_TrackChange
¶
Bases: BaseOxmlElement
A revision element — w:ins, w:del, w:moveFrom, w:moveTo or a *Change.
Serves every position these tag names appear in, since lxml dispatches on tag name alone. A content revision has run children; a paragraph-mark or table-row marker has none; a property revision has the previous properties element.
date
property
¶
When the revision was made, or None when the document does not say.
None too when the timestamp is not a valid ISO 8601 datetime. Word writes
w:date in that form, but an anonymised document has it stripped or blanked and
that is not a reason to refuse to read the revision.
is_content_revision
property
¶
True when this revision wraps content rather than marking a position.
text
property
¶
The text this revision covers, the empty string when it covers none.
Both w:t and w:delText count: the point of a deletion is the text it removed,
and reporting nothing for it would make the revision useless to read.
run_original_text
¶
run_original_text(r: CT_R) -> str
The text of r as the document read before its revisions.
Differs from CT_R.text only for a run inside a deletion, whose text is in
w:delText and so does not appear in the document as it now reads.
Source code in src/docx/oxml/revision.py
iter_original_run_content
¶
iter_original_run_content(
element: BaseOxmlElement,
) -> Iterator[CT_R | CT_Hyperlink]
Generate the runs of element as the document read before its revisions.
Deletions are descended into and insertions skipped — the opposite of
docx.oxml.sdt.iter_run_content, which generates the document as it now
reads.
Source code in src/docx/oxml/revision.py
iter_revision_elements
¶
iter_revision_elements(
element: BaseOxmlElement,
) -> List[CT_TrackChange]
Every revision element in the subtree of element, in document order.