An editor readback can look identical while its bytes differ. In a Whispart publishing run, saved Markdown used LF line endings where the local input used CRLF. Treating that difference as a failed save was noisy. Treating all whitespace as disposable would have been worse: the article contained indented Python.
Whispart develops selected GAN imagery into physical wall art and framed works. The same publishing process carries both visual essays and technical notes. For technical notes, preserving a runnable example is part of delivering the article.
Name the one difference you accept
This comparator accepts CRLF-to-LF conversion. It keeps indentation, tabs, blank lines, trailing spaces and the final newline significant. An isolated carriage return is rejected so an unexpected format cannot quietly enter the comparison.
def canonical_editor_text(value: str) -> str:
# Accept CRLF and LF. Treat an isolated CR as an unexpected format.
if "\r" in value.replace("\r\n", ""):
raise ValueError("Unexpected isolated carriage return")
return value.replace("\r\n", "\n")
def assert_saved(expected: str, saved: str) -> None:
if canonical_editor_text(expected) != canonical_editor_text(saved):
raise AssertionError("Saved Markdown differs from the approved text")
The second replacement is deliberately absent: there is no strip(), whitespace regular expression or split-and-join operation. A broad cleanup can make two different code samples appear equal. Python's string method reference documents the literal replacement used here.
Check the failure you actually care about
expected = "if ready:\n publish()\n"
assert_saved(expected, expected.replace("\n", "\r\n"))
try:
assert_saved(expected, "if ready:\npublish()\n")
except AssertionError:
print("Lost indentation detected")
else:
raise AssertionError("The check hid a meaningful change")
The example is synthetic; it does not publish anything. Locally, nine checks covered accepted CRLF conversion and detected indentation removal, tabs replacing spaces, two-space indentation, a removed final newline, a changed token, an added blank line and an isolated CR. A Unicode line separator was also left unchanged. The comparator itself does not decide whether any of those edits is stylistically desirable. It reports that the saved text differs from the approved text.
Give the final newline its own policy
If a particular editor adds one terminal newline, decide that policy explicitly after observing it. This implementation rejects the difference. Do not call .strip() on both articles just to make the check pass; that would also accept deleted leading indentation and changed trailing spaces throughout the boundary of the text.
Keep the approved local source, read the saved editor value after reopening the same draft, compare under the narrow rule, then inspect the rendered preview. A source comparison cannot prove that a renderer preserved a code block or a link. Likewise, a matching preview cannot prove that the saved editable source will survive the next edit.
The useful output is a small, explainable difference, not an automatic rewrite of whatever the editor returned. For the physical-art work this publishing serves, Whispart's process notes show why a faithful handoff matters beyond the screen.
This article and its examples were written with AI for Whispart. The comparator and nine local checks were executed with Python before publication. No platform API or live publishing call is part of the sample.
Top comments (0)