pseudo-localization 2.0.2 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -0
- package/bin/pseudo-localize +147 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/localize.d.ts +5 -0
- package/lib/localize.js +1 -1
- package/lib/localize.js.map +1 -1
- package/lib/localize.test.js +2 -0
- package/lib/localize.test.js.map +1 -0
- package/package.json +21 -8
- package/CHANGELOG.md +0 -43
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
[](https://codesandbox.io/s/1q7n08or4j)
|
|
12
|
+
|
|
11
13
|
`pseudo-localization` is a script that performs [pseudolocalization](https://en.wikipedia.org/wiki/Pseudolocalization) against the DOM or individual strings.
|
|
12
14
|
|
|
13
15
|
[Demo here](https://tryggvigy.github.io/pseudo-localization/hamlet.html). Changing text nodes and adding or removing trees of elements will trigger a pseudo-localization run on all the new text added to the DOM. Try it yourself by changing text or adding/removing elements using the devtools.
|
|
@@ -70,6 +72,34 @@ class Page extends React.Component {
|
|
|
70
72
|
}
|
|
71
73
|
```
|
|
72
74
|
|
|
75
|
+
Using hooks? Here's an example:
|
|
76
|
+
|
|
77
|
+
```jsx
|
|
78
|
+
import React from 'react';
|
|
79
|
+
import pseudoLocalization from 'pseudo-localization';
|
|
80
|
+
|
|
81
|
+
function PseudoLocalization() {
|
|
82
|
+
React.useEffect(() => {
|
|
83
|
+
pseudoLocalization.start();
|
|
84
|
+
|
|
85
|
+
return () => {
|
|
86
|
+
pseudoLocalization.stop()
|
|
87
|
+
};
|
|
88
|
+
}, []);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// And use it
|
|
92
|
+
|
|
93
|
+
function Page() {
|
|
94
|
+
return (
|
|
95
|
+
<main>
|
|
96
|
+
<PseudoLocalization />
|
|
97
|
+
<h1>I will get pseudo localized along with everything else under document.body!</h1>
|
|
98
|
+
<main>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
73
103
|
You can also call the underlying `localize` function to pseudo-localize any string. This is useful for non-browser environments like nodejs.
|
|
74
104
|
|
|
75
105
|
|
|
@@ -168,6 +198,46 @@ Accepts an `options` object as an argument. Here are the keys in the `options` o
|
|
|
168
198
|
#### `strategy` - default (`'accented'`)
|
|
169
199
|
The pseudo localization strategy to use when transforming strings. Accepted values are `accented` or `bidi`.
|
|
170
200
|
|
|
201
|
+
## CLI Interface
|
|
202
|
+
For easy scripting a CLI interface is exposed. The interface supports raw input, JSON files, and CommonJS modules.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npx pseudo-localization ./path/to/file.json
|
|
206
|
+
|
|
207
|
+
# pass in a JS transpiled ES module or an exported CJS module
|
|
208
|
+
npx pseudo-localization ./path/to/file
|
|
209
|
+
|
|
210
|
+
# pass in JSON files through STDIN
|
|
211
|
+
cat ./path/to/file.json | npx pseudo-localization --strategy bidi
|
|
212
|
+
|
|
213
|
+
# pass a string via a pipe
|
|
214
|
+
echo hello world | npx pseudo-localization
|
|
215
|
+
|
|
216
|
+
# direct input pseudo-localization
|
|
217
|
+
npx pseudo-localization -i "hello world"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
CLI Options:
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
pseudo-localization [src] [options]
|
|
224
|
+
|
|
225
|
+
Pseudo localize a string, JSON file, or a JavaScript object
|
|
226
|
+
|
|
227
|
+
Positionals:
|
|
228
|
+
src The source as a path or from STDIN [string]
|
|
229
|
+
|
|
230
|
+
Options:
|
|
231
|
+
-o, --output Writes output to STDOUT by default. Optionally specify a JSON
|
|
232
|
+
file to write the pseudo-localizations to [string]
|
|
233
|
+
-i, --input Pass in direct input to pseudo-localization [string]
|
|
234
|
+
--debug Print out all stack traces and other debug info [boolean]
|
|
235
|
+
--pretty Pretty print JSON output [boolean]
|
|
236
|
+
--strategy Set the strategy for localization
|
|
237
|
+
[choices: "accented", "bidi"] [default: "accented"]
|
|
238
|
+
--help Show help [boolean]
|
|
239
|
+
--version Show version number [boolean]
|
|
240
|
+
```
|
|
171
241
|
|
|
172
242
|
## Support
|
|
173
243
|
Works in all evergreen browsers.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const getStdin = require('get-stdin');
|
|
6
|
+
const flatten = require('flat');
|
|
7
|
+
const unflatten = require('flat').unflatten;
|
|
8
|
+
|
|
9
|
+
const { localize } = require('../lib/index');
|
|
10
|
+
|
|
11
|
+
const argv = require('yargs')
|
|
12
|
+
.usage(
|
|
13
|
+
'$0 [src] [options]',
|
|
14
|
+
'Pseudo localize a string, JSON file, or a JavaScript object',
|
|
15
|
+
function(yargs) {
|
|
16
|
+
yargs.positional('src', {
|
|
17
|
+
describe: 'The source as a path or from STDIN',
|
|
18
|
+
type: 'string',
|
|
19
|
+
coerce: path.resolve,
|
|
20
|
+
conflicts: 'i',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
.options({
|
|
25
|
+
o: {
|
|
26
|
+
alias: 'output',
|
|
27
|
+
describe:
|
|
28
|
+
'Writes output to STDOUT by default. Optionally specify a JSON file to write the pseudo-localizations to',
|
|
29
|
+
type: 'string',
|
|
30
|
+
coerce: path.resolve,
|
|
31
|
+
},
|
|
32
|
+
i: {
|
|
33
|
+
alias: 'input',
|
|
34
|
+
describe: 'Pass in direct input to pseudo-localize',
|
|
35
|
+
type: 'string',
|
|
36
|
+
conflicts: 'src',
|
|
37
|
+
},
|
|
38
|
+
debug: {
|
|
39
|
+
describe: 'Print out all stack traces and other debug info',
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
},
|
|
42
|
+
pretty: {
|
|
43
|
+
describe: 'Pretty print JSON output',
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
},
|
|
46
|
+
strategy: {
|
|
47
|
+
describe: 'Set the strategy for localization',
|
|
48
|
+
choices: ['accented', 'bidi'],
|
|
49
|
+
default: 'accented',
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
.help()
|
|
53
|
+
.version().argv;
|
|
54
|
+
|
|
55
|
+
const debug = function(e) {
|
|
56
|
+
if (argv.debug) {
|
|
57
|
+
console.error(e);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const write = function(output) {
|
|
62
|
+
argv.output ? fs.writeFileSync(argv.output, output) : fs.writeSync(1, output);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const convert = function(input) {
|
|
66
|
+
const options = { strategy: argv.strategy };
|
|
67
|
+
|
|
68
|
+
if (typeof input === 'string') {
|
|
69
|
+
write(localize(input, options));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Flatten nested translation JSONs
|
|
74
|
+
input = flatten(input, {
|
|
75
|
+
safe: true,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
for (let key in input) {
|
|
79
|
+
// this will need to be updated if other primitives
|
|
80
|
+
// support pseudo-localization
|
|
81
|
+
if (typeof input[key] === 'string') {
|
|
82
|
+
input[key] = localize(input[key], options);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Retrieve initial JSON structure
|
|
87
|
+
output = unflatten(input, {
|
|
88
|
+
safe: true,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
write(JSON.stringify(output, null, argv.pretty ? 4 : undefined) + '\n');
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
(function() {
|
|
95
|
+
'use strict';
|
|
96
|
+
|
|
97
|
+
let json = null;
|
|
98
|
+
|
|
99
|
+
if (argv.i) {
|
|
100
|
+
convert(argv.i + '\n');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (argv.src) {
|
|
105
|
+
try {
|
|
106
|
+
json = require(argv.src);
|
|
107
|
+
|
|
108
|
+
if (json.default) {
|
|
109
|
+
json = json.default;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
convert(json);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
debug(e);
|
|
115
|
+
|
|
116
|
+
console.error(
|
|
117
|
+
`${e.message}\nUnable to parse input file. Make sure it is in JSON format or is an exported JS module`
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
getStdin()
|
|
124
|
+
.then(function(input) {
|
|
125
|
+
if (!input) {
|
|
126
|
+
console.warn('No input from STDIN detected. Exiting...');
|
|
127
|
+
process.exit(0);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let string = input;
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
string = JSON.parse(input);
|
|
134
|
+
} catch (e) {
|
|
135
|
+
// do nothing
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
convert(string);
|
|
139
|
+
})
|
|
140
|
+
.catch(function(e) {
|
|
141
|
+
debug(e);
|
|
142
|
+
console.error(
|
|
143
|
+
`${e.message}\nUnable to parse source from STDIN. Is it a valid JSON file?`
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
})(argv);
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { pseudoLocalizeString, Options } from './localize';
|
|
2
|
+
/**
|
|
3
|
+
* export the underlying pseudo localization function so this import style
|
|
4
|
+
* import { localize } from 'pseudo-localization';
|
|
5
|
+
* can be used.
|
|
6
|
+
*/
|
|
7
|
+
export { pseudoLocalizeString as localize };
|
|
8
|
+
declare type StartOptions = Options & {
|
|
9
|
+
blacklistedNodeNames?: string[];
|
|
10
|
+
};
|
|
11
|
+
declare const pseudoLocalization: {
|
|
12
|
+
start: ({ strategy, blacklistedNodeNames, }?: StartOptions) => void;
|
|
13
|
+
stop: () => void;
|
|
14
|
+
localize: (string: string, { strategy }?: Options) => string;
|
|
15
|
+
};
|
|
16
|
+
export default pseudoLocalization;
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"localize",{enumerable:true,get:function get(){return _localize.default}});exports.default=void 0;var _localize=_interopRequireDefault(require("./localize.js"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}var pseudoLocalization=function(){var opts={blacklistedNodeNames:["STYLE"]};var observer=null;var observerConfig={characterData:true,childList:true,subtree:true};var textNodesUnder=function textNodesUnder(element){var walker=document.createTreeWalker(element,NodeFilter.SHOW_TEXT,function(node){var isAllWhitespace=!/[^\s]/.test(node.nodeValue);if(isAllWhitespace)return NodeFilter.FILTER_REJECT;var isBlacklistedNode=opts.blacklistedNodeNames.includes(node.parentElement.nodeName);if(isBlacklistedNode)return NodeFilter.FILTER_REJECT;return NodeFilter.FILTER_ACCEPT});var currNode;var textNodes=[];while(currNode=walker.nextNode()){textNodes.push(currNode)}return textNodes};var isNonEmptyString=function isNonEmptyString(str){return str&&typeof str==="string"};var pseudoLocalize=function pseudoLocalize(element){var textNodesUnderElement=textNodesUnder(element);var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"localize",{enumerable:true,get:function get(){return _localize.default}});exports.default=void 0;var _localize=_interopRequireDefault(require("./localize.js"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _createForOfIteratorHelper(o,allowArrayLike){var it=typeof Symbol!=="undefined"&&o[Symbol.iterator]||o["@@iterator"];if(!it){if(Array.isArray(o)||(it=_unsupportedIterableToArray(o))||allowArrayLike&&o&&typeof o.length==="number"){if(it)o=it;var i=0;var F=function F(){};return{s:F,n:function n(){if(i>=o.length)return{done:true};return{done:false,value:o[i++]}},e:function e(_e){throw _e},f:F}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var normalCompletion=true,didErr=false,err;return{s:function s(){it=it.call(o)},n:function n(){var step=it.next();normalCompletion=step.done;return step},e:function e(_e2){didErr=true;err=_e2},f:function f(){try{if(!normalCompletion&&it.return!=null)it.return()}finally{if(didErr)throw err}}}}function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen)}function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++){arr2[i]=arr[i]}return arr2}var pseudoLocalization=function(){var opts={blacklistedNodeNames:["STYLE"]};var observer=null;var observerConfig={characterData:true,childList:true,subtree:true};var textNodesUnder=function textNodesUnder(element){var walker=document.createTreeWalker(element,NodeFilter.SHOW_TEXT,function(node){var isAllWhitespace=!/[^\s]/.test(node.nodeValue);if(isAllWhitespace)return NodeFilter.FILTER_REJECT;var isBlacklistedNode=opts.blacklistedNodeNames.includes(node.parentElement.nodeName);if(isBlacklistedNode)return NodeFilter.FILTER_REJECT;return NodeFilter.FILTER_ACCEPT});var currNode;var textNodes=[];while(currNode=walker.nextNode()){textNodes.push(currNode)}return textNodes};var isNonEmptyString=function isNonEmptyString(str){return str&&typeof str==="string"};var pseudoLocalize=function pseudoLocalize(element){var textNodesUnderElement=textNodesUnder(element);var _iterator=_createForOfIteratorHelper(textNodesUnderElement),_step;try{for(_iterator.s();!(_step=_iterator.n()).done;){var textNode=_step.value;var nodeValue=textNode.nodeValue;if(isNonEmptyString(nodeValue)){textNode.nodeValue=(0,_localize.default)(nodeValue,opts)}}}catch(err){_iterator.e(err)}finally{_iterator.f()}};var domMutationCallback=function domMutationCallback(mutationsList){var _iterator2=_createForOfIteratorHelper(mutationsList),_step2;try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){var mutation=_step2.value;if(mutation.type==="childList"&&mutation.addedNodes.length>0){observer.disconnect();mutation.addedNodes.forEach(pseudoLocalize);observer.observe(document.body,observerConfig)}else if(mutation.type==="characterData"){var nodeValue=mutation.target.nodeValue;var isBlacklistedNode=opts.blacklistedNodeNames.includes(mutation.target.parentElement.nodeName);if(isNonEmptyString(nodeValue)&&!isBlacklistedNode){observer.disconnect();mutation.target.nodeValue=(0,_localize.default)(nodeValue,opts);observer.observe(document.body,observerConfig)}}}}catch(err){_iterator2.e(err)}finally{_iterator2.f()}};var start=function start(){var _ref=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{},_ref$strategy=_ref.strategy,strategy=_ref$strategy===void 0?"accented":_ref$strategy,_ref$blacklistedNodeN=_ref.blacklistedNodeNames,blacklistedNodeNames=_ref$blacklistedNodeN===void 0?opts.blacklistedNodeNames:_ref$blacklistedNodeN;opts.blacklistedNodeNames=blacklistedNodeNames;opts.strategy=strategy;pseudoLocalize(document.body);observer=new MutationObserver(domMutationCallback);observer.observe(document.body,observerConfig)};var stop=function stop(){observer&&observer.disconnect()};return{start:start,stop:stop,localize:_localize.default}}();var _default=pseudoLocalization;exports.default=_default;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["pseudoLocalization","opts","blacklistedNodeNames","observer","observerConfig","characterData","childList","subtree","textNodesUnder","element","walker","document","createTreeWalker","NodeFilter","SHOW_TEXT","node","isAllWhitespace","test","nodeValue","FILTER_REJECT","isBlacklistedNode","includes","parentElement","nodeName","FILTER_ACCEPT","currNode","textNodes","nextNode","push","isNonEmptyString","str","pseudoLocalize","textNodesUnderElement","textNode","domMutationCallback","mutationsList","mutation","type","addedNodes","length","disconnect","forEach","observe","body","target","start","strategy","MutationObserver","stop","localize","pseudoLocalizeString"],"mappings":"sMAAA,+D,
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["pseudoLocalization","opts","blacklistedNodeNames","observer","observerConfig","characterData","childList","subtree","textNodesUnder","element","walker","document","createTreeWalker","NodeFilter","SHOW_TEXT","node","isAllWhitespace","test","nodeValue","FILTER_REJECT","isBlacklistedNode","includes","parentElement","nodeName","FILTER_ACCEPT","currNode","textNodes","nextNode","push","isNonEmptyString","str","pseudoLocalize","textNodesUnderElement","textNode","domMutationCallback","mutationsList","mutation","type","addedNodes","length","disconnect","forEach","observe","body","target","start","strategy","MutationObserver","stop","localize","pseudoLocalizeString"],"mappings":"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","sourcesContent":["import pseudoLocalizeString from './localize.js';\n\n/**\n * export the underlying pseudo localization function so this import style\n * import { localize } from 'pseudo-localization';\n * can be used.\n */\nexport { default as localize } from './localize.js';\n\nconst pseudoLocalization = (() => {\n const opts = {\n blacklistedNodeNames: ['STYLE'],\n };\n\n // Observer for dom updates. Initialization is defered to make parts\n // of the API safe to use in non-browser environments like nodejs\n let observer = null;\n const observerConfig = {\n characterData: true,\n childList: true,\n subtree: true,\n };\n\n const textNodesUnder = element => {\n const walker = document.createTreeWalker(\n element,\n NodeFilter.SHOW_TEXT,\n node => {\n const isAllWhitespace = !/[^\\s]/.test(node.nodeValue);\n if (isAllWhitespace) return NodeFilter.FILTER_REJECT;\n\n const isBlacklistedNode = opts.blacklistedNodeNames.includes(\n node.parentElement.nodeName\n );\n if (isBlacklistedNode) return NodeFilter.FILTER_REJECT;\n\n return NodeFilter.FILTER_ACCEPT;\n }\n );\n\n let currNode;\n const textNodes = [];\n while ((currNode = walker.nextNode())) textNodes.push(currNode);\n return textNodes;\n };\n\n const isNonEmptyString = str => str && typeof str === 'string';\n\n const pseudoLocalize = element => {\n const textNodesUnderElement = textNodesUnder(element);\n for (let textNode of textNodesUnderElement) {\n const nodeValue = textNode.nodeValue;\n if (isNonEmptyString(nodeValue)) {\n textNode.nodeValue = pseudoLocalizeString(nodeValue, opts);\n }\n }\n };\n\n const domMutationCallback = mutationsList => {\n for (let mutation of mutationsList) {\n if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {\n // Turn the observer off while performing dom manipulation to prevent\n // infinite dom mutation callback loops\n observer.disconnect();\n // For every node added, recurse down it's subtree and convert\n // all children as well\n mutation.addedNodes.forEach(pseudoLocalize);\n observer.observe(document.body, observerConfig);\n } else if (mutation.type === 'characterData') {\n const nodeValue = mutation.target.nodeValue;\n const isBlacklistedNode = opts.blacklistedNodeNames.includes(\n mutation.target.parentElement.nodeName\n );\n if (isNonEmptyString(nodeValue) && !isBlacklistedNode) {\n // Turn the observer off while performing dom manipulation to prevent\n // infinite dom mutation callback loops\n observer.disconnect();\n // The target will always be a text node so it can be converted\n // directly\n mutation.target.nodeValue = pseudoLocalizeString(nodeValue, opts);\n observer.observe(document.body, observerConfig);\n }\n }\n }\n };\n\n const start = ({\n strategy = 'accented',\n blacklistedNodeNames = opts.blacklistedNodeNames,\n } = {}) => {\n opts.blacklistedNodeNames = blacklistedNodeNames;\n opts.strategy = strategy;\n // Pseudo localize the DOM\n pseudoLocalize(document.body);\n // Start observing the DOM for changes and run\n // pseudo localization on any added text nodes\n observer = new MutationObserver(domMutationCallback);\n observer.observe(document.body, observerConfig);\n };\n\n const stop = () => {\n observer && observer.disconnect();\n };\n\n return {\n start,\n stop,\n localize: pseudoLocalizeString,\n };\n})();\n\nexport default pseudoLocalization;\n"],"file":"index.js"}
|
package/lib/localize.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var ACCENTED_MAP={a:"\u0227",A:"\u0226",b:"\u0180",B:"\u0181",c:"\u0188",C:"\u0187",d:"\u1E13",D:"\u1E12",e:"\u1E17",E:"\u1E16",f:"\u0192",F:"\u0191",g:"\u0260",G:"\u0193",h:"\u0127",H:"\u0126",i:"\u012B",I:"\u012A",j:"\u0135",J:"\u0134",k:"\u0137",K:"\u0136",l:"\u0140",L:"\u013F",m:"\u1E3F",M:"\u1E3E",n:"\u019E",N:"\u0220",o:"\u01FF",O:"\u01FE",p:"\u01A5",P:"\u01A4",q:"\u024B",Q:"\u024A",r:"\u0159",R:"\u0158",s:"\u015F",S:"\u015E",t:"\u0167",T:"\u0166",v:"\u1E7D",V:"\u1E7C",u:"\u016D",U:"\u016C",w:"\u1E87",W:"\u1E86",x:"\u1E8B",X:"\u1E8A",y:"\u1E8F",Y:"\u1E8E",z:"\u1E91",Z:"\u1E90"};var BIDI_MAP={a:"\u0250",A:"\u2200",b:"q",B:"\u0510",c:"\u0254",C:"\u2183",d:"p",D:"\u15E1",e:"\u01DD",E:"\u018E",f:"\u025F",F:"\u2132",g:"\u0183",G:"\u2141",h:"\u0265",H:"H",i:"\u0131",I:"I",j:"\u027E",J:"\u017F",k:"\u029E",K:"\u04FC",l:"\u0285",L:"\u2142",m:"\u026F",M:"W",n:"u",N:"N",o:"o",O:"O",p:"d",P:"\u0500",q:"b",Q:"\xD2",r:"\u0279",R:"\u1D1A",s:"s",S:"S",t:"\u0287",T:"\u22A5",u:"n",U:"\u2229",v:"\u028C",V:"\u0245",w:"\u028D",W:"M",x:"x",X:"X",y:"\u028E",Y:"\u2144",z:"z",Z:"Z"};var strategies={accented:{prefix:"",postfix:"",map:ACCENTED_MAP,elongate:true},bidi:{prefix:"\u202E",postfix:"\u202C",map:BIDI_MAP,elongate:false}};var pseudoLocalizeString=function pseudoLocalizeString(string){var _ref=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{},_ref$strategy=_ref.strategy,strategy=_ref$strategy===void 0?"accented":_ref$strategy;var opts=strategies[strategy];var pseudoLocalizedText="";var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;function _createForOfIteratorHelper(o,allowArrayLike){var it=typeof Symbol!=="undefined"&&o[Symbol.iterator]||o["@@iterator"];if(!it){if(Array.isArray(o)||(it=_unsupportedIterableToArray(o))||allowArrayLike&&o&&typeof o.length==="number"){if(it)o=it;var i=0;var F=function F(){};return{s:F,n:function n(){if(i>=o.length)return{done:true};return{done:false,value:o[i++]}},e:function e(_e){throw _e},f:F}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var normalCompletion=true,didErr=false,err;return{s:function s(){it=it.call(o)},n:function n(){var step=it.next();normalCompletion=step.done;return step},e:function e(_e2){didErr=true;err=_e2},f:function f(){try{if(!normalCompletion&&it.return!=null)it.return()}finally{if(didErr)throw err}}}}function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen)}function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++){arr2[i]=arr[i]}return arr2}var ACCENTED_MAP={a:"\u0227",A:"\u0226",b:"\u0180",B:"\u0181",c:"\u0188",C:"\u0187",d:"\u1E13",D:"\u1E12",e:"\u1E17",E:"\u1E16",f:"\u0192",F:"\u0191",g:"\u0260",G:"\u0193",h:"\u0127",H:"\u0126",i:"\u012B",I:"\u012A",j:"\u0135",J:"\u0134",k:"\u0137",K:"\u0136",l:"\u0140",L:"\u013F",m:"\u1E3F",M:"\u1E3E",n:"\u019E",N:"\u0220",o:"\u01FF",O:"\u01FE",p:"\u01A5",P:"\u01A4",q:"\u024B",Q:"\u024A",r:"\u0159",R:"\u0158",s:"\u015F",S:"\u015E",t:"\u0167",T:"\u0166",v:"\u1E7D",V:"\u1E7C",u:"\u016D",U:"\u016C",w:"\u1E87",W:"\u1E86",x:"\u1E8B",X:"\u1E8A",y:"\u1E8F",Y:"\u1E8E",z:"\u1E91",Z:"\u1E90"};var BIDI_MAP={a:"\u0250",A:"\u2200",b:"q",B:"\u0510",c:"\u0254",C:"\u2183",d:"p",D:"\u15E1",e:"\u01DD",E:"\u018E",f:"\u025F",F:"\u2132",g:"\u0183",G:"\u2141",h:"\u0265",H:"H",i:"\u0131",I:"I",j:"\u027E",J:"\u017F",k:"\u029E",K:"\u04FC",l:"\u0285",L:"\u2142",m:"\u026F",M:"W",n:"u",N:"N",o:"o",O:"O",p:"d",P:"\u0500",q:"b",Q:"\xD2",r:"\u0279",R:"\u1D1A",s:"s",S:"S",t:"\u0287",T:"\u22A5",u:"n",U:"\u2229",v:"\u028C",V:"\u0245",w:"\u028D",W:"M",x:"x",X:"X",y:"\u028E",Y:"\u2144",z:"z",Z:"Z"};var strategies={accented:{prefix:"",postfix:"",map:ACCENTED_MAP,elongate:true},bidi:{prefix:"\u202E",postfix:"\u202C",map:BIDI_MAP,elongate:false}};var pseudoLocalizeString=function pseudoLocalizeString(string){var _ref=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{},_ref$strategy=_ref.strategy,strategy=_ref$strategy===void 0?"accented":_ref$strategy;var opts=strategies[strategy];var pseudoLocalizedText="";var _iterator=_createForOfIteratorHelper(string),_step;try{for(_iterator.s();!(_step=_iterator.n()).done;){var character=_step.value;if(opts.map[character]){var cl=character.toLowerCase();if(opts.elongate&&(cl==="a"||cl==="e"||cl==="o"||cl==="u")){pseudoLocalizedText+=opts.map[character]+opts.map[character]}else pseudoLocalizedText+=opts.map[character]}else pseudoLocalizedText+=character}}catch(err){_iterator.e(err)}finally{_iterator.f()}if(pseudoLocalizedText.startsWith(opts.prefix)&&pseudoLocalizedText.endsWith(opts.postfix)){return pseudoLocalizedText}return opts.prefix+pseudoLocalizedText+opts.postfix};var _default=pseudoLocalizeString;exports.default=_default;
|
|
2
2
|
//# sourceMappingURL=localize.js.map
|
package/lib/localize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/localize.js"],"names":["ACCENTED_MAP","a","A","b","B","c","C","d","D","e","E","f","F","g","G","h","H","i","I","j","J","k","K","l","L","m","M","n","N","o","O","p","P","q","Q","r","R","s","S","t","T","v","V","u","U","w","W","x","X","y","Y","z","Z","BIDI_MAP","strategies","accented","prefix","postfix","map","elongate","bidi","pseudoLocalizeString","string","strategy","opts","pseudoLocalizedText","character","cl","toLowerCase","startsWith","endsWith"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/localize.js"],"names":["ACCENTED_MAP","a","A","b","B","c","C","d","D","e","E","f","F","g","G","h","H","i","I","j","J","k","K","l","L","m","M","n","N","o","O","p","P","q","Q","r","R","s","S","t","T","v","V","u","U","w","W","x","X","y","Y","z","Z","BIDI_MAP","strategies","accented","prefix","postfix","map","elongate","bidi","pseudoLocalizeString","string","strategy","opts","pseudoLocalizedText","character","cl","toLowerCase","startsWith","endsWith"],"mappings":"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","sourcesContent":["const ACCENTED_MAP = {\n a: 'ȧ',\n A: 'Ȧ',\n b: 'ƀ',\n B: 'Ɓ',\n c: 'ƈ',\n C: 'Ƈ',\n d: 'ḓ',\n D: 'Ḓ',\n e: 'ḗ',\n E: 'Ḗ',\n f: 'ƒ',\n F: 'Ƒ',\n g: 'ɠ',\n G: 'Ɠ',\n h: 'ħ',\n H: 'Ħ',\n i: 'ī',\n I: 'Ī',\n j: 'ĵ',\n J: 'Ĵ',\n k: 'ķ',\n K: 'Ķ',\n l: 'ŀ',\n L: 'Ŀ',\n m: 'ḿ',\n M: 'Ḿ',\n n: 'ƞ',\n N: 'Ƞ',\n o: 'ǿ',\n O: 'Ǿ',\n p: 'ƥ',\n P: 'Ƥ',\n q: 'ɋ',\n Q: 'Ɋ',\n r: 'ř',\n R: 'Ř',\n s: 'ş',\n S: 'Ş',\n t: 'ŧ',\n T: 'Ŧ',\n v: 'ṽ',\n V: 'Ṽ',\n u: 'ŭ',\n U: 'Ŭ',\n w: 'ẇ',\n W: 'Ẇ',\n x: 'ẋ',\n X: 'Ẋ',\n y: 'ẏ',\n Y: 'Ẏ',\n z: 'ẑ',\n Z: 'Ẑ',\n};\n\nconst BIDI_MAP = {\n a: 'ɐ',\n A: '∀',\n b: 'q',\n B: 'Ԑ',\n c: 'ɔ',\n C: 'Ↄ',\n d: 'p',\n D: 'ᗡ',\n e: 'ǝ',\n E: 'Ǝ',\n f: 'ɟ',\n F: 'Ⅎ',\n g: 'ƃ',\n G: '⅁',\n h: 'ɥ',\n H: 'H',\n i: 'ı',\n I: 'I',\n j: 'ɾ',\n J: 'ſ',\n k: 'ʞ',\n K: 'Ӽ',\n l: 'ʅ',\n L: '⅂',\n m: 'ɯ',\n M: 'W',\n n: 'u',\n N: 'N',\n o: 'o',\n O: 'O',\n p: 'd',\n P: 'Ԁ',\n q: 'b',\n Q: 'Ò',\n r: 'ɹ',\n R: 'ᴚ',\n s: 's',\n S: 'S',\n t: 'ʇ',\n T: '⊥',\n u: 'n',\n U: '∩',\n v: 'ʌ',\n V: 'Ʌ',\n w: 'ʍ',\n W: 'M',\n x: 'x',\n X: 'X',\n y: 'ʎ',\n Y: '⅄',\n z: 'z',\n Z: 'Z',\n};\n\nconst strategies = {\n accented: {\n prefix: '',\n postfix: '',\n map: ACCENTED_MAP,\n elongate: true,\n },\n bidi: {\n // Surround words with Unicode formatting marks forcing\n // right-to-left directionality of characters\n prefix: '\\u202e',\n postfix: '\\u202c',\n map: BIDI_MAP,\n elongate: false,\n },\n};\n\nconst pseudoLocalizeString = (string, { strategy = 'accented' } = {}) => {\n let opts = strategies[strategy];\n\n let pseudoLocalizedText = '';\n for (let character of string) {\n if (opts.map[character]) {\n const cl = character.toLowerCase();\n // duplicate \"a\", \"e\", \"o\" and \"u\" to emulate ~30% longer text\n if (\n opts.elongate &&\n (cl === 'a' || cl === 'e' || cl === 'o' || cl === 'u')\n ) {\n pseudoLocalizedText += opts.map[character] + opts.map[character];\n } else pseudoLocalizedText += opts.map[character];\n } else pseudoLocalizedText += character;\n }\n\n // If this string is from the DOM, it should already contain the pre- and postfix\n if (\n pseudoLocalizedText.startsWith(opts.prefix) &&\n pseudoLocalizedText.endsWith(opts.postfix)\n ) {\n return pseudoLocalizedText;\n }\n return opts.prefix + pseudoLocalizedText + opts.postfix;\n};\n\nexport default pseudoLocalizeString;\n"],"file":"localize.js"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var _localize=_interopRequireDefault(require("./localize"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}describe("localize",function(){test("accented",function(){expect((0,_localize.default)("abcd")).toBe("\u0227\u0227\u0180\u0188\u1E13");expect((0,_localize.default)("aeou")).toBe("\u0227\u0227\u1E17\u1E17\u01FF\u01FF\u016D\u016D");expect((0,_localize.default)("foo bar")).toBe("\u0192\u01FF\u01FF\u01FF\u01FF \u0180\u0227\u0227\u0159");expect((0,_localize.default)("CAPITAL_LETTERS")).toBe("\u0187\u0226\u0226\u01A4\u012A\u0166\u0226\u0226\u013F_\u013F\u1E16\u1E16\u0166\u0166\u1E16\u1E16\u0158\u015E");expect((0,_localize.default)("123,. n -~\xF0\xDE")).toBe("123,. \u019E -~\xF0\xDE")});test("bidi",function(){var bidi={strategy:"bidi"};expect((0,_localize.default)("abcd",bidi)).toBe("\u202E\u0250q\u0254p\u202C");expect((0,_localize.default)("aeou",bidi)).toBe("\u202E\u0250\u01DDon\u202C");expect((0,_localize.default)("foo bar",bidi)).toBe("\u202E\u025Foo q\u0250\u0279\u202C");expect((0,_localize.default)("CAPITAL_LETTERS",bidi)).toBe("\u202E\u2183\u2200\u0500I\u22A5\u2200\u2142_\u2142\u018E\u22A5\u22A5\u018E\u1D1AS\u202C");expect((0,_localize.default)("123,. n -~\xF0\xDE",bidi)).toBe("\u202E123,. u -~\xF0\xDE\u202C");expect((0,_localize.default)("\u202E\u025Foo\u202C",bidi)).toBe("\u202E\u025Foo\u202C")})});
|
|
2
|
+
//# sourceMappingURL=localize.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/localize.test.js"],"names":["describe","test","expect","toBe","bidi","strategy"],"mappings":"aAAA,4D,kFAEAA,QAAQ,CAAC,UAAD,CAAa,UAAM,CACzBC,IAAI,CAAC,UAAD,CAAa,UAAM,CACrBC,MAAM,CAAC,sBAAS,MAAT,CAAD,CAAN,CAAyBC,IAAzB,CAA8B,gCAA9B,EAEAD,MAAM,CAAC,sBAAS,MAAT,CAAD,CAAN,CAAyBC,IAAzB,CAA8B,kDAA9B,EACAD,MAAM,CAAC,sBAAS,SAAT,CAAD,CAAN,CAA4BC,IAA5B,CAAiC,yDAAjC,EACAD,MAAM,CAAC,sBAAS,iBAAT,CAAD,CAAN,CAAoCC,IAApC,CAAyC,+GAAzC,EAEAD,MAAM,CAAC,sBAAS,oBAAT,CAAD,CAAN,CAAiCC,IAAjC,CAAsC,yBAAtC,CACD,CARG,CAAJ,CAUAF,IAAI,CAAC,MAAD,CAAS,UAAM,CACjB,GAAMG,CAAAA,IAAI,CAAG,CAAEC,QAAQ,CAAE,MAAZ,CAAb,CAYAH,MAAM,CAAC,sBAAS,MAAT,CAAiBE,IAAjB,CAAD,CAAN,CAA+BD,IAA/B,CAAoC,4BAApC,EACAD,MAAM,CAAC,sBAAS,MAAT,CAAiBE,IAAjB,CAAD,CAAN,CAA+BD,IAA/B,CAAoC,4BAApC,EACAD,MAAM,CAAC,sBAAS,SAAT,CAAoBE,IAApB,CAAD,CAAN,CAAkCD,IAAlC,CAAuC,oCAAvC,EACAD,MAAM,CAAC,sBAAS,iBAAT,CAA4BE,IAA5B,CAAD,CAAN,CAA0CD,IAA1C,CAA+C,yFAA/C,EACAD,MAAM,CAAC,sBAAS,oBAAT,CAAyBE,IAAzB,CAAD,CAAN,CAAuCD,IAAvC,CAA4C,gCAA5C,EAEAD,MAAM,CAAC,sBAAS,sBAAT,CAAkBE,IAAlB,CAAD,CAAN,CAAgCD,IAAhC,CAAqC,sBAArC,CACD,CApBG,CAqBL,CAhCO,CAAR","sourcesContent":["import localize from './localize';\n\ndescribe('localize', () => {\n test('accented', () => {\n expect(localize('abcd')).toBe('ȧȧƀƈḓ');\n // aeou are duplicated\n expect(localize('aeou')).toBe('ȧȧḗḗǿǿŭŭ');\n expect(localize('foo bar')).toBe('ƒǿǿǿǿ ƀȧȧř');\n expect(localize('CAPITAL_LETTERS')).toBe('ƇȦȦƤĪŦȦȦĿ_ĿḖḖŦŦḖḖŘŞ');\n // Everything except ASCII alphabet is passed through\n expect(localize('123,. n -~ðÞ')).toBe('123,. ƞ -~ðÞ');\n });\n\n test('bidi', () => {\n const bidi = { strategy: 'bidi' };\n\n /**\n * There are invisivle unicode formatting marks\n * surrounding each output. For example\n *\n * \"ɐqɔp\" is actually \"\\u202e\" + \"ɐqɔp\" + \"\\u202c\"\n *\n * The presense of the formatting marks cause most UIs\n * (likely including your text editor) to render the\n * string backwards, if you will, or from right-to-left.\n */\n expect(localize('abcd', bidi)).toBe('ɐqɔp');\n expect(localize('aeou', bidi)).toBe('ɐǝon');\n expect(localize('foo bar', bidi)).toBe('ɟoo qɐɹ');\n expect(localize('CAPITAL_LETTERS', bidi)).toBe('Ↄ∀ԀI⊥∀⅂_⅂Ǝ⊥⊥ƎᴚS');\n expect(localize('123,. n -~ðÞ', bidi)).toBe('123,. u -~ðÞ');\n // formatting marks are not duplicated if already present\n expect(localize('ɟoo', bidi)).toBe('ɟoo');\n });\n});\n"],"file":"localize.test.js"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pseudo-localization",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Dynamic pseudo-localization in the browser and nodejs",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
7
|
-
"lib"
|
|
7
|
+
"lib",
|
|
8
|
+
"bin"
|
|
8
9
|
],
|
|
10
|
+
"bin": "./bin/pseudo-localize",
|
|
9
11
|
"scripts": {
|
|
10
12
|
"start": "node devserver.js",
|
|
11
|
-
"prepare": "babel src --out-dir lib --minified --no-comments --source-maps",
|
|
12
|
-
"
|
|
13
|
+
"prepare": "babel src --out-dir lib --minified --no-comments --source-maps --ignore '**/*.test.js'",
|
|
14
|
+
"check-formatting": "prettier --list-different src/**/*.js",
|
|
15
|
+
"lint": "eslint src/**/*.js",
|
|
16
|
+
"test-js": "jest src/*",
|
|
17
|
+
"test": "npm run test-js jest && npm run check-formatting && npm run lint"
|
|
13
18
|
},
|
|
14
19
|
"author": "Tryggvi Gylfason (http://twitter.com/tryggvigy)",
|
|
15
20
|
"keywords": [
|
|
@@ -29,9 +34,17 @@
|
|
|
29
34
|
},
|
|
30
35
|
"license": "MIT",
|
|
31
36
|
"devDependencies": {
|
|
32
|
-
"@babel/cli": "7.
|
|
33
|
-
"@babel/core": "7.
|
|
34
|
-
"@babel/preset-env": "7.
|
|
37
|
+
"@babel/cli": "^7.5.5",
|
|
38
|
+
"@babel/core": "^7.5.5",
|
|
39
|
+
"@babel/preset-env": "^7.5.5",
|
|
40
|
+
"babel-jest": "^24.8.0",
|
|
41
|
+
"eslint": "^6.1.0",
|
|
42
|
+
"jest-cli": "^24.8.0",
|
|
43
|
+
"prettier": "^1.18.2"
|
|
35
44
|
},
|
|
36
|
-
"dependencies": {
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"flat": "^5.0.2",
|
|
47
|
+
"get-stdin": "^7.0.0",
|
|
48
|
+
"yargs": "^17.2.1"
|
|
49
|
+
}
|
|
37
50
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
##2.0.2
|
|
2
|
-
- Fix a bug where blacklisted nodes would get pseudo-localized when mutated in the DOM
|
|
3
|
-
|
|
4
|
-
##2.0.1
|
|
5
|
-
- Mention in package.json description that `pseudo-localization` works with nodejs.
|
|
6
|
-
|
|
7
|
-
##2.0.0
|
|
8
|
-
- Safeguard childlist mutations and empty strings https://github.com/tryggvigy/pseudo-localization/pull/12
|
|
9
|
-
- Fixes https://github.com/tryggvigy/pseudo-localization/issues/6 and https://github.com/tryggvigy/pseudo-localization/issues/11
|
|
10
|
-
- Fix a bug where DOM mutation localizations did not respect the strategy specified https://github.com/tryggvigy/pseudo-localization/pull/16
|
|
11
|
-
- Refactor internals to use import/export ES modules https://github.com/tryggvigy/pseudo-localization/pull/16
|
|
12
|
-
- **BREAKING** `require` usage will have to change from
|
|
13
|
-
```js
|
|
14
|
-
const pseudoLocalization = require('pseudo-localization');
|
|
15
|
-
```
|
|
16
|
-
to
|
|
17
|
-
```js
|
|
18
|
-
const pseudoLocalization = require('pseudo-localization').default;
|
|
19
|
-
```
|
|
20
|
-
- Transform to "not dead" browsers through babel https://github.com/tryggvigy/pseudo-localization/pull/16
|
|
21
|
-
- Fixes https://github.com/tryggvigy/pseudo-localization/issues/8
|
|
22
|
-
|
|
23
|
-
##1.3.0
|
|
24
|
-
- Allow blacklisting nodes ([#9](https://github.com/tryggvigy/pseudo-localization/pull/9))
|
|
25
|
-
|
|
26
|
-
## 1.2.0
|
|
27
|
-
- Expose `localize` function
|
|
28
|
-
|
|
29
|
-
## 1.1.5
|
|
30
|
-
- Fix typo in README
|
|
31
|
-
- Set MIT as license in package.json
|
|
32
|
-
|
|
33
|
-
## 1.1.4
|
|
34
|
-
- Update explanatory picture in README.md
|
|
35
|
-
|
|
36
|
-
## 1.1.3
|
|
37
|
-
- Add support for bidirectional text
|
|
38
|
-
- `pseudoLocalization.start({ strategy: 'bidi' });`
|
|
39
|
-
- Changed several things to improve legibility
|
|
40
|
-
- Removed `[]` surrounding each string. horizontal Cutoff should be relatively easy to spot without those.
|
|
41
|
-
- Stop using `one two three ...` to elongagate the string by ~30-40% and instead duplicate letters withing the string itself.
|
|
42
|
-
- Tidy up pseudo language symbols maps to contain more legibile symbols
|
|
43
|
-
- Make pseudo language deterministic. Always use the same pseudo symbol for the same english letter.
|