AppleScript - Speech to Text - applescript

I am trying to write a small AppleScript that can output a string of text which can be manipulated by another script. This works:
tell application "SpeechRecognitionServer"
set display to no
set theResponse to listen for {"yes", "no"}
if theResponse is "yes" then
display
else
say "Goodbye."
end if
end tell
The only problem is that it repeats the command that you issue it! (in our case, yes or no). So my question is: Is there a way to prevent it from repeating the command? I just do not see why it repeats the command, nor can I figure out which process runs the voice or I would just kill it.
Thanks

Manual fix:
System Preferences -> Speech -> Speech Recognition Tab
Disable the "Upon Recognition" checkbox.
Programatic fix:
This involves disabling these prefs before your code and then setting them back to their original values afterwards. That is, if you intend for this code to be portable to other users. If its only a personal script for yourself, then the manual fix is fine to set it permanently.
Refer to this forum for people asking the same question, and the various approaches they have tried:
http://macscripter.net/viewtopic.php?id=33259

Related

(NO mystery:) How Automator transfers "invisible" information to Script-Editor

( I have been pushed to an obvious answer to my "Mystery" from a friendly member here.
I feel a little ashamed not to have found this solution myself, but will leave this posting online if there aren't too many irritated folks around. Maybe someone else can learn from this … apologies to every "know-it-alls"!)
I have recorded these actions with Automator:
– Cmd-tab to bring TextEdit to front (must have some lines typed)
– Pressed left arrow 7 times using shift down
– Stopped the recording
Next I selected and copied (Cmd-c) all action icons in Automator's "Record my actions" window.
I switched to Script-Editor and pasted (Cmd-v) them into a new window.
Then, I repeated above recording with 3 times UP arrow and copied icons into another new window.
I took only the two "set uiScript to …" lines and appended them in the first script.
THEY READ IDENTICAL:
set uiScript to "keystroke \"\t\" using command down"
my doWithTimeout(uiScript)
set uiScript to "keystroke \"\" using shift down" -- 7 times left-arrow
my doWithTimeout(uiScript)
set uiScript to "keystroke \"\" using shift down" -- 3 times up-arrow
my doWithTimeout(uiScript)
on doWithTimeout(uiScript)
set endDate to (current date)
repeat
try
run script "tell application \"System Events\"\n" & uiScript & "\nend tell"
exit repeat
end try
end repeat
end doWithTimeout
(To make resulting code more readable I omitted error code and "delays".)
Now, if I disable one of the "keystroke" lines (=> --my doWith…) the script somehow knows that it either has to do Shift-leftArrow 7 times OR Shift-upArrow 3 times.
I tried this after computer restart, even copied the code from this web page and pasted it into a new Script Editor window – it still knew what to do!
HOW CAN THAT BE ???
My only idea is: there must be some internal Applescript database that recognises content even if copied/pasted.
Does anybody know ?
Only if I re-write the code identically will there happen NOTHING – until I copy the first line of either recording ("set uiScript to …"). So the information must be linked to this first line somehow.
(BTW: first two lines that bring TextEdit –or, e.g. a Finder window– to the front work only from opened Script Editor; you have to bring TextEdit to the front yourself, if you start the saved-as-program script from Script-Editor's menu icon subfolder. Nevertheless the script won't work without them…)
It "knows" because the keystrokes are in the string - keystrokes using control type keys (such as arrow keys) just don’t have a text representation, so they wind up being invisible. Some text editors such as BBEdit can show these invisible characters, but they don’t show up in the Script Editor.
Apple has obviously made Automator's Watch Me Do action able to capture some of these control keys in a string, but for the rest of us it is more difficult, since the control keys will actually perform their function when pressed. If you need to use these kinds of keys, the key code command can be used, since it refers to the actual keyboard key, for example:
tell application "System Events"
repeat 3 times
key code 126 using shift down -- up arrow
end repeat
end tell
As the answer is quite simple but may still be interesting to some, I'll explain it shortly:
red_menace (in his comment above) pointed out that strings may contain invisible elements (like arrow keys), therefore I next checked the obvious:
If you "cursor-walk" along the "set uiScript …" strings the cursor will actually "pause" for 7 or 3 "steps" respectively on its way.
I hadn't thought/heard of any "invisible" string-chars (apart from obvious ones in Word etc.).

Run AppleScript progress bar in separate window from command line?

To display dialogs from the command line I just use
$ osascript File.scpt
However, the progress bar feature isn't constrained to a dialog window because it adapts to the current application, e.g. a Finder window, where the progress updates are shown on the bottom of the window. File.scpt would look something like this.
set numUpdates to 100
set progress total steps to numUpdates
set progress completed steps to 0
set progress description to "Updating..."
set progress additional description to "Preparing to process."
set cycle to 1
repeat with a from 1 to numUpdates
# update description, completed steps, etc
end repeat
When I run my script from a terminal window, however, the script runs but nothing is shown to indicate the progress. Is there a way to force the progress bar to open as a new dialog or something along those lines without having to export the script as a ".app" file?
The reason Script Editor can display progress in its window and Terminal cannot is because Script Editor has its own extended scripting definition with the extra functions so when the script is run via script editor it has been programmed with the extra progress indicator but no other applications are sorry. The way I see it, you pretty much have 2 ways I can think of that will let you display "Progress" in AppleScript:
This is kinda ugly but I used to just have a transparent spinner gif file that will be displayed in a dialog which will give the affect that something is loading or working. and a single button saying Nothing or OK eg.
display dialog "Loading..." buttons:{"OK"} with icon ("/path/to/loader.gif" as POSIX file)
And if you wanna make it temporary just add giving up after (duration in seconds)
This is probably the best option but it is probably more complicated. I advise that you transfer to a programming language called "AppleScript Objective C" otherwise known as "Cocoa AppleScript". This allows you to use the basic AppleScript commands with Cocoa Windows/Dialogs/etc including progress bars!. to start you off you should download Xcode and research AppleScript Objective C and perhaps stick to it. Its better than AppleScript but still has the same functions :)

Xcode AppleScript : change label which content of variable

Here is my script :
property MyLabel : missing value
on buttonClicked_(sender)
set the plistfile_path to "~/Desktop/MY_DATA.plist"
tell application "System Events"
set p_list to property list file (plistfile_path)
-- read the plist data
set theMyDataFromPlist to value of property list item "DATA1" of p_list
end tell
end buttonClicked_
This gonna take the data I want from a plist and set in a variable (theMyDataFromPlist).
How can I print this variable on the label "MyLabel" and make the script auto refresh when the data change ?
also, when I click on the text (or another button), can I copy the value to the clipboard. (would set the clipboard to theMyDataFromPlist work?)
I also wonder is that possible to do the same with Swift?
How can I print this variable on the label "MyLabel"
Where would you like to print the variable? You can make AppleScript display a dialog:
set variable to 42
display dialog "The value of variable is " & variable
AppleScript is not designed as a terminal language, it is for UI scripting, so it's not like most scripting languages that just offer a print as where would the user see the printed value.
and make the script auto refresh when the data change ?
Not quite sure what you expect here. That your system magically runs your script whenever the content of a file changes? That's not going to happen. You can create a launchd job and have launchd monitor that file and then execute your script when the file changes; this is described here:
https://discussions.apple.com/message/13182902#13182902
But some process will have to monitor the file and if your script should do so, it has to be running all the time, non-stop. Then you could make some code run once every X seconds, checking the file last modification date and whenever that changes, re-read the plist. This polling is super ugly but the best thing that AS can do out of the box.
BTW where is the rest? You say
also, when I click on the text (or another button),
can I copy the value to the clipboard.
Which text? Which button? Sound like you have a whole application there but all you showed us are 11 lines script code. You didn't even mention that you have a whole application with a UI. Your question starts with "Here is my script", so you make it sound like this 11 lines is all that you have.
(would set the clipboard to theMyDataFromPlist work?)
Why don't you simply try it out? Pasting that line into ScriptEditor would have taken equally long than asking this question. I just tried it and it turns out that you can only set strings.
This code won't work:
-- bad code
set variable to 42
set the clipboard to variable
But this code does work:
-- good code
set variable to 42
set the clipboard to "" & variable
I also wonder is that possible to do the same with Swift?
Personally I would not even consider writing an application in AppleScript; I'd rather stop writing code before I do that. Of course this can be done in Swift or in Obj-C. Everything you can do in AS can be done in these other two languages and no, the opposite doesn't hold true.
Using Obj-C or Swift, you can also use GCD and with GCD monitoring a file for changes is easy. Just see
https://stackoverflow.com/a/11447826/15809

