Example #1
0
def _apply_meta_attach(meta, ctx):
    action = ctx.new_action()
    begin = meta.startswith(META_ATTACH_FLAG)
    end = meta.endswith(META_ATTACH_FLAG)
    if begin:
        meta = meta[len(META_ATTACH_FLAG):]
        action.prev_attach = True
    if end:
        meta = meta[:-len(META_ATTACH_FLAG)]
        action.next_attach = True
    last_word = ctx.last_action.word or ''
    if not meta:
        # We use an empty connection to indicate a "break" in the
        # application of orthography rules. This allows the
        # stenographer to tell Plover not to auto-correct a word.
        action.orthography = False
    elif (last_word and not meta.isspace() and ctx.last_action.orthography
          and begin and (not end or _has_word_boundary(meta))):
        new_word = add_suffix(last_word, meta)
        common_len = len(commonprefix([last_word, new_word]))
        replaced = last_word[common_len:]
        action.prev_replace = ctx.last_text(len(replaced))
        assert replaced.lower() == action.prev_replace.lower()
        last_word = last_word[:common_len]
        meta = new_word[common_len:]
    action.text = meta
    if action.prev_attach:
        action.word = _rightmost_word(last_word + meta)
    return action
Example #2
0
def _apply_meta_attach(meta, ctx):
    action = ctx.new_action()
    begin = meta.startswith(META_ATTACH_FLAG)
    end = meta.endswith(META_ATTACH_FLAG)
    if begin:
        meta = meta[len(META_ATTACH_FLAG):]
        action.prev_attach = True
    if end:
        meta = meta[:-len(META_ATTACH_FLAG)]
        action.next_attach = True
    last_word = ctx.last_action.word or ''
    if not meta:
        # We use an empty connection to indicate a "break" in the
        # application of orthography rules. This allows the
        # stenographer to tell Plover not to auto-correct a word.
        action.orthography = False
    elif (
        last_word and
        not meta.isspace() and
        ctx.last_action.orthography and
        begin and (not end or _has_word_boundary(meta))
    ):
        new_word = add_suffix(last_word, meta)
        common_len = len(commonprefix([last_word, new_word]))
        replaced = last_word[common_len:]
        action.prev_replace = ctx.last_text(len(replaced))
        assert replaced.lower() == action.prev_replace.lower()
        last_word = last_word[:common_len]
        meta = new_word[common_len:]
    action.text = meta
    if action.prev_attach:
        action.word = _rightmost_word(last_word + meta)
    return action
Example #3
0
 def test_runner(test, *args, **kwargs):
     fn(test, *args, **kwargs)
     result = add_suffix(test.word, test.suffix)
     report = orthographic_rules_report(test.word, test.suffix)
     msg = '%s\n%s' % (
         test.format(location=False, result=result),
         '\n'.join('• %s: %s' % (k, pformat(v)) for k, v in report.items()),
     )
     assert result == test.expected, msg
