1 | /**
|
2 | * Sutton SignWriting Core Module v1.1.0
|
3 | * https://github.com/Slevinski/SignWriting
|
4 | * Copyright (c) 2007-2019, Steve Slevinski
|
5 | * fsw.js is released under the MIT License.
|
6 | */
|
7 |
|
8 | (function (global, factory) {
|
9 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
10 | typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
11 | (global = global || self, factory((global.ssw = global.ssw || {}, global.ssw.fsw = {})));
|
12 | }(this, function (exports) { 'use strict';
|
13 |
|
14 | /**
|
15 | * Object of regular expressions for FSW strings
|
16 | *
|
17 | * { symbol, coord, sort, box, prefix, spatial, signbox, sign, term }
|
18 | * @alias fsw.re
|
19 | * @type {object}
|
20 | */
|
21 | let re = {
|
22 | 'symbol': 'S[123][0-9a-f]{2}[0-5][0-9a-f]',
|
23 | 'coord': '[0-9]{3}x[0-9]{3}',
|
24 | 'sort': 'A',
|
25 | 'box': '[BLMR]'
|
26 | };
|
27 | re.prefix = `(?:${re.sort}(?:${re.symbol})+)`;
|
28 | re.spatial = `${re.symbol}${re.coord}`;
|
29 | re.signbox = `${re.box}${re.coord}(?:${re.spatial})*`;
|
30 | re.sign = `${re.prefix}?${re.signbox}`;
|
31 | re.term = `${re.prefix}${re.signbox}`;
|
32 |
|
33 | /**
|
34 | * Object of regular expressions for style strings
|
35 | *
|
36 | * { colorize, colorhex, colorname, padding, zoom, zoomsym, classbase, id, colorbase, color, colors, background, detail, detailsym, classes, full }
|
37 | * @alias style.re
|
38 | * @type {object}
|
39 | */
|
40 | let re$1 = {
|
41 | 'colorize': 'C',
|
42 | 'colorhex': '(?:[0-9a-fA-F]{3}){1,2}',
|
43 | 'colorname': '[a-zA-Z]+',
|
44 | 'padding': 'P[0-9]{2}',
|
45 | 'zoom': 'Z(?:[0-9]+(?:\\.[0-9]+)?|x)',
|
46 | 'zoomsym': 'Z[0-9]{2},[0-9]+(?:\\.[0-9]+)?(?:,[0-9]{3}x[0-9]{3})?',
|
47 | 'classbase': '-?[_a-zA-Z][_a-zA-Z0-9-]{0,100}',
|
48 | 'id': '[a-zA-Z][_a-zA-Z0-9-]{0,100}'
|
49 | };
|
50 | re$1.colorbase = `(?:${re$1.colorhex}|${re$1.colorname})`;
|
51 | re$1.color = `_${re$1.colorbase}_`;
|
52 | re$1.colors = `_${re$1.colorbase}(?:,${re$1.colorbase})?_`;
|
53 | re$1.background = `G${re$1.color}`;
|
54 | re$1.detail = `D${re$1.colors}`;
|
55 | re$1.detailsym = `D[0-9]{2}${re$1.colors}`;
|
56 | re$1.classes = `${re$1.classbase}(?: ${re$1.classbase})*`;
|
57 | re$1.full = `-(${re$1.colorize})?(${re$1.padding})?(${re$1.background})?(${re$1.detail})?(${re$1.zoom})?(?:-((?:${re$1.detailsym})*)((?:${re$1.zoomsym})*))?(?:-(${re$1.classes})?!(?:(${re$1.id})!)?)?`;
|
58 |
|
59 | /** 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.
|
60 | * [Characters set definitions](https://tools.ietf.org/id/draft-slevinski-formal-signwriting-07.html#rfc.section.2.2)
|
61 | * @module convert
|
62 | */
|
63 | /**
|
64 | * Function to convert an FSW coordinate string to an array of x,y integers
|
65 | * @function convert.fsw2coord
|
66 | * @param {string} fswCoord - An FSW coordinate string
|
67 | * @returns {number[]} Array of x,y integers
|
68 | * @example
|
69 | * convert.fsw2coord('500x500')
|
70 | *
|
71 | * return [500, 500]
|
72 | */
|
73 |
|
74 |
|
75 | const fsw2coord = fswCoord => fswCoord.split('x').map(num => parseInt(num));
|
76 |
|
77 | const parse = {
|
78 | /**
|
79 | * Function to parse an fsw symbol with optional coordinate and style string
|
80 | * @function fsw.parse.symbol
|
81 | * @param {string} fswSym - an fsw symbol
|
82 | * @returns {object} elements of fsw symbol
|
83 | * @example
|
84 | * fsw.parse.symbol('S10000500x500-C')
|
85 | *
|
86 | * return {
|
87 | * 'symbol': 'S10000',
|
88 | * 'coord': [500, 500],
|
89 | * 'style': '-C'
|
90 | * }
|
91 | */
|
92 | symbol: fswSym => {
|
93 | const regex = `^(${re.symbol})(${re.coord})?(${re$1.full})?`;
|
94 | const symbol = typeof fswSym === 'string' ? fswSym.match(new RegExp(regex)) : undefined;
|
95 | return {
|
96 | 'symbol': symbol ? symbol[1] : undefined,
|
97 | 'coord': symbol && symbol[2] ? fsw2coord(symbol[2]) : undefined,
|
98 | 'style': symbol ? symbol[3] : undefined
|
99 | };
|
100 | },
|
101 |
|
102 | /**
|
103 | * Function to parse an fsw sign with style string
|
104 | * @function fsw.parse.sign
|
105 | * @param {string} fswSign - an fsw sign
|
106 | * @returns {object} elements of fsw sign
|
107 | * @example
|
108 | * fsw.parse.sign('AS10011S10019S2e704S2e748M525x535S2e748483x510S10011501x466S2e704510x500S10019476x475-C')
|
109 | *
|
110 | * return {
|
111 | * sequence: ['S10011', 'S10019', 'S2e704', 'S2e748'],
|
112 | * box: 'M',
|
113 | * max: [525, 535],
|
114 | * spatials: [
|
115 | * {
|
116 | * symbol: 'S2e748',
|
117 | * coord: [483, 510]
|
118 | * },
|
119 | * {
|
120 | * symbol: 'S10011',
|
121 | * coord: [501, 466]
|
122 | * },
|
123 | * {
|
124 | * symbol: 'S2e704',
|
125 | * coord: [510, 500]
|
126 | * },
|
127 | * {
|
128 | * symbol: 'S10019',
|
129 | * coord: [476, 475]
|
130 | * }
|
131 | * ],
|
132 | * style: '-C'
|
133 | * }
|
134 | */
|
135 | sign: fswSign => {
|
136 | const regex = `^(${re.prefix})?(${re.signbox})(${re$1.full})?`;
|
137 | const sign = typeof fswSign === 'string' ? fswSign.match(new RegExp(regex)) : undefined;
|
138 |
|
139 | if (sign) {
|
140 | return {
|
141 | 'sequence': sign[1] ? sign[1].slice(1).match(/.{6}/g) : undefined,
|
142 | 'box': sign[2][0],
|
143 | 'max': fsw2coord(sign[2].slice(1, 8)),
|
144 | 'spatials': sign[2].length < 9 ? undefined : sign[2].slice(8).match(/(.{13})/g).map(m => {
|
145 | return {
|
146 | symbol: m.slice(0, 6),
|
147 | coord: [parseInt(m.slice(6, 9)), parseInt(m.slice(10, 13))]
|
148 | };
|
149 | }),
|
150 | 'style': sign[3]
|
151 | };
|
152 | } else {
|
153 | return {};
|
154 | }
|
155 | }
|
156 | };
|
157 |
|
158 | /**
|
159 | * Array of numbers for kinds of symbols: writing, location, and punctuation.
|
160 | * @alias fsw.kind
|
161 | * @type {array}
|
162 | */
|
163 |
|
164 | const kind = [0x100, 0x37f, 0x387];
|
165 | /**
|
166 | * Array of numbers for categories of symbols: hand, movement, dynamics, head, trunk & limb, location, and punctuation.
|
167 | * @alias fsw.category
|
168 | * @type {array}
|
169 | */
|
170 |
|
171 | const category = [0x100, 0x205, 0x2f7, 0x2ff, 0x36d, 0x37f, 0x387];
|
172 | /**
|
173 | * Array of numbers for the 30 symbol groups.
|
174 | * @alias fsw.group
|
175 | * @type {array}
|
176 | */
|
177 |
|
178 | const group = [0x100, 0x10e, 0x11e, 0x144, 0x14c, 0x186, 0x1a4, 0x1ba, 0x1cd, 0x1f5, 0x205, 0x216, 0x22a, 0x255, 0x265, 0x288, 0x2a6, 0x2b7, 0x2d5, 0x2e3, 0x2f7, 0x2ff, 0x30a, 0x32a, 0x33b, 0x359, 0x36d, 0x376, 0x37f, 0x387];
|
179 | /**
|
180 | * Object of symbol ranges with starting and ending numbers.
|
181 | *
|
182 | * { all, writing, hand, movement, dynamic, head, hcenter, vcenter, trunk, limb, location, punctuation }
|
183 | * @alias fsw.ranges
|
184 | * @type {object}
|
185 | */
|
186 |
|
187 | const ranges = {
|
188 | 'all': [0x100, 0x38b],
|
189 | 'writing': [0x100, 0x37e],
|
190 | 'hand': [0x100, 0x204],
|
191 | 'movement': [0x205, 0x2f6],
|
192 | 'dynamic': [0x2f7, 0x2fe],
|
193 | 'head': [0x2ff, 0x36c],
|
194 | 'hcenter': [0x2ff, 0x36c],
|
195 | 'vcenter': [0x2ff, 0x375],
|
196 | 'trunk': [0x36d, 0x375],
|
197 | 'limb': [0x376, 0x37e],
|
198 | 'location': [0x37f, 0x386],
|
199 | 'punctuation': [0x387, 0x38b]
|
200 | };
|
201 | /**
|
202 | * Function to test if symbol is of a certain type.
|
203 | * @function fsw.isType
|
204 | * @param {string} key - an FSW symbol key
|
205 | * @param {string} type - the name of a symbol range
|
206 | * @returns {boolean} is symbol of specified type
|
207 | * @example
|
208 | * fsw.isType('S10000', 'hand')
|
209 | *
|
210 | * return true
|
211 | */
|
212 |
|
213 | const isType = (key, type) => {
|
214 | const parsed = parse.symbol(key);
|
215 |
|
216 | if (parsed.symbol) {
|
217 | const dec = parseInt(parsed.symbol.slice(1, 4), 16);
|
218 | const range = ranges[type];
|
219 |
|
220 | if (range) {
|
221 | return range[0] <= dec && range[1] >= dec;
|
222 | }
|
223 | }
|
224 |
|
225 | return false;
|
226 | };
|
227 |
|
228 | /**
|
229 | * Array of colors associated with the seven symbol categories.
|
230 | * @alias fsw.colors
|
231 | * @type {array}
|
232 | */
|
233 |
|
234 | const colors = ['#0000CC', '#CC0000', '#FF0099', '#006600', '#000000', '#884411', '#FF9900'];
|
235 | /**
|
236 | * Function that returns the standardized color for a symbol.
|
237 | * @function fsw.colorize
|
238 | * @param {string} key - an FSW symbol key
|
239 | * @returns {string} name of standardized color for symbol
|
240 | * @example
|
241 | * fsw.colorize('S10000')
|
242 | *
|
243 | * return '#0000CC'
|
244 | */
|
245 |
|
246 | const colorize = key => {
|
247 | const parsed = parse.symbol(key);
|
248 | let color = '#000000';
|
249 |
|
250 | if (parsed.symbol) {
|
251 | const dec = parseInt(parsed.symbol.slice(1, 4), 16);
|
252 | const index = category.findIndex(val => val > dec);
|
253 | color = colors[index < 0 ? 6 : index - 1];
|
254 | }
|
255 |
|
256 | return color;
|
257 | };
|
258 |
|
259 | exports.category = category;
|
260 | exports.colorize = colorize;
|
261 | exports.colors = colors;
|
262 | exports.group = group;
|
263 | exports.isType = isType;
|
264 | exports.kind = kind;
|
265 | exports.parse = parse;
|
266 | exports.ranges = ranges;
|
267 | exports.re = re;
|
268 |
|
269 | Object.defineProperty(exports, '__esModule', { value: true });
|
270 |
|
271 | }));
|
272 |
|
273 | /* help fund development on https://patreon.com/signwriting */
|