0
# Stenography Engine
1
2
The StenoEngine class is the central coordination hub for all stenographic processing in Plover. It manages machine communication, dictionary operations, translation processing, and output generation through a comprehensive event-driven architecture.
3
4
## Capabilities
5
6
### Engine Initialization
7
8
Creates and configures the stenography engine with required dependencies.
9
10
```python { .api }
11
def __init__(self, config, controller=None, keyboard_emulation=None):
12
"""
13
Initialize the stenography engine.
14
15
Args:
16
config: Configuration object containing engine settings
17
controller: Optional controller interface for engine management
18
keyboard_emulation: Optional keyboard emulation interface for output
19
20
Creates engine instance with specified configuration and optional
21
controller and keyboard emulation interfaces.
22
"""
23
```
24
25
### Engine Lifecycle Management
26
27
Controls the stenography engine's operational state with support for starting, stopping, and restarting the processing pipeline.
28
29
```python { .api }
30
def start(self) -> None:
31
"""
32
Start the stenography engine and begin processing.
33
34
Initializes machine connection, loads configuration,
35
and begins stroke capture and translation processing.
36
"""
37
38
def quit(self, code: int = 0) -> None:
39
"""
40
Shutdown the stenography engine gracefully.
41
42
Args:
43
code: Exit code for application termination
44
45
Disconnects machine, saves configuration, and stops all processing.
46
"""
47
48
def restart(self) -> None:
49
"""
50
Restart the stenography engine.
51
52
Performs complete shutdown and restart cycle,
53
reloading configuration and reconnecting machine.
54
"""
55
56
def join(self) -> None:
57
"""
58
Wait for engine thread completion.
59
60
Blocks until engine processing thread terminates.
61
"""
62
```
63
64
### Output Control
65
66
Manages stenographic output generation with toggle and explicit control methods.
67
68
```python { .api }
69
def toggle_output(self) -> None:
70
"""
71
Toggle stenographic output on or off.
72
73
Switches between enabled and disabled output states,
74
affecting whether translations are sent to applications.
75
"""
76
77
def set_output(self, enabled: bool) -> None:
78
"""
79
Set stenographic output state explicitly.
80
81
Args:
82
enabled: True to enable output, False to disable
83
84
Controls whether stroke translations are converted to text output.
85
"""
86
87
@property
88
def output(self) -> bool:
89
"""
90
Get current output state.
91
92
Returns:
93
True if output is enabled, False otherwise
94
"""
95
96
@output.setter
97
def output(self, enabled: bool) -> None:
98
"""
99
Set output state via property assignment.
100
101
Args:
102
enabled: True to enable output, False to disable
103
"""
104
```
105
106
### Configuration Management
107
108
Provides access to engine configuration with support for runtime updates and persistence.
109
110
```python { .api }
111
@property
112
def config(self) -> dict:
113
"""
114
Get engine configuration as dictionary.
115
116
Returns:
117
Complete configuration dictionary with all settings
118
"""
119
120
@config.setter
121
def config(self, update: dict) -> None:
122
"""
123
Update engine configuration.
124
125
Args:
126
update: Dictionary of configuration changes to apply
127
128
Updates configuration and triggers necessary reloads.
129
"""
130
131
def __getitem__(self, setting: str):
132
"""
133
Get specific configuration value.
134
135
Args:
136
setting: Configuration key to retrieve
137
138
Returns:
139
Value of specified configuration setting
140
"""
141
142
def __setitem__(self, setting: str, value) -> None:
143
"""
144
Set specific configuration value.
145
146
Args:
147
setting: Configuration key to set
148
value: New value for the setting
149
150
Updates configuration and applies changes immediately.
151
"""
152
153
def load_config(self) -> None:
154
"""
155
Reload configuration from file.
156
157
Reads configuration from disk and applies all changes,
158
potentially triggering machine reconnection and dictionary reload.
159
"""
160
161
def reset_machine(self) -> None:
162
"""
163
Reset and reconnect stenotype machine.
164
165
Disconnects current machine and attempts reconnection
166
with current configuration settings.
167
"""
168
```
169
170
### Dictionary Operations
171
172
Comprehensive dictionary interaction supporting lookup, reverse lookup, and translation management.
173
174
```python { .api }
175
def lookup(self, strokes: tuple) -> str:
176
"""
177
Look up translation for stroke sequence.
178
179
Args:
180
strokes: Tuple of stroke strings to look up
181
182
Returns:
183
Translation string if found, None otherwise
184
185
Searches dictionaries in precedence order with filters applied.
186
"""
187
188
def raw_lookup(self, strokes: tuple) -> str:
189
"""
190
Look up translation without dictionary filters.
191
192
Args:
193
strokes: Tuple of stroke strings to look up
194
195
Returns:
196
Raw translation string if found, None otherwise
197
198
Bypasses all dictionary filters for direct lookup.
199
"""
200
201
def lookup_from_all(self, strokes: tuple) -> list:
202
"""
203
Look up translations from all dictionaries.
204
205
Args:
206
strokes: Tuple of stroke strings to look up
207
208
Returns:
209
List of (dictionary_path, translation) tuples
210
211
Returns matches from all dictionaries regardless of precedence.
212
"""
213
214
def raw_lookup_from_all(self, strokes: tuple) -> list:
215
"""
216
Raw lookup from all dictionaries without filters.
217
218
Args:
219
strokes: Tuple of stroke strings to look up
220
221
Returns:
222
List of (dictionary_path, translation) tuples
223
224
Bypasses filters and returns all matches across dictionaries.
225
"""
226
227
def reverse_lookup(self, translation: str) -> list:
228
"""
229
Find stroke sequences for translation.
230
231
Args:
232
translation: Translation text to reverse lookup
233
234
Returns:
235
List of stroke tuples that produce the translation
236
237
Searches all dictionaries for strokes matching translation.
238
"""
239
240
def casereverse_lookup(self, translation: str) -> list:
241
"""
242
Case-insensitive reverse lookup.
243
244
Args:
245
translation: Translation text to reverse lookup
246
247
Returns:
248
List of stroke tuples for case-insensitive matches
249
"""
250
251
def add_translation(self, strokes: tuple, translation: str, dictionary_path: str = None) -> None:
252
"""
253
Add new translation to dictionary.
254
255
Args:
256
strokes: Tuple of stroke strings
257
translation: Translation text to associate
258
dictionary_path: Specific dictionary path, uses first writable if None
259
260
Adds translation to specified or default writable dictionary.
261
"""
262
263
@property
264
def dictionaries(self) -> StenoDictionaryCollection:
265
"""
266
Get dictionary collection.
267
268
Returns:
269
StenoDictionaryCollection managing all loaded dictionaries
270
"""
271
272
def add_dictionary_filter(self, dictionary_filter) -> None:
273
"""
274
Add dictionary filter function.
275
276
Args:
277
dictionary_filter: Function to filter dictionary lookups
278
279
Filter functions receive (strokes, translation) and return bool.
280
"""
281
282
def remove_dictionary_filter(self, dictionary_filter) -> None:
283
"""
284
Remove dictionary filter function.
285
286
Args:
287
dictionary_filter: Filter function to remove
288
"""
289
```
290
291
### Translation State Management
292
293
Controls translator state for undo functionality and stroke sequencing.
294
295
```python { .api }
296
@property
297
def translator_state(self):
298
"""
299
Get current translator state.
300
301
Returns:
302
Internal translator state object for undo operations
303
"""
304
305
@translator_state.setter
306
def translator_state(self, state) -> None:
307
"""
308
Set translator state.
309
310
Args:
311
state: Translator state object to restore
312
313
Used for implementing undo functionality.
314
"""
315
316
def clear_translator_state(self, undo: bool = False) -> None:
317
"""
318
Clear translator state.
319
320
Args:
321
undo: Whether to trigger undo before clearing
322
323
Resets translation state, optionally undoing current translations.
324
"""
325
326
@property
327
def starting_stroke_state(self) -> StartingStrokeState:
328
"""
329
Get starting stroke state.
330
331
Returns:
332
StartingStrokeState named tuple with formatting preferences
333
"""
334
335
@starting_stroke_state.setter
336
def starting_stroke_state(self, state: StartingStrokeState) -> None:
337
"""
338
Set starting stroke state.
339
340
Args:
341
state: StartingStrokeState with attach, capitalize, space_char
342
"""
343
```
344
345
### Suggestions
346
347
Provides translation suggestions for improving stenographic efficiency.
348
349
```python { .api }
350
def get_suggestions(self, translation: str) -> list:
351
"""
352
Get stroke suggestions for translation.
353
354
Args:
355
translation: Translation text to get suggestions for
356
357
Returns:
358
List of Suggestion namedtuples with text and steno_list
359
360
Analyzes dictionaries to suggest efficient stroke patterns.
361
"""
362
```
363
364
### Machine State
365
366
Access to stenotype machine connection status and capabilities.
367
368
```python { .api }
369
@property
370
def machine_state(self) -> str:
371
"""
372
Get current machine state.
373
374
Returns:
375
Machine state string: 'stopped', 'initializing', 'connected', or 'disconnected'
376
"""
377
```
378
379
### Hook System
380
381
Event-driven architecture enabling extensions to respond to stenographic events.
382
383
```python { .api }
384
HOOKS = [
385
'stroked', 'translated', 'machine_state_changed',
386
'output_changed', 'config_changed', 'dictionaries_loaded',
387
'send_string', 'send_backspaces', 'send_key_combination',
388
'add_translation', 'focus', 'configure', 'lookup',
389
'suggestions', 'quit'
390
]
391
392
def hook_connect(self, hook: str, callback) -> None:
393
"""
394
Connect callback to engine event.
395
396
Args:
397
hook: Event name from HOOKS list
398
callback: Function to call when event occurs
399
400
Callback signature varies by hook type.
401
"""
402
403
def hook_disconnect(self, hook: str, callback) -> None:
404
"""
405
Disconnect callback from engine event.
406
407
Args:
408
hook: Event name from HOOKS list
409
callback: Function to disconnect
410
"""
411
```
412
413
**Usage Examples:**
414
415
```python
416
from plover.engine import StenoEngine
417
from plover.config import Config
418
419
# Create engine with configuration
420
config = Config()
421
engine = StenoEngine(config)
422
423
# Connect to stroke events
424
def on_stroke(stroke):
425
print(f"Stroke: {stroke}")
426
427
engine.hook_connect('stroked', on_stroke)
428
429
# Start processing
430
engine.start()
431
432
# Control output
433
engine.set_output(True)
434
engine.toggle_output()
435
436
# Work with dictionaries
437
translation = engine.lookup(('H', 'E', 'L', 'O'))
438
engine.add_translation(('K', 'U', 'S', 'T', 'O', 'M'), 'custom')
439
440
# Get suggestions
441
suggestions = engine.get_suggestions('hello')
442
443
# Shutdown
444
engine.quit()
445
```
446
447
## Hook Event Details
448
449
### Stroke Events
450
- `stroked`: Fired when stroke received from machine
451
- Callback signature: `callback(stroke: list[str])`
452
- `translated`: Fired when stroke translated to text
453
- Callback signature: `callback(old: list, new: list)`
454
455
### State Events
456
- `machine_state_changed`: Machine connection status changed
457
- Callback signature: `callback(machine_type: str, machine_state: str)`
458
- `output_changed`: Output enabled/disabled state changed
459
- Callback signature: `callback(enabled: bool)`
460
- `config_changed`: Configuration updated
461
- Callback signature: `callback(update: dict)`
462
- `dictionaries_loaded`: Dictionary collection reloaded
463
- Callback signature: `callback()`
464
465
### Output Events
466
- `send_string`: Text string sent to output
467
- Callback signature: `callback(text: str)`
468
- `send_backspaces`: Backspaces sent to output
469
- Callback signature: `callback(count: int)`
470
- `send_key_combination`: Key combination sent
471
- Callback signature: `callback(combo: str)`
472
473
### Interface Events
474
- `add_translation`: Translation added to dictionary
475
- Callback signature: `callback()`
476
- `focus`: Focus main window requested
477
- Callback signature: `callback()`
478
- `configure`: Configuration dialog requested
479
- Callback signature: `callback()`
480
- `lookup`: Lookup dialog requested
481
- Callback signature: `callback()`
482
- `suggestions`: Suggestions dialog requested
483
- Callback signature: `callback()`
484
- `quit`: Application quit requested
485
- Callback signature: `callback()`
486
487
## Threading and Engine Management
488
489
### Engine Threading
490
491
Core threading method that runs the engine's main event loop.
492
493
```python { .api }
494
def run(self) -> None:
495
"""
496
Main event loop for the engine thread.
497
498
Processes queued operations from other threads in a thread-safe manner.
499
This method runs continuously until the engine is shut down via quit().
500
501
Note: This method is typically called automatically when using start(),
502
but can be called directly for custom threading scenarios.
503
"""
504
```
505
506
### Context Manager Support
507
508
Thread-safe access to engine internals through context manager protocol.
509
510
```python { .api }
511
def __enter__(self) -> 'StenoEngine':
512
"""
513
Enter context manager for thread-safe engine access.
514
515
Returns:
516
Engine instance for use within context
517
518
Enables 'with engine:' syntax for thread-safe operations.
519
"""
520
521
def __exit__(self, exc_type, exc_value, traceback) -> None:
522
"""
523
Exit context manager and release thread lock.
524
525
Args:
526
exc_type: Exception type if raised within context
527
exc_value: Exception value if raised within context
528
traceback: Exception traceback if raised within context
529
"""
530
```
531
532
### Dictionary-Style Configuration Access
533
534
Convenient dictionary-style access to engine configuration settings.
535
536
```python { .api }
537
def __getitem__(self, setting: str) -> Any:
538
"""
539
Get configuration setting using dictionary syntax.
540
541
Args:
542
setting: Configuration key name
543
544
Returns:
545
Configuration value for the specified setting
546
547
Enables engine['setting_name'] syntax for configuration access.
548
"""
549
550
def __setitem__(self, setting: str, value: Any) -> None:
551
"""
552
Set configuration setting using dictionary syntax.
553
554
Args:
555
setting: Configuration key name
556
value: New value for the setting
557
558
Enables engine['setting_name'] = value syntax for configuration.
559
"""
560
```
561
562
### Available Hook Events
563
564
The engine supports these predefined hook event types:
565
566
```python { .api }
567
HOOKS = [
568
'stroked', # Stroke input received
569
'translated', # Translation completed
570
'machine_state_changed', # Machine connection state changed
571
'output_changed', # Output enabled/disabled state changed
572
'config_changed', # Configuration updated
573
'dictionaries_loaded', # Dictionary loading completed
574
'send_string', # String output requested
575
'send_backspaces', # Backspace output requested
576
'send_key_combination', # Key combination output requested
577
'add_translation', # Translation addition requested
578
'focus', # Application focus requested
579
'configure', # Configuration dialog requested
580
'lookup', # Lookup dialog requested
581
'suggestions', # Suggestions dialog requested
582
'quit' # Application quit requested
583
]
584
```
585
586
## Types
587
588
```python { .api }
589
from typing import List, Dict, Tuple, Optional, Callable, Any
590
from collections import namedtuple
591
592
StartingStrokeState = namedtuple('StartingStrokeState',
593
'attach capitalize space_char', defaults=(False, False, ' '))
594
595
MachineParams = namedtuple('MachineParams', 'type options keymap')
596
597
HookCallback = Callable[..., None]
598
StrokeList = List[str]
599
TranslationTuple = Tuple[str, ...]
600
ConfigDict = Dict[str, Any]
601
```