Spelling and/or interface to Dictionary app?

hi there - I’m new to Applescript, although proficient in perl and C and so on - which doesn’t help :slight_smile:

I tried dabbling with Applescript a long time ago but gave up - partly because there wasn’t anything I really needed to do, which couldn’t be done in perl, or on the command line - or manually.

Now however, I have a mission!

I have a generated list of words in a simple text file and I would like to print out, nicely, the Dictionary application’s considered opinion on each of these 417 words. I don’t want to type each one in. And I like the format of Dictionary’s output.

A job for Applescript!!!

So, I had a look at the dictionary for, umm, Dictionary. I don’t see “lookup ” or anything like that :frowning:

Am I doomed? A google search on “applescript dictionary” didn’t help, of course :slight_smile: But neither did adding “spelling” :frowning:

It would be very odd if Dictionary, an application by Apple, couldn’t look up a word???

Thanks in advance,

colin

Colin;

I’ve been able to get a definition, but the formatting you admire is not preserved. If you want only the definition click the triangle in front of Thesaurus to closed. I would think that a little text item delimiter work would get you back what you want.


set Wrd to text returned of (display dialog "Enter a word" default answer "")
activate application "Dictionary"
tell application "System Events" to tell process "Dictionary"
	keystroke Wrd & return
	set Def to (value of UI element 1 of scroll area 1 of scroll area 1 of group 1 of window 1) as Unicode text
end tell
set F to open for access ((path to desktop as text) & "Defs.txt") with write permission
try
	write Wrd & return & Def to F
	close access F
on error
	close access F
end try

For a bunch of words:


set F to open for access ((path to desktop as text) & "Defs.txt") with write permission

set W to {"abcess", "confound", "magic", "simitar"}
repeat with Wrd in W
	activate application "Dictionary"
	tell application "System Events" to tell process "Dictionary"
		keystroke contents of Wrd & return
		set Def to (value of UI element 1 of scroll area 1 of scroll area 1 of group 1 of window 1)
	end tell
	-- need some word processing here to recover format
	try
		write Wrd & return & Def to F
	on error
		close access F
		exit repeat
	end try
end repeat
close access F

That’s great.

I have to admit then that Applescript is powerful.

I’m still surprised that you can’t just ask an Apple-written Dictionary application to look up a word using Applescript though :wink:

colin

I guess one could ask Dictionary to print a pdf ?

colin

Hi,

I took a slightly different approach. There is a URI protocol of ‘dict’.

set myWord to "magic"
tell application "Dictionary" to launch
open location "dict:///" & myWord

If you open TextEdit with a blank Rich Text window, this should preserve the formatting:

set myWords to {"cat", "dog", "magic"}

repeat with myWord in myWords
	tell application "Dictionary" to activate
	open location "dict:///" & myWord
	delay 1
	tell application "System Events" to tell process "Dictionary"
		keystroke tab
		keystroke "a" using command down
		keystroke "c" using command down
	end tell
	tell application "TextEdit" to activate
	delay 0.5
	tell application "System Events" to tell process "TextEdit"
		keystroke "v" using command down
	end tell
end repeat

Best wishes

John M

OK, I can see I’m going to need to get into Applescript. This is cool!

Of course, if a word isn’t in the dictionary, one needs to handle that :slight_smile: - but you’ve already been really helpful, both of you. I’ll have a go at making this a proper little app… (which will take me longer than typing in the 417 words - but who cares?)

Thanks,

colin

Dictionary isn’t really scriptable beyond a few “Standard” commands. I imagine the fact that it has a scripting dictionary means it might be made scriptable in the future. :confused: Meanwhile, GUI scripting’s the only way, except for .

That’s great, John! Thanks for the information. :slight_smile:

Here’s an expansion of your script. It’s quite a bit longer, but faster. (It doesn’t need to keeping swapping the frontmost applications.) It also catches non-existent entries doesn’t require any special preparation for TextEdit. Some Dictionary entries have pictures with them. (eg. “Elephant”.) Hopefully Colin doesn’t need those. :slight_smile:

