AK-21/Graphite-Industrial-Intelligence
0
1/**2 * @import {3 * Code,4 * Construct,5 * State,6 * TokenizeContext,7 * Tokenizer8 * } from 'micromark-util-types'9 */10 11import { factorySpace } from 'micromark-factory-space';12import { asciiAlphanumeric, asciiAlpha, markdownLineEndingOrSpace, markdownLineEnding, markdownSpace } from 'micromark-util-character';13/** @type {Construct} */14export const htmlText = {15 name: 'htmlText',16 tokenize: tokenizeHtmlText17};18 19/**20 * @this {TokenizeContext}21 * Context.22 * @type {Tokenizer}23 */24function tokenizeHtmlText(effects, ok, nok) {25 const self = this;26 /** @type {NonNullable<Code> | undefined} */27 let marker;28 /** @type {number} */29 let index;30 /** @type {State} */31 let returnState;32 return start;33 34 /**35 * Start of HTML (text).36 *37 * ```markdown38 * > | a <b> c39 * ^40 * ```41 *42 * @type {State}43 */44 function start(code) {45 effects.enter("htmlText");46 effects.enter("htmlTextData");47 effects.consume(code);48 return open;49 }50 51 /**52 * After `<`, at tag name or other stuff.53 *54 * ```markdown55 * > | a <b> c56 * ^57 * > | a <!doctype> c58 * ^59 * > | a <!--b--> c60 * ^61 * ```62 *63 * @type {State}64 */65 function open(code) {66 if (code === 33) {67 effects.consume(code);68 return declarationOpen;69 }70 if (code === 47) {71 effects.consume(code);72 return tagCloseStart;73 }74 if (code === 63) {75 effects.consume(code);76 return instruction;77 }78 79 // ASCII alphabetical.80 if (asciiAlpha(code)) {81 effects.consume(code);82 return tagOpen;83 }84 return nok(code);85 }86 87 /**88 * After `<!`, at declaration, comment, or CDATA.89 *90 * ```markdown91 * > | a <!doctype> c92 * ^93 * > | a <!--b--> c94 * ^95 * > | a <![CDATA[>&<]]> c96 * ^97 * ```98 *99 * @type {State}100 */101 function declarationOpen(code) {102 if (code === 45) {103 effects.consume(code);104 return commentOpenInside;105 }106 if (code === 91) {107 effects.consume(code);108 index = 0;109 return cdataOpenInside;110 }111 if (asciiAlpha(code)) {112 effects.consume(code);113 return declaration;114 }115 return nok(code);116 }117 118 /**119 * In a comment, after `<!-`, at another `-`.120 *121 * ```markdown122 * > | a <!--b--> c123 * ^124 * ```125 *126 * @type {State}127 */128 function commentOpenInside(code) {129 if (code === 45) {130 effects.consume(code);131 return commentEnd;132 }133 return nok(code);134 }135 136 /**137 * In comment.138 *139 * ```markdown140 * > | a <!--b--> c141 * ^142 * ```143 *144 * @type {State}145 */146 function comment(code) {147 if (code === null) {148 return nok(code);149 }150 if (code === 45) {151 effects.consume(code);152 return commentClose;153 }154 if (markdownLineEnding(code)) {155 returnState = comment;156 return lineEndingBefore(code);157 }158 effects.consume(code);159 return comment;160 }161 162 /**163 * In comment, after `-`.164 *165 * ```markdown166 * > | a <!--b--> c167 * ^168 * ```169 *170 * @type {State}171 */172 function commentClose(code) {173 if (code === 45) {174 effects.consume(code);175 return commentEnd;176 }177 return comment(code);178 }179 180 /**181 * In comment, after `--`.182 *183 * ```markdown184 * > | a <!--b--> c185 * ^186 * ```187 *188 * @type {State}189 */190 function commentEnd(code) {191 return code === 62 ? end(code) : code === 45 ? commentClose(code) : comment(code);192 }193 194 /**195 * After `<![`, in CDATA, expecting `CDATA[`.196 *197 * ```markdown198 * > | a <![CDATA[>&<]]> b199 * ^^^^^^200 * ```201 *202 * @type {State}203 */204 function cdataOpenInside(code) {205 const value = "CDATA[";206 if (code === value.charCodeAt(index++)) {207 effects.consume(code);208 return index === value.length ? cdata : cdataOpenInside;209 }210 return nok(code);211 }212 213 /**214 * In CDATA.215 *216 * ```markdown217 * > | a <![CDATA[>&<]]> b218 * ^^^219 * ```220 *221 * @type {State}222 */223 function cdata(code) {224 if (code === null) {225 return nok(code);226 }227 if (code === 93) {228 effects.consume(code);229 return cdataClose;230 }231 if (markdownLineEnding(code)) {232 returnState = cdata;233 return lineEndingBefore(code);234 }235 effects.consume(code);236 return cdata;237 }238 239 /**240 * In CDATA, after `]`, at another `]`.241 *242 * ```markdown243 * > | a <![CDATA[>&<]]> b244 * ^245 * ```246 *247 * @type {State}248 */249 function cdataClose(code) {250 if (code === 93) {251 effects.consume(code);252 return cdataEnd;253 }254 return cdata(code);255 }256 257 /**258 * In CDATA, after `]]`, at `>`.259 *260 * ```markdown261 * > | a <![CDATA[>&<]]> b262 * ^263 * ```264 *265 * @type {State}266 */267 function cdataEnd(code) {268 if (code === 62) {269 return end(code);270 }271 if (code === 93) {272 effects.consume(code);273 return cdataEnd;274 }275 return cdata(code);276 }277 278 /**279 * In declaration.280 *281 * ```markdown282 * > | a <!b> c283 * ^284 * ```285 *286 * @type {State}287 */288 function declaration(code) {289 if (code === null || code === 62) {290 return end(code);291 }292 if (markdownLineEnding(code)) {293 returnState = declaration;294 return lineEndingBefore(code);295 }296 effects.consume(code);297 return declaration;298 }299 300 /**301 * In instruction.302 *303 * ```markdown304 * > | a <?b?> c305 * ^306 * ```307 *308 * @type {State}309 */310 function instruction(code) {311 if (code === null) {312 return nok(code);313 }314 if (code === 63) {315 effects.consume(code);316 return instructionClose;317 }318 if (markdownLineEnding(code)) {319 returnState = instruction;320 return lineEndingBefore(code);321 }322 effects.consume(code);323 return instruction;324 }325 326 /**327 * In instruction, after `?`, at `>`.328 *329 * ```markdown330 * > | a <?b?> c331 * ^332 * ```333 *334 * @type {State}335 */336 function instructionClose(code) {337 return code === 62 ? end(code) : instruction(code);338 }339 340 /**341 * After `</`, in closing tag, at tag name.342 *343 * ```markdown344 * > | a </b> c345 * ^346 * ```347 *348 * @type {State}349 */350 function tagCloseStart(code) {351 // ASCII alphabetical.352 if (asciiAlpha(code)) {353 effects.consume(code);354 return tagClose;355 }356 return nok(code);357 }358 359 /**360 * After `</x`, in a tag name.361 *362 * ```markdown363 * > | a </b> c364 * ^365 * ```366 *367 * @type {State}368 */369 function tagClose(code) {370 // ASCII alphanumerical and `-`.371 if (code === 45 || asciiAlphanumeric(code)) {372 effects.consume(code);373 return tagClose;374 }375 return tagCloseBetween(code);376 }377 378 /**379 * In closing tag, after tag name.380 *381 * ```markdown382 * > | a </b> c383 * ^384 * ```385 *386 * @type {State}387 */388 function tagCloseBetween(code) {389 if (markdownLineEnding(code)) {390 returnState = tagCloseBetween;391 return lineEndingBefore(code);392 }393 if (markdownSpace(code)) {394 effects.consume(code);395 return tagCloseBetween;396 }397 return end(code);398 }399 400 /**401 * After `<x`, in opening tag name.402 *403 * ```markdown404 * > | a <b> c405 * ^406 * ```407 *408 * @type {State}409 */410 function tagOpen(code) {411 // ASCII alphanumerical and `-`.412 if (code === 45 || asciiAlphanumeric(code)) {413 effects.consume(code);414 return tagOpen;415 }416 if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {417 return tagOpenBetween(code);418 }419 return nok(code);420 }421 422 /**423 * In opening tag, after tag name.424 *425 * ```markdown426 * > | a <b> c427 * ^428 * ```429 *430 * @type {State}431 */432 function tagOpenBetween(code) {433 if (code === 47) {434 effects.consume(code);435 return end;436 }437 438 // ASCII alphabetical and `:` and `_`.439 if (code === 58 || code === 95 || asciiAlpha(code)) {440 effects.consume(code);441 return tagOpenAttributeName;442 }443 if (markdownLineEnding(code)) {444 returnState = tagOpenBetween;445 return lineEndingBefore(code);446 }447 if (markdownSpace(code)) {448 effects.consume(code);449 return tagOpenBetween;450 }451 return end(code);452 }453 454 /**455 * In attribute name.456 *457 * ```markdown458 * > | a <b c> d459 * ^460 * ```461 *462 * @type {State}463 */464 function tagOpenAttributeName(code) {465 // ASCII alphabetical and `-`, `.`, `:`, and `_`.466 if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) {467 effects.consume(code);468 return tagOpenAttributeName;469 }470 return tagOpenAttributeNameAfter(code);471 }472 473 /**474 * After attribute name, before initializer, the end of the tag, or475 * whitespace.476 *477 * ```markdown478 * > | a <b c> d479 * ^480 * ```481 *482 * @type {State}483 */484 function tagOpenAttributeNameAfter(code) {485 if (code === 61) {486 effects.consume(code);487 return tagOpenAttributeValueBefore;488 }489 if (markdownLineEnding(code)) {490 returnState = tagOpenAttributeNameAfter;491 return lineEndingBefore(code);492 }493 if (markdownSpace(code)) {494 effects.consume(code);495 return tagOpenAttributeNameAfter;496 }497 return tagOpenBetween(code);498 }499 500 /**501 * Before unquoted, double quoted, or single quoted attribute value, allowing502 * whitespace.503 *504 * ```markdown505 * > | a <b c=d> e506 * ^507 * ```508 *509 * @type {State}510 */511 function tagOpenAttributeValueBefore(code) {512 if (code === null || code === 60 || code === 61 || code === 62 || code === 96) {513 return nok(code);514 }515 if (code === 34 || code === 39) {516 effects.consume(code);517 marker = code;518 return tagOpenAttributeValueQuoted;519 }520 if (markdownLineEnding(code)) {521 returnState = tagOpenAttributeValueBefore;522 return lineEndingBefore(code);523 }524 if (markdownSpace(code)) {525 effects.consume(code);526 return tagOpenAttributeValueBefore;527 }528 effects.consume(code);529 return tagOpenAttributeValueUnquoted;530 }531 532 /**533 * In double or single quoted attribute value.534 *535 * ```markdown536 * > | a <b c="d"> e537 * ^538 * ```539 *540 * @type {State}541 */542 function tagOpenAttributeValueQuoted(code) {543 if (code === marker) {544 effects.consume(code);545 marker = undefined;546 return tagOpenAttributeValueQuotedAfter;547 }548 if (code === null) {549 return nok(code);550 }551 if (markdownLineEnding(code)) {552 returnState = tagOpenAttributeValueQuoted;553 return lineEndingBefore(code);554 }555 effects.consume(code);556 return tagOpenAttributeValueQuoted;557 }558 559 /**560 * In unquoted attribute value.561 *562 * ```markdown563 * > | a <b c=d> e564 * ^565 * ```566 *567 * @type {State}568 */569 function tagOpenAttributeValueUnquoted(code) {570 if (code === null || code === 34 || code === 39 || code === 60 || code === 61 || code === 96) {571 return nok(code);572 }573 if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {574 return tagOpenBetween(code);575 }576 effects.consume(code);577 return tagOpenAttributeValueUnquoted;578 }579 580 /**581 * After double or single quoted attribute value, before whitespace or the end582 * of the tag.583 *584 * ```markdown585 * > | a <b c="d"> e586 * ^587 * ```588 *589 * @type {State}590 */591 function tagOpenAttributeValueQuotedAfter(code) {592 if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {593 return tagOpenBetween(code);594 }595 return nok(code);596 }597 598 /**599 * In certain circumstances of a tag where only an `>` is allowed.600 *601 * ```markdown602 * > | a <b c="d"> e603 * ^604 * ```605 *606 * @type {State}607 */608 function end(code) {609 if (code === 62) {610 effects.consume(code);611 effects.exit("htmlTextData");612 effects.exit("htmlText");613 return ok;614 }615 return nok(code);616 }617 618 /**619 * At eol.620 *621 * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about622 * > empty tokens.623 *624 * ```markdown625 * > | a <!--a626 * ^627 * | b-->628 * ```629 *630 * @type {State}631 */632 function lineEndingBefore(code) {633 effects.exit("htmlTextData");634 effects.enter("lineEnding");635 effects.consume(code);636 effects.exit("lineEnding");637 return lineEndingAfter;638 }639 640 /**641 * After eol, at optional whitespace.642 *643 * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about644 * > empty tokens.645 *646 * ```markdown647 * | a <!--a648 * > | b-->649 * ^650 * ```651 *652 * @type {State}653 */654 function lineEndingAfter(code) {655 // Always populated by defaults.656 657 return markdownSpace(code) ? factorySpace(effects, lineEndingAfterPrefix, "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code) : lineEndingAfterPrefix(code);658 }659 660 /**661 * After eol, after optional whitespace.662 *663 * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about664 * > empty tokens.665 *666 * ```markdown667 * | a <!--a668 * > | b-->669 * ^670 * ```671 *672 * @type {State}673 */674 function lineEndingAfterPrefix(code) {675 effects.enter("htmlTextData");676 return returnState(code);677 }678}