Dictionary Format: Difference between revisions

From Plover Wiki
mNo edit summary
(→‎Escaping Special Characters: reformat into definition list)
 
(19 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<markdown>
== About Strokes and Dictionaries ==
This page contains an explanation for the syntax used in Plover's dictionaries, as well as the operators that control capitalization, spacing, keyboard shortcuts, and other commands.


**Table of Contents**
- [About Strokes and Dictionaries](#about-strokes-and-dictionaries)
- [Plover's Default Dictionaries](#plovers-default-dictionaries)
  - [Dictionary priority](#dictionary-priority)
- [JSON and RTF/CRE](#json-and-rtfcre)
  - [Limitations](#limitations)
- [Plover Control Commands](#plover-control-commands)
- [Sending Symbols](#sending-symbols)
- [Prefix strokes](#prefix-strokes)
- [Text Formatting](#text-formatting)
  - [Prefixes, Infixes, and Suffixes](#prefixes-infixes-and-suffixes)
  - [Glue Operator (Numbers, Fingerspelling)](#glue-operator-numbers-fingerspelling)
  - [Capitalizing](#capitalizing)
    - [Capitalize Next Word](#capitalize-next-word)
    - [Capitalize Last Word](#capitalize-last-word)
  - [Uncapitalizing](#uncapitalizing)
    - [Uncapitalize Next Word](#uncapitalize-next-word)
    - [Uncapitalize Last Word](#uncapitalize-last-word)
  - [Carrying Capitalization](#carrying-capitalization)
  - [Uppercasing (CAPS)](#uppercasing-caps)
    - [Uppercase Next Word](#uppercase-next-word)
    - [Uppercase Last Word](#uppercase-last-word)
  - [Spacing](#spacing)
    - [Suppress Next Space](#suppress-next-space)
    - [Manually Add a Space](#manually-add-a-space)
  - [Canceling Formatting of Next Word](#canceling-formatting-of-next-word)
  - [Format Currency](#format-currency)
  - [Conditional](#conditional)
- [Friendly Command Names](#friendly-command-names)
- [Undoable Line Breaks and Tabs](#undoable-line-breaks-and-tabs)
- [Macros](#macros)
  - [Undo / Delete Last Stroke](#undo--delete-last-stroke)
  - [Repeat Last Stroke](#repeat-last-stroke)
  - [Toggle asterisk](#toggle-asterisk)
  - [Retroactively Add Space](#retroactively-add-space)
  - [Retroactively Delete Space](#retroactively-delete-space)
- [Keyboard Shortcuts](#keyboard-shortcuts)
  - [Modifier Names](#modifier-names)
  - [Shortcut Key Names](#shortcut-key-names)
  - [Example Shortcuts](#example-shortcuts)
  - [Escaping Special Characters](#escaping-special-characters)
  - ["Do Nothing" Translation](#do-nothing-translation)
- [Output Modes](#output-modes)
  - [Reset Command](#reset-command)
  - [Modes](#modes)
  - [Custom Modes](#custom-modes)
- [Summary of suggested commands you can cut and paste into your dictionary](#summary-of-suggested-commands-you-can-cut-and-paste-into-your-dictionary)
## About Strokes and Dictionaries
If you are new to stenography:
If you are new to stenography:


- A _stroke_ is a group of keyboard keys that are pressed simultaneously to produce output. As soon as all keys on the keyboard are released, the steno machine sends out that entire chord of key presses as a stroke.  
* A ''stroke'' is a group of keyboard keys that are pressed simultaneously to produce output. As soon as all keys on the keyboard are released, the steno machine sends out that entire chord of key presses as a stroke.  
- Plover converts that input into English words and phrases on the screen, by using _dictionaries_.
* Plover converts that input into English words and phrases on the screen, by using ''dictionaries''
- The dictionaries map a stroke (or a combination of strokes) to an English word or phrase, number, punctuation symbol, emoji, software command, or a meta command for controlling spacing and capitalization.
* with Plover, outputs are not limited to characters and punctuation symbols... Yes, a real stenographer chords emoji😅
- Every stenographer creates their own customized dictionary to supplement or amend the default dictionary that comes with a steno application, such as Plover. By default, you add your customizations to the `user.json` dictionary that comes with Plover.
* Steno machines makes use of either defined software command, or a meta command, for controlling spacing and capitalization.
* Every stenographer creates their own customized dictionary to supplement or amend the default dictionary that comes with a steno application, such as Plover. By default, you add your customizations to the <code>user.json</code> dictionary that comes with Plover.


## Plover's Default Dictionaries
== Plover's Default Dictionaries ==
Plover comes supplied with three dictionaries:


Plover comes supplied with three dictionaries:
* <code>main.json</code>. This contains the default dictionary. It is based on Mirabai Knight's own personal dictionary, which follows a StenEd-style theory. It contains over 140,000 entries and is adequate for anyone learning stenography. Mirabai uses this dictionary professionally for her realtime work.
* <code>commands.json</code>. This contains [[Dictionary Format#Plover Control Commands|Plover Control Commands]].
* <code>user.json</code>. This is available for your personal customizations. <code>user.json</code> is a blank dictionary. By default, the <code>user.json</code> dictionary is at the bottom of the dictionary list and has the highest priority - it is the first dictionary Plover will use. When you define new strokes, they will get added to this dictionary. This means you can see which strokes you've defined yourself, instead of trying to locate them inside the default dictionaries.


- `main.json`. This contains the default dictionary. It is based on Mirabai Knight's own personal dictionary, which follows a StenEd-style theory. It contains over 140,000 entries and is adequate for anyone learning stenography. Mirabai uses this dictionary professionally for her realtime work.
You can add extra dictionaries to Plover, as well. Dictionaries may be located on your system in any directory/folder; they do not have to be in a subdirectory/subfolder of the Plover installation.<blockquote>'''Note:''' We do not recommend you remove the <code>commands.json</code> dictionary from the dictionary list. This is because Plover has some concepts that users of other steno software will not be familiar with initially.</blockquote>
- `commands.json`. This contains [Plover Control Commands](#plover-control-commands).
- `user.json`. This is available for your personal customizations. `user.json` is a blank dictionary. By default, the `user.json` dictionary is at the bottom of the dictionary list and has the highest priority - it is the first dictionary Plover will use. When you define new strokes, they will get added to this dictionary. This means you can see which strokes you've defined yourself, instead of trying to locate them inside the default dictionaries.


You can add extra dictionaries to Plover, as well. Dictionaries may be located on your system in any directory/folder; they do not have to be in a subdirectory/subfolder of the Plover installation.
=== Dictionary priority ===
If two dictionaries contain the same steno strokes, Plover will use the one in the dictionary that has the highest priority. The dictionaries in the dictionary list are prioritised from the bottom up.


> **Note:** We do not recommend you remove the `commands.json` dictionary from the dictionary list. This is because Plover has some concepts that users of other steno software will not be familiar with initially.  
By default, the <code>user.json</code> dictionary is placed at the bottom of the dictionary list and has the highest priority. If you want new strokes to go to different dictionary (for example, you have your own dictionary already), make sure that dictionary is at the bottom of the list.{{Info|text=With Plover 4.0+, default dictionary priority is now top-down and can be changed.  In the configuration settings, you can select your preferred ordering of dictionary priority to be bottom-up or top-down.}}


### Dictionary priority
== Dictionary File Formats ==
Plover is (or will be) able to import dictionaries from other steno programs. Here are some technical notes on each file format.


If two dictionaries contain the same steno strokes, Plover will use the one in the dictionary that has the highest priority. The dictionaries in the dictionary list are prioritised from the bottom up.  
Some formats (including those not listed here) may require installation of a dedicated plugin.
{{Info|text=There is a plugin <code>plover-python-dictionary</code> available in the [[Plugins#Via the built-in Plugins Manager (recommended)|plugins manager]] that allows you to use Python (<code>.py</code>) dictionaries. After installing the plugin, you will need to restart Plover before it will let you load Python dictionaries.}}


By default, the `user.json` dictionary is placed at the bottom of the dictionary list and has the highest priority. If you want new strokes to go to different dictionary (for example, you have your own dictionary already), make sure that dictionary is at the bottom of the list.
=== Limitations ===
There are some limitations with each format:


> **Note:** With Plover 4.0+, default dictionary priority is now top-down and can be changed. In the configuration settings, you can select your preferred ordering of dictionary priority to be bottom-up or top-down.  
* RTF dictionaries will cause Plover to take longer to start up and won't have Unicode support.
* The JSON format that Plover uses is not used or supported by other steno applications. If you want to move or copy your Plover JSON formatted dictionary to another steno software application, you will need to convert it to RTF.
* The Plover JSON format doesn't have support for stroke metadata. At the moment, Plover doesn't support reading/writing of RTF metadata.


## JSON and RTF/CRE
=== json ===
The standard Plover format. Described at Dictionary format.


Plover supports two types of dictionaries:
=== rtf (aka CRE) ===
 
A standard interchange format. Described at http://www.legalxml.org/workgroups/substantive/transcripts/cre-spec.htm .
- **JSON** (the default and recommended format), and
- **RTF/CRE**.  


RTF/CRE is an import/export format used by proprietary steno software. This means Plover can work with exported dictionaries from Eclipse, ProCAT, Case CATalyst, and other steno software applications.
RTF/CRE is an import/export format used by proprietary steno software. This means Plover can work with exported dictionaries from Eclipse, ProCAT, Case CATalyst, and other steno software applications.
=== dct (aka Stentura, Jet, MDB, Microsoft Access) ===
These are standard Microsoft Access databases (otherwise known as Microsoft Jet databases, or MDB files. They contain a single table named &quot;Steno&quot;, which has columns named &quot;Steno&quot;, &quot;English&quot;, and &quot;Flags&quot;. Each row represents a translation.


> **Note:** With Plover 4.0+, there is a plugin `plover-python-dictionary` that allows you to use Python (`.py`) dictionaries. After installing the plugin, you will need to restart Plover before it will let you load Python dictionaries.
&quot;Steno&quot; is a text column containing the stroke, encoded as a concatenated sequence of six-digit hex strings representing bitmasks; each bit represents a key in the standard steno order


### Limitations
&quot;English&quot; is a text column giving the text translation of that stroke.


There are some limitations with each format:
&quot;Flags&quot; is an integer bitmap. 0x8000 indicates a suffix; 0x4000 indicates a prefix; 0x2000 indicates that the next word should be capitalised.


- RTF dictionaries will cause Plover to take longer to start up and won't have Unicode support.
Python lacks good cross-platform MDB support, so Plover reads the files using pure Python.
- The JSON format that Plover uses is not used or supported by other steno applications. If you want to move or copy your Plover JSON formatted dictionary to another steno software application, you will need to convert it to RTF.
- The Plover JSON format doesn't have support for stroke metadata. At the moment, Plover doesn't support reading/writing of RTF metadata.


## Plover Control Commands
=== sgdct (CaseCat) ===
CaseCATalyst dictionaries have the extension &quot;.sgdct&quot;. There is often a corresponding &quot;.sgxml&quot; file, but this contains no dictionary data.


You can control some aspects of Plover with [strokes](#strokes-and-dictionaries). Plover's default dictionary (`commands.json`) contains these commands:
Much of the detail of the file format remains unknown. Contributions and corrections are very welcome. Thanks are due to Sooty, who provided example files for dissection.


| Command name | Command | Default Stroke | Description |
The files begin with a 640-byte header, which begins with the magic number SGCAT32. Nothing is known about header fields at present.
|----------|----------| ----------| ----------|
| Add Translation | `{PLOVER:ADD_TRANSLATION}` | `TKUPT` (think DUPT for "Dictionary UPdaTe") | Opens a translation window where you can enter a stroke and translation text to create a new dictionary entry. |
| Disable Output | `{PLOVER:SUSPEND}` | `PHRO*F` (think PLOF for "PLover OFf") | Stop translating steno. With a keyboard machine, you will be able to type normally again. |
| Enable Output | `{PLOVER:RESUME}` | `PHRO*PB` (think PLON for "PLover ON") | Re-enable Plover's output. You can write this stroke to switch back from your keyboard into steno mode. |
| Toggle Output | `{PLOVER:TOGGLE}` | `PHROLG` (think PLOLG, for PLOver toGGLe) | Toggle between output being enabled and disabled. |


These commands are not in `commands.json` by default, but can be added to a dictionary:
One or more records follow the header. Each record gives a single translation from steno to text.


The record header is 21 bytes. header[18] contains the number of strokes, and header[19] gives the number of letters in the text. Each is an unsigned byte. The purpose of all other fields in the record header is unknown at present.


| Command name| Command | _Suggested_ Stroke | Description |
The stroke follows, as a sequence of four-byte unsigned integers. Each integer is a bitmap of keys in the standard steno order, with the first &quot;S&quot; as the most significant bit.
|----------|----------| ----------| ----------|
| Look Up Stroke | `{PLOVER:LOOKUP}` | `PHR*UP` | Open a search dialog that you write a translation into to get a list of entries in your dictionaries. |
| Suggestions | `{PLOVER:SUGGESTIONS}` | `PHROGS` (think PLOSHUN) for PLOver suggesTION) | Open and focus the plover suggestions window which will suggest alternative ways of writing |
| Configure | `{PLOVER:CONFIGURE}` | `PHROFG` (think PLOFG, for PLOver conFiG) | Open and focus the Plover configuration window. |
| Focus | `{PLOVER:FOCUS}` | `PHROFBGS` (think PLOFKS, for PLOver focus) | Open and focus the main Plover window. |
| Quit | `{PLOVER:QUIT}` | `PHROBGT` (think PLOKT, for PLOver **qu**i**t**) | Quit Plover entirely. |
| Set configuration | `{PLOVER:SET_CONFIG:option:value}`, `{PLOVER:SET_CONFIG:option1:value1,option2:value2,...}` | | Set Plover config option. |


Example for `SET_CONFIG` Plover command:
Then the text follows, as ordinary ASCII text. Nothing is currently known about coding of text outside the ASCII range. Various non-ASCII characters crop up, apparently as control codes.


* `{PLOVER:SET_CONFIG:'translation_frame_opacity':100}`
Finally, there are zero to three padding bytes, in order to bring us up to a four-byte boundary.
* `{PLOVER:SET_CONFIG:'start_attached':True,'start_capitalized':True}`


As a side effect, `SET_CONFIG` also reload the (changed) dictionaries.
== Plover Control Commands ==
You can control some aspects of Plover with [[Dictionary Format#About Strokes and Dictionaries|strokes]]. Plover's default dictionary (<code>commands.json</code>) contains these commands:
{| class="wikitable"
!Command name
!Command
!Default Stroke
!Description
|-
|Add Translation
|<code>{PLOVER:ADD_TRANSLATION}</code>
|<code>TKUPT</code> (think DUPT for "Dictionary UPdaTe")
|Opens a translation window where you can enter a stroke and translation text to create a new dictionary entry.
|-
|Disable Output
|<code>{PLOVER:SUSPEND}</code>
|<code>PHRO*F</code> (think PLOF for "PLover OFf")
|Stop translating steno. With a keyboard machine, you will be able to type normally again.
|-
|Enable Output
|<code>{PLOVER:RESUME}</code>
|<code>PHRO*PB</code> (think PLON for "PLover ON")
|Re-enable Plover's output. You can write this stroke to switch back from your keyboard into steno mode.
|-
|Toggle Output
|<code>{PLOVER:TOGGLE}</code>
|<code>PHROLG</code> (think PLOLG, for PLOver toGGLe)
|Toggle between output being enabled and disabled.
|}
These commands are not in <code>commands.json</code> by default, but can be added to a dictionary:
{| class="wikitable"
!Command name
!Command
!''Suggested'' Stroke
!Description
|-
|Look Up Stroke
|<code>{PLOVER:LOOKUP}</code>
|<code>PHR*UP</code>
|Open a search dialog that you write a translation into to get a list of entries in your dictionaries.
|-
|Suggestions
|<code>{PLOVER:SUGGESTIONS}</code>
|<code>PHROGS</code> (think PLOSHUN) for PLOver suggesTION)
|Open and focus the plover suggestions window which will suggest alternative ways of writing
|-
|Configure
|<code>{PLOVER:CONFIGURE}</code>
|<code>PHROFG</code> (think PLOFG, for PLOver conFiG)
|Open and focus the Plover configuration window.
|-
|Focus
|<code>{PLOVER:FOCUS}</code>
|<code>PHROFBGS</code> (think PLOFKS, for PLOver focus)
|Open and focus the main Plover window.
|-
|Quit
|<code>{PLOVER:QUIT}</code>
|<code>PHROBGT</code> (think PLOKT, for PLOver '''qu'''i'''t''')
|Quit Plover entirely.
|-
|Set configuration
|<code>{PLOVER:SET_CONFIG:option:value}</code>, <code>{PLOVER:SET_CONFIG:option1:value1,option2:value2,...}</code>
|
|Set Plover config option.
|}
Example for <code>SET_CONFIG</code> Plover command:


## Sending Symbols
* <code>{PLOVER:SET_CONFIG:'translation_frame_opacity':100}</code>
* <code>{PLOVER:SET_CONFIG:'start_attached':True,'start_capitalized':True}</code>


Since Plover 3.0.0, users can write full Unicode. You can use symbols in your JSON dictionary, or paste them into the "Add Translation" dialog (or into the dictionary manager). You can get symbols from a character insert panel in your operating system (if you have one), or you can copy and paste symbols from another application, such as a web browser.
As a side effect, <code>SET_CONFIG</code> also reload the (changed) dictionaries.


```json
== Sending Symbols ==
{
Since Plover 3.0.0, users can write full Unicode. You can use symbols in your JSON dictionary, or paste them into the "<kbd><samp>Add Translation</samp></kbd>" dialog (or into the dictionary manager). You can get symbols from a character insert panel in your operating system (if you have one), or you can copy and paste symbols from another application, such as a web browser.
  "SHR*UG": "¯\\_(ツ)_/¯",
<code>{
  "TR*PL": "{^}™",
  "SHR*UG": "¯\\_(ツ)_/¯",
  "TPHA*ES": "n̶o̶ yes"
  "TR*PL": "{^}™",
}
  "TPHA*ES": "n̶o̶ yes"
```
}</code>
 
## Prefix strokes


== Prefix strokes ==
It's possible to select the translation for a stroke depends on whether the previous word is finished.
It's possible to select the translation for a stroke depends on whether the previous word is finished.


Given the dictionary:
Given the dictionary:
<code>{
    "S": "word",
    "/S": "{prefix^}"
}</code>
with a stroke <code>S</code>, the translation <code>"/S": "{prefix^}"</code> is chosen; unless the previous word is not finished (for example if the previous translation is <code>{con^}</code>), then the translation <code>"S": "word"</code> is chosen.


```json
It's possible to explicitly mark a translation as "finished" with <code>{$}</code> (or equivalently <code>{:word_end}</code>).
{
"S": "word",
"/S": "{prefix^}"
}
```
 
with a stroke `S`, the translation `"/S": "{prefix^}"` is chosen; unless the previous word is not finished
(for example if the previous translation is `{con^}`), then the translation `"S": "word"` is chosen.
 
It's possible to explicitly mark a translation as "finished" with `{$}` (or equivalently `{:word_end}`).
 
See this [blackbox test](https://github.com/openstenoproject/plover/blob/df65bf1c6e2e6e7f958f635f0a3922b0b7b80c63/test/test_blackbox.py#L1597-L1604)
for an example.
 


## Text Formatting
[https://github.com/openstenoproject/plover/blob/df65bf1c6e2e6e7f958f635f0a3922b0b7b80c63/test/test_blackbox.py#L1597-L1604 See this blackbox test for an example.]


### Prefixes, Infixes, and Suffixes
== Text Formatting ==


=== Prefixes, Infixes, and Suffixes ===
Strokes can be attached at the beginning and/or end using the "attach" operator. You can also use some of the built-in orthographic rules that Plover uses for creating intelligent strokes.
Strokes can be attached at the beginning and/or end using the "attach" operator. You can also use some of the built-in orthographic rules that Plover uses for creating intelligent strokes.


- `{^}` is the attach operator.
* <code>{^}</code> is the attach operator.
- `{^ish}` is an orthographic-aware suffix that will add "ish" to the end of the previous word. E.g. `RED/EURB` will output `reddish`. Note: addition of a second "d" caused by Plover's understanding of English orthography.
* <code>{^ish}</code> is an orthographic-aware suffix that will add "ish" to the end of the previous word. E.g. <code>RED/EURB</code> will output <code>reddish</code>. Note: addition of a second "d" caused by Plover's understanding of English orthography.
- `{^}ish` is a suffix with the text outside the operator—this means that the text will simply be attached without grammar rules. Using this stroke in the previous example would give instead `redish`.
* <code>{^}ish</code> is a suffix with the text outside the operator—this means that the text will simply be attached without grammar rules. Using this stroke in the previous example would give instead <code>redish</code>.
- `{^-to-^}` is an infix, e.g. `day-to-day`.
* <code>{^-to-^}</code> is an infix, e.g. <code>day-to-day</code>.
- `{in^}` is a prefix, e.g. `influx`.
* <code>{in^}</code> is a prefix, e.g. <code>influx</code>.
- Most custom punctuation entries will take advantage of the attach operator, e.g. `{^—^}` for an emdash.
* Most custom punctuation entries will take advantage of the attach operator, e.g. <code>{^—^}</code> for an emdash.


### Glue Operator (Numbers, Fingerspelling)
=== Glue Operator (Numbers, Fingerspelling) ===
Glue is sort of like the [[Dictionary Format#Prefixes, Infixes, and Suffixes|attach operator]] above, except that "glued" strokes only attach to neighboring "glue" strokes.


Glue is sort of like the [attach operator](#prefixes-infixes-suffixes) above, except that "glued" strokes only attach to neighboring "glue" strokes.
Translations containing ''only'' digits are glued, allowing you to output multiple number strokes to make a large number.


Translations containing *only* digits are glued, allowing you to output multiple number strokes to make a large number.
* <code>{&}</code> is the glue operator.
 
* <code>{&a}</code>, <code>{&b}</code>, <code>{&c}</code>, etc. are how the fingerspelling alphabet is made.
- `{&}` is the glue operator.
* <code>{&th}</code> is a multiletter glue stroke, which can be useful (<code>TH*</code> in the default dictionary)
- `{&a}`, `{&b}`, `{&c}`, etc. are how the fingerspelling alphabet is made.
- `{&th}` is a multiletter glue stroke, which can be useful (`TH*` in the default dictionary)


Because glued translations only glue to other glued translations, they won't attach to regular words. This gives us some power because you can write:
Because glued translations only glue to other glued translations, they won't attach to regular words. This gives us some power because you can write:


`THR/-R/#H/#A/KATS` to get "there are 45 cats" and only `#H` (4) and `#A` (5) are "glued" to each other.
<code>THR/-R/#H/#A/KATS</code> to get "there are 45 cats" and only <code>#H</code> (4) and <code>#A</code> (5) are "glued" to each other.
 
### Capitalizing


=== Capitalizing ===
Capitalizing a word means turning the first letter into a capital, e.g. proper nouns and in titles. Usually your dictionary has capitals pre-defined, but there are times when you need to capitalize a word on the go.
Capitalizing a word means turning the first letter into a capital, e.g. proper nouns and in titles. Usually your dictionary has capitals pre-defined, but there are times when you need to capitalize a word on the go.


#### Capitalize Next Word
==== Capitalize Next Word ====


- `{-|}`
* <code>{-|}</code>


The next word will have a capitalized first letter. In the default dictionary, we have `"KPA": "{-|}"`, which will capitalize the next word; and `"KPA*": "{^}{-|}"` which omits a space and capitalizes the next word. That last stroke would let you writeLikeThis. This formatting style is called "camel case', which some programmers use in their work.  
The next word will have a capitalized first letter. In the default dictionary, we have <code>"KPA": "{-|}"</code>, which will capitalize the next word; and <code>"KPA*": "{^}{-|}"</code> which omits a space and capitalizes the next word. That last stroke would let you writeLikeThis. This formatting style is called "camel case', which some programmers use in their work.


Capitalize next word can also be used in name titles, like `Ms. {-|}`.
Capitalize next word can also be used in name titles, like <code>Ms. {-|}</code>.


**Default strokes:**
'''Default strokes:'''


- `KPA`: `{-|}` (think "cap")
* <code>KPA</code>: <code>{-|}</code> (think "cap")
- `KPA*`: `{^}{-|}` (also suppresses space)
* <code>KPA*</code>: <code>{^}{-|}</code> (also suppresses space)


#### Capitalize Last Word
==== Capitalize Last Word ====


- `{*-|}`
* <code>{*-|}</code>


The last stroke word will have a capitalized first letter. This is useful in case you realize that a word should be capitalized after you've written it. It can also be used in a stroke, like in `{*-|}{^ville}`. This would capitalize the last word and attach to it. This would be useful for town names on the fly, such as `Catville`.
The last stroke word will have a capitalized first letter. This is useful in case you realize that a word should be capitalized after you've written it. It can also be used in a stroke, like in <code>{*-|}{^ville}</code>. This would capitalize the last word and attach to it. This would be useful for town names on the fly, such as <code>Catville</code>.


**Suggested stroke:** `KA*PD`
'''Suggested stroke:''' <code>KA*PD</code>


### Uncapitalizing
=== Uncapitalizing ===


#### Uncapitalize Next Word
==== Uncapitalize Next Word ====


- `{>}`
* <code>{>}</code>


Forces the next letter to be lowercase, e.g. `{>}Plover` `plover`
Forces the next letter to be lowercase, e.g. <code>{>}Plover</code> <code>plover</code>


**Suggested stroke:** `HRO*ER` (lower)
'''Suggested stroke:''' <code>HRO*ER</code> (lower)


#### Uncapitalize Last Word
==== Uncapitalize Last Word ====


- `{*>}`
* <code>{*>}</code>


Rewrite the last word to start with a lowercase letter, e.g. `Plover{*>}` `plover`
Rewrite the last word to start with a lowercase letter, e.g. <code>Plover{*>}</code> <code>plover</code>


**Suggested stroke:** `HRO*ERD` (lowered)
'''Suggested stroke:''' <code>HRO*ERD</code> (lowered)


### Carrying Capitalization
=== Carrying Capitalization ===


- `{~|text}` or `{^~|text^}` where the attach operator is optional and the text can be changed.
* <code>{~|text}</code> or <code>{^~|text^}</code> where the attach operator is optional and the text can be changed.


In English, we have punctuation that doesn't get capitalized, but instead the next letter gets the capitalization. For example, if you end a sentence in quotes, the next sentence still starts with a capital letter! `"You can't eat that!" The baby ate on.`
In English, we have punctuation that doesn't get capitalized, but instead the next letter gets the capitalization. For example, if you end a sentence in quotes, the next sentence still starts with a capital letter! <code>"You can't eat that!" The baby ate on.</code>


In order to support this, there is a special pre/in/suffix syntax that will "pass on" or "carry" the capitalized state. You might find this useful with quotes, parentheses, and words like `'til` or `'cause`.  
In order to support this, there is a special pre/in/suffix syntax that will "pass on" or "carry" the capitalized state. You might find this useful with quotes, parentheses, and words like <code>'til</code> or <code>'cause</code>.


The default dictionary for Plover should use these operators where appropriate.
The default dictionary for Plover should use these operators where appropriate.
{
  "KW-GS": "{~|\"^}",
  "KR-GS": "{^~|\"}",
  "KA*US": "{~|'^}cause",
  "PREPB": "{~|(^}",
  "PR*EPB": "{^~|)}"
}
For a newline, the syntax would be <code>{^~|\n^}</code>.


```json
=== Uppercasing (CAPS) ===
{
See [[Dictionary Format#Output Modes|Output Modes]] for CAPS mode, which acts like CAPS lock on a regular keyboard. Alternatively, you can use a [[Dictionary Format#Keyboard Shortcuts|Keyboard Shortcut]] set to <code>{#Caps_Lock}</code> to activate the system CAPS lock like you can on your keyboard.
  "KW-GS": "{~|\"^}",
  "KR-GS": "{^~|\"}",
  "KA*US": "{~|'^}cause",
  "PREPB": "{~|(^}",
  "PR*EPB": "{^~|)}"
}
```
 
For a newline, the syntax would be `{^~|\n^}`.
 
### Uppercasing (CAPS)
 
See [Output Modes](#output-modes) for CAPS mode, which acts like CAPS lock on a regular keyboard. Alternatively, you can use a [Keyboard Shortcut](#keyboard-shortcuts) set to `{#Caps_Lock}` to activate the system CAPS lock like you can on your keyboard.
 
**Suggested stroke:** `"KA*PS": "{MODE:CAPS}"`
 
#### Uppercase Next Word


- `{<}`
'''Suggested stroke:''' <code>"KA*PS": "{MODE:CAPS}"</code>


Output next stroke in capital letters, e.g. `{<}cat` → `CAT`
==== Uppercase Next Word ====


**Suggested stroke:** `KPA*L` (cap all)
* <code>{<}</code>


#### Uppercase Last Word
Output next stroke in capital letters, e.g. <code>{<}cat</code> → <code>CAT</code>


- `{*<}`
'''Suggested stroke:''' <code>KPA*L</code> (cap all)


Rewrite last word in capital letters, e.g. `cat{*<}` → `CAT`
==== Uppercase Last Word ====


**Suggested stroke:** `*UPD`
* <code>{*<}</code>


Rewrite last word in capital letters, e.g. <code>cat{*<}</code> → <code>CAT</code>


### Spacing
'''Suggested stroke:''' <code>*UPD</code>


#### Suppress Next Space
=== Spacing ===


- `{^^}` (or `{^}`)
==== Suppress Next Space ====


See also: [Retroactively Delete Space](#retroactively-delete-space)
* <code>{^^}</code> (or <code>{^}</code>)


**Default stroke:** `TK-LS` (**D**e**l**ete **S**pace)
See also: [[Dictionary Format#Retroactively Delete Space|Retroactively Delete Space]]


This is a special case of an infix. See also [Prefixes, Infixes, and Suffixes](#prefixes-infixes-and-suffixes).
'''Default stroke:''' <code>TK-LS</code> ('''D'''e'''l'''ete '''S'''pace)


#### Manually Add a Space
This is a special case of an infix. See also [[Dictionary Format#Prefixes, Infixes, and Suffixes|Prefixes, Infixes, and Suffixes]].


- `{^ ^}`
==== Manually Add a Space ====


See also: [Retroactively Add Space](#retroactively-add-space)
* <code>{^ ^}</code>


**Default stroke:** `S-P` (**SP**ace)
See also: [[Dictionary Format#Retroactively Add Space|Retroactively Add Space]]


This is a special case of an infix. See also [Prefixes, Infixes, and Suffixes](#prefixes-infixes-and-suffixes).
'''Default stroke:''' <code>S-P</code> ('''SP'''ace)


### Canceling Formatting of Next Word
This is a special case of an infix. See also [[Dictionary Format#Prefixes, Infixes, and Suffixes|Prefixes, Infixes, and Suffixes]].


=== Canceling Formatting of Next Word ===
In order to cancel formatting of the next word, use the empty meta tag as your definition:
In order to cancel formatting of the next word, use the empty meta tag as your definition:


- `{}`
* <code>{}</code>


Using `{}` in front of a arrow key commands, as in `{}{#Left}`, is useful if the arrow key commands are used to move cursor to edit text. Canceling formatting actions for cursor movement prevents Plover from, for instance, capitalizing words in middle of a sentence if cursor is moved back when the last stroke, such as `{.}`, includes action to capitalize next word.
Using <code>{}</code> in front of a arrow key commands, as in <code>{}{#Left}</code>, is useful if the arrow key commands are used to move cursor to edit text. Canceling formatting actions for cursor movement prevents Plover from, for instance, capitalizing words in middle of a sentence if cursor is moved back when the last stroke, such as <code>{.}</code>, includes action to capitalize next word.


See also the ["do nothing" translation](#do-nothing-translation)
See also the [[Dictionary Format#"Do Nothing" Translation|"do nothing" translation]]


### Format Currency
=== Format Currency ===
There is a built-in meta in Plover that allows you to format the last-written number as currency. The format is <code>{*($c)}</code> where <code>$</code> is any currency symbol you'd like, and <code>c</code> is the amount, formatted in standard currency format, with either no decimals or two. Commas are added every 3 numbers before the decimal automatically.


There is a built-in meta in Plover that allows you to format the last-written number as currency. The format is `{*($c)}` where `$` is any currency symbol you'd like, and `c` is the amount, formatted in standard currency format, with either no decimals or two. Commas are added every 3 numbers before the decimal automatically.
* <code>{*($c)}</code>: Standard English dollars
 
** <code>23{*($c)}</code> → $23
- `{*($c)}`: Standard English dollars
** <code>2000.5{*($c)}</code> → $2,000.50
  + `23{*($c)}` → $23
* <code>{*($c CAD)}</code>: You can include other text, e.g. when specifying a currency's country
  + `2000.5{*($c)}` → $2,000.50
** <code>100{*($c CAD)}</code> → $100 CAD
- `{*($c CAD)}`: You can include other text, e.g. when specifying a currency's country
* <code>{*(c円)}</code>: The symbol can be placed on either side of the number, which often happens in languages other than English and in certain regions.
  - `100{*($c CAD)}` → $100 CAD
** <code>2345{*(c円)}</code>: 2,345円
- `{*(c円)}`: The symbol can be placed on either side of the number, which often happens in languages other than English and in certain regions.
  - `2345{*(c円)}`: 2,345円


Here are some other currency symbols, in case you need to copy-paste them into your entries: £, ¥, €, $, ₩, ¢
Here are some other currency symbols, in case you need to copy-paste them into your entries: £, ¥, €, $, ₩, ¢


### Conditional
=== Conditional ===


- `{=regex/text_if_match/text_if_no_match}`
* <code>{=regex/text_if_match/text_if_no_match}</code>


Conditional translation depending on the following text. Outputs `text_if_match` if the following text matches the regex, otherwise outputs `text_if_no_match`. Regex is case-sensitive. For example, `{=[AEIOUaeiou]/an/a}` outputs "a" unless the next word starts with a vowel, in which case it outputs "an".
Conditional translation depending on the following text. Outputs <code>text_if_match</code> if the following text matches the regex, otherwise outputs <code>text_if_no_match</code>. Regex is case-sensitive. For example, <code>{=[AEIOUaeiou]/an/a}</code> outputs "a" unless the next word starts with a vowel, in which case it outputs "an".
 
## Friendly Command Names


== Friendly Command Names ==
In a sufficiently-new Plover version, it's possible to use friendly names for some commands/metas.
In a sufficiently-new Plover version, it's possible to use friendly names for some commands/metas.


For detailed descriptions of the commands, see the other sections.
For detailed descriptions of the commands, see the other sections.
{| class="wikitable"
!Command/macro/meta
!Equivalent
|-
|<code>{*}</code>
|<code>=retrospective_toggle_asterisk</code>
|-
|<code>{*!}</code>
|<code>=retrospective_delete_space</code>
|-
|<code>{*?}</code>
|<code>=retrospective_insert_space</code>
|-
|<code>{*+}</code>
|<code>=repeat_last_stroke</code>
|-
|<code>{^}</code>
|<code>{:attach}</code>
|-
|<code>{^word}</code>
|<code>{:attach:^word}</code>
|-
|<code>{word^}</code>
|<code>{:attach:word^}</code>
|-
|<code>{^word^}</code>
|<code>{:attach:word}</code>
|-
|<code>{&a}</code>
|<code>{:glue:a}</code>
|-
|<code><nowiki>{-\|}</nowiki></code>
|<code>{:case:cap_first_word}</code>
|-
|<code><nowiki>{*-\|}</nowiki></code>
|<code>{:retro_case:cap_first_word}</code>
|-
|<code><nowiki>{~\|word}</nowiki></code>
|<code>{:carry_capitalize:word}</code>
|-
|<code>{<}</code>
|<code>{:case:upper_first_word}</code>
|-
|<code>{*<}</code>
|<code>{:retro_case:upper_first_word}</code>
|-
|<code>{>}</code>
|<code>{:case:lower_first_char}</code>
|-
|<code>{*>}</code>
|<code>{:retro_case:lower_first_char}</code>
|-
|<code>{*($c)}</code>
|<code>{:retro_currency:$c}</code>
|-
|<code>{#shift(a)}</code>
|<code>{:key_combo:shift(a)}</code>
|-
|<code>{PLOVER:LOOKUP}</code>
|<code>{:command:LOOKUP}</code>
|-
|<code>{MODE:CAPS}</code>
|<code>{:mode:CAPS}</code>
|-
|<code>{.}</code>
|<code>{:stop:.}</code>
|-
|<code>{,}</code>
|<code>{:comma:,}</code>
|-
|<code>{$}</code>
|<code>{:word_end}</code>
|}
Note that currently the <code>{#a}</code> form will be interpreted literally in the "Strokes" text box of the Plover "Add Translation" dialog box, however entering a stroke mapped to <code>{:key_combo:a}</code> will enter the raw stroke into the text box.


| Command/macro/meta | Equivalent |
== Undoable Line Breaks and Tabs ==
|------|------------|
When you use [[Dictionary Format#Keyboard Shortcuts|keyboard shortcuts]], the asterisk/undo command on Plover will not have any effect. This is a limitation imposed by the fact that most commands will not have a meaningful undo. For example, you wouldn't "undo" a "copy" command. For this reason, <code>{#return}</code> and <code>{#tab}</code> don't work how many users would expect.
| `{*}`  | `=retrospective_toggle_asterisk` |
| `{*!}` | `=retrospective_delete_space` |
| `{*?}` | `=retrospective_insert_space` |
| `{*+}` | `=repeat_last_stroke` |
| `{^}` | `{:attach}` |
| `{^word}` | `{:attach:^word}` |
| `{word^}` | `{:attach:word^}` |
| `{^word^}` | `{:attach:word}` |
| `{&a}` | `{:glue:a}` |
| `{-\|}` | `{:case:cap_first_word}` |
| `{*-\|}` | `{:retro_case:cap_first_word}` |
| `{~\|word}` | `{:carry_capitalize:word}` |
| `{<}` | `{:case:upper_first_word}` |
| `{*<}` | `{:retro_case:upper_first_word}` |
| `{>}` | `{:case:lower_first_char}` |
| `{*>}` | `{:retro_case:lower_first_char}` |
| `{*($c)}` | `{:retro_currency:$c}` |
| `{#shift(a)}` | `{:key_combo:shift(a)}` |
| `{PLOVER:LOOKUP}` | `{:command:LOOKUP}` |
| `{MODE:CAPS}` | `{:mode:CAPS}` |
| `{.}` | `{:stop:.}` |
| `{,}` | `{:comma:,}` |
| `{$}` | `{:word_end}` |
 
Note that currently the `{#a}` form will be interpreted literally in the "Strokes" text box of the Plover "Add Translation" dialog box, however entering a stroke mapped to `{:key_combo:a}` will enter the raw stroke into the text box.
 
## Undoable Line Breaks and Tabs
 
When you use [keyboard shortcuts](#keyboard-shortcuts), the asterisk/undo command on Plover will not have any effect. This is a limitation imposed by the fact that most commands will not have a meaningful undo. For example, you wouldn't "undo" a "copy" command. For this reason, `{#return}` and `{#tab}` don't work how many users would expect.


Instead, we must use special characters that can be undone by Plover for new paragraphs and erasable tabs. Specifically:  
Instead, we must use special characters that can be undone by Plover for new paragraphs and erasable tabs. Specifically:


- `\n` or `\r` for line breaks.  
* <code>\n</code> or <code>\r</code> for line breaks.
- `\t` for tabs.  
* <code>\t</code> for tabs.


For example:
For example:


- `{^\n^}{-|}`
* <code>{^\n^}{-|}</code>  This translation would create a line break without spacing and then capitalize the next word. It can be removed with the asterisk key.
 
* <code>{^\t^}</code>  This translation presses the tab key without any other spacing. It can be undone with the asterisk key.
    This translation would create a line break without spacing and then capitalize the next word. It can be removed with the asterisk key.
 
- `{^\t^}`
 
    This translation presses the tab key without any other spacing. It can be undone with the asterisk key.
 
## Macros


== Macros ==
Macros can be mapped from a stroke and perform operations on the stroke-level. This means that it can perform actions based on previous strokes, not necessarily on previous words or translations.
Macros can be mapped from a stroke and perform operations on the stroke-level. This means that it can perform actions based on previous strokes, not necessarily on previous words or translations.


### Undo / Delete Last Stroke
=== Undo / Delete Last Stroke ===


- `=undo`
* <code>=undo</code>


The built-in "undo" macro is assigned to the asterisk key `*`. You can map other strokes to "undo" or "delete last stroke" by creating a stroke where the translation is `=undo`
The built-in "undo" macro is assigned to the asterisk key <code>*</code>. You can map other strokes to "undo" or "delete last stroke" by creating a stroke where the translation is <code>=undo</code>


### Repeat Last Stroke
=== Repeat Last Stroke ===


- `{*+}`
* <code>{*+}</code>  A stroke mapping to this macro will send the last stroke entered. A common stroke to map to repeat-last is the bare number bar; <code>"#": "{*+}"</code>; causing <code>KAT/#/#</code> to behave like <code>KAT/KAT/KAT</code>.  Repeat last stroke <code>{*+}</code> is very useful for keys that you repeat. For example, when you are moving around text in a document.


    A stroke mapping to this macro will send the last stroke entered. A common stroke to map to repeat-last is the bare number bar; `"#": "{*+}"`; causing `KAT/#/#` to behave like `KAT/KAT/KAT`.
'''Suggested stroke:''' <code>#</code>


    Repeat last stroke `{*+}` is very useful for keys that you repeat. For example, when you are moving around text in a document.
=== Toggle asterisk ===


**Suggested stroke:** `#`
* <code>{*}</code>  A stroke mapping to this macro will toggle the asterisk key on the last stroke entered. For example, if you had this stroke in your dictionary as Number Bar + Asterisk, <code>"#*": "{*}"</code>, when you write <code>KAT/#*</code> it will behave as if you wrote <code>KA*T</code>.  Toggle asterisk <code>{*}</code> is useful for when you notice that you should have included an asterisk in your last stroke. For example, you wanted to write the name "Mark" (a person's name), but you wrote "mark" (the noun/verb). At this point, you can use Toggle asterisk <code>{*}</code> to correct it. You wouldn't have to erase the word and re-stroke it (this time, with you including the missing the asterisk).


### Toggle asterisk
'''Suggested stroke:''' <code>#*</code>


- `{*}`
=== Retroactively Add Space ===


    A stroke mapping to this macro will toggle the asterisk key on the last stroke entered. For example, if you had this stroke in your dictionary as Number Bar + Asterisk, `"#*": "{*}"`, when you write `KAT/#*` it will behave as if you wrote `KA*T`.  
* <code>{*?}</code>  A stroke mapping to this macro will add a space between your last stroke and the one before that, splitting apart the two strokes. For example, if your dictionary contained <code>PER</code> as "Perfect", <code>SWAEUGS</code> as "Situation" and <code>PER/SWAEUGS</code> as "Persuasion". If you meant to write "Perfect situation", but saw your output was "Persuasion", you could force these two strokes to be split apart by using the <code>{*?}</code> stroke. This means your output would change on the screen from "Persuasion" to "Perfect situation".


    Toggle asterisk `{*}` is useful for when you notice that you should have included an asterisk in your last stroke. For example, you wanted to write the name "Mark" (a person's name), but you wrote "mark" (the noun/verb). At this point, you can use Toggle asterisk `{*}` to correct it. You wouldn't have to erase the word and re-stroke it (this time, with you including the missing the asterisk).
'''Suggested stroke:''' <code>AFPS</code> (add space)


**Suggested stroke:** `#*`
=== Retroactively Delete Space ===


### Retroactively Add Space
* <code>{*!}</code>  A stroke mapping to this macro will delete the space between your last stroke and the one before that. If you wrote "Basket ball" but wanted it to be "Basketball", you could force these strokes together by using the {*!} stroke. Plover will go back and remove the space before your last stroke; As a result, your output would become "Basketball".


- `{*?}`
'''Suggested stroke:''' <code>TK-FPS</code> ('''d'''elete space)
 
    A stroke mapping to this macro will add a space between your last stroke and the one before that, splitting apart the two strokes. For example, if your dictionary contained `PER` as "Perfect", `SWAEUGS` as "Situation" and `PER/SWAEUGS` as "Persuasion". If you meant to write "Perfect situation", but saw your output was "Persuasion", you could force these two strokes to be split apart by using the `{*?}` stroke. This means your output would change on the screen from "Persuasion" to "Perfect situation".
 
**Suggested stroke:** `AFPS` (add space)
 
### Retroactively Delete Space
 
- `{*!}`
 
    A stroke mapping to this macro will delete the space between your last stroke and the one before that. If you wrote "Basket ball" but wanted it to be "Basketball", you could force these strokes together by using the {*!} stroke. Plover will go back and remove the space before your last stroke; As a result, your output would become "Basketball".
 
**Suggested stroke:** `TK-FPS` (**d**elete space)
 
## Keyboard Shortcuts


== Keyboard Shortcuts ==
Most Plover strokes are just text and formatting operators. Plover handles standard strokes really well. This allows it to handle "undoing" with the asterisk key, as well as automatically handling case and spacing. However, Plover's text and formatting strokes can't send arbitrary key strokes, such as sending keyboard shortcuts.
Most Plover strokes are just text and formatting operators. Plover handles standard strokes really well. This allows it to handle "undoing" with the asterisk key, as well as automatically handling case and spacing. However, Plover's text and formatting strokes can't send arbitrary key strokes, such as sending keyboard shortcuts.


**Note:** Plover 3.1 introduces new rules for commands that differ slightly from the previous implementation. Before Plover 3.1, commands were used to send symbols because Plover didn't have full Unicode support. *It used to be possible to send "+" by writing `{#plus}`, but the system has been updated.*
'''Note:''' Plover 3.1 introduces new rules for commands that differ slightly from the previous implementation. Before Plover 3.1, commands were used to send symbols because Plover didn't have full Unicode support. ''It used to be possible to send "+" by writing <code>{#plus}</code>, but the system has been updated.''


- `{#}` is the command operator.
* <code>{#}</code> is the command operator.


Inside of a command block, you write in what keys you want Plover to simulate. The keys hit in command blocks won't be "undone" when using the asterisk (because you can't backspace a keyboard shortcut). You select the keys by their name. All key names will only refer to the base key. For example, to use letter keys, you just use the corresponding letter (case insensitive) separated by spaces:
Inside of a command block, you write in what keys you want Plover to simulate. The keys hit in command blocks won't be "undone" when using the asterisk (because you can't backspace a keyboard shortcut). You select the keys by their name. All key names will only refer to the base key. For example, to use letter keys, you just use the corresponding letter (case insensitive) separated by spaces:


- `{#a b c d}` will send "abcd" and will not affect Plover's text formatting or asterisk undo-buffer.
* <code>{#a b c d}</code> will send "abcd" and will not affect Plover's text formatting or asterisk undo-buffer.


You can also use key names, which is needed when you are accessing a symbol key. For example, on the QWERTY layout there is an equal/plus key in the top right, which you can access by either of its names:
You can also use key names, which is needed when you are accessing a symbol key. For example, on the QWERTY layout there is an equal/plus key in the top right, which you can access by either of its names:


- `{#equal plus}` will send "==". Plover doesn't send modifiers. It just hits the key based on the name.  
* <code>{#equal plus}</code> will send "==". Plover doesn't send modifiers. It just hits the key based on the name.


If you want to send symbols, though, don't use commands. Commands should be used for keyboard shortcuts only. Instead, use the symbol in your dictionary entry.
If you want to send symbols, though, don't use commands. Commands should be used for keyboard shortcuts only. Instead, use the symbol in your dictionary entry.


### Modifier Names
=== Modifier Names ===
 
If you want to use a modifier, use it by name (e.g. <code>Shift_L</code>). For convenience, all key names are case insensitive and you can optionally default to the left modifier by dropping the side selector:
If you want to use a modifier, use it by name (e.g. `Shift_L`). For convenience, all key names are case insensitive and you can optionally default to the left modifier by dropping the side selector:
{| class="wikitable"
 
!Modifier
| Modifier | Command Key Names (case-insensitive) |
!Command Key Names (case-insensitive)
|----------|----------|
|-
| Shift | `Shift_L`, `Shift_R`, `shift` |  
|Shift
| Control | `Control_L`, `Control_R`, `control` |  
|<code>Shift_L</code>, <code>Shift_R</code>, <code>shift</code>
| Alt | `Alt_L`, `Alt_R`, `alt`, `option` |  
|-
| Super | `Super_L`, `Super_R`, `super`, `windows`, `command` |  
|Control
 
|<code>Control_L</code>, <code>Control_R</code>, <code>control</code>
|-
|Alt
|<code>Alt_L</code>, <code>Alt_R</code>, <code>alt</code>, <code>option</code>
|-
|Super
|<code>Super_L</code>, <code>Super_R</code>, <code>super</code>, <code>windows</code>, <code>command</code>
|}
For modifiers, use parentheses to delimit where the keys are pressed down.
For modifiers, use parentheses to delimit where the keys are pressed down.


### Shortcut Key Names
=== Shortcut Key Names ===
 
Here are the key names you'll want to use:
Here are the key names you'll want to use:
{| class="wikitable"
!Keys
!Command Key Names (case-insensitive)
|-
|Letters
|<code>a</code>, <code>b</code>, <code>c</code>, <code>d</code>, <code>e</code>, <code>f</code>, <code>g</code>, <code>h</code>, <code>i</code>, <code>j</code>, <code>k</code>, <code>l</code>, <code>m</code>, <code>n</code>, <code>o</code>, <code>p</code>, <code>q</code>, <code>r</code>, <code>s</code>, <code>t</code>, <code>u</code>, <code>v</code>, <code>w</code>, <code>x</code>, <code>y</code>, <code>z</code>
|-
|Accented Letters (international layouts)
|<code>udiaeresis</code>, <code>eacute</code>, etc.
|-
|Numbers
|<code>0</code>, <code>1</code>, <code>2</code>, <code>3</code>, <code>4</code>, <code>5</code>, <code>6</code>, <code>7</code>, <code>8</code>, <code>9</code>
|-
|Control Keys
|<code>Escape</code>, <code>Tab</code>, <code>Caps_Lock</code>, <code>space</code>, <code>BackSpace</code>, <code>Delete</code>, <code>Return</code>, etc.
|-
|F-Keys
|<code>F1</code>, <code>F2</code>, <code>F3</code>, <code>F4</code>, <code>F5</code>, <code>F6</code>, <code>F7</code>, <code>F8</code>, <code>F9</code>, <code>F10</code>, <code>F11</code>, <code>F12</code>
|-
|Common Named Keys
|<code>= equal</code><code>- minus</code><code>[ bracketleft</code><code>] bracketright</code><code>/ slash</code><code>\ backslash</code><code>' quoteright</code><code>, comma</code><code>. period</code><code>; semicolon</code><code>~ asciitilde</code><code>^ asciicircum</code><code>` quoteleft</code>[https://github.com/openstenoproject/plover/blob/master/plover/key_combo.py#L21 …and more]
|-
|Media Keys
|'''Common''': <code>AudioRaiseVolume</code>, <code>AudioLowerVolume</code>, <code>AudioMute</code>, <code>AudioNext</code>, <code>AudioPrev</code>, <code>AudioStop</code>, <code>AudioPlay</code>, <code>AudioPause</code>, <code>Eject</code>'''Mac''': <code>MonBrightnessUp</code>, <code>MonBrightnessDown</code>, <code>KbdBrightnessUp</code>, <code>KbdBrightnessDown</code>
'''Windows''': <code>Back</code>, <code>Forward</code>, <code>Refresh</code>'''Linux''': XF86 key names are supported, for example <code>XF86_MonBrightnessUp</code> - refer to the [https://github.com/python-xlib/python-xlib/blob/master/Xlib/keysymdef/xf86.py definition file in <code>python-xlib</code>] for the key names.
|}
Consult the code for the [https://github.com/openstenoproject/plover/blob/master/plover/key_combo.py#L21 full list of supported keyboard shortcut keys].


| Keys | Command Key Names (case-insensitive) |
'''Note:''' a key name will determine a key to emulate with '''no modifiers''' based on your keyboard layout. For example, let's say we want to make a keyboard shortcut to hit shift-2 which is "@" in QWERTY: <code>{#at}</code> will only press the <code>2</code> key. To get the <code>@</code> symbol, we need to add the shift key: <code>{#shift(at)}</code>, which is functionally the same as <code>{#shift(2)}</code>.
|----------|----------|
| Letters | `a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`, `j`, `k`, `l`, `m`, `n`, `o`, `p`, `q`, `r`, `s`, `t`, `u`, `v`, `w`, `x`, `y`, `z` |
| Accented Letters (international layouts) | `udiaeresis`, `eacute`, etc.  |
| Numbers | `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9` |
| Control Keys |  `Escape`, `Tab`, `Caps_Lock`, `space`, `BackSpace`, `Delete`, `Return`, etc. |
| F-Keys | `F1`, `F2`, `F3`, `F4`, `F5`, `F6`, `F7`, `F8`, `F9`, `F10`, `F11`, `F12` |
| Common Named Keys | `= equal`<br />`- minus`<br />`[ bracketleft`<br />`] bracketright`<br />`/ slash`<br />`\ backslash`<br />`' quoteright`<br />`, comma`<br />`. period`<br />`; semicolon`<br />`~ asciitilde`<br />`^ asciicircum`<br />`` ` quoteleft``<br />[…and more](https://github.com/openstenoproject/plover/blob/master/plover/key_combo.py#L21) |
| Media Keys | **Common**: `AudioRaiseVolume`, `AudioLowerVolume`, `AudioMute`, `AudioNext`, `AudioPrev`, `AudioStop`, `AudioPlay`, `AudioPause`, `Eject`<br />**Mac**: `MonBrightnessUp`, `MonBrightnessDown`, `KbdBrightnessUp`, `KbdBrightnessDown`<br />**Windows**: `Back`, `Forward`, `Refresh`<br />**Linux**: XF86 key names are supported, for example `XF86_MonBrightnessUp` - refer to [the definition file in `python-xlib`](https://github.com/python-xlib/python-xlib/blob/master/Xlib/keysymdef/xf86.py) for the key names. |
 
Consult the code for the [full list of supported keyboard shortcut keys](https://github.com/openstenoproject/plover/blob/master/plover/key_combo.py#L21).
 
**Note:** a key name will determine a key to emulate with **no modifiers** based on your keyboard layout. For example, let's say we want to make a keyboard shortcut to hit shift-2 which is "@" in QWERTY: `{#at}` will only press the `2` key. To get the `@` symbol, we need to add the shift key: `{#shift(at)}`, which is functionally the same as `{#shift(2)}`.
 
### Example Shortcuts


=== Example Shortcuts ===
Here are some shortcuts. They are in JSON format:
Here are some shortcuts. They are in JSON format:


- `"STPH-G": "{#right}"` — right arrow on the keyboard, for moving the cursor to the right once
* <code>"STPH-G": "{#right}"</code> — right arrow on the keyboard, for moving the cursor to the right once
- `"SKWR-G": "{#shift(right)}"` — shift and right arrow on the keyboard, for selecting one character
* <code>"SKWR-G": "{#shift(right)}"</code> — shift and right arrow on the keyboard, for selecting one character
- `"SKWR-BG": "{#control(shift(right))}"` — shift, control, and right arrow on the keyboard, for selecting one word to the right on Windows/Linux
* <code>"SKWR-BG": "{#control(shift(right))}"</code> — shift, control, and right arrow on the keyboard, for selecting one word to the right on Windows/Linux
- `"SKWR-BG": "{#option(shift(right))}"` — option (alt), control, and right arrow on the keyboard, for selecting one word to the right on Mac
* <code>"SKWR-BG": "{#option(shift(right))}"</code> — option (alt), control, and right arrow on the keyboard, for selecting one word to the right on Mac


These next strokes are not particularly useful, but they show you what you can do with the command syntax:
These next strokes are not particularly useful, but they show you what you can do with the command syntax:


- `"TKAO*UP": "{#control(c v v v)}"` — copy, then paste 3 times
* <code>"TKAO*UP": "{#control(c v v v)}"</code> — copy, then paste 3 times
- `"SKPH-Z": "{#control(z shift(z))"` — program-dependent, but possibly "undo/redo". Notice how the first z has only the control operator, and the second has both the control and the shift operator.
* <code>"SKPH-Z": "{#control(z shift(z))"</code> — program-dependent, but possibly "undo/redo". Notice how the first z has only the control operator, and the second has both the control and the shift operator.


Commands are case insensitive - adding capitals will not affect the output. `{#control(z shift(z))` is the same as `"{#CONTROL_L(Z SHIFT(Z))}"`
Commands are case insensitive - adding capitals will not affect the output. <code>{#control(z shift(z))</code> is the same as <code>"{#CONTROL_L(Z SHIFT(Z))}"</code>


### Escaping Special Characters
=== Escaping Special Characters ===
Most symbols (e.g. <code>+, =, ~, r</code>) can just be included directly in the definition. But some symbols are part of the dictionary syntax and so need to be escaped:
{| class="wikitable"
!Symbol
!Escaped Form
|-
|<code>\</code>
|<code>\\</code>
|-
|<code>{</code>
|<code>\{</code>
|-
|<code>}</code>
|<code>\}</code>
|}
<code>\</code> is a special case. It must be escaped only if there's any possible ambiguity.


Most symbols (e.g. `+, =, ~, r`) can just be included directly in the definition. But some symbols are part of the dictionary syntax and so need to be escaped:
Special case: <code>=content</code> might be interpreted as the invocation of a macro named <code>content</code>. Use <code>{#}=content</code> instead.
 
| Symbol | Escaped Form |
|----------|----------|
| `\` | `\\`  |
| `{` | `\{`  |
| `}` | `\}`  |
 
`\` is a special case. It must be escaped only if there's any possible ambiguity.
 
Special case: `=content` might be interpreted as the invocation of a macro named `content`.
Use `{#}=content` instead.
 
If you edit the JSON file directly rather than with Plover's built-in editor/"Add translation" feature,
you need to escape those characters in addition, according to JSON syntax:
 
| Symbol | Escaped Form |
|----------|----------|
| `\` | `\\`  |
| `"` | `\"`  |


If you edit the JSON file directly rather than with Plover's built-in editor/ [[File:Translation add.svg|link=|32px]][[Built-in_Tools#Add_translation_dialog|Add translation feature]], you need to escape those characters in addition, according to JSON syntax:
{| class="wikitable"
!Symbol
!Escaped Form
|-
|<code>\</code>
|<code>\\</code>
|-
|<code>"</code>
|<code>\"</code>
|}
Example:
Example:
 
{| class="wikitable"
| JSON | Plover show | Plover input | Plover output |
!JSON
|-|-|-|-|
!Plover show
| `"ab"` | `ab` | `ab` | `<a> <b>` |
!Plover input
| `"\\{"` | `\{` | `\{` | `<{>` |
!Plover output
| `"\\\\{"` | `\\{` | `\\{` | `<\> <{>` |
|-
| `"\""` | `"` | `"` | `<">` |
|<code>"ab"</code>
| `"\\"` | `\` | `\` | `<\>` |
|<code>ab</code>
| `"\\\\"` | `\\` | `\\` | `<\> <\>` |
|<code>ab</code>
| `"\\\\\\"` | `\\\` | `\\\` | `<\> <\> <\>` |
|<code><nowiki><a> <b></nowiki></code>
| `"\n"` | `\n` | `\n` | `<\n>` |
|-
| `"\\n"` | `\\n` | `\\n` | `<\> <n>` |
|<code>"\\{"</code>
| `"\\x"` | `\x` | `\x` | `<\> <x>` |
|<code>\{</code>
| `"\\\n"` | `\\n` | (none) | `<\> <\n>` |
|<code>\{</code>
| `"\\\\n"` | `\\\n` | `\\\n` | `<\> <\> <n>` |
|<code><{></code>
|-
|<code>"\\\\{"</code>
|<code>\\{</code>
|<code>\\{</code>
|<code><\> <{></code>
|-
|<code>"\""</code>
|<code>"</code>
|<code>"</code>
|<code><"></code>
|-
|<code>"\\"</code>
|<code>\</code>
|<code>\</code>
|<code><\></code>
|-
|<code>"\\\\"</code>
|<code>\\</code>
|<code>\\</code>
|<code><\> <\></code>
|-
|<code>"\\\\\\"</code>
|<code>\\\</code>
|<code>\\\</code>
|<code><\> <\> <\></code>
|-
|<code>"\n"</code>
|<code>\n</code>
|<code>\n</code>
|<code><\n></code>
|-
|<code>"\\n"</code>
|<code>\\n</code>
|<code>\\n</code>
|<code><\> <n></code>
|-
|<code>"\\x"</code>
|<code>\x</code>
|<code>\x</code>
|<code><\> <x></code>
|-
|<code>"\\\n"</code>
|<code>\\n</code>
|(none)
|<code><\> <\n></code>
|-
|<code>"\\\\n"</code>
|<code>\\\n</code>
|<code>\\\n</code>
|<code><\> <\> <n></code>
|}


Column explanation:
Column explanation:


* JSON: how the entry is stored in the JSON file.
; '''JSON:'''
* Plover show: how the entry is displayed in Plover "Add translation" dialog. (version 4)
:how the entry is stored in the JSON file.
* Plover input: how the entry can be added to the dictionary using Plover "Add translation"
; '''Plover show:'''
dialog. `(none)` means it's only possible to obtain the entry by editing the JSON in an
:how the entry is displayed in Plover [[File:Translation add.svg|link=|32px]] "[[Built-in_Tools#Add_translation_dialog|Add translation]]" dialog. (version 4)
external editor.
; '''Plover input:'''
* Plover output: what Plover will send to the emulated keyboard when that stroke is
:how the entry can be added to the dictionary using Plover "[[Built-in_Tools#Add_translation_dialog|Add translation]]" dialog. <code>(none)</code> means it's only possible to obtain the entry by editing the JSON in an external editor.
pressed.
; '''Plover output:'''
:what Plover will send to the emulated keyboard when that stroke is pressed.


=== "Do Nothing" Translation ===
You can use the keyboard shortcut syntax (<code>{#}</code>) if you want a stroke that effectively does nothing. For example: a null or canceled stroke, which doesn't affect formatting, doesn't output anything, and cannot be "undone" with the asterisk key. A stroke mapped to <code>{#}</code> will effectively do nothing but show up in your logs.


### "Do Nothing" Translation
* <code>{#}</code> an effective "null" stroke.


You can use the keyboard shortcut syntax (`{#}`) if you want a stroke that effectively does nothing. For example: a null or canceled stroke, which doesn't affect formatting, doesn't output anything, and cannot be "undone" with the asterisk key. A stroke mapped to `{#}` will effectively do nothing but show up in your logs.
See also: [[Dictionary Format#Canceling Formatting of Next Word|Canceling Formatting of Next Word]]


- `{#}` an effective "null" stroke.
== Output Modes ==


See also: [Canceling Formatting of Next Word](#canceling-formatting-of-next-word)
* <code>{MODE:}</code> is the mode operator
 
## Output Modes
 
- `{MODE:}` is the mode operator


Plover supports special character casing, such as CAPS LOCK and Title Case. It also supports replacing its implicit space with other characters. This is useful for when you want to write_in_snake_case.
Plover supports special character casing, such as CAPS LOCK and Title Case. It also supports replacing its implicit space with other characters. This is useful for when you want to write_in_snake_case.


**Output modes** are activated with a special syntax in your dictionary. They can be a stroke or just part of a stroke. They can then be turned off with a special reset command.  
'''Output modes''' are activated with a special syntax in your dictionary. They can be a stroke or just part of a stroke. They can then be turned off with a special reset command.


An example flow for CAPS LOCK might be:
An example flow for CAPS LOCK might be:


1. Turn on CAPS LOCK.
# Turn on CAPS LOCK.
1. Write in capital letters.
# Write in capital letters.
1. Turn off CAPS LOCK.
# Turn off CAPS LOCK.


However, there's nothing stopping you from building in output modes into your strokes. For example, you might want your new paragraph stroke to reset the case mode, no matter what.
However, there's nothing stopping you from building in output modes into your strokes. For example, you might want your new paragraph stroke to reset the case mode, no matter what.


### Reset Command
=== Reset Command ===
You can reset the output mode to its default with <code>{MODE:RESET}</code>.<blockquote>'''Important''': We recommended you have a reset output mode command, so that you can always reset Plover's output mode. This is in case you change it by accident.</blockquote>


You can reset the output mode to its default with `{MODE:RESET}`.
* <code>{MODE:RESET}</code>: Reset the case and space character. We recommended this for getting out of any custom output mode. For example: <code>"R-R": "{^~|\n^}{MODE:RESET}"</code> and <code>"TPEFBG": "{#escape}{MODE:RESET}"</code>
 
* <code>{MODE:RESET_CASE}</code>: Exit caps, lower, or title case.
> **Important**: We recommended you have a reset output mode command, so that you can always reset Plover's output mode. This is in case you change it by accident.
* <code>{MODE:RESET_SPACE}</code>: Use spaces as normal.
 
- `{MODE:RESET}`: Reset the case and space character. We recommended this for getting out of any custom output mode.
    For example: `"R-R": "{^~|\n^}{MODE:RESET}"` and `"TPEFBG": "{#escape}{MODE:RESET}"`
- `{MODE:RESET_CASE}`: Exit caps, lower, or title case.
- `{MODE:RESET_SPACE}`: Use spaces as normal.
 
### Modes


=== Modes ===
There are some built-in modes you can use:
There are some built-in modes you can use:
{| class="wikitable"
!Dictionary Syntax
!Sample Output
|-
|<code>{MODE:CAPS}</code>
|THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
|-
|<code>{MODE:TITLE}</code>
|The Quick Brown Fox Jumps Over The Lazy Dog.
|-
|<code>{MODE:LOWER}</code>
|the quick brown fox jumps over the lazy dog.
|-
|<code>{MODE:CAMEL}</code>
|theQuickBrownFoxJumpsOverTheLazyDog.
|-
|<code>{MODE:SNAKE}</code>
|The_quick_brown_fox_jumps_over_the_lazy_dog.
|}


| Dictionary Syntax | Sample Output |
=== Custom Modes ===
|-----------|---------|
You can define your own custom modes with the <code>SET_SPACE:</code> operator. This allows you to replace the space that Plover outputs with anything. Plover's snake-mode is the same as <code>SET_SPACE:_</code>.
| `{MODE:CAPS}` | THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. |
| `{MODE:TITLE}` | The Quick Brown Fox Jumps Over The Lazy Dog. |
| `{MODE:LOWER}` | the quick brown fox jumps over the lazy dog. |
| `{MODE:CAMEL}` | theQuickBrownFoxJumpsOverTheLazyDog. |
| `{MODE:SNAKE}` | The_quick_brown_fox_jumps_over_the_lazy_dog. |
 
### Custom Modes
 
You can define your own custom modes with the `SET_SPACE:` operator. This allows you to replace the space that Plover outputs with anything. Plover's snake-mode is the same as `SET_SPACE:_`.  


Here are some other examples:
Here are some other examples:
{| class="wikitable"
!Dictionary Syntax
!Sample Output
|-
|<code>{MODE:SET_SPACE:}</code>
|Thequickbrownfoxjumpsoverthelazydog.
|-
|<code>{MODE:SET_SPACE:-}</code>
|The-quick-brown-fox-jumps-over-the-lazy-dog.
|-
|<code>{MODE:SET_SPACE:😁}</code>
|The😁quick😁brown😁fox😁jumps😁over😁the😁lazy😁dog.
|}


| Dictionary Syntax | Sample Output |
== Summary of suggested commands you can cut and paste into your dictionary ==
|---------|-----------|
Here is a summary of the suggested commands you can cut and paste into your personal dictionary:
| `{MODE:SET_SPACE:}` | Thequickbrownfoxjumpsoverthelazydog. |
<code>{
| `{MODE:SET_SPACE:-}` | The-quick-brown-fox-jumps-over-the-lazy-dog. |
"PHR*UP":"{PLOVER:LOOKUP}",
| `{MODE:SET_SPACE:😁}` | The😁quick😁brown😁fox😁jumps😁over😁the😁lazy😁dog. |
"PHROFG":"{PLOVER:CONFIGURE}",
"PHROFBGS":"{PLOVER:FOCUS}",
"PHROBGT":"{PLOVER:QUIT}",
"KA*PD":"{*-|}",
"KA*PS":"{MODE:CAPS}",
"KPA*L":"{<}",
"*UPD":"{*<}",
"HRO*ER":"{>}",
"HRO*ERD":"{*>}",
"#":"{*+}",
"#*":"{*}",
"AFPS":"{*?}",
"TK-FPS":"{*!}"
}</code>
<blockquote>{{Info-Info|text=''Note:'' The final entry '''must not''' have a trailing comma.}}</blockquote>


## Summary of suggested commands you can cut and paste into your dictionary


Here is a summary of the suggested commands you can cut and paste into your personal dictionary:


```json
{
"PHR*UP":"{PLOVER:LOOKUP}",
"PHROFG":"{PLOVER:CONFIGURE}",
"PHROFBGS":"{PLOVER:FOCUS}",
"PHROBGT":"{PLOVER:QUIT}",
"KA*PD":"{*-|}",
"KA*PS":"{MODE:CAPS}",
"KPA*L":"{<}",
"*UPD":"{*<}",
"HRO*ER":"{>}",
"HRO*ERD":"{*>}",
"#":"{*+}",
"#*":"{*}",
"AFPS":"{*?}",
"TK-FPS":"{*!}"
}
```
> **Note:** The final entry must not have a trailing comma.
</markdown>
[[Category:Plover]]
[[Category:Plover]]

Latest revision as of 07:39, 20 May 2024

About Strokes and Dictionaries

If you are new to stenography:

  • A stroke is a group of keyboard keys that are pressed simultaneously to produce output. As soon as all keys on the keyboard are released, the steno machine sends out that entire chord of key presses as a stroke.
  • Plover converts that input into English words and phrases on the screen, by using dictionaries
  • with Plover, outputs are not limited to characters and punctuation symbols... Yes, a real stenographer chords emoji😅
  • Steno machines makes use of either defined software command, or a meta command, for controlling spacing and capitalization.
  • Every stenographer creates their own customized dictionary to supplement or amend the default dictionary that comes with a steno application, such as Plover. By default, you add your customizations to the user.json dictionary that comes with Plover.

Plover's Default Dictionaries

Plover comes supplied with three dictionaries:

  • main.json. This contains the default dictionary. It is based on Mirabai Knight's own personal dictionary, which follows a StenEd-style theory. It contains over 140,000 entries and is adequate for anyone learning stenography. Mirabai uses this dictionary professionally for her realtime work.
  • commands.json. This contains Plover Control Commands.
  • user.json. This is available for your personal customizations. user.json is a blank dictionary. By default, the user.json dictionary is at the bottom of the dictionary list and has the highest priority - it is the first dictionary Plover will use. When you define new strokes, they will get added to this dictionary. This means you can see which strokes you've defined yourself, instead of trying to locate them inside the default dictionaries.

You can add extra dictionaries to Plover, as well. Dictionaries may be located on your system in any directory/folder; they do not have to be in a subdirectory/subfolder of the Plover installation.

Note: We do not recommend you remove the commands.json dictionary from the dictionary list. This is because Plover has some concepts that users of other steno software will not be familiar with initially.

Dictionary priority

If two dictionaries contain the same steno strokes, Plover will use the one in the dictionary that has the highest priority. The dictionaries in the dictionary list are prioritised from the bottom up.

By default, the user.json dictionary is placed at the bottom of the dictionary list and has the highest priority. If you want new strokes to go to different dictionary (for example, you have your own dictionary already), make sure that dictionary is at the bottom of the list.

format=frameless
format=frameless

With Plover 4.0+, default dictionary priority is now top-down and can be changed. In the configuration settings, you can select your preferred ordering of dictionary priority to be bottom-up or top-down.

Dictionary File Formats

Plover is (or will be) able to import dictionaries from other steno programs. Here are some technical notes on each file format.

Some formats (including those not listed here) may require installation of a dedicated plugin.

format=frameless
format=frameless

There is a plugin plover-python-dictionary available in the plugins manager that allows you to use Python (.py) dictionaries. After installing the plugin, you will need to restart Plover before it will let you load Python dictionaries.

Limitations

There are some limitations with each format:

  • RTF dictionaries will cause Plover to take longer to start up and won't have Unicode support.
  • The JSON format that Plover uses is not used or supported by other steno applications. If you want to move or copy your Plover JSON formatted dictionary to another steno software application, you will need to convert it to RTF.
  • The Plover JSON format doesn't have support for stroke metadata. At the moment, Plover doesn't support reading/writing of RTF metadata.

json

The standard Plover format. Described at Dictionary format.

rtf (aka CRE)

A standard interchange format. Described at http://www.legalxml.org/workgroups/substantive/transcripts/cre-spec.htm .

RTF/CRE is an import/export format used by proprietary steno software. This means Plover can work with exported dictionaries from Eclipse, ProCAT, Case CATalyst, and other steno software applications.

dct (aka Stentura, Jet, MDB, Microsoft Access)

These are standard Microsoft Access databases (otherwise known as Microsoft Jet databases, or MDB files. They contain a single table named "Steno", which has columns named "Steno", "English", and "Flags". Each row represents a translation.

"Steno" is a text column containing the stroke, encoded as a concatenated sequence of six-digit hex strings representing bitmasks; each bit represents a key in the standard steno order

"English" is a text column giving the text translation of that stroke.

"Flags" is an integer bitmap. 0x8000 indicates a suffix; 0x4000 indicates a prefix; 0x2000 indicates that the next word should be capitalised.

Python lacks good cross-platform MDB support, so Plover reads the files using pure Python.

sgdct (CaseCat)

CaseCATalyst dictionaries have the extension ".sgdct". There is often a corresponding ".sgxml" file, but this contains no dictionary data.

Much of the detail of the file format remains unknown. Contributions and corrections are very welcome. Thanks are due to Sooty, who provided example files for dissection.

The files begin with a 640-byte header, which begins with the magic number SGCAT32. Nothing is known about header fields at present.

One or more records follow the header. Each record gives a single translation from steno to text.

The record header is 21 bytes. header[18] contains the number of strokes, and header[19] gives the number of letters in the text. Each is an unsigned byte. The purpose of all other fields in the record header is unknown at present.

The stroke follows, as a sequence of four-byte unsigned integers. Each integer is a bitmap of keys in the standard steno order, with the first "S" as the most significant bit.

Then the text follows, as ordinary ASCII text. Nothing is currently known about coding of text outside the ASCII range. Various non-ASCII characters crop up, apparently as control codes.

Finally, there are zero to three padding bytes, in order to bring us up to a four-byte boundary.

Plover Control Commands

You can control some aspects of Plover with strokes. Plover's default dictionary (commands.json) contains these commands:

Command name Command Default Stroke Description
Add Translation {PLOVER:ADD_TRANSLATION} TKUPT (think DUPT for "Dictionary UPdaTe") Opens a translation window where you can enter a stroke and translation text to create a new dictionary entry.
Disable Output {PLOVER:SUSPEND} PHRO*F (think PLOF for "PLover OFf") Stop translating steno. With a keyboard machine, you will be able to type normally again.
Enable Output {PLOVER:RESUME} PHRO*PB (think PLON for "PLover ON") Re-enable Plover's output. You can write this stroke to switch back from your keyboard into steno mode.
Toggle Output {PLOVER:TOGGLE} PHROLG (think PLOLG, for PLOver toGGLe) Toggle between output being enabled and disabled.

These commands are not in commands.json by default, but can be added to a dictionary:

Command name Command Suggested Stroke Description
Look Up Stroke {PLOVER:LOOKUP} PHR*UP Open a search dialog that you write a translation into to get a list of entries in your dictionaries.
Suggestions {PLOVER:SUGGESTIONS} PHROGS (think PLOSHUN) for PLOver suggesTION) Open and focus the plover suggestions window which will suggest alternative ways of writing
Configure {PLOVER:CONFIGURE} PHROFG (think PLOFG, for PLOver conFiG) Open and focus the Plover configuration window.
Focus {PLOVER:FOCUS} PHROFBGS (think PLOFKS, for PLOver focus) Open and focus the main Plover window.
Quit {PLOVER:QUIT} PHROBGT (think PLOKT, for PLOver quit) Quit Plover entirely.
Set configuration {PLOVER:SET_CONFIG:option:value}, {PLOVER:SET_CONFIG:option1:value1,option2:value2,...} Set Plover config option.

Example for SET_CONFIG Plover command:

  • {PLOVER:SET_CONFIG:'translation_frame_opacity':100}
  • {PLOVER:SET_CONFIG:'start_attached':True,'start_capitalized':True}

As a side effect, SET_CONFIG also reload the (changed) dictionaries.

Sending Symbols

Since Plover 3.0.0, users can write full Unicode. You can use symbols in your JSON dictionary, or paste them into the "Add Translation" dialog (or into the dictionary manager). You can get symbols from a character insert panel in your operating system (if you have one), or you can copy and paste symbols from another application, such as a web browser.

{
  "SHR*UG": "¯\\_(ツ)_/¯",
  "TR*PL": "{^}™",
  "TPHA*ES": "n̶o̶ yes"
}

Prefix strokes

It's possible to select the translation for a stroke depends on whether the previous word is finished.

Given the dictionary:

{
    "S": "word",
    "/S": "{prefix^}"
}

with a stroke S, the translation "/S": "{prefix^}" is chosen; unless the previous word is not finished (for example if the previous translation is {con^}), then the translation "S": "word" is chosen.

It's possible to explicitly mark a translation as "finished" with {$} (or equivalently {:word_end}).

See this blackbox test for an example.

Text Formatting

Prefixes, Infixes, and Suffixes

Strokes can be attached at the beginning and/or end using the "attach" operator. You can also use some of the built-in orthographic rules that Plover uses for creating intelligent strokes.

  • {^} is the attach operator.
  • {^ish} is an orthographic-aware suffix that will add "ish" to the end of the previous word. E.g. RED/EURB will output reddish. Note: addition of a second "d" caused by Plover's understanding of English orthography.
  • {^}ish is a suffix with the text outside the operator—this means that the text will simply be attached without grammar rules. Using this stroke in the previous example would give instead redish.
  • {^-to-^} is an infix, e.g. day-to-day.
  • {in^} is a prefix, e.g. influx.
  • Most custom punctuation entries will take advantage of the attach operator, e.g. {^—^} for an emdash.

Glue Operator (Numbers, Fingerspelling)

Glue is sort of like the attach operator above, except that "glued" strokes only attach to neighboring "glue" strokes.

Translations containing only digits are glued, allowing you to output multiple number strokes to make a large number.

  • {&} is the glue operator.
  • {&a}, {&b}, {&c}, etc. are how the fingerspelling alphabet is made.
  • {&th} is a multiletter glue stroke, which can be useful (TH* in the default dictionary)

Because glued translations only glue to other glued translations, they won't attach to regular words. This gives us some power because you can write:

THR/-R/#H/#A/KATS to get "there are 45 cats" and only #H (4) and #A (5) are "glued" to each other.

Capitalizing

Capitalizing a word means turning the first letter into a capital, e.g. proper nouns and in titles. Usually your dictionary has capitals pre-defined, but there are times when you need to capitalize a word on the go.

Capitalize Next Word

  • {-|}

The next word will have a capitalized first letter. In the default dictionary, we have "KPA": "{-|}", which will capitalize the next word; and "KPA*": "{^}{-|}" which omits a space and capitalizes the next word. That last stroke would let you writeLikeThis. This formatting style is called "camel case', which some programmers use in their work.

Capitalize next word can also be used in name titles, like Ms. {-|}.

Default strokes:

  • KPA: {-|} (think "cap")
  • KPA*: {^}{-|} (also suppresses space)

Capitalize Last Word

  • {*-|}

The last stroke word will have a capitalized first letter. This is useful in case you realize that a word should be capitalized after you've written it. It can also be used in a stroke, like in {*-|}{^ville}. This would capitalize the last word and attach to it. This would be useful for town names on the fly, such as Catville.

Suggested stroke: KA*PD

Uncapitalizing

Uncapitalize Next Word

  • {>}

Forces the next letter to be lowercase, e.g. {>}Ploverplover

Suggested stroke: HRO*ER (lower)

Uncapitalize Last Word

  • {*>}

Rewrite the last word to start with a lowercase letter, e.g. Plover{*>}plover

Suggested stroke: HRO*ERD (lowered)

Carrying Capitalization

  • {~|text} or {^~|text^} where the attach operator is optional and the text can be changed.

In English, we have punctuation that doesn't get capitalized, but instead the next letter gets the capitalization. For example, if you end a sentence in quotes, the next sentence still starts with a capital letter! "You can't eat that!" The baby ate on.

In order to support this, there is a special pre/in/suffix syntax that will "pass on" or "carry" the capitalized state. You might find this useful with quotes, parentheses, and words like 'til or 'cause.

The default dictionary for Plover should use these operators where appropriate.

{
  "KW-GS": "{~|\"^}",
  "KR-GS": "{^~|\"}",
  "KA*US": "{~|'^}cause",
  "PREPB": "{~|(^}",
  "PR*EPB": "{^~|)}"
}

For a newline, the syntax would be {^~|\n^}.

Uppercasing (CAPS)

See Output Modes for CAPS mode, which acts like CAPS lock on a regular keyboard. Alternatively, you can use a Keyboard Shortcut set to {#Caps_Lock} to activate the system CAPS lock like you can on your keyboard.

Suggested stroke: "KA*PS": "{MODE:CAPS}"

Uppercase Next Word

  • {<}

Output next stroke in capital letters, e.g. {<}catCAT

Suggested stroke: KPA*L (cap all)

Uppercase Last Word

  • {*<}

Rewrite last word in capital letters, e.g. cat{*<}CAT

Suggested stroke: *UPD

Spacing

Suppress Next Space

  • {^^} (or {^})

See also: Retroactively Delete Space

Default stroke: TK-LS (Delete Space)

This is a special case of an infix. See also Prefixes, Infixes, and Suffixes.

Manually Add a Space

  • {^ ^}

See also: Retroactively Add Space

Default stroke: S-P (SPace)

This is a special case of an infix. See also Prefixes, Infixes, and Suffixes.

Canceling Formatting of Next Word

In order to cancel formatting of the next word, use the empty meta tag as your definition:

  • {}

Using {} in front of a arrow key commands, as in {}{#Left}, is useful if the arrow key commands are used to move cursor to edit text. Canceling formatting actions for cursor movement prevents Plover from, for instance, capitalizing words in middle of a sentence if cursor is moved back when the last stroke, such as {.}, includes action to capitalize next word.

See also the "do nothing" translation

Format Currency

There is a built-in meta in Plover that allows you to format the last-written number as currency. The format is {*($c)} where $ is any currency symbol you'd like, and c is the amount, formatted in standard currency format, with either no decimals or two. Commas are added every 3 numbers before the decimal automatically.

  • {*($c)}: Standard English dollars
    • 23{*($c)} → $23
    • 2000.5{*($c)} → $2,000.50
  • {*($c CAD)}: You can include other text, e.g. when specifying a currency's country
    • 100{*($c CAD)} → $100 CAD
  • {*(c円)}: The symbol can be placed on either side of the number, which often happens in languages other than English and in certain regions.
    • 2345{*(c円)}: 2,345円

Here are some other currency symbols, in case you need to copy-paste them into your entries: £, ¥, €, $, ₩, ¢

Conditional

  • {=regex/text_if_match/text_if_no_match}

Conditional translation depending on the following text. Outputs text_if_match if the following text matches the regex, otherwise outputs text_if_no_match. Regex is case-sensitive. For example, {=[AEIOUaeiou]/an/a} outputs "a" unless the next word starts with a vowel, in which case it outputs "an".

Friendly Command Names

In a sufficiently-new Plover version, it's possible to use friendly names for some commands/metas.

For detailed descriptions of the commands, see the other sections.

Command/macro/meta Equivalent
{*} =retrospective_toggle_asterisk
{*!} =retrospective_delete_space
{*?} =retrospective_insert_space
{*+} =repeat_last_stroke
{^} {:attach}
{^word} {:attach:^word}
{word^} {:attach:word^}
{^word^} {:attach:word}
{&a} {:glue:a}
{-\|} {:case:cap_first_word}
{*-\|} {:retro_case:cap_first_word}
{~\|word} {:carry_capitalize:word}
{<} {:case:upper_first_word}
{*<} {:retro_case:upper_first_word}
{>} {:case:lower_first_char}
{*>} {:retro_case:lower_first_char}
{*($c)} {:retro_currency:$c}
{#shift(a)} {:key_combo:shift(a)}
{PLOVER:LOOKUP} {:command:LOOKUP}
{MODE:CAPS} {:mode:CAPS}
{.} {:stop:.}
{,} {:comma:,}
{$} {:word_end}

Note that currently the {#a} form will be interpreted literally in the "Strokes" text box of the Plover "Add Translation" dialog box, however entering a stroke mapped to {:key_combo:a} will enter the raw stroke into the text box.

Undoable Line Breaks and Tabs

When you use keyboard shortcuts, the asterisk/undo command on Plover will not have any effect. This is a limitation imposed by the fact that most commands will not have a meaningful undo. For example, you wouldn't "undo" a "copy" command. For this reason, {#return} and {#tab} don't work how many users would expect.

Instead, we must use special characters that can be undone by Plover for new paragraphs and erasable tabs. Specifically:

  • \n or \r for line breaks.
  • \t for tabs.

For example:

  • {^\n^}{-|} This translation would create a line break without spacing and then capitalize the next word. It can be removed with the asterisk key.
  • {^\t^} This translation presses the tab key without any other spacing. It can be undone with the asterisk key.

Macros

Macros can be mapped from a stroke and perform operations on the stroke-level. This means that it can perform actions based on previous strokes, not necessarily on previous words or translations.

Undo / Delete Last Stroke

  • =undo

The built-in "undo" macro is assigned to the asterisk key *. You can map other strokes to "undo" or "delete last stroke" by creating a stroke where the translation is =undo

Repeat Last Stroke

  • {*+} A stroke mapping to this macro will send the last stroke entered. A common stroke to map to repeat-last is the bare number bar; "#": "{*+}"; causing KAT/#/# to behave like KAT/KAT/KAT. Repeat last stroke {*+} is very useful for keys that you repeat. For example, when you are moving around text in a document.

Suggested stroke: #

Toggle asterisk

  • {*} A stroke mapping to this macro will toggle the asterisk key on the last stroke entered. For example, if you had this stroke in your dictionary as Number Bar + Asterisk, "#*": "{*}", when you write KAT/#* it will behave as if you wrote KA*T. Toggle asterisk {*} is useful for when you notice that you should have included an asterisk in your last stroke. For example, you wanted to write the name "Mark" (a person's name), but you wrote "mark" (the noun/verb). At this point, you can use Toggle asterisk {*} to correct it. You wouldn't have to erase the word and re-stroke it (this time, with you including the missing the asterisk).

Suggested stroke: #*

Retroactively Add Space

  • {*?} A stroke mapping to this macro will add a space between your last stroke and the one before that, splitting apart the two strokes. For example, if your dictionary contained PER as "Perfect", SWAEUGS as "Situation" and PER/SWAEUGS as "Persuasion". If you meant to write "Perfect situation", but saw your output was "Persuasion", you could force these two strokes to be split apart by using the {*?} stroke. This means your output would change on the screen from "Persuasion" to "Perfect situation".

Suggested stroke: AFPS (add space)

Retroactively Delete Space

  • {*!} A stroke mapping to this macro will delete the space between your last stroke and the one before that. If you wrote "Basket ball" but wanted it to be "Basketball", you could force these strokes together by using the {*!} stroke. Plover will go back and remove the space before your last stroke; As a result, your output would become "Basketball".

Suggested stroke: TK-FPS (delete space)

Keyboard Shortcuts

Most Plover strokes are just text and formatting operators. Plover handles standard strokes really well. This allows it to handle "undoing" with the asterisk key, as well as automatically handling case and spacing. However, Plover's text and formatting strokes can't send arbitrary key strokes, such as sending keyboard shortcuts.

Note: Plover 3.1 introduces new rules for commands that differ slightly from the previous implementation. Before Plover 3.1, commands were used to send symbols because Plover didn't have full Unicode support. It used to be possible to send "+" by writing {#plus}, but the system has been updated.

  • {#} is the command operator.

Inside of a command block, you write in what keys you want Plover to simulate. The keys hit in command blocks won't be "undone" when using the asterisk (because you can't backspace a keyboard shortcut). You select the keys by their name. All key names will only refer to the base key. For example, to use letter keys, you just use the corresponding letter (case insensitive) separated by spaces:

  • {#a b c d} will send "abcd" and will not affect Plover's text formatting or asterisk undo-buffer.

You can also use key names, which is needed when you are accessing a symbol key. For example, on the QWERTY layout there is an equal/plus key in the top right, which you can access by either of its names:

  • {#equal plus} will send "==". Plover doesn't send modifiers. It just hits the key based on the name.

If you want to send symbols, though, don't use commands. Commands should be used for keyboard shortcuts only. Instead, use the symbol in your dictionary entry.

Modifier Names

If you want to use a modifier, use it by name (e.g. Shift_L). For convenience, all key names are case insensitive and you can optionally default to the left modifier by dropping the side selector:

Modifier Command Key Names (case-insensitive)
Shift Shift_L, Shift_R, shift
Control Control_L, Control_R, control
Alt Alt_L, Alt_R, alt, option
Super Super_L, Super_R, super, windows, command

For modifiers, use parentheses to delimit where the keys are pressed down.

Shortcut Key Names

Here are the key names you'll want to use:

Keys Command Key Names (case-insensitive)
Letters a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
Accented Letters (international layouts) udiaeresis, eacute, etc.
Numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Control Keys Escape, Tab, Caps_Lock, space, BackSpace, Delete, Return, etc.
F-Keys F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12
Common Named Keys = equal- minus[ bracketleft] bracketright/ slash\ backslash' quoteright, comma. period; semicolon~ asciitilde^ asciicircum` quoteleft…and more
Media Keys Common: AudioRaiseVolume, AudioLowerVolume, AudioMute, AudioNext, AudioPrev, AudioStop, AudioPlay, AudioPause, EjectMac: MonBrightnessUp, MonBrightnessDown, KbdBrightnessUp, KbdBrightnessDown

Windows: Back, Forward, RefreshLinux: XF86 key names are supported, for example XF86_MonBrightnessUp - refer to the definition file in python-xlib for the key names.

Consult the code for the full list of supported keyboard shortcut keys.

Note: a key name will determine a key to emulate with no modifiers based on your keyboard layout. For example, let's say we want to make a keyboard shortcut to hit shift-2 which is "@" in QWERTY: {#at} will only press the 2 key. To get the @ symbol, we need to add the shift key: {#shift(at)}, which is functionally the same as {#shift(2)}.

Example Shortcuts

Here are some shortcuts. They are in JSON format:

  • "STPH-G": "{#right}" — right arrow on the keyboard, for moving the cursor to the right once
  • "SKWR-G": "{#shift(right)}" — shift and right arrow on the keyboard, for selecting one character
  • "SKWR-BG": "{#control(shift(right))}" — shift, control, and right arrow on the keyboard, for selecting one word to the right on Windows/Linux
  • "SKWR-BG": "{#option(shift(right))}" — option (alt), control, and right arrow on the keyboard, for selecting one word to the right on Mac

These next strokes are not particularly useful, but they show you what you can do with the command syntax:

  • "TKAO*UP": "{#control(c v v v)}" — copy, then paste 3 times
  • "SKPH-Z": "{#control(z shift(z))" — program-dependent, but possibly "undo/redo". Notice how the first z has only the control operator, and the second has both the control and the shift operator.

Commands are case insensitive - adding capitals will not affect the output. {#control(z shift(z)) is the same as "{#CONTROL_L(Z SHIFT(Z))}"

Escaping Special Characters

Most symbols (e.g. +, =, ~, r) can just be included directly in the definition. But some symbols are part of the dictionary syntax and so need to be escaped:

Symbol Escaped Form
\ \\
{ \{
} \}

\ is a special case. It must be escaped only if there's any possible ambiguity.

Special case: =content might be interpreted as the invocation of a macro named content. Use {#}=content instead.

If you edit the JSON file directly rather than with Plover's built-in editor/ Add translation feature, you need to escape those characters in addition, according to JSON syntax:

Symbol Escaped Form
\ \\
" \"

Example:

JSON Plover show Plover input Plover output
"ab" ab ab <a> <b>
"\\{" \{ \{ <{>
"\\\\{" \\{ \\{ <\> <{>
"\"" " " <">
"\\" \ \ <\>
"\\\\" \\ \\ <\> <\>
"\\\\\\" \\\ \\\ <\> <\> <\>
"\n" \n \n <\n>
"\\n" \\n \\n <\> <n>
"\\x" \x \x <\> <x>
"\\\n" \\n (none) <\> <\n>
"\\\\n" \\\n \\\n <\> <\> <n>

Column explanation:

JSON:
how the entry is stored in the JSON file.
Plover show:
how the entry is displayed in Plover "Add translation" dialog. (version 4)
Plover input:
how the entry can be added to the dictionary using Plover "Add translation" dialog. (none) means it's only possible to obtain the entry by editing the JSON in an external editor.
Plover output:
what Plover will send to the emulated keyboard when that stroke is pressed.

"Do Nothing" Translation

You can use the keyboard shortcut syntax ({#}) if you want a stroke that effectively does nothing. For example: a null or canceled stroke, which doesn't affect formatting, doesn't output anything, and cannot be "undone" with the asterisk key. A stroke mapped to {#} will effectively do nothing but show up in your logs.

  • {#} an effective "null" stroke.

See also: Canceling Formatting of Next Word

Output Modes

  • {MODE:} is the mode operator

Plover supports special character casing, such as CAPS LOCK and Title Case. It also supports replacing its implicit space with other characters. This is useful for when you want to write_in_snake_case.

Output modes are activated with a special syntax in your dictionary. They can be a stroke or just part of a stroke. They can then be turned off with a special reset command.

An example flow for CAPS LOCK might be:

  1. Turn on CAPS LOCK.
  2. Write in capital letters.
  3. Turn off CAPS LOCK.

However, there's nothing stopping you from building in output modes into your strokes. For example, you might want your new paragraph stroke to reset the case mode, no matter what.

Reset Command

You can reset the output mode to its default with {MODE:RESET}.

Important: We recommended you have a reset output mode command, so that you can always reset Plover's output mode. This is in case you change it by accident.

  • {MODE:RESET}: Reset the case and space character. We recommended this for getting out of any custom output mode. For example: "R-R": "{^~|\n^}{MODE:RESET}" and "TPEFBG": "{#escape}{MODE:RESET}"
  • {MODE:RESET_CASE}: Exit caps, lower, or title case.
  • {MODE:RESET_SPACE}: Use spaces as normal.

Modes

There are some built-in modes you can use:

Dictionary Syntax Sample Output
{MODE:CAPS} THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
{MODE:TITLE} The Quick Brown Fox Jumps Over The Lazy Dog.
{MODE:LOWER} the quick brown fox jumps over the lazy dog.
{MODE:CAMEL} theQuickBrownFoxJumpsOverTheLazyDog.
{MODE:SNAKE} The_quick_brown_fox_jumps_over_the_lazy_dog.

Custom Modes

You can define your own custom modes with the SET_SPACE: operator. This allows you to replace the space that Plover outputs with anything. Plover's snake-mode is the same as SET_SPACE:_.

Here are some other examples:

Dictionary Syntax Sample Output
{MODE:SET_SPACE:} Thequickbrownfoxjumpsoverthelazydog.
{MODE:SET_SPACE:-} The-quick-brown-fox-jumps-over-the-lazy-dog.
{MODE:SET_SPACE:😁} The😁quick😁brown😁fox😁jumps😁over😁the😁lazy😁dog.

Summary of suggested commands you can cut and paste into your dictionary

Here is a summary of the suggested commands you can cut and paste into your personal dictionary:

{
"PHR*UP":"{PLOVER:LOOKUP}",
"PHROFG":"{PLOVER:CONFIGURE}",
"PHROFBGS":"{PLOVER:FOCUS}",
"PHROBGT":"{PLOVER:QUIT}",
"KA*PD":"{*-|}",
"KA*PS":"{MODE:CAPS}",
"KPA*L":"{<}",
"*UPD":"{*<}",
"HRO*ER":"{>}",
"HRO*ERD":"{*>}",
"#":"{*+}",
"#*":"{*}",
"AFPS":"{*?}",
"TK-FPS":"{*!}"
}

Template:Info-Info