https://github.com/willwade/aacprocessors
A python library to read, import, export and modify pagesets from different AAC providers
https://github.com/willwade/aacprocessors
Last synced: 4 months ago
JSON representation
A python library to read, import, export and modify pagesets from different AAC providers
- Host: GitHub
- URL: https://github.com/willwade/aacprocessors
- Owner: willwade
- License: agpl-3.0
- Created: 2025-01-14T21:27:00.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-17T15:35:39.000Z (6 months ago)
- Last Synced: 2025-12-21T22:37:54.282Z (5 months ago)
- Language: Python
- Size: 21.7 MB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# AACProcessors
[](https://badge.fury.io/py/aac-processors)
[](https://pypi.org/project/aac-processors/)
[](https://github.com/willwade/AACProcessors/actions/workflows/test.yml)
[](https://codecov.io/gh/willwade/AACProcessors)
[](https://www.gnu.org/licenses/agpl-3.0)
A Python library to read, import, export and modify pagesets from different AAC (Augmentative and Alternative Communication) providers. NB: Node/JS version at https://github.com/willwade/AACProcessors-nodejs and probably more coverage now. Currently supports:
- Grid 3 (`.gridset`)
- CoughDrop (OpenBoard) (`.obf`, `.obz`)
- TouchChat (`.touchChat`)
- Snap Core First (`.spb`)
And unusual formats:
- Dot Processor (.dot)
- OPML (.opml)
- Apple Panels
- Screenshot Processor (optional)
## Features
- Extract text content from AAC pagesets
- Load AAC pagesets into a common tree structure
- Support for multiple AAC software formats
- Translation support for extracted text
- Consistent API across different AAC formats
- Convert between different AAC formats
- Analyze vocabulary usage and structure
## Installation
```bash
pip install aac-processors
```
## Quick Start
```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")
```
## Try it now!
Want to try AACProcessors without installing? Click below to run our interactive demo:
[](https://colab.research.google.com/github/willwade/AACProcessors/blob/main/examples/demo_aacprocessors.ipynb)
This interactive notebook will:
- Install AACProcessors
- Download example AAC files
- Demonstrate key features:
- Viewing file structures
- Extracting texts
- Analyzing vocabulary
- Converting between formats
## Usage Examples
### Converting Between Formats (OBZ Import/Export)
```python
from aac_processors import GridsetProcessor, CoughDropProcessor
# Convert Grid3 to CoughDrop OBZ
grid_processor = GridsetProcessor()
cough_processor = CoughDropProcessor()
# Load Grid3 file into common tree structure
tree = grid_processor.load_into_tree("path/to/your.gridset")
# Export tree to CoughDrop OBZ format
cough_processor.export_tree(tree, "output.obz")
# Import from OBZ
imported_tree = cough_processor.load_into_tree("path/to/board.obz")
```
### Viewing File Structure
The library includes two ways to view AAC board structures:
1. Using the command-line viewer:
```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
```
2. Programmatically:
```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
```
The viewer will show:
- Complete board structure with pages and buttons
- Button types (๐ฃ๏ธ Speech, ๐ Navigation, โก Action)
- Grid layout and button positions
- Navigation analysis (dead ends, orphaned pages)
- Circular references in navigation
### Vocabulary Analysis
```python
from aac_processors import GridsetProcessor
from collections import Counter
import re
def analyze_vocabulary(file_path):
processor = GridsetProcessor()
tree = processor.load_into_tree(file_path)
# Collect all text from buttons
words = []
for page in tree.pages.values():
for button in page.buttons:
if button.label:
# Split into words and clean
button_words = re.findall(r'\w+', button.label.lower())
words.extend(button_words)
if button.message:
message_words = re.findall(r'\w+', button.message.lower())
words.extend(message_words)
# Count word frequencies
word_counts = Counter(words)
# Print statistics
print(f"Total unique words: {len(word_counts)}")
print("\nMost common words:")
for word, count in word_counts.most_common(10):
print(f" {word}: {count}")
return word_counts
# Example usage
vocabulary = analyze_vocabulary("path/to/your.gridset")
```
## Demo
See `demo.py` for a complete example of how to use the library.
```bash
python demo.py
```
Output:
```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)
โโ Says: tired.
[Empty] (3, 2)
[Empty] (3, 3)
Row 4:
[Empty] (4, 0)
[Empty] (4, 1)
[Empty] (4, 2)
[Empty] (4, 3)
Row 5:
[Empty] (5, 0)
[Empty] (5, 1)
[Empty] (5, 2)
[Empty] (5, 3)
Row 3:
[Empty] (3, 0)
๐ like (3, 1)
โโ Says: like
โโ Goes to: Like
๐ Places to go (3, 2)
โโ Says: Places to go
โโ Goes to: let's go
๐ Alphabet (3, 3)
โโ Says: Alphabet
โโ Goes to: Alphabet
=== Navigation Analysis ===
Total Pages: 6
Dead End Pages (no way back):
- Family
- Feelings
Orphaned Pages (no way to reach):
- Drinks
- About me 2
=== Extracting Texts ===
Extracted 43 texts from SimpleTest.gridset
Sample texts: ["something's wrong", 'Age', 'Back to home page', 'I feel', 'Pets']
=== Loading Tree Structure ===
Loaded 6 pages from SimpleTest.gridset
Page Drinks: Drinks
Grid size: (5, 4)
Buttons: 7
Page Family: Family
Grid size: (5, 7)
Buttons: 8
```
## Supported Formats
### Grid 3 (`.gridset`)
- Full support for reading grid layouts
- Text extraction from buttons and pages
- Translation support
### CoughDrop (`.obf`, `.obz`)
- Support for both single board (`.obf`) and board set (`.obz`) formats
- Extraction of button labels and messages
- Translation capabilities
### TouchChat (`.touchChat`)
- Support for TouchChat page sets
- Button text extraction
- Page structure loading
### Snap Core First (`.spb`)
- Support for Snap Core First board sets
- Text extraction from buttons and pages
- Basic translation support
### Screenshot Processor (optional)
The screenshot processor is an optional dependency that requires additional dependencies. Install it with:
```bash
pip install aac-processors[screenshot]
```
#### screenshot Usage
```python
from aac_processors import ScreenshotProcessor
# Create processor
processor = ScreenshotProcessor()
# Load and print a board structure from screenshot
tree = processor.load_into_tree(
"path/to/screenshot.png",
grid_rows=6, # Optional: specify grid dimensions if known
grid_cols=4 # e.g. 6x4 for TouchChat24, 6x10 for TouchChat60
)
viewer.print_tree(tree)
# Extract text from screenshot
texts = processor.extract_texts("path/to/screenshot.png")
print(texts)
# Initialize processor with debug images enabled (optional)
processor = ScreenshotProcessor(save_debug_images=True)
# Get detailed page info including colors and grid layout
page = processor.create_page_from_screenshot(
"path/to/screenshot.png",
grid_rows=6, # Number of rows if known
grid_cols=4, # Number of columns if known
ignore_rows=1, # Skip top N rows (e.g. for menu bars)
)
print(f"Grid size: {page.grid_size}")
for btn in page.buttons:
print(f"Button at {btn.position}: {btn.label} (color: {btn.style.body_color})")
```
Debug Images: When `save_debug_images=True` is set, the processor creates two visualization files alongside the input image:
- `input.png.debug.png`: Shows the detected grid cells in green
- `input.png.text_debug.png`: Shows detected text regions in blue with text overlay
## Command Line Interface
The package provides a command-line interface (CLI) for viewing and converting AAC files. After installation, you can use it in two ways:
### Interactive Mode
Simply run without arguments to enter interactive mode:
```bash
aac-processors
```
This will guide you through:
1. Selecting an AAC file (with tab completion)
2. Choosing to view its structure or convert it
3. If converting, selecting the target format and output path
### Command Line Mode
For direct command-line usage:
1. View an AAC file structure:
```bash
aac-processors view input.gridset
```
2. Convert between formats:
```bash
# Basic conversion (auto-generates output filename)
aac-processors convert input.gridset --to coughdrop
# Specify custom output path
aac-processors convert input.obf --to grid --output custom_name.gridset
```
## API Documentation
### Base Classes
#### FileProcessor
The base class that all format-specific processors inherit from.
```python
class FileProcessor:
def extract_texts(self, file_path: str) -> List[str]:
"""Extract all text content from the file"""
def load_into_tree(self, file_path: str) -> AACTree:
"""Load the file into a common tree structure"""
def process_texts(
self,
file_path: str,
translations: Optional[Dict[str, str]] = None,
output_path: Optional[str] = None
) -> Union[List[str], str, None]:
"""Process and translate texts in the file.
Returns:
- List[str] if extracting texts (translations=None)
- str if translating (path to translated file)
- None if error occurs
"""
def set_source_file(self, file_path: str) -> None:
"""Set the source file path for processing"""
def cleanup_temp_files(self) -> None:
"""Clean up any temporary files created during processing"""
```
### Common Data Structures
#### AACTree
Represents the common structure for all AAC formats.
```python
class AACTree:
pages: Dict[str, AACPage] # Dictionary of pages by ID
root_id: Optional[str] # ID of the root page
def add_page(self, page: AACPage) -> None:
"""Add a page to the tree"""
def get_page(self, page_id: str) -> Optional[AACPage]:
"""Get a page by ID"""
```
#### AACPage
Represents a single page in an AAC system.
```python
class AACPage:
id: str # Unique identifier for the page
name: str # Display name of the page
grid_size: Tuple[int, int] # (rows, columns)
buttons: List[AACButton] # List of buttons on the page
```
#### AACButton
Represents a button in an AAC system.
```python
class AACButton:
id: str # Unique identifier for the button
label: str # Display text
type: ButtonType # SPEAK, NAVIGATE, ACTION, etc.
position: Tuple[int, int] # Grid position (row, col)
vocalization: Optional[str] # Text to speak
target_page_id: Optional[str] # For navigation buttons
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## Testing
To run the tests:
```bash
python -m pytest
```
Current test coverage: 52%
## Dev
```bash
uv pip install -e ".[dev,screenshot]"
```
## License
This project is licensed under the AGPLv3 License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
- OpenAAC
- The AAC community for their feedback and support
## Contributors
- [Will Wade](https://github.com/willwade)
- [OpenAAC](https://github.com/OpenAAC)