40 lines
1 KiB
JavaScript
40 lines
1 KiB
JavaScript
|
var punycode = require('punycode');
|
||
|
var revEntities = require('./reversed.json');
|
||
|
|
||
|
module.exports = encode;
|
||
|
|
||
|
function encode (str, opts) {
|
||
|
if (typeof str !== 'string') {
|
||
|
throw new TypeError('Expected a String');
|
||
|
}
|
||
|
if (!opts) opts = {};
|
||
|
|
||
|
var numeric = true;
|
||
|
if (opts.named) numeric = false;
|
||
|
if (opts.numeric !== undefined) numeric = opts.numeric;
|
||
|
|
||
|
var special = opts.special || {
|
||
|
'"': true, "'": true,
|
||
|
'<': true, '>': true,
|
||
|
'&': true
|
||
|
};
|
||
|
|
||
|
var codePoints = punycode.ucs2.decode(str);
|
||
|
var chars = [];
|
||
|
for (var i = 0; i < codePoints.length; i++) {
|
||
|
var cc = codePoints[i];
|
||
|
var c = punycode.ucs2.encode([ cc ]);
|
||
|
var e = revEntities[cc];
|
||
|
if (e && (cc >= 127 || special[c]) && !numeric) {
|
||
|
chars.push('&' + (/;$/.test(e) ? e : e + ';'));
|
||
|
}
|
||
|
else if (cc < 32 || cc >= 127 || special[c]) {
|
||
|
chars.push('&#' + cc + ';');
|
||
|
}
|
||
|
else {
|
||
|
chars.push(c);
|
||
|
}
|
||
|
}
|
||
|
return chars.join('');
|
||
|
}
|