Example #4
0
def _atom_to_action_spaces_after(atom, last_action):
    """Convert an atom into an action.

    Arguments:

    atom -- A string holding an atom. An atom is an irreducible string that is
    either entirely a single meta command or entirely text containing no meta
    commands.

    last_action -- The context in which the new action takes place.

    Returns: An action for the atom.

    """

    action = _Action(space_char=last_action.space_char, case=last_action.case)
    last_word = last_action.word
    last_glue = last_action.glue
    last_attach = last_action.attach
    last_capitalize = last_action.capitalize
    last_lower = last_action.lower
    last_upper = last_action.upper
    last_upper_carry = last_action.upper_carry
    last_orthography = last_action.orthography
    last_space = SPACE if last_action.text.endswith(SPACE) else NO_SPACE
    was_space = len(last_space) is not 0
    begin = False  # for meta attach
    meta = _get_meta(atom)
    if meta is not None:
        meta = _unescape_atom(meta)
        if meta in META_COMMAS:
            action.text = meta + SPACE
            if last_action.text != '':
                if was_space:
                    action.replace = SPACE
                else:
                    action.replace = NO_SPACE
            if last_attach:
                action.replace = NO_SPACE
        elif meta in META_STOPS:
            action.text = meta + SPACE
            action.capitalize = True
            action.lower = False
            if last_action.text != '':
                if was_space:
                    action.replace = SPACE
                else:
                    action.replace = NO_SPACE
            if last_attach:
                action.replace = NO_SPACE
        elif meta == META_CAPITALIZE:
            action = last_action.copy_state()
            action.capitalize = True
            action.lower = False
        elif meta == META_LOWER:
            action = last_action.copy_state()
            if was_space:
                # Persist space state
                action.replace = SPACE
                action.text = SPACE
            action.lower = True
            action.capitalize = False
        elif meta == META_UPPER:
            action = last_action.copy_state()
            action.lower = False
            action.upper = True
            action.capitalize = False
        elif (meta.startswith(META_CARRY_CAPITALIZATION) or
              meta.startswith(META_ATTACH_FLAG + META_CARRY_CAPITALIZATION)):
            action = _apply_carry_capitalize(meta, last_action, spaces_after=True)
        elif meta == META_RETRO_CAPITALIZE:
            action = last_action.copy_state()
            action.word = _capitalize(action.word)
            if len(last_action.text) < len(last_action.word):
                action.replace = last_action.word + SPACE
                action.text = _capitalize(last_action.word + SPACE)
            else:
                action.replace = last_action.text
                action.text = _capitalize_nowhitespace(last_action.text)
        elif meta == META_RETRO_LOWER:
            action = last_action.copy_state()
            action.word = _lower(action.word)
            if len(last_action.text) < len(last_action.word):
                action.replace = last_action.word + SPACE
                action.text = _lower(last_action.word + SPACE)
            else:
                action.replace = last_action.text
                action.text = _lower_nowhitespace(last_action.text)
        elif meta == META_RETRO_UPPER:
            action = last_action.copy_state()
            action.word = _upper(action.word)
            action.upper_carry = True
            if len(last_action.text) < len(last_action.word):
                action.replace = last_action.word + SPACE
                action.text = _upper(last_action.word + SPACE)
            else:
                action.replace = last_action.text
                action.text = _upper(last_action.text)
        elif meta.startswith(META_RETRO_FORMAT):
            if meta.startswith(META_RETRO_FORMAT) and meta.endswith(')'):
                action = _apply_currency(meta, last_action, spaces_after=True)
        elif meta.startswith(META_COMMAND):
            action = last_action.copy_state()
            action.command = meta[len(META_COMMAND):]
        elif meta.startswith(META_MODE):
            action = last_action.copy_state()
            action = _change_mode(meta[len(META_MODE):], action)
        elif meta.startswith(META_GLUE_FLAG):
            action.glue = True
            text = meta[len(META_GLUE_FLAG):]
            if last_capitalize:
                text = _capitalize(text)
            if last_lower:
                text = _lower(text)
            action.text = text + SPACE
            action.word = _rightmost_word(text)
            if last_glue:
                if was_space:
                    action.replace = SPACE
                else:
                    action.replace = NO_SPACE
                action.word = _rightmost_word(last_word + text)
            if last_attach:
                action.replace = NO_SPACE
                action.word = _rightmost_word(last_word + text)
        elif (meta.startswith(META_ATTACH_FLAG) or
              meta.endswith(META_ATTACH_FLAG)):
            begin = meta.startswith(META_ATTACH_FLAG)
            end = meta.endswith(META_ATTACH_FLAG)
            if begin:
                meta = meta[len(META_ATTACH_FLAG):]
            if end and len(meta) >= len(META_ATTACH_FLAG):
                meta = meta[:-len(META_ATTACH_FLAG)]

            space = NO_SPACE if end else SPACE
            replace_space = NO_SPACE if last_attach else SPACE

            if end:
                action.attach = True
            if begin and end and meta == '':
                # We use an empty connection to indicate a "break" in the
                # application of orthography rules. This allows the
                # stenographer to tell plover not to auto-correct a word.
                action.orthography = False
                if last_action.text != '':
                    action.replace = replace_space
            if (((begin and not end) or (begin and end and ' ' in meta)) and
                    last_orthography):
                new = orthography.add_suffix(last_word.lower(), meta)
                common = commonprefix([last_word.lower(), new])
                if last_action.text == '':
                    replace_space = NO_SPACE
                action.replace = last_word[len(common):] + replace_space
                meta = new[len(common):]
            if begin and end:
                if last_action.text != '':
                    action.replace = replace_space
            if last_capitalize:
                meta = _capitalize(meta)
            if last_lower:
                meta = _lower(meta)
            if last_upper_carry:
                meta = _upper(meta)
                action.upper_carry = True
            action.text = meta + space
            action.word = _rightmost_word(
                last_word[:len(last_word + last_space)-len(action.replace)]
                + meta)
            if end and not begin and last_space == SPACE:
                action.word = _rightmost_word(meta)
        elif meta.startswith(META_KEY_COMBINATION):
            action = last_action.copy_state()
            action.combo = meta[len(META_KEY_COMBINATION):]
    else:
        text = _unescape_atom(atom)
        if last_capitalize:
            text = _capitalize(text)
        if last_lower:
            text = _lower(text)
        if last_upper:
            text = _upper(text)
            action.upper_carry = True

        action.text = text + SPACE
        action.word = _rightmost_word(text)

    action.text = _apply_mode(action.text, action.case, action.space_char,
                              begin, last_attach, last_glue,
                              last_capitalize, last_upper, last_lower)
    return action
 def test_add_suffix(self):
     cases = (
     
         ('artistic', 'ly', 'artistically'),
         ('cosmetic', 'ly', 'cosmetically'),
         ('establish', 's', 'establishes'),
         ('speech', 's', 'speeches'),
         ('approach', 's', 'approaches'),
         ('beach', 's', 'beaches'),
         ('arch', 's', 'arches'),
         ('larch', 's', 'larches'),
         ('march', 's', 'marches'),
         ('search', 's', 'searches'),
         ('starch', 's', 'starches'),
         ('stomach', 's', 'stomachs'),
         ('monarch', 's', 'monarchs'),
         ('patriarch', 's', 'patriarchs'),
         ('oligarch', 's', 'oligarchs'),
         ('cherry', 's', 'cherries'),
         ('day', 's', 'days'),
         ('penny', 's', 'pennies'),
         ('pharmacy', 'ist', 'pharmacist'),
         ('melody', 'ist', 'melodist'),
         ('pacify', 'ist', 'pacifist'),
         ('geology', 'ist', 'geologist'),
         ('metallurgy', 'ist', 'metallurgist'),
         ('anarchy', 'ist', 'anarchist'),
         ('monopoly', 'ist', 'monopolist'),
         ('alchemy', 'ist', 'alchemist'),
         ('botany', 'ist', 'botanist'),
         ('therapy', 'ist', 'therapist'),
         ('theory', 'ist', 'theorist'),
         ('psychiatry', 'ist', 'psychiatrist'),
         ('lobby', 'ist', 'lobbyist'),
         ('hobby', 'ist', 'hobbyist'),
         ('copy', 'ist', 'copyist'),
         ('beauty', 'ful', 'beautiful'),
         ('weary', 'ness', 'weariness'),
         ('weary', 'some', 'wearisome'),
         ('lonely', 'ness', 'loneliness'),
         ('narrate', 'ing', 'narrating'),
         ('narrate', 'or', 'narrator'),
         ('generalize', 'ability', 'generalizability'),
         ('reproduce', 'able', 'reproducible'),
         ('grade', 'ations', 'gradations'),
         ('urine', 'ary', 'urinary'),
         ('achieve', 'able', 'achievable'),
         ('polarize', 'ation', 'polarization'),
         ('done', 'or', 'donor'),
         ('analyze', 'ed', 'analyzed'),
         ('narrate', 'ing', 'narrating'),
         ('believe', 'able', 'believable'),
         ('animate', 'ors', 'animators'),
         ('discontinue', 'ation', 'discontinuation'),
         ('innovate', 'ive', 'innovative'),
         ('future', 'ists', 'futurists'),
         ('illustrate', 'or', 'illustrator'),
         ('emerge', 'ent', 'emergent'),
         ('equip', 'ed', 'equipped'),
         ('defer', 'ed', 'deferred'),
         ('defer', 'er', 'deferrer'),
         ('defer', 'ing', 'deferring'),
         ('pigment', 'ed', 'pigmented'),
         ('refer', 'ed', 'referred'),
         ('fix', 'ed', 'fixed'),
         ('alter', 'ed', 'altered'),
         ('interpret', 'ing', 'interpreting'),
         ('wonder', 'ing', 'wondering'),
         ('target', 'ing', 'targeting'),
         ('limit', 'er', 'limiter'),
         ('maneuver', 'ing', 'maneuvering'),
         ('monitor', 'ing', 'monitoring'),
         ('color', 'ing', 'coloring'),
         ('inhibit', 'ing', 'inhibiting'),
         ('master', 'ed', 'mastered'),
         ('target', 'ing', 'targeting'),
         ('fix', 'ed', 'fixed'),
         ('scrap', 'y', 'scrappy'),
         ('trip', 's', 'trips'),
         ('equip', 's', 'equips'),
         ('bat', 'en', 'batten'),
         ('smite', 'en', 'smitten'),
         ('got', 'en', 'gotten'),
         ('bite', 'en', 'bitten'),
         ('write', 'en', 'written'),
         ('flax', 'en', 'flaxen'),
         ('wax', 'en', 'waxen'),
         ('fast', 'est', 'fastest'),
         ('white', 'er', 'whiter'),
         ('crap', 'y', 'crappy'),
         ('lad', 'er', 'ladder'),
         ('translucent', 'cy', 'translucency'),
         ('bankrupt', 'cy', 'bankruptcy'),
         ('inadequate', 'cy', 'inadequacy'),
         ('secret', 'cy', 'secrecy'),
         ('impolite', 'cy', 'impolicy'),
         ('idiot', 'cy', 'idiocy'),
         ('free', 'ed', 'freed'),
         ('free', 'er', 'freer'),
         ('regulate', 'ry', 'regulatory'),
     )
     for word, suffix, expected in cases:
         result = add_suffix(word, suffix)
         msg = 'add_suffix(%r, %r) returned %r instead of %r' % (
             word, suffix, result, expected,
         )
         self.assertEqual(result, expected, msg=msg)
