MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-2616

The docs renderer prints backticks literally when `code` sits inside **bold** — `renderInline` is a flat split, so the bold arm emits its own contents as raw text

Done
Description

Repo: motir-core. One PR. Found while running MOTIR-2608, whose sub-step 2 opens with a bold run wrapping the code span `.devcontainer/devcontainer.json` — and renders, in the shipped production build, with the backticks visibly on screen. Not caused by that card's diff: the construct is on origin/main unchanged, and 2608's change neither introduced nor can fix it.

The cause

app/(public)/docs/_components/DocBlocks.tsxrenderInline:

text.split(/(\*\*[^*]+\*\*|`[^`]+`)/g).map((part, index) => {
  if (part.startsWith('**') && part.endsWith('**')) {
    return <strong …>{part.slice(2, -2)}</strong>;   // ← raw text, never re-scanned
  }
  …
});

The split is FLAT and one level deep. A bold run is matched whole, and its contents are emitted as a raw string child of <strong> — so any backtick inside it is never seen by the code arm. The mirror case is different and correct: a code span containing ** SHOULD print the asterisks, because code is literal — which is why the fix belongs in the bold arm only.

[^*]+ also means the two marks cannot interleave at all, so the failure is not confined to bold-wrapping-code — a bold run that merely contains a backtick pair splits at the wrong boundary, and the rendered emphasis then covers the wrong words.

The sites, on origin/main (2026-08-10)

Five, in three modules, found with:

grep -rno '\*\*[^*]*`[^`]*`[^*]*\*\*' lib/apiDocs/*.ts
sitewhat a reader sees
lib/apiDocs/sandbox.ts:250the --rm warning — backticks printed
lib/apiDocs/sandbox.ts:273sub-step 2's filename — backticks printed
lib/apiDocs/sandbox.ts:293a bold run split mid-sentence around two code spans
lib/apiDocs/cli.ts:226same shape, around .motir.json
lib/apiDocs/guide.ts:189same shape, around totalCount

That is a reading from 2026-08-10 and it will drift — re-run the grep rather than trusting the table, and fix every site it returns.

Do this

  1. Make renderInline recursive on the bold arm: feed part.slice(2, -2) back through renderInline instead of emitting it as a raw string, so a code span inside bold becomes a <code> inside the <strong>. Leave the code arm literal.
  2. Widen the split so the two marks can interleave — the [^*]+ inside the bold alternative is what forces a whole run to be asterisk-free, and it is the cause of the mid-sentence split at sandbox.ts:293.
  3. Do NOT reach for a Markdown library. DocBlocks.tsx's own header records why this renderer exists (two marks, in a document set we author ourselves); this is a bug in that renderer, not a case for replacing it.

Acceptance criteria

  1. A prose block whose text is a bold run wrapping a code span renders a <strong> containing a <code>, with no backtick and no asterisk in the rendered text — asserted by a component test that reads the rendered DOM, not the source string.
  2. The mirror holds: a code span containing ** still renders the asterisks literally. The test asserts BOTH directions, so the fix cannot degenerate into "strip every mark everywhere".
  3. Every site the grep above returns renders correctly on the built page, and the fix is in the renderer — no authored string in lib/apiDocs/*.ts is edited to route around it.
  4. renderInlineMarks — the exported sibling renderInline backs, used by callers laying out their own paragraph — inherits the fix rather than getting a second copy.
  5. app/**/docs/** per-file coverage floors stay green, and every existing api-docs test still passes.

Out of scope

The authored copy. Nothing in lib/apiDocs/*.ts should be rewritten to dodge the renderer — a page whose bold cannot contain a filename is the defect being fixed.