コード例 #1
0
def repeat_last_fragment(translator: Translator, stroke: Stroke, macro_args: str) -> None:
    '''
    Macro to repeat the last fragments(s) in Plover.

    :param translator: The active Plover translator that is executing the macro.
    :type translator: plover.translation.Translator

    :param stroke: The current stroke (what invoked this macro).
    :type stroke: plover.translation.Stroke

    :param macro_args: The optional arguments specified to the macro as a comma-delimited string.
                       Piece 1: The number of previous fragments to repeat. Default is 1.
    :type macro_args: str
    '''

    # Get the current state
    translations = translator.get_state().translations
    if not translations:
        return

    # Process input
    try:
        num_to_repeat = int(macro_args.split(DELIM_ARGS)[0])
    except:
        num_to_repeat = 1

    # Output the new translations
    formatter = RetroFormatter(translations)
    last_fragments = formatter.last_fragments(num_to_repeat)

    for fragment in last_fragments:
        new_translation = Translation([stroke], fragment)
        translator.translate_translation(new_translation)
コード例 #2
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi(self)
        engine = QApplication.instance().engine
        self._engine = engine
        self._dictionaries = []
        self._reverse_order = False
        self._selected_dictionary = None
        engine.signal_connect('config_changed', self.on_config_changed)
        self.on_config_changed(engine.config)
        engine.signal_connect('dictionaries_loaded', self.on_dictionaries_loaded)
        self.on_dictionaries_loaded(self._engine.dictionaries)

        self._special_fmt = (
            '<span style="' +
            'background-color:' + self.palette().base().color().name() +';' +
            'font-family:monospace;' +
            '">%s</span>'
        )

        self.strokes.installEventFilter(self)
        self.translation.installEventFilter(self)

        with engine:

            # Pre-populate the strokes or translations with last stroke/word.
            last_translations = engine.translator_state.translations
            translation = None
            for t in reversed(last_translations):
                # Find the last undoable stroke.
                if t.has_undo():
                    translation = t
                    break
            # Is it a raw stroke?
            if translation is not None and not translation.english:
                # Yes.
                self.strokes.setText(translation.formatting[0].text)
                self.on_strokes_edited()
                self.strokes.selectAll()
            else:
                # No, grab the last-formatted word.
                retro_formatter = RetroFormatter(last_translations)
                last_words = retro_formatter.last_words(strip=True)
                if last_words:
                    self.translation.setText(last_words[0])
                    self.on_translation_edited()

            self._original_state = self.EngineState(None,
                                                    engine.translator_state,
                                                    engine.starting_stroke_state)
            engine.clear_translator_state()
            self._strokes_state = self.EngineState(self._dictionary_filter,
                                                   engine.translator_state,
                                                   StartingStrokeState(True, False))
            engine.clear_translator_state()
            self._translations_state = self.EngineState(None,
                                                        engine.translator_state,
                                                        StartingStrokeState(True, False))
        self._engine_state = self._original_state
        self._focus = None
コード例 #3
0
    def on_translation(self, old, new):

        # Check for new output.
        for a in reversed(new):
            if a.text and not a.text.isspace():
                break
        else:
            return

        # Get previous words equal to the maximum possible search result count.
        with self._engine:
            last_translations = self._engine.translator_state.translations
            retro_formatter = RetroFormatter(last_translations)
            split_words = retro_formatter.last_words(self._word_limit,
                                                     rx=self.WORD_RX)

        suggestion_list = []
        for phrase in self.tails(split_words):
            phrase = ''.join(phrase)
            suggestion_list.extend(self._engine.get_suggestions(phrase))

        if not suggestion_list and split_words:
            suggestion_list = [Suggestion(split_words[-1], [])]

        if suggestion_list and suggestion_list != self._last_suggestions:
            self._last_suggestions = suggestion_list
            self._show_suggestions(suggestion_list)
コード例 #4
0
    def on_translated(self, old, new):
        # Check for new output.
        for a in reversed(new):
            if a.text and not a.text.isspace():
                break
        else:
            return

        last_translations = self.engine.translator_state.translations
        retro_formatter = RetroFormatter(last_translations)
        split_words = retro_formatter.last_words(10, rx=WORD_RX)

        suggestion_list = []
        for phrase in tails(split_words):
            phrase = "".join(phrase)
            suggestion_list.extend(self.engine.get_suggestions(phrase))

        if suggestion_list:
            self.output(format_suggestions(suggestion_list))
コード例 #5
0
    def _on_translated(self, _old, new):
        if len(new) == 0:
            # true if the stroke is an undo stroke
            return

        with self.engine:
            last_translations = self.engine.translator_state.translations
            retro_formatter = RetroFormatter(last_translations)
            split_words = retro_formatter.last_words(10, rx=self.WORD_RX)

        # last few "phrases", e.g. "let's go", "'s go", "s go", "go"
        phrases = set(
            ("".join(split_words[i:]) for i in range(len(split_words))))
        # last translation in case it isn't shown exactly, e.g. "{#Return}{^}", {^ing}
        if len(last_translations) > 0:
            last_translation = last_translations[-1].english
            if last_translation is not None:
                phrases.add(escape_translation(last_translation))

        for phrase in phrases:
            for suggestion in self.engine.get_suggestions(phrase):
                self.card_suggestions.add_suggestion(suggestion)
