/** * Where markdown is code and where it is prose. * * One primitive, three consumers — the sanitizer, the item-reference linker, and the * marker scanner. They have to agree: if the sanitizer defuses something the marker * scanner still sees as a comment, the projection refuses runs for a hazard that is no * longer there; if they disagree the other way, a quoted marker injects itself into an * issue. Agreement is cheap to state as a shared function and expensive to maintain as a * convention across three regexes. * * Measured on this project's roadmap (76 items, 451,503 characters of body text) on * 2026-09-07: 40 of the 41 hazard spans a naive sanitizer would rewrite are **inside * code** — `@clack/prompts`, `actions/checkout@v4`, CSS colour hexes such as `#0891b2` * that a `#123` pattern also matches, and one HTML comment. Exactly one is in prose. So * code-awareness is not a refinement of the sanitizer; it is the difference between * corrupting 40 spans and defusing 1. * * The inline-code pattern here is deliberately stronger than the prior art in * `packages/website/scripts/blog/mdx-escape.mjs`, whose `` /(`[^`\n]*`)/ `` recognises * single-backtick spans only. Two of the figures above were wrong under that weaker * pattern: it read a prose `#17` as code, and it could not see that all 32 item-id * references are code spans. Tightening the pattern is the reason this module exists * rather than a detail of it — which is also why `mdx-escape.mjs` is left alone: it * escapes for a different dialect, in a different package, and widening it would be a * change to the blog pipeline nobody asked for. * * Requirements: richer-issue-bodies/AC-8 * * @module */ /** One inline code span, with its bounds in the source and its content between the ticks. */ export interface CodeSpan { /** Index of the first backtick. */ start: number; /** Index one past the last backtick. */ end: number; /** Text between the backtick runs, unmodified. */ content: string; /** How many backticks delimit it, so a rewrite can re-wrap with the same number. */ ticks: number; } /** * A byte per character: 1 inside a fenced block or an inline code span, 0 in prose. * * Fence opener and closer lines are themselves marked as code. That is deliberate: an * info string such as ```` ```ts ```` is not prose, and a rule that rewrote it would * change what language a block claims to be. * * Linear in the length of the text: one pass over lines, and one regex walk per prose * line. */ export declare function codeMask(text: string): Uint8Array; /** * Every inline code span outside a fenced block, in order of appearance. * * Spans *inside* a fence are not returned: their backticks are literal text there, and a * caller rewriting one would be editing the contents of a code block. */ export declare function inlineCodeSpans(text: string): CodeSpan[]; /** * Rewrite the prose runs of a document, copying every code run byte-identical. * * `fn` is called once per maximal prose run. It may return text of any length — offsets * are not preserved across the call, which is why the mask is computed once up front * rather than consulted per match. */ export declare function mapProse(text: string, fn: (prose: string) => string): string; /** * The last index at or before `limit` where a line break sits in **prose**. * * Used to choose a truncation point. A blank line inside a fenced block is masked as * code, so restricting the cut to an unmasked newline is what stops truncation leaving a * fence open — a body ending mid-fence renders the rest of the issue as one code block. * * Returns -1 when no such position exists, which the caller must treat as "cannot * truncate safely" rather than as position 0. */ export declare function lastProseBreakBefore(text: string, limit: number): number; //# sourceMappingURL=markdown.d.ts.map