import { parseFenceSpans, type FenceSpan } from "./fences.js" ;
export type InlineCodeState = {
open: boolean ;
ticks: number;
};
export function createInlineCodeState(): InlineCodeState {
return { open: false , ticks: 0 };
}
type InlineCodeSpansResult = {
spans: Array<[number, number]>;
state: InlineCodeState;
};
export type CodeSpanIndex = {
inlineState: InlineCodeState;
isInside: (index: number) => boolean ;
};
export function buildCodeSpanIndex(text: string, inlineState?: InlineCodeState): CodeSpanIndex {
const fenceSpans = parseFenceSpans(text);
const startState = inlineState
? { open: inlineState.open, ticks: inlineState.ticks }
: createInlineCodeState();
const { spans: inlineSpans, state: nextInlineState } = parseInlineCodeSpans(
text,
fenceSpans,
startState,
);
return {
inlineState: nextInlineState,
isInside: (index: number) =>
isInsideFenceSpan(index, fenceSpans) || isInsideInlineSpan(index, inlineSpans),
};
}
function parseInlineCodeSpans(
text: string,
fenceSpans: FenceSpan[],
initialState: InlineCodeState,
): InlineCodeSpansResult {
const spans: Array<[number, number]> = [];
let open = initialState.open;
let ticks = initialState.ticks;
let openStart = open ? 0 : -1 ;
let i = 0 ;
while (i < text.length) {
const fence = findFenceSpanAtInclusive(fenceSpans, i);
if (fence) {
i = fence.end;
continue ;
}
if (text[i] !== "`" ) {
i += 1 ;
continue ;
}
const runStart = i;
let runLength = 0 ;
while (i < text.length && text[i] === "`" ) {
runLength += 1 ;
i += 1 ;
}
if (!open) {
open = true ;
ticks = runLength;
openStart = runStart;
continue ;
}
if (runLength === ticks) {
spans.push([openStart, i]);
open = false ;
ticks = 0 ;
openStart = -1 ;
}
}
if (open) {
spans.push([openStart, text.length]);
}
return {
spans,
state: { open, ticks },
};
}
function findFenceSpanAtInclusive(spans: FenceSpan[], index: number): FenceSpan | undefined {
return spans.find((span) => index >= span.start && index < span.end);
}
function isInsideFenceSpan(index: number, spans: FenceSpan[]): boolean {
return spans.some((span) => index >= span.start && index < span.end);
}
function isInsideInlineSpan(index: number, spans: Array<[number, number]>): boolean {
return spans.some(([start, end]) => index >= start && index < end);
}
Messung V0.5 in Prozent C=100 H=89 G=94
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland