This commit is contained in:
139
node_modules/mdast-util-to-markdown/lib/util/safe.js
generated
vendored
Normal file
139
node_modules/mdast-util-to-markdown/lib/util/safe.js
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
module.exports = safe
|
||||
|
||||
var patternCompile = require('./pattern-compile')
|
||||
var patternInScope = require('./pattern-in-scope')
|
||||
|
||||
function safe(context, input, config) {
|
||||
var value = (config.before || '') + (input || '') + (config.after || '')
|
||||
var positions = []
|
||||
var result = []
|
||||
var infos = {}
|
||||
var index = -1
|
||||
var before
|
||||
var after
|
||||
var position
|
||||
var pattern
|
||||
var expression
|
||||
var match
|
||||
var start
|
||||
var end
|
||||
|
||||
while (++index < context.unsafe.length) {
|
||||
pattern = context.unsafe[index]
|
||||
|
||||
if (!patternInScope(context.stack, pattern)) {
|
||||
continue
|
||||
}
|
||||
|
||||
expression = patternCompile(pattern)
|
||||
|
||||
while ((match = expression.exec(value))) {
|
||||
before = 'before' in pattern || pattern.atBreak
|
||||
after = 'after' in pattern
|
||||
|
||||
position = match.index + (before ? match[1].length : 0)
|
||||
|
||||
if (positions.indexOf(position) === -1) {
|
||||
positions.push(position)
|
||||
infos[position] = {before: before, after: after}
|
||||
} else {
|
||||
if (infos[position].before && !before) {
|
||||
infos[position].before = false
|
||||
}
|
||||
|
||||
if (infos[position].after && !after) {
|
||||
infos[position].after = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
positions.sort(numerical)
|
||||
|
||||
start = config.before ? config.before.length : 0
|
||||
end = value.length - (config.after ? config.after.length : 0)
|
||||
index = -1
|
||||
|
||||
while (++index < positions.length) {
|
||||
position = positions[index]
|
||||
|
||||
if (
|
||||
// Character before or after matched:
|
||||
position < start ||
|
||||
position >= end
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
// If this character is supposed to be escaped because it has a condition on
|
||||
// the next character, and the next character is definitly being escaped,
|
||||
// then skip this escape.
|
||||
if (
|
||||
position + 1 < end &&
|
||||
positions[index + 1] === position + 1 &&
|
||||
infos[position].after &&
|
||||
!infos[position + 1].before &&
|
||||
!infos[position + 1].after
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (start !== position) {
|
||||
// If we have to use a character reference, an ampersand would be more
|
||||
// correct, but as backslashes only care about punctuation, either will
|
||||
// do the trick
|
||||
result.push(escapeBackslashes(value.slice(start, position), '\\'))
|
||||
}
|
||||
|
||||
start = position
|
||||
|
||||
if (
|
||||
/[!-/:-@[-`{-~]/.test(value.charAt(position)) &&
|
||||
(!config.encode || config.encode.indexOf(value.charAt(position)) === -1)
|
||||
) {
|
||||
// Character escape.
|
||||
result.push('\\')
|
||||
} else {
|
||||
// Character reference.
|
||||
result.push(
|
||||
'&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';'
|
||||
)
|
||||
start++
|
||||
}
|
||||
}
|
||||
|
||||
result.push(escapeBackslashes(value.slice(start, end), config.after))
|
||||
|
||||
return result.join('')
|
||||
}
|
||||
|
||||
function numerical(a, b) {
|
||||
return a - b
|
||||
}
|
||||
|
||||
function escapeBackslashes(value, after) {
|
||||
var expression = /\\(?=[!-/:-@[-`{-~])/g
|
||||
var positions = []
|
||||
var results = []
|
||||
var index = -1
|
||||
var start = 0
|
||||
var whole = value + after
|
||||
var match
|
||||
|
||||
while ((match = expression.exec(whole))) {
|
||||
positions.push(match.index)
|
||||
}
|
||||
|
||||
while (++index < positions.length) {
|
||||
if (start !== positions[index]) {
|
||||
results.push(value.slice(start, positions[index]))
|
||||
}
|
||||
|
||||
results.push('\\')
|
||||
start = positions[index]
|
||||
}
|
||||
|
||||
results.push(value.slice(start))
|
||||
|
||||
return results.join('')
|
||||
}
|
||||
Reference in New Issue
Block a user