Skip to content

hftf/dope

 
 

Repository files navigation

Declarative open phrasing engine

Background

A stenographic phrasing system allows for systematically writing commonly-encountered phrases, and especially ones that combine a starter (subject pronoun, optional relativizer), a medial (auxiliary, modal, negation, adverb, etc.), and an ender (verb and tense). For example, the phrase “who could it have been happening to” has two starters (relativizer who, pronoun it), four medials (modal can, perfect aspect have, progressive/continuous aspect been, and subject–auxiliary inversion), and three enders (main verb happen, extra word to, and clause-level past tense turning can into could).

Phrasing systems encode meaning in key chords, and are primarily built around the few (10ish) available starter chords that are unused by and therefore do not conflict with other dictionaries that the user requires. Since the range of licit phrases is combinatorially complete, stenographic phrasing systems are usually implemented as programmatic dictionaries (written in Python, so requiring a plugin) rather than static JSON dictionaries as the latter would be unnecessarily large (> 10 MB) and very hard to adjust.

The user presses a combination of keys to specify all the starters, medials, and enders, and the phrasing system handles conjugation, word ordering, and so on. For example, the starter KPWH specifies the pronoun it; the medial A specifies the modal can, the medial EU specifies the perfect progressive aspect, the medial ^ specifies subject–auxiliary inversion; the ender PZ specifies the main verb happen and paired with T specifies the extra word to, and the ender D specifies past tense. So altogether, pressing ^KPWHAEUPTDZ gives the phrase could it have been happening to. Since relativizers and modals are mutually exclusive (they share the same keyspace) – that is, who cannot be used with can in the same phrase – the earlier example requires two strokes: e.g. WHO/^KPWHAEUPTDZ.

Diagram of the phrase above
startermedialender
KPWHA^EUPZTD
pronoun KPWH
it
modal A
can
tense can
could
D
past
inversion   it could
could it
^
 
aspect E
perfect
U
prog.
main verb PZ
happen
extra wordT
to
could ithavebeenhappeningto

Important precursors of this project include the phrasing systems of Aerick, Jade, Jeff, Josiah, and other inspirations, and it began as a fork and rewrite of Jeff’s. Further background and motivations are found in READMEs of precursor projects.

To give a very brief history of the above phrasing systems:

  1. First-generation scripts define rudimentary sets of starters, medials, and enders and allow concatenating them together like strings.
  2. Redundant enders for inflected forms of the same verb (such as don’t and doesn’t) are eliminated, since they conjugate entirely predictably based on the subject. This also prevents some ungrammatical outputs (such as I doesn’t).
  3. Encode progressively more linguistic information; syntactic features become the primary unit of operation rather than mere words that undergo combinatorial expansion. Maximize limited key space by compressing more efficiently. Richer affordances for customization.

Motivation

This is an engine for designing and customizing a stenographic phrasing system. The distinction between a system and an engine lies mainly in the separation of concerns. In a system, practically any code that gets the job done will do; an engine, however, is a backbone layer and allows for tweaking individual modules that live apart in the source code (for example, key mappings are independent of conjugation data, which are decoupled from grammatical rules and the lookup algorithm), with the expectation that changing one part won’t break anything else.

The distinction is not a concrete one, so it is really more about progress in relative terms, such as refactoring 1,000 lines of code into more manageable, separate files – a welcome novelty for Python dictionaries that get executed as eval jank.

Improvements on other programmatic phrasing systems

At the time of writing, these are mainly goals for the project rather than accurate representations of its current status.

Replace large-scale hard-coding with automatic generation

A major goal is to minimize code and eliminate hard-coded data that are entirely predictable, like conjugations and phrase structures. Such repetitive programs are hard to check, change, and maintain, and allow for typos to easily creep in. This means far greater use of declarative programming, unbundling control flow, passing state via objects, and code that is basically self-documenting.

Let's say you wanted to modify Jeff phrasing to remove contractions: it requires editing strings in dozens of places, which is error-prone. In contrast, you would only need to change one rule to do so in the engine.

Admittedly, hardcoding as a strategy can make a reverse lookup algorithm easier to write, and replacing hard-coded data with routines that generate the same data may add lines of code. But I believe the readability and extensibility trade-off is worth it.

Automated testing

Automated testing increases confidence in making changes and contributions as you can instantly check whether changes introduce regressions. Test cases and harnesses are not included when judging total lines of code.

Automatically handle conjugation, contraction, negation, and subject–auxiliary question inversion

