Read selected text out-loud on Ubuntu Linux

Tyler Smith - May 13 '21 - - Dev Community

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 and xsel 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
Enter fullscreen mode Exit fullscreen mode

Next, make a user-scripts directory in your home folder, then navigate into that directory.

mkdir ~/user-scripts
cd ~/user-scripts
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .