AK-21/Graphite-Industrial-Intelligence
0
1/**2 * @import {3 * Construct,4 * State,5 * TokenizeContext,6 * Tokenizer7 * } from 'micromark-util-types'8 */9 10import { factoryDestination } from 'micromark-factory-destination';11import { factoryLabel } from 'micromark-factory-label';12import { factorySpace } from 'micromark-factory-space';13import { factoryTitle } from 'micromark-factory-title';14import { factoryWhitespace } from 'micromark-factory-whitespace';15import { markdownLineEndingOrSpace, markdownLineEnding, markdownSpace } from 'micromark-util-character';16import { normalizeIdentifier } from 'micromark-util-normalize-identifier';17/** @type {Construct} */18export const definition = {19 name: 'definition',20 tokenize: tokenizeDefinition21};22 23/** @type {Construct} */24const titleBefore = {25 partial: true,26 tokenize: tokenizeTitleBefore27};28 29/**30 * @this {TokenizeContext}31 * Context.32 * @type {Tokenizer}33 */34function tokenizeDefinition(effects, ok, nok) {35 const self = this;36 /** @type {string} */37 let identifier;38 return start;39 40 /**41 * At start of a definition.42 *43 * ```markdown44 * > | [a]: b "c"45 * ^46 * ```47 *48 * @type {State}49 */50 function start(code) {51 // Do not interrupt paragraphs (but do follow definitions).52 // To do: do `interrupt` the way `markdown-rs` does.53 // To do: parse whitespace the way `markdown-rs` does.54 effects.enter("definition");55 return before(code);56 }57 58 /**59 * After optional whitespace, at `[`.60 *61 * ```markdown62 * > | [a]: b "c"63 * ^64 * ```65 *66 * @type {State}67 */68 function before(code) {69 // To do: parse whitespace the way `markdown-rs` does.70 71 return factoryLabel.call(self, effects, labelAfter,72 // Note: we don’t need to reset the way `markdown-rs` does.73 nok, "definitionLabel", "definitionLabelMarker", "definitionLabelString")(code);74 }75 76 /**77 * After label.78 *79 * ```markdown80 * > | [a]: b "c"81 * ^82 * ```83 *84 * @type {State}85 */86 function labelAfter(code) {87 identifier = normalizeIdentifier(self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1));88 if (code === 58) {89 effects.enter("definitionMarker");90 effects.consume(code);91 effects.exit("definitionMarker");92 return markerAfter;93 }94 return nok(code);95 }96 97 /**98 * After marker.99 *100 * ```markdown101 * > | [a]: b "c"102 * ^103 * ```104 *105 * @type {State}106 */107 function markerAfter(code) {108 // Note: whitespace is optional.109 return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, destinationBefore)(code) : destinationBefore(code);110 }111 112 /**113 * Before destination.114 *115 * ```markdown116 * > | [a]: b "c"117 * ^118 * ```119 *120 * @type {State}121 */122 function destinationBefore(code) {123 return factoryDestination(effects, destinationAfter,124 // Note: we don’t need to reset the way `markdown-rs` does.125 nok, "definitionDestination", "definitionDestinationLiteral", "definitionDestinationLiteralMarker", "definitionDestinationRaw", "definitionDestinationString")(code);126 }127 128 /**129 * After destination.130 *131 * ```markdown132 * > | [a]: b "c"133 * ^134 * ```135 *136 * @type {State}137 */138 function destinationAfter(code) {139 return effects.attempt(titleBefore, after, after)(code);140 }141 142 /**143 * After definition.144 *145 * ```markdown146 * > | [a]: b147 * ^148 * > | [a]: b "c"149 * ^150 * ```151 *152 * @type {State}153 */154 function after(code) {155 return markdownSpace(code) ? factorySpace(effects, afterWhitespace, "whitespace")(code) : afterWhitespace(code);156 }157 158 /**159 * After definition, after optional whitespace.160 *161 * ```markdown162 * > | [a]: b163 * ^164 * > | [a]: b "c"165 * ^166 * ```167 *168 * @type {State}169 */170 function afterWhitespace(code) {171 if (code === null || markdownLineEnding(code)) {172 effects.exit("definition");173 174 // Note: we don’t care about uniqueness.175 // It’s likely that that doesn’t happen very frequently.176 // It is more likely that it wastes precious time.177 self.parser.defined.push(identifier);178 179 // To do: `markdown-rs` interrupt.180 // // You’d be interrupting.181 // tokenizer.interrupt = true182 return ok(code);183 }184 return nok(code);185 }186}187 188/**189 * @this {TokenizeContext}190 * Context.191 * @type {Tokenizer}192 */193function tokenizeTitleBefore(effects, ok, nok) {194 return titleBefore;195 196 /**197 * After destination, at whitespace.198 *199 * ```markdown200 * > | [a]: b201 * ^202 * > | [a]: b "c"203 * ^204 * ```205 *206 * @type {State}207 */208 function titleBefore(code) {209 return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, beforeMarker)(code) : nok(code);210 }211 212 /**213 * At title.214 *215 * ```markdown216 * | [a]: b217 * > | "c"218 * ^219 * ```220 *221 * @type {State}222 */223 function beforeMarker(code) {224 return factoryTitle(effects, titleAfter, nok, "definitionTitle", "definitionTitleMarker", "definitionTitleString")(code);225 }226 227 /**228 * After title.229 *230 * ```markdown231 * > | [a]: b "c"232 * ^233 * ```234 *235 * @type {State}236 */237 function titleAfter(code) {238 return markdownSpace(code) ? factorySpace(effects, titleAfterOptionalWhitespace, "whitespace")(code) : titleAfterOptionalWhitespace(code);239 }240 241 /**242 * After title, after optional whitespace.243 *244 * ```markdown245 * > | [a]: b "c"246 * ^247 * ```248 *249 * @type {State}250 */251 function titleAfterOptionalWhitespace(code) {252 return code === null || markdownLineEnding(code) ? ok(code) : nok(code);253 }254}