While Jeff phrasing already achieves this goal, it can still output ungrammatical forms, such as (examples use Jeff phrasing key mappings) TWRUPLdo we may or KPWRUPBLGSdo you must.

Follow Pythonic conventions

Replace hyphens in filenames with underscores and name variables more carefully to avoid clobbering built-ins like dict. Tabular code is also space-aligned for readability.

Centralize

Despite the ease of making a GitHub repository, patches to phrasing systems (or even to dictionaries generally) have often been distributed as file uploads that lack provenance. It should be easier to share modifications (and documentations of conflicts) in the form of a separate “userspace” config file, a file footer, or a fork, rather than wholesale file replacements that are difficult to audit and interoperate.


Reclaim the -F key for more iconic verb enders

Jeff phrasing uses -F for perfect aspect, a good choice due to its left position and iconicity of the auxiliary verb “have.”

However, the lack of -F in ender space makes many enders unmemorable and the task of learning the phrasing system far more about memorizing arbitrary shapes. On top of training the hands on an entirely new ergonomics for phrasing, learning over 75 enders and their possible extra words is more than memorization enough.

With -F as an ender key, many more enders are iconic of the way they sound (e.g. feel = -FL). This also opens up two more avenues to leverage: -F as an early S (or fricative sound in general), and -FR as another M (in many theories, -FR is already an early M, particularly in the right-bank compounds MB and MP). Some verb enders that benefit are:

VerbEnderJeff’sExplanation
-F as F or V
feel FL LT FeeL
find FPB PBLG FiNd
forgetFRG RG FoRGet
have F T haVe
-FR as M
mean FR PBL Mean
mind FRPB PBLS MiNd
-F as early fricative (S, H, CH, X)
ask FBG RB aSK
set FS BLS Set + S
changeFPG PBGZ CHanGe
expectFPGT PGS eXPeCT
hope FP RPS HoPe
help FPL PLGS HeL↶P
leave FLZ LGZ Lea↶Ve + Z
↶ = inversion

While this change may not make optimal use of keyboard space, as there aren’t too many more enders to include, the freed up room could potentially be used for extra words.

It is important to understand that, aside from enabling some extra functionality, iconicity is the main reason why this project is (by default) designed around, but does not necessitate, the use of extra keys. For most hobbyists, it’s the most readily available trade-off for achieving less arbitrariness. (See § Key layout below; if you don’t want to use extra keys, you can always customize it to your liking while still making use of the underlying engine.)

Make right pinky shifting optional

In Jeff phrasing, to avoid diagonal shapes -TZ and -SD on the right pinky keys, verbs ending in -S always use -SZ (rather than -SD) for past tense, and verbs ending in -S or -Z with extra word -T always use -TSDZ for past tense.

These ergonomic exceptions are now optional (rather than mandatory) to increase flexibility for users comfortable with shifting and to prevent ungrammatical outputs (see the following section).

Produce no ungrammatical output

The goal of the phrasing engine is not to produce any ungrammatical forms, and to produce exactly all grammatical forms; that is, it is generative. Stenography-system-level suffix keys (-D, -G, -S, -Z) in the same stroke should be prevented from having an unwanted effect (see also above section).

Reserve keys for single function (instead of overload with select adverbs)

In order to include select adverbs, Jeff phrasing overloads certain combinations of perfect and progressive aspects with question inversion, but we still have a need to write these phrases.

Adverbs are to be implemented as a second stroke with dedicated key space.

Use a retroactive second stroke for other features (adverbs, passive voice)

Some phrasing systems and extensions aspire to do too many things at once in a stroke: control several adverbs, passive voice, suffixed object pronouns, and contractions. Remember, a stenographic keyboard typically has only 23–28 keys (and duplicate asterisk keys provide no extra bits), all of which are needed after accounting for the most necessary bits of information:

Feature Number Bits required (log₂ N)
Subject 8–15 3–4 (but free only among 7 keys)
Modal 4+ 2+
Aspect 4 2
Tense 2 1
Negation 2 1
Inversion 2 1
Contraction 2 1
Verbs 64+ 6+
Extra word 2 1
Redundancy for
ergonomic pinky shapes
1
Total20+ (but free only among 23 keys)

There are also 8+ relativizers (3+ bits), but the bits from modal, aspect, and negation are cannibalized.

Better learning resources and terminology

In my opinion, phrasing resources suffer from two key issues, aside from practice materials: organization and terminology.

