/** * @typedef {import('micromark-util-types').Construct} Construct * @typedef {import('micromark-util-types').Tokenizer} Tokenizer * @typedef {import('micromark-util-types').Exiter} Exiter * @typedef {import('micromark-util-types').State} State */ import {ok as assert} from 'uvu/assert' import {factorySpace} from 'micromark-factory-space' import {markdownSpace} from 'micromark-util-character' import {codes} from 'micromark-util-symbol/codes.js' import {constants} from 'micromark-util-symbol/constants.js' import {types} from 'micromark-util-symbol/types.js' /** @type {Construct} */ export const blockQuote = { name: 'blockQuote', tokenize: tokenizeBlockQuoteStart, continuation: {tokenize: tokenizeBlockQuoteContinuation}, exit } /** @type {Tokenizer} */ function tokenizeBlockQuoteStart(effects, ok, nok) { const self = this return start /** @type {State} */ function start(code) { if (code === codes.greaterThan) { const state = self.containerState assert(state, 'expected `containerState` to be defined in container') if (!state.open) { effects.enter(types.blockQuote, {_container: true}) state.open = true } effects.enter(types.blockQuotePrefix) effects.enter(types.blockQuoteMarker) effects.consume(code) effects.exit(types.blockQuoteMarker) return after } return nok(code) } /** @type {State} */ function after(code) { if (markdownSpace(code)) { effects.enter(types.blockQuotePrefixWhitespace) effects.consume(code) effects.exit(types.blockQuotePrefixWhitespace) effects.exit(types.blockQuotePrefix) return ok } effects.exit(types.blockQuotePrefix) return ok(code) } } /** @type {Tokenizer} */ function tokenizeBlockQuoteContinuation(effects, ok, nok) { return factorySpace( effects, effects.attempt(blockQuote, ok, nok), types.linePrefix, this.parser.constructs.disable.null.includes('codeIndented') ? undefined : constants.tabSize ) } /** @type {Exiter} */ function exit(effects) { effects.exit(types.blockQuote) }