@willwade/aac-processors 0.1.11 → 0.1.12
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/dist/browser/processors/gridset/resolver.js +10 -0
- package/dist/browser/processors/gridsetProcessor.js +126 -4
- package/dist/processors/gridset/resolver.js +10 -0
- package/dist/processors/gridsetProcessor.js +126 -4
- package/package.json +1 -3
- package/examples/.coverage +0 -0
- package/examples/.keep +0 -1
- package/examples/README.md +0 -55
- package/examples/browser-test.html +0 -331
- package/examples/communikate.dot +0 -2637
- package/examples/demo.js +0 -143
- package/examples/example-images/FileMap.xml +0 -51
- package/examples/example-images/Grids/Start/0-1-0-text-0.png +0 -0
- package/examples/example-images/Grids/Start/0-2-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/0-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/0-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/0-5-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/1-1-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/1-2-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/1-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/1-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/1-5-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/10-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/10-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/11-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/11-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/2-1-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/2-2-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/2-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/2-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/2-5-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/3-1-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/3-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/3-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/3-5-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/4-1-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/4-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/4-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/4-5-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/5-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/5-5-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/6-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/6-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/7-1-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/7-2-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/7-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/7-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/8-1-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/8-2-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/8-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/8-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/9-1.png +0 -0
- package/examples/example-images/Grids/Start/9-2.png +0 -0
- package/examples/example-images/Grids/Start/9-3-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/9-4-0-text-0.jpeg +0 -0
- package/examples/example-images/Grids/Start/grid.xml +0 -1325
- package/examples/example-images/Settings0/Styles/styles.xml +0 -39
- package/examples/example-images/Settings0/WebBrowser/webbrowserextensions.xml +0 -3
- package/examples/example-images/Settings0/settings.xml +0 -16
- package/examples/example-images.gridset +0 -0
- package/examples/example-images.zip +0 -0
- package/examples/example.ce +0 -0
- package/examples/example.dot +0 -14
- package/examples/example.grd +0 -1
- package/examples/example.gridset +0 -0
- package/examples/example.obf +0 -27
- package/examples/example.obz +0 -0
- package/examples/example.opml +0 -18
- package/examples/example.spb +0 -0
- package/examples/example.sps +0 -0
- package/examples/example2.grd +0 -1
- package/examples/obf/aboutme.json +0 -376
- package/examples/obf/array.json +0 -6
- package/examples/obf/hash.json +0 -4
- package/examples/obf/links.obz +0 -0
- package/examples/obf/simple.obf +0 -53
- package/examples/package-lock.json +0 -1326
- package/examples/package.json +0 -10
- package/examples/styled-output/converted-snap-to-touchchat.ce +0 -0
- package/examples/styled-output/styled-example.ce +0 -0
- package/examples/styled-output/styled-example.gridset +0 -0
- package/examples/styled-output/styled-example.obf +0 -37
- package/examples/styled-output/styled-example.spb +0 -0
- package/examples/styling-example.ts +0 -316
- package/examples/translate.js +0 -39
- package/examples/translate_demo.js +0 -254
- package/examples/typescript-demo.ts +0 -251
- package/examples/vitedemo/README.md +0 -164
- package/examples/vitedemo/index.html +0 -580
- package/examples/vitedemo/package-lock.json +0 -1751
- package/examples/vitedemo/package.json +0 -24
- package/examples/vitedemo/src/main.ts +0 -1001
- package/examples/vitedemo/src/vite-env.d.ts +0 -1
- package/examples/vitedemo/test-files/example.dot +0 -14
- package/examples/vitedemo/test-files/example.grd +0 -1
- 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 +0 -18
- package/examples/vitedemo/test-files/simple.obf +0 -53
- package/examples/vitedemo/tsconfig.json +0 -24
- package/examples/vitedemo/vite.config.ts +0 -57
|
@@ -42,6 +42,13 @@ export function resolveGrid3CellImage(zip, args, zipEntries) {
|
|
|
42
42
|
const y = args.y;
|
|
43
43
|
const entries = new Set(listZipEntries(zip, zipEntries));
|
|
44
44
|
const has = (p) => entries.has(normalizeZipPathLocal(p));
|
|
45
|
+
// Debug logging for cells that fail to resolve
|
|
46
|
+
const shouldDebug = imageName?.startsWith('-') && x !== undefined && y !== undefined;
|
|
47
|
+
const debugLog = (msg) => {
|
|
48
|
+
if (shouldDebug) {
|
|
49
|
+
console.log(`[Resolver] ${baseDir} (${x},${y}) "${imageName}": ${msg}`);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
45
52
|
// Built-in resource like [grid3x]... (old format, not symbol library)
|
|
46
53
|
// Check this BEFORE general symbol references to avoid misclassification
|
|
47
54
|
if (imageName && imageName.startsWith('[')) {
|
|
@@ -72,6 +79,7 @@ export function resolveGrid3CellImage(zip, args, zipEntries) {
|
|
|
72
79
|
// to be prefixed with the cell coordinates
|
|
73
80
|
if (imageName.startsWith('-') && x != null && y != null) {
|
|
74
81
|
const coordPrefixed = joinBaseDir(baseDir, `${x}-${y}${imageName}`);
|
|
82
|
+
debugLog(`trying coord-prefixed: ${coordPrefixed}, found: ${has(coordPrefixed)}`);
|
|
75
83
|
if (has(coordPrefixed))
|
|
76
84
|
return coordPrefixed;
|
|
77
85
|
}
|
|
@@ -114,12 +122,14 @@ export function resolveGrid3CellImage(zip, args, zipEntries) {
|
|
|
114
122
|
`${x}-${y}.jpg`,
|
|
115
123
|
`${x}-${y}.png`,
|
|
116
124
|
].map((n) => joinBaseDir(baseDir, n));
|
|
125
|
+
debugLog(`trying candidates: ${candidates.filter(has).join(', ') || 'none found'}`);
|
|
117
126
|
for (const c of candidates) {
|
|
118
127
|
if (has(c))
|
|
119
128
|
return c;
|
|
120
129
|
}
|
|
121
130
|
}
|
|
122
131
|
}
|
|
132
|
+
debugLog(`NOT FOUND - returning null`);
|
|
123
133
|
return null;
|
|
124
134
|
}
|
|
125
135
|
/**
|
|
@@ -646,15 +646,130 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
646
646
|
// Track WordList AutoContent cells and their positions for "more" button placement
|
|
647
647
|
const wordListAutoContentCells = [];
|
|
648
648
|
let wordListCellIndex = 0;
|
|
649
|
+
// Helper function to find next available position in grid (auto-flow)
|
|
650
|
+
// Returns {x, y} for next available slot that can accommodate the given span
|
|
651
|
+
const findNextAvailablePosition = (width, height, gridLayout) => {
|
|
652
|
+
for (let y = 0; y < maxRows; y++) {
|
|
653
|
+
for (let x = 0; x <= maxCols - width; x++) {
|
|
654
|
+
// Check if this position and the required span area are all free
|
|
655
|
+
let fits = true;
|
|
656
|
+
for (let dy = 0; dy < height && y + dy < maxRows; dy++) {
|
|
657
|
+
for (let dx = 0; dx < width && x + dx < maxCols; dx++) {
|
|
658
|
+
if (gridLayout[y + dy][x + dx] !== null) {
|
|
659
|
+
fits = false;
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (!fits)
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
if (fits) {
|
|
667
|
+
return { x, y };
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
// If no position found, return 0,0 (will be placed at first available)
|
|
672
|
+
return { x: 0, y: 0 };
|
|
673
|
+
};
|
|
674
|
+
// Helper function to find next available X position in a specific row
|
|
675
|
+
const findNextAvailableXInRow = (rowY, width, gridLayout) => {
|
|
676
|
+
for (let x = 0; x <= maxCols - width; x++) {
|
|
677
|
+
let fits = true;
|
|
678
|
+
for (let dx = 0; dx < width; dx++) {
|
|
679
|
+
if (gridLayout[rowY][x + dx] !== null) {
|
|
680
|
+
fits = false;
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (fits)
|
|
685
|
+
return x;
|
|
686
|
+
}
|
|
687
|
+
return 0;
|
|
688
|
+
};
|
|
689
|
+
const cellsWithExplicitPosition = [];
|
|
690
|
+
const cellsWithYOnly = [];
|
|
691
|
+
const cellsWithXOnly = [];
|
|
692
|
+
const cellsWithAutoFlow = [];
|
|
649
693
|
cellArr.forEach((cell, idx) => {
|
|
650
694
|
if (!cell || !cell.Content)
|
|
651
695
|
return;
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
696
|
+
const hasX = cell['@_X'] !== undefined;
|
|
697
|
+
const hasY = cell['@_Y'] !== undefined;
|
|
698
|
+
if (hasX && hasY) {
|
|
699
|
+
cellsWithExplicitPosition.push({ cell, idx });
|
|
700
|
+
}
|
|
701
|
+
else if (hasY && !hasX) {
|
|
702
|
+
cellsWithYOnly.push({ cell, idx });
|
|
703
|
+
}
|
|
704
|
+
else if (!hasY && hasX) {
|
|
705
|
+
cellsWithXOnly.push({ cell, idx });
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
cellsWithAutoFlow.push({ cell, idx });
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
// Process cells in order: explicit -> Y-only -> X-only -> auto-flow
|
|
712
|
+
const allCellsToProcess = [
|
|
713
|
+
...cellsWithExplicitPosition,
|
|
714
|
+
...cellsWithYOnly,
|
|
715
|
+
...cellsWithXOnly,
|
|
716
|
+
...cellsWithAutoFlow,
|
|
717
|
+
];
|
|
718
|
+
allCellsToProcess.forEach(({ cell, idx }) => {
|
|
719
|
+
// Extract span information first
|
|
656
720
|
const colSpan = parseInt(String(cell['@_ColumnSpan'] || '1'), 10);
|
|
657
721
|
const rowSpan = parseInt(String(cell['@_RowSpan'] || '1'), 10);
|
|
722
|
+
// Determine position based on what attributes are present
|
|
723
|
+
const hasX = cell['@_X'] !== undefined;
|
|
724
|
+
const hasY = cell['@_Y'] !== undefined;
|
|
725
|
+
let cellX;
|
|
726
|
+
let cellY;
|
|
727
|
+
if (hasX && hasY) {
|
|
728
|
+
// Explicit position: both X and Y provided
|
|
729
|
+
// Grid 3 XML coordinates are already 0-based, use them directly
|
|
730
|
+
cellX = Math.max(0, parseInt(String(cell['@_X']), 10));
|
|
731
|
+
cellY = Math.max(0, parseInt(String(cell['@_Y']), 10));
|
|
732
|
+
}
|
|
733
|
+
else if (hasY && !hasX) {
|
|
734
|
+
// Y-only: auto-flow X in the specified row
|
|
735
|
+
// Grid 3 XML coordinates are already 0-based, use them directly
|
|
736
|
+
cellY = Math.max(0, parseInt(String(cell['@_Y']), 10));
|
|
737
|
+
cellX = findNextAvailableXInRow(cellY, colSpan, gridLayout);
|
|
738
|
+
}
|
|
739
|
+
else if (!hasY && hasX) {
|
|
740
|
+
// X-only: place at specified X in next available row
|
|
741
|
+
// Grid 3 XML coordinates are already 0-based, use them directly
|
|
742
|
+
cellX = Math.max(0, parseInt(String(cell['@_X']), 10));
|
|
743
|
+
// Find first row where this X position is available
|
|
744
|
+
cellY = 0;
|
|
745
|
+
let found = false;
|
|
746
|
+
for (let y = 0; y < maxRows; y++) {
|
|
747
|
+
let fits = true;
|
|
748
|
+
for (let dx = 0; dx < colSpan && cellX + dx < maxCols; dx++) {
|
|
749
|
+
if (gridLayout[y][cellX + dx] !== null) {
|
|
750
|
+
fits = false;
|
|
751
|
+
break;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
if (fits) {
|
|
755
|
+
cellY = y;
|
|
756
|
+
found = true;
|
|
757
|
+
break;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
if (!found) {
|
|
761
|
+
// No available row found, use auto-flow
|
|
762
|
+
const pos = findNextAvailablePosition(colSpan, rowSpan, gridLayout);
|
|
763
|
+
cellX = pos.x;
|
|
764
|
+
cellY = pos.y;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
// No position: auto-flow both X and Y
|
|
769
|
+
const pos = findNextAvailablePosition(colSpan, rowSpan, gridLayout);
|
|
770
|
+
cellX = pos.x;
|
|
771
|
+
cellY = pos.y;
|
|
772
|
+
}
|
|
658
773
|
// Extract scan block number (1-8) for block scanning support
|
|
659
774
|
const scanBlock = parseInt(String(cell['@_ScanBlock'] || '1'), 10);
|
|
660
775
|
// Extract visibility from Grid 3's <Visibility> child element
|
|
@@ -797,6 +912,13 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
797
912
|
y: cellY,
|
|
798
913
|
dynamicFiles,
|
|
799
914
|
}, entries) || undefined;
|
|
915
|
+
// Debug: log resolution for cells with images
|
|
916
|
+
if (declaredImageName && resolvedImageEntry) {
|
|
917
|
+
console.log(`[GridsetProcessor] Cell (${cellX + 1},${cellY + 1}) [XML coords]: ${declaredImageName} -> ${resolvedImageEntry}`);
|
|
918
|
+
}
|
|
919
|
+
else if (declaredImageName && !resolvedImageEntry) {
|
|
920
|
+
console.log(`[GridsetProcessor] Cell (${cellX + 1},${cellY + 1}) [XML coords]: ${declaredImageName} -> NOT FOUND`);
|
|
921
|
+
}
|
|
800
922
|
// Check if image is a symbol library reference
|
|
801
923
|
let symbolLibraryRef = null;
|
|
802
924
|
if (declaredImageName && isSymbolLibraryReference(declaredImageName)) {
|
|
@@ -47,6 +47,13 @@ function resolveGrid3CellImage(zip, args, zipEntries) {
|
|
|
47
47
|
const y = args.y;
|
|
48
48
|
const entries = new Set(listZipEntries(zip, zipEntries));
|
|
49
49
|
const has = (p) => entries.has(normalizeZipPathLocal(p));
|
|
50
|
+
// Debug logging for cells that fail to resolve
|
|
51
|
+
const shouldDebug = imageName?.startsWith('-') && x !== undefined && y !== undefined;
|
|
52
|
+
const debugLog = (msg) => {
|
|
53
|
+
if (shouldDebug) {
|
|
54
|
+
console.log(`[Resolver] ${baseDir} (${x},${y}) "${imageName}": ${msg}`);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
50
57
|
// Built-in resource like [grid3x]... (old format, not symbol library)
|
|
51
58
|
// Check this BEFORE general symbol references to avoid misclassification
|
|
52
59
|
if (imageName && imageName.startsWith('[')) {
|
|
@@ -77,6 +84,7 @@ function resolveGrid3CellImage(zip, args, zipEntries) {
|
|
|
77
84
|
// to be prefixed with the cell coordinates
|
|
78
85
|
if (imageName.startsWith('-') && x != null && y != null) {
|
|
79
86
|
const coordPrefixed = joinBaseDir(baseDir, `${x}-${y}${imageName}`);
|
|
87
|
+
debugLog(`trying coord-prefixed: ${coordPrefixed}, found: ${has(coordPrefixed)}`);
|
|
80
88
|
if (has(coordPrefixed))
|
|
81
89
|
return coordPrefixed;
|
|
82
90
|
}
|
|
@@ -119,12 +127,14 @@ function resolveGrid3CellImage(zip, args, zipEntries) {
|
|
|
119
127
|
`${x}-${y}.jpg`,
|
|
120
128
|
`${x}-${y}.png`,
|
|
121
129
|
].map((n) => joinBaseDir(baseDir, n));
|
|
130
|
+
debugLog(`trying candidates: ${candidates.filter(has).join(', ') || 'none found'}`);
|
|
122
131
|
for (const c of candidates) {
|
|
123
132
|
if (has(c))
|
|
124
133
|
return c;
|
|
125
134
|
}
|
|
126
135
|
}
|
|
127
136
|
}
|
|
137
|
+
debugLog(`NOT FOUND - returning null`);
|
|
128
138
|
return null;
|
|
129
139
|
}
|
|
130
140
|
/**
|
|
@@ -672,15 +672,130 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
672
672
|
// Track WordList AutoContent cells and their positions for "more" button placement
|
|
673
673
|
const wordListAutoContentCells = [];
|
|
674
674
|
let wordListCellIndex = 0;
|
|
675
|
+
// Helper function to find next available position in grid (auto-flow)
|
|
676
|
+
// Returns {x, y} for next available slot that can accommodate the given span
|
|
677
|
+
const findNextAvailablePosition = (width, height, gridLayout) => {
|
|
678
|
+
for (let y = 0; y < maxRows; y++) {
|
|
679
|
+
for (let x = 0; x <= maxCols - width; x++) {
|
|
680
|
+
// Check if this position and the required span area are all free
|
|
681
|
+
let fits = true;
|
|
682
|
+
for (let dy = 0; dy < height && y + dy < maxRows; dy++) {
|
|
683
|
+
for (let dx = 0; dx < width && x + dx < maxCols; dx++) {
|
|
684
|
+
if (gridLayout[y + dy][x + dx] !== null) {
|
|
685
|
+
fits = false;
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
if (!fits)
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
692
|
+
if (fits) {
|
|
693
|
+
return { x, y };
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
// If no position found, return 0,0 (will be placed at first available)
|
|
698
|
+
return { x: 0, y: 0 };
|
|
699
|
+
};
|
|
700
|
+
// Helper function to find next available X position in a specific row
|
|
701
|
+
const findNextAvailableXInRow = (rowY, width, gridLayout) => {
|
|
702
|
+
for (let x = 0; x <= maxCols - width; x++) {
|
|
703
|
+
let fits = true;
|
|
704
|
+
for (let dx = 0; dx < width; dx++) {
|
|
705
|
+
if (gridLayout[rowY][x + dx] !== null) {
|
|
706
|
+
fits = false;
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
if (fits)
|
|
711
|
+
return x;
|
|
712
|
+
}
|
|
713
|
+
return 0;
|
|
714
|
+
};
|
|
715
|
+
const cellsWithExplicitPosition = [];
|
|
716
|
+
const cellsWithYOnly = [];
|
|
717
|
+
const cellsWithXOnly = [];
|
|
718
|
+
const cellsWithAutoFlow = [];
|
|
675
719
|
cellArr.forEach((cell, idx) => {
|
|
676
720
|
if (!cell || !cell.Content)
|
|
677
721
|
return;
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
722
|
+
const hasX = cell['@_X'] !== undefined;
|
|
723
|
+
const hasY = cell['@_Y'] !== undefined;
|
|
724
|
+
if (hasX && hasY) {
|
|
725
|
+
cellsWithExplicitPosition.push({ cell, idx });
|
|
726
|
+
}
|
|
727
|
+
else if (hasY && !hasX) {
|
|
728
|
+
cellsWithYOnly.push({ cell, idx });
|
|
729
|
+
}
|
|
730
|
+
else if (!hasY && hasX) {
|
|
731
|
+
cellsWithXOnly.push({ cell, idx });
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
cellsWithAutoFlow.push({ cell, idx });
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
// Process cells in order: explicit -> Y-only -> X-only -> auto-flow
|
|
738
|
+
const allCellsToProcess = [
|
|
739
|
+
...cellsWithExplicitPosition,
|
|
740
|
+
...cellsWithYOnly,
|
|
741
|
+
...cellsWithXOnly,
|
|
742
|
+
...cellsWithAutoFlow,
|
|
743
|
+
];
|
|
744
|
+
allCellsToProcess.forEach(({ cell, idx }) => {
|
|
745
|
+
// Extract span information first
|
|
682
746
|
const colSpan = parseInt(String(cell['@_ColumnSpan'] || '1'), 10);
|
|
683
747
|
const rowSpan = parseInt(String(cell['@_RowSpan'] || '1'), 10);
|
|
748
|
+
// Determine position based on what attributes are present
|
|
749
|
+
const hasX = cell['@_X'] !== undefined;
|
|
750
|
+
const hasY = cell['@_Y'] !== undefined;
|
|
751
|
+
let cellX;
|
|
752
|
+
let cellY;
|
|
753
|
+
if (hasX && hasY) {
|
|
754
|
+
// Explicit position: both X and Y provided
|
|
755
|
+
// Grid 3 XML coordinates are already 0-based, use them directly
|
|
756
|
+
cellX = Math.max(0, parseInt(String(cell['@_X']), 10));
|
|
757
|
+
cellY = Math.max(0, parseInt(String(cell['@_Y']), 10));
|
|
758
|
+
}
|
|
759
|
+
else if (hasY && !hasX) {
|
|
760
|
+
// Y-only: auto-flow X in the specified row
|
|
761
|
+
// Grid 3 XML coordinates are already 0-based, use them directly
|
|
762
|
+
cellY = Math.max(0, parseInt(String(cell['@_Y']), 10));
|
|
763
|
+
cellX = findNextAvailableXInRow(cellY, colSpan, gridLayout);
|
|
764
|
+
}
|
|
765
|
+
else if (!hasY && hasX) {
|
|
766
|
+
// X-only: place at specified X in next available row
|
|
767
|
+
// Grid 3 XML coordinates are already 0-based, use them directly
|
|
768
|
+
cellX = Math.max(0, parseInt(String(cell['@_X']), 10));
|
|
769
|
+
// Find first row where this X position is available
|
|
770
|
+
cellY = 0;
|
|
771
|
+
let found = false;
|
|
772
|
+
for (let y = 0; y < maxRows; y++) {
|
|
773
|
+
let fits = true;
|
|
774
|
+
for (let dx = 0; dx < colSpan && cellX + dx < maxCols; dx++) {
|
|
775
|
+
if (gridLayout[y][cellX + dx] !== null) {
|
|
776
|
+
fits = false;
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (fits) {
|
|
781
|
+
cellY = y;
|
|
782
|
+
found = true;
|
|
783
|
+
break;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (!found) {
|
|
787
|
+
// No available row found, use auto-flow
|
|
788
|
+
const pos = findNextAvailablePosition(colSpan, rowSpan, gridLayout);
|
|
789
|
+
cellX = pos.x;
|
|
790
|
+
cellY = pos.y;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
// No position: auto-flow both X and Y
|
|
795
|
+
const pos = findNextAvailablePosition(colSpan, rowSpan, gridLayout);
|
|
796
|
+
cellX = pos.x;
|
|
797
|
+
cellY = pos.y;
|
|
798
|
+
}
|
|
684
799
|
// Extract scan block number (1-8) for block scanning support
|
|
685
800
|
const scanBlock = parseInt(String(cell['@_ScanBlock'] || '1'), 10);
|
|
686
801
|
// Extract visibility from Grid 3's <Visibility> child element
|
|
@@ -823,6 +938,13 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
823
938
|
y: cellY,
|
|
824
939
|
dynamicFiles,
|
|
825
940
|
}, entries) || undefined;
|
|
941
|
+
// Debug: log resolution for cells with images
|
|
942
|
+
if (declaredImageName && resolvedImageEntry) {
|
|
943
|
+
console.log(`[GridsetProcessor] Cell (${cellX + 1},${cellY + 1}) [XML coords]: ${declaredImageName} -> ${resolvedImageEntry}`);
|
|
944
|
+
}
|
|
945
|
+
else if (declaredImageName && !resolvedImageEntry) {
|
|
946
|
+
console.log(`[GridsetProcessor] Cell (${cellX + 1},${cellY + 1}) [XML coords]: ${declaredImageName} -> NOT FOUND`);
|
|
947
|
+
}
|
|
826
948
|
// Check if image is a symbol library reference
|
|
827
949
|
let symbolLibraryRef = null;
|
|
828
950
|
if (declaredImageName && (0, resolver_2.isSymbolLibraryReference)(declaredImageName)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@willwade/aac-processors",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "A comprehensive TypeScript library for processing AAC (Augmentative and Alternative Communication) file formats with translation support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"browser": "dist/browser/index.browser.js",
|
|
@@ -80,13 +80,11 @@
|
|
|
80
80
|
"files": [
|
|
81
81
|
"dist/**/*",
|
|
82
82
|
"docs/**/*",
|
|
83
|
-
"examples/**/*",
|
|
84
83
|
"README.md",
|
|
85
84
|
"LICENSE"
|
|
86
85
|
],
|
|
87
86
|
"directories": {
|
|
88
87
|
"doc": "docs",
|
|
89
|
-
"example": "examples",
|
|
90
88
|
"test": "test"
|
|
91
89
|
},
|
|
92
90
|
"scripts": {
|
package/examples/.coverage
DELETED
|
Binary file
|
package/examples/.keep
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
package/examples/README.md
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# AAC Processors Example Pagesets
|
|
2
|
-
|
|
3
|
-
This directory contains example AAC pagesets in various formats used for testing and demonstration purposes.
|
|
4
|
-
|
|
5
|
-
## Available Pagesets
|
|
6
|
-
|
|
7
|
-
### Grid3 Format (.gridset)
|
|
8
|
-
- **example.gridset** - Main example pageset with multiple grids and wordlists
|
|
9
|
-
- **example-images.gridset** - Example pageset with embedded images
|
|
10
|
-
|
|
11
|
-
### Snap Format (.spb, .sps)
|
|
12
|
-
- **example.spb** - Snap pageset (binary format)
|
|
13
|
-
- **example.sps** - Snap pageset (alternative format)
|
|
14
|
-
|
|
15
|
-
### TouchChat Format (.ce)
|
|
16
|
-
- **example.ce** - TouchChat pageset
|
|
17
|
-
|
|
18
|
-
### OBF/OBZ Format (.obf, .obz)
|
|
19
|
-
- **example.obf** - OBF pageset (JSON-based)
|
|
20
|
-
- **example.obz** - OBZ pageset (compressed)
|
|
21
|
-
|
|
22
|
-
**obf/** - Directory containing validation test samples from the obf-node project:
|
|
23
|
-
- **simple.obf** - Simple, valid OBF file for basic validation tests
|
|
24
|
-
- **aboutme.json** - Invalid OBF (missing locale field) for error testing
|
|
25
|
-
- **hash.json** - Non-OBF JSON structure for format detection tests
|
|
26
|
-
- **array.json** - JSON array (not object) for structure validation tests
|
|
27
|
-
- **links.obz** - OBZ package with links for zip archive validation
|
|
28
|
-
|
|
29
|
-
### Asterics Grid Format (.grd)
|
|
30
|
-
- **example.grd** - Asterics Grid pageset
|
|
31
|
-
- **example2.grd** - Alternative Asterics Grid pageset
|
|
32
|
-
|
|
33
|
-
### DOT Format (.dot)
|
|
34
|
-
- **example.dot** - Simple DOT format pageset
|
|
35
|
-
- **communikate.dot** - Communikate DOT format pageset
|
|
36
|
-
|
|
37
|
-
### OPML Format (.opml)
|
|
38
|
-
- **example.opml** - OPML pageset
|
|
39
|
-
|
|
40
|
-
### Styled Output
|
|
41
|
-
- **styled-output/** - Directory containing example pagesets with styling applied
|
|
42
|
-
|
|
43
|
-
## Usage
|
|
44
|
-
|
|
45
|
-
These pagesets are used by:
|
|
46
|
-
- Unit tests in the main test suite
|
|
47
|
-
- Demo scripts in the `scripts/` directory
|
|
48
|
-
- Integration examples
|
|
49
|
-
|
|
50
|
-
To run demo scripts that use these pagesets, see the [scripts/README.md](../scripts/README.md).
|
|
51
|
-
|
|
52
|
-
## Browser Demo (Vite)
|
|
53
|
-
|
|
54
|
-
For browser testing, use the Vite demo in `examples/vitedemo`. It bundles the
|
|
55
|
-
library and exercises real processors in a browser environment.
|