Automatically switching between two running programs

Because I really don't know a lot about this domain of programming, it might be clearer for me to explain what I would do if I were to input myself the commands I want to automatize (i.e. I just launch a script and all this procedure should be done automatically).
Lauch both the Game and the Task.
Start a game of the Game and immediately pause it.
Alt tab to the task.
Do it until a point determined in the program. At which point I am
told to switch to the game.
Alt tab to the game
Unpause it and start a clockwatch.
When the clockwatch reaches X minutes (X determined in advance),
pause the game.
Alt tab to the task.
Repeat steps 4-7 N number of times.
I have no idea whether it is possible or what tools to use. I understood that a simple bash file won't be enough and I might need to use a "fake keyboard" program to force some inputs (such as "space bar" to pause the game). But I have no idea how to coordinate all of that.
Thanks in advance for any help. Even telling me it's not possible is an acceptable answer :)
EDIT : Edited the list for clarity
From what information you have given, it is difficult to tell whether the complete process can be automated, but there are tools like AutoHotKey which you can use to write scripts to automate desktop applications.
A simple script in autohotkey to start a program "Notepad", another program "Calculater", and switch back to "Notepad" and write "Hello World!" in it.
SetTitleMatchMode, 2
Run "C:\Windows:\Notepad.exe"
Run "calc.exe"
WinActivate, Notepad
Send, Hello World!
The above is a very simple script. It does not activate the specific notepad window you want if multiple notepad windows are open. However, that can be automated too.

BBEdit AppleScript for reformatting multiple files

I'm looking to write an Applescript which will utilize BBEdit — loop through a ton of HTML files and autoformat them (so the indentation is easier to read).
So far I have:
tell application "BBEdit"
activate
open {file "Macintosh HD:TEST DIRECTORY:testfile copy 2.html"} with LF translation
(format mode hierarchical)
beep
display alert "Finished!"
end tell
This applies the transformation to a single file, but has anyone got any suggestions how to apply this to an unknown number of HTML files?
You've almost got it; the trick is that you want to loop through the files returned by open. Thus, you need something like this:
tell application "BBEdit"
set docs to open LIST_OF_FILES with LF translation
repeat with doc in docs
-- format doc
save doc
end repeat
beep -- Or even `say "Finished!" without waiting until completion`
-- if you want your computer to talk to you
display alert "Finished!"
end tell
As you can see, all you need to do is place your formatting code inside this loop (and don't forget to save the files!); the loop will set doc to each element of the list docs in turn, and run the body with that element. If you're not sure how to select the files, one way is choose file with multiple selections allowed; this will pop up a dialog box which will allow you to select as many files as you want. To use it, just replace LIST_OF_FILES with (choose file with multiple selections allowed).
BBEdit will perform a find/replace on any group of files you want. Just hit command+shift+f to bring up Multi-File Search instead of the basic find/replace window.
If you have more than one set of find/replace commands that you need to execute at the same time, you need a Text Factory. See here for details on how to set one up: http://www.barebones.com/products/bbedit/benefitsexercise.html
Does that help?
You should use the Text Factory feature for this. Under "File > New > Text Factory". Any operation you can perform on a single file can be done on any number of files and you can save the operation for future use.

Resources