diff --git a/changedetectionio/diff.py b/changedetectionio/diff.py
index 11be4621c..70c3694ec 100644
--- a/changedetectionio/diff.py
+++ b/changedetectionio/diff.py
@@ -45,18 +45,36 @@ def render_inline_word_diff(before_line: str, after_line: str, html_colour: bool
redlines = Redlines(before_normalized, after_normalized or ' ')
diff_output = redlines.output_markdown
+ # Check if the whole line is replaced by testing if all content has changed
+ # A whole line is replaced when there's only removed and added content with no unchanged text
+ whole_line_replaced = False
+
+ # Check if whole line is replaced before transforming
+ removed_matches = list(REDLINES_REMOVED_RE.finditer(diff_output))
+ added_matches = list(REDLINES_ADDED_RE.finditer(diff_output))
+
+ if removed_matches and added_matches:
+ # Calculate total changed content length vs original output length
+ # Remove all the span tags to see what's left
+ temp_output = REDLINES_REMOVED_RE.sub('', diff_output)
+ temp_output = REDLINES_ADDED_RE.sub('', temp_output)
+ # If there's no unchanged content left (only whitespace), it's a whole line replacement
+ whole_line_replaced = temp_output.strip() == ''
+
if html_colour:
# Replace redlines' default styles with our custom inline styles
# Strip trailing spaces from content but preserve them outside the span
def replace_removed(m):
content = m.group(1).rstrip()
trailing = m.group(1)[len(content):] if len(m.group(1)) > len(content) else ''
- return f'{content}{trailing}'
+ line_break = '\n' if whole_line_replaced else ''
+ return f'{content}{trailing}{line_break}'
def replace_added(m):
content = m.group(1).rstrip()
trailing = m.group(1)[len(content):] if len(m.group(1)) > len(content) else ''
- return f'{content}{trailing}'
+ line_break = '\n' if whole_line_replaced else ''
+ return f'{content}{trailing}{line_break}'
diff_output = REDLINES_REMOVED_RE.sub(replace_removed, diff_output)
diff_output = REDLINES_ADDED_RE.sub(replace_added, diff_output)
@@ -70,12 +88,14 @@ def render_inline_word_diff(before_line: str, after_line: str, html_colour: bool
def replace_removed_plain(m):
content = m.group(1).rstrip()
trailing = m.group(1)[len(content):] if len(m.group(1)) > len(content) else ''
- return f'[-{content}-]{trailing}'
+ line_break = '\n' if whole_line_replaced else ''
+ return f'[-{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 ''
- return f'[+{content}+]{trailing}'
+ line_break = '\n' if whole_line_replaced else ''
+ return f'[+{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)