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.