I'm bad at proofreading. I manage to gloss over most of my mistakes, no matter how many times I read something that I wrote.
Because of this, it was a godsend when I discovered that hitting the alt
+ esc
keys on my Macbook would read the selected text out-loud (Apple speak selection docs). I hear many of the mistakes I miss while proofreading. It's become an indispensable part of my writing workflow.
Unfortunately, my Linux machine doesn't have this feature built in, so I needed to hack it together.
Building the read-selected-text script
If you have any experience using Apple's alt
+ esc
text-to-speech feature, let me start by saying this won't be nearly as good. But, we can get something that's good enough.
Here's how it'll work:
- We'll create a script that runs when you hit
ctrl
+esc
. - The script will check to see if the text-to-speech application is already running. If it is, it will kill the process to stop the speech.
- If speech-to-text is not running, it will copy the text to the clipboard and pipe it into the text-to-speech application.
First, we're going to need to install a few packages:
-
xclip
andxsel
help manage the clipboard for X11 desktops (Linux's standard windowing system). -
espeak
reads text out-loud.
Run the following commands in your terminal:
sudo apt update
sudo apt install xclip xsel espeak
Next, make a user-scripts
directory in your home folder, then navigate into that directory.
mkdir ~/user-scripts
cd ~/user-scripts
Next we're going to create a read-selected-text
file, then set it as executable.
touch read-selected-text
chmod +x read-selected-text
Now, open the file with Nano by running nano read-select-text
, and paste the following into the file:
#! /bin/bash
espeak_pid=$(pidof espeak)
# espeak argument reference:
# -a for volume. Max 200
# -p for pitch. 0 to 99, default is 50
# -v for voice
if [ -z "$espeak_pid"]
then
xclip -out -selection primary | xclip -in -selection clipboard
xsel --clipboard | tr "\n" " " | espeak -a 200 -p 60 -v english-us
else
kill $espeak_pid
fi
Press ctrl
+ o
to save, then ctrl
+ x
to exit Nano.
Binding the script to a keyboard shorting
Open the Settings app, and navigate to Keyboard on the left-hand sidebar. At the bottom of this screen, click Customize Shortcuts, then scroll to the bottom and click Custom Shortcuts. Click the Add Shortcut button.
In the name field, title the shortcut "Read Selected Text."
In the command field, type the full path to the script we created earlier (my script's path is /home/tyler/user-scripts/read-selected-text
). You can run the pwd
command in your user-scripts
directory to find your full path.
Set the shortcut. I set mine to ctrl
+ esc
, but you can set yours to whatever you like.
Finally, click the Add button at the top of the window.
You can now test your screen reader. Select some text on your computer and run your shortcut. You should hear a robotic voice read the text back to you.
Potential issues
X11 has been the default window system in Linux for decades, but distributions are starting to adopt Wayland. I haven't tested this script on a Wayland-based Ubuntu machine, but I suspect it might not work.
I also imagine this script will run into issues if two instances of espeak are ever running at the same time.
I built this as a minimal-effort script to get me up and running using information that I found on Stack Exchange and Ubuntu's documentation. If you have any improvements (or if you found parts of my instructions that are incorrect), please drop them in the comments below!
Top comments (10)
Here is how I've done it in Manjaro i3;
sudo pamac install xclip xsel espeak
/usr/local/bin/read-selected-text
sudo chmod +x /usr/local/bin/read-selected-text
~/.i3/config
:bindsym Ctrl+Escape exec read-selected-text
mod+shift+r
BTW the voice is really funny :kidding:
Nice! Thanks for sharing. I really need to give Manjaro another run one of these days: it had the nicest XFCE theme I've ever used.
Nice one, worked smoothly.
Asking myself how you do screen reading with that Steven Hawking voice though. Anyway useful because I use that as a voice to check how "long" a written text will probably need to be spoken, as a voice from the off when casting videos.
Thanks!
I'm glad it helped! I personally wish that the voice-to-text was a little less robotic with this method, but it still does the job 🙂
im lost when you said use nano if you could help me navigate that? thank you so much this is going to help immesely
Happy to help! From the
user-scripts
folder, runnano read-select-text
. I updated the the article to include that instruction 🙂It works and, as you say, it's just OK. The voice is way too robotic to really help to improve one's pronunciation. Any clue if there's a source to get different voices which can be inputted with better pronuciation?
I did
espeak -a 200 -p 60 -v en-gb
since it is a British project in its beginning and the pronunciation is a little bit less robotic.You may try out different pronunciations listed in
speak --voices
Thanks for the post, bu the way! I also miss the old Mac reader.
Thanks for reading the post, Ricardo!
Yeah... it's less than ideal. I've had some ideas on how to make a better version, but they're more effort than I'm willing to put in at the moment since I primarily use MacOS. If I ever switch over to Linux full-time, I'll make something better and drop a comment here so you get notified.
Thanks. I changed your script to use the google text to speech. The voice is a lot less robotic. You can find the instructions here: github.com/yosoufe/instructions/bl...
Sounds awesome!