Customizing Orca

How do I define my own punctuation or character pronunciations?

Here's an example you can add to your ~/.orca/orca-customizations.py file. Be careful about the syntax -- if you screw it up, you might screw up Orca.

import orca.chnames
orca.chnames.chnames["'"] = "tick"
orca.chnames.chnames['"'] = "quote"
orca.chnames.chnames["!"] = "bang"

The basic idea is that orca.chnames.chnames is a dictionary where the keys are the characters you want to create a pronunciation for and the values are the pronunciation. Note that the above example provides two alternative mechanisms for the keys -- one uses double quote characters to allow you to embed single quotes inside the string, and the other uses single quote characters to allow you to embed double quotes in the string.

How do I define my own keybindings?

You can currently redefine your key bindings for Orca in two main ways. The first way is to be able to choose between the destkop and laptop layouts, which can be selected on the "General" page of the Orca Configuration GUI (press Insert+space to bring up the Orca preferences GUI). For finer-grained control, you can also redefine indivual key bindings on the "Key Bindings" page of the Orca Configuration GUI.

NOTE: the remainder of this answer might be out of date.

Here's an example you can add to your ~/.orca/user-settings.py file. It sets up a global keybinding for Insert+t (Insert is the Orca modifier) to speak and braille "Hello World."

# Set up custom keybindings.
#
import orca.braille
import orca.input_event
import orca.keybindings
import orca.orca
import orca.speech
from orca.orca_i18n import _
def sayHello(script, inputEvent=None):
    message = _("Hello World")
    # Say/braille something.
    #
    orca.speech.speak(message)
    orca.braille.displayMessage(message)
    # Consume the event so it will not go to an application.
    #
    return True
sayHelloHandler = orca.input_event.InputEventHandler(
    sayHello,
    _("Says hello to this fine world."))
myKeyBindings = orca.keybindings.KeyBindings()
myKeyBindings.add(orca.keybindings.KeyBinding(
    "t",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayHelloHandler))
orca.settings.keyBindingsMap["default"] = myKeyBindings

Customizing Orca To Speak/Braille Battery Status, Date, Time and Weather Information (scripting)

Notes

If you don't want to learn about scripting, if you only want to add a little extra functionality to Orca and want to skip the headache, then you want the orca-customizations.py file. It is the script used in this tutorial with the added capability of battery status reporting.

  • The keybindings are Orca-a battery status, Orca-d date, Orca-t time, and Orca-w weather.

Just change the line that says xipCode = 0 to match your zip/postal code and save the file as ~/.orca/orca-customizations.py Close and restart Orca and it should work as expected. I originally meant to try and teach the basics of Python in this tutorial. However, trying to do everything here would make this document incredibly long. So instead, I will give a link to an excellent Python tutorial. This is where I got my start. The link is: http://www.sthurlow.com/python/

Creating Scripts

There are two ways to go about this. For scripts to add global functionality such as time and date, battery status, weather, etc creating a file, ~/.orca/orca-customizations.py, will do the trick. Open a terminal, and type the following:

cd .orca
gedit orca-customizations.py

This will create the file if it doesn't exist already. The second way is to create your own custom script area. This is actually quite a bit easier than it sounds. To set up your custom script area, open a terminal if you haven't done so already and type the following commands.

cd .orca
mkdir orca-scripts
cd orca-scripts
touch __init__.py

There, you've done it! Your very own custom script area. Go ahead and celibrate, we'll wait... Now, for an explination of what was just done. cd .orca changes you to the .orca directory. It begins with a . because it is a hidden folder, so if you are in your home directory you won't know it is there unless you have view hidden directories on. Any file or folder that starts with a . is hidden. Just for reference, this is different from starting something with ./ which runs or executes a program. mkdir orca-scripts creates a new directory called orca-scripts. Just remember, mkdir equals make directory. cd orca-scripts Can you guess what this does? That's right, takes you into the orca-scripts directory. (2 points!) touch init.py is a neat command. It creates a file with nothing in it called, you guessed it, init.py. It's much easier than firing up your favorite text editor and navigating through a bunch of folders just to save a blank file. So, now that you have your very own custom script area, you may be wondering why you need such a thing. When a new program is loaded or gains focus, let's say Firefox for example, Orca searches several places to find out how it is supposed to handle the new program. In general, Orca is going to look for a script module whose name matches the name of the application in use. If that's not found, it's going to look for a module whose name matches the name of the toolkit in use. If that's not found, then it falls back to default.py. This can be changed by adding to settings._scriptMappings by calling settings.setScriptMapping. You can change the Firefox behavior by creating your own custom firefox.py script in the orca-scripts folder. This presents a special case though. IN the case of Firefox, you will most likely want to keep all of the abilities it has already like skip to next/previous heading etc. So, in your custom script, you will need to import orca.scripts.toolkits.Gecko in your script. Ok, if I haven't lost you so far, it gets easier, trust me. IN the next section I will give your brain as well as mine a chance to quit smoking. Let's write a script to add time functionality to Orca.

Time and Date

Most screen readers have a key combination that when pressed speaks the time and date. Orca, however, does not have this feature built in to it. No big deal though, we'll just roll our own. to get started, lets go to the .orca directory. To get to your .orca directory type:

cd ~/.orca
gedit orca-customizations.py

This will open up a new file in Gedit. You can use your text editor of choice instead of course. Enter the following lines in as they are shown. Remember that indentation is of upmost importants in Python. So, if two spaces appear at the beginning of the line here, they must also be at the beginning of the line in your script.

"""This script adds time functionality to Orca
Adapted by Storm Dragon from the script posted at:
http://wiki.gnome.org/Projects/Orca/FrequentlyAskedQuestions#head-6a8c1c2511ba01d7397f68f754eec0d923d166f1
feel free to modify and/or redistribute this script as you see fit."""
import orca.input_event # watches for input that Orca recognizes
import orca.keybindings # Handles binding keystrokes for Orca to use.
import orca.orca # Imports the main screen reader
import orca.speech # Handles Orca's speaking abilities
import orca.braille # Displays information in Braille format

myKeyBindings = orca.keybindings.KeyBindings()

#Define the sayTime function
def sayTime(script, inputEvent=None):
  import time # imports the Python time library
  message = time.strftime("%I:%M%p", time.localtime())
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  return True
#end sayTime function

