Open Source Stenography Software providing real-time stenographic typing, machine support, and plugin architecture.
npx @tessl/cli install tessl/pypi-plover@4.0.00
# Plover
1
2
Plover is a cross-platform stenography application that enables high-speed typing through machine shorthand. It provides real-time stenographic translation, supports multiple stenotype machines, offers customizable dictionaries, and includes a comprehensive plugin architecture for extensibility.
3
4
## Package Information
5
6
- **Package Name**: plover
7
- **Package Type**: pypi
8
- **Language**: Python
9
- **Installation**: `pip install plover`
10
11
## Core Imports
12
13
```python
14
# Core engine and configuration
15
from plover.engine import StenoEngine
16
from plover.config import Config
17
18
# Registry system for plugins
19
from plover.registry import registry
20
21
# Stenographic data models
22
from plover.steno import Stroke
23
from plover.translation import Translation, Translator
24
from plover.formatting import Formatter
25
26
# Dictionary system
27
from plover.steno_dictionary import StenoDictionary, StenoDictionaryCollection
28
29
# Exception classes
30
from plover.exception import InvalidConfigurationError, DictionaryLoaderException
31
```
32
33
## Basic Usage
34
35
```python
36
import plover
37
from plover.engine import StenoEngine
38
from plover.config import Config
39
from plover.oslayer.config import CONFIG_FILE
40
41
# Initialize configuration
42
config = Config(CONFIG_FILE)
43
44
# Create and start stenography engine
45
# Parameters: config, controller=None, keyboard_emulation=None
46
from plover.oslayer.keyboardcontrol import KeyboardEmulation
47
engine = StenoEngine(config, controller=None, keyboard_emulation=KeyboardEmulation())
48
engine.start()
49
50
# Connect to engine events
51
def on_stroke_received(stroke):
52
print(f"Stroke received: {stroke}")
53
54
engine.hook_connect('stroked', on_stroke_received)
55
56
# Control output
57
engine.set_output(True) # Enable stenographic output
58
engine.toggle_output() # Toggle output state
59
60
# Access dictionaries
61
dictionaries = engine.dictionaries
62
translation = dictionaries.lookup(('STENO',)) # Tuple of stroke strings
63
64
# Add custom translation
65
engine.add_translation(('KUFT/TOM',), 'custom') # Tuple of stroke strings to translation
66
67
# Shutdown
68
engine.quit()
69
```
70
71
## Architecture
72
73
Plover is built around several key components:
74
75
- **StenoEngine**: Central coordination hub managing all stenographic processing, machine communication, and output generation
76
- **Plugin Registry**: Extensible system supporting 10 plugin types including machines, dictionaries, GUI tools, and extensions
77
- **Dictionary System**: Hierarchical dictionary management with precedence rules, filtering, and multiple format support
78
- **Machine Interface**: Abstracted hardware interface supporting serial, USB, and keyboard input methods
79
- **Translation Pipeline**: Real-time stroke processing with formatting, orthography rules, and output generation
80
- **Hook System**: Event-driven architecture enabling extensions to respond to all stenographic events
81
- **Configuration Management**: Comprehensive settings system with file persistence and runtime updates
82
83
## Capabilities
84
85
### Stenography Engine
86
87
Core stenographic processing engine providing machine control, dictionary management, translation processing, and output generation with comprehensive event hooks.
88
89
```python { .api }
90
class StenoEngine:
91
def __init__(self, config, controller=None, keyboard_emulation=None): ...
92
def start(self) -> None: ...
93
def quit(self, code: int = 0) -> None: ...
94
def restart(self) -> None: ...
95
def toggle_output(self) -> None: ...
96
def set_output(self, enabled: bool) -> None: ...
97
@property
98
def output(self) -> bool: ...
99
@property
100
def config(self) -> dict: ...
101
def hook_connect(self, hook: str, callback) -> None: ...
102
def hook_disconnect(self, hook: str, callback) -> None: ...
103
```
104
105
[Stenography Engine](./engine.md)
106
107
### Plugin Registry System
108
109
Centralized plugin management system supporting dynamic registration and discovery of extensions, machines, dictionaries, GUI components, and other plugin types.
110
111
```python { .api }
112
class Registry:
113
PLUGIN_TYPES = (
114
'command', 'dictionary', 'extension', 'gui',
115
'gui.qt.machine_option', 'gui.qt.tool', 'machine',
116
'macro', 'meta', 'system'
117
)
118
119
def register_plugin(self, plugin_type: str, name: str, obj) -> None: ...
120
def get_plugin(self, plugin_type: str, plugin_name: str) -> Plugin: ...
121
def list_plugins(self, plugin_type: str) -> list: ...
122
def update(self) -> None: ...
123
124
registry: Registry
125
```
126
127
[Plugin Registry](./registry.md)
128
129
### Configuration System
130
131
Comprehensive configuration management with file persistence, validation, and runtime updates supporting all aspects of stenographic operation.
132
133
```python { .api }
134
class Config:
135
def __init__(self, path: str = None): ...
136
def load(self) -> None: ...
137
def save(self) -> None: ...
138
def __getitem__(self, key: str): ...
139
def __setitem__(self, key: str, value): ...
140
def update(self, **kwargs) -> None: ...
141
142
class DictionaryConfig:
143
def __new__(cls, path: str, enabled: bool = True): ...
144
@property
145
def short_path(self) -> str: ...
146
```
147
148
[Configuration](./configuration.md)
149
150
### Dictionary System
151
152
Powerful dictionary management system supporting multiple formats, hierarchical precedence, filtering, and real-time updates with comprehensive lookup capabilities.
153
154
```python { .api }
155
class StenoDictionary:
156
readonly: bool
157
158
@classmethod
159
def create(cls, resource: str) -> 'StenoDictionary': ...
160
@classmethod
161
def load(cls, resource: str) -> 'StenoDictionary': ...
162
def save(self) -> None: ...
163
def lookup(self, strokes: tuple) -> str: ...
164
def reverse_lookup(self, translation: str) -> list: ...
165
166
class StenoDictionaryCollection:
167
def lookup(self, strokes: tuple) -> str: ...
168
def set(self, strokes: tuple, translation: str, path: str = None) -> None: ...
169
def add_filter(self, filter_func) -> None: ...
170
```
171
172
[Dictionary System](./dictionaries.md)
173
174
### Machine Interface System
175
176
Abstracted machine interface supporting various stenotype hardware with unified API for stroke capture, state management, and device-specific configuration.
177
178
```python { .api }
179
class StenotypeBase:
180
KEYS_LAYOUT: str
181
ACTIONS: tuple
182
183
def start_capture(self) -> None: ...
184
def stop_capture(self) -> None: ...
185
def add_stroke_callback(self, callback) -> None: ...
186
def add_state_callback(self, callback) -> None: ...
187
def set_keymap(self, keymap: dict) -> None: ...
188
@classmethod
189
def get_option_info(cls) -> dict: ...
190
```
191
192
[Machine Interface](./machines.md)
193
194
### Stenographic Data Models
195
196
Core data structures for representing stenographic strokes, translations, and formatting with support for normalization, validation, and conversion between formats.
197
198
```python { .api }
199
class Stroke:
200
@classmethod
201
def from_steno(cls, steno: str) -> 'Stroke': ...
202
@classmethod
203
def from_keys(cls, keys: set) -> 'Stroke': ...
204
@property
205
def steno_keys(self) -> tuple: ...
206
@property
207
def rtfcre(self) -> str: ...
208
@property
209
def is_correction(self) -> bool: ...
210
211
def normalize_stroke(steno: str, strict: bool = True) -> str: ...
212
def normalize_steno(steno: str, strict: bool = True) -> str: ...
213
```
214
215
[Stenographic Data](./steno-data.md)
216
217
### Extension Framework
218
219
Comprehensive extension system enabling custom functionality through hooks, plugins, and direct engine API access with support for background processing and GUI integration.
220
221
```python { .api }
222
class Extension:
223
def __init__(self, engine: StenoEngine): ...
224
def start(self) -> None: ...
225
def stop(self) -> None: ...
226
```
227
228
[Extensions](./extensions.md)
229
230
## Types
231
232
```python { .api }
233
from typing import Dict, List, Tuple, Optional, Callable, Union
234
from collections import namedtuple
235
236
# Core data types
237
StartingStrokeState = namedtuple('StartingStrokeState',
238
'attach capitalize space_char', defaults=(False, False, ' '))
239
240
MachineParams = namedtuple('MachineParams', 'type options keymap')
241
242
Suggestion = namedtuple('Suggestion', 'text steno_list')
243
244
# Machine states
245
STATE_STOPPED: str
246
STATE_INITIALIZING: str
247
STATE_RUNNING: str
248
STATE_ERROR: str
249
250
# Hook types
251
HookCallback = Callable[..., None]
252
StrokeCallback = Callable[[List[str]], None]
253
StateCallback = Callable[[str], None]
254
255
# Configuration types
256
ConfigValue = Union[str, int, bool, List, Dict]
257
DictionaryPath = str
258
259
# Exception classes
260
class InvalidConfigurationError(Exception):
261
"""Raised when configuration contains errors or invalid values."""
262
pass
263
264
class DictionaryLoaderException(Exception):
265
"""Raised when dictionary file cannot be loaded or parsed."""
266
267
path: str # Path to failed dictionary file
268
exception: Exception # Underlying exception that caused failure
269
270
def __init__(self, path: str, exception: Exception): ...
271
```