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.
72 lines
1.6 KiB
72 lines
1.6 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 |
|
}; |