Cross-references and cards¶
The [[…]] marker¶
Three written forms are accepted:
[[7|Febrile seizures]] article 7, shown as "Febrile seizures"
[[7#workup|the workup]] article 7, jumping to the section slugged "workup"
[[febrile-seizures]] legacy slug form, label taken from the slug
The id form is preferred because an id survives a rename. The slug form is rewritten to the id form on save, never in a bulk migration — rewriting prose nobody asked to change is how you lose an author's trust.
A section anchor only decides where the reader lands. A renamed or deleted section degrades to the top of the article rather than becoming a broken link.
Automatic linking¶
link_cross_references() runs on save of a published article and on
publish — never on a draft — and is idempotent: it seeds its "already seen"
set from the markers already in the text.
What it will not touch:
- anything past the first mention of a term in a section
- more than 6 links in one section
- a partial word — matches are at word boundaries
- code spans, existing links, existing markers, headings, image alt text, and table rows (a pipe inside a cell breaks the table)
- anything on the stop list
- titles under 4 characters
The manual counterpart is a two-step moderator tool:
GET /articles/{id}/crosslinks returns proposals and writes nothing;
POST /articles/{id}/crosslinks applies an approved subset, re-matching each
proposal's offset at write time so nothing lands in text that has since moved.
It is willing to match a short abbreviation — "CF", "TB" — where autolink is
not, on a case-sensitive match.
The editorial rule¶
An article may link its own subject. This was tried the other way and reverted. One link per target per section; never inside a table row. Drug names have no target library yet. The full note is Linking and cards.
Hover previews¶
Deliberately small: id, slug, title, a plain-text excerpt of up to 260
characters with markup, markers and images stripped, the section count and the
status. It 404s for a non-moderator on an unpublished article.
The front end fetches it after a 350 ms hover and caches it per slug for the life of the page; on a touch device the card opens on tap instead of following the link.
GET /articles/link-targets?q= is a different endpoint for a different job —
the editor's picker when writing a new marker. It needs sections and a
title-first ranked match, not a definition excerpt.
The glossary¶
A shared definition for a term, written inline in any article, stem, explanation or option:
{{hyperoxia test}} the shared definition for this term
{{ductal-dependent|…}} a one-off inline explanation, not shared
{{|…|caution}} a trailing chip tied to no particular word
A GlossaryTerm has a lookup key, a display term, a definition of at
most 400 characters, a kind of define, fact, why or caution, an
optional article_id for "read more", and a source.
400 characters is about four sentences — where an explanation stops being an aside and starts being an article nobody has written yet.
A term with no entry renders as plain prose rather than an error, so the entry and the prose that references it can land in either order.
| Endpoint | Gate |
|---|---|
GET /glossary?q= , GET /glossary/{key} |
any signed-in user |
POST /glossary (upsert by key) |
moderator |
POST /glossary/bulk (up to 200, all-or-nothing) |
moderator |
DELETE /glossary/{key} |
moderator |
The link checker¶
Exits non-zero if it finds anything. It reports:
| Bucket | Catches |
|---|---|
markers |
A [[…]] pointing at a missing article, at an unpublished article from a published one, or at a redirect or old slug rather than the live article |
key_points |
A question key point citing an article that is gone |
section_links |
A question ↔ article link naming a section that no longer exists |
| one per pointer table | Rows in question_article_links, study_plan_block_articles, flashcard_article_links, user_collection_articles and article_exam_links whose article is not among the living |
It is stricter than the reader on purpose: a redirect still counts as broken, because library policy is to point at what is there.