sayTimeHandler = orca.input_event.InputEventHandler(
    sayTime,
    "Speaks and/or Brailles the time.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "t",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayTimeHandler)) # Sets Orca-t as the say time key

orca.settings.keyBindingsMap["default"] = myKeyBindings
#end time code

From the code above you can see that to work with speech you must import the speech library and to work with Braille, you must import the Braille library. The sayTime function is pretty straight forward. You first set the information you want to display in the message variable. Then, call the speech and Braille functions with the message you want spoken and/or Brailled. Be sure to remember to import the time library in this case or it won't work as expected. Some info about the time library. The line in the script that gives us our time message is:

message = time.strftime("%I:%M%p", time.localtime())

For our purposes, only the part inside the quote marks matters. The %I gives the hour in twelve hour format. The : appears as a normal :, nothing special about it. The %M displays the minutes, and because it is in twelve hour format, %p will let us know if it's evening or morning with an uppercase PM or AM. For reference, here are the choices available when setting up a time and/or date string.

Python Time Codes:

%a abbreviated weekday name.
%A full weekday name.
%b abbreviated month name.
%B full month name.
%d Date of the month (01 to 31)
%H Hour in 24-hour format (00 to 23)
%I Hour in 12-hour format (01,12)
%m Month number (01 to 12)
%M Minute (00 to 59)
%p AM or PM.
%S Second (00 to 59)
%y 2 digit year (00 to 99)
%Y 4 digit year.
%Z Time zone name.

For more information about Python's time library: http://www.python.org/doc/2.5.2/lib/module-time.html The lines after the function add the key press to the learn mode. This is always a good thing to do for completeness and for those trying to learn their way around. Next comes the line that actually maps the key press. In our case the key is Orca-t. That is to say, insert-t for desktop layout or capslock-t for laptop layout. Simply put, the last line of code:

orca.settings.keyBindingsMap["default"] = myKeyBindings

seals the bargain. Next, we will add more functionallity to our orca-customizations.py file and in so doing show that the more things change, the more they stay the same.

Adding Date to the Mix

Why have date and time as two seperate commands? Well, I guess it's personal preference. When I want the time I don't particularly care what the date is, and usually when I want the date I don't want the time tossed in to it. Pluss, they each feel more important if they get their own special attention from you. Actually, I think short messages are best and I am willing to put up with remembering more key presses to keep them short. IF you want the time and date in the same command, simply change the date string in the code in the previous section. The thing that stands out about this next script, is it is exactly the same as the first script. It has two functions instead of one, the second fuction is the same as the first the only thing changed is the time string. This time, it shows the date instead. There are 2 more lines added to add the key binding to learn mode and set the actual keys to press, in our case Orca-d. Here is the script:

"""This script adds time and date functionality to Orca
New in this script, time or date can be pasted from the clipboard
Adapted by Storm Dragon from the script posted at:
http://wiki.gnome.org/Projects/Orca/FrequentlyAskedQuestions#head-6a8c1c2511ba01d7397f68f754eec0d923d166f1
feel free to modify and/or redistribute this script as you see fit."""
import orca.input_event # watches for input that Orca recognizes
import orca.keybindings # Handles binding keystrokes for Orca to use.
import orca.orca # Imports the main screen reader
import orca.speech # Handles Orca's speaking abilities
import orca.braille # Displays information in Braille format

myKeyBindings = orca.keybindings.KeyBindings()

#Define the sayTime function
def sayTime(script, inputEvent=None):
  import time # imports the Python time library
  message = time.strftime("%I:%M%p", time.localtime())
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  return True
#end sayTime function

#Define the sayDate function
def sayDate(script, inputEvent=None):
  import time # imports the Python time library
  message = time.strftime("%A, %B %d, %Y", time.localtime())
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  return True
#end sayDate function

#Set up sayTime keys
sayTimeHandler = orca.input_event.InputEventHandler(
    sayTime,
    "Presents the time.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "t",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayTimeHandler)) # Sets Orca-t as the say time key

#add sayDate info
sayDateHandler = orca.input_event.InputEventHandler(
    sayDate,
    "Presents the date.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "d",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayDateHandler)) # Sets Orca-d as the say date key

orca.settings.keyBindingsMap["default"] = myKeyBindings
#end time and date code

As promised, this code is almost exactly the same as the one in the last section. If you go back and compare the two files you will notice that they both have exactly the same code with the only additions being the sayDate function and the extra key binding commands.

Extra Functionality

Now that you have the code to add speach and/or Braille as well as that necessary to add key bindings, all that is left is adding the scripts you want. Basically, more functions and imports. As a good example of what is possible let's build on our existing customizations.py. So far we can speak and Braille the current date and time. Perhaps, however, there are times when you would like to be able to add this information to a document. You can, of course, just type it in. What's the fun in that though? Also, the rules of laziness dictate that a quick key press should be used in this matter. So, let's take our time and date script and add the information spoken or Brailled to the clipboard. This way, once we have pressed orca-t for the time or orca-d for the date, we can press control-v to paste the provided information from the clipboard. Here's the code.

"""This script adds time and date functionality to Orca
New in this script, time or date can be pasted from the clipboard
Adapted by Storm Dragon from the script posted at:
http://wiki.gnome.org/Projects/Orca/FrequentlyAskedQuestions#head-6a8c1c2511ba01d7397f68f754eec0d923d166f1
feel free to modify and/or redistribute this script as you see fit."""
#import gets code that has already been written.
#think of it as using wheels instead of trying to reinvent them.
import orca.input_event # watches for input that Orca recognizes
import orca.keybindings # Handles binding keystrokes for Orca to use.
import orca.orca # Imports the main screen reader
import orca.speech # Handles Orca's speaking abilities
import orca.braille # Displays information in Braille format

#places text in the clipboard
def setClipboardText(text):
  import gtk # import the gtk library
  cb = gtk.Clipboard()
  cb.set_text(text)
  cb.store()

myKeyBindings = orca.keybindings.KeyBindings()

#Define the sayTime function
def sayTime(script, inputEvent=None):
  import time # imports the Python time library
  message = time.strftime("%I:%M%p", time.localtime())
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  setClipboardText(message)
  return True
#end sayTime function

#Define the sayDate function
def sayDate(script, inputEvent=None):
  import time # imports the Python time library
  message = time.strftime("%A, %B %d, %Y", time.localtime())
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  setClipboardText(message)
  return True
#end sayDate function

#Set up sayTime keys
sayTimeHandler = orca.input_event.InputEventHandler(
    sayTime,
    "Presents the time.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "t",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayTimeHandler)) # Sets Orca-t as the say time key

#add sayDate info
sayDateHandler = orca.input_event.InputEventHandler(
    sayDate,
    "Presents the date.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "d",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayDateHandler)) # Sets Orca-d as the say date key

orca.settings.keyBindingsMap["default"] = myKeyBindings
#end time and date code

Although new functionality was added, the ability to paste from the clipboard, the basic script is the exact same. We had to import the gtk library, but this was only for the setClipboardText function. Originally I had the import gtk statement at the end of all of the Orca imports. I got to thinking that the library was only necessary for the clipboard though so I put it in the setClipboardText function. This serves two purposes. First, it shows us that it's not necessary for the whole Orca script, only for the clipboard function. Second, functions are locally scoped. This means that things inside a function are only there while the function is in use. So, and I may be wrong about this, because we only import gtk when it is necessary, it should speed up the script by a few mili seconds. It doesn't sound like much, but every bit helps.

Adding Weather Information

IN this section I will show you how to get weather. The key binding is orca-w. This will present the current temperature | current conditions. For example 64 | mostly cloudy I really wanted to get this information from the top panel (where the clock is) but I couldn't find any information on accessing it. So, I did the next best thing. The weather info comes from Yahoo. This was a tricky piece of code, but after studying the developer documentation and writing and rewriting, I got it working. Here is the new script with documentation:

"""This script adds time and date functionality to Orca
New in this script, time or date can be pasted from the clipboard
Adapted by Storm Dragon from the script posted at:
http://wiki.gnome.org/Projects/Orca/FrequentlyAskedQuestions#head-6a8c1c2511ba01d7397f68f754eec0d923d166f1
feel free to modify and/or redistribute this script as you see fit."""
import orca.input_event # watches for input that Orca recognizes
import orca.keybindings # Handles binding keystrokes for Orca to use.
import orca.orca # Imports the main screen reader
import orca.speech # Handles Orca's speaking abilities
import orca.braille # Displays information in Braille format

#change the next line to your zip code:
zipCode = 28624

#places text in the clipboard
def setClipboardText(text):
  import gtk # import the gtk library
  cb = gtk.Clipboard()
  cb.set_text(text)
  cb.store()

#getWeather function gets weather from Yahoo
def getWeather(zip_code):
  if zip_code != 0:
    import urllib
    from xml.dom import minidom
    WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
    WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'
    url = WEATHER_URL % zip_code
    dom = minidom.parse(urllib.urlopen(url))
    ycondition = dom.getElementsByTagNameNS(WEATHER_NS, 'condition')[0]
    weatherReport = ycondition.getAttribute('temp') + ' | ' + ycondition.getAttribute('text')
  else:
    weatherReport = "No zip code set: Please edit .orca/orca-customizations.py"
  return weatherReport

myKeyBindings = orca.keybindings.KeyBindings()

#Define the sayTime function
def sayTime(script, inputEvent=None):
  import time # imports the Python time library
  message = time.strftime("%I:%M%p", time.localtime())
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  setClipboardText(message)
  return True
#end sayTime function


#Define the sayDate function
def sayDate(script, inputEvent=None):
  import time # imports the Python time library
  message = time.strftime("%A, %B %d, %Y", time.localtime())
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  setClipboardText(message)
  return True
#end sayDate function

#Define the sayWeather function
def sayWeather(script, inputEvent=None):
  message = getWeather(zipCode)
  orca.speech.speak(message)
  orca.braille.displayMessage(message)
  return True
#end sayWeather function

#Set up sayTime keys
sayTimeHandler = orca.input_event.InputEventHandler(
    sayTime,
    "Presents the time.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "t",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayTimeHandler)) # Sets Orca-t as the say time key

#add sayDate info
sayDateHandler = orca.input_event.InputEventHandler(
    sayDate,
    "Presents the date.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "d",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayDateHandler)) # Sets Orca-d as the say date key

#add sayWeather info
sayWeatherHandler = orca.input_event.InputEventHandler(
    sayWeather,
    "Get current temperature and conditions.") # Shows the function of the key press in learn mode

myKeyBindings.add(orca.keybindings.KeyBinding(
    "w",
    1 << orca.settings.MODIFIER_ORCA,
    1 << orca.settings.MODIFIER_ORCA,
    sayWeatherHandler)) # Sets Orca-d as the say date key

orca.settings.keyBindingsMap["default"] = myKeyBindings
#end time, date, and weather code

Once again, the code is basically the same. The only new additions are the sayWeather function which should seem awfully familiar, and the getWeather function which was quite interesting to write. This script is getting kind of long wouldn't you say? So, in the next section, let's tidy things up a bit.

Tidying Up

As you have probably noticed, this orca-customizations.py file can get rather long in a hurry. Never fear though, import to the rescue. It is possible to write your scripts in seperate files and use import to import them into your orca-customizations.py script. So, for example, if you took all of the code for the weather and placed it into a file called weather.py in your .orca directory, you would then use: import weather This, in theory, will import the weather code from weather.py and because it is now in your orca-customizations.py file, it will work as expected. You can do pretty much anything you want with your orca-customizations.py file. The only thing you really are required to have is the keybinding. As long as you follow the pattern above, everything should be ok. Good luck, and happy scriptin!

How do I set up my own custom script area?

The short answer is that if you create an empty ~/.orca/orca-scripts/__init__.py and place your custom scripts in ~/.orca/orca-scripts, Orca will pick up any scripts from there before looking in the installed area.

}}}


The information on this page and the other Orca-related pages on this site are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


CategoryAccessibility

Projects/Orca/FrequentlyAskedQuestions/CustomizingOrca (last edited 2013-12-28 15:28:31 by WilliamJonMcCann)