Debugging with Speech: Issues and Work-arounds?

  • Thread starter Veli-Pekka Tätilä
  • Start date
V

Veli-Pekka Tätilä

Hi,
I'm just discovering the Perl debugger, and contrary to my initial
expectations as a GUI-guy, I seem to like it after a while. ONe indirect
reason for this is the fact that only one GUI-element can have the focus at
a time. So as a legally blind screen reader user, any fancy docking views or
logs are no good in a graphical debugger. The reason, the keyboard and
screen reader focus can be only on a single control at a time so there's no
good way to merely glance at the screen contents. Speech is also a linear
output medium in which you cannot navigate backwords or skip around in real
time apart from moving the keyboard or screen readder focus. So a
command-line debugger for a visually impaired (or vi) user is pretty much
like the GUI equivalent but provides a more minimal and on-demand type of
interface.

There are some problems with the Perl debugger from an accessibility, speech
user, point of view which I'd like to briefly point out here. Don't get me
wrong, I've seen apps that do much worse but this being Perl, I'd be
interested in trying to customize the debugger or workaround these issues in
some other way. Also, all this is written from a screen reader user's point
of view, most sighted designers of console or GUI apps take their eyes and
mice for granted. On the other hand, graphical debuggers can be quite
keyboard inaccessible, or require the use of heavy full-screen magnification
which is even slower personally.

Though the problems may seem marginal at first, actually working with speech
in any longer debugging session reveals this is not the case. I'm using XP
and a beta of Dolphin Supernova here but you could try the yasr reader in
Linux, without the monitor of course, to see how it is like. Jaws or
WindowEyes will do just as well, of which Windows demos are available.

When it comes to the debug commands, consider the stepping first. Here's a
sample from a recent script of mine:

main::(taskman.plx:4): focusToRunning();
DB<1>

In a conventional GUI reader working in a console, which is how most Mac and
WIndows readres are like, the reader will usually read the new console
contents when you hit enter. THis flow is linear and the only thing you can
do to affect it is stopping it. Many readers also provide their own
cursor-like navigation, irrespective of the consoel cursor, but this feature
is still char, word and line oriented and doesn't support regular
expressions in any reader I've seen.

So the above prompt would be read in its entirety with the package, script
and line number pre-pended before the code , which I usually consider the
most important. While the file and package info is great initially, it is
mostly redundant after the first reading, cannot be skipped and slows down
getting the rest of the information. The two major principles here would be
having the most important stuff, the code line, first and minimizing
redundant information by not redisplaying info that the user can ask for or
is supposed to know. Alternatively, you can put the redundant bits last so
they can be skipped by interrupting speech.

The debugger prompt can actually be much worse if you happen to visit
someone else's package:

Win32::GuiTest::FindWindowLike(C:/Perl/site/lib/Win32/GuiTest.pm:434):
434: my $hWndStart = shift || GetDesktopWindow(); # Where to start
DB<1>

This time rattling through the path and the package name takes several
seconds, even at speeds over 300 words per minute. There are some other
aspects that are worth considering. The colons can be interpreted funnily
with some speech synths such as Dolphin Orpheus. If they aren't read out
loud, they add long pauses which cascade, further lengthening the wait.
While colons for a long and commas for a short pause can be used to
structure speech output, the pause is all too long for package names.
Ideally they could be whitespace separated to add no delay but to tell the
reader that it should deal with the parts as separate words. The debugger
prompt DB is slightly redundant, too, I would change it to a greater than
sign.

The line and command numbers aren't as useful as for the sighted, either,
and could be removed. Besides the line number appears twice and both
instances are read. I rarely use the history mechanism directly for the
commands. As to the lines, there's no easy way to see the larger context all
at once. Sure you can print out a window of code with v as in:

