docx-redline v1.0.2
02

Every Redliner constructor option

Redliner(source, author="Redline", initials=None, date=None, track_changes=True, scope=("body", "headers", "footers", "notes"))

examples/02_redliner_options.py โ€” ran in 0.27s ยท exit 0

Console output

============================================================================
02 ยท Redliner options
============================================================================

--- source: a path, a file object, or an existing Document ---
path     -> 92 paragraphs
file-like-> 92 paragraphs
Document -> 92 paragraphs

--- author / initials โ€” attribution stamped on every revision ---
derived initials: JB
explicit initials: JBQ

--- date โ€” pin it and the output is byte-reproducible ---
same stamp     : True 2026-01-01T00:00:00Z
floating stamp : 2026-...

--- track_changes โ€” also set Word's own toggle in settings.xml ---
track_changes=True  -> <w:trackChanges/> present: True
track_changes=False -> <w:trackChanges/> present: False

--- scope โ€” which stories document-wide operations touch ---
('body',)                                     92 paragraphs in scope
('body', 'headers', 'footers')                92 paragraphs in scope
('body', 'headers', 'footers', 'notes')       92 paragraphs in scope

--- include_tables โ€” table cells are paragraphs too ---
with tables   : 92
without tables: 84

Source

"""02 ยท Every Redliner constructor option.

Redliner(source, author="Redline", initials=None, date=None,
         track_changes=True, scope=("body", "headers", "footers", "notes"))
"""

import docx
from _shared import SOURCE, banner, section

from docx_redline import Redliner

banner("02 ยท Redliner options")

section("source: a path, a file object, or an existing Document")
print("path     ->", len(Redliner(SOURCE).paragraphs()), "paragraphs")
with open(SOURCE, "rb") as handle:
    print("file-like->", len(Redliner(handle).paragraphs()), "paragraphs")
print("Document ->", len(Redliner(docx.Document(SOURCE)).paragraphs()), "paragraphs")

section("author / initials โ€” attribution stamped on every revision")
rl = Redliner(SOURCE, author="Jordan Blake")
rl.replace_text("thirty (30) days", "forty-five (45) days")
print("derived initials:", rl.ctx.author.initials)
rl = Redliner(SOURCE, author="Jordan Blake", initials="JBQ")
print("explicit initials:", rl.ctx.author.initials)

section("date โ€” pin it and the output is byte-reproducible")
one = Redliner(SOURCE, author="A", date="2026-01-01T00:00:00Z")
two = Redliner(SOURCE, author="A", date="2026-01-01T00:00:00Z")
for r in (one, two):
    r.replace_text("thirty (30) days", "forty-five (45) days")
print("same stamp     :", one.ctx.author.date == two.ctx.author.date, one.ctx.author.date)
print("floating stamp :", Redliner(SOURCE).ctx.author.date[:4] + "-...")

section("track_changes โ€” also set Word's own toggle in settings.xml")
for flag in (True, False):
    rl = Redliner(SOURCE, track_changes=flag)
    settings = rl.document.settings.element
    on = settings.find("{http://schemas.openxmlformats.org/wordprocessingml/2006/main}trackChanges")
    print(f"track_changes={flag!s:<5} -> <w:trackChanges/> present: {on is not None}")

section("scope โ€” which stories document-wide operations touch")
# The sample contract has no headers, footers or notes, so every scope sees the
# same 92 body paragraphs. On a document that has them, narrowing the scope is
# what stops a document-wide replace_text rewriting the running header too.
for scope in [("body",), ("body", "headers", "footers"), ("body", "headers", "footers", "notes")]:
    rl = Redliner(SOURCE, scope=scope)
    print(f"{scope!s:<44} {len(rl.paragraphs()):>3} paragraphs in scope")

section("include_tables โ€” table cells are paragraphs too")
rl = Redliner(SOURCE)
print("with tables   :", len(rl.paragraphs(include_tables=True)))
print("without tables:", len(rl.paragraphs(include_tables=False)))

What it wrote

This example prints its result rather than saving a document โ€” read the console output beside it.