コード例 #6
0
    def on_translation(self, old, new):

        # verify new output exists
        for a in reversed(new):
            if a.text and not a.text.isspace(): break
        else: return

        # check for optimality
        last = None
        for phrase in self.tails(
                self.engine.translator_state.translations[-10:]):
            english = ''.join(RetroFormatter(phrase).last_fragments(999))
            if english == last: continue
            last = english
            stroked = [y for x in phrase for y in x.rtfcre]
            suggestions = [
                y for x in self.engine.get_suggestions(english)
                for y in x.steno_list if len(y) < len(stroked)
            ]
            if suggestions:
                self.f.write(
                    f'[{datetime.now().strftime("%F %T")}] {english:15} || {"/".join(stroked)} -> {", ".join("/".join(x) for x in suggestions)}\n'
                )
                self.f.flush()
コード例 #7
0
    def __init__(self, engine, on_output, on_exit):
        self.engine = engine
        self.on_exit = on_exit
        self.on_output = on_output
        self.outcome = ""

        self.strokes_info = ""
        self.translation_info = ""
        # we start in the strokes field
        add_filter(engine)

        self.dicts = []
        for path in self.engine.dictionaries:
            d = self.engine.dictionaries[path]
            if not d.readonly:
                self.dicts.append(d)

        self.dict_index = 0

        picker_kb = KeyBindings()

        # FormattedTextControl can't have accept_handler bound
        @picker_kb.add("enter")
        def _(event):
            self.accept(None)

        @picker_kb.add("left")
        def _(event):
            target = self.dict_index - 1
            if target < 0:
                target = len(self.dicts) - 1
            self.dict_index = target

        @picker_kb.add("right")
        def _(event):
            target = self.dict_index + 1
            if target > len(self.dicts) - 1:
                target = 0
            self.dict_index = target

        self.dictionary_picker = Window(FormattedTextControl(
            focusable=True,
            text=lambda: f"{self.dicts[self.dict_index].path}",
            style="class:normal",
            key_bindings=picker_kb),
                                        height=1)

        self.strokes_field = TextArea(
            prompt="Strokes: ",
            height=1,
            multiline=False,
            wrap_lines=False,
            accept_handler=self.accept,
            style="class:normal",
        )

        self.strokes_field.buffer.on_text_changed += self.strokes_changed
        self.translation_field = TextArea(
            prompt="Output: ",
            height=1,
            multiline=False,
            wrap_lines=False,
            accept_handler=self.accept,
            style="class:normal",
        )

        self.translation_field.buffer.on_text_changed += self.translation_changed

        last_translations = engine.translator_state.translations
        retro_formatter = RetroFormatter(last_translations)
        last_words = retro_formatter.last_words(1)

        if last_words:
            self.translation_field.text = last_words[0].replace("\n",
                                                                "").rstrip()

        kb = KeyBindings()

        @kb.add("escape", eager=True)
        def _(event):
            layout = get_app().layout
            remove_filter(self.engine)
            self.outcome = "Add translation abandoned"
            self.update_output()
            on_exit()

        def focus(direction):
            layout = get_app().layout
            if direction == 'next':
                layout.focus_next()
            if direction == 'previous':
                layout.focus_previous()

            if layout.has_focus(self.strokes_field):
                add_filter(self.engine)
            else:
                remove_filter(self.engine)
            self.update_output()

        @kb.add("tab")
        def _(event):
            focus('next')

        @kb.add("s-tab")
        def _(event):
            focus('previous')

        self.container = HSplit(
            [
                self.dictionary_picker, self.strokes_field,
                self.translation_field
            ],
            key_bindings=kb,
        )
コード例 #8
0
    def on_stroke(self, stroke: Stroke):
        if self.started:
            raw_steno = ""
            tran_text = ""
            paragraph = ""
            keys = stroke.steno_keys[:]

            # Contains an array of the latest dictionary entry matches
            formatted = self.translations[
                -1].english if self.translations else []
            tran_text = formatted or ""

            # Loop through the inputted keys to format output. (I.e. with one key, include hyphen to know which it was)
            for key in keys:
                if len(keys) == 2 and key.find("-") != -1:
                    raw_steno += key[0] + key[1].replace("-", "")
                elif len(keys) > 2:
                    raw_steno += key.replace("-", "")
                else:
                    raw_steno += key

            if self._both_steno_realtime.isChecked():
                if self.printer is not None:
                    self._tape.appendPlainText(raw_steno + "\t\t" + tran_text)
                    self.left_right(self.printer, raw_steno, tran_text)

            elif self._raw_only.isChecked():
                self._tape.appendPlainText(raw_steno)

                try:
                    self.printer.text(raw_steno)
                    self.printer.text("\n")
                except:
                    self._tape.setPlainText(
                        "Printer is not connected or cannot establish communication."
                    )
                    self._connect.setEnabled(True)

            else:
                tran_text = self.translations[self.starting_point:]
                formatter = RetroFormatter(
                    self.translations[self.starting_point:]) or ""

                for word in formatter.last_words(-1):
                    paragraph += word

                    if word and word.find("\n" or "\r") > -1:
                        try:
                            self.printer.text(paragraph)
                            self.printer.text("\n\n")

                            # Make sure to reset the start pointer
                            self.starting_point = len(self.translations)
                            paragraph = ""

                        except:
                            self._tape.setPlainText(
                                "Printer is not connected or establish communication."
                            )
                            self._connect.setEnabled(True)

                self._tape.setPlainText(paragraph)