### Example symbol library filenames Source: https://github.com/willwade/aacprocessors/blob/main/docs/touchchat.md List of example symbol library files. ```text AntiquatedLink.db Imagine.c4s Metacom.c4s MinSpeak.c4s PCS.c45 Pixon.c4s PRC.c4s Saltillo.c4s Sample.c4s SymbolStix.c4s Tawasol.c4s ``` -------------------------------- ### Full Grid XML Example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md A complete example of a Grid XML file showing the root element, background color, grid GUID, column and row definitions, auto content commands, a cell with a jump command, scan block audio descriptions, and a word list. Note the comment about the maximum of 8 scan block audio descriptions. ```xml #E2EDF8FF e631d2c5-cc2c-49b3-b6bb-eb1c81af84af Prediction Special Special [grid3x]star.wmf 1 2 3 4 5 6 7 8 Grids\Treats\wordlist-0-0.gridbmp ``` -------------------------------- ### Translation output: deep-translator install and Spanish translations Source: https://github.com/willwade/aacprocessors/blob/main/examples/demo_aacprocessors.ipynb Output from running the translation example. It shows deep-translator being installed and then translating each grid label to Spanish, followed by GridsetProcessor saving each grid XML and finally saving the translated gridset as translated_SimpleTest.gridset. ```text Collecting deep-translator Downloading deep_translator-1.11.4-py3-none-any.whl.metadata (30 kB) Requirement already satisfied: beautifulsoup4<5.0.0,>=4.9.1 in /usr/local/lib/python3.10/dist-packages (from deep-translator) (4.12.3) Requirement already satisfied: requests<3.0.0,>=2.23.0 in /usr/local/lib/python3.10/dist-packages (from deep-translator) (2.32.3) Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.10/dist-packages (from beautifulsoup4<5.0.0,>=4.9.1->deep-translator) (2.6) Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.23.0->deep-translator) (3.4.0) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.23.0->deep-translator) (3.10) Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.23.0->deep-translator) (2.2.3) Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.23.0->deep-translator) (2024.12.14) Downloading deep_translator-1.11.4-py3-none-any.whl (42 kB) [?25l [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m0.0/42.3 kB[0m [31m?[0m eta [36m-:--:--[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m42.3/42.3 kB[0m [31m2.5 MB/s[0m eta [36m0:00:00[0m [?25hInstalling collected packages: deep-translator Successfully installed deep-translator-1.11.4 Translated 'Mum' to 'Mamá' Translated 'orange squash' to 'Calabaza naranja' Translated 'J 2 O' to 'J 2 O' Translated 'Age' to 'Edad' Translated 'something different' to 'algo diferente' Translated 'Back to home page' to 'Volver a la página de inicio' Translated 'Comment' to 'Comentario' Translated 'I feel' to 'Siento' Translated 'Name' to 'Nombre' Translated 'happy.' to 'feliz.' Translated 'Milk shake' to 'Batido' Translated 'Family' to 'Familia' Translated 'don't like' to 'No me gusta' Translated 'I'm asking a question' to 'Estoy haciendo una pregunta' Translated 'blackcurrant squash' to 'calabaza grosella negra' Translated 'Younger Sister' to 'Hermana menor' Translated 'tired.' to 'cansado.' Translated 'About me' to 'Acerca de mí' Translated 'sad.' to 'triste.' Translated 'excited.' to 'entusiasmado.' Translated 'Home' to 'Hogar' Translated 'Back' to 'Atrás' Translated 'Dad' to 'Papá' Translated 'Birthday' to 'Cumpleaños' Translated 'Pets' to 'Mascotas' Translated 'Places I have been' to 'Lugares en los que he estado' Translated 'Aunts and Uncles' to 'Tías y tíos' Translated 'like to look' to 'Me gusta mirar' Translated 'Vegetable smoothie' to 'Batido de verduras' Translated 'My birthday' to 'Mi cumpleaños' Translated 'People at home' to 'Gente en casa' Translated 'Alphabet' to 'Alfabeto' Translated 'angry.' to 'enojado.' Translated 'something's wrong' to 'algo esta mal' Translated 'Places to go' to 'Lugares para ir' Translated 'quick chat' to 'Charla rápida' Translated 'like' to 'como' Translated 'Older Sister' to 'Hermana mayor' Translated 'I want' to 'Quiero' Translated 'fantastic.' to 'fantástico.' Translated 'Vegetarian' to 'Vegetariano' Translated 'Cousins' to 'Primos' Translated 'Water' to 'Agua' GridsetProcessor: Saved changes to /tmp/tmpc9sddipx/Grids/About me/grid.xml GridsetProcessor: Saved changes to /tmp/tmpc9sddipx/Grids/Drinks/grid.xml GridsetProcessor: Saved changes to /tmp/tmpc9sddipx/Grids/About me 2/grid.xml GridsetProcessor: Saved changes to /tmp/tmpc9sddipx/Grids/Start/grid.xml GridsetProcessor: Saved changes to /tmp/tmpc9sddipx/Grids/Family/grid.xml GridsetProcessor: Saved changes to /tmp/tmpc9sddipx/Grids/Feelings/grid.xml Translated gridset saved to: translated_SimpleTest.gridset ``` -------------------------------- ### Simple Command Example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md A command without parameters, using the ID attribute. This example shows a Jump.Back command. ```xml ``` -------------------------------- ### Install screenshot processor dependencies Source: https://github.com/willwade/aacprocessors/blob/main/README.md Install the optional screenshot processor dependencies for aac-processors. ```bash pip install aac-processors[screenshot] ``` -------------------------------- ### Command with Parameters Example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md A command with parameters, using the Parameter element with Key and value attributes. This example shows an Action.Speak command with unit and movecaret parameters. ```xml All 0 ``` -------------------------------- ### Run demo.py Source: https://github.com/willwade/aacprocessors/blob/main/README.md Run the demo script to see a complete example of using the library. The output shows the structure of the AAC board, including pages, grids, and buttons. ```bash python demo.py ``` -------------------------------- ### Install aac-processors with pip Source: https://github.com/willwade/aacprocessors/blob/main/examples/demo_aacprocessors.ipynb Installs the aac-processors package version 0.1.1. The output shows the package and its dependencies being resolved and installed. ```python !pip install aac-processors ``` ```text Collecting aac-processors==0.1.1 Downloading aac_processors-0.1.1-py3-none-any.whl.metadata (17 kB) Requirement already satisfied: beautifulsoup4>=4.12.2 in /usr/local/lib/python3.10/dist-packages (from aac-processors==0.1.1) (4.12.3) Requirement already satisfied: lxml>=4.9.3 in /usr/local/lib/python3.10/dist-packages (from aac-processors==0.1.1) (5.3.0) Requirement already satisfied: openpyxl>=3.1.2 in /usr/local/lib/python3.10/dist-packages (from aac-processors==0.1.1) (3.1.5) Requirement already satisfied: pandas>=2.1.1 in /usr/local/lib/python3.10/dist-packages (from aac-processors==0.1.1) (2.2.2) Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.10/dist-packages (from beautifulsoup4>=4.12.2->aac-processors==0.1.1) (2.6) Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.10/dist-packages (from openpyxl>=3.1.2->aac-processors==0.1.1) (2.0.0) Requirement already satisfied: numpy>=1.22.4 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.1->aac-processors==0.1.1) (1.26.4) Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.1->aac-processors==0.1.1) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.1->aac-processors==0.1.1) (2024.2) Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.1->aac-processors==0.1.1) (2024.2) Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.2->pandas>=2.1.1->aac-processors==0.1.1) (1.17.0) Downloading aac_processors-0.1.1-py3-none-any.whl (52 kB) [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m52.5/52.5 kB[0m [31m4.0 MB/s[0m eta [36m0:00:00[0m [?25hInstalling collected packages: aac-processors Successfully installed aac-processors-0.1.1 ``` -------------------------------- ### Jump.To Parameter Example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Example of a Parameter element for the Jump.To command, specifying a grid name. The value is the grid file name without extension, e.g., 'Quantity'. ```xml Quantity ``` -------------------------------- ### Buttons table example Source: https://github.com/willwade/aacprocessors/blob/main/docs/touchchat.md Example CSV representation of the Buttons table with symbol_link_id column. ```csv id resource_id label message symbol_link_id 1 3 building building 1 ``` -------------------------------- ### Settings0/settings.xml excerpt with StartGrid Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Example excerpt from Settings0/settings.xml showing the StartGrid element set to '01 CORE pg1', which identifies the home grid. ```xml 01 CORE pg1 ``` -------------------------------- ### Style definition example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Example of a Style element with Key 'Workspace' and various colour, font, and size properties. This is referenced in each page's grid.xml. ```xml ``` -------------------------------- ### Cells container example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Wrapper for all cell definitions in a grid. ```xml ``` -------------------------------- ### Caption property example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Sets the text displayed on a button. ```xml Hello ``` -------------------------------- ### StyleData example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Shows the structure of style.xml with a StyleData root element and a comment indicating style definitions. ```xml ``` -------------------------------- ### Extended style example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Shows how to extend a predefined style by adding properties like BackColour, TileColour, BorderColour, FontColour, FontName, and FontSize. ```xml ``` -------------------------------- ### Output of python demo.py Source: https://github.com/willwade/aacprocessors/blob/main/README.md Example output from running demo.py, showing the AAC board structure with pages, grids, and buttons. It includes the root page and nested target pages like About me, Family, and Feelings. ```bash === Viewing File Structure === Viewing structure of SimpleTest.gridset: === AAC Board Structure === Root Page: 📄 Start (4x4 grid) Row 0: [Empty] (0, 0) 🔀 quick chat (0, 1) └─ Says: quick chat └─ Goes to: quick chat 🔀 don't like (0, 2) └─ Says: don't like └─ Goes to: Don't like 🔀 something different (0, 3) └─ Says: something different └─ Goes to: something different Row 1: [Empty] (1, 0) 🔀 something's wrong (1, 1) └─ Says: something's wrong └─ Goes to: something's wrong 🔀 I want (1, 2) └─ Says: I want └─ Goes to: I want 🔀 Comment (1, 3) └─ Says: Comment └─ Goes to: Comment Row 2: [Empty] (2, 0) 🔀 About me (2, 1) └─ Says: About me └─ Goes to: About me └─ Target Page: 📄 About me (5x4 grid) Row 0: 🗣️ [No Label] (0, 0) 🗣️ Back (0, 1) └─ Says: Back 🔀 Family (0, 2) └─ Says: Family └─ Goes to: Family └─ Target Page: 📄 Family (5x7 grid) Row 0: [Empty] (0, 0) 🗣️ Back (0, 1) └─ Says: Back [Empty] (0, 2) 🗣️ Younger Sister (0, 3) └─ Says: Younger Sister [Empty] (0, 4) [Empty] (0, 5) [Empty] (0, 6) Row 1: [Empty] (1, 0) 🗣️ Dad (1, 1) └─ Says: Dad [Empty] (1, 2) [Empty] (1, 3) [Empty] (1, 4) [Empty] (1, 5) [Empty] (1, 6) Row 2: [Empty] (2, 0) [Empty] (2, 1) [Empty] (2, 2) 🔀 Cousins (2, 3) └─ Says: Cousins └─ Goes to: Cousins [Empty] (2, 4) [Empty] (2, 5) [Empty] (2, 6) Row 3: [Empty] (3, 0) 🗣️ Mum (3, 1) └─ Says: Mum [Empty] (3, 2) [Empty] (3, 3) [Empty] (3, 4) [Empty] (3, 5) [Empty] (3, 6) Row 4: [Empty] (4, 0) [Empty] (4, 1) [Empty] (4, 2) 🔀 Aunts and Uncles (4, 3) └─ Says: Aunts and Uncles └─ Goes to: Aunts and Uncles [Empty] (4, 4) [Empty] (4, 5) [Empty] (4, 6) 🗣️ Vegetarian (0, 3) └─ Says: Vegetarian Row 1: [Empty] (1, 0) 🗣️ Name (1, 1) └─ Says: Name 🔀 Pets (1, 2) └─ Says: Pets └─ Goes to: Pets [Empty] (1, 3) Row 2: [Empty] (2, 0) 🗣️ Age (2, 1) └─ Says: Age 🔀 Places I have been (2, 2) └─ Says: Places I have been └─ Goes to: Places I have been [Empty] (2, 3) Row 3: [Empty] (3, 0) 🗣️ My birthday (3, 1) └─ Says: My birthday 🗣️ like to look (3, 2) └─ Says: like to look [Empty] (3, 3) Row 4: [Empty] (4, 0) [Empty] (4, 1) [Empty] (4, 2) [Empty] (4, 3) 🔀 I'm asking a question (2, 2) └─ Says: I'm asking a question └─ Goes to: questions 🔀 I feel (2, 3) └─ Says: I feel └─ Goes to: Feelings └─ Target Page: 📄 Feelings (6x4 grid) Row 0: 🗣️ [No Label] (0, 0) 🗣️ Back (0, 1) └─ Says: Back 🗣️ angry. (0, 2) └─ Says: angry. [Empty] (0, 3) Row 1: [Empty] (1, 0) 🗣️ happy. (1, 1) └─ Says: happy. 🗣️ excited. (1, 2) └─ Says: excited. [Empty] (1, 3) Row 2: [Empty] (2, 0) 🗣️ sad. (2, 1) └─ Says: sad. 🗣️ fantastic. (2, 2) └─ Says: fantastic. [Empty] (2, 3) Row 3: [Empty] (3, 0) 🗣️ tired. (3, 1) ``` -------------------------------- ### Quick Start: Extract, Load, and Translate with GridsetProcessor Source: https://github.com/willwade/aacprocessors/blob/main/README.md Shows the basic usage of AACProcessors: extract texts, load into a tree, and translate texts using a dictionary. Requires a Grid 3 file path. ```python from aac_processors import GridsetProcessor, CoughDropProcessor, TouchChatProcessor, SnapProcessor # Example with Grid 3 processor = GridsetProcessor() texts = processor.extract_texts("path/to/your.gridset") print(f"Found {len(texts)} text items") # Load into tree structure tree = processor.load_into_tree("path/to/your.gridset") print(f"Found {len(tree.pages)} pages") # Translate texts translations = { "Hello": "Hola", "Goodbye": "Adiós" } translated_file = processor.process_texts("path/to/your.gridset", translations, "path/to/output.gridset") ``` -------------------------------- ### ColumnDefinitions example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Defines columns in the grid. Each ColumnDefinition element represents a column; repeat as needed. ```xml ``` -------------------------------- ### CaptionAndImage property example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Contains both a caption and an image. Image references a symbol-library filename and extension; the grid is licensed for Widgit symbols. ```xml Keyboard [grid3x]keyboard.wmf ``` -------------------------------- ### Root element example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Shows the basic structure of the root element in a Grid3 XML document, where child elements are placed. ```xml ``` -------------------------------- ### ScanBlockAudioDescriptions example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Provides audio descriptions for scan blocks. The maximum number of scan blocks is 8; each entry includes the ScanBlock number. ```xml 1 ``` -------------------------------- ### Run aac-processors in interactive mode Source: https://github.com/willwade/aacprocessors/blob/main/README.md Run the CLI without arguments to enter interactive mode, which guides you through selecting an AAC file (with tab completion), choosing to view or convert it, and if converting, selecting the target format and output path. ```bash aac-processors ``` -------------------------------- ### View Grid3 file structure with GridsetProcessor and viewer Source: https://github.com/willwade/aacprocessors/blob/main/examples/demo_aacprocessors.ipynb Loads a Grid3 file into a tree structure and prints it using the viewer. Requires the downloaded SimpleTest.gridset file. The output shows the board hierarchy with pages, rows, and cell actions. ```python import os from aac_processors import GridsetProcessor, viewer # Initialize processor processor = GridsetProcessor() gridset_file = "SimpleTest.gridset" if os.path.exists(gridset_file): print(f"Viewing structure of {os.path.basename(gridset_file)}") tree = processor.load_into_tree(gridset_file) viewer.print_tree(tree) ``` -------------------------------- ### symbol_links table example Source: https://github.com/willwade/aacprocessors/blob/main/docs/touchchat.md Example CSV representation of the symbol_links table mapping symbol_link_id to a symbol RID. ```csv id rid feature 1 {32BA0E22-7FE1F748-AA1C879C-BF24066D} 14 ``` -------------------------------- ### View File Structure via Command Line and Programmatically Source: https://github.com/willwade/aacprocessors/blob/main/README.md Shows three ways to view a board structure: using the standalone script, the package module, or programmatically with the viewer module. The viewer prints the tree and can auto-detect the file path. ```bash # Using the standalone viewer script python demo_viewer.py path/to/your/board.gridset # Or using the package module directly python -m aac_processors.viewer path/to/your/board.gridset # Programmatically: from aac_processors import viewer, GridsetProcessor # Load and print a board structure processor = GridsetProcessor() tree = processor.load_into_tree("path/to/your.gridset") viewer.print_tree(tree) # Or use the auto-detection feature viewer.main() # Will prompt for file path ``` -------------------------------- ### Licensing for boards and images Source: https://github.com/willwade/aacprocessors/blob/main/docs/obf_.obz Open Board File Formats.md Shows how to define licenses for a board and its images. If no license is defined, the importing app should assume the resource is private and all rights reserved. ```json { "format": "open-board-0.1", "id": "1", "url": "http://coughdropaac.com/boards/123", "name": "Example Board", "license": { "type": "CC-By-SA", "Copyright\_notice\_url": "https://creativecommons.org/licenses/by-sa/4.0", "source\_url": "http://coughdropaac.com/boards/123?optional", "author\_name": "Bob Jones", "author\_url": "http://about.me/bobjones", "author\_email": "email\_or\_link@dontneedboth.com" } "images": \[ { "id": "1", "url": "http://cdn.coughdropaac.com/happy.png", "width": 1024, "height": 768, "content\_type": "image/png", "license": { "type": "CC-By", "copyright\_notice\_url": "https://creativecommons.org/licenses/by/4.0", "source\_url": "http://coughdropaac.com/optional/url", "author\_name": "Sarah Miller", "author\_url": "http://facebook.com/bobjones", "author\_email": "email\_or\_link@dontneedboth.com" } } \] } ``` -------------------------------- ### RowDefinitions example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Defines rows in the grid. Each RowDefinition element represents a row; repeat as needed. ```xml ``` -------------------------------- ### Cell attribute example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Shows a Cell element with X, Y, and optional ScanBlock attributes. ScanBlock ranges from 1 to 8 and is optional. ```xml ``` -------------------------------- ### Cell with BasedOnStyle example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Shows a cell that references a predefined style from style.xml. The Style element is inside Content and uses BasedOnStyle. ```xml ``` -------------------------------- ### Basic .obf board JSON structure Source: https://github.com/willwade/aacprocessors/blob/main/docs/obf_.obz Open Board File Formats.md Defines a basic .obf board with a grid layout, two buttons, and an external image reference. The format attribute must be "open-board-0.1" and all IDs must be strings unique within the file. ```json { "format": "open-board-0.1", "id": "1", "locale": "en", "url": "http://www.myaacapp.com/boards/123", "name": "Example Board", "description_html": "This is just a simple example board I put together.", "buttons": [ { "id": "1", "image_id": "2", "label": "happy", "border_color": "rgb(0, 0, 55)", "background_color": "rgba(200, 255, 255, 0.2)" }, { "id": "2", "label": "drinks", "image_id": "2" }, ], "grid": { "rows": 1, "columns": 2, "order": [ ["1","2"] ] }, "images": [ { "id": "1", "url": "http://cdn.myaacapp.com/happy.png", "width": 1024, "height": 768, "content_type": "image/png" } ] } ``` -------------------------------- ### View File Structure Programmatically with viewer.print_tree Source: https://github.com/willwade/aacprocessors/blob/main/README.md Programmatic way to view a board structure using the viewer module. Imports ButtonType for potential type checking. The viewer prints the tree and can auto-detect the file path. ```python from aac_processors import viewer, GridsetProcessor from aac_processors.tree_structure import ButtonType # Load and print a board structure processor = GridsetProcessor() tree = processor.load_into_tree("path/to/your.gridset") viewer.print_tree(tree) # Or use the auto-detection feature viewer.main() # Will prompt for file path ``` -------------------------------- ### Upload OBZ to obfviewer and display rendered image Source: https://github.com/willwade/aacprocessors/blob/main/examples/demo_aacprocessors.ipynb Uploads a converted OBZ file to the obfviewer API using curl, then attempts to extract and display a rendered image. The output shows a failure case where the API returns an error because 'renderedImage' is missing, with details 'a.images is not iterable'. ```python import json import subprocess from IPython.display import Image, display if output_obz: print(f"Successfully converted to OBZ: {output_obz}") try: # Upload the file to obfviewer upload_command = [ "curl", "-X", "POST", "-H", "Content-Type: application/zip", "--data-binary", f"@{output_obz}", "https://obfviewer.acecentre.net/api/upload", ] result = subprocess.run(upload_command, capture_output=True, text=True) if result.returncode == 0: response_json = json.loads(result.stdout) if "renderedImage" in response_json: image_data = response_json["renderedImage"] image_data = image_data.split(",", 1)[1] # Remove data URL prefix with open("board.png", "wb") as f: f.write( bytes.fromhex(image_data.replace("\n", "")) ) # added for fix base64 decoding display(Image("board.png")) else: print("Error: 'renderedImage' not found in the response.") print("Response:", json.dumps(response_json, indent=2)) else: print("Error uploading file:") print(result.stderr) except Exception as e: print(f"An error occurred during the upload or image extraction process: {e}") else: print("Conversion failed") ``` ```text Output: Successfully converted to OBZ: translated_grid.obz Error: 'renderedImage' not found in the response. Response: { "error": "Failed to process OBZ file", "details": "a.images is not iterable" } ``` -------------------------------- ### SQL schema for Tobii Dynavox Snap .sps database Source: https://github.com/willwade/aacprocessors/blob/main/docs/TobiiDynavox-Snap-Details.md Complete SQLite schema for the .sps file, defining all tables (CommandSequence, ButtonPlacement, PageLayout, PageExtra, PageSetData, SyncData, Synchronization, Page, PageSetProperties, ButtonPageLink, Button) and their indexes. Use this to recreate or inspect the database structure. ```sql BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS "CommandSequence" ( "Id" integer NOT NULL, "SerializedCommands" varchar, "ButtonId" integer, PRIMARY KEY("Id" AUTOINCREMENT) ); CREATE TABLE IF NOT EXISTS "ButtonPlacement" ( "Id" integer NOT NULL, "GridPosition" varchar, "Visible" integer, "ButtonId" integer, "PageLayoutId" integer, PRIMARY KEY("Id" AUTOINCREMENT) ); CREATE TABLE IF NOT EXISTS "PageLayout" ( "Id" integer NOT NULL, "PageLayoutSetting" varchar, "PageId" integer, PRIMARY KEY("Id" AUTOINCREMENT) ); CREATE TABLE IF NOT EXISTS "PageExtra" ( "Id" integer, "AccessedAt" bigint, PRIMARY KEY("Id"), FOREIGN KEY("Id") REFERENCES "Page"("Id") ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS "PageSetData" ( "Id" integer NOT NULL, "Identifier" varchar, "Data" blob, "RefCount" integer DEFAULT 0, PRIMARY KEY("Id" AUTOINCREMENT) ); CREATE TABLE IF NOT EXISTS "SyncData" ( "UniqueId" varchar(36) NOT NULL, "Type" integer, "Timestamp" bigint, "SyncHash" integer, "Deleted" integer, "Description" VARCHAR, PRIMARY KEY("UniqueId") ); CREATE TABLE IF NOT EXISTS "Synchronization" ( "Id" integer NOT NULL, "SyncServerIdentifier" varchar, "PageSetTimestamp" bigint, "PageSetSyncHash" integer, PRIMARY KEY("Id" AUTOINCREMENT) ); CREATE TABLE IF NOT EXISTS "Page" ( "Id" integer NOT NULL, "UniqueId" varchar(36), "Title" varchar, "PageType" integer, "Language" varchar, "BackgroundColor" integer, "ContentTag" varchar, "Timestamp" bigint, "SyncHash" integer, "LibrarySymbolId" integer, "PageSetImageId" integer, "GridDimension" varchar, "MessageBarVisible" integer, PRIMARY KEY("Id" AUTOINCREMENT) ); CREATE TABLE IF NOT EXISTS "PageSetProperties" ( "Id" integer, "ContentIdentifier" VARCHAR, "ContentVersion" VARCHAR, "SchemaVersion" VARCHAR, "UniqueId" VARCHAR(36), "Language" VARCHAR, "Timestamp" BIGINT, "SyncHash" integer, "DefaultHomePageUniqueId" VARCHAR(36), "SerializedHomePageUniqueIdOverrides" BLOB, "DefaultKeyboardPageUniqueId" VARCHAR(36), "SerializedKeyboardPageUniqueIdOverrides" BLOB, "ToolBarUniqueId" VARCHAR(36), "DashboardUniqueId" VARCHAR(36), "MessageBarUniqueId" VARCHAR(36), "MessageBarVisible" integer, "ToolBarVisible" integer, "FriendlyName" VARCHAR, "Description" VARCHAR, "IconImageId" integer, "SerializedPreferredGridDimensions" VARCHAR, "GridDimension" VARCHAR, "SmartSymLayout" int, "FontFamily" VARCHAR, "FontSize" float, "FontStyle" int, "PageBackgroundColor" integer, "MessageBarBackgroundColor" integer, "ToolBarBackgroundColor" integer, "MessageWindowTextColor" integer, "MessageWindowFontSize" float, PRIMARY KEY("Id") ); CREATE TABLE IF NOT EXISTS "ButtonPageLink" ( "Id" INTEGER NOT NULL, "ButtonId" INTEGER NOT NULL, "PageUniqueId" varchar(36) NOT NULL, PRIMARY KEY("Id" AUTOINCREMENT), FOREIGN KEY("ButtonId") REFERENCES "Button"("Id") ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS "Button" ( "Id" INTEGER NOT NULL, "Language" varchar, "Label" varchar, "LabelOwnership" integer, "Message" varchar, "AudioCue" varchar, "ImageOwnership" integer, "LabelColor" integer, "BackgroundColor" integer, "BorderColor" integer, "BorderThickness" float, "FontSize" float, "FontFamily" varchar, "FontStyle" integer, "SmartSymLayout" integer, "CommandFlags" integer, "ContentType" integer, "ContentTag" varchar, "LibrarySymbolId" integer, "PageSetImageId" integer, "SerializedContentTypeHandler" varchar, "MessageRecordingId" integer, "AudioCueRecordingId" integer, "PageId" integer, "UseMessageRecording" integer, "UseAudioCueRecording" integer, "UniqueId" varchar(36), PRIMARY KEY("Id" AUTOINCREMENT) ); CREATE INDEX IF NOT EXISTS "CommandSequence_ButtonId" ON "CommandSequence" ( "ButtonId" ); CREATE INDEX IF NOT EXISTS "ButtonPlacement_PageLayoutId" ON "ButtonPlacement" ( "PageLayoutId" ); CREATE INDEX IF NOT EXISTS "PageLayout_PageId" ON "PageLayout" ( "PageId" ); CREATE INDEX IF NOT EXISTS "Button_AudioCueRecordingId" ON "Button" ( "AudioCueRecordingId" ); CREATE INDEX IF NOT EXISTS "Button_MessageRecordingId" ON "Button" ( "MessageRecordingId" ); CREATE INDEX IF NOT EXISTS "Button_PageId" ON "Button" ( "PageId" ); CREATE INDEX IF NOT EXISTS "Button_PageSetImageId" ON "Button" ( "PageSetImageId" ); CREATE UNIQUE INDEX IF NOT EXISTS "PageSetData_Identifier" ON "PageSetData" ( "Identifier" ); CREATE UNIQUE INDEX IF NOT EXISTS "Page_UniqueId" ON "Page" ( "UniqueId" ); CREATE INDEX IF NOT EXISTS "Page_PageSetImageId" ON "Page" ( "PageSetImageId" ); COMMIT; ``` -------------------------------- ### WordList cell example Source: https://github.com/willwade/aacprocessors/blob/main/docs/Grid3-XML-Format.md Defines a cell that uses AutoContent type and WordList subtype. Note: these cells should have ContentType = AutoContent and ContentSubType = WodList. ```xml AutoContent WordList ```