I find many existing phrasing resources confusingly organized and too shape-focused; many infographic explainers omit key labels! Learning resources should distinguish iconic from arbitrary chords, and prefer meaningful over alphabetical ordering. It should also be possible to generate documentation and learning resources from code (code-as-data).

Phrasing resources often misuse linguistic terminology (e.g. misuse “plural” to refer to the third-person singular inflection -s) or are counterintuitive (e.g. “simple form”). Using mainstream linguistic terminology helps understand the reasons behind the system’s design. The algorithm itself should be based on linguistic principles. Something like do-support should really not need to be documented in a table, since the use of do-support should already be intuitive to the user (do what I mean). Similarly, contractions and irregular verb forms are implementation details and do not need full documentation.

While tables of starters and enders are useful, tables of phrase structures are hard to remember. Iconic and pictorial diagrams (not just infographic – information spatially arranged into a graphic) would be most helpful for visual learners.

Eventual convergence through experimentation and divergence

Paradoxically, the ultimate end goal of this project is not for each user to customize and tweak their phrasing system or design their own, but, through it, once enough people have done so, to converge closer to a single optimal English phrasing system design, in the same way that the Ireland layout is the standard in English stenography. People need to try diverse possibilities for us to collectively reach the best ideas.

Therefore, you are encouraged to fork, pull request, etc. Any amount of contribution makes a difference.

Phrasing system (default design)

By default, the system is designed for the key layout below. (The ^ and + keys require the plover-stenotype-extended plugin.)

^TPH*FPLTD
SKWR*RBGSZ
#AOEU+

Unless otherwise stated, assume that most design aspects are identical to Jeff phrasing. At the moment, while documentation is incomplete, it may be more useful to read the code. Look for dicts in files named *_data.py.

Warning

At this time, the key layout above is assumed, so chords may not have comfortable shapes for everyone. This will be made more customizable at some point, through an interface being developed in settings.py. Feel free to hack the code to do what you want!

Pictographic key layout

There are two types of phrase: phrases without a relativizer, and phrases with a relativizer. In Jeff phrasing, these are called “full form” and “simple form” respectively.

Each region of the keyboard controls a different feature of the phrase. These regions are mapped below. Nuances are discussed in later sections.

Subject
(“full form”)
Relativizer + Subject
(“simple form”)

❓🚻🚻🚻⛔🆚🆚🆚🆙🔙
🚻🚻🚻🚻⛔🆚🆚🆚🆚🆚
 #️⃣Ⓜ️Ⓜ️ 🏧⛎🗜  

Symbol Keys Usage (oversimplified)
#️⃣ # number key (unused)
🚻 STKPWHR subject pronoun
Ⓜ️ AO modal
* negation
🏧 E perfect aspect (have)
U progressive aspect (be)
🔙 D tense
🗜 + contraction
^ inversion
🆚 FRPBLGSZ main verb
🆙 T extra word

❓🚾🚾🚾🚹🆚🆚🆚🆙🔙
🚾🚾🚾🚾🚹🆚🆚🆚🆚🆚
 #️⃣🚾🚾 🚹🚹🗜  

SymbolKeysUsage (oversimplified)
Ⓜ️, ⛔, 🏧, ⛎ are invalid
🚾STKPWHRAOrelativizer
🚹*EUsimple subject pronoun
same

Relativizer

For phrasing purposes, a relativizer is effectively an extra word prefixed before the subject. Relativizers can be coordinators (e.g. and, but) or subordinators (e.g. if, that, when, who). A relativizer may also be called a conjunction, preposition, complementizer, or relative pronoun. Relativizers are so named because they introduce a relative (or subordinate) clause – also called a wh-clause as it often begins with a wh-word (what, who, which, when, where, why, how).

Relativizers cannot be used with modality, aspect, or negation, as they overload the keyspace used by both “full form” subject pronouns and modals, and are used in conjunction with a limited set of subject pronouns that overload aspect and negation. This limitation may be why it is counterintuitively called “simple form” in Jeff phrasing, despite adding an extra initial word.

SubordinatorsCoordinators
STPA if*† SPWHbut
STHA that* SKP and
SWH whenSKPRor
SWHR where
SWHA what
SWHO who
SWHAO why
SWHRAOhow
* forbids inversion† requires subject

Subject pronoun

Subjects specify the person (first, second, third) and number (singular, plural) of the phrase. These features surface as inflections on the tensed (finite) verb, which is a phenomenon called subject–verb agreement (concord).

