From 5bc1ec169bb8f437ca726f911c83273fd70ab3e7 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Fri, 16 Aug 2019 09:42:32 -0500 Subject: [PATCH] Updated grammars --- _html_grammar.py | 7 +- _multiedit.py | 282 +++++++++++++++++++++++++++++++++ _namingcon.py | 2 - vocabulary_config/enabled.json | 1 + 4 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 _multiedit.py create mode 100644 vocabulary_config/enabled.json diff --git a/_html_grammar.py b/_html_grammar.py index 923437b..080c12c 100644 --- a/_html_grammar.py +++ b/_html_grammar.py @@ -41,11 +41,11 @@ class HTMLTags(MappingRule): "line break": Text( "
" ), "image": Text( "" ), "equals": Text( "=" ), - " tags": Text("<%(tagname)s>") ,#+ Text(""), + " kick": Text("<%(tagname)s>") ,#+ Text(""), # used to specify tag attributes - "attribute": Text( ' attributeName=""' ) + Key( "left" ), - "attribute ": Text( ' %(attribute)s=""' ) + Key( "left" ), + "attribute": Text( ' attributeName=""' ) + Key( "left" ), + " attribute": Text( ' %(attribute)s=""' ) + Key( "left" ), } @@ -57,6 +57,7 @@ class HTMLTags(MappingRule): "title": "title", "SRC": "src", "HREF": "href", + "type": "type" } ), Choice("tagname", { diff --git a/_multiedit.py b/_multiedit.py new file mode 100644 index 0000000..c3150c4 --- /dev/null +++ b/_multiedit.py @@ -0,0 +1,282 @@ +# +# This file is a command-module for Dragonfly. +# (c) Copyright 2008 by Christo Butcher +# Licensed under the LGPL, see +# + +""" +Command-module for cursor movement and **editing** +============================================================================ + +This module allows the user to control the cursor and +efficiently perform multiple text editing actions within a +single phrase. + + +Example commands +---------------------------------------------------------------------------- + +*Note the "/" characters in the examples below are simply +to help the reader see the different parts of each voice +command. They are not present in the actual command and +should not be spoken.* + +Example: **"up 4 / down 1 page / home / space 2"** + This command will move the cursor up 4 lines, down 1 page, + move to the beginning of the line, and then insert 2 spaces. + +Example: **"left 7 words / backspace 3 / insert hello Cap world"** + This command will move the cursor left 7 words, then delete + the 3 characters before the cursor, and finally insert + the text "hello World". + +Example: **"home / space 4 / down / 43 times"** + This command will insert 4 spaces at the beginning of + of this and the next 42 lines. The final "43 times" + repeats everything in front of it that many times. + + +Discussion of this module +---------------------------------------------------------------------------- + +This command-module creates a powerful voice command for +editing and cursor movement. This command's structure can +be represented by the following simplified language model: + + - *CommandRule* -- top-level rule which the user can say + - *repetition* -- sequence of actions (name = "sequence") + - *KeystrokeRule* -- rule that maps a single + spoken-form to an action + - *optional* -- optional specification of repeat count + - *integer* -- repeat count (name = "n") + - *literal* -- "times" + +The top-level command rule has a callback method which is +called when this voice command is recognized. The logic +within this callback is very simple: + +1. Retrieve the sequence of actions from the element with + the name "sequence". +2. Retrieve the repeat count from the element with the name + "n". +3. Execute the actions the specified number of times. + +""" + +try: + import pkg_resources + pkg_resources.require("dragonfly >= 0.6.5beta1.dev-r99") +except ImportError: + pass + +from dragonfly import * + + +#--------------------------------------------------------------------------- +# Here we globally defined the release action which releases all +# modifier-keys used within this grammar. It is defined here +# because this functionality is used in many different places. +# Note that it is harmless to release ("...:up") a key multiple +# times or when that key is not held down at all. + +release = Key("shift:up, ctrl:up") + + +#--------------------------------------------------------------------------- +# Set up this module's configuration. + +config = Config("multi edit") +config.cmd = Section("Language section") +config.cmd.map = Item( + # Here we define the *default* command map. If you would like to + # modify it to your personal taste, please *do not* make changes + # here. Instead change the *config file* called "_multiedit.txt". + { + # Spoken-form -> -> -> Action object + "up []": Key("up:%(n)d"), + "down []": Key("down:%(n)d"), + "left []": Key("left:%(n)d"), + "right []": Key("right:%(n)d"), + "page up []": Key("pgup:%(n)d"), + "page down []": Key("pgdown:%(n)d"), + "up (page | pages)": Key("pgup:%(n)d"), + "down (page | pages)": Key("pgdown:%(n)d"), + "left (word | words)": Key("c-left:%(n)d"), + "right (word | words)": Key("c-right:%(n)d"), + "home": Key("home"), + "end": Key("end"), + "doc home": Key("c-home"), + "doc end": Key("c-end"), + + "space []": release + Key("space:%(n)d"), + "enter []": release + Key("enter:%(n)d"), + "tab []": Key("tab:%(n)d"), + "delete []": release + Key("del:%(n)d"), + "delete [ | this] (line|lines)": release + Key("home, s-down:%(n)d, del"), + "backspace []": release + Key("backspace:%(n)d"), + "pop up": release + Key("apps"), + + "paste": release + Key("c-v"), + "duplicate ": release + Key("c-c, c-v:%(n)d"), + "copy": release + Key("c-c"), + "cut": release + Key("c-x"), + "select all": release + Key("c-a"), + "[hold] shift": Key("shift:down"), + "release shift": Key("shift:up"), + "[hold] control": Key("ctrl:down"), + "release control": Key("ctrl:up"), + "release [all]": release, + + "say ": release + Text("%(text)s"), + "mimic ": release + Mimic(extra="text"), + }, + namespace={ + "Key": Key, + "Text": Text, + } +) +namespace = config.load() + +#--------------------------------------------------------------------------- +# Here we prepare the list of formatting functions from the config file. + +# Retrieve text-formatting functions from this module's config file. +# Each of these functions must have a name that starts with "format_". +format_functions = {} +if namespace: + for name, function in namespace.items(): + if name.startswith("format_") and callable(function): + spoken_form = function.__doc__.strip() + + # We wrap generation of the Function action in a function so + # that its *function* variable will be local. Otherwise it + # would change during the next iteration of the namespace loop. + def wrap_function(function): + def _function(dictation): + formatted_text = function(dictation) + Text(formatted_text).execute() + return Function(_function) + + action = wrap_function(function) + format_functions[spoken_form] = action + + +# Here we define the text formatting rule. +# The contents of this rule were built up from the "format_*" +# functions in this module's config file. +if format_functions: + class FormatRule(MappingRule): + + mapping = format_functions + extras = [Dictation("dictation")] + +else: + FormatRule = None + + +#--------------------------------------------------------------------------- +# Here we define the keystroke rule. + +# This rule maps spoken-forms to actions. Some of these +# include special elements like the number with name "n" +# or the dictation with name "text". This rule is not +# exported, but is referenced by other elements later on. +# It is derived from MappingRule, so that its "value" when +# processing a recognition will be the right side of the +# mapping: an action. +# Note that this rule does not execute these actions, it +# simply returns them when it's value() method is called. +# For example "up 4" will give the value Key("up:4"). +# More information about Key() actions can be found here: +# http://dragonfly.googlecode.com/svn/trunk/dragonfly/documentation/actionkey.html +class KeystrokeRule(MappingRule): + + exported = False + + mapping = config.cmd.map + extras = [ + IntegerRef("n", 1, 100), + Dictation("text"), + Dictation("text2"), + ] + defaults = { + "n": 1, + } + # Note: when processing a recognition, the *value* of + # this rule will be an action object from the right side + # of the mapping given above. This is default behavior + # of the MappingRule class' value() method. It also + # substitutes any "%(...)." within the action spec + # with the appropriate spoken values. + + +#--------------------------------------------------------------------------- +# Here we create an element which is the sequence of keystrokes. + +# First we create an element that references the keystroke rule. +# Note: when processing a recognition, the *value* of this element +# will be the value of the referenced rule: an action. +alternatives = [] +alternatives.append(RuleRef(rule=KeystrokeRule())) +if FormatRule: + alternatives.append(RuleRef(rule=FormatRule())) +single_action = Alternative(alternatives) + +# Second we create a repetition of keystroke elements. +# This element will match anywhere between 1 and 16 repetitions +# of the keystroke elements. Note that we give this element +# the name "sequence" so that it can be used as an extra in +# the rule definition below. +# Note: when processing a recognition, the *value* of this element +# will be a sequence of the contained elements: a sequence of +# actions. +sequence = Repetition(single_action, min=1, max=16, name="sequence") + + +#--------------------------------------------------------------------------- +# Here we define the top-level rule which the user can say. + +# This is the rule that actually handles recognitions. +# When a recognition occurs, it's _process_recognition() +# method will be called. It receives information about the +# recognition in the "extras" argument: the sequence of +# actions and the number of times to repeat them. +class RepeatRule(CompoundRule): + + # Here we define this rule's spoken-form and special elements. + spec = " [[[and] repeat [that]] times]" + extras = [ + sequence, # Sequence of actions defined above. + IntegerRef("n", 1, 100), # Times to repeat the sequence. + ] + defaults = { + "n": 1, # Default repeat count. + } + + # This method gets called when this rule is recognized. + # Arguments: + # - node -- root node of the recognition parse tree. + # - extras -- dict of the "extras" special elements: + # . extras["sequence"] gives the sequence of actions. + # . extras["n"] gives the repeat count. + def _process_recognition(self, node, extras): + sequence = extras["sequence"] # A sequence of actions. + count = extras["n"] # An integer repeat count. + for i in range(count): + for action in sequence: + action.execute() + release.execute() + + +#--------------------------------------------------------------------------- +# Create and load this module's grammar. + +grammar = Grammar("multi edit") # Create this module's grammar. +grammar.add_rule(RepeatRule()) # Add the top-level rule. +grammar.load() # Load the grammar. + +# Unload function which will be called at unload time. +def unload(): + global grammar + if grammar: grammar.unload() + grammar = None diff --git a/_namingcon.py b/_namingcon.py index d7d7a0a..3af658f 100644 --- a/_namingcon.py +++ b/_namingcon.py @@ -10,8 +10,6 @@ Command module for programming variable naming conventions from dragonfly import * - - # helper function handling "camelBack" def camel_back(command): someString = str(command) diff --git a/vocabulary_config/enabled.json b/vocabulary_config/enabled.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vocabulary_config/enabled.json @@ -0,0 +1 @@ +{} \ No newline at end of file