on getDictionaryEntriesFor(myWords)
	set rtfFilePath to (path to desktop as Unicode text) & "Dictionary entries.rtf"
	tell application "Dictionary" to activate
	
	-- Open a file ready to received RTF data.
	set fRef to (open for access file rtfFilePath with write permission)
	try
		set eof fRef to 0
		
		repeat with myWord in myWords
			-- Set the clipboard to a known neutral value.
			tell application "Dictionary" to set the clipboard to missing value
			-- Request the Dictionary entry for this word.
			open location "dict:///" & myWord
			-- Wait for the word to appear in Dictionary's text field or until a one-second timeout.
			set timer to 0.0
			tell application "System Events"
				tell application process "Dictionary"
					repeat until (value of text field 1 of group 1 of tool bar 1 of front window is myWord's contents) or (timer is 1.0)
						delay 0.2
						set timer to timer + 0.2
					end repeat
				end tell
			end tell
			if (timer is 1.0) then
				-- If the search has timed out, display a "not found" message.
				beep
				tell application "Dictionary" to display dialog "No Dictionary entry was found for \"" & myWord & ".\"" buttons {"OK"} default button 1 with icon note giving up after 2
			else
				-- Otherwise commit the Dictionary entry to the clipboard.
				tell application "System Events"
					keystroke tab using shift down -- Cycle the focus in reverse. (Should suit either focus-tab preference.)
					keystroke "ac" using command down
				end tell
				-- Read the RTF data from the clipboard.
				tell application "Dictionary"
					repeat while ((the clipboard) is missing value)
						delay 0.2
					end repeat
					set dictionaryText to («class RTF » of (the clipboard as record))
				end tell
				-- Write the RTF data to the file.
				write dictionaryText to fRef
			end if
		end repeat
		
		-- Edit out the "}{" from between each RTF grouping in the file.
		-- TextEdit will rationalise the rest when it opens it.
		set dictionaryText to (read fRef from 1) -- (as text).
		set astid to AppleScript's text item delimiters
		set AppleScript's text item delimiters to "}{\\rtf1\\"
		set dictionaryText to dictionaryText's text items
		set AppleScript's text item delimiters to "\\rtf1\\"
		set dictionaryText to dictionaryText as string
		set AppleScript's text item delimiters to astid
		
		set eof fRef to 0
		write dictionaryText to fRef
		close access fRef
	on error msg
		display dialog msg buttons {"OK"} default button 1 with icon stop
		close access fRef
		error number -128
	end try
	
	tell application "TextEdit"
		activate
		open file rtfFilePath
	end tell
end getDictionaryEntriesFor

getDictionaryEntriesFor({"dog", "splx", "cat", "magic"})

Tristement, :(, I can’t even get parts of Nigel’s solution to work, specifically the part below feeds me two beeps and never stops in the repeat while clipboard is missing value loop.

set myWord to "magic"
tell application "Dictionary" to set the clipboard to missing value
-- Request the Dictionary entry for this word.
open location "dict:///" & myWord
-- Wait for the word to appear in Dictionary's text field or until a one-second timeout.
set timer to 0.0
tell application "System Events"
	tell application process "Dictionary"
		repeat until (value of text field 1 of group 1 of tool bar 1 of front window is myWord's contents) or (timer is 1.0)
			delay 0.2
			set timer to timer + 0.2
		end repeat
	end tell
end tell
if (timer is 1.0) then
	-- If the search has timed out, display a "not found" message.
	beep
	tell application "Dictionary" to display dialog "No Dictionary entry was found for \"" & myWord & ".\"" buttons {"OK"} default button 1 with icon note giving up after 2
else
	-- Otherwise commit the Dictionary entry to the clipboard.
	tell application "System Events"
		keystroke tab
		keystroke "ac" using command down
	end tell
	-- Read the RTF data from the clipboard.
	tell application "Dictionary"
		repeat while ((the clipboard) is missing value)
			delay 0.2
		end repeat
		set dictionaryText to («class RTF » of (the clipboard as record))
	end tell
	-- Write the RTF data to the file.
	write dictionaryText to fRef
end if

And I haven’t even tried Nigel’s yet! Sorry. I’ve used John’s:


set theFile to choose file with prompt "Select a text file:"
set mytext to read theFile
set myWords to words in mytext

repeat with myWord in myWords
...

and am busy processing the result, but I’m still going to go through all the solutions in detail.

The whole thing is due to my (6 year old) kiddies’ homework: They have made three concentric discs, of decreasing sizes. One set of 24 consonants (plus ‘th’ etc) on the outside, 5 vowels in the middle, and 10 consonants on the inside. They then have to rotate the discs and see how many words they can make.

So, they kept asking, “b.a.th is a word. Is c.a.d a word?” etc.

The following perl script generates all the word wheel words:

Hi, I can’t make these scripts to work. It seems the key command is not doing the right thing. On my OSX 10.4.10, Dictionary ver 1.0.1, after typing a query in the dictionary, then key doesn’t lead me to the word definition row. Therefore the succeeding <command+a> and <command+c> do not work either. Do you guys have any solution? Or where can I downgrade dictionary to 1.0.0 which may solve the problem?

Hi, Rio. Welcome to the BBS. :slight_smile:

My script works perfectly on my own OSX 10.4.10 machine “ BUT I’ve just realised that it relies on the “Full keyboard access” setting in the “Keyboard Shortcuts” tab of my “Keyboard & Mouse” preferences. My preferred setting is “Text boxes and lists only”; but if I change the setting to “All controls”, it takes two keystrokes instead of one to get to the right place. That might be what you need.

It may be possible for the script to detect the preference setting, but I’m afraid I don’t have time to look into it this weekend. If no-one else has done so by next week, I’ll have a go then…

HI Nigel,

I have tried to modify the settings in keyboard shortcut preferences, but neither of them could do the job. If I set to “Text boxes and lists only”, the key will select the query item, instead of jumping to word definition. The only way to do so on my machine is to click on the paragraph directly. I tried to modify my input methods (was using Japanese Romaji) to U.S. english, still no luck.

looking forward for your help, thanks…

The problem I was talking about a couple of days ago seems soluble by doing a shift-tab instead of a straight tab, to cycle the focus in reverse. This works for me, whatever the “Full keyboard access” preference. I’ve modified my script in post #7 above.

Another point is that the script can only access visible text. If either of Dictionary’s disclosure triangles (for “Dictionary” or “Thesaurus”) have been left closed, the script won’t be able to access the text for the relevant entries.

Otherwise, I’ve no idea why it doesn’t/didn’t work for Adam or for Rio. :frowning:

The modified version (#7 post) works perfectly for me now. The “trick” is the disclosure triangles. Both must be pointing down.

Unfortunately the trick doesn’t work for me.

I tried everything I could guess of, including:

  1. remove all the plugins in inputmanagers folder, both the system one and user one
  2. disable application enhancer
  3. trying to use the shortcut key in universal access (ctrl-F7) instead of tab
  4. make a new account, reboot

none of them works. :frowning:

will there be something else?

Hello Nigel,

Your script works on 10.5 Leopard! But I have trouble if the word is not in the dictionary. I don’t think the “timer” mechanism is the right answer.

In Leopard, I can’t get RTF data if the word is not in the dictionary. The focus area will always stay at the key-in field, so this line:

set dictionaryText to (« class RTF » of (the clipboard as record))

will get only utf8 data.

Is there a command to judge the class before this command?

thanks and best regards.

Is there any way we can use dictionary services instead
http://developer.apple.com/documentation/UserExperience/Reference/DictionaryServicesRef/Reference/reference.html#//apple_ref/c/func/DCSGetTermRangeInString

I know this link is for cocoa and not applescript - but can it be ported somehow ?

The above scripts don’t work for me :frowning:

Please also consider this solution :wink: