Skip to content

Commit 554c2e8

Browse files
feat: add utils
for manipulating the named HTML entities
1 parent 6ca7443 commit 554c2e8

File tree

7 files changed

+308
-0
lines changed

7 files changed

+308
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,17 @@ import {
8080
<MjmlConditionalComment condition="if IE">MSO conditionals</MjmlConditionalComment>
8181
// <!--[if IE]>MSO conditionals<![endif]-->
8282
```
83+
84+
## Utils
85+
86+
We do have also some utils for post processing the output HTML.
87+
Because not all mail clients do support named HTML entities, like `&apos;`.
88+
So we need to replace them to hex.
89+
90+
```js
91+
import {namedEntityToHexCode} from 'mjml-react/utils';
92+
93+
const html = '<div>&apos;</div>';
94+
namedEntityToHexCode(html);
95+
// <div>&#39;</div>
96+
```

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"main": "dist/src/index.js",
1010
"files": [
1111
"extensions.js",
12+
"entities.js",
1213
"dist"
1314
],
1415
"publishConfig": {

src/utils/html-entities.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const entities = require('./html-entities.json');
2+
3+
export function namedEntityToHexCode(html) {
4+
return html.replace(/&([a-z0-9]{2,8});/ig, (match, p1) => {
5+
if (entities[p1]) {
6+
return `&#${entities[p1]};`;
7+
}
8+
return match;
9+
});
10+
}

src/utils/html-entities.json

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
{
2+
"apos": 39,
3+
"nbsp": 160,
4+
"iexcl": 161,
5+
"cent": 162,
6+
"pound": 163,
7+
"curren": 164,
8+
"yen": 165,
9+
"brvbar": 166,
10+
"sect": 167,
11+
"uml": 168,
12+
"copy": 169,
13+
"ordf": 170,
14+
"laquo": 171,
15+
"not": 172,
16+
"shy": 173,
17+
"reg": 174,
18+
"macr": 175,
19+
"deg": 176,
20+
"plusmn": 177,
21+
"sup2": 178,
22+
"sup3": 179,
23+
"acute": 180,
24+
"micro": 181,
25+
"para": 182,
26+
"middot": 183,
27+
"cedil": 184,
28+
"sup1": 185,
29+
"ordm": 186,
30+
"raquo": 187,
31+
"frac14": 188,
32+
"frac12": 189,
33+
"frac34": 190,
34+
"iquest": 191,
35+
"Agrave": 192,
36+
"Aacute": 193,
37+
"Acirc": 194,
38+
"Atilde": 195,
39+
"Auml": 196,
40+
"Aring": 197,
41+
"Aelig": 198,
42+
"Ccedil": 199,
43+
"Egrave": 200,
44+
"Eacute": 201,
45+
"Ecirc": 202,
46+
"Euml": 203,
47+
"Igrave": 204,
48+
"Iacute": 205,
49+
"Icirc": 206,
50+
"Iuml": 207,
51+
"ETH": 208,
52+
"Ntilde": 209,
53+
"Ograve": 210,
54+
"Oacute": 211,
55+
"Ocirc": 212,
56+
"Otilde": 213,
57+
"Ouml": 214,
58+
"times": 215,
59+
"Oslash": 216,
60+
"Ugrave": 217,
61+
"Uacute": 218,
62+
"Ucirc": 219,
63+
"Uuml": 220,
64+
"Yacute": 221,
65+
"THORN": 222,
66+
"szlig": 223,
67+
"agrave": 224,
68+
"aacute": 225,
69+
"acirc": 226,
70+
"atilde": 227,
71+
"auml": 228,
72+
"aring": 229,
73+
"aelig": 230,
74+
"ccedil": 231,
75+
"egrave": 232,
76+
"eacute": 233,
77+
"ecirc": 234,
78+
"euml": 235,
79+
"igrave": 236,
80+
"iacute": 237,
81+
"icirc": 238,
82+
"iuml": 239,
83+
"eth": 240,
84+
"ntilde": 241,
85+
"ograve": 242,
86+
"oacute": 243,
87+
"ocirc": 244,
88+
"otilde": 245,
89+
"ouml": 246,
90+
"divide": 247,
91+
"oslash": 248,
92+
"ugrave": 249,
93+
"uacute": 250,
94+
"ucirc": 251,
95+
"uuml": 252,
96+
"yacute": 253,
97+
"thorn": 254,
98+
"yuml": 255,
99+
"quot": 34,
100+
"amp": 38,
101+
"lt": 60,
102+
"gt": 62,
103+
"OElig": 338,
104+
"oelig": 339,
105+
"Scaron": 352,
106+
"scaron": 353,
107+
"Yuml": 376,
108+
"circ": 710,
109+
"tilde": 732,
110+
"ensp": 8194,
111+
"emsp": 8195,
112+
"thinsp": 8201,
113+
"zwnj": 8204,
114+
"zwj": 8205,
115+
"lrm": 8206,
116+
"rlm": 8207,
117+
"ndash": 8211,
118+
"mdash": 8212,
119+
"lsquo": 8216,
120+
"rsquo": 8217,
121+
"sbquo": 8218,
122+
"ldquo": 8220,
123+
"rdquo": 8221,
124+
"bdquo": 8222,
125+
"dagger": 8224,
126+
"Dagger": 8225,
127+
"permil": 8240,
128+
"lsaquo": 8249,
129+
"rsaquo": 8250,
130+
"euro": 8364,
131+
"fnof": 402,
132+
"Alpha": 913,
133+
"Beta": 914,
134+
"Gamma": 915,
135+
"Delta": 916,
136+
"Epsilon": 917,
137+
"Zeta": 918,
138+
"Eta": 919,
139+
"Theta": 920,
140+
"Iota": 921,
141+
"Kappa": 922,
142+
"Lambda": 923,
143+
"Mu": 924,
144+
"Nu": 925,
145+
"Xi": 926,
146+
"Omicron": 927,
147+
"Pi": 928,
148+
"Rho": 929,
149+
"Sigma": 931,
150+
"Tau": 932,
151+
"Upsilon": 933,
152+
"Phi": 934,
153+
"Chi": 935,
154+
"Psi": 936,
155+
"Omega": 937,
156+
"alpha": 945,
157+
"beta": 946,
158+
"gamma": 947,
159+
"delta": 948,
160+
"epsilon": 949,
161+
"zeta": 950,
162+
"eta": 951,
163+
"theta": 952,
164+
"iota": 953,
165+
"kappa": 954,
166+
"lambda": 955,
167+
"mu": 956,
168+
"nu": 957,
169+
"xi": 958,
170+
"omicron": 959,
171+
"pi": 960,
172+
"rho": 961,
173+
"sigmaf": 962,
174+
"sigma": 963,
175+
"tau": 964,
176+
"upsilon": 965,
177+
"phi": 966,
178+
"chi": 967,
179+
"psi": 968,
180+
"omega": 969,
181+
"thetasym": 977,
182+
"upsih": 978,
183+
"piv": 982,
184+
"bull": 8226,
185+
"hellip": 8230,
186+
"prime": 8242,
187+
"Prime": 8243,
188+
"oline": 8254,
189+
"frasl": 8260,
190+
"weierp": 8472,
191+
"image": 8465,
192+
"real": 8476,
193+
"trade": 8482,
194+
"alefsym": 8501,
195+
"larr": 8592,
196+
"uarr": 8593,
197+
"rarr": 8594,
198+
"darr": 8595,
199+
"harr": 8596,
200+
"crarr": 8629,
201+
"lArr": 8656,
202+
"uArr": 8657,
203+
"rArr": 8658,
204+
"dArr": 8659,
205+
"hArr": 8660,
206+
"forall": 8704,
207+
"part": 8706,
208+
"exist": 8707,
209+
"empty": 8709,
210+
"nabla": 8711,
211+
"isin": 8712,
212+
"notin": 8713,
213+
"ni": 8715,
214+
"prod": 8719,
215+
"sum": 8721,
216+
"minus": 8722,
217+
"lowast": 8727,
218+
"radic": 8730,
219+
"prop": 8733,
220+
"infin": 8734,
221+
"ang": 8736,
222+
"and": 8743,
223+
"or": 8744,
224+
"cap": 8745,
225+
"cup": 8746,
226+
"int": 8747,
227+
"there4": 8756,
228+
"sim": 8764,
229+
"cong": 8773,
230+
"asymp": 8776,
231+
"ne": 8800,
232+
"equiv": 8801,
233+
"le": 8804,
234+
"ge": 8805,
235+
"sub": 8834,
236+
"sup": 8835,
237+
"nsub": 8836,
238+
"sube": 8838,
239+
"supe": 8839,
240+
"oplus": 8853,
241+
"otimes": 8855,
242+
"perp": 8869,
243+
"sdot": 8901,
244+
"lceil": 8968,
245+
"rceil": 8969,
246+
"lfloor": 8970,
247+
"rfloor": 8971,
248+
"lang": 9001,
249+
"rang": 9002,
250+
"loz": 9674,
251+
"spades": 9824,
252+
"clubs": 9827,
253+
"hearts": 9829,
254+
"diams": 9830
255+
}

src/utils/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {namedEntityToHexCode} from './html-entities';

test/utils.spec.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {expect} from 'chai';
2+
3+
import {namedEntityToHexCode} from '../src/utils/index';
4+
5+
describe('utils', () => {
6+
7+
describe('namedEntityToHexCode', () => {
8+
it('should not replace incomplete entity', () => {
9+
expect(namedEntityToHexCode('&amp')).to.equal('&amp');
10+
});
11+
12+
it('should not replace unknown entity', () => {
13+
expect(namedEntityToHexCode('&rambo;')).to.equal('&rambo;');
14+
});
15+
16+
it('should not replace entity in hex code', () => {
17+
expect(namedEntityToHexCode('&#38;')).to.equal('&#38;');
18+
});
19+
20+
it('should replace known entity to hex code', () => {
21+
expect(namedEntityToHexCode('&amp;')).to.equal('&#38;');
22+
expect(namedEntityToHexCode('&apos;')).to.equal('&#39;');
23+
});
24+
});
25+
26+
});

utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./dist/src/utils/index');

0 commit comments

Comments
 (0)