433 sub FindWindowLike {
434==> my $hWndStart = shift || GetDesktopWindow(); # Where to start
435: my $windowre = shift; # Regexp
436: my $classre = shift; # Regexp
<snip>

However, the code must be cursored through in textual units like lines or
words. Without the find command or good markers, you would also have to find
the right line by listening to the beginning of the numbers until they match
the one you are looking for. This is true of simple console readers or the
kind of GUI readers in which the console is just another app. Even when you
do find the line, you cannot easily skip the numbers in the beginning of
lines or move the focus between the debugger output and the code listing,
without some heavy marker trickery. Here I can see two underlying design
considerations. Firstly, the screen reader sees only a single very small bit
of the screen at a time which is commonly called the straw analogy (you can
also think of it as a tiny viewport). The second is that unless you know
hotkeys or the app in advance, most keyboard navigation is essentially
sequential and text can only be navigated mechanically in simple units.

Though data structures are mostly printed very nicely, arrays could do with
some improvements. e.g:

DB<1> x a..z
0 'a'
1 'b'
2 'c'
3 'd'
<snip>

Indeces are great if you have to depend on them but say for a stack like
instance, just getting the count and a comma separated list of elements as
in Python or Java would fit the bill better. Again part of the problem are
the screen readers themselves. That is, they cannot skip the initial indeces
and cannot be trained to do so, much as I'd like to.

Well, the other features I thought I'd deal with here are stack traces and
watch expressions. However, they aren't that problematic to begin with and
their primary issues have already been identifiedd so I'll skip them. I
should mention that one extra issue is telling app prompts apart from the
text printed by the debugger. You can do it by context but the sudden prints
often surprise me and again there's no bullet proof way of skipping to the
next debugger prompt in a screen reader.

As the last example here, I'd like to mention the h command for help. While
the debug man page is pretty nice the help screen can look quite confusing
to a GUI reader.

List/search source lines: Control script execution:
l [ln|sub] List source code T Stack trace
- or . List previous/current line s [expr] Single step [in expr]
v [line] View around line n [expr] Next, steps over subs
<snip>

The problem is that the reader doesn't recognize the multi-column layout and
reads it in units of lines from column one till the line break. There are no
commas or other things that would render to pauses in speech so the commands
are badly run together. The only sensible way to decode the output in once
head would be to cursor through it by word, again manually. Also, while this
would be more relevant to OT affairs like ls, notice that most readers will
always read columns from left to right so the order does matter. So the
first one should be the most varying, often needed or uniquely identifying
column. As to the help screen, I wish an optional single-column layout could
be used. Identifying the issue, one shouldn't rely on a screen reader's
ability to break info into columns or read indents, unless some good
semantic info is available (i.e. in a formatted or tagged document).

Now that I've covered the issues, I'd like to ask for help in solving them.

The very first things that came to mind were to use a graphical debugger or
an editor that integrates well to Perl. The graphical debuggers I've read
about are based on X or TK. The latter is horribly keyboard inaccessible and
none of the GUI frameworks in the former seem to be accessible on Windows
using Active Accessibility. Even Gnome 2 is not, as far as I can tell. The
only accessible GUI lib I know of is Win32, with Swing and FireFox based
solutions requiring reader additions or extra components. As for the editor
situation, it is not exactly bright either. WinVi works almost good enough
to be truely accessible but I'm not sure if it can integrate with Perl. I'm
currently using NoteTab Pro taking advantage of its goto line and regexp
features for quick navigation, plus the tabs of course. Most Vi or Emacs
Win32 ports I've seen have serious issues with focus tracking due to custom
cursors, or are totally console based and poorly supported by GUI readers.
GUI readers can only properly read the semantics and structure of Win32 and
Swing applications. An ASCII check box is just punctuation to them and again
none I know can be trained at this level. Heck even app-specific
interpretation for punctuation is a no-can-do.

Lastly even if I would get EmacsSpeak working either in Win32 or Cygwin it
would not, as far as I know, be able to interface with SAPI synths in
Windows. As I've been using this particular speech synth in Finnish and US
English for about seven years now, switching to something else would mean a
huge speed and intelligibility drop at least initially. I don't think too
highly of Festival, see my speech synth page, and neither do I have a
hardware synth.

The second option that occurred to me was to customize the debugger. I've
browsed through the perldebug man page but for the life of me cannot find
any commands that would let me re-order output as outlined above, or even
make the debugger much less verbose. I did, however, find some hooks that
let me execute code prior to or right after the debugging prompts. If it was
somehow possible to get the debugger text in these hooks, i guess I could
filter it with regular expressions. The debugger can output most lines in a
file, too, but I cannot think of easy means of reading it on update and
displaying the info appropriately snipped and re-arranged.

The last option, I think, would be to hack or rewrite the debugger. If it is
possible, I'd much rather filter the debugger output using some other
program, or patch and eval code in memory, as opposed to physically touching
the debugger code or even making a copy of it. I've been reading bits of the
perldebguts man page and while some hooks seem clean and simple, there are
passages that totally beat me. Still I reckon it might not be awfully
difficult to get a very bearbones debugger up and running, I reckon.
However, if the existing debugger can cleanly offer the various chunks in
the output, it would be redundant for me to reverse-engineer how to pull the
pieces apart. I must confess I have merely taken a very brief look at the
debugger source just to see how it is like rather than to truely grasp it,
if you know what I mean, <grin>.

Well it seems to be more than 2 am here local time so I'll stop right here.
Hope this might be an enlightening read and doesn't ccome across as merely
nagging. For more info on usability principles and screen reading, you could
take a look at my accessibility section.

PS: Before I forget, I'm running Active Perl 5.8.7 here.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Veli-Pekka Tätilä
main::(taskman.plx:4): focusToRunning();
DB<1> ....
So the above prompt would be read in its entirety with the package, script
and line number pre-pended before the code , which I usually consider the
most important. While the file and package info is great initially, it is
mostly redundant after the first reading,

.... unless it changes.
reader that it should deal with the parts as separate words. The debugger
prompt DB is slightly redundant, too

.... unless you debug a program which shows its own prompt...
However, the code must be cursored through in textual units like lines or
words. Without the find command or good markers, you would also have to find
the right line by listening to the beginning of the numbers until they match
the one you are looking for.

Not clear: who is "without the find command or good markers"? What is
the problem with using DB's "/"?
This is true of simple console readers or the
kind of GUI readers in which the console is just another app. Even when you
do find the line, you cannot easily skip the numbers in the beginning of
lines or move the focus between the debugger output and the code listing,
without some heavy marker trickery. Here I can see two underlying design
considerations. Firstly, the screen reader sees only a single very small bit
of the screen at a time which is commonly called the straw analogy (you can
also think of it as a tiny viewport). The second is that unless you know
hotkeys or the app in advance, most keyboard navigation is essentially
sequential and text can only be navigated mechanically in simple
units.

I do not understand what is your point here...
Now that I've covered the issues

I do not think so. You got some "big picture" in, but it is too big.
I think a short summary of the problems as you see them would make
things much more grokable.
The second option that occurred to me was to customize the debugger.

You will find that this should be very easy. I would hope that most
of the functionality you complain about is concentrated in about 3
lines of Perl - the debugger is not particularly smart...

[Unfortunately, at some moment in the past the debugger code got
peppered with wrong-or-trivial comments. Nowadays there is no way
to distinguish "old, cryptic, but trustworthy" from the "new
improved" one; the only solution I know is to disregard all the
comments, and read the code itself.]

Yours,
Ilya
 
V

Veli-Pekka Tätilä

Ilya said:
... unless it changes.
That is true, that's why I said mostly redundant. I guess I should write a
filter which only shows such things when the previous output is not equal to
the current one.
The debugger prompt DB is slightly redundant, too
... unless you debug a program which shows its own prompt...
Umm yes, silly me. Well at least I'd still like to kill the command number
and angle brackets in it as I don't need them and they are read unless one
stops the speech.
Not clear: who is "without the find command or good markers"?
A big lot of screen reader users. Most primitive console readers lack these
features I think. MAny GUi readers include the find command but it is a bit
impractical to use and doesn't support regular expressions or even
meta-characters for line breaks. I think some of the more advanced readers
such as Jaws for WIndows do have the markers for quikc and direct focus
changes. AS far as I know, my reader and magnifier of choice, Dolphin
Supernova, however, does not have this feature.
What is the problem with using DB's "/"?
That command works fine. My point was that it is stil not very straight
forward to browse through lines of code with the debugger if you happen to
be using a GUI reader. But as I said the code listing is not really any of
the big issues, as I can browse the code in my text editor. Totally without
the line numbers and more freely than using screen reader specific virtual
focus.
I do not understand what is your point here...
Well this is more to do with GUI apps, I think, but there are some lessons
that are relevant here. FIrst off, as I said you cannot train screen readers
in detail to read the information out of order so the problem must be fixed
in the debugger end. Secondly, the sighted can randomly access any part of
the screen or browse through code quickly and selectively. This is next to
impossible with a screen reader. Most movement when using the virtual focus
or a text editor is essentially sequential and apart from matching text,
you'll have to repetitively use commands like next line, word or char to
control the reading process. THough the reader tracks the cursor, its
reading is linear, left to right and you cannot easily skip anything in the
stream. Lastly, my account might be even too detailed for the scope of the
post, simply because I'm naturally interested in accessibility. My bad I
guess said:
I think a short summary of the problems as you see them would make
things much more grokable.
It is remarkably difficult unless you've used a screen reader before. A
concrete demo would be nice, but as I canot do it live, here are the
relevant screen reader prompts. I only use a handful of the screen reader
commands, as most of them are hard to recall or slow to lookup, so this
might not be the most efficient way. This intro is a lean subset of
Supernova usage relevant to consoel applications alone.

Here's some simple sample code for the debugging:

# Redundant sample code.
use strict; use warnings;
my @nums = 1..100;
my @mapped = map {2 * $_} @nums;
for my $num (@mapped)
{
print "$num\n";
} # for

Firstly, the screen reader normally tracks the cursor for focus changes and
only reads new information when you hit enter. So, say I'll start
single-stepping on line one. I would get the following output automatically
on hitting enter.

main colon <beep indicating repetition> <pause> left paren demo dot plx
colon four right paren colon my at mapped equals map left brace two star
dollar underline right brace at nums semicolon <pause> D B less than one
greater than.

Notice that case differences are gone, the screen reader cannot structure
the output meaningfully, you have no idea of white space and the whole
package prompt is read before the relevant code itself. The only way to
interact with this output is to mute it.

Say I missed what's exactly inside the map block. I cannot take advantage of
SUpernova's cursor tracking for reading, simply because the cursor canot
reach the source code. In stead, I'll have to use a screne reader specific
navigation mode, called virtual focus, to get the screne reader's focus near
the code.

So I hit f4 to initiate virtual focus:

[f4] virtual focus c colon back slash windows back slash <snip> maximize
button close button title bar

Oh, this is the title bar. Now I'd need to move the virtual focus to where I
was. I don't know how to route it to where the physical cursor is, so the
two choices I have are finding and cursoring around. The find command isn't
too practical. Typing in [f4, ctrl+f3, map, <enter>] does get the virtual
focus in the right line but rather than the current word it reads the whole
line. To find out what's going on I'll need to cursor right along the line
in units of words, which causses the word on the left side of the cursor to
be read.

The alternative is to just cursor around the screen. To find the line using
this latter method, is about hitting the down arrow many times:

[down] loading # aha not this one so.
[down] editor # nah
[holding down] bottom
[up] db less than one greater than console # here's the cursor but the code.
[up] main colon # this is it but it is going to read the whole line so.
[ctrl+right] main colon # this is the first word so the next one .
[ctrl+right] my
[ctrl+right] at mapped
equals
map left brace two # this is it, the expression.

So this is what I ment when I said that only a bit of the screen can be seen
at a time. The practical effects are quite devastating compared to even a
dumb terminal. A sighted user could simply glance at the code. I'll have to
put in some effort to find the line in the first place. Further more, though
the find looks briefer, I don't use it as much as I should because it is
limited and lctrl+f3, enter is a lot slower to hit than just f3 in a text
editor. The text editor is a good tool if the doc is long and besides the
editor commands are not tied to a particular screen reader.

The cursoring method is not all that slow, as you can hold down the arrows
and only listen to the very beginning of lines to know that they aren't the
one you'd like to find. Even if I knew it would be the 20th lien, though, I
could not directly move to it with a goto or repeated down command like you
can in a good text editor. Most screen readers don't implement power-user
commands like this, and the concept of virtual focus is screen reader
specific. Fortunately virtual focus remembres your previous position in the
window so you don't always have to cursor around that many lines to find the
desired one. I guess this example serves to illustrate how prompts can be on
the way, if you'd just like to get the important bits read automatically on
an enter press.

Next, suppose I'd liek to examine the 0..9 slice of the @mapped array to see
what numbers went in there. As I already know the index range, I'd rather
not be told them at all or would want indeces printed only when ($index %
$n) == 0.

Here's how the slice is read when you hit enter, though:

zero one two four three six four eight five ten <snip> twenty db less than
nine greater than.

Here you see the linear left-to-right reading order in action. The column
mode is a GUI-only thing for Supernova, so it reads all indeces and their
values interlieved in a very difficult fashion. The last value and the db
prompt are run together, too.

Again a sighted person could just decide he or she doesn't want to see the
indeces, only the data, but this is not trivial with a screen reader.
Entering virtual focus:

[f4] virtual focus <pause> db less than 8 greater than x at mapped # Aha
this is the last debugger line.
[down] 0 2 # first row.
1 4 # second row.
etc...

is manigible but it is still difficult to omit the indeces. I reckon a
sighted person could decide not to pay attention to the left-most column at
all. You could swap the columns in the debugger output, though, to make the
index available but optional. However, this format would be suboptimal if
you do want to find out the indeces right away.

I've just realized that Perl already has nice devices for presenting the
data in the desired format. I've only used debugger's for statically typed
languages so the ability to execute any statement on the fly didn't occur to
me.

A nicer representation of the array could be gotten with:

p join(', ', @mapped[0..9])

If one turns off punctuation, the commas are translated to pauses. Similarly
if the indeces are desired, the folowing statements could be run

my $i = 0
for(@mapped[0..9]) { print("$i\t$_\n"), $i++ }

Yet another thing that sighted can do but which is hard with a screen reader
is filtering columns by common characteristics. But again finding say every
item ending with 0 is pretty easy if you grep a little:

print "$_ " for( grep{ /0$/ } @mapped)

Sadly these kind of power-user reformatting features aren't available in any
screen reader I've seen. Perl can help only as long as it can print the
data. As far as filtering goes, it would be real nice to get the same effect
for the listed source lines. So that you could use a regexp search to home
in on the map expression, in the example I had earlier. But anyway, as far
as convenient printing of the data structures goes, seems Perl shines here
as it is interpreted.

lastly, one situation in which markers to which you can route the virtual
focus would be highly useful are in comparing distant lines. If there are
many lines between the two to be compared, you'll always have to re-find the
line or cursor over the lines in between to be able to do comparisons of any
kind. As Supernova doesn't support markers for these transitions, the
easiest option I've discoverd is to copy the bits to be cmpared in different
buffers in the text editor. Each buffer recalls its cursor position so
switching between the lines is just a matter of pressing ctrl+tab.
would hope that most of the functionality you complain about is
concentrated in about 3
lines of Perl - the debugger is not particularly smart...
Yes, I think so, too, and that's why I considered undertaking such a
challenge. I'd need to implement redundancy filtering but a general solution
is pretty easy.
improved" one; the only solution I know is to disregard all the
comments, and read the code itself.]
Oh well, I'll try.

