UNPKG

1.18 kBJavaScriptView Raw
1/* Dependencies. */
2const has = require('has')
3const xtend = require('xtend')
4
5/* Expose. */
6module.exports = encode
7
8encode.escape = escape
9
10/* List of enforced escapes. */
11const defaultEscapes = {
12 '#': '\\#',
13 '$': '\\$',
14 '%': '\\%',
15 '&': '\\&',
16 '\\': '\\textbackslash{}',
17 '^': '\\textasciicircum{}',
18 '_': '\\_',
19 '{': '\\{',
20 '}': '\\}',
21 '~': '\\textasciitilde{}',
22}
23
24/* Encode special characters in `value`. */
25function encode (value, opts = {}) {
26 const escapes = xtend(defaultEscapes, opts)
27 const set = toExpression(Object.keys(escapes))
28
29 value = value.replace(set, function (char, pos, val) {
30 return one(char, val.charAt(pos + 1), escapes)
31 })
32
33 return value
34}
35
36/* Encode `char` according to `options`. */
37function one (char, next, escapes) {
38 if (has(escapes, char)) {
39 return escapes[char]
40 }
41
42 return char
43}
44
45/* Create an expression for `characters`. */
46function toExpression (characters) {
47 const pattern = characters.map(escapeRegExp).join('|')
48
49 return new RegExp(`[${pattern}]`, 'g')
50}
51
52function escapeRegExp (str) {
53 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') // eslint-disable-line no-useless-escape
54}