/** * @typedef {import('micromark-util-types').Construct} Construct * @typedef {import('micromark-util-types').Tokenizer} Tokenizer * @typedef {import('micromark-util-types').State} State * @typedef {import('micromark-util-types').Code} Code */ import {factorySpace} from 'micromark-factory-space' import {markdownLineEnding, markdownSpace} from 'micromark-util-character' /** @type {Construct} */ export const thematicBreak = { name: 'thematicBreak', tokenize: tokenizeThematicBreak } /** @type {Tokenizer} */ function tokenizeThematicBreak(effects, ok, nok) { let size = 0 /** @type {NonNullable} */ let marker return start /** @type {State} */ function start(code) { effects.enter('thematicBreak') marker = code return atBreak(code) } /** @type {State} */ function atBreak(code) { if (code === marker) { effects.enter('thematicBreakSequence') return sequence(code) } if (markdownSpace(code)) { return factorySpace(effects, atBreak, 'whitespace')(code) } if (size < 3 || (code !== null && !markdownLineEnding(code))) { return nok(code) } effects.exit('thematicBreak') return ok(code) } /** @type {State} */ function sequence(code) { if (code === marker) { effects.consume(code) size++ return sequence } effects.exit('thematicBreakSequence') return atBreak(code) } }