Hope this gives you a clearer picture.​
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Veli-Pekka Tätilä
That is true, that's why I said mostly redundant. I guess I should write a
filter which only shows such things when the previous output is not equal to
the current one.

So far I can remember 3 places in debugger you compain about:

a) How dumpvar.pl/Dumpvar.pm dump an array;

b) Pre-prompt "positional info" output;

c) Debugger's prompt itself.

For 'a' just use `o compactDump=1'. For 'b' and 'c', you may need to
modify the debugger itself.

0) Find the code which prints "positional info";

1) Separate it into a subroutine which takes all the information
from its arguments (no access to global variables). Likewise for
the prompt-creation code.

2) Make the debugger to access this code through subroutine references
stored in global variables;

3) Reset these global variables to the values which suit you (from
~/.perldbrc).

I think this is going to be a very small modification to the
debugger. (When done, do not forget to post patches to perl5-porters.)
It is remarkably difficult unless you've used a screen reader before.

Maybe I will need *soon*. ;-(

[Many pages of very detailed discussion skipped.]

Hmm, what I asked was a short summary. E.g., above I suggested how
you can tune many things done in debugger to suite your needs. WHAT
ELSE (capitalized ;-) would you like to be changed?

Yours,
Ilya
 
V

Veli-Pekka Tätilä

Ilya said:
So far I can remember 3 places in debugger you complain about:
a) How dumpvar.pl/Dumpvar.pm dump an array;
Yes, though as I said, this is easy enough to side step with some filtering
or printed code run with the p command, at least for non-nestedd structures.
That is so easy that it doesn't make too much sense, in my view, to even
modify the debugger for this. Maybe I could add some aliases for different
kinds of speech-friendly pretty printing.
b) Pre-prompt "positional info" output;
It is one of the more serious issues. I'm especially irked by the pakage and
file path prompt before the code. It is not that bad in virtual focus, a
screen reader specific navigation mode, as it is taken to be a single word.
However, If one would just like to get an idea of which line it is and so
use the automatic reading after an enter press, there's no easy way to skip
the package info in that case. THis is called reading in live focus in
Supernova, because no screen reader specific navigation commands are
involved and the reader tracks the OS's keyboard focus. I'll use the terms
live focus (LF) and virtual focus (VF) from now on.

Most of my other complaints have been vpretty minor. So I guess changing
this one bit in the debugger would neatly satisfy most of my changes. I'll
look into it.
c) Debugger's prompt itself.
Yep, though, again, this is small potatoes in comparison to the previous
issue. I just mentioned it for completeness.

There's at least one issue you forgot, though it is not that big, either,
because good HTMl manual pages are available.

d) Inability of GUI-readers to distinguish multi-column layout in the
console.

This means in practise that on trying to read the help screen line by line
in VF, it reads across the columns without pauses. It makes the output
somewhat difficult to grasp in sensible chunks. In contrast, most help
screens including the one for Perl, don't depend on the column structure to
be intelligible. In the perl help columns aren't recognized either but the
order: switch, description makes sense even in line chunks.

Maybe I should add another thing, which would be a nice extra:

e) Finding only parts of code lines with regular expressions.

This is basically the same as the regexp searching commands, except that it
should be able to display just the matching bits on a line, not the whole
line. This feature would be helpful in trying to re-read bits of code in LF,
without having to use virtual focus to cursor around the code. If one has to
switch to a text editor for code reading, some serious issues will arise. It
turns out that the screen reader forgets its virtual focus position when you
come back to the same window, meaning you'll have to start cursoring from
the top of the window again.
'b' and 'c', you may need to modify the debugger itself.
0) Find the code which prints "positional info";
1) Separate it into a subroutine which takes all the information
from its arguments (no access to global variables). Likewise for
the prompt-creation code.
2) Make the debugger to access this code through subroutine references
stored in global variables;
3) Reset these global variables to the values which suit you (from
~/.perldbrc).
Thanks for the instructions, I've archived this bit.
It is remarkably difficult unless you've used a screen reader before.
Maybe I will need *soon*. ;-(
[Many pages of very detailed discussion skipped.]
Oh woops, <grin>. Maybe it would be just easier to run a demo of a Windows
screen reader or compile some Linux reader from sources. Most Windows
readers already come with their own speech synths and are pretty easy to
install.

Supernova, the one I'm using, can be found here:

http://www.dolphincomputeraccess.com/products/index.htm

For screen reading alone, HAl will do just as well.

For Linux, the Yasr reader with the Festival speech synth, is a basic screen
reader not tied to a particular editor, like Emacs. I think Gentoo and
Debian have packages for both.
WHAT ELSE (capitalized ;-) would you like to be changed?
Not much I guess. Resolving the out-of-order issue would be half of the
problem, I think. Turning the help into single columns would be nice, but I
can live without it or do the conversion in a text file manually. The same
goes for browsing the code, it is doable in a text editor. To be able to
answer this question comprehensively I'll need to play some more with the
debugger. I'm just getting into command-line debugging, having done it in
Visual Studio for CPP prior to this, and wanted to highlight the most
frequent and or obvious issues.

Hey, thanks for telling me explicitly about the caps. Smilies could be added
on the list, too. They are rendered partly or not at all, as I have no
punctuation or formatting prompts on when reading normal e-mail, for
efficiency's sake.
 
D

Dr.Ruud

Ilya Zakharevich schreef:
[Ilya suggests Veli-Pekka Tätilä how to tune the debugger]
I think this is going to be a very small modification to the
debugger. (When done, do not forget to post patches to
perl5-porters.)

Ilya, thanks for this stimulating post. I have never used perl's
debugger, and maybe never will, but I will always remember that it is
easy to tune.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Veli-Pekka Tätilä
Yes, though as I said, this is easy enough to side step with some filtering
or printed code run with the p command, at least for non-nestedd structures.
That is so easy that it doesn't make too much sense, in my view, to even
modify the debugger for this.

As I said, no need to modify the debugger. Just set compactDump
option. (I never managed to make "deeply nested" stuff printed "nice",
but simple output should be handled reasonably well.)
It is one of the more serious issues. I'm especially irked by the pakage and
file path prompt before the code. It is not that bad in virtual focus, a
screen reader specific navigation mode, as it is taken to be a single word.
However, If one would just like to get an idea of which line it is and so
use the automatic reading after an enter press, there's no easy way to skip
the package info in that case. THis is called reading in live focus in
Supernova, because no screen reader specific navigation commands are
involved and the reader tracks the OS's keyboard focus. I'll use the terms
live focus (LF) and virtual focus (VF) from now on.

I think most of your "Screen Readers are Stupid" complaints will be
satisfied by PerlDB "addons". E.g., instead of navigating the
information already on screen via (unflexible) screen-read interface,
make PerlDB *repeat* the necessary information by printing something
new on screen. This can be easily done by aliases (especially if
PerlDB provides enough helper functions to make writing the aliases easier).
d) Inability of GUI-readers to distinguish multi-column layout in the
console.

You mean the "concise" help screen? Will this be better:

List/search source lines: Control script execution:
l [ln|sub] List source code | T Stack trace
- or . List previous/current line| s [expr] Single step [in expr]
v [line] View around line | n [expr] Next, steps over subs
f filename View source in file | <CR/Enter> Repeat last n or s
/pattern/ ?patt? Search forw/backw | r Return from subroutine
M Show module versions | c [ln|sub] Continue until position
Debugger controls: | L List break/watch/actions
o [...] Set debugger options | t [expr] Toggle trace [trace expr]
<[<]|{[{]|>[>] [cmd] Do pre/post-prompt| b [ln|event|sub] [cnd] Set breakpoint
! [N|pat] Redo a previous command | B ln|* Delete a/all breakpoints
H [-num] Display last num commands | a [ln] cmd Do cmd before line
= [a val] Define/list an alias | A ln|* Delete a/all actions
h h Complete help page | W expr|* Delete a/all watch exprs
|[|]db_cmd Send output to pager | ![!] syscmd Run cmd in a subprocess
q or ^D Quit | R Attempt a restart
Data Examination: expr Execute perl code, also see: s,n,t expr
x|m expr Evals expr in list context, dumps the result or lists methods.
p expr Print expression expr (uses script's current package).
S [[!]pat] List subroutine names [not] matching pattern pat.
X [Vars] List Variables in current package. Vars can be ~pattern or !pat
V [Pk [Vars]] Same as X for package Pk. Type h y for access to lexicals.
For more help, type h cmd_letter, or run perldoc perldebug for all docs.

For seeing customers, we can add some color for the added "|" line to
make it stnd out better.

Yours,
Ilya
 
V

Veli-Pekka Tätilä

Ilya said:
As I said, no need to modify the debugger. Just set compactDump
I just tried the compactDump option and it works like a charm, thanks. It
gets most short arrays on one line without the indeces.
never managed to make "deeply nested" stuff printed "nice"
I could say the same. Especially if you have subtrees with a lot of children
and would like to see all the sibling nodes at once. Here's an example of a
parse tree, that would be both visually and aurally hard to represent as
nested hashes:

http://www.tol.oulu.fi/kurssit/okp/Luennot/Kuvat/Johtopuu.jpg

I do have an ASCII representation I reconstructed with magnification. For
the nodes it lists their level, parent, siblings and the graphical ordering
but it is far from pretty. The above image looks like this in text:

1 assign to id, equals, expr
2 id of assign to x, preceeds equals, expr
2 expr of assign to id, asterisk, expr, follows id, equals
3 id of expr to x, between x and asterisk, expr
3 x of id, preceeds id, asterisk, expr
3 expr of expr to left paren, expr, right paren, follows id, asterisk
4 expr of expr to id, plus, expr, between x, left paren and right paren
4 x of id, preceeds left paren, expr, right paren
5 id of expr to y, preceeds plus, expr
5 expr of expr to id, follows id, plus
6 y of id, preceeds id
6 id of expr to z, follows y
7 z of expr

Even though the representation is rather formal, it'll only do for
relatively simple, distinctly tree-like structures. I guess it would be hard
to generalize for all structures composed of arrays and hashes. WHen reading
code with speech, most readres apart from Jaws for Windows, cannot read
indentation or visual layout sensibly. So giving enough context in text and
imposing structure by pauses or beeps is a major challenge.
I think most of your "Screen Readers are Stupid" complaints will be
satisfied by PerlDB "addons".
I'm along the same lines mostly. IT is quite sad really. IT wouldn't be
awfully difficult to build some more intelligence to these readers say with
plug-ins. Yet the market for programming blind folks, let alone for those
doing it in Perl, is so small that you don't make much money with such
additions. I've been thinking of how program code could be read aloud very
well and have some skeletal guidelines for c-like languages. I'll post the
list at the end.
instead of navigating the information already on screen via (unflexible)
screen-read interface, make PerlDB *repeat* the necessary information by
printing something new on screen.
Now we're talking business, that is you hit the nail on the head. This is
exactly what I'm after when I talked about regexp searching bits of code
lines.
This can be easily done by aliases
Can these aliases span multiple lines or statements? That would be a great
way to extend the debugger. Particularly, if you can put the commands in
files. That way, should I need to use someone else's debugger, I can simply
plug-in my own config file and be moderately happy,
if PerlDB provides enough helper functions to make writing the aliases
I think there are some nice funcs documented on the DB man page. I'll start
in there. I've also taken a look at the db.pm source file.
d) Inability of GUI-readers to distinguish multi-column layout in the
console.
You mean the "concise" help screen? Will this be better:
List/search source lines: Control script execution:
l [ln|sub] List source code | T Stack trace
- or . List previous/current line| s [expr] Single step [in expr]
v [line] View around line | n [expr] Next, steps over subs
f filename View source in file | <CR/Enter> Repeat last n or s
<snip>
Not that much. The best option would be to have some kind of single column
layout with one switch per line. could this splitting to a single column be
done using some regexp matching ,that is is the column separator
well-defined?
For seeing customers, we can add some color for the added "|" line to
make it stnd out better.
That could be one option. Which reminds me though I'm legally blind and use
speech primarily, I've still got a bit of sight and can use heavy
full-screen magnification, too. I ordinarily use both when examining code so
it is not as difficult as it would seem by the screen readder prompts alone.

Still, say color, isn't much help to me, though some users might find it a
great aid. Syntax highlighting, for instance, means a drop in contrast and
thus poorer readability. This is most definitely OT but in case you are
interested in my sight-situation, I've got a page attempting to describe how
and what I see. URL:

http://www.student.oulu.fi/~vtatila/sight.html

Lastly, here are some skeletal notes on how program code could be machine
read out loud. They should be simple enough to be expressed in code and most
definitely could be followed by a human reader. HOpe this brief form makes
sense, they are primarily for myself at this point. Java and C should go by
these rules nicely and many of them apply to Perl, too. Perl is such a rich
language that I didn't wish to start with Perl in specifying the basic
rules, however. Formatting is tabular using spaces so a fixed width font
would do best. Here we go:

operator prompt
+ plus
- minus
* times
/ per
% modulo
++a pr-einc
--a pre-dec
a++ post-inc
a-- post-dec
..f f field
->f f field
..f() f
->f() f
(t) cast to t
< less than
greater than <= at least
= at most
== equals
!= differs
= is
op= op is
a?:c cond a ? true b : false c
! not
&& and
|| or
& bit and
| bit or
^ xor
~ negation
<< left shift// c comment c
/*c*/ comment block c end
f{ block
} end f
{ bear block
a[x] a at x
x1,x2 x1 comma op x2
t* pointer to t
t& ref to t
&i i's address OR address of i
*i deref i OR value of i

Omission rules for punctuation:
code prompt argument
a.f() a f void function, dot implied
a.f(a, b) a f a PAUSE b simple param list
if(cpmd) if cond parens implied by context
else if(cond) else if cond parens implied by context
else(cond) else cond parens implied by context
while(cond) while cond parens implied by context
for(exps) for exps parens implied by context
switch(expr) switch expr parens implied by context
(exp) op a parens exp end op explicite parens: precedence
case label: case label colon implied by context
lab: statement label lab statement rare, so explicit
x1;<nl>x2; x1 PAUSE x2 statements pause delimited
x1; x2; <nl> x1 PAUSE x2 line emphasizes related statements
; nop has meaning as a no-op
for(x;y;z) for x PAUSE y PAUSE z statements implied by pauses
for(x : y) for x in y audible equivalent of colon
x<type> x of type prompt taken from generics
a[j][k] a at j k for simple Expressions
[x1][x2] at [ROW] x1 [COL] x2 more explicit inddeces
{r1},{r2} row r1 row r2 {} no blocks in inits
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Veli-Pekka Tätilä
Can these aliases span multiple lines or statements?

Alias is just a way to ask debugger to do something by a short command
line. E.g., if you have a function foo(L1,L2) which prints some lines
of code, you can ask PerlDB to call foo(L1, L2) when you give command

fo L1 L2

Getting the lines of code is not hard (see perldb guts
documentation). Maybe there are also some functions exported by
debugger to do this.
Not that much. The best option would be to have some kind of single column
layout with one switch per line. could this splitting to a single column be
done using some regexp matching ,that is is the column separator
well-defined?

Currently the 'h' text is hard-coded, with only BOLD and ITALIC
escapes. One can easily add new S<> escape, which does nothing in the
usual mode, and will break the line at this point if one configures
PerlDB for a (future) "blind user" mode.
Lastly, here are some skeletal notes on how program code could be machine
read out loud. They should be simple enough to be expressed in code and most
definitely could be followed by a human reader.
operator prompt
+ plus
- minus

I do not think your notes are sufficient. Consider a syntax-highlight
editor; then it knows which, e.g., dollar signs are parts of code, of
double-quoted strings, of comments, of regular expressions, of
character classes in regular expressions. Obviously, they should be
read differently.

Given your interest in this, I do not see why do you need any screen
reader at all. You have Emacs; you have something like festival (or
any other speech synthesis program); just write a simple Emacs Lisp
function which would take a region in Emacs, and will write down what
you want to a pipe to the speech synthesis program. Hmm, I'm pretty
sure this must have been already done many times. Google for speech
in emacs newsgroups...

Or, when you write your aliases for PerlDB, create one with your
transformations in mind (you will not have benefits of syntax
highlighting, though).

Emacs Lisp is something extremely ugly, but already implemented
keyboard navigation + syntax highlighting will compensate for the
problems.

Hope this helps,
Ilya
 
V

Veli-Pekka Tätilä

Ilya said:
Alias is just a way to ask debugger to do something by a short command
line. E.g., if you have a function foo(L1,L2) which prints some lines
of code, you can ask PerlDB to call foo(L1, L2) when you give command
fo L1 L2
Ah this seems nice. YOur comment about easily accessing code lines is
useful, too. I dug up the docs, which said:
Quote:
@{"_<$filename"} holds the lines of $filename for a file compiled by Perl.
End quote.

One can easily add new S<> escape, which does nothing in the usual mode,
and will break the line at this point if one
configures PerlDB for a (future) "blind user" mode.
Again thanks for the idea, this would appear to be pretty easy, too. Many
apps already have some kind of blind user mode built-in. My current text
editor, NoteTab Pro, for instance, supports autoclosing the find dialog on a
match in blind-user mode.

Rendering programming languages aurally:
By the way, this is not specific to the debugger but of course the debugger
Experience would be all the more enjoyable, if some app could do this kind
of more or less magical filtering.
I do not think your notes are sufficient <snip>. it knows which,
e.g., dollar signs are parts of code, of double-quoted strings,
of comments, of regular expressions <snip>
Yes, you would obviously have to interpret such characters in double quotes
raw, and interpret regular expressions specially, too. A lot of such things
are perl specific, however, and my notes at this point are generally about
c-like languages with some Java and CPP specifics thrown in. I've yet to
seriously ponder Perl in particular, in this regard. The other reason why I
didn't separate, say bits in double quotes, is that these are also guide
lines for the human reader reading bits of code to me on a machine lacking a
screen reader. Double quotes are easily interpreted right by a human reader,
but regexp are another matter.
You have Emacs; you have something like festival (or any other speech
synthesis program); just write a simple Emacs Lisp function which
would take a region in Emacs, and will write down what you want to
a pipe to the speech synthesis program.
Well, there are several issues with this, though I'm willing to try it
nevertheless. First of all, I'm pretty heavily tied to a Wintel box partly
because of absolute must-have music, OCR and proprietry reader programs, and
partly because apart from text editing and programming, I prefer an
accessible GUI even legally blind, odd as it may seem.

Then I'd need to learn Emacs and Lisp which is not that impossible, I guess.
I already know some Vi and kind of like it and am considering learning Lisp
anyway. I sort of like the Lisp syntax in its regularity.

But the last and most serious issue is getting the app itself. Plainly put,
where can I get a precompiled binary of Emacspeak for Win32 which supports
Microsoft speech API? I did Googling with different keywords, visited the
Emacspeaksite and so on but have been unable to find the Windows version.
I've seen some mails referring to someone's SAPI-enabled port to NT but so
far it hasn't turned up. Any links would be appreciated.

On a side-note, I would pretty badly need the MS speech API support rather
than Festival, because this multi-lingual formant speech synth I've been
using for seven years or so, is a Windows-only, binary release and you
cannot pipe stuff to it, as far as I know. Switching synths would mean a
serious productivity decrease because of pronounciation and intelligibility,
and losing Finnish language support, too, as I've noticed in trying to use
OS X with the Macintalk voices.
sure this must have been already done many times. Google for speech
in emacs newsgroups...
Will do, thanks for the advice.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Veli-Pekka Tätilä
....

But the last and most serious issue is getting the app itself. Plainly put,
where can I get a precompiled binary of Emacspeak for Win32 which supports
Microsoft speech API?

What for? Is your sound card multiplexed? If so, then all you need
is a program which takes text from STDIN, and emits the output to the
sound card. What I have here is rsynth (of '93?). I know that the
newer source-available alternative is festival.
On a side-note, I would pretty badly need the MS speech API support rather
than Festival, because this multi-lingual formant speech synth I've been
using for seven years or so, is a Windows-only, binary release and you
cannot pipe stuff to it, as far as I know. Switching synths would mean a
serious productivity decrease because of pronounciation and intelligibility,
and losing Finnish language support, too, as I've noticed in trying to use
OS X with the Macintalk voices.

You do not lose anything (well, you lose finnish comments/strings in
program texts; do you have many programs with finnish
comments/strings?) - what we discuss is an addon.

Which way of input is understood by your program (one which can be
generated programmatically)? If worst comes to worst, just open a new
window and show your converted text there.

Yours,
Ilya
 
V

Veli-Pekka Tätilä

Ilya said:
What for? Is your sound card multiplexed?
Hmmm, I think it can do hardware mixing and does have several outputs.
However, the name Microsoft speech API is a bit misleading. It let's one
deal with both speech recognition and text to speech via a uniform
interface. Naturally, using text to speech is what interests me. More
specifically using the same speech synth as in my screen reader but driven
by Emacspeak.
You do not lose anything (well, you lose finnish comments/strings in
program texts;
Again, here I just ment that I hope I don't have to switch to Festival to
keep Emacspeak happy. But then again it might not be that bad after all.
Though the speech of Festival is not very intelligible at high rates, you
could get so great a spoken representation of Perl code via some serious
hacking in Emacsspeak, that this more than compensates for it. Still, I'd
like to use my existing Microsoft speech API compatible speech synth in
Emacspeak in WIndows, if at all possible.

Finnish comments are not an issue in Perl programs, I always write comments
in English. Partly because I've learned computing largely in that language,
and partly to avoid having to switch speech languages in the first place. I
mentioned Finnish support because I write a lot of e-mail in it and I
figured out that if I'm going to do coding in Emacspeak, I might as well use
it as my e-mail editor, too.
Which way of input is understood by your program
My current synth can be controlled via the Microsoft SAPI 5.x speech API at
least. The synthesizer itself is Dolphin Orpheus of which this is version
2.02.

Here are my reviews of both versions, to give you a picture of what kind of
synth it is:

http://www.student.oulu.fi/~vtatila/reviews_of_speech_synths.html#orph1

http://www.student.oulu.fi/~vtatila/reviews_of_speech_synths.html#orph2

And for comparison, here's Festival:

http://www.student.oulu.fi/~vtatila/reviews_of_speech_synths.html#festival

Hope this clarifies things.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Veli-Pekka Tätilä
Hmmm, I think it can do hardware mixing and does have several outputs.

Now that I thought more of it, I have some vague recollection that if
sound card has no mixing, windows will mix in software... So this
question may be meaningless on sufficiently powerfull computer with
Windows.
However, the name Microsoft speech API is a bit misleading. It let's one
deal with both speech recognition and text to speech via a uniform
interface. Naturally, using text to speech is what interests me. More
specifically using the same speech synth as in my screen reader but driven
by Emacspeak.

Well, if you can write a small wrapper application (possibly in Perl
XS ;-) which interfaces with your beloved API, and takes the text from
STDIN, everything should be OK (although I have no idea how Emacsspeak
works, I doubt it needs anything else).

Yours,
Ilya
 
V

Veli-Pekka Tätilä

Ilya said:
Well, if you can write a small wrapper application (possibly in Perl
XS ;-) which interfaces with your beloved API, and takes the text from
STDIN, everything should be OK (although I have no idea how Emacsspeak
works, I doubt it needs anything else).
I've never written XS apps but a pure Perl version is easy to write. You can
interface with Microsoft Speech API 5.x by using Win32::OLE. It will even
support asynchronous operation without me having to deal with threads.
Threads with OLE in Perl would crash anyway, which is a known problem.

Are other IPC mechanisms supported in Emacspeak, WIndows and Perl so they
might be faster. I'm thinking of sockets at this point.

Now seems the only thing I need is the Windows port of Emacspeak, which I
still have been unable to find so far. It must be somewhere, musn't it. I've
even read about a port but just couldn't find it at least yesterday.
"emacspeak for windows" quoted only returns some research papers and a
couple of posts within the Google top 10. emacspeak win32 without the quotes
doesn't produce much better results. The best hit seems to be the
installation instructions at:

http://home.vr-web.de/gerhard.stenzel/emacspeak/install-win32.html#c36e2526b5

But they talk about compiling from sources which I usually don't want to do
given a choice. I'm infinitely happy that there are tools like apt-get and
ppm available.

Ah, SAPI support is already available in Emacspeak so if it is SAPI 5 I
might not need to code anything at all.
The FAQ to which they link appears to hint at a binary version somewhere:

http://www.gnu.org/software/emacs/windows/faq3.html#install

I can find Emacs for Windows quite alright, but at least in tools like
apt-get Emacspeak shows up as a separate package from Emacs as far as I can
remember.

Neither does going through the Emacspeak Source Forge site help all that
much. I can only see various redhat packages and the sources at:

http://prdownloads.sourceforge.net/emacspeak/

If all else fails I suppose I could do something like the following:
Get a minimal Debian system somewhere and install it on some virtualization
solution running Linux inside Windows. Independent installation is quite
possible via TeraTerm, my Windows screen reader and a serial-port enabled
distro. The Linux distro could then host Emacspeak but I'd like to use my
Windows speech synth still. One way around this would be to talk to Windows
via a virtual serial port as above, receive the traffic to a Win32 perl
script and drive my SAPI synth from there. Not all that simple but none of
the substeps involved seem so difficult. I've already, for example,
installed LInux in Windows, talked to SAPI (pun intended) from Perl, and
delt with the serial port in Java prior to this writing.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Veli-Pekka Tätilä
Now seems the only thing I need is the Windows port of Emacspeak, which I
still have been unable to find so far.

I do not know what Emacspeak is, but if it is Emacs with speech
extensions, I do not see why any port is needed. AFACS, the only
thing needed is a "speak this" application; anything else is a frill
(which may improve performance a tiny bit).

So on your place I would download .el files, and would read about
its "pathway to speaker" settings.

Yours,
Ilya
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,039
Messages
2,570,375
Members
47,020
Latest member
anuradha

Latest Threads

Top