1 |
|
2 | /** 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.
|
3 | * [Characters set definitions](https://tools.ietf.org/id/draft-slevinski-formal-signwriting-09.html#name-characters)
|
4 | * @module convert
|
5 | */
|
6 |
|
7 | import { re as reFsw } from '../fsw/fsw-re';
|
8 | import { re as reSwu } from '../swu/swu-re';
|
9 |
|
10 | /**
|
11 | * Function to convert an SWU structural marker to FSW equivalent
|
12 | * @function convert.swu2mark
|
13 | * @param {string} swuMark - character for SWU structural marker
|
14 | * @returns {string} FSW structural marker
|
15 | * @example
|
16 | * convert.swu2mark('ð ')
|
17 | *
|
18 | * return 'A'
|
19 | */
|
20 | const swu2mark = (swuMark) => {
|
21 | return { 'ð ': 'A', 'ð ': 'B', 'ð ': 'L', 'ð ': 'M', 'ð ': 'R' }[swuMark]
|
22 | }
|
23 |
|
24 | /**
|
25 | * Function to convert an FSW structural marker to SWU equivalent
|
26 | * @function convert.mark2swu
|
27 | * @param {string} fswMark - character for FSW structural marker
|
28 | * @returns {string} SWU structural marker
|
29 | * @example
|
30 | * convert.mark2swu('A')
|
31 | *
|
32 | * return 'ð '
|
33 | */
|
34 | const mark2swu = (fswMark) => {
|
35 | return { 'A': 'ð ', 'B': 'ð ', 'L': 'ð ', 'M': 'ð ', 'R': 'ð ' }[fswMark]
|
36 | }
|
37 |
|
38 | /**
|
39 | * Function to convert an SWU number character to an integer
|
40 | * @function convert.swu2num
|
41 | * @param {string} swuNum - SWU number character
|
42 | * @returns {number} Integer value for number
|
43 | * @example
|
44 | * convert.swu2num('ðĪ')
|
45 | *
|
46 | * return 500
|
47 | */
|
48 | const swu2num = (swuNum) => parseInt(swuNum.codePointAt(0)) - 0x1D80C + 250;
|
49 |
|
50 | /**
|
51 | * Function to convert a number to an SWU number character
|
52 | * @function convert.num2swu
|
53 | * @param {number} num - Integer value for number
|
54 | * @returns {string} SWU number character
|
55 | * @example
|
56 | * convert.num2swu(500)
|
57 | *
|
58 | * return 'ðĪ'
|
59 | */
|
60 | const num2swu = (num) => String.fromCodePoint(0x1D80C + parseInt(num) - 250);
|
61 |
|
62 | /**
|
63 | * Function to convert two SWU number characters to an array of x,y integers
|
64 | * @function convert.swu2coord
|
65 | * @param {string} swuCoord - Two SWU number character
|
66 | * @returns {number[]} Array of x,y integers
|
67 | * @example
|
68 | * convert.swu2coord('ðĪðĪ')
|
69 | *
|
70 | * return [500, 500]
|
71 | */
|
72 | const swu2coord = (swuCoord) => [swu2num(swuCoord.slice(0, 2)), swu2num(swuCoord.slice(2, 4))];
|
73 |
|
74 | /**
|
75 | * Function to convert an array of x,y integers to two SWU number characters
|
76 | * @function convert.coord2swu
|
77 | * @param {number[]} coord - Array of x,y integers
|
78 | * @returns {string} Two SWU number character
|
79 | * @example
|
80 | * convert.coord2swu([500, 500])
|
81 | *
|
82 | * return 'ðĪðĪ'
|
83 | */
|
84 | const coord2swu = (coord) => coord.map(num => num2swu(num)).join('');
|
85 |
|
86 |
|
87 | /**
|
88 | * Function to convert an FSW coordinate string to an array of x,y integers
|
89 | * @function convert.fsw2coord
|
90 | * @param {string} fswCoord - An FSW coordinate string
|
91 | * @returns {number[]} Array of x,y integers
|
92 | * @example
|
93 | * convert.fsw2coord('500x500')
|
94 | *
|
95 | * return [500, 500]
|
96 | */
|
97 | const fsw2coord = (fswCoord) => fswCoord.split('x').map(num => parseInt(num));
|
98 |
|
99 | /**
|
100 | * Function to convert an array of x,y integers to an FSW coordinate string
|
101 | * @function convert.coord2fsw
|
102 | * @param {number[]} coord - Array of x,y integers
|
103 | * @returns {string} An FSW coordinate string
|
104 | * @example
|
105 | * convert.coord2fsw([500, 500])
|
106 | *
|
107 | * return '500x500'
|
108 | */
|
109 | const coord2fsw = (coord) => coord.join('x');
|
110 |
|
111 | /**
|
112 | * Function to convert an SWU symbol character to a code point on plane 4
|
113 | * @function convert.swu2code
|
114 | * @param {string} swuSym - SWU symbol character
|
115 | * @returns {number} Code point on plane 4
|
116 | * @example
|
117 | * convert.swu2code('ņ')
|
118 | *
|
119 | * return 0x40001
|
120 | */
|
121 | const swu2code = (swuSym) => parseInt(swuSym.codePointAt(0));
|
122 |
|
123 | /**
|
124 | * Function to convert a code point on plane 4 to an SWU symbol character
|
125 | * @function convert.code2swu
|
126 | * @param {number} code - Code point on plane 4
|
127 | * @returns {string} SWU symbol character
|
128 | * @example
|
129 | * convert.code2swu(0x40001)
|
130 | *
|
131 | * return 'ņ'
|
132 | */
|
133 | const code2swu = (code) => String.fromCodePoint(code);
|
134 |
|
135 | /**
|
136 | * Function to convert an SWU symbol character to a 16-bit ID
|
137 | * @function convert.swu2id
|
138 | * @param {string} swuSym - SWU symbol character
|
139 | * @returns {number} 16-bit ID
|
140 | * @example
|
141 | * convert.swu2id('ņ')
|
142 | *
|
143 | * return 1
|
144 | */
|
145 | const swu2id = (swuSym) => swu2code(swuSym) - 0x40000;
|
146 |
|
147 | /**
|
148 | * Function to convert a 16-bit ID to an SWU symbol character
|
149 | * @function convert.id2swu
|
150 | * @param {number} id - 16-bit ID
|
151 | * @returns {string} SWU symbol character
|
152 | * @example
|
153 | * convert.id2swu(1)
|
154 | *
|
155 | * return 'ņ'
|
156 | */
|
157 | const id2swu = (id) => code2swu(id + 0x40000);
|
158 |
|
159 | /**
|
160 | * Function to convert an FSW symbol key to a 16-bit ID
|
161 | * @function convert.key2id
|
162 | * @param {string} key - FSW symbol key
|
163 | * @returns {number} 16-bit ID
|
164 | * @example
|
165 | * convert.key2id('S10000')
|
166 | *
|
167 | * return 1
|
168 | */
|
169 | 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);
|
170 |
|
171 | /**
|
172 | * Function to convert a 16-bit ID to an FSW symbol key
|
173 | * @function convert.id2key
|
174 | * @param {number} id - 16-bit ID
|
175 | * @returns {string} FSW symbol key
|
176 | * @example
|
177 | * convert.id2key(1)
|
178 | *
|
179 | * return 'S10000'
|
180 | */
|
181 | const id2key = (id) => {
|
182 | const symcode = id - 1;
|
183 | const base = parseInt(symcode / 96);
|
184 | const fill = parseInt((symcode - (base * 96)) / 16);
|
185 | const rotation = parseInt(symcode - (base * 96) - (fill * 16));
|
186 | return 'S' + (base + 0x100).toString(16) + fill.toString(16) + rotation.toString(16);
|
187 | }
|
188 |
|
189 | /**
|
190 | * Function to convert an SWU symbol character to an FSW symbol key
|
191 | * @function convert.swu2key
|
192 | * @param {string} swuSym - SWU symbol character
|
193 | * @returns {string} FSW symbol key
|
194 | * @example
|
195 | * convert.swu2key('ņ')
|
196 | *
|
197 | * return 'S10000'
|
198 | */
|
199 | const swu2key = (swuSym) => {
|
200 | const symcode = swu2code(swuSym) - 0x40001;
|
201 | const base = parseInt(symcode / 96);
|
202 | const fill = parseInt((symcode - (base * 96)) / 16);
|
203 | const rotation = parseInt(symcode - (base * 96) - (fill * 16));
|
204 | return 'S' + (base + 0x100).toString(16) + fill.toString(16) + rotation.toString(16);
|
205 | }
|
206 |
|
207 | /**
|
208 | * Function to convert an FSW symbol key to an SWU symbol character
|
209 | * @function convert.key2swu
|
210 | * @param {string} key - FSW symbol key
|
211 | * @returns {string} SWU symbol character
|
212 | * @example
|
213 | * convert.key2swu('S10000')
|
214 | *
|
215 | * return 'ņ'
|
216 | */
|
217 | 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));
|
218 |
|
219 | /**
|
220 | * Function to convert SWU text to FSW text
|
221 | * @function convert.swu2fsw
|
222 | * @param {string} swuText - SWU text
|
223 | * @returns {string} FSW text
|
224 | * @example
|
225 | * convert.swu2fsw('ð ņņņĨņĐð ðĪðĪĐņĐðĢĩðĪņðĪðĢĪņĨðĪðĪņðĢŪðĢ')
|
226 | *
|
227 | * return 'AS10011S10019S2e704S2e748M525x535S2e748483x510S10011501x466S2e704510x500S10019476x475'
|
228 | */
|
229 | const swu2fsw = (swuText) => {
|
230 | if (!swuText) return '';
|
231 | let fsw = swuText.replace(/ð /g, "A").replace(/ð /g, "B").replace(/ð /g, "L").replace(/ð /g, "M").replace(/ð /g, "R");
|
232 | const syms = fsw.match(new RegExp(reSwu.symbol, 'g'));
|
233 | if (syms) {
|
234 | syms.forEach(function (sym) {
|
235 | fsw = fsw.replace(sym, swu2key(sym));
|
236 | });
|
237 | }
|
238 | const coords = fsw.match(new RegExp(reSwu.coord, 'g'));
|
239 | if (coords) {
|
240 | coords.forEach(function (coord) {
|
241 | fsw = fsw.replace(coord, swu2coord(coord).join('x'));
|
242 | });
|
243 | }
|
244 | return fsw;
|
245 | }
|
246 |
|
247 | /**
|
248 | * Function to convert FSW text to SWU text
|
249 | * @function convert.fsw2swu
|
250 | * @param {string} fswText - FSW text
|
251 | * @returns {string} SWU text
|
252 | * @example
|
253 | * convert.fsw2swu('AS10011S10019S2e704S2e748M525x535S2e748483x510S10011501x466S2e704510x500S10019476x475')
|
254 | *
|
255 | * return 'ð ņņņĨņĐð ðĪðĪĐņĐðĢĩðĪņðĪðĢĪņĨðĪðĪņðĢŪðĢ'
|
256 | */
|
257 | const fsw2swu = (fswText) => {
|
258 | if (!fswText) return '';
|
259 | const prefixes = fswText.match(new RegExp(reFsw.prefix, 'g'));
|
260 | if (prefixes) {
|
261 | prefixes.forEach(function (prefix) {
|
262 | fswText = fswText.replace(prefix, 'ð ' +
|
263 | prefix.slice(1).match(/.{6}/g).map(key => key2swu(key)).join(''))
|
264 | })
|
265 | }
|
266 | const boxes = fswText.match(new RegExp(reFsw.box + reFsw.coord, 'g'));
|
267 | if (boxes) {
|
268 | boxes.forEach(function (boxes) {
|
269 | fswText = fswText.replace(boxes,
|
270 | mark2swu(boxes.slice(0, 1)) +
|
271 | coord2swu(fsw2coord(boxes.slice(1, 8))))
|
272 | })
|
273 | }
|
274 | const spatials = fswText.match(new RegExp(reFsw.spatial, 'g'));
|
275 | if (spatials) {
|
276 | spatials.forEach(function (spatial) {
|
277 | fswText = fswText.replace(spatial,
|
278 | key2swu(spatial.slice(0, 6)) +
|
279 | coord2swu(fsw2coord(spatial.slice(6, 13))))
|
280 | })
|
281 | }
|
282 | return fswText;
|
283 | }
|
284 |
|
285 | export { swu2mark, mark2swu, swu2num, num2swu, swu2coord, coord2swu, fsw2coord, coord2fsw, swu2code, code2swu, swu2id, id2swu, key2id, id2key, swu2key, key2swu, swu2fsw, fsw2swu }
|