UNPKG

@marc-r2/micromark-extension-ofm-highlight

Version:

micromark extension to support OFM highlights

93 lines (92 loc) 2.77 kB
// ASCII Codes const TAB = 9; const SPACE = 32; const EQUALS = 61; /** * Create an extension for `micromark` to enable OFM highlight syntax. * Highlights use ==text== syntax where the number of equal signs must match. */ export function ofmHighlight() { return { text: { [EQUALS]: { name: "ofmHighlight", tokenize: tokenize, }, }, }; } /** * A tokenizer for Obsidian highlight syntax. * Highlights use ==text== syntax where the number of equal signs matters. */ function tokenize(effects, ok, nok) { let openingMarkerSize = 0; let closingMarkerSize = 0; return start; function start(code) { if (code !== EQUALS) { return nok(code); } effects.enter("ofmHighlight"); effects.enter("ofmHighlightMarker"); effects.consume(code); openingMarkerSize = 1; return openingMarker; } function openingMarker(code) { if (code === EQUALS) { effects.consume(code); openingMarkerSize++; return openingMarker; } if (openingMarkerSize < 2) { return nok(code); } effects.exit("ofmHighlightMarker"); effects.enter("ofmHighlightContent"); if (code === SPACE || code === null) { return nok(code); } effects.consume(code); return content; } function content(code) { if (code === null) { effects.exit("ofmHighlightContent"); effects.exit("ofmHighlight"); return ok(code); } if (code === TAB) { return nok(code); } if (code === EQUALS) { // Start potential closing marker detection effects.exit("ofmHighlightContent"); effects.enter("ofmHighlightMarker"); effects.consume(code); closingMarkerSize = 1; return closingMarker; } effects.consume(code); return content; } function closingMarker(code) { if (code === EQUALS) { effects.consume(code); closingMarkerSize++; return closingMarker; } if (closingMarkerSize >= 2) { effects.exit("ofmHighlightMarker"); effects.exit("ofmHighlight"); return ok(code); } // Single equals - not a valid closing marker // Exit the marker and continue as content, but consume the single = as content effects.exit("ofmHighlightMarker"); effects.enter("ofmHighlightContent"); // The single = was already consumed in the marker, it will be processed by mdast utility return content(code); } }