From 10ff8516e2dd58621cf6e194ff59bc5bf648d5dc Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Mon, 6 Oct 2025 17:00:37 +0200 Subject: [PATCH] Adding custom formats --- changedetectionio/blueprint/ui/views.py | 2 +- changedetectionio/diff.py | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/changedetectionio/blueprint/ui/views.py b/changedetectionio/blueprint/ui/views.py index 6e52eafa..97b7d1ba 100644 --- a/changedetectionio/blueprint/ui/views.py +++ b/changedetectionio/blueprint/ui/views.py @@ -223,7 +223,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMe content = diff.render_diff(from_version_file_contents, to_version_file_contents, include_equal=True, - html_colour=False, + html_colour=True, ignore_junk=datastore.data['settings']['application'].get('ignore_whitespace', False), ) diff --git a/changedetectionio/diff.py b/changedetectionio/diff.py index 59099e81..1324cb99 100644 --- a/changedetectionio/diff.py +++ b/changedetectionio/diff.py @@ -8,8 +8,16 @@ import re REMOVED_STYLE = "background-color: #fadad7; color: #b30000;" ADDED_STYLE = "background-color: #eaf2c2; color: #406619;" +# Diff label text formats (use {content} as placeholder) +DIFF_LABEL_TEXT_ADDED = '(added) {content}' +DIFF_LABEL_TEXT_REMOVED = '(removed) {content}' +DIFF_LABEL_TEXT_CHANGED = '(changed) {content}' +DIFF_LABEL_TEXT_INTO = '(into) {content}' + # Compiled regex patterns for performance WHITESPACE_NORMALIZE_RE = re.compile(r'\s+') + +# Because `redlines` wont let us easily add our own format, so we replace it. REDLINES_REMOVED_RE = re.compile(r"([^<]*)") REDLINES_ADDED_RE = re.compile(r"([^<]*)") @@ -91,15 +99,15 @@ def render_inline_word_diff(before_line: str, after_line: str, html_colour: bool content = m.group(1).rstrip() trailing = m.group(1)[len(content):] if len(m.group(1)) > len(content) else '' line_break = '\n' if whole_line_replaced else '' - prefix = '(changed)' if whole_line_replaced else '(removed)' - return f'{prefix} {content}{trailing}{line_break}' + label = DIFF_LABEL_TEXT_CHANGED if whole_line_replaced else DIFF_LABEL_TEXT_REMOVED + return f'{label.format(content=content)}{trailing}{line_break}' def replace_added_plain(m): content = m.group(1).rstrip() trailing = m.group(1)[len(content):] if len(m.group(1)) > len(content) else '' line_break = '\n' if whole_line_replaced else '' - prefix = '(into)' if whole_line_replaced else '(added)' - return f'{prefix} {content}{trailing}{line_break}' + label = DIFF_LABEL_TEXT_INTO if whole_line_replaced else DIFF_LABEL_TEXT_ADDED + return f'{label.format(content=content)}{trailing}{line_break}' diff_output = REDLINES_REMOVED_RE.sub(replace_removed_plain, diff_output) diff_output = REDLINES_ADDED_RE.sub(replace_added_plain, diff_output) @@ -203,7 +211,7 @@ def customSequenceMatcher( if html_colour: yield [f'{line}' for line in same_slicer(before, alo, ahi)] else: - yield [f"(removed) {line}" for line in same_slicer(before, alo, ahi)] if include_change_type_prefix else same_slicer(before, alo, ahi) + yield [DIFF_LABEL_TEXT_REMOVED.format(content=line) for line in same_slicer(before, alo, ahi)] if include_change_type_prefix else same_slicer(before, alo, ahi) elif include_replaced and tag == 'replace': before_lines = same_slicer(before, alo, ahi) after_lines = same_slicer(after, blo, bhi) @@ -222,13 +230,13 @@ def customSequenceMatcher( yield [f'{line}' for line in before_lines] + \ [f'{line}' for line in after_lines] else: - yield [f"(changed) {line}" for line in before_lines] + \ - [f"(into) {line}" for line in after_lines] if include_change_type_prefix else before_lines + after_lines + yield [DIFF_LABEL_TEXT_CHANGED.format(content=line) for line in before_lines] + \ + [DIFF_LABEL_TEXT_INTO.format(content=line) for line in after_lines] if include_change_type_prefix else before_lines + after_lines elif include_added and tag == 'insert': if html_colour: yield [f'{line}' for line in same_slicer(after, blo, bhi)] else: - yield [f"(added) {line}" for line in same_slicer(after, blo, bhi)] if include_change_type_prefix else same_slicer(after, blo, bhi) + yield [DIFF_LABEL_TEXT_ADDED.format(content=line) for line in same_slicer(after, blo, bhi)] if include_change_type_prefix else same_slicer(after, blo, bhi) def render_diff( previous_version_file_contents: str,