← Back to Workflow
Internal

Legal V2 Diff

Python script that compares a V1 master summary to a V2 master summary and produces a highlighted copy of V2 where all added/changed text is bolded.

"""
Legal V2 Diff Highlighter

Compares a V1 master summary to a V2 master summary and produces
a highlighted copy of V2 where all added/changed text is bolded.

Usage:
    python legal_v2_diff.py <v1_path> <v2_path> [output_path]

If output_path is omitted, saves as <v2_filename>_highlighted.md
alongside the V2 file.

Requires: pip install diff-match-patch
"""

import sys
import os
from diff_match_patch import diff_match_patch


def highlight_changes(v1_path, v2_path, output_path=None):
    with open(v1_path, "r", encoding="utf-8") as f:
        v1_text = f.read()
    with open(v2_path, "r", encoding="utf-8") as f:
        v2_text = f.read()

    dmp = diff_match_patch()
    dmp.Diff_Timeout = 0  # No timeout — maximum diff accuracy
    diffs = dmp.diff_main(v1_text, v2_text)
    dmp.diff_cleanupSemantic(diffs)

    result = []
    for op, text in diffs:
        if op == 0:  # Unchanged
            result.append(text)
        elif op == 1:  # Added in V2
            # Strip leading/trailing whitespace from bold markers
            # so we don't bold blank lines or indentation
            stripped = text.strip()
            if stripped:
                leading = text[: len(text) - len(text.lstrip())]
                trailing = text[len(text.rstrip()) :]
                result.append(f"{leading}**{stripped}**{trailing}")
            else:
                result.append(text)
        # op == -1: Deleted from V1 — not in V2, nothing to show

    output = "".join(result)

    if output_path is None:
        base, ext = os.path.splitext(v2_path)
        output_path = f"{base}_highlighted{ext}"

    with open(output_path, "w", encoding="utf-8") as f:
        f.write(output)

    print(f"Highlighted diff saved to: {output_path}")


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python legal_v2_diff.py <v1_path> <v2_path> [output_path]")
        sys.exit(1)

    v1 = sys.argv[1]
    v2 = sys.argv[2]
    out = sys.argv[3] if len(sys.argv) > 3 else None
    highlight_changes(v1, v2, out)

This is used in: