Skip to content

Commit ba6320e

Browse files
committed
add string_mappings constants file:
- use it in html2unicode and svg_text_utils to translate a limited set of HTML enitity to unicode - list unicode-to-entities mappings (used in svg text style and anchors)
1 parent 5b0d4cb commit ba6320e

File tree

3 files changed

+75
-14
lines changed

3 files changed

+75
-14
lines changed

src/constants/string_mappings.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright 2012-2016, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
// N.B. HTML entities are listed without the leading '&' and trailing ';'
13+
14+
module.exports = {
15+
16+
entityToUnicode: {
17+
'mu': 'μ',
18+
'amp': '&',
19+
'lt': '<',
20+
'gt': '>',
21+
'quot': '\"',
22+
'nbsp': ' ',
23+
'times': '×',
24+
'plusmn': '±',
25+
'deg': '°'
26+
},
27+
28+
unicodeToEntity: {
29+
'&': 'amp',
30+
'<': 'lt',
31+
'>': 'gt',
32+
'"': 'quot',
33+
'\'': '#x27',
34+
'\/': '#x2F'
35+
}
36+
37+
};

src/lib/html2unicode.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,7 @@
1010
'use strict';
1111

1212
var toSuperScript = require('superscript-text');
13-
14-
var ENTITIES = {
15-
'mu': 'μ',
16-
'amp': '&',
17-
'lt': '<',
18-
'gt': '>'
19-
};
13+
var stringMappings = require('../constants/string_mappings');
2014

2115
function fixSuperScript(x) {
2216
var idx = 0;
@@ -40,6 +34,7 @@ function stripTags(x) {
4034
}
4135

4236
function fixEntities(x) {
37+
var entityToUnicode = stringMappings.entityToUnicode;
4338
var idx = 0;
4439

4540
while((idx = x.indexOf('&', idx)) >= 0) {
@@ -49,7 +44,7 @@ function fixEntities(x) {
4944
continue;
5045
}
5146

52-
var entity = ENTITIES[x.slice(idx + 1, nidx)];
47+
var entity = entityToUnicode[x.slice(idx + 1, nidx)];
5348
if(entity) {
5449
x = x.slice(0, idx) + entity + x.slice(nidx + 1);
5550
} else {

src/lib/svg_text_utils.js

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var d3 = require('d3');
1515

1616
var Lib = require('../lib');
1717
var xmlnsNamespaces = require('../constants/xmlns_namespaces');
18+
var stringMappings = require('../constants/string_mappings');
1819

1920
// Append SVG
2021

@@ -67,6 +68,7 @@ exports.convertToTspans = function(_context, _callback) {
6768
var str = _context.text();
6869
var converted = convertToSVG(str);
6970
var that = _context;
71+
7072
// Until we get tex integrated more fully (so it can be used along with non-tex)
7173
// allow some elements to prohibit it by attaching 'data-notex' to the original
7274
var tex = (!that.attr('data-notex')) && converted.match(/([^$]*)([$]+[^$]*[$]+)([^$]*)/);
@@ -233,22 +235,48 @@ var PROTOCOLS = ['http:', 'https:', 'mailto:'];
233235

234236
var STRIP_TAGS = new RegExp('</?(' + Object.keys(TAG_STYLES).join('|') + ')( [^>]*)?/?>', 'g');
235237

238+
var ENTITY_TO_UNICODE = Object.keys(stringMappings.entityToUnicode).map(function(k) {
239+
return {
240+
regExp: new RegExp('&' + k + ';', 'g'),
241+
sub: stringMappings.entityToUnicode[k]
242+
};
243+
});
244+
245+
var UNICODE_TO_ENTITY = Object.keys(stringMappings.unicodeToEntity).map(function(k) {
246+
return {
247+
regExp: new RegExp(k, 'g'),
248+
sub: '&' + stringMappings.unicodeToEntity[k] + ';'
249+
};
250+
});
251+
236252
exports.plainText = function(_str) {
237253
// strip out our pseudo-html so we have a readable
238254
// version to put into text fields
239255
return (_str || '').replace(STRIP_TAGS, ' ');
240256
};
241257

258+
function replaceFromMapObject(_str, list) {
259+
var out = _str || '';
260+
261+
for(var i = 0; i < list.length; i++) {
262+
var item = list[i];
263+
out = out.replace(item.regExp, item.sub);
264+
}
265+
266+
return out;
267+
}
268+
269+
function convertEntities(_str) {
270+
return replaceFromMapObject(_str, ENTITY_TO_UNICODE);
271+
}
272+
242273
function encodeForHTML(_str) {
243-
return (_str || '').replace(/&/g, '&amp;')
244-
.replace(/</g, '&lt;')
245-
.replace(/>/g, '&gt;')
246-
.replace(/"/g, '&quot;')
247-
.replace(/'/g, '&#x27;')
248-
.replace(/\//g, '&#x2F;');
274+
return replaceFromMapObject(_str, UNICODE_TO_ENTITY);
249275
}
250276

251277
function convertToSVG(_str) {
278+
_str = convertEntities(_str);
279+
252280
var result = _str
253281
.split(/(<[^<>]*>)/).map(function(d) {
254282
var match = d.match(/<(\/?)([^ >]*)\s*(.*)>/i),
@@ -267,6 +295,7 @@ function convertToSVG(_str) {
267295
* resurrect it.
268296
*/
269297
extraStyle = extra.match(/^style\s*=\s*"([^"]+)"\s*/i);
298+
270299
// anchor and br are the only ones that don't turn into a tspan
271300
if(tag === 'a') {
272301
if(close) return '</a>';

0 commit comments

Comments
 (0)