DocumentBodyMigration.h header

#include <ew/app/DocumentBodyMigration.h>

Namespace ew::app

Functions

QString ew::app::bodySignature(const QString &html)

A canonical signature of the rendered rich model of a document body: the visible text plus, for every text run, its character formatting (bold / italic / underline / strikethrough / super-subscript / foreground colour / background colour / font family / font size / link) and, for every block, its block formatting (alignment / heading level / list kind + depth / indent / block-quote). Two bodies with the same signature render identically, regardless of how their HTML is serialized (the editor's QTextDocument::toHtml dialect vs. markdownToHtml's output). This is the yardstick the Markdown migration uses to prove a conversion lost nothing visible. Built by loading html into a headless QTextDocument and walking it, so it works in a non-GUI process.

std::optional< QString > ew::app::migrateBodyToMarkdown(const QString &body)

Attempts to migrate a document body the editor stored as rich-text HTML to the app's Markdown (with the {.ew …} extension), returning the Markdown only when the migration is verified render-lossless — i.e. bodySignature(body) == bodySignature(markdownToHtml(markdown)). Returns std::nullopt when the body is not rich text (already Markdown or plain text — nothing to migrate) or when the round-trip is not provably lossless, in which case the caller keeps the original HTML untouched. This is option (b) of docs/MARKDOWN_EDITING.md's migration gate: it can never silently drop formatting, so it is safe to run on real project bodies without a bulk rewrite.

void ew::app::migrateDocumentBodies(ew::core::Document &document)

Migrates document's bodies to Markdown in place when it is not already tagged BodyFormat::Markdown (i.e. a legacy body loaded with no format tag, or one a previous load could not migrate). The main body is converted via migrateBodyToMarkdown when that is verified lossless (then tagged Markdown); a body that is already plain Markdown/text is tagged Markdown unchanged; a rich-text body that cannot be losslessly migrated is left untouched and tagged Html (so the loss is never silent and a later converter improvement can migrate it on a future load). The document's version and variant bodies are migrated best-effort the same way (they carry no own tag). A document already tagged Markdown is left untouched. Call this after loading a document from disk; the migrated form persists on the next save.