2009-04-24 8 views
8

Ich muss eine Ruby-Methode schreiben, die ein Wort nimmt, sie durch die Thesaurus-Funktion von Dictionary.app von OS 10.5 ausführt und alternative Wörter zurückgibt.Die Thesaurus-Funktion von Dictionary.app programmgesteuert auf OSX verwenden (vorzugsweise via Ruby)

Wenn die Ruby-Methode die Befehlszeile aufruft, ist das in Ordnung; Ich muss es nur programmatisch von Ruby aus tun können.

Nachdem ich durch Ruby OSA gesehen habe, merke ich, dass das Wörterbuch durch einen Wörterbuchdienst [http://discussions.apple.com/thread.jspa?threadID=1561332] zugänglich ist, aber ich verstehe es nicht wirklich.

Wer sieht eine einfache Lösung?

Ich war auch für einen Automator-Workflow und Aufruf von der Kommandozeile aus, aber ich konnte die "Get Definition" -Funktion aus irgendeinem Grund nicht richtig mit einem Wort aus der Shell füllen (es hieß immer so konnte das Wort nicht finden, aber wenn es manuell geschaut wurde, funktionierte es).

Antwort

16

Leider unterstützt die einzige programmatische Schnittstelle dazu (Dictionary Services) nicht das Einstellen eines Wörterbuchs.

Es werden jedoch die Wörterbucheinstellungen zur Verwendung des ersten angegebenen Wörterbuchs herangezogen, sodass Sie die Voreinstellungen möglicherweise sehr hässlich zurücksetzen können, sodass der Thesaurus das einzige verfügbare Wörterbuch ist.

Das ist wirklich ekelhaft und wahrscheinlich, wenn atmete brechen auf, aber es sollte funktionieren:

/* compile with: 

    gcc -o thesaurus -framework CoreServices -framework Foundation thesaurus.m 
*/ 

#import <Foundation/Foundation.h> 
#include <CoreServices/CoreServices.h> 

int main(int argc, char *argv[]) { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
    NSMutableDictionary *dictionaryPrefs = 
    [[userDefaults persistentDomainForName:@"com.apple.DictionaryServices"] mutableCopy]; 

    NSArray *activeDictionaries = [dictionaryPrefs objectForKey:@"DCSActiveDictionaries"]; 

    [dictionaryPrefs setObject: 
    [NSArray arrayWithObject:@"/Library/Dictionaries/Oxford American Writer's Thesaurus.dictionary"] 
         forKey:@"DCSActiveDictionaries"]; 
    [userDefaults setPersistentDomain:dictionaryPrefs forName:@"com.apple.DictionaryServices"]; 

    NSString *word = [NSString stringWithUTF8String:argv[1]]; 
    puts([(NSString *)DCSCopyTextDefinition(NULL, (CFStringRef)word, 
              CFRangeMake(0, [word length])) UTF8String]); 

    [dictionaryPrefs setObject:activeDictionaries forKey: @"DCSActiveDictionaries"]; 
    [userDefaults setPersistentDomain:dictionaryPrefs forName:@"com.apple.DictionaryServices"]; 
} 

Und verwenden Sie es als:

% ./thesaurus string 
noun 
1 twine, cord, yarn, thread, strand. 
2 chain, group, firm, company. 
3 series, succession, chain, sequence, run, streak. 
4 line, train, procession, queue, file, column, convoy, cavalcade. 
[...] 
+0

+1, gut gemacht! Weg mich zu schlagen! – rampion

+0

Hey, danke für das Posten dieses-- Ich habe gerade kompiliert und versucht, es auf Mountain Lion zu verwenden, und es gibt das Wörterbuch anstelle Thesaurus-Eintrag zurück. Irgendeine Idee, wie man es für Mountain Lion anpasst? Oder ist jetzt vielleicht eine sauberere Lösung möglich? –

+0

Sieht nicht so aus, als hätte sich die Dictionary-Services-API seit 10.5 geändert (datei einen Fehler!), Aber "DCSActiveDictionaries" wurde in "NSGlobalDomain" unter dem Schlüssel "com.apple.DictionaryServices" in 10.7 verschoben. –

7

ich den Code aktualisiert haben für 10.7 zu arbeiten & 10.8. Alles an Nicholas Riley; Ich hätte es nicht ohne ihn schreiben können!

ich geändert habe es leicht, damit Sie das Wörterbuch für die Suche wählen, verwenden Sie es mögen: $dictionary $PATH_TO_DICT $word

#import <Foundation/Foundation.h> 
#include <CoreServices/CoreServices.h> 

NSUserDefaults* GetUserDefaults() { 
    return [NSUserDefaults standardUserDefaults]; 
} 

NSMutableDictionary* GetGlobalDomain() { 
    NSUserDefaults *userDefaults = GetUserDefaults(); 
    NSMutableDictionary *dictionaryPrefs = 
    [[userDefaults persistentDomainForName:@"Apple Global Domain"] mutableCopy]; 
    return dictionaryPrefs; 
} 

NSMutableDictionary* GetDictionaryPreferences() { 
    return [[GetGlobalDomain() objectForKey:@"com.apple.DictionaryServices"] mutableCopy]; 
} 

NSArray* GetCurrentDictionaryList() { 
    return [GetDictionaryPreferences() objectForKey:@"DCSActiveDictionaries"]; 
} 

void SetUserDictPreferences(NSArray* array) { 
    NSMutableDictionary *currentPref = GetDictionaryPreferences(); 
    [currentPref setObject:array forKey:@"DCSActiveDictionaries"]; 
    NSDictionary *immutPref = [NSDictionary dictionaryWithDictionary:currentPref]; 
    NSMutableDictionary *g = GetGlobalDomain(); 
    [g setObject:immutPref forKey:@"com.apple.DictionaryServices"]; 
    NSUserDefaults *defaults = GetUserDefaults(); 
    [defaults setPersistentDomain:g forName:@"Apple Global Domain"]; 
} 


int main(int argc, char *argv[]) { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSArray *currentPrefs = GetCurrentDictionaryList(); 

    NSString *dict = [NSString stringWithUTF8String:argv[1]]; 
    NSString *word = [NSString stringWithUTF8String:argv[2]]; 
    SetUserDictPreferences([NSArray arrayWithObject:dict]); 
    puts([(NSString *)DCSCopyTextDefinition(NULL, (CFStringRef)word, 
              CFRangeMake(0, [word length])) UTF8String]); 

    SetUserDictPreferences(currentPrefs); 
}