You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
435 lines
8.2 KiB
435 lines
8.2 KiB
'use strict' |
|
|
|
var asciiAlpha = require('../character/ascii-alpha.js') |
|
var asciiAlphanumeric = require('../character/ascii-alphanumeric.js') |
|
var markdownLineEnding = require('../character/markdown-line-ending.js') |
|
var markdownLineEndingOrSpace = require('../character/markdown-line-ending-or-space.js') |
|
var markdownSpace = require('../character/markdown-space.js') |
|
var factorySpace = require('./factory-space.js') |
|
|
|
var htmlText = { |
|
name: 'htmlText', |
|
tokenize: tokenizeHtmlText |
|
} |
|
|
|
function tokenizeHtmlText(effects, ok, nok) { |
|
var self = this |
|
var marker |
|
var buffer |
|
var index |
|
var returnState |
|
return start |
|
|
|
function start(code) { |
|
effects.enter('htmlText') |
|
effects.enter('htmlTextData') |
|
effects.consume(code) |
|
return open |
|
} |
|
|
|
function open(code) { |
|
if (code === 33) { |
|
effects.consume(code) |
|
return declarationOpen |
|
} |
|
|
|
if (code === 47) { |
|
effects.consume(code) |
|
return tagCloseStart |
|
} |
|
|
|
if (code === 63) { |
|
effects.consume(code) |
|
return instruction |
|
} |
|
|
|
if (asciiAlpha(code)) { |
|
effects.consume(code) |
|
return tagOpen |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
function declarationOpen(code) { |
|
if (code === 45) { |
|
effects.consume(code) |
|
return commentOpen |
|
} |
|
|
|
if (code === 91) { |
|
effects.consume(code) |
|
buffer = 'CDATA[' |
|
index = 0 |
|
return cdataOpen |
|
} |
|
|
|
if (asciiAlpha(code)) { |
|
effects.consume(code) |
|
return declaration |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
function commentOpen(code) { |
|
if (code === 45) { |
|
effects.consume(code) |
|
return commentStart |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
function commentStart(code) { |
|
if (code === null || code === 62) { |
|
return nok(code) |
|
} |
|
|
|
if (code === 45) { |
|
effects.consume(code) |
|
return commentStartDash |
|
} |
|
|
|
return comment(code) |
|
} |
|
|
|
function commentStartDash(code) { |
|
if (code === null || code === 62) { |
|
return nok(code) |
|
} |
|
|
|
return comment(code) |
|
} |
|
|
|
function comment(code) { |
|
if (code === null) { |
|
return nok(code) |
|
} |
|
|
|
if (code === 45) { |
|
effects.consume(code) |
|
return commentClose |
|
} |
|
|
|
if (markdownLineEnding(code)) { |
|
returnState = comment |
|
return atLineEnding(code) |
|
} |
|
|
|
effects.consume(code) |
|
return comment |
|
} |
|
|
|
function commentClose(code) { |
|
if (code === 45) { |
|
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 === null) { |
|
return nok(code) |
|
} |
|
|
|
if (code === 93) { |
|
effects.consume(code) |
|
return cdataClose |
|
} |
|
|
|
if (markdownLineEnding(code)) { |
|
returnState = cdata |
|
return atLineEnding(code) |
|
} |
|
|
|
effects.consume(code) |
|
return cdata |
|
} |
|
|
|
function cdataClose(code) { |
|
if (code === 93) { |
|
effects.consume(code) |
|
return cdataEnd |
|
} |
|
|
|
return cdata(code) |
|
} |
|
|
|
function cdataEnd(code) { |
|
if (code === 62) { |
|
return end(code) |
|
} |
|
|
|
if (code === 93) { |
|
effects.consume(code) |
|
return cdataEnd |
|
} |
|
|
|
return cdata(code) |
|
} |
|
|
|
function declaration(code) { |
|
if (code === null || code === 62) { |
|
return end(code) |
|
} |
|
|
|
if (markdownLineEnding(code)) { |
|
returnState = declaration |
|
return atLineEnding(code) |
|
} |
|
|
|
effects.consume(code) |
|
return declaration |
|
} |
|
|
|
function instruction(code) { |
|
if (code === null) { |
|
return nok(code) |
|
} |
|
|
|
if (code === 63) { |
|
effects.consume(code) |
|
return instructionClose |
|
} |
|
|
|
if (markdownLineEnding(code)) { |
|
returnState = instruction |
|
return atLineEnding(code) |
|
} |
|
|
|
effects.consume(code) |
|
return instruction |
|
} |
|
|
|
function instructionClose(code) { |
|
return code === 62 ? end(code) : instruction(code) |
|
} |
|
|
|
function tagCloseStart(code) { |
|
if (asciiAlpha(code)) { |
|
effects.consume(code) |
|
return tagClose |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
function tagClose(code) { |
|
if (code === 45 || 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 === 45 || asciiAlphanumeric(code)) { |
|
effects.consume(code) |
|
return tagOpen |
|
} |
|
|
|
if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { |
|
return tagOpenBetween(code) |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
function tagOpenBetween(code) { |
|
if (code === 47) { |
|
effects.consume(code) |
|
return end |
|
} |
|
|
|
if (code === 58 || code === 95 || 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 === 45 || |
|
code === 46 || |
|
code === 58 || |
|
code === 95 || |
|
asciiAlphanumeric(code) |
|
) { |
|
effects.consume(code) |
|
return tagOpenAttributeName |
|
} |
|
|
|
return tagOpenAttributeNameAfter(code) |
|
} |
|
|
|
function tagOpenAttributeNameAfter(code) { |
|
if (code === 61) { |
|
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 === null || |
|
code === 60 || |
|
code === 61 || |
|
code === 62 || |
|
code === 96 |
|
) { |
|
return nok(code) |
|
} |
|
|
|
if (code === 34 || code === 39) { |
|
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 === null) { |
|
return nok(code) |
|
} |
|
|
|
if (markdownLineEnding(code)) { |
|
returnState = tagOpenAttributeValueQuoted |
|
return atLineEnding(code) |
|
} |
|
|
|
effects.consume(code) |
|
return tagOpenAttributeValueQuoted |
|
} |
|
|
|
function tagOpenAttributeValueQuotedAfter(code) { |
|
if (code === 62 || code === 47 || markdownLineEndingOrSpace(code)) { |
|
return tagOpenBetween(code) |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
function tagOpenAttributeValueUnquoted(code) { |
|
if ( |
|
code === null || |
|
code === 34 || |
|
code === 39 || |
|
code === 60 || |
|
code === 61 || |
|
code === 96 |
|
) { |
|
return nok(code) |
|
} |
|
|
|
if (code === 62 || 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) { |
|
effects.exit('htmlTextData') |
|
effects.enter('lineEnding') |
|
effects.consume(code) |
|
effects.exit('lineEnding') |
|
return factorySpace( |
|
effects, |
|
afterPrefix, |
|
'linePrefix', |
|
self.parser.constructs.disable.null.indexOf('codeIndented') > -1 |
|
? undefined |
|
: 4 |
|
) |
|
} |
|
|
|
function afterPrefix(code) { |
|
effects.enter('htmlTextData') |
|
return returnState(code) |
|
} |
|
|
|
function end(code) { |
|
if (code === 62) { |
|
effects.consume(code) |
|
effects.exit('htmlTextData') |
|
effects.exit('htmlText') |
|
return ok |
|
} |
|
|
|
return nok(code) |
|
} |
|
} |
|
|
|
module.exports = htmlText
|
|
|