encode.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. var inverseXML = getInverseObj(require("../maps/xml.json")),
  2. xmlReplacer = getInverseReplacer(inverseXML);
  3. exports.XML = getInverse(inverseXML, xmlReplacer);
  4. var inverseHTML = getInverseObj(require("../maps/entities.json")),
  5. htmlReplacer = getInverseReplacer(inverseHTML);
  6. exports.HTML = getInverse(inverseHTML, htmlReplacer);
  7. function getInverseObj(obj){
  8. return Object.keys(obj).sort().reduce(function(inverse, name){
  9. inverse[obj[name]] = "&" + name + ";";
  10. return inverse;
  11. }, {});
  12. }
  13. function getInverseReplacer(inverse){
  14. return new RegExp("\\" + Object.keys(inverse).sort().join("|\\"), "g");
  15. }
  16. var re_nonASCII = /[^\0-\x7F]/g,
  17. re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
  18. function nonUTF8Replacer(c){
  19. return "&#x" + c.charCodeAt(0).toString(16).toUpperCase() + ";";
  20. }
  21. function astralReplacer(c){
  22. // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
  23. var high = c.charCodeAt(0);
  24. var low = c.charCodeAt(1);
  25. var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
  26. return "&#x" + codePoint.toString(16).toUpperCase() + ";";
  27. }
  28. function getInverse(inverse, re){
  29. function func(name){
  30. return inverse[name];
  31. }
  32. return function(data){
  33. return data
  34. .replace(re, func)
  35. .replace(re_astralSymbols, astralReplacer)
  36. .replace(re_nonASCII, nonUTF8Replacer);
  37. };
  38. }