mv whiteSpaceCtrl to a separate file

This commit is contained in:
harttle
2017-10-30 00:36:21 +08:00
parent 8c77fc5a3d
commit 502426f621
2 changed files with 79 additions and 73 deletions
+44 -73
View File
@@ -1,54 +1,68 @@
const lexical = require('./lexical.js') const lexical = require('./lexical.js')
const TokenizationError = require('./util/error.js').TokenizationError const TokenizationError = require('./util/error.js').TokenizationError
const _ = require('./util/underscore.js') const _ = require('./util/underscore.js')
const assert = require('../src/util/assert.js') const whiteSpaceCtrl = require('./whitespace-ctrl.js')
const assert = require('./util/assert.js')
function parse (html, filepath, options) { function parse (input, file, options) {
assert(_.isString(html), 'illegal input') assert(_.isString(input), 'illegal input')
var rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g var rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g
var currIndent = 0 var currIndent = 0
var lineNumber = LineNumber() var lineNumber = LineNumber(input)
var lastMatchEnd = 0 var lastMatchEnd = 0
var tokens = [] var tokens = []
for (var match; (match = rLiquid.exec(html)); lastMatchEnd = rLiquid.lastIndex) { for (var match; (match = rLiquid.exec(input)); lastMatchEnd = rLiquid.lastIndex) {
if (match.index > lastMatchEnd) { if (match.index > lastMatchEnd) {
tokens.push(parseHTMLToken(lastMatchEnd, match.index)) tokens.push(parseHTMLToken(lastMatchEnd, match.index))
} }
tokens.push(match[1] ? parseTagToken(match) : parseOutputToken(match)) tokens.push(match[1]
? parseTagToken(match[1], match[2].trim(), match.index)
: parseOutputToken(match[3], match[4].trim(), match.index))
} }
if (html.length > lastMatchEnd) { if (input.length > lastMatchEnd) {
tokens.push(parseHTMLToken(lastMatchEnd, html.length)) tokens.push(parseHTMLToken(lastMatchEnd, input.length))
} }
whiteSpaceCtrl(tokens, options) whiteSpaceCtrl(tokens, options)
return tokens return tokens
function parseOutputToken (match) { function parseTagToken (raw, value, pos) {
var token = factory('output', 3, match) var match = value.match(lexical.tagLine)
token.trim_left = (match[3].slice(0, 3) === '{{-') var token = {
token.trim_right = (match[3].slice(-3) === '-}}') type: 'tag',
return token indent: currIndent,
} line: lineNumber.get(pos),
trim_left: raw.slice(0, 3) === '{%-',
function parseTagToken (result) { trim_right: raw.slice(-3) === '-%}',
var token = factory('tag', 1, result) raw,
var match = token.value.match(lexical.tagLine) value,
input,
file
}
if (!match) { if (!match) {
throw new TokenizationError(`illegal tag syntax`, token) throw new TokenizationError(`illegal tag syntax`, token)
} }
token.name = match[1]
token.args = match[2]
return token
}
return _.assign(token, { function parseOutputToken (raw, value, pos) {
name: match[1], return {
args: match[2], type: 'output',
trim_left: (result[1].slice(0, 3) === '{%-'), line: lineNumber.get(pos),
trim_right: (result[1].slice(-3) === '-%}'), trim_left: raw.slice(0, 3) === '{{-',
indent: currIndent trim_right: raw.slice(-3) === '-}}',
}) raw,
value,
input,
file
}
} }
function parseHTMLToken (begin, end) { function parseHTMLToken (begin, end) {
var htmlFragment = html.slice(begin, end) var htmlFragment = input.slice(begin, end)
currIndent = _.last((htmlFragment || '').split('\n')).length currIndent = _.last((htmlFragment || '').split('\n')).length
return { return {
@@ -57,64 +71,21 @@ function parse (html, filepath, options) {
value: htmlFragment value: htmlFragment
} }
} }
function factory (type, offset, match) {
return {
type: type,
raw: match[offset],
value: match[offset + 1].trim(),
line: lineNumber.get(match),
input: html,
file: filepath
}
}
} }
function LineNumber () { function LineNumber (html) {
var parsedLinesCount = 0 var parsedLinesCount = 0
var lastMatchBegin = -1 var lastMatchBegin = -1
return { return {
get: function (match) { get: function (pos) {
var lines = match.input.slice(lastMatchBegin + 1, match.index).split('\n') var lines = html.slice(lastMatchBegin + 1, pos).split('\n')
parsedLinesCount += lines.length - 1 parsedLinesCount += lines.length - 1
lastMatchBegin = match.index lastMatchBegin = pos
return parsedLinesCount + 1 return parsedLinesCount + 1
} }
} }
} }
function whiteSpaceCtrl (tokens, options) {
options = _.assign({ greedy: true }, options)
var inRaw = false
tokens.forEach((token, i) => {
if (!inRaw && (token.trim_left || options.trim_left)) {
trimLeft(tokens[i - 1], options.greedy)
}
if (token.type === 'tag' && token.name === 'raw') inRaw = true
if (token.type === 'tag' && token.name === 'endraw') inRaw = false
if (!inRaw && (token.trim_right || options.trim_right)) {
trimRight(tokens[i + 1], options.greedy)
}
})
}
function trimLeft (token, greedy) {
if (!token || token.type !== 'html') return
var rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g
token.value = token.value.replace(rLeft, '')
}
function trimRight (token, greedy) {
if (!token || token.type !== 'html') return
var rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g
token.value = token.value.replace(rRight, '')
}
exports.parse = parse exports.parse = parse
exports.whiteSpaceCtrl = whiteSpaceCtrl exports.whiteSpaceCtrl = whiteSpaceCtrl
+35
View File
@@ -0,0 +1,35 @@
const _ = require('./util/underscore.js')
function whiteSpaceCtrl (tokens, options) {
options = _.assign({ greedy: true }, options)
var inRaw = false
tokens.forEach((token, i) => {
if (!inRaw && (token.trim_left || options.trim_left)) {
trimLeft(tokens[i - 1], options.greedy)
}
if (token.type === 'tag' && token.name === 'raw') inRaw = true
if (token.type === 'tag' && token.name === 'endraw') inRaw = false
if (!inRaw && (token.trim_right || options.trim_right)) {
trimRight(tokens[i + 1], options.greedy)
}
})
}
function trimLeft (token, greedy) {
if (!token || token.type !== 'html') return
var rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g
token.value = token.value.replace(rLeft, '')
}
function trimRight (token, greedy) {
if (!token || token.type !== 'html') return
var rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g
token.value = token.value.replace(rRight, '')
}
module.exports = whiteSpaceCtrl