Urara-Blog/node_modules/.pnpm-store/v3/files/68/b632bbb828f97573b273241e5905ae40106daeee0e14da122c6a7605aa04201be55e01837d509043ecbf03dfdabfb155c77631f85782a7c9e9e84416f75b65
2022-08-14 01:14:53 +08:00

159 lines
3.6 KiB
Text

/**
* @typedef {import('micromark-util-types').Construct} Construct
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
* @typedef {import('micromark-util-types').State} State
*/
import {ok as assert} from 'uvu/assert'
import {
asciiAlpha,
asciiAlphanumeric,
asciiAtext,
asciiControl
} 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 autolink = {name: 'autolink', tokenize: tokenizeAutolink}
/** @type {Tokenizer} */
function tokenizeAutolink(effects, ok, nok) {
let size = 1
return start
/** @type {State} */
function start(code) {
assert(code === codes.lessThan, 'expected `<`')
effects.enter(types.autolink)
effects.enter(types.autolinkMarker)
effects.consume(code)
effects.exit(types.autolinkMarker)
effects.enter(types.autolinkProtocol)
return open
}
/** @type {State} */
function open(code) {
if (asciiAlpha(code)) {
effects.consume(code)
return schemeOrEmailAtext
}
return asciiAtext(code) ? emailAtext(code) : nok(code)
}
/** @type {State} */
function schemeOrEmailAtext(code) {
return code === codes.plusSign ||
code === codes.dash ||
code === codes.dot ||
asciiAlphanumeric(code)
? schemeInsideOrEmailAtext(code)
: emailAtext(code)
}
/** @type {State} */
function schemeInsideOrEmailAtext(code) {
if (code === codes.colon) {
effects.consume(code)
return urlInside
}
if (
(code === codes.plusSign ||
code === codes.dash ||
code === codes.dot ||
asciiAlphanumeric(code)) &&
size++ < constants.autolinkSchemeSizeMax
) {
effects.consume(code)
return schemeInsideOrEmailAtext
}
return emailAtext(code)
}
/** @type {State} */
function urlInside(code) {
if (code === codes.greaterThan) {
effects.exit(types.autolinkProtocol)
return end(code)
}
if (
code === codes.eof ||
code === codes.space ||
code === codes.lessThan ||
asciiControl(code)
) {
return nok(code)
}
effects.consume(code)
return urlInside
}
/** @type {State} */
function emailAtext(code) {
if (code === codes.atSign) {
effects.consume(code)
size = 0
return emailAtSignOrDot
}
if (asciiAtext(code)) {
effects.consume(code)
return emailAtext
}
return nok(code)
}
/** @type {State} */
function emailAtSignOrDot(code) {
return asciiAlphanumeric(code) ? emailLabel(code) : nok(code)
}
/** @type {State} */
function emailLabel(code) {
if (code === codes.dot) {
effects.consume(code)
size = 0
return emailAtSignOrDot
}
if (code === codes.greaterThan) {
// Exit, then change the type.
effects.exit(types.autolinkProtocol).type = types.autolinkEmail
return end(code)
}
return emailValue(code)
}
/** @type {State} */
function emailValue(code) {
if (
(code === codes.dash || asciiAlphanumeric(code)) &&
size++ < constants.autolinkDomainSizeMax
) {
effects.consume(code)
return code === codes.dash ? emailValue : emailLabel
}
return nok(code)
}
/** @type {State} */
function end(code) {
assert(code === codes.greaterThan, 'expected `>`')
effects.enter(types.autolinkMarker)
effects.consume(code)
effects.exit(types.autolinkMarker)
effects.exit(types.autolink)
return ok
}
}