| 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 |
| }; |