Urara-Blog/node_modules/.pnpm-store/v3/files/1e/a9ff9a0a2fd09e1e4913bdf3d634e357f3c967b80fc638ee8887bef285f29ea2aac7a85c7192c21287ae8748f37f1f696c47dfcbe5f6d4cb015e6cb68a20c6
2022-08-14 01:14:53 +08:00

140 lines
2.9 KiB
Text

/**
* @typedef {import('micromark-util-types').Construct} Construct
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
* @typedef {import('micromark-util-types').State} State
*/
import {
asciiAlpha,
asciiAlphanumeric,
asciiAtext,
asciiControl
} from 'micromark-util-character'
/** @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) {
effects.enter('autolink')
effects.enter('autolinkMarker')
effects.consume(code)
effects.exit('autolinkMarker')
effects.enter('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 === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)
? schemeInsideOrEmailAtext(code)
: emailAtext(code)
}
/** @type {State} */
function schemeInsideOrEmailAtext(code) {
if (code === 58) {
effects.consume(code)
return urlInside
}
if (
(code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) &&
size++ < 32
) {
effects.consume(code)
return schemeInsideOrEmailAtext
}
return emailAtext(code)
}
/** @type {State} */
function urlInside(code) {
if (code === 62) {
effects.exit('autolinkProtocol')
return end(code)
}
if (code === null || code === 32 || code === 60 || asciiControl(code)) {
return nok(code)
}
effects.consume(code)
return urlInside
}
/** @type {State} */
function emailAtext(code) {
if (code === 64) {
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 === 46) {
effects.consume(code)
size = 0
return emailAtSignOrDot
}
if (code === 62) {
// Exit, then change the type.
effects.exit('autolinkProtocol').type = 'autolinkEmail'
return end(code)
}
return emailValue(code)
}
/** @type {State} */
function emailValue(code) {
if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) {
effects.consume(code)
return code === 45 ? emailValue : emailLabel
}
return nok(code)
}
/** @type {State} */
function end(code) {
effects.enter('autolinkMarker')
effects.consume(code)
effects.exit('autolinkMarker')
effects.exit('autolink')
return ok
}
}