@@ -18,6 +18,12 @@ import AdmZip from 'adm-zip';
1818import fs from 'fs' ;
1919import { XMLParser , XMLBuilder } from 'fast-xml-parser' ;
2020import { resolveGrid3CellImage } from './gridset/resolver' ;
21+ import {
22+ extractAllButtonsForTranslation ,
23+ validateTranslationResults ,
24+ type ButtonForTranslation ,
25+ type LLMLTranslationResult ,
26+ } from '../utilities/translation/translationProcessor' ;
2127import { getZipEntriesWithPassword , resolveGridsetPassword } from './gridset/password' ;
2228import crypto from 'crypto' ;
2329import zlib from 'zlib' ;
@@ -28,7 +34,7 @@ import { detectPluginCellType, Grid3CellType } from './gridset/pluginTypes';
2834import { detectCommand } from './gridset/commands' ;
2935import { type SymbolReference , parseSymbolReference } from './gridset/symbols' ;
3036import { isSymbolLibraryReference } from './gridset/resolver' ;
31- import { generateCloneId } from '../optional /analytics/utils/idGenerator' ;
37+ import { generateCloneId } from '../utilities /analytics/utils/idGenerator' ;
3238import { translateWithSymbols , extractSymbolsFromButton } from './gridset/symbolAlignment' ;
3339
3440class GridsetProcessor extends BaseProcessor {
@@ -1245,122 +1251,56 @@ class GridsetProcessor extends BaseProcessor {
12451251 * Extract symbol information from a gridset for LLM-based translation.
12461252 * Returns a structured format showing which buttons have symbols and their context.
12471253 *
1254+ * This method uses shared translation utilities that work across all AAC formats.
1255+ *
12481256 * @param filePathOrBuffer - Path to gridset file or buffer
12491257 * @returns Array of symbol information for LLM processing
12501258 */
1251- extractSymbolsForLLM ( filePathOrBuffer : string | Buffer ) : Array < {
1252- buttonId : string ;
1253- pageId : string ;
1254- pageName : string ;
1255- label : string ;
1256- message : string ;
1257- textToTranslate : string ;
1258- symbols : Array < {
1259- text : string ;
1260- image ?: string ;
1261- symbolLibrary ?: string ;
1262- symbolPath ?: string ;
1263- } > ;
1264- } > {
1259+ extractSymbolsForLLM ( filePathOrBuffer : string | Buffer ) : ButtonForTranslation [ ] {
12651260 const tree = this . loadIntoTree ( filePathOrBuffer ) ;
1266- const symbolInfo : Array < {
1267- buttonId : string ;
1268- pageId : string ;
1269- pageName : string ;
1270- label : string ;
1271- message : string ;
1272- textToTranslate : string ;
1273- symbols : Array < {
1274- text : string ;
1275- image ?: string ;
1276- symbolLibrary ?: string ;
1277- symbolPath ?: string ;
1278- } > ;
1279- } > = [ ] ;
12801261
1262+ // Collect all buttons from all pages
1263+ const allButtons : any [ ] = [ ] ;
12811264 Object . values ( tree . pages ) . forEach ( ( page ) => {
12821265 page . buttons . forEach ( ( button ) => {
1283- // Extract symbols from various sources
1284- const symbols : Array < {
1285- text : string ;
1286- image ?: string ;
1287- symbolLibrary ?: string ;
1288- symbolPath ?: string ;
1289- } > = [ ] ;
1290-
1291- // Check richText.symbols
1292- if ( button . semanticAction ?. richText ?. symbols ) {
1293- symbols . push ( ...button . semanticAction . richText . symbols ) ;
1294- }
1295-
1296- // Check symbolLibrary + symbolPath
1297- if ( button . symbolLibrary && button . symbolPath ) {
1298- const text = button . label || button . message || '' ;
1299- if ( text ) {
1300- symbols . push ( {
1301- text,
1302- symbolLibrary : button . symbolLibrary ,
1303- symbolPath : button . symbolPath ,
1304- } ) ;
1305- }
1306- }
1307-
1308- // Check image field for symbol reference
1309- if ( button . image && button . image . startsWith ( '[' ) ) {
1310- const text = button . label || button . message || '' ;
1311- if ( text ) {
1312- symbols . push ( {
1313- text,
1314- image : button . image ,
1315- } ) ;
1316- }
1317- }
1318-
1319- // Only include buttons that have symbols
1320- if ( symbols . length > 0 ) {
1321- const textToTranslate = button . message || button . label || '' ;
1322- if ( textToTranslate ) {
1323- symbolInfo . push ( {
1324- buttonId : button . id ,
1325- pageId : page . id ,
1326- pageName : page . name || page . id ,
1327- label : button . label || '' ,
1328- message : button . message || '' ,
1329- textToTranslate,
1330- symbols,
1331- } ) ;
1332- }
1333- }
1266+ // Add page context to each button
1267+ ( button as any ) . pageId = page . id ;
1268+ ( button as any ) . pageName = page . name || page . id ;
1269+ allButtons . push ( button ) ;
13341270 } ) ;
13351271 } ) ;
13361272
1337- return symbolInfo ;
1273+ // Use shared utility to extract buttons with translation context
1274+ return extractAllButtonsForTranslation ( allButtons , ( button ) => ( {
1275+ pageId : button . pageId ,
1276+ pageName : button . pageName ,
1277+ } ) ) ;
13381278 }
13391279
13401280 /**
13411281 * Apply LLM translations with symbol information.
13421282 * The LLM should provide translations with symbol attachments in the correct positions.
13431283 *
1284+ * This method uses shared translation utilities that work across all AAC formats.
1285+ *
13441286 * @param filePathOrBuffer - Path to gridset file or buffer
13451287 * @param llmTranslations - Array of LLM translations with symbol info
13461288 * @param outputPath - Where to save the translated gridset
1289+ * @param options - Translation options (e.g., allowPartial for testing)
13471290 * @returns Buffer of the translated gridset
13481291 */
13491292 processLLMTranslations (
13501293 filePathOrBuffer : string | Buffer ,
1351- llmTranslations : Array < {
1352- buttonId : string ;
1353- translatedLabel ?: string ;
1354- translatedMessage ?: string ;
1355- symbols ?: Array < {
1356- text : string ;
1357- image ?: string ;
1358- } > ;
1359- } > ,
1360- outputPath : string
1294+ llmTranslations : LLMLTranslationResult [ ] ,
1295+ outputPath : string ,
1296+ options ?: { allowPartial ?: boolean }
13611297 ) : Buffer {
13621298 const tree = this . loadIntoTree ( filePathOrBuffer ) ;
13631299
1300+ // Validate translations using shared utility
1301+ const buttonIds = Object . values ( tree . pages ) . flatMap ( ( page ) => page . buttons . map ( ( b ) => b . id ) ) ;
1302+ validateTranslationResults ( llmTranslations , buttonIds , options ) ;
1303+
13641304 // Create a map for quick lookup
13651305 const translationMap = new Map ( llmTranslations . map ( ( t ) => [ t . buttonId , t ] ) ) ;
13661306
0 commit comments