Example #6
0
def _atom_to_action_spaces_before(atom, last_action):
    """Convert an atom into an action.

    Arguments:

    atom -- A string holding an atom. An atom is an irreducible string that is
    either entirely a single meta command or entirely text containing no meta
    commands.

    last_action -- The context in which the new action takes place.

    Returns: An action for the atom.

    """
    
    action = _Action()
    last_word = last_action.word
    last_glue = last_action.glue
    last_attach = last_action.attach
    last_capitalize = last_action.capitalize
    last_lower = last_action.lower
    last_upper = last_action.upper
    last_upper_carry = last_action.upper_carry
    last_orthography = last_action.orthography
    meta = _get_meta(atom)
    if meta is not None:
        meta = _unescape_atom(meta)
        if meta in META_COMMAS:
            action.text = meta
        elif meta in META_STOPS:
            action.text = meta
            action.capitalize = True
            action.lower = False
            action.upper = False
        elif meta == META_CAPITALIZE:
            action = last_action.copy_state()
            action.capitalize = True
            action.lower = False
            action.upper = False
        elif meta == META_LOWER:
            action = last_action.copy_state()
            action.lower = True
            action.upper = False
            action.capitalize = False
        elif meta == META_UPPER:
            action = last_action.copy_state()
            action.lower = False
            action.upper = True
            action.capitalize = False
        elif meta == META_RETRO_CAPITALIZE:
            action = last_action.copy_state()
            action.word = _capitalize(action.word)
            if len(last_action.text) < len(last_action.word):
                action.replace = last_action.word
                action.text = _capitalize(last_action.word)
            else:
                action.replace = last_action.text
                action.text = _capitalize_nowhitespace(last_action.text)
        elif meta == META_RETRO_LOWER:
            action = last_action.copy_state()
            action.word = _lower(action.word)
            if len(last_action.text) < len(last_action.word):
                action.replace = last_action.word
                action.text = _lower(last_action.word)
            else:
                action.replace = last_action.text
                action.text = _lower_nowhitespace(last_action.text)
        elif meta == META_RETRO_UPPER:
            action = last_action.copy_state()
            action.word = _upper(action.word)
            action.upper_carry = True
            if len(last_action.text) < len(last_action.word):
                action.replace = last_action.word
                action.text = _upper(last_action.word)
            else:
                action.replace = last_action.text
                action.text = _upper(last_action.text)
        elif meta.startswith(META_RETRO_FORMAT):
            if (meta.startswith(META_RETRO_FORMAT) and meta.endswith(')')):
                dict_format = meta[len(META_RETRO_FORMAT):-len(')')]
                action = last_action.copy_state()
                action.replace = last_action.word
                try:
                    float(last_action.word)
                except ValueError:
                    pass
                else:
                    format = dict_format.replace('c', '{:,.2f}')
                    cast_input = float(last_action.word)
                try:
                    int(last_action.word)
                except ValueError:
                    pass
                else:
                    format = dict_format.replace('c', '{:,}')
                    cast_input = int(last_action.word)
                action.text = format.format(cast_input)
                action.word = action.text
        elif meta.startswith(META_COMMAND):
            action = last_action.copy_state()
            action.command = meta[len(META_COMMAND):]
        elif meta.startswith(META_GLUE_FLAG):
            action.glue = True
            glue = last_glue or last_attach
            space = NO_SPACE if glue else SPACE
            text = meta[len(META_GLUE_FLAG):]
            if last_capitalize:
                text = _capitalize(text)
            if last_lower:
                text = _lower(text)
            action.text = space + text
            action.word = _rightmost_word(last_word + action.text)
        elif (meta.startswith(META_ATTACH_FLAG) or 
              meta.endswith(META_ATTACH_FLAG)):
            begin = meta.startswith(META_ATTACH_FLAG)
            end = meta.endswith(META_ATTACH_FLAG)
            if begin:
                meta = meta[len(META_ATTACH_FLAG):]
            if end and len(meta) >= len(META_ATTACH_FLAG):
                meta = meta[:-len(META_ATTACH_FLAG)]
            space = NO_SPACE if begin or last_attach else SPACE
            if end:
                action.attach = True
            if begin and end and meta == '':
                # We use an empty connection to indicate a "break" in the 
                # application of orthography rules. This allows the stenographer 
                # to tell plover not to auto-correct a word.
                action.orthography = False
            if (((begin and not end) or (begin and end and ' ' in meta)) and 
                last_orthography):
                new = orthography.add_suffix(last_word.lower(), meta)
                common = commonprefix([last_word.lower(), new])
                action.replace = last_word[len(common):]
                meta = new[len(common):]
            if last_capitalize:
                meta = _capitalize(meta)
            if last_lower:
                meta = _lower(meta)
            if last_upper_carry:
                meta = _upper(meta)
                action.upper_carry = True
            action.text = space + meta
            action.word = _rightmost_word(
                last_word[:len(last_word)-len(action.replace)] + action.text)
        elif meta.startswith(META_KEY_COMBINATION):
            action = last_action.copy_state()
            action.combo = meta[len(META_KEY_COMBINATION):]
    else:
        text = _unescape_atom(atom)
        if last_capitalize:
            text = _capitalize(text)
        if last_lower:
            text = _lower(text)
        if last_upper:
            text = _upper(text)
            action.upper_carry = True
        space = NO_SPACE if last_attach else SPACE
        action.text = space + text
        action.word = _rightmost_word(text)
    return action
