123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /**
- * @typedef {import('micromark-util-types').Effects} Effects
- * @typedef {import('micromark-util-types').State} State
- * @typedef {import('micromark-util-types').TokenType} TokenType
- */
- import {
- asciiControl,
- markdownLineEndingOrSpace,
- markdownLineEnding
- } from 'micromark-util-character'
- /**
- * Parse destinations.
- *
- * ###### Examples
- *
- * ```markdown
- * <a>
- * <a\>b>
- * <a b>
- * <a)>
- * a
- * a\)b
- * a(b)c
- * a(b)
- * ```
- *
- * @param {Effects} effects
- * Context.
- * @param {State} ok
- * State switched to when successful.
- * @param {State} nok
- * State switched to when unsuccessful.
- * @param {TokenType} type
- * Type for whole (`<a>` or `b`).
- * @param {TokenType} literalType
- * Type when enclosed (`<a>`).
- * @param {TokenType} literalMarkerType
- * Type for enclosing (`<` and `>`).
- * @param {TokenType} rawType
- * Type when not enclosed (`b`).
- * @param {TokenType} stringType
- * Type for the value (`a` or `b`).
- * @param {number | undefined} [max=Infinity]
- * Depth of nested parens (inclusive).
- * @returns {State}
- * Start state.
- */ // eslint-disable-next-line max-params
- export function factoryDestination(
- effects,
- ok,
- nok,
- type,
- literalType,
- literalMarkerType,
- rawType,
- stringType,
- max
- ) {
- const limit = max || Number.POSITIVE_INFINITY
- let balance = 0
- return start
- /**
- * Start of destination.
- *
- * ```markdown
- * > | <aa>
- * ^
- * > | aa
- * ^
- * ```
- *
- * @type {State}
- */
- function start(code) {
- if (code === 60) {
- effects.enter(type)
- effects.enter(literalType)
- effects.enter(literalMarkerType)
- effects.consume(code)
- effects.exit(literalMarkerType)
- return enclosedBefore
- }
- // ASCII control, space, closing paren.
- if (code === null || code === 32 || code === 41 || asciiControl(code)) {
- return nok(code)
- }
- effects.enter(type)
- effects.enter(rawType)
- effects.enter(stringType)
- effects.enter('chunkString', {
- contentType: 'string'
- })
- return raw(code)
- }
- /**
- * After `<`, at an enclosed destination.
- *
- * ```markdown
- * > | <aa>
- * ^
- * ```
- *
- * @type {State}
- */
- function enclosedBefore(code) {
- if (code === 62) {
- effects.enter(literalMarkerType)
- effects.consume(code)
- effects.exit(literalMarkerType)
- effects.exit(literalType)
- effects.exit(type)
- return ok
- }
- effects.enter(stringType)
- effects.enter('chunkString', {
- contentType: 'string'
- })
- return enclosed(code)
- }
- /**
- * In enclosed destination.
- *
- * ```markdown
- * > | <aa>
- * ^
- * ```
- *
- * @type {State}
- */
- function enclosed(code) {
- if (code === 62) {
- effects.exit('chunkString')
- effects.exit(stringType)
- return enclosedBefore(code)
- }
- if (code === null || code === 60 || markdownLineEnding(code)) {
- return nok(code)
- }
- effects.consume(code)
- return code === 92 ? enclosedEscape : enclosed
- }
- /**
- * After `\`, at a special character.
- *
- * ```markdown
- * > | <a\*a>
- * ^
- * ```
- *
- * @type {State}
- */
- function enclosedEscape(code) {
- if (code === 60 || code === 62 || code === 92) {
- effects.consume(code)
- return enclosed
- }
- return enclosed(code)
- }
- /**
- * In raw destination.
- *
- * ```markdown
- * > | aa
- * ^
- * ```
- *
- * @type {State}
- */
- function raw(code) {
- if (
- !balance &&
- (code === null || code === 41 || markdownLineEndingOrSpace(code))
- ) {
- effects.exit('chunkString')
- effects.exit(stringType)
- effects.exit(rawType)
- effects.exit(type)
- return ok(code)
- }
- if (balance < limit && code === 40) {
- effects.consume(code)
- balance++
- return raw
- }
- if (code === 41) {
- effects.consume(code)
- balance--
- return raw
- }
- // ASCII control (but *not* `\0`) and space and `(`.
- // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it
- // doesn’t.
- if (code === null || code === 32 || code === 40 || asciiControl(code)) {
- return nok(code)
- }
- effects.consume(code)
- return code === 92 ? rawEscape : raw
- }
- /**
- * After `\`, at special character.
- *
- * ```markdown
- * > | a\*a
- * ^
- * ```
- *
- * @type {State}
- */
- function rawEscape(code) {
- if (code === 40 || code === 41 || code === 92) {
- effects.consume(code)
- return raw
- }
- return raw(code)
- }
- }
|