/**
* Research notes travel to Zotero as HTML: the note field is HTML, Zotero
* performs no format conversion on writes, and markdown text stored verbatim
* renders as raw markup (the failure mode community integrations hit). The
* plugin therefore converts the model's markdown itself, under a restricted
* grammar with one absolute rule: anything the grammar does not recognize is
* HTML-escaped and shown as literal text. There is no raw-HTML passthrough,
* no attribute inventing, and no scheme outside `https://`, `http://` and
* `zotero://` can become a link, so a hostile or merely confused model
* output degrades to visible text, never to markup.
*
* The grammar (documented for users in `docs/tools.md`):
* - paragraphs: blank-line separated; soft-wrapped lines join with spaces;
* - headings: ATX `#`–`####`; five or more hashes stay literal text;
* - emphasis: `**bold**` and `*italic*`; `_underscore_` stays literal so
* identifiers like `max_export_refs` survive research notes;
* - highlights: `==highlight==` mapped to ``;
* - math: `$$` blocks mapped to `` and `$math$` spans mapped to
* `` for native Zotero 7+ KaTeX rendering;
* - code: `` `spans` `` and ``` fenced blocks; no formatting inside;
* - links: `[text](url)` with `https://`, `http://` or `zotero://` URLs;
* other schemes render as literal text;
* - lists: `-`/`*` bullets and `1.`/`1)` numbers, one nesting level;
* task list items `- [ ]` / `- [x]` map to `