在OSX上以编程方式使用Dictionary.app的同义词库函数(最好是通过Ruby)

时间:2009-04-24 04:44:10

标签: ruby macos scripting dictionary

我需要编写一个带有单词的Ruby方法,通过OS 10.5的Dictionary.app的同义词库函数运行它,并返回替代单词。

如果Ruby方法最终调用命令行,那很好;我只需要能够以Ruby编程方式完成它。

在浏览Ruby OSA之后,我意识到可以通过一些字典服务[http://discussions.apple.com/thread.jspa?threadID=1561332]访问字典,但我真的没有。

有人看到一个简单的解决方案吗?

我还打算制作一个Automator工作流并从命令行调用它,但由于某种原因,我无法从shell中正确地提供“Get Definition”函数(它一直说它不能找不到这个词,但是当手动查看时它会起作用。)

2 个答案:

答案 0 :(得分:17)

不幸的是,这个(字典服务)的唯一编程接口不支持设置字典。

但是,它确实会查阅字典首选项以使用指定的第一个字典,因此您可能会以非常丑陋的方式重置首选项,因此同义词库是唯一可用的字典。

这真的很令人作呕,并且可能会因为喘不过气来打破,但它应该有效:

/* 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"];
}

并将其用作:

% ./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.
[...]

答案 1 :(得分:7)

我已将代码更新为10.7&amp; 10.8。归功于Nicholas Riley;没有他,我就无法写出来!

我稍微修改了它以允许您为查找选择字典,使用它像: $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);
}