Thursday, February 23, 2006

Emacspeak: Connecting Lynx And W3

Emacs/W3 is still the best Web page rendering option inside Emacspeak given the ability to apply XSL transforms, as well as obtaining aural styling via ACSS. However W3's url handling layer often breaks when faced with multiple redirects, especially when some of these happen through the Host: HTTP header. Additionally, HTTPS authentication sometimes fails mysteriously in the presence of redirects.

In many of these cases, lynx happily fetches the pages correctly; however you're then stuck using a fairly weak auditory interface in that Emacspeak degrades to being aterminal level screenreader.

An effective solution to this problem is to use lynx within an Emacs terminal, and after finding the content that is worth reading, handing off that content to Emacs/W3. The next few paragraphs show how.

The lynx-site.cfg File

This is where you add site-specific configurations. Here are the lines I have in my lynx-site.cfg to integrate lynx and Emacs. Before you use any of this, make sure you have executed M-x server-start in your running Emacs, and make sure that all is well by experimenting with emacsclient to ensure that external programs can hand-off editting tasks to the currently running Emacs.

#site defaults
#for bookshare:
DOWNLOADER:BKS Unpack:bks.pl  %s %s:TRUE 
PRINTER:Edit:emacsclient %s:TRUE
KEYMAP:???:EDITTEXTAREA	# use external editor to edit a form textarea
PRETTYSRC:TRUE
SOURCE_CACHE:MEMORY
SAVE_SPACE:~/.wget/
BOLD_HEADERS:TRUE
PRINTER:W3:emacsclient -e '(w3-open-local "%s")':TRUE

Below, I'll describe what each of the above lines do:

  • DOWNLOADER:BKS Unpack:bks.pl %s %s:TRUE
    The above line creates an additional item in the download menu that invokes the BookShare unpacker. Script bks-unpack.pl invokes the BookShare unpack tool with the appropriate options.
  • PRINTER:Edit:emacsclient %s:TRUE
    This creates an Edit item in the print menu. Invoking this menu item causes the current page to be handed off to Emacs for editting. If you want to edit the source, first switch to source view by hitting \ before invoking print.
  • KEYMAP:???:EDITTEXTAREA # use external editor to edit a form textarea
    This sets lynx up so that when editting a multiline textarea, you can hand off the editting job to Emacs. This is particularly useful for editting Wiki pages. Replace the ?? with the desired key sequence.
  • PRETTYSRC:TRUE
    SOURCE_CACHE:MEMORY

    The above two settings make the edit source functionality more pleasant to use.
  • PRINTER:W3:emacsclient -e '(w3-open-local "%s")':TRUE
    The above creates a W3 menu item in the print menu. Invoking this causes Emacs/W3 to display the current page --- again switch to source view before invoking this so that Emacs/W3 gets handed the HTML markup.

Script bks-unpack.pl

#!/usr/bin/perl -w
#$Id: bks.pl,v 1.1 2003/07/04 15:41:55 tvraman Exp tvraman $
#Description: Bookshare downloader for Lynx
use strict;
my $location="$ENV{HOME}/books/book-share";
my $password = 'xxxxxxx';
my $grabbed = shift;
my $target = shift;
my $dir =qx(basename $target .bks);
chomp $dir;
my $where = "$location/$dir";
qx(mkdir -p $where);
qx(mv $grabbed  $where/$target);
chdir $where;
qx(echo $password | bks-unpack -q $target 1>&- 2>&- &);

Tuesday, February 21, 2006

Emacspeak, SuDoKu And History

Here is a small enhancement to playing SuDoKu in Emacspeak. The feature is probably generally useful i.e., it's not specific to eyes-free interaction, but its presence encourages one to try different solution strategies.

Commands emacspeak-sudoku-history-push bound to m and emacspeak-sudoku-history-pop bound to M allow one to mark interesting states in the game and return to these prior states with a single keystroke. This means that when one is confronted with one of two choices, with no apparent additional information on which route to take, it becomes possible to push that state on to the history stack, try one of the alternatives and backtrack if necessary.

Monday, February 20, 2006

Emacspeak And Voice Locking Using Aural CSS

This is slightly reformatted from what was posted to the Emacspeak mailing list as separate message.

  1. Emacspeak defines a number of voice overlays such as voice-bolden, and voice-lighten that can be applied to a given voice to change what it sounds like.
  2. Voice overlays are defined in terms of Aural CSS (ACSS) to keep them independent of a specific TTS engine.
  3. For each such overlay there is a corresponding <overlay-name>-settings variable that can be customized via custom.
  4. The numbers in voice-bolden-settings as an example:
