UNPKG

6.16 kBJavaScriptView Raw
1import { parse } from './swu-parse';
2import { info } from './swu-info';
3
4const columnDefaults = {
5 'height': 500,
6 'width': 150,
7 'offset': 50,
8 'pad': 20,
9 'margin': 5,
10 'dynamic': false,
11 'background': undefined,
12 'punctuation': {
13 'spacing': true,
14 'pad': 30,
15 'pull': true
16 },
17 'style':{
18 'detail': ['black','white'],
19 'zoom': 1
20 }
21}
22
23/**
24 * Function to an object of column options with default values
25 *
26 * @function swu.columnDefaultsMerge
27 * @param {ColumnOptions} options - object of column options
28 * @returns {ColumnOptions} object of column options merged with column defaults
29 * @example
30 * swu.columnDefaultsMerge({height: 500,width:150})
31 *
32 * return {
33 * "height": 500,
34 * "width": 150,
35 * "offset": 50,
36 * "pad": 20,
37 * "margin": 5,
38 * "dynamic": false,
39 * "punctuation": {
40 * "spacing": true,
41 * "pad": 30,
42 * "pull": true
43 * },
44 * "style": {
45 * "detail": [
46 * "black",
47 * "white"
48 * ],
49 * "zoom": 1
50 * }
51 * }
52 */
53const columnDefaultsMerge = (options) => {
54 if (typeof options !== 'object') options = {};
55 return {
56 ...columnDefaults,
57 ...options,
58 punctuation: {
59 ...columnDefaults.punctuation,
60 ...options.punctuation
61 },
62 style: {
63 ...columnDefaults.style,
64 ...options.style
65 }
66 }
67}
68
69/**
70 * Function to transform an SWU text to an array of columns
71 *
72 * @function swu.columns
73 * @param {string} swuText - SWU text of signs and punctuation
74 * @param {ColumnOptions} options - object of column options
75 * @returns {{options:ColumnOptions,widths:number[],columns:ColumnData}} object of column options, widths array, and column data
76 * @example
77 * swu.columns('𝠀ρ²‘ρˆ©§π ƒπ€˜π€£ρ²‘𝣳𝣩ρˆ©§π€‰π£» 𝠀ρƒŠ’ρƒŠ«ρ‹›•ρ†‡‘π ƒπ€˜π€§ρƒŠ«π£»π€•ρƒŠ’𝣴𝣼ρ†‡‘π€Žπ€‚ρ‹›•π€†π£¦ ρŒπ£’𝀂', {height: 500,width:150})
78 *
79 * return {
80 * "options": {
81 * "height": 500,
82 * "width": 150,
83 * "offset": 50,
84 * "pad": 20,
85 * "margin": 5,
86 * "dynamic": false,
87 * "punctuation": {
88 * "spacing": true,
89 * "pad": 30,
90 * "pull": true
91 * },
92 * "style": {
93 * "detail": [
94 * "black",
95 * "white"
96 * ],
97 * "zoom": 1
98 * }
99 * },
100 * "widths": [
101 * 150
102 * ],
103 * "columns": [
104 * [
105 * {
106 * "x": 56,
107 * "y": 20,
108 * "minX": 481,
109 * "minY": 471,
110 * "width": 37,
111 * "height": 58,
112 * "lane": 0,
113 * "padding": 0,
114 * "segment": "sign",
115 * "text": "𝠀ρ²‘ρˆ©§π ƒπ€˜π€£ρ²‘𝣳𝣩ρˆ©§π€‰π£»",
116 * "zoom": 1
117 * },
118 * {
119 * "x": 57,
120 * "y": 118,
121 * "minX": 482,
122 * "minY": 468,
123 * "width": 36,
124 * "height": 65,
125 * "lane": 0,
126 * "padding": 0,
127 * "segment": "sign",
128 * "text": "𝠀ρƒŠ’ρƒŠ«ρ‹›•ρ†‡‘π ƒπ€˜π€§ρƒŠ«π£»π€•ρƒŠ’𝣴𝣼ρ†‡‘π€Žπ€‚ρ‹›•π€†π£¦",
129 * "zoom": 1
130 * },
131 * {
132 * "x": 39,
133 * "y": 203,
134 * "minX": 464,
135 * "minY": 496,
136 * "width": 72,
137 * "height": 8,
138 * "lane": 0,
139 * "padding": 0,
140 * "segment": "symbol",
141 * "text": "ρŒπ£’𝀂",
142 * "zoom": 1
143 * }
144 * ]
145 * ]
146 * }
147 */
148 const columns = (swuText, options) => {
149 if (typeof swuText !== 'string') return {};
150 const values = columnDefaultsMerge(options)
151
152 let input = parse.text(swuText);
153 let cursor = 0;
154 let cols = [];
155 let col = [];
156 let plus = 0;
157 let center = parseInt(values.width/2);
158 let maxHeight = values.height - values.margin;
159 let pullable = true;
160 let finalize = false;
161
162 for (let val of input) {
163 let informed = info(val);
164 cursor += plus;
165 if (values.punctuation.spacing){
166 cursor += ((informed.segment=='sign')?values.pad:0);
167 } else {
168 cursor += values.pad;
169 }
170
171 finalize = ((cursor + informed.height) > maxHeight);
172
173 if (finalize && informed.segment=='symbol' && values.punctuation.pull && pullable){
174 finalize = false;
175 pullable = false;
176 }
177
178 if (col.length == 0) { finalize = false; }
179
180 if ( finalize) {
181 cursor = values.pad;
182 cols.push(col);
183 col = [];
184 pullable = true;
185 }
186 col.push(Object.assign(informed,{
187 x: center + (values.offset * informed.lane) - ((500-informed.minX) * informed.zoom * values.style.zoom),
188 y: cursor,
189 text: val
190 }))
191 cursor += (informed.height * informed.zoom * values.style.zoom);
192 if (values.punctuation.spacing){
193 plus = (informed.segment=='sign')?values.pad:values.punctuation.pad;
194 } else {
195 plus = values.pad;
196 }
197 }
198
199 if (col.length) {
200 cols.push(col);
201 }
202
203 // over height issue when pulling punctuation
204 if (values.punctuation.pull) {
205 for (let col of cols){
206 let last = col[col.length -1];
207 let diff = (last.y + last.height) - (values.height - values.margin);
208 if (diff>0){
209 let adj = parseInt(diff/(col.length)) + 1;
210 for (let i in col){
211 col[i].y -= adj*i + adj;
212 }
213 }
214 }
215 }
216
217 // contract, expand, adjust
218 let widths = [];
219 for (let col of cols){
220 let min = [(center - values.offset - values.pad)]
221 let max = [(center + values.offset + values.pad)]
222 for (let item of col){
223 min.push(item.x - values.pad);
224 max.push(item.x + item.width + values.pad);
225 }
226 min = Math.min(...min);
227 max = Math.max(...max);
228
229 let width = values.width;
230 let adj = 0;
231
232 if (!values.dynamic){
233 adj = center - parseInt((min + max)/2);
234 } else {
235 width = max - min;
236 adj = -min;
237 }
238 for (let item of col){
239 item.x += adj;
240 }
241 widths.push(width);
242 }
243
244 return {
245 'options': values,
246 'widths': widths,
247 'columns': cols
248 };
249}
250
251export { columnDefaults, columnDefaultsMerge, columns }
\No newline at end of file