| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /**
- * @import {Effects, State, TokenType} from 'micromark-util-types'
- */
- 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.
- */
- 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);
- }
- }
|