Every example, run live
26 examples covering every option in the library. Each one is
executed when you open it, and the .docx
it writes is rendered below it โ insertions, deletions, moves, formatting
revisions and comments, straight from the OOXML.
Layer 1 ยท Redliner
Targeted, scripted edits: you know the paragraph.
Four edits, one save. Everything else in this folder is a variation on this.
Redliner(source, author="Redline", initials=None, date=None, track_changes=True, scope=("body", "headers", "footers", "notes"))
find_paragraphs(contains, regex, style, startswith, ignore_case, include_tables) find_paragraph(...) exactly one, or raises find_text(needle, regex, ignore_case, limit) text_of(paragraph) the view every other method uses
insert_text(paragraph, offset, text) insert_text_before(needle, text, **kw) insert_text_after(needle, text, **kw) append_text(paragraph, text) delete_text(paragraph, start, end) delete_matching(needle, regex=False, ignore_case=False, count=None)
replace_text(old, new, regex=False, ignore_case=False, count=1, insertion_first=False) set_paragraph_text(paragraph, new_text, ignore_case=False)
insert_paragraph_before/after(reference, text="", style=None, copy_format=True) append_paragraph(text, style=None) delete_paragraph(paragraph) delete_paragraphs(paragraphs) move_paragraph(paragraph, after) relocate_paragraph(source, after=None, before=None) apply_style(paragraph, name)
tables() insert_table_row(table, index=None, values=None) delete_table_row(table, index) delete_row(row) set_cell_text(cell, new_text)
format_runs(runs, **props) format_matching(needle, regex=False, count=None, **props) format_paragraph_text(paragraph, **props) format_paragraph(paragraph, **props)
add_comment(paragraph, text, runs=None, author=None, initials=None)
summary() -> RevisionSummary accept_all() / reject_all() -> Redliner accept_file(src, out) / reject_file(src, out) summarize(root, part=...) the module-level form
Layer 2 ยท ParagraphIndex
Stable paragraph ids and quoted spans, verified before anything is written.
ParagraphIndex(rl, include_tables=True) len / iter / index[pid] -> ParagraphRef .clauses .paragraph(pid) .find(needle, ignore_case) .render(para_ids, with_clause_labels, skip_empty) .manifest() .fingerprint() .locate(...) .apply(...) .refresh()
RedlineEdit(para_id, target, replacement="", rationale="", agent="", severity="medium", occurrence=1, insertion_first=False) ReviewNote(para_id, target, body, agent="", severity="medium", occurrence=1)
Nothing is written until every item has been located, so a plan that is half wrong cannot leave the document half edited by the time it is found out.
Every mapping is exactly one character to one character. That is what makes an offset computed on the folded string valid on the raw string it came from, and it is the whole reason offsets can be handed straight to the edit primitives.
fingerprint(source) a ParagraphIndex, a Redliner, or a path verify_plan(source, plan_fingerprint) -> the current fingerprint, or raises
validate_edits(payload) -> list[str] schema only, no document access load_edits(payload, strict=True) -> list[RedlineEdit | ReviewNote]
Layer 3 ยท Action items
A model restructures the document; numbering and references follow.
validate_actions(items) -> list[str] schema only apply_actions(rl, items, renumber=True, strict=False, explain=False) ActionPlanner(rl, renumber=True, strict=False, explain=False).run(items)
Each block applies exactly one action to a clean document and prints what the planner did with it -- including the consequences it derived on its own.
Contracts number their clauses in the body text, so a structural change is never one edit. Ask for one move and the planner derives the rest.
EXTRACT -> PROPOSE -> VALIDATE -> COMPARE -> PLAN -> COMMENT -> RENUMBER -> VERIFY -> REPORT
Three reviewers, one interface. This example runs entirely offline: the model-backed ones are constructed and inspected, never called, so no API key is needed to read it.
Other surfaces
Compare, op plans, structure, the CLI, errors.
validate(operations) -> list[str] apply_operations(rl, operations, strict=True) -> list[OpResult]
redline_files(original, revised, output, **kwargs) -> CompareStats compare_documents(original, revised, author="Compare", date=None, track_changes=True, similarity_floor=0.45) -> (Redliner, CompareStats)
ClauseTree(body) Clause parse_clause(p) iter_references(text) outline(tree, body_chars=240) render_outline(tree, body_chars=400, clauses=None) detect_strategy(body, tree=None) iter_blocks(body, tree=None) render_document(body, tree=None) segment_document(body, budget_tokens=25_000, strategy="auto", tree=None)
docx-redline {full,pipeline,compare,apply,accept,reject,summary,validate,doctor}
RedlineError base: an edit could not be located or applied ClauseError a clause number could not be resolved StalePlanError a plan was computed against a different version RedlineCredentialsError a model-backed reviewer has no API key