UNPKG

7.61 kBJavaScriptView Raw
1/**
2* Sutton SignWriting Core Module v1.4.2 (https://github.com/sutton-signwriting/core)
3* Author: Steve Slevinski (https://SteveSlevinski.me)
4* style.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 = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.ssw = global.ssw || {}, global.ssw.style = {})));
11})(this, (function (exports) { 'use strict';
12
13 /**
14 * Object of regular expressions for style strings
15 *
16 * @alias style.re
17 * @type {object}
18 * @property {string} colorize - regular expression for colorize section
19 * @property {string} colorhex - regular expression for color hex values with 3 or 6 characters
20 * @property {string} colorname - regular expression for css color name
21 * @property {string} padding - regular expression for padding section
22 * @property {string} zoom - regular expression for zoom section
23 * @property {string} classbase - regular expression for class name definition
24 * @property {string} id - regular expression for id definition
25 * @property {string} colorbase - regular expression for color hex or color name
26 * @property {string} color - regular expression for single color entry
27 * @property {string} colors - regular expression for double color entry
28 * @property {string} background - regular expression for background section
29 * @property {string} detail - regular expression for color details for line and optional fill
30 * @property {string} detailsym - regular expression for color details for individual symbols
31 * @property {string} classes - regular expression for one or more class names
32 * @property {string} full - full regular expression for style string
33 */
34 let re = {
35 'colorize': 'C',
36 'colorhex': '(?:[0-9a-fA-F]{3}){1,2}',
37 'colorname': '[a-zA-Z]+',
38 'padding': 'P[0-9]{2}',
39 'zoom': 'Z(?:[0-9]+(?:\\.[0-9]+)?|x)',
40 'classbase': '-?[_a-zA-Z][_a-zA-Z0-9-]{0,100}',
41 'id': '[a-zA-Z][_a-zA-Z0-9-]{0,100}'
42 };
43 re.colorbase = `(?:${re.colorhex}|${re.colorname})`;
44 re.color = `_${re.colorbase}_`;
45 re.colors = `_${re.colorbase}(?:,${re.colorbase})?_`;
46 re.background = `G${re.color}`;
47 re.detail = `D${re.colors}`;
48 re.detailsym = `D[0-9]{2}${re.colors}`;
49 re.classes = `${re.classbase}(?: ${re.classbase})*`;
50 re.full = `-(${re.colorize})?(${re.padding})?(${re.background})?(${re.detail})?(${re.zoom})?(?:-((?:${re.detailsym})*))?(?:-(${re.classes})?!(?:(${re.id})!)?)?`;
51
52 const prefixColor = color => {
53 const regex = new RegExp(`^${re.colorhex}$`);
54 return (regex.test(color) ? '#' : '') + color;
55 };
56
57 const definedProps = obj => Object.fromEntries(Object.entries(obj).filter(([k, v]) => v !== undefined));
58 /**
59 * Function to parse style string to object
60 * @function style.parse
61 * @param {string} styleString - a style string
62 * @returns {StyleObject} elements of style string
63 * @example
64 * style.parse('-CP10G_blue_D_red,Cyan_')
65 *
66 * return {
67 * 'colorize': true,
68 * 'padding': 10,
69 * 'background': 'blue',
70 * 'detail': ['red', 'Cyan']
71 * }
72 */
73
74
75 const parse = styleString => {
76 const regex = `^${re.full}`;
77 const m = (typeof styleString === 'string' ? styleString.match(new RegExp(regex)) : []) || [];
78 return definedProps({
79 'colorize': !m[1] ? undefined : !!m[1],
80 'padding': !m[2] ? undefined : parseInt(m[2].slice(1)),
81 'background': !m[3] ? undefined : prefixColor(m[3].slice(2, -1)),
82 'detail': !m[4] ? undefined : m[4].slice(2, -1).split(',').map(prefixColor),
83 'zoom': !m[5] ? undefined : m[5] === 'Zx' ? 'x' : parseFloat(m[5].slice(1)),
84 'detailsym': !m[6] ? undefined : m[6].match(new RegExp(re.detailsym, 'g')).map(val => {
85 const parts = val.split('_');
86 const detail = parts[1].split(',').map(prefixColor);
87 return {
88 'index': parseInt(parts[0].slice(1)),
89 'detail': detail
90 };
91 }),
92 'classes': !m[7] ? undefined : m[7],
93 'id': !m[8] ? undefined : m[8]
94 });
95 };
96
97 /**
98 * Function to compose style string from object
99 * @function style.compose
100 * @param {StyleObject} styleObject - an object of style options
101 * @returns {string} style string
102 * @example
103 * style.compose({
104 * 'colorize': true,
105 * 'padding': 10,
106 * 'background': 'blue',
107 * 'detail': ['red', 'Cyan'],
108 * 'zoom': 1.1,
109 * 'detailsym': [
110 * {
111 * 'index': 1,
112 * 'detail': ['#ff00ff']
113 * },
114 * {
115 * 'index': 2,
116 * 'detail': ['yellow', 'green']
117 * }
118 * ],
119 * 'classes': 'primary blinking',
120 * 'id': 'cursor'
121 * })
122 *
123 * return '-CP10G_blue_D_red,Cyan_Z1.1-D01_ff00ff_D02_yellow,green_-primary blinking!cursor!'
124 */
125
126 const compose = styleObject => {
127 if (typeof styleObject !== 'object' || styleObject === null) return undefined; // three sections
128
129 let style1 = '-';
130 style1 += !styleObject.colorize ? '' : 'C';
131 const padding = parseInt(styleObject.padding);
132 style1 += !padding || padding <= 0 || padding > 99 ? '' : 'P' + (padding > 9 ? padding : '0' + padding);
133 const background = !styleObject.background || !(typeof styleObject.background === 'string') ? undefined : styleObject.background.match(re.colorbase)[0];
134 style1 += !background ? '' : 'G_' + background + '_';
135 const detail1 = !styleObject.detail || !styleObject.detail[0] || !(typeof styleObject.detail[0] === 'string') ? undefined : styleObject.detail[0].match(re.colorbase)[0];
136 const detail2 = !styleObject.detail || !styleObject.detail[1] || !(typeof styleObject.detail[1] === 'string') ? undefined : styleObject.detail[1].match(re.colorbase)[0];
137
138 if (detail1) {
139 style1 += 'D_' + detail1;
140
141 if (detail2) {
142 style1 += ',' + detail2;
143 }
144
145 style1 += '_';
146 }
147
148 const zoom = styleObject.zoom === 'x' ? 'x' : parseFloat(styleObject.zoom);
149 style1 += !zoom || zoom <= 0 ? '' : 'Z' + zoom;
150 let style2 = '';
151 const detailsym = !styleObject.detailsym || !Array.isArray(styleObject.detailsym) ? [] : styleObject.detailsym.map(styleObject => {
152 const index = parseInt(styleObject.index);
153 if (!index || index <= 0 || index > 99) return '';
154 let style = 'D' + (index > 9 ? index : '0' + index);
155 const detail1 = !styleObject.detail || !styleObject.detail[0] ? undefined : styleObject.detail[0].match(re.colorbase)[0];
156 const detail2 = !styleObject.detail || !styleObject.detail[1] ? undefined : styleObject.detail[1].match(re.colorbase)[0];
157
158 if (detail1) {
159 style += '_' + detail1;
160
161 if (detail2) {
162 style += ',' + detail2;
163 }
164
165 style += '_';
166 }
167
168 return style;
169 });
170 style2 += detailsym.join('');
171 let style3 = '';
172 const classes = !styleObject.classes || !(typeof styleObject.classes === 'string') ? undefined : styleObject.classes.match(re.classes)[0];
173 style3 += !classes ? '' : classes;
174 const id = !styleObject.id || !(typeof styleObject.id === 'string') ? undefined : styleObject.id.match(re.id)[0];
175 style3 += classes || id ? '!' : '';
176 style3 += !id ? '' : id + '!';
177 return style1 + (style2 || style3 ? '-' + style2 : '') + (style3 ? '-' + style3 : '');
178 };
179
180 exports.compose = compose;
181 exports.parse = parse;
182 exports.re = re;
183
184 Object.defineProperty(exports, '__esModule', { value: true });
185
186}));
187
188/* support ongoing development on https://patreon.com/signwriting */