Body hashtags ARE the tag system (boss call, 2026-07-28): writers type
#elixir inline and the post's tags derive from the text on save —
there is no separate tags field. The public side is unchanged (tag
archives, feeds, chips); only the source of truth moved into the prose.
What counts as a hashtag
# followed immediately by a letter, at the start of a line or after
whitespace/(. That rule excludes, by construction:
- Markdown headings (
# Title— the space after#breaks the match); - URL fragments (
…/page#section— no preceding whitespace); - code (fenced blocks and inline backticks are stripped before scanning, mirroring the Renderer's component-scan mask);
- Markdown links/images (
[jump](#section)is an anchor, and a tag inside link text would nest links).
Letters are Unicode (#uudised and #новости tag fine); digits,
underscore and hyphen may follow. Dedup is case-insensitive keeping the
first spelling; capped at 20 per document (the old input's cap).
Summary
Functions
All hashtags in a document, first-spelling-wins, order-preserving.
The tag set for a whole version: the union of hashtags across every language's content (per-language bodies may tag differently; the version carries one combined list, same storage as before).
Rewrites every hashtag into a Markdown link ([#tag](url_fun.(tag))),
leaving code regions and existing Markdown links untouched — the
renderer runs this before the Markdown pass so the links pick up the
prose link styling.
Tags already used in a group, for the editor's # autocomplete: the
distinct tags across the group's posts, ranked prefix-match first, then by
how often they're used, then alphabetically.
Functions
All hashtags in a document, first-spelling-wins, order-preserving.
The tag set for a whole version: the union of hashtags across every language's content (per-language bodies may tag differently; the version carries one combined list, same storage as before).
Rewrites every hashtag into a Markdown link ([#tag](url_fun.(tag))),
leaving code regions and existing Markdown links untouched — the
renderer runs this before the Markdown pass so the links pick up the
prose link styling.
Tags already used in a group, for the editor's # autocomplete: the
distinct tags across the group's posts, ranked prefix-match first, then by
how often they're used, then alphabetically.
Reads the listing cache (which already carries each post's tags), so typing
a # costs no database round trip. Returns
[%{tag: "elixir", count: 12}], capped by :limit.