Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

ZSpeak! Only Zsh can do this!



Hi guys.

First of all, I want to introduce myself:
I am a fanatic linux user/developer since 1997
and recently (its a shame that it took so long) I discovered
Zsh and I want to say: You guys did a great job!

As I am a blind Linux user I began to wonder if ZLE (and other things)
could be extended to support Speech output.
This could be nice for various reasons:
1. For blind/visually impaired persons who want to get
a simple speech output from cli without much setup efforts.
2. Perhaps for mobile devices with are limited in space
for a large comprehensive speech output system.

As I said, I am fairly new to Zsh and shell programming in general.
But I couldn't resist to try my best, and here
is how far I got.

But it is far from being finished.
I wanted to post this here for various reasons:
1. Perhaps someone finds a way to do something much
   better than I currently do.
2. Perhaps someone can find some solutions for my TODO
   list.

OK, here we go. Please mail me with every (minor|major) suggestion.
I can use everything. Especially to learn nice Zsh techniques.


#
# Zspeak - Zsh Function to get speech feedback.
#
# by Mario Lang <lang@xxxxxxxxxxxxxxxxx>
#
# Currently only ZLE (the line editor) is supported.
# TODO:
# * Find a nice way to add/remove keybindings in speech-(on|off)
# * Find a way to make the prefix key-sequence configurable (^[v)
# * Add self-insert replacement functions to speak typed chars
#   * Add parameter and keybinding to control character echo
#   * Word-echo?? (magic-space??)
# * Add replacement function for up/down to speak new BUFFER content
# * Modify the completion system so that menu-completion inserted
#   text gets spoken.
# * Find a way to read stdout/stderr of commands too! is exec my friend?
#   If this can be done in a nice way, all kinds of non-interactive
#   console programs can be used eye-free with Zsh and a soft/hard-speechsynth.
# * Add speech rate parameter (and keybinding to change it)
# 
# Comments:
#   I am fairly new to Zsh and all its specialities.
#  If you find anything in this code which could be done
#  better, please tell me. I am eager to find the best way
#  to do this. Especially am I interested in ways
#  to get the last TODO item to work (stdout and stderr review).
#
#  This file should be called speech-on and placed
#  in fpath.
#  autoload it, and execute speech-on
#

speech-on () {
    zle -N speech-on
    zle -N speech-off
    zle -N speak-buffer
    zle -N speak-current-character
    zle -N speak-help
    zle -N forward-char speak-new-position
    zle -N backward-char speak-new-position
    #speech-load-spell-list
    bindkey "^[vb" speak-buffer
    bindkey "^[vc" speak-current-char
    bindkey "^[vh" speak-help
    bindkey "^[vo" speech-off
}

speech-off () {
    unset zspeak_spell
    bindkey "^[vo" speech-on
}

# BUG: Doesnt read in the spell list?? Any Zmagician?
speech-load-spell-list () {
    typeset -A zspeak_spell
    [[ -z $ZSPEAK_SPELL_LIST ]] && [[ -s "~/.zsh/spell.list" ]] \
				&& ZSPEAK_SPELL_LIST='~/.zsh/spell.list'
    if [[ -s "$ZSPEAK_SPELL_LIST" ]]; then
        zspeak_spell=(${$(<${ZSPEAK_SPELL_LIST})})
    else
        # Some fallback defaults
        zspeak_spell=(. dot , comma ; colon / slash _ underscore - dash)
    fi
}

speak-string () {
    # Here goes the compatibility code. All synth specific
    # decissions when outputting text should be done here.
    case $ZSPEAK_SYNTH in
	festival)
	    [[ -x `which festival` ]] && print "$@"|festival --tts
	    ;;
        speechd)
	    [[ -e "/dev/speech" ]] && print "$@">/dev/speech
	    ;;
	*)
    esac
}

spell-char () {
    speak-string $zspeak_spell[${1}]
}

# All following functions use the above as a backend
# So all speech synthesizer specific tweaks should go above this
# separator, and all Zsh/ZLE/whatever specific modifications below.

speak-buffer () {
    speak-string $BUFFER
}

speak-current-character () {
    spell-char $BUFFER["$CURSOR"]
}

speak-help () {
    speak-string `bindkey|grep "^\"^\[v"|sed 's/\"\(.*\)\" \(.*\)/\1 invokes \2. /'|sed 's/^^\[\([a-zA-Z0-9]\)/Alt \1 plus /'`
}

speak-new-position () {
    zle .$WIDGET "$@"
    speak-current-character
}

[[ -o kshautoload ]] || speech-on "$@"
 
-- 
CYa,
   Mario <mlang@xxxxxxxxxxx>
Homepage(s): http://delysid.org | http://piss.at/

Theory is gray, but the golden tree of life is green.
		-- Goethe



Messages sorted by: Reverse Date, Date, Thread, Author