diff --git a/_angularjs_grammar.py b/_angularjs_grammar.py
index 77b3028..6389040 100644
--- a/_angularjs_grammar.py
+++ b/_angularjs_grammar.py
@@ -2,18 +2,22 @@
# This script includes commands that are to be used for Angular programming
from dragonfly import (Grammar, CompoundRule, Dictation, RuleRef, DictList, DictListRef, Text, Key, AppContext, MappingRule, Function, Sequence, Mimic)
+import win32com.client
+speaker = win32com.client.Dispatch("SAPI.SpVoice")
def doSomethingToCommand(command):
newCommand = Sequence(command)
newCommand.execute()
class AngularEnabler(CompoundRule):
- spec = "Activate Angular JS" # Spoken form of command.
+ spec = "Activate Angular" # Spoken form of command.
def _process_recognition(self, node, extras): # Callback when command is spoken.
AngularBootstrap.disable()
AngularGrammar.enable()
- print "Angular JS grammar enabled"
+ s = "Angular JS grammar activated"
+ print s
+ speaker.Speak(s)
class AngularDisabler(CompoundRule):
spec = "switch language" # Spoken form of command.
@@ -21,11 +25,12 @@ class AngularDisabler(CompoundRule):
def _process_recognition(self, node, extras): # Callback when command is spoken.
AngularGrammar.disable()
AngularBootstrap.enable()
- print "Angular JS grammar disabled"
-
+ s = "Angular JS grammar deactivated"
+ print s
+ speaker.Speak(s)
class AngularTestRule(CompoundRule):
- spec = "test Angular JS" # Spoken form of command.
+ spec = "test Angular" # Spoken form of command.
def _process_recognition(self, node, extras): # Callback when command is spoken.
print "Angular JS grammar tested"
@@ -35,7 +40,9 @@ class AngularControlStructures(MappingRule):
mapping = {
"variable": Text("var "),
"function": Text("function functionName() {") + Key("enter")+ Key("enter"), #+ Text("}"),
- "self function": Text("(function() {") + Key("enter")+ Key("enter"), #+ Text("}())"),
+ "self function": Text("(function() {") + Key("enter") + Key("enter"), #+ Text("}())"),
+ "for each": Text("angular.forEach( , function(o) {") + Key("enter") + Key("enter") + Text("});") + Key("up"), #+ Key("up"),
+ "timeout": Text("$timeout(function() {") + Key("enter") + Key("enter") + Text("}, 100);") + Key("up"), #+ Key("up"),
"code block": Text("{") + Key("enter")+ Key("enter"), #+ Text("}"),
"if": Text("if() {") + Key("enter")+ Key("enter"), #+ Text("}"),
"if else": Text("if() {") + Key("enter")+ Key("enter") + Text("}") + Key("enter") + Text("else {") + Key("enter")+ Key("enter"), #+ Text("}"),
diff --git a/_custom_globals.py b/_custom_globals.py
index fcbf93a..23082cc 100644
--- a/_custom_globals.py
+++ b/_custom_globals.py
@@ -19,7 +19,7 @@ class UsefulStuff(MappingRule):
"enter|slap": Key("enter"),
"east": Key("end"),
"west": Key("home"),
-
+ "format": Key("ctrl") + Key("alt") + Key("b"),
}
globalStuff = Grammar("useful custom global commands") # Create a grammar to contain the command rule.
diff --git a/_explorer_tools.py b/_explorer_tools.py
new file mode 100644
index 0000000..f5ff5ed
--- /dev/null
+++ b/_explorer_tools.py
@@ -0,0 +1,246 @@
+#
+# This file is a command-module for Dragonfly.
+# (c) Copyright 2008 by Christo Butcher
+# Licensed under the LGPL, see
+#
+
+"""
+Command-module to control **Windows Explorer**
+============================================================================
+
+This module defines various voice-commands for use with Windows Explorer.
+
+.. note::
+
+ This module is still under development.
+
+Installation
+----------------------------------------------------------------------------
+
+If you are using DNS and Natlink, simply place this file in you Natlink
+macros directory. It will then be automatically loaded by Natlink when
+you next toggle your microphone or restart Natlink.
+
+"""
+
+try:
+ import pkg_resources
+ pkg_resources.require("dragonfly >= 0.6.5beta1.dev-r76")
+except ImportError:
+ pass
+
+import os.path
+import string
+import subprocess
+import time
+from urllib import unquote
+from dragonfly import (ConnectionGrammar, AppContext, CompoundRule,
+ Choice, Window, Config, Section, Item)
+
+
+#---------------------------------------------------------------------------
+
+class SingleFile(object):
+
+ def __init__(self, spec, command_line):
+ self.spec = spec
+ self.command_line = command_line
+
+ def execute(self, paths, directory):
+ for path in paths:
+ self.execute_single(path, directory)
+
+ def execute_single(self, path, directory):
+ data = {"path": path, "dir": directory}
+ arguments = [s % data for s in self.command_line]
+ print "Arguments: %r" % arguments
+ process = subprocess.Popen(arguments, stdout=subprocess.PIPE)
+ out, err = process.communicate()
+ print "Output:"; print out and out.strip()
+ print "Error:"; print err and err.strip()
+
+
+class MultiFile(object):
+
+ def __init__(self, spec, command_line_pre, command_line_post):
+ self.spec = spec
+ self.command_line_pre = command_line_pre
+ self.command_line_post = command_line_post
+
+ def execute(self, paths, directory):
+ data = {"dir": directory}
+ arguments_pre = [s % data for s in self.command_line_pre]
+ arguments_post = [s % data for s in self.command_line_post]
+ arguments = arguments_pre + paths
+ if arguments_post:
+ arguments += arguments_post
+
+ print "Arguments: %r" % arguments
+ process = subprocess.Popen(arguments, stdout=subprocess.PIPE)
+ out, err = process.communicate()
+ print "Output:"; print out and out.strip()
+ print "Error:"; print err and err.strip()
+
+
+class CreateArchiveHere(object):
+
+ def __init__(self, spec, extension):
+ self.spec = spec
+ self.extension = extension
+
+ def execute(self, paths, directory):
+ archive_path = os.path.splitext(os.path.basename(paths[0]))[0]
+ archive_path = os.path.join(directory, archive_path)
+ archive_path += time.strftime("-%y%m%d")
+
+ def filenames(basename, extension):
+# yield basename + extension
+ for letter in string.lowercase:
+ yield basename + letter + extension
+
+ available = False
+ for archive_path in filenames(archive_path, self.extension):
+ if not os.path.exists(archive_path):
+ available = True
+ break
+ if not available:
+ print "Warning: could not create archive."
+ return
+
+ arguments = [r"C:\Program Files\7-Zip\7z.exe", "a"]
+ arguments.append("-o" + directory)
+ arguments.append(archive_path)
+# arguments.append(os.path.splitext(archive_path)[0])
+ arguments.extend(paths)
+
+ print "Arguments: %r" % arguments
+ process = subprocess.Popen(arguments, stdout=subprocess.PIPE)
+ out, err = process.communicate()
+ print "Output:"; print out and out.strip()
+ print "Error:"; print err and err.strip()
+
+class RenameFile(object):
+
+ python_path = r"C:\Python25\python.exe"
+ rename_dialog_path = os.path.join(os.path.dirname(__file__),
+ "dialog_rename.py")
+
+ def __init__(self, spec):
+ self.spec = spec
+
+ def execute(self, paths, directory):
+ if len(paths) == 0:
+ print "Rename file error: nothing selected."
+ return
+ path = paths[0]
+
+ arguments = [self.python_path, self.rename_dialog_path, path]
+ subprocess.Popen(arguments)
+
+
+#---------------------------------------------------------------------------
+
+commands = [
+ SingleFile("open with ultra [edit]",
+ [r"C:\Program Files\IDM Computer Solutions\UltraEdit\Uedit32.exe", "%(path)s"]),
+ MultiFile("scan for (virus | viruses) | virus scan",
+ [r"C:\Program Files\F-Secure\Anti-Virus\fsav.exe"], ["/list"]),
+ SingleFile("extract archive here",
+ [r"C:\Program Files\7-Zip\7z.exe", "x", "-o%(dir)s", "%(path)s"]),
+ CreateArchiveHere("create zip archive here", ".zip"),
+ CreateArchiveHere("create [7] archive here", ".7z"),
+ RenameFile("rename file dialog"),
+ ]
+
+
+#---------------------------------------------------------------------------
+# Utility generator function for iterating over COM collections.
+
+def collection_iter(collection):
+ for index in xrange(collection.Count):
+ yield collection.Item(index)
+
+
+#---------------------------------------------------------------------------
+# This module's main grammar.
+
+class ControlGrammar(ConnectionGrammar):
+
+ def __init__(self):
+ ConnectionGrammar.__init__(
+ self,
+ name="Explorer control",
+ context=AppContext(executable="explorer"),
+ app_name="Shell.Application"
+ )
+
+ def get_active_explorer(self):
+ handle = Window.get_foreground().handle
+ for window in collection_iter(self.application.Windows()):
+ if window.HWND == handle:
+ return window
+ self._log.warning("%s: no active explorer." % self)
+ return None
+
+ def get_selected_paths(self):
+ window = self.get_active_explorer()
+ items = window.Document.SelectedItems()
+ paths = []
+ for item in collection_iter(items):
+ paths.append(item.Path)
+ print "Selected paths: %r" % paths
+ return paths
+
+ def get_selected_filenames(self):
+ paths = self.get_selected_paths()
+ return [os.path.basename(p) for p in paths]
+
+ def get_current_directory(self):
+ window = self.get_active_explorer()
+ path = window.LocationURL[8:]
+ if path.startswith("file:///"):
+ path = path[8:]
+ return unquote(path)
+
+grammar = ControlGrammar()
+
+
+#---------------------------------------------------------------------------
+
+class ListSelectionRule(CompoundRule):
+ spec = "list current selection"
+ def _process_recognition(self, node, extras):
+ print "Current selection:"
+ for filename in self.grammar.get_selected_filenames():
+ print " - %r" % filename
+
+grammar.add_rule(ListSelectionRule())
+
+
+#---------------------------------------------------------------------------
+
+class CommandRule(CompoundRule):
+
+ spec = "[command] "
+ extras = [Choice("command", dict((c.spec, c) for c in commands))]
+
+ def _process_recognition(self, node, extras):
+ command = extras["command"]
+ paths = self.grammar.get_selected_paths()
+ directory = self.grammar.get_current_directory()
+ print "Selected paths: %r" % paths
+ command.execute(paths, directory)
+
+grammar.add_rule(CommandRule())
+
+
+#---------------------------------------------------------------------------
+# Load the grammar instance and define how to unload it.
+
+grammar.load()
+
+# Unload function which will be called by natlink at unload time.
+def unload():
+ global grammar
+ if grammar: grammar.unload()
+ grammar = None
diff --git a/_firefox.py b/_firefox.py
new file mode 100644
index 0000000..4c60d42
--- /dev/null
+++ b/_firefox.py
@@ -0,0 +1,354 @@
+#
+# This file is a command-module for Dragonfly.
+# (c) Copyright 2008 by Christo Butcher
+# Licensed under the LGPL, see
+#
+
+"""
+Command-module for **Firefox**
+============================================================================
+
+This module offers direct control of the `Firefox
+`_ web browser. It
+requires the `mouseless-browsing
+`_
+(mlb) add-on for reliable access to hyperlinks.
+
+This module includes direct searching using Firefox's
+search bar and Firefox's keyword searching. It also
+allows single-utterance submitting of text into form text
+fields.
+
+Installation
+----------------------------------------------------------------------------
+
+If you are using DNS and Natlink, simply place this file in you Natlink
+macros directory. It will then be automatically loaded by Natlink when
+you next toggle your microphone or restart Natlink.
+
+Customization
+----------------------------------------------------------------------------
+
+Users should customize this module by editing its
+configuration file. In this file they should edit the
+``search.searchbar`` and ``search.keywords`` settings to
+match their own personal search preferences. These
+variables map *what you say* to which *search engines* to
+use.
+
+"""
+
+try:
+ import pkg_resources
+ pkg_resources.require("dragonfly >= 0.6.5beta1.dev-r76")
+except ImportError:
+ pass
+
+from dragonfly import *
+
+
+#---------------------------------------------------------------------------
+# Set up this module's configuration.
+
+config = Config("Firefox control")
+config.search = Section("Search-related section")
+config.search.keywords = Item(
+ default={
+ "wikipedia": "wikipedia",
+ },
+ doc="Mapping of spoken-forms to Firefox search-keywords.",
+ )
+config.search.searchbar = Item(
+ default=[
+ "google",
+ "yahoo",
+ "amazon",
+ "answers",
+ "creative commons",
+ "eBay",
+ "wikipedia",
+ ],
+ doc="Spoken-forms of search engines in the Firefox search-bar; they must be given in the same order here as they are available in Firefox.",
+ )
+
+config.lang = Section("Language section")
+config.lang.new_win = Item("new (window | win)")
+config.lang.new_tab = Item("new (tab | sub)")
+config.lang.close_tab = Item("close (tab | sub)")
+config.lang.close_tab_n = Item("close (tab | sub) ")
+config.lang.close_n_tabs = Item("close (tabs | subs)")
+config.lang.address_bar = Item("address [bar]")
+config.lang.copy_address = Item("copy address")
+config.lang.paste_address = Item("paste address")
+config.lang.search_bar = Item("search bar")
+config.lang.go_home = Item("go home")
+config.lang.stop_loading = Item("stop loading")
+config.lang.toggle_tags = Item("toggle tags")
+config.lang.fresh_tags = Item("fresh tags")
+config.lang.caret_browsing = Item("(caret | carrot) browsing")
+config.lang.bookmark_page = Item("bookmark [this] page")
+config.lang.save_page_as = Item("save [page | file] as")
+config.lang.print_page = Item("print [page | file]")
+config.lang.show_tab_n = Item("show tab ")
+config.lang.back = Item("back []")
+config.lang.forward = Item("forward []")
+config.lang.next_tab = Item("next tab []")
+config.lang.prev_tab = Item("(previous | preev) tab []")
+config.lang.normal_size = Item("normal text size")
+config.lang.smaller_size = Item("smaller text size []")
+config.lang.bigger_size = Item("bigger text size []")
+config.lang.find = Item("find")
+config.lang.find_text = Item("find ")
+config.lang.find_next = Item("find next []")
+
+config.lang.submit = Item("submit")
+config.lang.submit_text = Item("submit ")
+config.lang.submit_clipboard = Item("submit (clipboard | clip board)")
+config.lang.link_open = Item("[link] [open]")
+config.lang.link_save = Item("save [link] [as]")
+config.lang.link_save_now = Item("save [link] now now")
+config.lang.link_select = Item("[link] select")
+config.lang.link_menu = Item("[link] (menu | pop up)")
+config.lang.link_force = Item("[link] force")
+config.lang.link_window = Item("[link] [in [new]] window")
+config.lang.link_tab = Item("[link] [in [new]] tab")
+config.lang.link_copy = Item("[link] copy")
+config.lang.link_copy_into_tab = Item("[link] copy into tab")
+config.lang.link_list = Item("[link] list")
+config.lang.link_submit = Item("[link] submit")
+config.lang.link_submit_text = Item("[link] submit ")
+config.lang.link_submit_clipboard = Item("[link] submit (clipboard | clip board)")
+config.lang.link_dictation_box = Item("edit [link] ")
+config.lang.link_assign_keyword = Item("assign [a] keyword to [link] ")
+config.lang.tabify_links = Item("tab if I ")
+config.lang.tabify_links_sep = Item("comma")
+
+config.lang.search_text = Item("[power] search [for] ")
+config.lang.search_keyword_text = Item("[power] search [for] ")
+config.lang.search_searchbar_text = Item("[power] search [for] ")
+config.lang.search_clipboard = Item("[power] search [for] (clipboard | clip board)")
+config.lang.search_keyword_clipboard = Item("[power] search [for] clipboard")
+config.lang.search_searchbar_clipboard = Item("[power] search [for] clipboard")
+
+#config.generate_config_file()
+config.load()
+
+
+#---------------------------------------------------------------------------
+# Check and prepare search-related config values.
+
+keywords = config.search.keywords
+searchbar = dict([(n,i) for i,n in enumerate(config.search.searchbar)])
+
+
+#---------------------------------------------------------------------------
+# Create the rule to match mouseless-browsing link numbers.
+
+class LinkRule(Rule):
+
+ def __init__(self):
+ element = Number(zero=True)
+ Rule.__init__(self, "link_rule", element, exported=False)
+
+ def value(self, node):
+ # Format and return keystrokes to select the link.
+ digits = str(node.children[0].value())
+ link_keys = "f6,s-f6," + ",".join(["numpad"+i for i in digits])
+ self._log.debug("Link keys: %r" % link_keys)
+ return link_keys
+
+link = RuleRef(name="link", rule=LinkRule())
+
+
+#---------------------------------------------------------------------------
+# Create the main command rule.
+
+class CommandRule(MappingRule):
+
+ mapping = {
+ config.lang.new_win: Key("c-n"),
+ config.lang.new_tab: Key("c-t"),
+ config.lang.close_tab: Key("c-w"),
+ config.lang.close_tab_n: Key("0, %(n)d, enter/20, c-w"),
+ config.lang.close_n_tabs: Key("c-w/20:%(n)d"),
+ config.lang.address_bar: Key("a-d"),
+ config.lang.copy_address: Key("a-d, c-c"),
+ config.lang.paste_address: Key("a-d, c-v, enter"),
+ config.lang.search_bar: Key("c-k"),
+ config.lang.go_home: Key("a-home"),
+ config.lang.stop_loading: Key("escape"),
+ config.lang.toggle_tags: Key("f12"),
+ config.lang.fresh_tags: Key("f12, f12"),
+ config.lang.caret_browsing: Key("f7"),
+ config.lang.bookmark_page: Key("c-d"),
+ config.lang.save_page_as: Key("c-s"),
+ config.lang.print_page: Key("c-p"),
+
+ config.lang.show_tab_n: Key("0, %(n)d, enter"),
+ config.lang.back: Key("a-left/15:%(n)d"),
+ config.lang.forward: Key("a-right/15:%(n)d"),
+ config.lang.next_tab: Key("c-tab:%(n)d"),
+ config.lang.prev_tab: Key("cs-tab:%(n)d"),
+
+ config.lang.normal_size: Key("a-v/20, z/20, r"),
+ config.lang.smaller_size: Key("c-minus:%(n)d"),
+ config.lang.bigger_size: Key("cs-equals:%(n)d"),
+
+ config.lang.submit: Key("enter"),
+ config.lang.submit_text: Text("%(text)s") + Key("enter"),
+ config.lang.submit_clipboard: Key("c-v, enter"),
+
+ config.lang.find: Key("c-f"),
+ config.lang.find_text: Key("c-f") + Text("%(text)s"),
+ config.lang.find_next: Key("f3/10:%(n)d"),
+
+ config.lang.link_open: Key("%(link)s, enter"),
+ config.lang.link_save: Key("%(link)s, shift/10, apps/20, k"),
+ config.lang.link_save_now: Key("%(link)s, shift/10, apps/20, k")
+ + WaitWindow(title="Enter name of file")
+ + Pause("20") + Key("enter"),
+ config.lang.link_select: Key("%(link)s, shift"),
+ config.lang.link_menu: Key("%(link)s, shift/10, apps"),
+ config.lang.link_force: Key("%(link)s, shift/10, enter"),
+ config.lang.link_window: Key("%(link)s, shift/10, apps/20, w"),
+ config.lang.link_tab: Key("%(link)s, shift/10, apps/20, t"),
+ config.lang.link_copy: Key("%(link)s, shift/10, apps/20, a"),
+ config.lang.link_copy_into_tab: Key("%(link)s, shift/10, apps/20, a/10, c-t/20, c-v, enter"),
+ config.lang.link_list: Key("%(link)s, enter, a-down"),
+ config.lang.link_submit: Key("%(link)s, enter/30, enter"),
+ config.lang.link_submit_text: Key("%(link)s, enter/30")
+ + Text("%(text)s") + Key("enter"),
+ config.lang.link_submit_clipboard: Key("%(link)s, enter/30, c-v, enter"),
+ config.lang.link_dictation_box: Key("%(link)s, enter/30, cs-d"),
+ config.lang.link_assign_keyword: Key("%(link)s, enter/10, apps/20, k"),
+
+ config.lang.search_text: Key("c-k")
+ + Text("%(text)s") + Key("enter"),
+ config.lang.search_searchbar_text: Key("c-k, c-up:20, c-down:%(searchbar)d")
+ + Text("%(text)s") + Key("enter"),
+ config.lang.search_keyword_text: Key("a-d")
+ + Text("%(keyword)s %(text)s")
+ + Key("enter"),
+ config.lang.search_clipboard: Key("c-k, c-v, enter"),
+ config.lang.search_searchbar_clipboard: Key("c-k, c-up:20, c-down:%(searchbar)d, c-v, enter"),
+ config.lang.search_keyword_clipboard: Key("a-d") + Text("%(keyword)s")
+ + Key("c-v, enter"),
+ }
+ extras = [
+ link,
+ IntegerRef("n", 1, 20),
+ Dictation("text"),
+ Choice("keyword", keywords),
+ Choice("searchbar", searchbar),
+ ]
+ defaults = {
+ "n": 1,
+ }
+
+
+#---------------------------------------------------------------------------
+# Create the command rule for sliding.
+
+slide_directions = {
+ "up": (0,-1),
+ "down": (0,+1),
+ }
+slide_speeds = {
+ "1": 10,
+ "2": 20,
+ "3": 30,
+ "4": 40,
+ }
+slide_default_speed = 15
+slide_start_spec = "(-15,0.6)"
+
+slide_grammar = None
+
+def start_sliding(direction, speed):
+ offset_x = direction[0] * speed
+ offset_y = direction[1] * speed
+ offset_spec = "<%d,%d>" % (offset_x, offset_y)
+ action = Key("escape")
+ action.execute()
+ action = Mouse("%s/25, middle/25, %s" % (slide_start_spec, offset_spec))
+ action.execute()
+
+ global slide_grammar
+ if not slide_grammar:
+ slide_grammar = Grammar("Firefox slide grammar")
+ slide_grammar.add_rule(SlideControlRule())
+ slide_grammar.load()
+ slide_grammar.set_exclusive(True)
+
+def stop_sliding():
+ action = Key("escape")
+ action.execute()
+
+ global slide_grammar
+ if slide_grammar:
+ slide_grammar.set_exclusive(False)
+ slide_grammar.unload()
+ slide_grammar = None
+
+class SlideStartRule(MappingRule):
+
+ mapping = {
+ "slide []": Function(start_sliding),
+ }
+ extras = [
+ Choice("direction", slide_directions),
+ Choice("speed", slide_speeds),
+ ]
+ defaults = {
+ "speed": slide_default_speed,
+ }
+
+
+class SlideControlRule(MappingRule):
+
+ mapping = {
+ "[slide] []": Function(start_sliding),
+ "[slide] stop": Function(stop_sliding),
+ }
+ extras = [
+ Choice("direction", slide_directions),
+ Choice("speed", slide_speeds),
+ ]
+ defaults = {
+ "speed": slide_default_speed,
+ }
+
+
+#---------------------------------------------------------------------------
+# Create the main command rule.
+
+class TabifyRule(CompoundRule):
+
+ spec = config.lang.tabify_links
+ sep_element = Compound(config.lang.tabify_links_sep)
+ repeat_element = Sequence([sep_element, link])
+ repetitions = Repetition(child=repeat_element, min=0, max=8)
+ extras = [Sequence(name="links", children=(link, repetitions))]
+
+ def _process_recognition(self, node, extras):
+ link_nodes = node.get_children_by_name("link")
+ for n in link_nodes:
+ action = Key(n.value()) + Key("shift/10, apps/20, t/20")
+ action.execute()
+
+
+#---------------------------------------------------------------------------
+# Create and load this module's grammar.
+
+context = AppContext(executable="firefox")
+grammar = Grammar("firefox_general", context=context)
+grammar.add_rule(CommandRule())
+grammar.add_rule(SlideStartRule())
+grammar.add_rule(TabifyRule())
+grammar.load()
+
+# Unload function which will be called by natlink at unload time.
+def unload():
+ global grammar
+ if grammar: grammar.unload()
+ grammar = None
diff --git a/_html_grammar.py b/_html_grammar.py
index 080c12c..8a4a7cd 100644
--- a/_html_grammar.py
+++ b/_html_grammar.py
@@ -1,4 +1,5 @@
-# Author:Brandon Lovrien
+# Author: Jeremy Hayes
+# Modified from: Brandon Lovrien version
# This script includes commands used for HTML coding
from dragonfly import (Grammar, CompoundRule, Dictation, Text, Key, AppContext, MappingRule, Choice)
@@ -57,7 +58,9 @@ class HTMLTags(MappingRule):
"title": "title",
"SRC": "src",
"HREF": "href",
- "type": "type"
+ "type": "type",
+ "value": "value",
+
}
),
Choice("tagname", {
@@ -101,7 +104,7 @@ class HTMLTags(MappingRule):
"H1": "h1",
"H2": "h2",
"H3": "h3",
- "H4": "h4",
+ "(header 4 |H4)": "h4",
"H5": "h5",
"H6": "h6",
"head": "head",
diff --git a/_javascript_grammar.py b/_javascript_grammar.py
index af2d665..aef32a7 100644
--- a/_javascript_grammar.py
+++ b/_javascript_grammar.py
@@ -40,7 +40,12 @@ class JavaScriptControlStructures(MappingRule):
mapping = {
"variable": Text("var "),
- "console": Text("console.log();"),
+ "true": Text("true"),
+ "false": Text("false"),
+ "model": Text("model."),
+ "console": Text("console.log();") + Key("left") + Key("left"),
+ "parse Float": Text("parseFloat();") + Key("left") + Key("left"),
+ "parse INT": Text("parseInt();") + Key("left") + Key("left"),
"function": Text("function functionName() {") + Key("enter")+ Key("enter"), #+ Text("}"),
"variable function": Text("functionName = function () {") + Key("enter")+ Key("enter"), #+ Text("}"),
"self function": Text("(function() {") + Key("enter")+ Key("enter"), #+ Text("}())"),
@@ -101,6 +106,7 @@ class JavaScriptAssignmentOperators(MappingRule):
"multiply equals": Text("*="),
"divide equals": Text("/="),
"modulus equals": Text("%="),
+ "modulus": Text("%"),
}