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.
70 lines
1.8 KiB
70 lines
1.8 KiB
var entityMap = require("../maps/entities.json"), |
|
legacyMap = require("../maps/legacy.json"), |
|
xmlMap = require("../maps/xml.json"), |
|
decodeCodePoint = require("./decode_codepoint.js"); |
|
|
|
var decodeXMLStrict = getStrictDecoder(xmlMap), |
|
decodeHTMLStrict = getStrictDecoder(entityMap); |
|
|
|
function getStrictDecoder(map) { |
|
var keys = Object.keys(map).join("|"), |
|
replace = getReplacer(map); |
|
|
|
keys += "|#[xX][\\da-fA-F]+|#\\d+"; |
|
|
|
var re = new RegExp("&(?:" + keys + ");", "g"); |
|
|
|
return function(str) { |
|
return String(str).replace(re, replace); |
|
}; |
|
} |
|
|
|
var decodeHTML = (function() { |
|
var legacy = Object.keys(legacyMap).sort(sorter); |
|
|
|
var keys = Object.keys(entityMap).sort(sorter); |
|
|
|
for (var i = 0, j = 0; i < keys.length; i++) { |
|
if (legacy[j] === keys[i]) { |
|
keys[i] += ";?"; |
|
j++; |
|
} else { |
|
keys[i] += ";"; |
|
} |
|
} |
|
|
|
var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"), |
|
replace = getReplacer(entityMap); |
|
|
|
function replacer(str) { |
|
if (str.substr(-1) !== ";") str += ";"; |
|
return replace(str); |
|
} |
|
|
|
//TODO consider creating a merged map |
|
return function(str) { |
|
return String(str).replace(re, replacer); |
|
}; |
|
})(); |
|
|
|
function sorter(a, b) { |
|
return a < b ? 1 : -1; |
|
} |
|
|
|
function getReplacer(map) { |
|
return function replace(str) { |
|
if (str.charAt(1) === "#") { |
|
if (str.charAt(2) === "X" || str.charAt(2) === "x") { |
|
return decodeCodePoint(parseInt(str.substr(3), 16)); |
|
} |
|
return decodeCodePoint(parseInt(str.substr(2), 10)); |
|
} |
|
return map[str.slice(1, -1)]; |
|
}; |
|
} |
|
|
|
module.exports = { |
|
XML: decodeXMLStrict, |
|
HTML: decodeHTML, |
|
HTMLStrict: decodeHTMLStrict |
|
};
|
|
|