123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- var htmlFlow = {
- name: 'htmlFlow',
- tokenize: tokenizeHtmlFlow,
- resolveTo: resolveToHtmlFlow,
- concrete: true
- }
- export default htmlFlow
- import assert from 'assert'
- import asciiAlpha from '../character/ascii-alpha.mjs'
- import asciiAlphanumeric from '../character/ascii-alphanumeric.mjs'
- import codes from '../character/codes.mjs'
- import markdownLineEnding from '../character/markdown-line-ending.mjs'
- import markdownLineEndingOrSpace from '../character/markdown-line-ending-or-space.mjs'
- import markdownSpace from '../character/markdown-space.mjs'
- import constants from '../constant/constants.mjs'
- import fromCharCode from '../constant/from-char-code.mjs'
- import basics from '../constant/html-block-names.mjs'
- import raws from '../constant/html-raw-names.mjs'
- import types from '../constant/types.mjs'
- import blank from './partial-blank-line.mjs'
- var nextBlankConstruct = {tokenize: tokenizeNextBlank, partial: true}
- function resolveToHtmlFlow(events) {
- var index = events.length
- while (index--) {
- if (
- events[index][0] === 'enter' &&
- events[index][1].type === types.htmlFlow
- ) {
- break
- }
- }
- if (index > 1 && events[index - 2][1].type === types.linePrefix) {
- // Add the prefix start to the HTML token.
- events[index][1].start = events[index - 2][1].start
- // Add the prefix start to the HTML line token.
- events[index + 1][1].start = events[index - 2][1].start
- // Remove the line prefix.
- events.splice(index - 2, 2)
- }
- return events
- }
- function tokenizeHtmlFlow(effects, ok, nok) {
- var self = this
- var kind
- var startTag
- var buffer
- var index
- var marker
- return start
- function start(code) {
- assert(code === codes.lessThan, 'expected `<`')
- effects.enter(types.htmlFlow)
- effects.enter(types.htmlFlowData)
- effects.consume(code)
- return open
- }
- function open(code) {
- if (code === codes.exclamationMark) {
- effects.consume(code)
- return declarationStart
- }
- if (code === codes.slash) {
- effects.consume(code)
- return tagCloseStart
- }
- if (code === codes.questionMark) {
- effects.consume(code)
- kind = constants.htmlInstruction
- // While we’re in an instruction instead of a declaration, we’re on a `?`
- // right now, so we do need to search for `>`, similar to declarations.
- return self.interrupt ? ok : continuationDeclarationInside
- }
- if (asciiAlpha(code)) {
- effects.consume(code)
- buffer = fromCharCode(code)
- startTag = true
- return tagName
- }
- return nok(code)
- }
- function declarationStart(code) {
- if (code === codes.dash) {
- effects.consume(code)
- kind = constants.htmlComment
- return commentOpenInside
- }
- if (code === codes.leftSquareBracket) {
- effects.consume(code)
- kind = constants.htmlCdata
- buffer = constants.cdataOpeningString
- index = 0
- return cdataOpenInside
- }
- if (asciiAlpha(code)) {
- effects.consume(code)
- kind = constants.htmlDeclaration
- return self.interrupt ? ok : continuationDeclarationInside
- }
- return nok(code)
- }
- function commentOpenInside(code) {
- if (code === codes.dash) {
- effects.consume(code)
- return self.interrupt ? ok : continuationDeclarationInside
- }
- return nok(code)
- }
- function cdataOpenInside(code) {
- if (code === buffer.charCodeAt(index++)) {
- effects.consume(code)
- return index === buffer.length
- ? self.interrupt
- ? ok
- : continuation
- : cdataOpenInside
- }
- return nok(code)
- }
- function tagCloseStart(code) {
- if (asciiAlpha(code)) {
- effects.consume(code)
- buffer = fromCharCode(code)
- return tagName
- }
- return nok(code)
- }
- function tagName(code) {
- if (
- code === codes.eof ||
- code === codes.slash ||
- code === codes.greaterThan ||
- markdownLineEndingOrSpace(code)
- ) {
- if (
- code !== codes.slash &&
- startTag &&
- raws.indexOf(buffer.toLowerCase()) > -1
- ) {
- kind = constants.htmlRaw
- return self.interrupt ? ok(code) : continuation(code)
- }
- if (basics.indexOf(buffer.toLowerCase()) > -1) {
- kind = constants.htmlBasic
- if (code === codes.slash) {
- effects.consume(code)
- return basicSelfClosing
- }
- return self.interrupt ? ok(code) : continuation(code)
- }
- kind = constants.htmlComplete
- // Do not support complete HTML when interrupting.
- return self.interrupt
- ? nok(code)
- : startTag
- ? completeAttributeNameBefore(code)
- : completeClosingTagAfter(code)
- }
- if (code === codes.dash || asciiAlphanumeric(code)) {
- effects.consume(code)
- buffer += fromCharCode(code)
- return tagName
- }
- return nok(code)
- }
- function basicSelfClosing(code) {
- if (code === codes.greaterThan) {
- effects.consume(code)
- return self.interrupt ? ok : continuation
- }
- return nok(code)
- }
- function completeClosingTagAfter(code) {
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeClosingTagAfter
- }
- return completeEnd(code)
- }
- function completeAttributeNameBefore(code) {
- if (code === codes.slash) {
- effects.consume(code)
- return completeEnd
- }
- if (code === codes.colon || code === codes.underscore || asciiAlpha(code)) {
- effects.consume(code)
- return completeAttributeName
- }
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAttributeNameBefore
- }
- return completeEnd(code)
- }
- function completeAttributeName(code) {
- if (
- code === codes.dash ||
- code === codes.dot ||
- code === codes.colon ||
- code === codes.underscore ||
- asciiAlphanumeric(code)
- ) {
- effects.consume(code)
- return completeAttributeName
- }
- return completeAttributeNameAfter(code)
- }
- function completeAttributeNameAfter(code) {
- if (code === codes.equalsTo) {
- effects.consume(code)
- return completeAttributeValueBefore
- }
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAttributeNameAfter
- }
- return completeAttributeNameBefore(code)
- }
- function completeAttributeValueBefore(code) {
- if (
- code === codes.eof ||
- code === codes.lessThan ||
- code === codes.equalsTo ||
- code === codes.greaterThan ||
- code === codes.graveAccent
- ) {
- return nok(code)
- }
- if (code === codes.quotationMark || code === codes.apostrophe) {
- effects.consume(code)
- marker = code
- return completeAttributeValueQuoted
- }
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAttributeValueBefore
- }
- marker = undefined
- return completeAttributeValueUnquoted(code)
- }
- function completeAttributeValueQuoted(code) {
- if (code === marker) {
- effects.consume(code)
- return completeAttributeValueQuotedAfter
- }
- if (code === codes.eof || markdownLineEnding(code)) {
- return nok(code)
- }
- effects.consume(code)
- return completeAttributeValueQuoted
- }
- function completeAttributeValueUnquoted(code) {
- if (
- code === codes.eof ||
- code === codes.quotationMark ||
- code === codes.apostrophe ||
- code === codes.lessThan ||
- code === codes.equalsTo ||
- code === codes.greaterThan ||
- code === codes.graveAccent ||
- markdownLineEndingOrSpace(code)
- ) {
- return completeAttributeNameAfter(code)
- }
- effects.consume(code)
- return completeAttributeValueUnquoted
- }
- function completeAttributeValueQuotedAfter(code) {
- if (
- code === codes.slash ||
- code === codes.greaterThan ||
- markdownSpace(code)
- ) {
- return completeAttributeNameBefore(code)
- }
- return nok(code)
- }
- function completeEnd(code) {
- if (code === codes.greaterThan) {
- effects.consume(code)
- return completeAfter
- }
- return nok(code)
- }
- function completeAfter(code) {
- if (markdownSpace(code)) {
- effects.consume(code)
- return completeAfter
- }
- return code === codes.eof || markdownLineEnding(code)
- ? continuation(code)
- : nok(code)
- }
- function continuation(code) {
- if (code === codes.dash && kind === constants.htmlComment) {
- effects.consume(code)
- return continuationCommentInside
- }
- if (code === codes.lessThan && kind === constants.htmlRaw) {
- effects.consume(code)
- return continuationRawTagOpen
- }
- if (code === codes.greaterThan && kind === constants.htmlDeclaration) {
- effects.consume(code)
- return continuationClose
- }
- if (code === codes.questionMark && kind === constants.htmlInstruction) {
- effects.consume(code)
- return continuationDeclarationInside
- }
- if (code === codes.rightSquareBracket && kind === constants.htmlCdata) {
- effects.consume(code)
- return continuationCharacterDataInside
- }
- if (
- markdownLineEnding(code) &&
- (kind === constants.htmlBasic || kind === constants.htmlComplete)
- ) {
- return effects.check(
- nextBlankConstruct,
- continuationClose,
- continuationAtLineEnding
- )(code)
- }
- if (code === codes.eof || markdownLineEnding(code)) {
- return continuationAtLineEnding(code)
- }
- effects.consume(code)
- return continuation
- }
- function continuationAtLineEnding(code) {
- effects.exit(types.htmlFlowData)
- return htmlContinueStart(code)
- }
- function htmlContinueStart(code) {
- if (code === codes.eof) {
- return done(code)
- }
- if (markdownLineEnding(code)) {
- effects.enter(types.lineEnding)
- effects.consume(code)
- effects.exit(types.lineEnding)
- return htmlContinueStart
- }
- effects.enter(types.htmlFlowData)
- return continuation(code)
- }
- function continuationCommentInside(code) {
- if (code === codes.dash) {
- effects.consume(code)
- return continuationDeclarationInside
- }
- return continuation(code)
- }
- function continuationRawTagOpen(code) {
- if (code === codes.slash) {
- effects.consume(code)
- buffer = ''
- return continuationRawEndTag
- }
- return continuation(code)
- }
- function continuationRawEndTag(code) {
- if (code === codes.greaterThan && raws.indexOf(buffer.toLowerCase()) > -1) {
- effects.consume(code)
- return continuationClose
- }
- if (asciiAlpha(code) && buffer.length < constants.htmlRawSizeMax) {
- effects.consume(code)
- buffer += fromCharCode(code)
- return continuationRawEndTag
- }
- return continuation(code)
- }
- function continuationCharacterDataInside(code) {
- if (code === codes.rightSquareBracket) {
- effects.consume(code)
- return continuationDeclarationInside
- }
- return continuation(code)
- }
- function continuationDeclarationInside(code) {
- if (code === codes.greaterThan) {
- effects.consume(code)
- return continuationClose
- }
- return continuation(code)
- }
- function continuationClose(code) {
- if (code === codes.eof || markdownLineEnding(code)) {
- effects.exit(types.htmlFlowData)
- return done(code)
- }
- effects.consume(code)
- return continuationClose
- }
- function done(code) {
- effects.exit(types.htmlFlow)
- return ok(code)
- }
- }
- function tokenizeNextBlank(effects, ok, nok) {
- return start
- function start(code) {
- assert(markdownLineEnding(code), 'expected a line ending')
- effects.exit(types.htmlFlowData)
- effects.enter(types.lineEndingBlank)
- effects.consume(code)
- effects.exit(types.lineEndingBlank)
- return effects.attempt(blank, ok, nok)
- }
- }
|