def _atom_to_action(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_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 elif meta == META_CAPITALIZE: action = last_action.copy_state() action.capitalize = True action.lower = False elif meta == META_LOWER: action = last_action.copy_state() action.lower = True action.capitalize = False 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) 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) space = NO_SPACE if last_attach else SPACE action.text = space + text action.word = _rightmost_word(text) return action
def _atom_to_action(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_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 elif meta == META_CAPITALIZE: action = last_action.copy_state() action.capitalize = True action.lower = False elif meta == META_LOWER: action = last_action.copy_state() action.lower = True action.capitalize = False 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) 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) space = NO_SPACE if last_attach else SPACE action.text = space + text action.word = _rightmost_word(text) 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'), ) 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)
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() 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 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 != '': action.replace = 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 != '': action.replace = 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() 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 == 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(')')): dict_format = meta[len(META_RETRO_FORMAT):-len(')')] action = last_action.copy_state() action.replace = last_action.word + SPACE 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) + SPACE action.word = format.format(cast_input) 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 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: action.replace = 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) 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') ) 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)
def test_add_suffix(self): # c+ly->cally assert add_suffix('artistic', 'ly') == 'artistically' # sibilant+s->es assert add_suffix('establish', 's') == 'establishes' assert add_suffix('speech', 's') == 'speeches' assert add_suffix('approach', 's') == 'approaches' assert add_suffix('beach', 's') == 'beaches' assert add_suffix('arch', 's') == 'arches' assert add_suffix('larch', 's') == 'larches' assert add_suffix('march', 's') == 'marches' assert add_suffix('search', 's') == 'searches' assert add_suffix('starch', 's') == 'starches' # hard ch+s->s assert add_suffix('stomach', 's') == 'stomachs' assert add_suffix('monarch', 's') == 'monarchs' assert add_suffix('patriarch', 's') == 'patriarchs' assert add_suffix('oligarch', 's') == 'oligarchs' # y+s->ies assert add_suffix('cherry', 's') == 'cherries' assert add_suffix('day', 's') == 'days' # y+ist->ist assert add_suffix('pharmacy', 'ist') == 'pharmacist' assert add_suffix('melody', 'ist') == 'melodist' assert add_suffix('pacify', 'ist') == 'pacifist' assert add_suffix('geology', 'ist') == 'geologist' assert add_suffix('metallurgy', 'ist') == 'metallurgist' assert add_suffix('anarchy', 'ist') == 'anarchist' assert add_suffix('monopoly', 'ist') == 'monopolist' assert add_suffix('alchemy', 'ist') == 'alchemist' assert add_suffix('botany', 'ist') == 'botanist' assert add_suffix('therapy', 'ist') == 'therapist' assert add_suffix('theory', 'ist') == 'theorist' assert add_suffix('psychiatry', 'ist') == 'psychiatrist' # y+ist->i exceptions assert add_suffix('lobby', 'ist') == 'lobbyist' assert add_suffix('hobby', 'ist') == 'hobbyist' assert add_suffix('copy', 'ist') != 'copyist' # TODO # y+!i->i assert add_suffix('beauty', 'ful') == 'beautiful' assert add_suffix('weary', 'ness') == 'weariness' assert add_suffix('weary', 'some') == 'wearisome' # e+vowel->vowel assert add_suffix('narrate', 'ing') == 'narrating' assert add_suffix('narrate', 'or') == 'narrator' # consonant doubling assert add_suffix('equip', 'ed') == 'equipped' assert add_suffix('defer', 'ed') == 'deferred' assert add_suffix('defer', 'er') == 'deferrer' assert add_suffix('defer', 'ing') == 'deferring' assert add_suffix('pigment', 'ed') == 'pigmented' assert add_suffix('refer', 'ed') == 'referred' assert add_suffix('fix', 'ed') == 'fixed' assert add_suffix('alter', 'ed') != 'altered' # TODO assert add_suffix('interpret', 'ing') != 'interpreting' # TODO assert add_suffix('wonder', 'ing') != 'wondering' # TODO assert add_suffix('target', 'ing') != 'targeting' # TODO assert add_suffix('limit', 'er') != 'limiter' # TODO assert add_suffix('maneuver', 'ing') != 'maneuvering' # TODO assert add_suffix('monitor', 'ing') != 'monitoring' # TODO assert add_suffix('color', 'ing') != 'coloring' # TODO assert add_suffix('inhibit', 'ing') != 'inhibiting' # TODO assert add_suffix('master', 'ed') != 'mastered' # TODO
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() 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 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 != '': action.replace = 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 != '': action.replace = 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() 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 == 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(')')): dict_format = meta[len(META_RETRO_FORMAT):-len(')')] action = last_action.copy_state() action.replace = last_action.word + SPACE 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) + SPACE action.word = format.format(cast_input) 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 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: action.replace = 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) 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"), ) 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)
def _translations_to_string(self, translations): """ Converts a list of Translation objects into printable text. Argument: translations -- A list of Translation objects. Returns a two-tuple, the first element of which is a printable string and the second element of which is a list of index, key combination pairs. Each key combination should be invoked after the sum of the number of emulated characters of the printable string and the number of emulated key combinations is equal to index. """ text_length = 0 text = [] key_combinations = [] previous_atom = None for translation in translations: if self._get_engine_command(translation): continue # Reduce the translation to atoms. An atom is in # irreducible string that is either entirely a single meta # command or entirely text containing no meta commands. if translation.english is not None: to_atomize = translation.english if to_atomize.isdigit(): to_atomize = self._apply_glue(to_atomize) atoms = META_RE.findall(to_atomize) else: to_atomize = translation.rtfcre if to_atomize.isdigit(): to_atomize = self._apply_glue(to_atomize) atoms = [to_atomize] for atom in atoms: atom = atom.strip() if text: space = SPACE else: space = NO_SPACE meta = self._get_meta(atom) if meta is not None: meta = self._unescape_atom(meta) english = meta space = NO_SPACE # Correct for most meta commands. old_text = '' if meta in META_COMMAS or meta in META_STOPS: pass # Space is already deleted. elif meta.startswith(META_GLUE_FLAG): english = meta[1:] previous_meta = self._get_meta(previous_atom) if (previous_meta is None or not previous_meta.startswith(META_GLUE_FLAG)): space = SPACE elif meta.startswith(META_ATTACH_FLAG): english = meta[1:] if english.endswith(META_ATTACH_FLAG): english = english[:-1] if text: old_text = text.pop() english = orthography.add_suffix(old_text, english); elif meta.endswith(META_ATTACH_FLAG): space = SPACE english = meta[:-1] elif meta == META_CAPITALIZE: english = NO_SPACE elif meta.startswith(META_KEY_COMBINATION): english = NO_SPACE combo = meta[1:] key_combinations.append((text_length, combo)) text_length += 1 text_length -= len(old_text) else: english = self._unescape_atom(atom) # Check if the previous atom is a meta command that # influences the next atom, namely this atom. previous_meta = self._get_meta(previous_atom) if previous_meta is not None: if previous_meta in META_STOPS: space = STOP_SPACE if english: english = english[0].upper() + english[1:] elif previous_meta == META_CAPITALIZE: space = NO_SPACE if english: english = english[0].upper() + english[1:] elif previous_meta.endswith(META_ATTACH_FLAG): space = NO_SPACE elif previous_meta.startswith(META_KEY_COMBINATION): space = NO_SPACE new_text = space + english text_length += len(new_text) text.append(new_text) previous_atom = atom return (''.join(text), key_combinations)