Two third-person null subjects exist in “full form”: STWR (singular) and STKPWHR (plural).

SubjectsSingularPlural
First personSWRITWR we
Second personKPWRyou
Third personKWHRheTWHthey
SKWHRshe
KPWH it
STKHthis STKWHthese
STWHthat
STHRthereSTPHRthere
STKPWHR(null)STWR(null)₂

Note

💡 Memorization tip: Both of the first-person subjects I SWR and we TWR contain the keys WR.

Only eight subjects total exist in “simple form”:

Simple subjectsSingularPlural
First personEUI*EU we
Second personUyou
Third personEhe*Uthey
*Eshe
* it
 (null)

Note

In Jeff phrasing, “simple form” does not allow a null subject.

Tense

Phrases can be in present (non-past) or past tense.

Note

Tense applies to the first verb in the clause, not the main verb.

Tense
  Present (non-past)
D Past

Aspect

English has two axes of aspect: imperfect vs. perfect (auxiliary have), and simple vs. progressive (auxiliary be).

Perfect aspect generally indicates completed actions, and progressive aspect indicates continuous actions.

AspectImperfectPerfect
Simple SimpleEPerfect (have V·en)
ProgressiveUProgressive (be V·ing)EUPerfect progressive (have been V·ing)

Modality

The modality (or mood) can be can, will, shall, or null. The forms could, would, should are selected by past tense. (Other modals in English include may/might, must, need to, be able to, etc., but these are not available as phrase-level modals, only as ad-hoc enders.)

Modals are usually defective verbs (so can only be finite, inflecting for tense).

Note

The so-called “future tense” is treated here as a will modal, not a tense, which is consistent with the approach taken in many English grammars. See also this video.

Modal
  (null)
A can
AO will
O shall

Subject–auxiliary question inversion

Subject–auxiliary inversion is the main feature of questions or interrogative phrases. When an auxiliary is absent, there is do-support (a dummy do acts like an auxiliary). Interrogatives are contrasted with declarative (or indicative) statements.

Inversion
  Declarative (no inversion)
^ Subject–auxiliary inversion

Polarity

Phrases are positive (affirmative) or negative. When an auxiliary is absent in a negative phrase, there is do-support.

Negation is only implemented for the matrix (main) clause, and so it is governed by (attaches after) the first verb. This means that e.g. he could not have gone is possible in the phrasing system, while *he could have not gone is not.

A similar rule applies to negated infinitives: not to go is possible, but *to not go is not.

Polarity
  Positive
* Negative

Contraction

TODO/Self-explanatory. Multiple contractions (e.g. couldn’t’ve) can technically be supported by the engine, but no interface exists for applying them yet.

Note

aren’t is the exceptional contracted form of am + not (which only appears in interrogatives).

Contraction
  No contraction
+ Contraction

Main verb (or other ender)

TODO/Self-explanatory.

Some defective verbs and non-verbs (common adverbs) are also available.

Note

Main-verb have can rarely take do-support (e.g. have you no shame), but this is archaic in most English dialects, so is not supported.

Extra word

The extra word depends entirely on the main verb. It tries to be the most frequent collocation or most useful otherwise.

Some examples of extra words: a, it, to, the, that, like, on.

The verb enders are defined in verb_data.py:138. The following table shows the defaults.

Verb ender table

