You can make a difference in the Apple Support Community!

When you sign up with your Apple Account, you can provide valuable feedback to other community members by upvoting helpful replies and User Tips.

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Results from OpenThesaurus as a Service: How?

I'd like to create a Service to query the German OpenThesaurus. It kind of works, but the results that I get are a strange selection of the content. How should I proceed?


User uploaded file


User uploaded file


http://youtu.be/4g6LOljD_Bo

iMac, OS X Mountain Lion (10.8.5)

Posted on Oct 21, 2014 9:23 AM

Reply
3 replies

Oct 21, 2014 11:26 AM in response to Hans Elting

Hans,


Probably got as far as you.


In AppleScript action, set myWord to input as text. That should be sufficient to pass it to the next action. I can get the Get Definition of Word action to pop-up and stare at me, but continuing just gets an error, as the expected word is not passed to it. What I see in the Get Definition of Word action is a search field, and how to automatically populate that is troubling me.


Another approach, is to open Dicitionary App and in its preferences, drag the OpenThesaurus German entry to the top of the dictionary list. When you select a Word in text, or just place the mouse pointer over it, and three-finger tap on a trackpad (or control+command+D), the OpenThesaurus dictionary entry for this word pops up on screen. Here is a screen capture from Google translate, though I certainly knew what book was in German.😉


User uploaded file

Oct 22, 2014 3:51 AM in response to Hans Elting

Hans,


An Automator Service reduced to one line of bash script code that will launch the Apple Dictionary, and use the selected Deutsch wort, as the dictionary entry. Don't overlook a right-click on the word, then choose Service from the contextual menu, and this Service name. Assumes installation of OpenThesaurus Deutsch.


User uploaded file


If you were in Safari, then

dict:///finden


would launch the Apple Dictionary with the OpenThesaurus Deutsch results for finden.


And in Terminal:

open dict:///finden

Oct 22, 2014 8:26 PM in response to Hans Elting

Hello


I have tried the OpenThesaurus Deutsch.dictionary found at http://tekl.de/deutsch/Lexikon-Plugins.html and confirmed that the Automator action "Get Definition of Word" returns not the "best" match in the dictionary.


As far as I can tell, the Automator action uses an undocumented function DCSCopyRecordsForSearchString() of DictionaryServices framework and retrieve the first match result, which usually should be the primary match but not necessarily so when the OpenThesaurus Deutsch.dictionary returns results in strange order.


E.g., Given query = Beispiel, the headword retrieved from the DSCRecords returned by DCSCopyRecordsForSearchString() function is as follows.


leuchtendes Beispiel ← Beispiel

wie zum Beispiel ← Beispiel

nurals Beispiel ← Beispiel

schlagendes Beispiel ← Beispiel

Beispiel ⇒ abschreckendes Beispiel

Horror-Beispiel ← Beispiel

ein Beispiel nehmen an ← Beispiel

ohne Beispiel ← Beispiel

zum Beispiel ← Beispiel

Beispiel

mit gutem Beispiel vorangehen ← Beispiel

sehr gutes Beispiel ← Beispiel


And the Automator action returns the definition for the first record, whose headword = "leuchtendes Beispiel ← Beispiel", whereas the desired definition for the query would be for the headword = "Beispiel".


So the strange result we're seing is result of strange index order of OpenThesaurus Deutsch.dictionary and limitation of the "Get Definition of Word" action.


A remedy is to avoid the limited Automator action and use the DCSCopyRecordsForSearchString() function directly and select the record(s) whose headword matches the query word. The following RubyCocoa script demonstrates the method. However, RubyCocoa is no longer a part of standard installation of OSX 10.10 and you'd need to install it by yourself if you're running OSX 10.10.


cf.

http://rubycocoa.sourceforge.net/


* excerpt from RubyCocoa-1.2.0/doc/getting-started.md


## Build from Source


Extract RubyCocoa source from the '.tar.gz' file into a directory somewhere.


$ tar xzf RubyCocoa-x.x.x.tar.gz

$ cd RubyCocoa-x.x.x

$ ruby install.rb config

$ ruby install.rb setup

