| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /**
- * @import {
- * Code,
- * Effects,
- * State,
- * TokenType
- * } from 'micromark-util-types'
- */
- import { factorySpace } from 'micromark-factory-space';
- import { markdownLineEnding } from 'micromark-util-character';
- /**
- * Parse titles.
- *
- * ###### Examples
- *
- * ```markdown
- * "a"
- * 'b'
- * (c)
- * "a
- * b"
- * 'a
- * b'
- * (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 of the whole title (`"a"`, `'b'`, `(c)`).
- * @param {TokenType} markerType
- * Type for the markers (`"`, `'`, `(`, and `)`).
- * @param {TokenType} stringType
- * Type for the value (`a`).
- * @returns {State}
- * Start state.
- */
- export function factoryTitle(effects, ok, nok, type, markerType, stringType) {
- /** @type {NonNullable<Code>} */
- let marker;
- return start;
- /**
- * Start of title.
- *
- * ```markdown
- * > | "a"
- * ^
- * ```
- *
- * @type {State}
- */
- function start(code) {
- if (code === 34 || code === 39 || code === 40) {
- effects.enter(type);
- effects.enter(markerType);
- effects.consume(code);
- effects.exit(markerType);
- marker = code === 40 ? 41 : code;
- return begin;
- }
- return nok(code);
- }
- /**
- * After opening marker.
- *
- * This is also used at the closing marker.
- *
- * ```markdown
- * > | "a"
- * ^
- * ```
- *
- * @type {State}
- */
- function begin(code) {
- if (code === marker) {
- effects.enter(markerType);
- effects.consume(code);
- effects.exit(markerType);
- effects.exit(type);
- return ok;
- }
- effects.enter(stringType);
- return atBreak(code);
- }
- /**
- * At something, before something else.
- *
- * ```markdown
- * > | "a"
- * ^
- * ```
- *
- * @type {State}
- */
- function atBreak(code) {
- if (code === marker) {
- effects.exit(stringType);
- return begin(marker);
- }
- if (code === null) {
- return nok(code);
- }
- // Note: blank lines can’t exist in content.
- if (markdownLineEnding(code)) {
- // To do: use `space_or_tab_eol_with_options`, connect.
- effects.enter("lineEnding");
- effects.consume(code);
- effects.exit("lineEnding");
- return factorySpace(effects, atBreak, "linePrefix");
- }
- effects.enter("chunkString", {
- contentType: "string"
- });
- return inside(code);
- }
- /**
- *
- *
- * @type {State}
- */
- function inside(code) {
- if (code === marker || code === null || markdownLineEnding(code)) {
- effects.exit("chunkString");
- return atBreak(code);
- }
- effects.consume(code);
- return code === 92 ? escape : inside;
- }
- /**
- * After `\`, at a special character.
- *
- * ```markdown
- * > | "a\*b"
- * ^
- * ```
- *
- * @type {State}
- */
- function escape(code) {
- if (code === marker || code === 92) {
- effects.consume(code);
- return inside;
- }
- return inside(code);
- }
- }
|