VerbExtra wordEnderJeff’sExplanationNotes
(null) talk T =
Modal verbs (auxiliary verbs)
can n/a BGS unavailable but listed here for completion;
only useful in “simple form”
will RBGS
shall RBL
may be PL = Maypast tense: might
must be PBLGS = MuSt + just’s Jdefective (no past tense): taken by just
Adverbs (non-verbs)
just PBLGSZ= JuSZtlisted after must: overrides its past tense
really RLG = RealLYLG (i.e. -liȝ)
Common verbs
be a B = Be
have to F T haVe
do it RP = arb.†
go to G = Go
get to GS = Get + Spast participle: got; passive voice: gotten
he had got to (obligation) available
he had gotten (obtained) unavailable
say thatBS = from common BS*
use used to TZ
Z= uZe
used to TZ = uZed Tospecial case: really acts as use + to T
Verbs of cognition
know thatPB = kNow
think thatPBG = thiNGk
remember thatRPL = ReMember
understandthe RPB = undeRstaNd
believe thatBL = BeLieve
imagine thatPLG = iMaGine
forget to FRG RG FoRGet
mean to FR PBL MFRean
learn to RPBL RPBSLea↶RN
seem to PLS = See↶M
expect thatFPGT PGS eXPeCGT
realize thatRLZ RLS ReaLiZe
mind FRPB PBLSMiNd
suppose thatFPZ 🆕 SuPPoZe
Verbs of desire
want to P = from common PT*
wish to RBS = wiSH + S
need to PBL RPG Need + dental L
hope to FP RPS HoPe
like to LG BLG LiKGe
love to LGZ LG LoVZe + like’s G
care RG RZ CGa↶Re
More verbs
become a BGS RPBGBeKome + S
change expect FPGT
FPG PBGZCHanGe
consider RBGS RBGZKonSide↶R
find thatFPB PBLGFiNd
happen to PZ = haPPen + Z
try to RT = T↶Ry
make a PBLG RPBLMaKe
work on RBG = woRK
play withPLGS 🆕 PLaYG + S
start to FRS 🆕 SFtaRt + S
choose to FPS 🆕 CHooSe
Verbs of placement
put it PS = Put + S
set FS BLS Set + S
let LS = Let + S
give GZ = GiVZe
take RBT = arb.†
keep PG = KGee↶P
bring RPBG = B↶RiNG
provide RPZ = P↶RoVZide
Verbs of action, communication
come to BG = Kome
live LZ = LiVZe
move PLZ = MoVZe
leave FLZ LGZ Lea↶VZe
remain RPLS = ReMain + S
call BLG RBLGKaLL
recall RL = RecaLL
read RS = Read + S
run try RT
R = Run
show RB RBZ SHow
ask FBG RB aSK
tell LT RLT Te↶LL
talk to T 🆕 Talk
help FPL 🆕 HeL↶P
Verbs of perception
feel likeFL LT FeeL
hear thatFRP = HeaR + P
see talk to TS
S = See
look tell LT
L = Look
notice thatPBS 🆕 NotiSe
recognize thatRGZ 🆕 RecoGniZe
Key† arbitrarily assigned chord= same↶ inversionXY: Y key represents variant of X sound
no T extra word due to other ender* right-bank abbreviation already widely used in stenography

Infinitive

The infinitive (or non-finite) form is selected by a null subject with inversion (^). This makes sense as there cannot be inversion without a subject. Verbs have only one infinitive form, which follows to, thus STWR and STKPWHR neutralize (behave identically) in this context.

Note

Defective verbs (modals and non-verbs) do not have an infinitive form.

Passive voice

Passive voice effectively inserts auxiliary be before the main verb and selects the past participle form of the main verb.

A test implementation currently uses a retroactive second stroke +-P (i.e. press + and P after the first stroke).

Adverb

Not yet implemented. Adverbs can include medial just, really, even, still, always, never, etc. There is extra complexity because adverbs may exhibit free positioning.

Fallback second stroke for conflicts

If a higher-priority dictionary overrides the phrasing system, then adding the second stroke + is available as a fallback. For example, SKP-LD is defined as and would in main.json, so SKP-LD would not available for phrasing and looked, but SKP-LD/+ is available as a fallback for and looked. Similarly, KPWRES is defined as impress, so KPWRES/+ can be used to access the phrase you have seen.

Summary of differences with other phrasing systems

FeatureJeffJosiahDope default
Perfect aspect (have)FE
Progressive aspect (be) EU
Subject–auxiliary inversionU^
Past tense of ender containing -S-SZBoth -SZ or -SD
Contraction Hard-coded onlyControlled by +
Fallback for conflictsNot implementedSecond stroke +
Passive voice Not implementedSecond stroke +-P
Adverbs (just, even, still, always, never)Overloaded *EUFNot implemented
Reverse lookup ReadyMostly implemented
Chord assignmentsMay differ variously
Chord assignments: verb endersCannot use FCan use F
Chord assignments: can, will, shall endersBGS, RBGS, RBLRemoved
“Simple form” subject keys*EU^EU*EU
“Simple form” negation n/a * n/a
“Simple form” inversion n/a n/a ^
“Simple form” allows empty subjectno yes yes

Learning and practice

Materials or curricula for specifically practicing a phrasing system do not really exist yet. However, a drill on Steno Jig often gives many sentences with high-frequency phrases: Markov-chain (randomly) generated sentences.

The phrasing system should be relatively straightforward to pick up; just read this documentation, then start using it. It is recommended to make liberal use of the suggestions window and tapey-tape.

