/** * @import { * Construct, * Exiter, * State, * TokenizeContext, * Tokenizer * } from 'micromark-util-types' */ import { factorySpace } from 'micromark-factory-space'; import { markdownSpace } from 'micromark-util-character'; /** @type {Construct} */ export const blockQuote = { continuation: { tokenize: tokenizeBlockQuoteContinuation }, exit, name: 'blockQuote', tokenize: tokenizeBlockQuoteStart }; /** * @this {TokenizeContext} * Context. * @type {Tokenizer} */ function tokenizeBlockQuoteStart(effects, ok, nok) { const self = this; return start; /** * Start of block quote. * * ```markdown * > | > a * ^ * ``` * * @type {State} */ function start(code) { if (code === 62) { const state = self.containerState; if (!state.open) { effects.enter("blockQuote", { _container: true }); state.open = true; } effects.enter("blockQuotePrefix"); effects.enter("blockQuoteMarker"); effects.consume(code); effects.exit("blockQuoteMarker"); return after; } return nok(code); } /** * After `>`, before optional whitespace. * * ```markdown * > | > a * ^ * ``` * * @type {State} */ function after(code) { if (markdownSpace(code)) { effects.enter("blockQuotePrefixWhitespace"); effects.consume(code); effects.exit("blockQuotePrefixWhitespace"); effects.exit("blockQuotePrefix"); return ok; } effects.exit("blockQuotePrefix"); return ok(code); } } /** * Start of block quote continuation. * * ```markdown * | > a * > | > b * ^ * ``` * * @this {TokenizeContext} * Context. * @type {Tokenizer} */ function tokenizeBlockQuoteContinuation(effects, ok, nok) { const self = this; return contStart; /** * Start of block quote continuation. * * Also used to parse the first block quote opening. * * ```markdown * | > a * > | > b * ^ * ``` * * @type {State} */ function contStart(code) { if (markdownSpace(code)) { // Always populated by defaults. return factorySpace(effects, contBefore, "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code); } return contBefore(code); } /** * At `>`, after optional whitespace. * * Also used to parse the first block quote opening. * * ```markdown * | > a * > | > b * ^ * ``` * * @type {State} */ function contBefore(code) { return effects.attempt(blockQuote, ok, nok)(code); } } /** @type {Exiter} */ function exit(effects) { effects.exit("blockQuote"); }