2

Context:

I have an AppleScript .scpt file that speaks the selected text in the System Voice. The selected text is copied to the clipboard, and then the text is spoken via the say command. The script is triggered by keystroke via FastScripts.

Because the macOS Text-to-Speech volume is too loud by default (and there is no global volume control for the Speech), I use AppleScript to set the volume as a fraction of the current volume. I learned how to achieve this from this post:

How to change volume of “say” in AppleScript?

Here is the part of my code that is relevant to my question:

set the clipboard to ("[[volm 0.35]] " & (the clipboard))
set this_say_Pid to do shell script "LANG=en_US.UTF-8 pbpaste -Prefer txt | say > /dev/null 2>&1 & echo $!"

The above code speaks the clipboard text at a volume that is 35% of the current system volume, which is what I desire. (Yes, the audible Speech is really that loud by default.)

The code works well, except I've discovered a bug.


How to reproduce the bug:

To observe this bug, copy the following text to the clipboard, and then run the above code:

 

- This is a test.

The problem-text is difficult to format in Markdown (which is what Stack Exchange uses) because 1) blank newlines are automatically removed, and 2) a hyphen-space combination is converted to a list bullet point. This is why the above text formatting looks wonky; I had to use a blockquote to get around issue one, and I had to add a code block to get around issue two.

Here is the problem-text, literally spelled out in words (if you want to open a text file and recreate the text):

newline
hyphen space Text

Make sure that you include the blank newline when you copy the text onto the clipboard. Make sure that there is a space between the hyphen and the first word of the text. Otherwise, the bug will not surface.

The problem-text must be the very beginning of the clipboard text. That is, if the problem-text is in the middle or at the end of the clipboard text, the bug will not surface.


Additional ways to reproduce the bug:

The hyphen (-) can be substituted for an en dash (–) (⌥ option + -) or an em dash (—) (⌥ option + ⇧ shift + -), and the bug will still surface. As far as I have found in my tests, there are no other punctuation symbols that can be substituted for the hyphen that will trigger the bug.


There is another way to trigger the bug, which does not involve a hyphen or dash. If the text is preceded by at least 2 newline characters, the bug will surface.

For example:

  • If there is 1 newline character, the bug will not surface.

  • If there are 47 newline characters above the text, the bug will surface.

Whether there are any spaces between the 2+ newline characters and the text does not matter; the bug surfaces either way.


The effect of the bug:

  • When running the AppleScript code with the problem text on your clipboard, the volume is not decreased one bit; the clipboard will be spoken at the system volume level.

  • Also, there is a noticeable delay before the text is spoken.


To be clear, while the context of my question is an .scpt file, this is not technically an AppleScript bug. The bug exists when using say directly in Terminal.app. For example, type the following in Terminal to reproduce the bug:

say "[[volm 0.35]]
- This is a test."

Is it possible to remedy this bug, so that, when the clipboard contents begin with any type of problem-text, my script remains sensitive to the custom volume, and a delay is not introduced?

  • Thank you for bringing that to my attention. That was a typo that I've just fixed. Yes, I am able to reproduce the bug from within Script Editor.app, by replacing the first line with the following line of code: set the clipboard to ("[[volm 0.35]] " & ("\n- This is a test.")) – rubik's sphere Apr 5 '17 at 1:31
  • While my most recent edit was published after you published your "Okay, after some testing..." comment, I was actually working on this edit and discovered the newline revelation before reading your comment. It was a coincidence. – rubik's sphere Apr 5 '17 at 3:03
  • Regarding your second comment, my script takes the selected text and puts it on the clipboard. It's not that often that the selected text begins with more than one newline or a newline + hyphen/dash + space. But it is often enough that it is a nuisance and worth the energy to create a post to solve the issue. The Speech at full volume is very startling. It's not me necessarily that is employing the problem-text; it's any text selection that exists that contains the problem-text. I would prefer that my script doesn't have this bug, because the text that I select is unpredictable. – rubik's sphere Apr 5 '17 at 3:07
2

The best is to put '[[volm 0.35]] ' into the shell (not in the clipboard), like this:

set this_say_Pid to do shell script "say '[[volm 0.35]]\\ '$(LANG=en_US.UTF-8 pbpaste -Prefer txt) > /dev/null 2>&1 & echo $!"

Or, if you want to put "[[volm 0.35]] " into the clipboard, use the single quotes, like this:

set the clipboard to ("'[[volm 0.35]] '" & (the clipboard))
set this_say_Pid to do shell script "LANG=en_US.UTF-8 pbpaste -Prefer txt | say > /dev/null 2>&1 & echo $!"
  • I have actually found that your first solution contains a new bug. If the clipboard contains a hyphen that is not followed by a space, then your code will not speak the text. For example, try using this text: -Speak this sentence. – rubik's sphere Apr 13 '17 at 18:59
  • I updated my answer, I put an escaped space after '[[volm 0.35]] – jackjr300 Apr 22 '17 at 5:01
  • I've found a bug in your second solution. If the text contains an apostrophe, then the code will mispronounce the word that contains the apostrophe. If there is more than one apostrophe in the clipboard text, then only the first word that contains an apostrophe will be mispronounced. For example, run the code with the following line on the clipboard: They've been here and they've been here and they've been here. You'll notice that the first They've is pronounced as "they vee." But, this isn't a big deal; your first solution doesn't have this bug, so I will simply use the first solution. – rubik's sphere Jun 1 '17 at 4:53
1

Simply add a comma after the [[volm 0.35]] part of your shell script. A space after the comma is probably not required.

set the clipboard to ("[[volm 0.35]], " & ("\n- This is a test."))

This also eliminates the second error (hyphen and text without separating space).

  • Your solution works perfectly and is bug-free, as well. – rubik's sphere Apr 26 '17 at 0:31

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.