$ ruby install.rb test

$ sudo ruby install.rb intstall



Anyway, here's an Automator service workflow which should work under OSX 10.6 through 10.9.


0) Service receives selected [text] in [any application]


1) Run Shell Script action

- Shell = /bin/bash

- Pass input = as arguments

- Code = as follows


#!/bin/bash /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -w <<'EOF' - "$@" # # v0.10 # written by Hiroto, 2014-10 # require 'osx/cocoa' include OSX # OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/DictionaryServices.framework' # [1] while File.exist?(BSFILE = File.expand_path("/tmp/DictionaryServices.#{rand(1e10)}.bridgesupport")) do end Signal.trap("EXIT") { File.delete BSFILE if File.exist?(BSFILE) } File.open(BSFILE, "w") { |f| f.print DATA.read } OSX.load_bridge_support_file BSFILE # [2] File.delete BSFILE if File.exist?(BSFILE) # ----------------------------------------------------- # * some DictionaryServices functions (OS X 10.6.8) # # (undocumented) # # extern CFArrayRef DCSGetActiveDictionaries (void) # extern CFSetRef DCSCopyAvailableDictionaries (void) # extern DCSDictionaryRef DCSGetDefaultDictionary (void) # extern DCSDictionaryRef DCSGetDefaultThesaurus (void) # extern DCSDictionaryRef DCSDictionaryCreate (CFURLRef) # extern CFURLRef DCSDictionaryGetURL (DCSDictionaryRef) # extern CFStringRef DCSDictionaryGetName (DCSDictionaryRef) # extern CFStringRef DCSDictionaryGetIdentifier (DCSDictionaryRef) # # extern CFArrayRef DCSCopyRecordsForSearchString (DCSDictionaryRef, CFStringRef, unsigned long long, long long) # unsigned long long method # 0 = exact match # 1 = forward match (prefix match) # 2 = partial query match (matching (leading) part of query; including ignoring diacritics, four tones in Chinese, etc) # >=3 = ? (exact match?) # # long long max_record_count # # extern CFStringRef DCSRecordGetString (DCSRecordRef) # extern CFStringRef DCSRecordGetHeadword (DCSRecordRef) # extern CFStringRef DCSRecordGetRawHeadword (DCSRecordRef) # extern CFStringRef DCSRecordGetTitle (DCSRecordRef) # extern CFStringRef DCSRecordGetAnchor (DCSRecordRef) # extern CFURLRef DCSRecordGetDataURL (DCSRecordRef) # # extern CFStringRef DCSRecordCopyData (DCSRecordRef, long) # long output_style # 0 = XML XHTML <html> string # 1 = XML XHTML <html> string # 2 = XML XHTML <html> string # 3 = plain text # 4 = XML XHTML <text> string (single element) # * corresponding to (?) # Transform.xsl # TransformApp.xsl # TransformPanel.xsl # TransformSimpleText.xsl # TransformText.xsl # # (documented) # # CFStringRef DCSCopyTextDefinition (DCSDictionaryRef, CFStringRef, CFRange) # CFRange DCSGetTermRangeInString (DCSDictionaryRef, CFStringRef, CFIndex) # # ----------------------------------------------------- def dict(argv) # # array argv : array of queries # dictf = '/Library/Dictionaries/OpenThesaurus Deutsch.dictionary' url = NSURL.fileURLWithPath(dictf) dct, = DCSGetActiveDictionaries().select { |d| DCSDictionaryGetURL(d).path == url.path } argv.map {|a| a.to_ns }.each do |q| # [3] rr = DCSCopyRecordsForSearchString(dct, q, 0, 200) unless rr puts "Not found: %s" % q next end # q1 = nomalised query (NFKC, lowercase, w/o diacritical marks) CFStringTransform(q1 = q.mutableCopy, nil, 'NFKD; [:M:] Remove; NFC; lower()', false) rr.select { |r| # compare normalised headword (h1) and normalised query (q1) CFStringTransform(h1 = DCSRecordGetHeadword(r).mutableCopy, nil, 'NFKD; [:M:] Remove; NFC; lower()', false) h1 == q1 }.each do |r| # r = DCSRecordRef data = DCSRecordCopyData(r, 3) puts data puts end end end dict ARGV # # [1] DictionaryServices.framework/Resources/BridgeSupport/DictionaryServices.bridgesupport has problem to be fixed. # I.e., in signatures of DCSCopyTextDefinition(), DCSGetTermRangeInString() function etc, # {??=qq} should have been {_CFRange=qq} # {??=ii} should have been {_CFRange=ii} # [2] Fixed and extended bridgesupport file is loaded by OSX.load_bridge_support_file. # It now includes signatures for several undocumented functions as well. # [3] argv.to_ns is required to handle unicode characters correctly (in ruby 1.8). # __END__ <?xml version="1.0" standalone="yes"?> <!DOCTYPE signatures SYSTEM "file://localhost/System/Library/DTDs/BridgeSupport.dtd"> <signatures version="0.9"> <function name="DCSCopyTextDefinition"> <arg type="^{__DCSDictionary=}"></arg> <arg type="^{__CFString=}"></arg> <arg type64="{_CFRange=qq}" type="{_CFRange=ii}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSGetTermRangeInString"> <arg type="^{__DCSDictionary=}"></arg> <arg type="^{__CFString=}"></arg> <arg type64="q" type="l"></arg> <retval type64="{_CFRange=qq}" type="{_CFRange=ii}"></retval> </function> <function name="DCSDictionaryCreate"> <arg type="^{__CFURL=}"></arg> <retval type="^{__DCSDictionary=}"></retval> </function> <function name="DCSGetActiveDictionaries"> <retval type="^{__CFArray=}"></retval> </function> <function name="DCSCopyAvailableDictionaries"> <retval type="^{__CFSet=}"></retval> </function> <function name="DCSGetDefaultDictionary"> <retval type="^{__DCSDictionary=}"></retval> </function> <function name="DCSGetDefaultThesaurus"> <retval type="^{__DCSDictionary=}"></retval> </function> <function name="DCSDictionaryGetURL"> <arg type="^{__DCSDictionary=}"></arg> <retval type="^{__CFURL=}"></retval> </function> <function name="DCSDictionaryGetName"> <arg type="^{__DCSDictionary=}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSDictionaryGetIdentifier"> <arg type="^{__DCSDictionary=}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSCopyRecordsForSearchString"> <arg type="^{__DCSDictionary=}"></arg> <arg type="^{__CFString=}"></arg> <arg type="l"></arg> <arg type="l"></arg> <retval type="^{__CFArray=}"></retval> </function> <function name="DCSRecordGetHeadword"> <arg type="^{__DCSRecord=}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSRecordGetString"> <arg type="^{__DCSRecord=}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSRecordGetRawHeadword"> <arg type="^{__DCSRecord=}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSRecordGetTitle"> <arg type="^{__DCSRecord=}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSRecordGetAnchor"> <arg type="^{__DCSRecord=}"></arg> <retval type="^{__CFString=}"></retval> </function> <function name="DCSRecordGetDataURL"> <arg type="^{__DCSRecord=}"></arg> <retval type="^{__CFURL=}"></retval> </function> <function name="DCSRecordCopyData"> <arg type="^{__DCSRecord=}"></arg> <arg type="l"></arg> <retval type="^{__CFString=}"></retval> </function> </signatures> EOF



2) Run AppleScript action

- Code = as follows


on run argv set s to _join(argv's item 1, linefeed) activate display alert s end run on _join(tt, d) (* list tt : source list string d : separator return string : tt joined with d *) local astid0, t try set {astid0, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {} & d} set t to "" & tt set AppleScript's text item delimiters to astid0 on error errs number errn set AppleScript's text item delimiters to astid0 error errs number errn end try return t end _join




Automator Service workflow will look something like this.


User uploaded file



Codes are tested under 10.6.8.

OpenThesaurus Deutsch.dictionary is assumed to have been installed as /Library/Dictionaries/OpenThesaurus Deutsch.dictionary


Regards,

H

Results from OpenThesaurus as a Service: How?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.