Example #7
0
    def test_add_suffix(self):
        cases = (
            ('artistic', 'ly', 'artistically'),
            ('cosmetic', 'ly', 'cosmetically'),
            ('establish', 's', 'establishes'),
            ('speech', 's', 'speeches'),
            ('approach', 's', 'approaches'),
            ('beach', 's', 'beaches'),
            ('arch', 's', 'arches'),
            ('larch', 's', 'larches'),
            ('march', 's', 'marches'),
            ('search', 's', 'searches'),
            ('starch', 's', 'starches'),
            ('stomach', 's', 'stomachs'),
            ('monarch', 's', 'monarchs'),
            ('patriarch', 's', 'patriarchs'),
            ('oligarch', 's', 'oligarchs'),
            ('cherry', 's', 'cherries'),
            ('day', 's', 'days'),
            ('penny', 's', 'pennies'),
            ('pharmacy', 'ist', 'pharmacist'),
            ('melody', 'ist', 'melodist'),
            ('pacify', 'ist', 'pacifist'),
            ('geology', 'ist', 'geologist'),
            ('metallurgy', 'ist', 'metallurgist'),
            ('anarchy', 'ist', 'anarchist'),
            ('monopoly', 'ist', 'monopolist'),
            ('alchemy', 'ist', 'alchemist'),
            ('botany', 'ist', 'botanist'),
            ('therapy', 'ist', 'therapist'),
            ('theory', 'ist', 'theorist'),
            ('psychiatry', 'ist', 'psychiatrist'),
            ('lobby', 'ist', 'lobbyist'),
            ('hobby', 'ist', 'hobbyist'),
            ('copy', 'ist', 'copyist'),
            ('beauty', 'ful', 'beautiful'),
            ('weary', 'ness', 'weariness'),
            ('weary', 'some', 'wearisome'),
            ('lonely', 'ness', 'loneliness'),
            ('narrate', 'ing', 'narrating'),
            ('narrate', 'or', 'narrator'),
            ('generalize', 'ability', 'generalizability'),
            ('reproduce', 'able', 'reproducible'),
            ('grade', 'ations', 'gradations'),
            ('urine', 'ary', 'urinary'),
            ('achieve', 'able', 'achievable'),
            ('polarize', 'ation', 'polarization'),
            ('done', 'or', 'donor'),
            ('analyze', 'ed', 'analyzed'),
            ('narrate', 'ing', 'narrating'),
            ('believe', 'able', 'believable'),
            ('animate', 'ors', 'animators'),
            ('discontinue', 'ation', 'discontinuation'),
            ('innovate', 'ive', 'innovative'),
            ('future', 'ists', 'futurists'),
            ('illustrate', 'or', 'illustrator'),
            ('emerge', 'ent', 'emergent'),
            ('equip', 'ed', 'equipped'),
            ('defer', 'ed', 'deferred'),
            ('defer', 'er', 'deferrer'),
            ('defer', 'ing', 'deferring'),
            ('pigment', 'ed', 'pigmented'),
            ('refer', 'ed', 'referred'),
            ('fix', 'ed', 'fixed'),
            ('alter', 'ed', 'altered'),
            ('interpret', 'ing', 'interpreting'),
            ('wonder', 'ing', 'wondering'),
            ('target', 'ing', 'targeting'),
            ('limit', 'er', 'limiter'),
            ('maneuver', 'ing', 'maneuvering'),
            ('monitor', 'ing', 'monitoring'),
            ('color', 'ing', 'coloring'),
            ('inhibit', 'ing', 'inhibiting'),
            ('master', 'ed', 'mastered'),
            ('target', 'ing', 'targeting'),
            ('fix', 'ed', 'fixed'),
            ('scrap', 'y', 'scrappy'),
            ('trip', 's', 'trips'),
            ('equip', 's', 'equips'),
            ('bat', 'en', 'batten'),
            ('smite', 'en', 'smitten'),
            ('got', 'en', 'gotten'),
            ('bite', 'en', 'bitten'),
            ('write', 'en', 'written'),
            ('flax', 'en', 'flaxen'),
            ('wax', 'en', 'waxen'),
            ('fast', 'est', 'fastest'),
            ('white', 'er', 'whiter'),
            ('crap', 'y', 'crappy'),
            ('lad', 'er', 'ladder'),
            ('translucent', 'cy', 'translucency'),
            ('bankrupt', 'cy', 'bankruptcy'),
            ('inadequate', 'cy', 'inadequacy'),
            ('secret', 'cy', 'secrecy'),
            ('impolite', 'cy', 'impolicy'),
            ('idiot', 'cy', 'idiocy'),
            ('free', 'ed', 'freed'),
            ('free', 'er', 'freer'),
            ('regulate', 'ry', 'regulatory'),
        )

        failed = []
        for word, suffix, expected in cases:
            if add_suffix(word, suffix) != expected:
                failed.append((word, suffix, expected))

        for word, suffix, expected in failed:
            print 'add_suffix(%s, %s) is %s not %s' % (
                word, suffix, add_suffix(word, suffix), expected)

        self.assertEqual(len(failed), 0)
Example #8
0
def test_add_suffix(word, suffix, expected):
    assert add_suffix(word, suffix) == expected
Example #9
0
def test_add_suffix(word, suffix, expected):
    assert add_suffix(word, suffix) == expected