UNPKG

11.6 kBJavaScriptView Raw
1/**
2* Sutton SignWriting Core Module v1.2.0 (https://github.com/sutton-signwriting/core)
3* Author: Steve Slevinski (https://SteveSlevinski.me)
4* convert.js is released under the MIT License.
5*/
6
7(function (global, factory) {
8 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
9 typeof define === 'function' && define.amd ? define(['exports'], factory) :
10 (global = global || self, factory((global.ssw = global.ssw || {}, global.ssw.convert = {})));
11}(this, function (exports) { 'use strict';
12
13 /**
14 * Object of regular expressions for FSW strings
15 *
16 * { symbol, coord, sort, box, prefix, spatial, signbox, sign, sortable }
17 * @alias fsw.re
18 * @type {object}
19 */
20 let re = {
21 'symbol': 'S[123][0-9a-f]{2}[0-5][0-9a-f]',
22 'coord': '[0-9]{3}x[0-9]{3}',
23 'sort': 'A',
24 'box': '[BLMR]'
25 };
26 re.prefix = `(?:${re.sort}(?:${re.symbol})+)`;
27 re.spatial = `${re.symbol}${re.coord}`;
28 re.signbox = `${re.box}${re.coord}(?:${re.spatial})*`;
29 re.sign = `${re.prefix}?${re.signbox}`;
30 re.sortable = `${re.prefix}${re.signbox}`;
31
32 /**
33 * Object of regular expressions for SWU strings in UTF-16
34 *
35 * { symbol, coord, sort, box, prefix, spatial, signbox, sign, sortable }
36 * @alias swu.re
37 * @type {object}
38 */
39 let re$1 = {
40 'symbol': '(?:(?:\uD8C0[\uDC01-\uDFFF])|(?:[\uD8C1-\uD8FC][\uDC00-\uDFFF])|(?:\uD8FD[\uDC00-\uDC80]))',
41 'coord': '(?:\uD836[\uDC0C-\uDDFF]){2}',
42 'sort': '\uD836\uDC00',
43 'box': '\uD836[\uDC01-\uDC04]'
44 };
45 re$1.prefix = `(?:${re$1.sort}(?:${re$1.symbol})+)`;
46 re$1.spatial = `${re$1.symbol}${re$1.coord}`;
47 re$1.signbox = `${re$1.box}${re$1.coord}(?:${re$1.spatial})*`;
48 re$1.sign = `${re$1.prefix}?${re$1.signbox}`;
49 re$1.sortable = `${re$1.prefix}${re$1.signbox}`;
50
51 /** The convert module contains functions to convert between Formal SignWriitng in ASCII (FSW) and SignWriting in Unicode (SWU) characters, along with other types of data.
52 * [Characters set definitions](https://tools.ietf.org/id/draft-slevinski-formal-signwriting-07.html#rfc.section.2.2)
53 * @module convert
54 */
55 /**
56 * Function to convert an SWU structural marker to FSW equivalent
57 * @function convert.swu2mark
58 * @param {string} swuMark - character for SWU structural marker
59 * @returns {string} FSW structural marker
60 * @example
61 * convert.swu2mark('𝠀')
62 *
63 * return 'A'
64 */
65
66 const swu2mark = swuMark => {
67 return {
68 '𝠀': 'A',
69 '𝠁': 'B',
70 '𝠂': 'L',
71 '𝠃': 'M',
72 '𝠄': 'R'
73 }[swuMark];
74 };
75 /**
76 * Function to convert an FSW structural marker to SWU equivalent
77 * @function convert.mark2swu
78 * @param {string} fswMark - character for FSW structural marker
79 * @returns {string} SWU structural marker
80 * @example
81 * convert.mark2swu('A')
82 *
83 * return '𝠀'
84 */
85
86
87 const mark2swu = fswMark => {
88 return {
89 'A': '𝠀',
90 'B': '𝠁',
91 'L': '𝠂',
92 'M': '𝠃',
93 'R': '𝠄'
94 }[fswMark];
95 };
96 /**
97 * Function to convert an SWU number character to an integer
98 * @function convert.swu2num
99 * @param {string} swuNum - SWU number character
100 * @returns {number} Integer value for number
101 * @example
102 * convert.swu2num('ðĪ†')
103 *
104 * return 500
105 */
106
107
108 const swu2num = swuNum => parseInt(swuNum.codePointAt(0)) - 0x1D80C + 250;
109 /**
110 * Function to convert a number to an SWU number character
111 * @function convert.num2swu
112 * @param {number} num - Integer value for number
113 * @returns {string} SWU number character
114 * @example
115 * convert.num2swu(500)
116 *
117 * return 'ðĪ†'
118 */
119
120
121 const num2swu = num => String.fromCodePoint(0x1D80C + parseInt(num) - 250);
122 /**
123 * Function to convert two SWU number characters to an array of x,y integers
124 * @function convert.swu2coord
125 * @param {string} swuCoord - Two SWU number character
126 * @returns {number[]} Array of x,y integers
127 * @example
128 * convert.swu2coord('ðĪ†ðĪ†')
129 *
130 * return [500, 500]
131 */
132
133
134 const swu2coord = swuCoord => [swu2num(swuCoord.slice(0, 2)), swu2num(swuCoord.slice(2, 4))];
135 /**
136 * Function to convert an array of x,y integers to two SWU number characters
137 * @function convert.coord2swu
138 * @param {number[]} coord - Array of x,y integers
139 * @returns {string} Two SWU number character
140 * @example
141 * convert.coord2swu([500, 500])
142 *
143 * return 'ðĪ†ðĪ†'
144 */
145
146
147 const coord2swu = coord => coord.map(num => num2swu(num)).join('');
148 /**
149 * Function to convert an FSW coordinate string to an array of x,y integers
150 * @function convert.fsw2coord
151 * @param {string} fswCoord - An FSW coordinate string
152 * @returns {number[]} Array of x,y integers
153 * @example
154 * convert.fsw2coord('500x500')
155 *
156 * return [500, 500]
157 */
158
159
160 const fsw2coord = fswCoord => fswCoord.split('x').map(num => parseInt(num));
161 /**
162 * Function to convert an array of x,y integers to an FSW coordinate string
163 * @function convert.coord2fsw
164 * @param {number[]} coord - Array of x,y integers
165 * @returns {string} An FSW coordinate string
166 * @example
167 * convert.coord2fsw([500, 500])
168 *
169 * return '500x500'
170 */
171
172
173 const coord2fsw = coord => coord.join('x');
174 /**
175 * Function to convert an SWU symbol character to a code point on plane 4
176 * @function convert.swu2code
177 * @param {string} swuSym - SWU symbol character
178 * @returns {number} Code point on plane 4
179 * @example
180 * convert.swu2code('ņ€€')
181 *
182 * return 0x40001
183 */
184
185
186 const swu2code = swuSym => parseInt(swuSym.codePointAt(0));
187 /**
188 * Function to convert a code point on plane 4 to an SWU symbol character
189 * @function convert.code2swu
190 * @param {number} code - Code point on plane 4
191 * @returns {string} SWU symbol character
192 * @example
193 * convert.code2swu(0x40001)
194 *
195 * return 'ņ€€'
196 */
197
198
199 const code2swu = code => String.fromCodePoint(code);
200 /**
201 * Function to convert an SWU symbol character to a 16-bit ID
202 * @function convert.swu2id
203 * @param {string} swuSym - SWU symbol character
204 * @returns {number} 16-bit ID
205 * @example
206 * convert.swu2id('ņ€€')
207 *
208 * return 1
209 */
210
211
212 const swu2id = swuSym => swu2code(swuSym) - 0x40000;
213 /**
214 * Function to convert a 16-bit ID to an SWU symbol character
215 * @function convert.id2swu
216 * @param {number} id - 16-bit ID
217 * @returns {string} SWU symbol character
218 * @example
219 * convert.id2swu(1)
220 *
221 * return 'ņ€€'
222 */
223
224
225 const id2swu = id => code2swu(id + 0x40000);
226 /**
227 * Function to convert an FSW symbol key to a 16-bit ID
228 * @function convert.key2id
229 * @param {string} key - FSW symbol key
230 * @returns {number} 16-bit ID
231 * @example
232 * convert.key2id('S10000')
233 *
234 * return 1
235 */
236
237
238 const key2id = key => 1 + (parseInt(key.slice(1, 4), 16) - 256) * 96 + parseInt(key.slice(4, 5), 16) * 16 + parseInt(key.slice(5, 6), 16);
239 /**
240 * Function to convert a 16-bit ID to an FSW symbol key
241 * @function convert.id2key
242 * @param {number} id - 16-bit ID
243 * @returns {string} FSW symbol key
244 * @example
245 * convert.id2key(1)
246 *
247 * return 'S10000'
248 */
249
250
251 const id2key = id => {
252 const symcode = id - 1;
253 const base = parseInt(symcode / 96);
254 const fill = parseInt((symcode - base * 96) / 16);
255 const rotation = parseInt(symcode - base * 96 - fill * 16);
256 return 'S' + (base + 0x100).toString(16) + fill.toString(16) + rotation.toString(16);
257 };
258 /**
259 * Function to convert an SWU symbol character to an FSW symbol key
260 * @function convert.swu2key
261 * @param {string} swuSym - SWU symbol character
262 * @returns {string} FSW symbol key
263 * @example
264 * convert.swu2key('ņ€€')
265 *
266 * return 'S10000'
267 */
268
269
270 const swu2key = swuSym => {
271 const symcode = swu2code(swuSym) - 0x40001;
272 const base = parseInt(symcode / 96);
273 const fill = parseInt((symcode - base * 96) / 16);
274 const rotation = parseInt(symcode - base * 96 - fill * 16);
275 return 'S' + (base + 0x100).toString(16) + fill.toString(16) + rotation.toString(16);
276 };
277 /**
278 * Function to convert an FSW symbol key to an SWU symbol character
279 * @function convert.key2swu
280 * @param {string} key - FSW symbol key
281 * @returns {string} SWU symbol character
282 * @example
283 * convert.key2swu('S10000')
284 *
285 * return 'ņ€€'
286 */
287
288
289 const key2swu = key => code2swu(0x40001 + (parseInt(key.slice(1, 4), 16) - 256) * 96 + parseInt(key.slice(4, 5), 16) * 16 + parseInt(key.slice(5, 6), 16));
290 /**
291 * Function to convert SWU text to FSW text
292 * @function convert.swu2fsw
293 * @param {string} swuText - SWU text
294 * @returns {string} FSW text
295 * @example
296 * convert.swu2fsw('𝠀ņ€€’ņ€€šņ‹šĨņ‹›Đ𝠃ðĪŸðĪĐņ‹›ĐðĢĩðĪņ€€’ðĪ‡ðĢĪņ‹šĨðĪðĪ†ņ€€šðĢŪðĢ­')
297 *
298 * return 'AS10011S10019S2e704S2e748M525x535S2e748483x510S10011501x466S2e704510x500S10019476x475'
299 */
300
301
302 const swu2fsw = swuText => {
303 if (!swuText) return '';
304 let fsw = swuText.replace(/𝠀/g, "A").replace(/𝠁/g, "B").replace(/𝠂/g, "L").replace(/𝠃/g, "M").replace(/𝠄/g, "R");
305 const syms = fsw.match(new RegExp(re$1.symbol, 'g'));
306
307 if (syms) {
308 syms.forEach(function (sym) {
309 fsw = fsw.replace(sym, swu2key(sym));
310 });
311 }
312
313 const coords = fsw.match(new RegExp(re$1.coord, 'g'));
314
315 if (coords) {
316 coords.forEach(function (coord) {
317 fsw = fsw.replace(coord, swu2coord(coord).join('x'));
318 });
319 }
320
321 return fsw;
322 };
323 /**
324 * Function to convert FSW text to SWU text
325 * @function convert.fsw2swu
326 * @param {string} fswText - FSW text
327 * @returns {string} SWU text
328 * @example
329 * convert.fsw2swu('AS10011S10019S2e704S2e748M525x535S2e748483x510S10011501x466S2e704510x500S10019476x475')
330 *
331 * return '𝠀ņ€€’ņ€€šņ‹šĨņ‹›Đ𝠃ðĪŸðĪĐņ‹›ĐðĢĩðĪņ€€’ðĪ‡ðĢĪņ‹šĨðĪðĪ†ņ€€šðĢŪðĢ­'
332 */
333
334
335 const fsw2swu = fswText => {
336 if (!fswText) return '';
337 const prefixes = fswText.match(new RegExp(re.prefix, 'g'));
338
339 if (prefixes) {
340 prefixes.forEach(function (prefix) {
341 fswText = fswText.replace(prefix, '𝠀' + prefix.slice(1).match(/.{6}/g).map(key => key2swu(key)).join(''));
342 });
343 }
344
345 const boxes = fswText.match(new RegExp(re.box + re.coord, 'g'));
346
347 if (boxes) {
348 boxes.forEach(function (boxes) {
349 fswText = fswText.replace(boxes, mark2swu(boxes.slice(0, 1)) + coord2swu(fsw2coord(boxes.slice(1, 8))));
350 });
351 }
352
353 const spatials = fswText.match(new RegExp(re.spatial, 'g'));
354
355 if (spatials) {
356 spatials.forEach(function (spatial) {
357 fswText = fswText.replace(spatial, key2swu(spatial.slice(0, 6)) + coord2swu(fsw2coord(spatial.slice(6, 13))));
358 });
359 }
360
361 return fswText;
362 };
363
364 exports.code2swu = code2swu;
365 exports.coord2fsw = coord2fsw;
366 exports.coord2swu = coord2swu;
367 exports.fsw2coord = fsw2coord;
368 exports.fsw2swu = fsw2swu;
369 exports.id2key = id2key;
370 exports.id2swu = id2swu;
371 exports.key2id = key2id;
372 exports.key2swu = key2swu;
373 exports.mark2swu = mark2swu;
374 exports.num2swu = num2swu;
375 exports.swu2code = swu2code;
376 exports.swu2coord = swu2coord;
377 exports.swu2fsw = swu2fsw;
378 exports.swu2id = swu2id;
379 exports.swu2key = swu2key;
380 exports.swu2mark = swu2mark;
381 exports.swu2num = swu2num;
382
383 Object.defineProperty(exports, '__esModule', { value: true });
384
385}));
386
387/* support ongoing development on https://patreon.com/signwriting */