UNPKG

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