All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
450 lines
9.2 KiB
JavaScript
450 lines
9.2 KiB
JavaScript
var htmlText = {
|
||
name: 'htmlText',
|
||
tokenize: tokenizeHtmlText
|
||
}
|
||
export default htmlText
|
||
|
||
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 types from '../constant/types.mjs'
|
||
import spaceFactory from './factory-space.mjs'
|
||
|
||
function tokenizeHtmlText(effects, ok, nok) {
|
||
var self = this
|
||
var marker
|
||
var buffer
|
||
var index
|
||
var returnState
|
||
|
||
return start
|
||
|
||
function start(code) {
|
||
assert(code === codes.lessThan, 'expected `<`')
|
||
effects.enter(types.htmlText)
|
||
effects.enter(types.htmlTextData)
|
||
effects.consume(code)
|
||
return open
|
||
}
|
||
|
||
function open(code) {
|
||
if (code === codes.exclamationMark) {
|
||
effects.consume(code)
|
||
return declarationOpen
|
||
}
|
||
|
||
if (code === codes.slash) {
|
||
effects.consume(code)
|
||
return tagCloseStart
|
||
}
|
||
|
||
if (code === codes.questionMark) {
|
||
effects.consume(code)
|
||
return instruction
|
||
}
|
||
|
||
if (asciiAlpha(code)) {
|
||
effects.consume(code)
|
||
return tagOpen
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
|
||
function declarationOpen(code) {
|
||
if (code === codes.dash) {
|
||
effects.consume(code)
|
||
return commentOpen
|
||
}
|
||
|
||
if (code === codes.leftSquareBracket) {
|
||
effects.consume(code)
|
||
buffer = constants.cdataOpeningString
|
||
index = 0
|
||
return cdataOpen
|
||
}
|
||
|
||
if (asciiAlpha(code)) {
|
||
effects.consume(code)
|
||
return declaration
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
|
||
function commentOpen(code) {
|
||
if (code === codes.dash) {
|
||
effects.consume(code)
|
||
return commentStart
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
|
||
function commentStart(code) {
|
||
if (code === codes.eof || code === codes.greaterThan) {
|
||
return nok(code)
|
||
}
|
||
|
||
if (code === codes.dash) {
|
||
effects.consume(code)
|
||
return commentStartDash
|
||
}
|
||
|
||
return comment(code)
|
||
}
|
||
|
||
function commentStartDash(code) {
|
||
if (code === codes.eof || code === codes.greaterThan) {
|
||
return nok(code)
|
||
}
|
||
|
||
return comment(code)
|
||
}
|
||
|
||
function comment(code) {
|
||
if (code === codes.eof) {
|
||
return nok(code)
|
||
}
|
||
|
||
if (code === codes.dash) {
|
||
effects.consume(code)
|
||
return commentClose
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = comment
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
effects.consume(code)
|
||
return comment
|
||
}
|
||
|
||
function commentClose(code) {
|
||
if (code === codes.dash) {
|
||
effects.consume(code)
|
||
return end
|
||
}
|
||
|
||
return comment(code)
|
||
}
|
||
|
||
function cdataOpen(code) {
|
||
if (code === buffer.charCodeAt(index++)) {
|
||
effects.consume(code)
|
||
return index === buffer.length ? cdata : cdataOpen
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
|
||
function cdata(code) {
|
||
if (code === codes.eof) {
|
||
return nok(code)
|
||
}
|
||
|
||
if (code === codes.rightSquareBracket) {
|
||
effects.consume(code)
|
||
return cdataClose
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = cdata
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
effects.consume(code)
|
||
return cdata
|
||
}
|
||
|
||
function cdataClose(code) {
|
||
if (code === codes.rightSquareBracket) {
|
||
effects.consume(code)
|
||
return cdataEnd
|
||
}
|
||
|
||
return cdata(code)
|
||
}
|
||
|
||
function cdataEnd(code) {
|
||
if (code === codes.greaterThan) {
|
||
return end(code)
|
||
}
|
||
|
||
if (code === codes.rightSquareBracket) {
|
||
effects.consume(code)
|
||
return cdataEnd
|
||
}
|
||
|
||
return cdata(code)
|
||
}
|
||
|
||
function declaration(code) {
|
||
if (code === codes.eof || code === codes.greaterThan) {
|
||
return end(code)
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = declaration
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
effects.consume(code)
|
||
return declaration
|
||
}
|
||
|
||
function instruction(code) {
|
||
if (code === codes.eof) {
|
||
return nok(code)
|
||
}
|
||
|
||
if (code === codes.questionMark) {
|
||
effects.consume(code)
|
||
return instructionClose
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = instruction
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
effects.consume(code)
|
||
return instruction
|
||
}
|
||
|
||
function instructionClose(code) {
|
||
return code === codes.greaterThan ? end(code) : instruction(code)
|
||
}
|
||
|
||
function tagCloseStart(code) {
|
||
if (asciiAlpha(code)) {
|
||
effects.consume(code)
|
||
return tagClose
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
|
||
function tagClose(code) {
|
||
if (code === codes.dash || asciiAlphanumeric(code)) {
|
||
effects.consume(code)
|
||
return tagClose
|
||
}
|
||
|
||
return tagCloseBetween(code)
|
||
}
|
||
|
||
function tagCloseBetween(code) {
|
||
if (markdownLineEnding(code)) {
|
||
returnState = tagCloseBetween
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
if (markdownSpace(code)) {
|
||
effects.consume(code)
|
||
return tagCloseBetween
|
||
}
|
||
|
||
return end(code)
|
||
}
|
||
|
||
function tagOpen(code) {
|
||
if (code === codes.dash || asciiAlphanumeric(code)) {
|
||
effects.consume(code)
|
||
return tagOpen
|
||
}
|
||
|
||
if (
|
||
code === codes.slash ||
|
||
code === codes.greaterThan ||
|
||
markdownLineEndingOrSpace(code)
|
||
) {
|
||
return tagOpenBetween(code)
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
|
||
function tagOpenBetween(code) {
|
||
if (code === codes.slash) {
|
||
effects.consume(code)
|
||
return end
|
||
}
|
||
|
||
if (code === codes.colon || code === codes.underscore || asciiAlpha(code)) {
|
||
effects.consume(code)
|
||
return tagOpenAttributeName
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = tagOpenBetween
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
if (markdownSpace(code)) {
|
||
effects.consume(code)
|
||
return tagOpenBetween
|
||
}
|
||
|
||
return end(code)
|
||
}
|
||
|
||
function tagOpenAttributeName(code) {
|
||
if (
|
||
code === codes.dash ||
|
||
code === codes.dot ||
|
||
code === codes.colon ||
|
||
code === codes.underscore ||
|
||
asciiAlphanumeric(code)
|
||
) {
|
||
effects.consume(code)
|
||
return tagOpenAttributeName
|
||
}
|
||
|
||
return tagOpenAttributeNameAfter(code)
|
||
}
|
||
|
||
function tagOpenAttributeNameAfter(code) {
|
||
if (code === codes.equalsTo) {
|
||
effects.consume(code)
|
||
return tagOpenAttributeValueBefore
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = tagOpenAttributeNameAfter
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
if (markdownSpace(code)) {
|
||
effects.consume(code)
|
||
return tagOpenAttributeNameAfter
|
||
}
|
||
|
||
return tagOpenBetween(code)
|
||
}
|
||
|
||
function tagOpenAttributeValueBefore(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 tagOpenAttributeValueQuoted
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = tagOpenAttributeValueBefore
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
if (markdownSpace(code)) {
|
||
effects.consume(code)
|
||
return tagOpenAttributeValueBefore
|
||
}
|
||
|
||
effects.consume(code)
|
||
marker = undefined
|
||
return tagOpenAttributeValueUnquoted
|
||
}
|
||
|
||
function tagOpenAttributeValueQuoted(code) {
|
||
if (code === marker) {
|
||
effects.consume(code)
|
||
return tagOpenAttributeValueQuotedAfter
|
||
}
|
||
|
||
if (code === codes.eof) {
|
||
return nok(code)
|
||
}
|
||
|
||
if (markdownLineEnding(code)) {
|
||
returnState = tagOpenAttributeValueQuoted
|
||
return atLineEnding(code)
|
||
}
|
||
|
||
effects.consume(code)
|
||
return tagOpenAttributeValueQuoted
|
||
}
|
||
|
||
function tagOpenAttributeValueQuotedAfter(code) {
|
||
if (
|
||
code === codes.greaterThan ||
|
||
code === codes.slash ||
|
||
markdownLineEndingOrSpace(code)
|
||
) {
|
||
return tagOpenBetween(code)
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
|
||
function tagOpenAttributeValueUnquoted(code) {
|
||
if (
|
||
code === codes.eof ||
|
||
code === codes.quotationMark ||
|
||
code === codes.apostrophe ||
|
||
code === codes.lessThan ||
|
||
code === codes.equalsTo ||
|
||
code === codes.graveAccent
|
||
) {
|
||
return nok(code)
|
||
}
|
||
|
||
if (code === codes.greaterThan || markdownLineEndingOrSpace(code)) {
|
||
return tagOpenBetween(code)
|
||
}
|
||
|
||
effects.consume(code)
|
||
return tagOpenAttributeValueUnquoted
|
||
}
|
||
|
||
// We can’t have blank lines in content, so no need to worry about empty
|
||
// tokens.
|
||
function atLineEnding(code) {
|
||
assert(returnState, 'expected return state')
|
||
assert(markdownLineEnding(code), 'expected eol')
|
||
effects.exit(types.htmlTextData)
|
||
effects.enter(types.lineEnding)
|
||
effects.consume(code)
|
||
effects.exit(types.lineEnding)
|
||
return spaceFactory(
|
||
effects,
|
||
afterPrefix,
|
||
types.linePrefix,
|
||
self.parser.constructs.disable.null.indexOf('codeIndented') > -1
|
||
? undefined
|
||
: constants.tabSize
|
||
)
|
||
}
|
||
|
||
function afterPrefix(code) {
|
||
effects.enter(types.htmlTextData)
|
||
return returnState(code)
|
||
}
|
||
|
||
function end(code) {
|
||
if (code === codes.greaterThan) {
|
||
effects.consume(code)
|
||
effects.exit(types.htmlTextData)
|
||
effects.exit(types.htmlText)
|
||
return ok
|
||
}
|
||
|
||
return nok(code)
|
||
}
|
||
}
|