Setting Value
family nil
average-pitch 1
pitch-range 6
stress 6
richness nil
punctuation nil
Unset values (nil) show up as "unspecified" in the customize interface.
  1. Do not directly customize voice-bolden and friends, instead customize the corresponding voice-bolden-settings, since that ensures that all voices that are defined in terms of voice-bolden get correctly updated.
  2. Discovering what to customize:

Command emacspeak-show-personality-at-point (bound by default to C-e M-v) will show you the value of properties personality and face at point. A recent update I implemented last weekend makes this more useful, so make sure you do a CVS update; earlier this command used to display the ACSS setting --- now it displays the abstract name. Describe-variable on these names should tell you what to customize; so as an example:

Put point on a comment line, and hit C-e M-v: you will hear

Personality emacspeak-voice-lock-comment-personality
Face font-lock-comment-delimiter-face

Describe-variable of emacspeak-voice-lock-comment-personality gives:

emacspeak-voice-lock-comment-personality's value is acss-p0-s0-all

Documentation:
Personality used for font-lock-comment-face
This personality uses  voice-monotone whose  effect can be changed globally by customizing voice-monotone-settings.

How It All Works

Here is a brief explanation of the connection between voice-bolden and its associated voice-bolden-settings.

  1. Voice settings are initially in voice-bolden-settings which is a list of numbers.
  2. That list of numbers needs to be translated to appropriate device-specific codes to send to the TTS engine.
  3. You do not want to do this translation each time you speak something.
  4. So when voice-bolden is defined, the definition happens in two steps:
  • The list of settings is stored away in voice-bolden-settings,
  • A corresponding voice-name is generated --- acss-a<n>-p<n>-r<n>-s<n> and the corresponding control codes to send to the device are stored away in a hash-table keyed by the above symbol.
  • Finally, voice-bolden is assigned the above symbol.

What this gives is:

  1. The ability to customize the voice via custom by editting the list of numbers in voice-bolden-settings
  2. When that list is editted, voice-bolden is arranged to be updated automatically.

Other Useful Commands

In addition, commands emacspeak-wizards-generate-voice-sampler can be useful in generating a buffer that shows what the various ACSS settings sound like. Command emacspeak-wizards-voice-sampler can be used to apply a specific voice to a region of text while experimenting with the various settings.

Saturday, February 11, 2006

Playing SuDoKu Using Auditory Feedback

Emacspeak speech-enables SuDoKu implemented by sudoku.el. Speech-enabling games is an effective means of discovering what additions one needs to make to an auditory interface for working effectively in an eyes-free environment --- this was aptly demonstrated a few years ago by identifying interesting conversational gestures by speech-enabling the game of Tetris --- see Conversational Gestures For The Audio Desktop from Assets 1998.

Advicing Interactive Commands

As with speech-enabling any Emacs module, emacspeak-sudoku advices all interactive commands to produce spoken feedback. In addition to speaking the cell moved to, all navigation commands produce an auditory icon that is a function of whether the cell value is mutable --- original values cannot be changed and this is indicated with a distinctive icon.

Additional Interactive Commands

Playing SuDoKu effectively requires one to build a good mental image of the state of the board as well as the ability to effectively query the game for currently active constraints. The eye's ability to quickly move around the board and perceive row, column and sub-square constraints needs to be compensated for in an eyes-free environment. As an example, it is too difficult to build the necessary mental model by just listening to the board spoken aloud, or by listening to idnividual cells by navigating to them.

Here are the set of additional interactive commands that needed to be added in order to be able to play the game effectively.

r
Speak current row.
c
Speak current column
s
Speak current sub-square.
R
Speak number of remaining cells in current row.
C
Speak number of remaining cells in current column.
S
Speak number of remaining cells in current sub-square.
d
Move to the sub-square below the current sub-square.
u
Move to the sub-square above the current sub-square.
n
Move to the next sub-square.
p
Move to the previous sub-square.
a
Move to the beginning of current row.
e
Move to the end of the current row.
t
Move to the top of the current column.
b
Move to the bottom of the current column.
,
Speaks information about the overall distribution of numbers on the board.
  • d --- Conveys how many instances of each digit have been filled in.
  • s --- Conveys number of remaining cells in each sub-square.
  • r --- Conveys number of remaining cells in each row.
  • c --- Conveys number of remaining cells in each column.
/
Speaks number of remaining cells in the current board.
.
Speaks value in current cell.

Notes on how invormation is spoken:

  • Numbers are spoken in groups of 3 to achieve effective intonation.
  • When navigating by sub-squares, point always moves to the top left corner of the sub-square.
  • Additional commands bound to M-r, M-c and M-s erase the current row, column or sub-square respectively. These commands would probably be convenient to have independent of whether one is using visual output.

Effectiveness Of The Resulting Interface

With the above interface in place, the simpler levels of the game are a breeze, levels difficult and evil are sufficiently challenging to be fun.