Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

formatting & translations: add support for prefix strokes #1157

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news.d/feature/1157.core.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add prefix strokes (syntax `/STROKE`) that will only translate if they are at the beginning of a word. Word endings can be specified with `{:word_end}` or `{$}`.
13 changes: 11 additions & 2 deletions plover/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ def parse(meta):
(r'\*-\|', 'retro_case', Case.CAP_FIRST_WORD.value ),
(r'\*>' , 'retro_case', Case.LOWER_FIRST_CHAR.value),
(r'\*<' , 'retro_case', Case.UPPER_FIRST_WORD.value),
# Explicit word end.
(r'(\$)', 'word_end', 0),
# Mode.
(r'MODE:(.*)', 'mode', 0),
# Currency.
Expand Down Expand Up @@ -554,7 +556,7 @@ def __init__(self,
# Current.
glue=False, word=None, orthography=True, space_char=' ',
upper_carry=False, case=None, text=None, trailing_space='',
combo=None, command=None,
word_is_finished=None, combo=None, command=None,
# Next.
next_attach=False, next_case=None
):
Expand All @@ -576,7 +578,9 @@ def __init__(self,

upper_carry -- True if we are uppercasing the current word.

othography -- True if orthography rules should be applies when adding
word_is_finished -- True if word is finished.

orthography -- True if orthography rules should be applies when adding
a suffix to this action.

space_char -- this character will replace spaces after all other
Expand Down Expand Up @@ -609,6 +613,10 @@ def __init__(self,
self.orthography = orthography
self.next_attach = next_attach
self.next_case = next_case
if word_is_finished is None:
self.word_is_finished = not self.next_attach
else:
self.word_is_finished = word_is_finished
# Persistent state variables
self.space_char = space_char
self.case = case
Expand All @@ -628,6 +636,7 @@ def copy_state(self):
case=self.case, glue=self.glue, orthography=self.orthography,
space_char=self.space_char, upper_carry=self.upper_carry,
word=self.word, trailing_space=self.trailing_space,
word_is_finished=self.word_is_finished,
# Next.
next_attach=self.next_attach, next_case=self.next_case,
)
Expand Down
11 changes: 7 additions & 4 deletions plover/gui_qt/add_translation_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,13 @@ def _unfocus_translation(self):
self._focus = None

def _strokes(self):
strokes = self.strokes.text().replace('/', ' ').split()
if not strokes:
return ()
return normalize_steno('/'.join(strokes))
strokes = self.strokes.text().strip()
has_prefix = strokes.startswith('/')
strokes = '/'.join(strokes.replace('/', ' ').split())
if has_prefix:
strokes = '/' + strokes
strokes = normalize_steno(strokes)
return strokes

def _translation(self):
translation = self.translation.text().strip()
Expand Down
2 changes: 2 additions & 0 deletions plover/meta/attach.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def meta_attach(ctx, meta):
if end:
meta = meta[:-len(META_ATTACH_FLAG)]
action.next_attach = True
action.word_is_finished = False
last_word = ctx.last_action.word or ''
if not meta:
# We use an empty connection to indicate a "break" in the
Expand Down Expand Up @@ -62,6 +63,7 @@ def meta_carry_capitalize(ctx, meta):
if end:
meta = meta[:-len(META_ATTACH_FLAG)]
action.next_attach = True
action.word_is_finished = False
if meta or begin or end:
action.text = meta
return action
4 changes: 4 additions & 0 deletions plover/meta/word_end.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def meta_word_end(ctx, meta):
action = ctx.copy_last_action()
action.word_is_finished = True
return action
9 changes: 9 additions & 0 deletions plover/steno.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def normalize_stroke(stroke):

def normalize_steno(strokes_string):
"""Convert steno strings to one common form."""
if not strokes_string:
return ()
return tuple(normalize_stroke(stroke) for stroke
in strokes_string.split(STROKE_DELIMITER))

Expand Down Expand Up @@ -75,6 +77,10 @@ def __init__(self, steno_keys) :
# Remove duplicate keys and save local versions of the input
# parameters.
steno_keys_set = set(steno_keys)
if not steno_keys_set:
self.steno_keys = []
self.rtfcre = ''
return
# Order the steno keys so comparisons can be made.
steno_keys = list(sort_steno_keys(steno_keys_set))

Expand All @@ -101,6 +107,9 @@ def __init__(self, steno_keys) :
# Determine if this stroke is a correction stroke.
self.is_correction = (self.rtfcre == system.UNDO_STROKE_STENO)

def __hash__(self):
return hash(self.rtfcre)

def __str__(self):
if self.is_correction:
prefix = '*'
Expand Down
21 changes: 19 additions & 2 deletions plover/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from plover import system


PREFIX_STROKE = Stroke(())

_ESCAPE_RX = re.compile('(\\\\[nrt]|[\n\r\t])')
_ESCAPE_REPLACEMENTS = {
'\n': r'\n',
Expand Down Expand Up @@ -299,7 +301,7 @@ def translate_stroke(self, stroke):
stroke -- The Stroke object to process.

"""
mapping = self.lookup([stroke])
mapping = self._lookup_with_prefix(self._state.translations, [stroke])
macro = _mapping_to_macro(mapping, stroke)
if macro is not None:
self.translate_macro(macro)
Expand Down Expand Up @@ -354,7 +356,7 @@ def _find_translation_helper(self, stroke, suffixes=()):
replaced = translations[i:]
strokes = [s for t in replaced for s in t.strokes]
strokes.append(stroke)
mapping = self.lookup(strokes, suffixes)
mapping = self._lookup_with_prefix(translations[:i], strokes, suffixes)
if mapping is not None:
t = Translation(strokes, mapping)
t.replaced = replaced
Expand Down Expand Up @@ -382,6 +384,21 @@ def lookup(self, strokes, suffixes=()):
return main_mapping + ' ' + suffix_mapping
return None

def _previous_word_is_finished(self, last_translations):
if not last_translations:
return True
formatting = last_translations[-1].formatting
if not formatting:
return True
return formatting[-1].word_is_finished

def _lookup_with_prefix(self, last_translations, strokes, suffixes=()):
if self._previous_word_is_finished(last_translations):
mapping = self.lookup([PREFIX_STROKE] + strokes, suffixes)
if mapping is not None:
return mapping
return self.lookup(strokes, suffixes)


class _State:
"""An object representing the current state of the translator state machine.
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ plover.meta =
retro_case = plover.meta.case:meta_retro_case
retro_currency = plover.meta.currency:meta_retro_currency
stop = plover.meta.punctuation:meta_stop
word_end = plover.meta.word_end:meta_word_end
plover.system =
English Stenotype = plover.system.english_stenotype
setuptools.installation =
Expand Down
9 changes: 9 additions & 0 deletions test/test_blackbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,3 +1592,12 @@ def test_meta_attach_suffix(self):

TEFT/AT/TEFT ' testattach test'
'''

def test_prefix_strokes(self):
r'''
"/S": "{prefix^}",
"S": "{^suffix}",
"O": "{O'^}{$}",

S/S/O/S/S " prefixsuffix O'prefixsuffix"
'''