How to learn a phrasing system

  1. Read/skim the documentation once. (20 minutes)
  2. Go back over the documentation and pick out some of the examples. Break up the outlines into their constituent parts to confirm you understand them. (20 minutes)
  3. Read/skim the code once. (optional)
  4. Come up with some pictographics or mnemonics, or create a cheat sheet, to arrange some of what you learned from the above in your head. (20 minutes)
  5. Write some text while consulting any of Plover’s lookup panels and stroke-saving suggestions in tapey_tape.txt.
  6. Practice on the Steno Jig drill linked above.
  7. Repeat any of the above steps as desired.

You can probably get acquainted with a phrasing system to a basic level in as little as one day this way.

Installation

At this time, the project is still in early development and is not quite ready to work out of the box. However, you are welcome to try it if you can get it to work.

  1. Ensure all dependencies are installed: plover_python_dictionary, plover-stenotype-extended (both Plover plugins), appdirs (Python module).
  2. Clone or download this folder (currently called dope) and put it as a subdirectory inside the plover appdir.
  3. Open Plover and add dope/my_phrasing.py as a dictionary. (The other .py files need to be in the same folder as my_phrasing.py, but do not add them to Plover as they are not dictionaries themselves.)

Troubleshooting

If the module resolution at the top of my_phrasing.py is not working (errors like No module named 'noun_data' appear),

dope/my_phrasing.py

Lines 1 to 10 in b070652

# Following ten lines of jank needed because Plover doesn't know how to import local modules
try:
import plover
plover_dir = plover.oslayer.config.CONFIG_DIR
except:
import appdirs
plover_dir = appdirs.user_data_dir('plover', 'plover')
import os, sys
dope_dir = os.path.join(plover_dir, 'dope/')
sys.path.append(dope_dir)

then, for now, you can try to replace it with a hard-coded path:

-try:
-	import plover
-	plover_dir = plover.oslayer.config.CONFIG_DIR
-except:
-	import appdirs
-	plover_dir = appdirs.user_data_dir('plover', 'plover')
+plover_dir = '/home/path/to/my/plover/appdir'

To-do list

Remember that this project encompasses both phrasing system and engine (internals) – see § Motivation above. The former is fairly stable, while the latter still needs to undergo more work.

Short-term

  • Write installation instructions
    • Mention dictionary priority
  • Write testing instructions
  • Consider dropping the terms starter/medial/ender entirely
    • For “chord”?
  • Consider grouping verbs by arbitrary added key (e.g. S, Z)
  • Abstraction of user settings
    • Duplicate tests for different settings
    • Document how a user can change settings
  • Add some Josiah extensions (depends on above)
  • Create better resources
    • Video lessons? Interactive lessons?
    • Cheat sheet/poster/explainer?
    • Sample texts for drilling
  • Change extra word in passive to supposed to
  • Automatically fix double to, e.g. I am going to followed by to be a (sugar)
  • Allow some relativizers with past participle, e.g. when asked

Long-term

  • Handle unwanted suffix keys
  • Produce no ungrammatical output
  • Fix conflicts with my dictionaries
  • Singular/plural distinction in relativizers
    • Allow why are, how are, etc. (the only available null simple subject is singular)
  • Irrealis (so-called “past subjunctive”) with if
    • Could repurpose if + past tense
  • Adverb medials (just, really, even, still, always, never)
  • Consider reprioritizing low-frequency combos to make fingerwork more convenient (can have, shall have are less common than could have, should have, so maybe we can avoid needing to press -D to make could, should)
  • Consider KPWREPLD you might have (*you have might) etc.

About

  • Started learning Jeff phrasing on September 25, 2023
  • Started rewrite on September 26, 2023
  • First published on October 13, 2023
  • Split from parent repository on January 29, 2024

Status/FAQ

Is this project finished?
Not fully. But on a daily basis, it does everything I want it to. I have already found the configuration that works for me and have been using it stably for a year with no changes.
Is development active?
Currently inactive (but not abandoned). I was interested in building more robust and further abstractions for the engine, but haven’t managed to find other users or testers to try it out, and have less availability for this hobby.
How many people use this?
I don’t know if anyone else uses it.
How do I…?
This project is basically available as-is (DIY). Setting it up and tweaking it both assume some familiarity with coding and development tools. But if you find a way to send me a message, I may be able to help.

About

Declarative open phrasing engine for Plover

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

No contributors

Languages

  • Python 100.0%