@willwade/aac-processors 0.0.30 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -852
- package/dist/browser/core/baseProcessor.js +241 -0
- package/dist/browser/core/stringCasing.js +179 -0
- package/dist/browser/core/treeStructure.js +255 -0
- package/dist/browser/index.browser.js +73 -0
- package/dist/browser/processors/applePanelsProcessor.js +582 -0
- package/dist/browser/processors/astericsGridProcessor.js +1509 -0
- package/dist/browser/processors/dotProcessor.js +221 -0
- package/dist/browser/processors/gridset/commands.js +962 -0
- package/dist/browser/processors/gridset/crypto.js +53 -0
- package/dist/browser/processors/gridset/password.js +49 -0
- package/dist/browser/processors/gridset/pluginTypes.js +277 -0
- package/dist/browser/processors/gridset/resolver.js +137 -0
- package/dist/browser/processors/gridset/symbolAlignment.js +276 -0
- package/dist/browser/processors/gridset/symbols.js +464 -0
- package/dist/browser/processors/gridsetProcessor.js +2002 -0
- package/dist/browser/processors/obfProcessor.js +705 -0
- package/dist/browser/processors/opmlProcessor.js +274 -0
- package/dist/browser/types/aac.js +38 -0
- package/dist/browser/utilities/analytics/utils/idGenerator.js +89 -0
- package/dist/browser/utilities/translation/translationProcessor.js +200 -0
- package/dist/browser/utils/io.js +95 -0
- package/dist/browser/validation/baseValidator.js +156 -0
- package/dist/browser/validation/gridsetValidator.js +356 -0
- package/dist/browser/validation/obfValidator.js +500 -0
- package/dist/browser/validation/validationTypes.js +46 -0
- package/dist/cli/index.js +5 -5
- package/dist/core/analyze.d.ts +2 -2
- package/dist/core/analyze.js +2 -2
- package/dist/core/baseProcessor.d.ts +5 -4
- package/dist/core/baseProcessor.js +22 -27
- package/dist/core/treeStructure.d.ts +5 -5
- package/dist/core/treeStructure.js +1 -4
- package/dist/index.browser.d.ts +37 -0
- package/dist/index.browser.js +99 -0
- package/dist/index.d.ts +1 -48
- package/dist/index.js +1 -136
- package/dist/index.node.d.ts +48 -0
- package/dist/index.node.js +152 -0
- package/dist/processors/applePanelsProcessor.d.ts +5 -4
- package/dist/processors/applePanelsProcessor.js +58 -62
- package/dist/processors/astericsGridProcessor.d.ts +7 -6
- package/dist/processors/astericsGridProcessor.js +31 -42
- package/dist/processors/dotProcessor.d.ts +5 -4
- package/dist/processors/dotProcessor.js +25 -33
- package/dist/processors/excelProcessor.d.ts +4 -3
- package/dist/processors/excelProcessor.js +6 -3
- package/dist/processors/gridset/crypto.d.ts +18 -0
- package/dist/processors/gridset/crypto.js +57 -0
- package/dist/processors/gridset/helpers.d.ts +1 -1
- package/dist/processors/gridset/helpers.js +18 -8
- package/dist/processors/gridset/password.d.ts +20 -3
- package/dist/processors/gridset/password.js +29 -12
- package/dist/processors/gridset/symbols.js +63 -46
- package/dist/processors/gridset/wordlistHelpers.d.ts +3 -3
- package/dist/processors/gridset/wordlistHelpers.js +21 -20
- package/dist/processors/gridsetProcessor.d.ts +7 -12
- package/dist/processors/gridsetProcessor.js +116 -77
- package/dist/processors/obfProcessor.d.ts +9 -7
- package/dist/processors/obfProcessor.js +131 -56
- package/dist/processors/obfsetProcessor.d.ts +5 -4
- package/dist/processors/obfsetProcessor.js +10 -16
- package/dist/processors/opmlProcessor.d.ts +5 -4
- package/dist/processors/opmlProcessor.js +27 -34
- package/dist/processors/snapProcessor.d.ts +8 -7
- package/dist/processors/snapProcessor.js +15 -12
- package/dist/processors/touchchatProcessor.d.ts +8 -7
- package/dist/processors/touchchatProcessor.js +22 -17
- package/dist/types/aac.d.ts +0 -2
- package/dist/types/aac.js +2 -0
- package/dist/utils/io.d.ts +12 -0
- package/dist/utils/io.js +107 -0
- package/dist/validation/gridsetValidator.js +10 -9
- package/dist/validation/snapValidator.js +28 -35
- package/docs/BROWSER_USAGE.md +618 -0
- package/docs/PAGESET_GETTING_STARTED.md +185 -0
- package/examples/README.md +77 -0
- package/examples/browser-test-server.js +81 -0
- package/examples/browser-test.html +331 -0
- package/examples/vitedemo/QUICKSTART.md +75 -0
- package/examples/vitedemo/README.md +157 -0
- package/examples/vitedemo/index.html +531 -0
- package/examples/vitedemo/package-lock.json +1221 -0
- package/examples/vitedemo/package.json +18 -0
- package/examples/vitedemo/src/main.ts +871 -0
- package/examples/vitedemo/test-files/example.dot +14 -0
- package/examples/vitedemo/test-files/example.grd +1 -0
- package/examples/vitedemo/test-files/example.gridset +0 -0
- package/examples/vitedemo/test-files/example.obz +0 -0
- package/examples/vitedemo/test-files/example.opml +18 -0
- package/examples/vitedemo/test-files/simple.obf +53 -0
- package/examples/vitedemo/tsconfig.json +24 -0
- package/examples/vitedemo/vite.config.ts +34 -0
- package/package.json +21 -4
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid 3 Symbol Library Resolution
|
|
3
|
+
*
|
|
4
|
+
* Grid 3 uses symbol libraries stored as .pix files in the installation directory.
|
|
5
|
+
* Symbol references in Grid files use the format: [library]/path/to/symbol.png
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - [widgit]/food/apple.png
|
|
9
|
+
* - [tawasl]/above bw.png
|
|
10
|
+
* - [ssnaps]963.jpg
|
|
11
|
+
* - [grid3x]/folder/document.png
|
|
12
|
+
*
|
|
13
|
+
* This module provides symbol resolution and metadata extraction.
|
|
14
|
+
*/
|
|
15
|
+
import { getFs, getPath } from '../../utils/io';
|
|
16
|
+
/**
|
|
17
|
+
* Default Grid 3 installation paths by platform
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_GRID3_PATHS = {
|
|
20
|
+
win32: 'C:\\Program Files (x86)\\Smartbox\\Grid 3',
|
|
21
|
+
darwin: '/Applications/Grid 3.app/Contents/Resources',
|
|
22
|
+
linux: '/opt/smartbox/grid3',
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Path to Symbols directory within Grid 3 installation
|
|
26
|
+
* Contains .symbols ZIP archives with actual images
|
|
27
|
+
*/
|
|
28
|
+
const SYMBOLS_SUBDIR = 'Resources\\Symbols';
|
|
29
|
+
/**
|
|
30
|
+
* Path to symbol search indexes within Grid 3 installation
|
|
31
|
+
* Contains .pix index files for searching
|
|
32
|
+
*/
|
|
33
|
+
const SYMBOLSEARCH_SUBDIR = 'Locale';
|
|
34
|
+
/**
|
|
35
|
+
* Known symbol libraries in Grid 3
|
|
36
|
+
*/
|
|
37
|
+
export const SYMBOL_LIBRARIES = {
|
|
38
|
+
WIDGIT: 'widgit',
|
|
39
|
+
TAWASL: 'tawasl',
|
|
40
|
+
SSNAPS: 'ssnaps',
|
|
41
|
+
GRID3X: 'grid3x',
|
|
42
|
+
GRID2X: 'grid2x',
|
|
43
|
+
BLISSX: 'blissx',
|
|
44
|
+
EYEGAZ: 'eyegaz',
|
|
45
|
+
INTERL: 'interl',
|
|
46
|
+
METACM: 'metacm',
|
|
47
|
+
MJPCS: 'mjpcs#',
|
|
48
|
+
PCSHC: 'pcshc#',
|
|
49
|
+
PCSTL: 'pcstl#',
|
|
50
|
+
SESENS: 'sesens',
|
|
51
|
+
SSTIX: 'sstix#',
|
|
52
|
+
SYMOJI: 'symoji',
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Default locale to use
|
|
56
|
+
*/
|
|
57
|
+
export const DEFAULT_LOCALE = 'en-GB';
|
|
58
|
+
function getNodeFs() {
|
|
59
|
+
try {
|
|
60
|
+
return getFs();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
throw new Error('Symbol library access is not available in this environment.');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function getNodePath() {
|
|
67
|
+
try {
|
|
68
|
+
return getPath();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
throw new Error('Path utilities are not available in this environment.');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
let cachedAdmZip = null;
|
|
75
|
+
function getAdmZip() {
|
|
76
|
+
if (cachedAdmZip)
|
|
77
|
+
return cachedAdmZip;
|
|
78
|
+
try {
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
80
|
+
const module = require('adm-zip');
|
|
81
|
+
const resolved = module.default || module;
|
|
82
|
+
cachedAdmZip = resolved;
|
|
83
|
+
return resolved;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
throw new Error('Symbol library access requires AdmZip in this environment.');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse a symbol reference string
|
|
91
|
+
* @param reference - Symbol reference like "[widgit]/food/apple.png"
|
|
92
|
+
* @returns Parsed symbol reference
|
|
93
|
+
*/
|
|
94
|
+
export function parseSymbolReference(reference) {
|
|
95
|
+
const trimmed = reference.trim();
|
|
96
|
+
// Match pattern: [library]/path or [library]path
|
|
97
|
+
const match = trimmed.match(/^\[([^\]]+)\](.+)$/);
|
|
98
|
+
if (!match) {
|
|
99
|
+
return {
|
|
100
|
+
library: '',
|
|
101
|
+
path: trimmed,
|
|
102
|
+
fullReference: trimmed,
|
|
103
|
+
isValid: false,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const [, library, symbolPath] = match;
|
|
107
|
+
return {
|
|
108
|
+
library: library.toLowerCase(),
|
|
109
|
+
path: symbolPath.replace(/^\\+/, '').trim(), // Remove leading slashes
|
|
110
|
+
fullReference: trimmed,
|
|
111
|
+
isValid: true,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if a string is a symbol library reference
|
|
116
|
+
* @param reference - String to check
|
|
117
|
+
* @returns True if it's a symbol reference like [widgit]/...
|
|
118
|
+
*/
|
|
119
|
+
export function isSymbolReference(reference) {
|
|
120
|
+
return reference.trim().startsWith('[');
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get the default Grid 3 installation path for the current platform
|
|
124
|
+
* @returns Default Grid 3 path or empty string if not found
|
|
125
|
+
*/
|
|
126
|
+
export function getDefaultGrid3Path() {
|
|
127
|
+
const platform = (typeof process !== 'undefined' && process.platform ? process.platform : 'unknown');
|
|
128
|
+
const defaultPath = DEFAULT_GRID3_PATHS[platform] || '';
|
|
129
|
+
try {
|
|
130
|
+
const fs = getNodeFs();
|
|
131
|
+
if (defaultPath && fs.existsSync(defaultPath)) {
|
|
132
|
+
return defaultPath;
|
|
133
|
+
}
|
|
134
|
+
// Try to find Grid 3 in common locations
|
|
135
|
+
const commonPaths = [
|
|
136
|
+
'C:\\Program Files (x86)\\Smartbox\\Grid 3',
|
|
137
|
+
'C:\\Program Files\\Smartbox\\Grid 3',
|
|
138
|
+
'C:\\Program Files\\Smartbox\\Grid 3',
|
|
139
|
+
'/Applications/Grid 3.app',
|
|
140
|
+
'/opt/smartbox/grid3',
|
|
141
|
+
];
|
|
142
|
+
for (const testPath of commonPaths) {
|
|
143
|
+
if (fs.existsSync(testPath)) {
|
|
144
|
+
return testPath;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return '';
|
|
150
|
+
}
|
|
151
|
+
return '';
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get the Symbol Libraries directory path
|
|
155
|
+
* Contains .symbols ZIP archives with actual image files
|
|
156
|
+
* @param grid3Path - Grid 3 installation path
|
|
157
|
+
* @returns Path to Symbol Libraries directory (e.g., "C:\...\Grid 3\Resources\Symbols")
|
|
158
|
+
*/
|
|
159
|
+
export function getSymbolLibrariesDir(grid3Path) {
|
|
160
|
+
const path = getNodePath();
|
|
161
|
+
return path.join(grid3Path, SYMBOLS_SUBDIR);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get the symbol search indexes directory path for a given locale
|
|
165
|
+
* Contains .pix index files for searching symbols
|
|
166
|
+
* @param grid3Path - Grid 3 installation path
|
|
167
|
+
* @param locale - Locale code (e.g., 'en-GB')
|
|
168
|
+
* @returns Path to symbol search indexes directory (e.g., "C:\...\Grid 3\Locale\en-GB\symbolsearch")
|
|
169
|
+
*/
|
|
170
|
+
export function getSymbolSearchIndexesDir(grid3Path, locale = DEFAULT_LOCALE) {
|
|
171
|
+
const path = getNodePath();
|
|
172
|
+
return path.join(grid3Path, SYMBOLSEARCH_SUBDIR, locale, 'symbolsearch');
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get all available symbol libraries in the Grid 3 installation
|
|
176
|
+
* @param options - Resolution options
|
|
177
|
+
* @returns Array of symbol library information
|
|
178
|
+
*/
|
|
179
|
+
export function getAvailableSymbolLibraries(options = {}) {
|
|
180
|
+
const grid3Path = options.grid3Path || options.symbolDir || getDefaultGrid3Path();
|
|
181
|
+
if (!grid3Path) {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
const symbolsDir = getSymbolLibrariesDir(grid3Path);
|
|
185
|
+
const fs = getNodeFs();
|
|
186
|
+
if (!fs.existsSync(symbolsDir)) {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
const libraries = [];
|
|
190
|
+
const files = fs.readdirSync(symbolsDir);
|
|
191
|
+
for (const file of files) {
|
|
192
|
+
if (file.endsWith('.symbols')) {
|
|
193
|
+
const path = getNodePath();
|
|
194
|
+
const fullPath = path.join(symbolsDir, file);
|
|
195
|
+
const stats = fs.statSync(fullPath);
|
|
196
|
+
const libraryName = path.basename(file, '.symbols');
|
|
197
|
+
libraries.push({
|
|
198
|
+
name: libraryName,
|
|
199
|
+
pixFile: fullPath, // Reuse this field for the .symbols file path
|
|
200
|
+
exists: true,
|
|
201
|
+
size: stats.size,
|
|
202
|
+
locale: 'global', // .symbols files are not locale-specific
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return libraries.sort((a, b) => a.name.localeCompare(b.name));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Check if a symbol library exists
|
|
210
|
+
* @param libraryName - Name of the library (e.g., 'widgit', 'tawasl')
|
|
211
|
+
* @param options - Resolution options
|
|
212
|
+
* @returns Symbol library info or undefined if not found
|
|
213
|
+
*/
|
|
214
|
+
export function getSymbolLibraryInfo(libraryName, options = {}) {
|
|
215
|
+
const grid3Path = options.grid3Path || options.symbolDir || getDefaultGrid3Path();
|
|
216
|
+
if (!grid3Path) {
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
const symbolsDir = getSymbolLibrariesDir(grid3Path);
|
|
220
|
+
const normalizedLibName = libraryName.toLowerCase();
|
|
221
|
+
// Try different case variations
|
|
222
|
+
const variations = [
|
|
223
|
+
normalizedLibName + '.symbols',
|
|
224
|
+
normalizedLibName.toUpperCase() + '.symbols',
|
|
225
|
+
libraryName + '.symbols',
|
|
226
|
+
];
|
|
227
|
+
for (const file of variations) {
|
|
228
|
+
const path = getNodePath();
|
|
229
|
+
const fullPath = path.join(symbolsDir, file);
|
|
230
|
+
const fs = getNodeFs();
|
|
231
|
+
if (fs.existsSync(fullPath)) {
|
|
232
|
+
const stats = fs.statSync(fullPath);
|
|
233
|
+
return {
|
|
234
|
+
name: libraryName,
|
|
235
|
+
pixFile: fullPath,
|
|
236
|
+
exists: true,
|
|
237
|
+
size: stats.size,
|
|
238
|
+
locale: 'global',
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Resolve a symbol reference to extract the actual image data
|
|
246
|
+
* @param reference - Symbol reference like "[tawasl]/above bw.png"
|
|
247
|
+
* @param options - Resolution options
|
|
248
|
+
* @returns Resolution result with image data if found
|
|
249
|
+
*/
|
|
250
|
+
export function resolveSymbolReference(reference, options = {}) {
|
|
251
|
+
const parsed = parseSymbolReference(reference);
|
|
252
|
+
if (!parsed.isValid) {
|
|
253
|
+
return {
|
|
254
|
+
reference: parsed,
|
|
255
|
+
found: false,
|
|
256
|
+
error: 'Invalid symbol reference format',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
const grid3Path = options.grid3Path || getDefaultGrid3Path();
|
|
260
|
+
if (!grid3Path) {
|
|
261
|
+
return {
|
|
262
|
+
reference: parsed,
|
|
263
|
+
found: false,
|
|
264
|
+
error: 'Grid 3 installation not found. Please specify grid3Path.',
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const libraryInfo = getSymbolLibraryInfo(parsed.library, { grid3Path });
|
|
268
|
+
if (!libraryInfo || !libraryInfo.exists) {
|
|
269
|
+
return {
|
|
270
|
+
reference: parsed,
|
|
271
|
+
found: false,
|
|
272
|
+
error: `Symbol library '${parsed.library}' not found at ${libraryInfo?.pixFile || 'unknown'}`,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
// .symbols files are ZIP archives
|
|
277
|
+
const AdmZip = getAdmZip();
|
|
278
|
+
const zip = new AdmZip(libraryInfo.pixFile);
|
|
279
|
+
// The path in the symbol reference becomes the path within the symbols/ folder
|
|
280
|
+
// e.g., [tawasl]/above bw.png becomes symbols/above bw.png
|
|
281
|
+
const symbolPath = `symbols/${parsed.path}`;
|
|
282
|
+
const entry = zip.getEntry(symbolPath);
|
|
283
|
+
if (!entry) {
|
|
284
|
+
// Try without the symbols/ prefix (in case reference already includes it)
|
|
285
|
+
const altPath = parsed.path.startsWith('symbols/') ? parsed.path : `symbols/${parsed.path}`;
|
|
286
|
+
const altEntry = zip.getEntry(altPath);
|
|
287
|
+
if (!altEntry) {
|
|
288
|
+
return {
|
|
289
|
+
reference: parsed,
|
|
290
|
+
found: false,
|
|
291
|
+
error: `Symbol '${parsed.path}' not found in library '${parsed.library}'`,
|
|
292
|
+
path: libraryInfo.pixFile,
|
|
293
|
+
libraryInfo,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
// Found with alternate path
|
|
297
|
+
const data = altEntry.getData();
|
|
298
|
+
return {
|
|
299
|
+
reference: parsed,
|
|
300
|
+
found: true,
|
|
301
|
+
path: libraryInfo.pixFile,
|
|
302
|
+
data,
|
|
303
|
+
libraryInfo,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
// Found the symbol!
|
|
307
|
+
const data = entry.getData();
|
|
308
|
+
return {
|
|
309
|
+
reference: parsed,
|
|
310
|
+
found: true,
|
|
311
|
+
path: libraryInfo.pixFile,
|
|
312
|
+
data,
|
|
313
|
+
libraryInfo,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
return {
|
|
318
|
+
reference: parsed,
|
|
319
|
+
found: false,
|
|
320
|
+
error: `Failed to extract symbol: ${error.message}`,
|
|
321
|
+
path: libraryInfo.pixFile,
|
|
322
|
+
libraryInfo,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Get all symbol references from a gridset
|
|
328
|
+
* This scans button images for symbol references
|
|
329
|
+
* @param tree - AAC tree from loaded gridset
|
|
330
|
+
* @returns Array of unique symbol references
|
|
331
|
+
*/
|
|
332
|
+
export function extractSymbolReferences(tree) {
|
|
333
|
+
const references = new Set();
|
|
334
|
+
for (const pageId in tree.pages) {
|
|
335
|
+
const page = tree.pages[pageId];
|
|
336
|
+
if (page.buttons) {
|
|
337
|
+
for (const button of page.buttons) {
|
|
338
|
+
if (button.image && isSymbolReference(String(button.image))) {
|
|
339
|
+
references.add(String(button.image));
|
|
340
|
+
}
|
|
341
|
+
// Check for symbol library metadata
|
|
342
|
+
if (button.symbolLibrary) {
|
|
343
|
+
const ref = `[${button.symbolLibrary}]${button.symbolPath || ''}`;
|
|
344
|
+
references.add(ref);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return Array.from(references).sort();
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Create a symbol reference from library and path
|
|
353
|
+
* @param library - Library name
|
|
354
|
+
* @param symbolPath - Path within the library
|
|
355
|
+
* @returns Formatted symbol reference
|
|
356
|
+
*/
|
|
357
|
+
export function createSymbolReference(library, symbolPath) {
|
|
358
|
+
const normalizedLib = library.toLowerCase().replace(/\[|\]/g, '');
|
|
359
|
+
const normalizedPath = symbolPath.replace(/^\\+/, '');
|
|
360
|
+
return `[${normalizedLib}]${normalizedPath}`;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Get the library name from a symbol reference
|
|
364
|
+
* @param reference - Symbol reference
|
|
365
|
+
* @returns Library name or empty string
|
|
366
|
+
*/
|
|
367
|
+
export function getSymbolLibraryName(reference) {
|
|
368
|
+
const parsed = parseSymbolReference(reference);
|
|
369
|
+
return parsed.library;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get the symbol path from a symbol reference
|
|
373
|
+
* @param reference - Symbol reference
|
|
374
|
+
* @returns Symbol path or empty string
|
|
375
|
+
*/
|
|
376
|
+
export function getSymbolPath(reference) {
|
|
377
|
+
const parsed = parseSymbolReference(reference);
|
|
378
|
+
return parsed.path;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Check if a symbol library is one of the known Grid 3 libraries
|
|
382
|
+
* @param libraryName - Library name to check
|
|
383
|
+
* @returns True if it's a known library
|
|
384
|
+
*/
|
|
385
|
+
export function isKnownSymbolLibrary(libraryName) {
|
|
386
|
+
const normalized = libraryName.toLowerCase().replace(/\[|\]/g, '');
|
|
387
|
+
return Object.values(SYMBOL_LIBRARIES).includes(normalized);
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Get display name for a symbol library
|
|
391
|
+
* @param libraryName - Library name
|
|
392
|
+
* @returns Human-readable display name
|
|
393
|
+
*/
|
|
394
|
+
export function getSymbolLibraryDisplayName(libraryName) {
|
|
395
|
+
const normalized = libraryName.toLowerCase().replace(/\[|\]/g, '');
|
|
396
|
+
const displayNames = {
|
|
397
|
+
widgit: 'Widgit Symbols',
|
|
398
|
+
tawasl: 'Tawasol (Arabic)',
|
|
399
|
+
ssnaps: 'Smartbox Symbol Snapshots',
|
|
400
|
+
grid3x: 'Grid 3 Extended',
|
|
401
|
+
grid2x: 'Grid 2 Extended',
|
|
402
|
+
blissx: 'Blissymbols',
|
|
403
|
+
eyegaz: 'Eye Gaze Symbols',
|
|
404
|
+
interl: 'International Symbols',
|
|
405
|
+
metacm: 'MetaComm',
|
|
406
|
+
mjpcs: 'Mayer-Johnson PCS',
|
|
407
|
+
pcshc: 'PCS High Contrast',
|
|
408
|
+
pcstl: 'PCS Thin Line',
|
|
409
|
+
sesens: 'Sensory Software',
|
|
410
|
+
sstix: 'Smartbox TIX',
|
|
411
|
+
symoji: 'Symbol Emoji',
|
|
412
|
+
};
|
|
413
|
+
return displayNames[normalized] || normalized.charAt(0).toUpperCase() + normalized.slice(1);
|
|
414
|
+
}
|
|
415
|
+
export function analyzeSymbolUsage(tree) {
|
|
416
|
+
const references = extractSymbolReferences(tree);
|
|
417
|
+
const byLibrary = {};
|
|
418
|
+
const libraries = new Set();
|
|
419
|
+
for (const ref of references) {
|
|
420
|
+
const lib = getSymbolLibraryName(ref);
|
|
421
|
+
byLibrary[lib] = (byLibrary[lib] || 0) + 1;
|
|
422
|
+
if (lib) {
|
|
423
|
+
libraries.add(lib);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
totalSymbols: references.length,
|
|
428
|
+
byLibrary,
|
|
429
|
+
uniqueReferences: references,
|
|
430
|
+
librariesUsed: Array.from(libraries).sort(),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Convert symbol reference to filename for embedded images
|
|
435
|
+
* Grid 3 sometimes embeds symbols with special naming
|
|
436
|
+
* @param reference - Symbol reference
|
|
437
|
+
* @param cellX - Cell X coordinate
|
|
438
|
+
* @param cellY - Cell Y coordinate
|
|
439
|
+
* @returns Generated filename
|
|
440
|
+
*/
|
|
441
|
+
export function symbolReferenceToFilename(reference, cellX, cellY) {
|
|
442
|
+
const parsed = parseSymbolReference(reference);
|
|
443
|
+
const dotIndex = parsed.path.lastIndexOf('.');
|
|
444
|
+
const ext = dotIndex >= 0 ? parsed.path.slice(dotIndex) : '.png';
|
|
445
|
+
// Grid 3 format: {x}-{y}-0-text-0.{ext}
|
|
446
|
+
return `${cellX}-${cellY}-0-text-0${ext}`;
|
|
447
|
+
}
|
|
448
|
+
// ============================================================================
|
|
449
|
+
// BACKWARD COMPATIBILITY ALIASES
|
|
450
|
+
// ============================================================================
|
|
451
|
+
/**
|
|
452
|
+
* @deprecated Use getSymbolLibrariesDir() instead - more descriptive name
|
|
453
|
+
* Get the Symbols directory path (where .symbols ZIP archives are)
|
|
454
|
+
*/
|
|
455
|
+
export function getSymbolsDir(grid3Path) {
|
|
456
|
+
return getSymbolLibrariesDir(grid3Path);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* @deprecated Use getSymbolSearchIndexesDir() instead - more descriptive name
|
|
460
|
+
* Get the symbol search directory for a given locale (where .pix index files are)
|
|
461
|
+
*/
|
|
462
|
+
export function getSymbolSearchDir(grid3Path, locale = DEFAULT_LOCALE) {
|
|
463
|
+
return getSymbolSearchIndexesDir(grid3Path, locale);
|
|
464
|
+
}
|