Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Python: Mac の辞書アプリをターミナルから利用するためのスクリプト
#!/usr/bin/python2.7
# coding: utf-8
"""Mac に備え付けの辞書アプリをコマンドラインで利用する
Usage:
/usr/bin/python2.7 __file__ < [検索したい単語を格納したファイル.txt]
See:
- Accessing Dictionaries
https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/DictionaryServicesProgGuide/access/access.html#//apple_ref/doc/uid/TP40006152-CH5-SW1
"""
import sys
# Mac の辞書サービス
from DictionaryServices import DCSGetTermRangeInString, DCSCopyTextDefinition
# 定数
# 標準入出力に使用するもの
ENCODING = 'utf-8'
# 辞書サービスに使用するもの
DICTIONARY = None
OFFSET = 0
# 設定値
config = {
# 入力された単語そのものを出力するかどうか
'print_word': True,
}
def get_stdin_with_encoding(encoding=None):
"""ジェネレータ: 標準入力を 1 行ずつ取得する取得する。
標準入力を 1 行ずつ取得し前処理をした後に返す。
- 先頭と末尾の空白、改行コードは削除する。
- 指定された文字コードでのデコード
Args:
encoding: 標準入力をデコードする際の文字コード。
Yields:
前処理(空白の削除、デコード)済の標準入力。
"""
while True:
# 標準入力から 1 行取得する。
# 前処理として空白の削除とデコードを行う。
line_raw = sys.stdin.readline().strip()
line = line_raw.decode(encoding) if encoding else line_raw
if not line:
break
yield line
def get_dict_definition(word):
"""指定した単語に対する定義を取得する。
Args:
word: 辞書で定義を取得したい単語。
Returns:
辞書で検索した単語の定義。該当するアイテムが存在しない場合は空文字列を返す。
"""
word_range = DCSGetTermRangeInString(DICTIONARY, word, OFFSET)
try:
word_definition = DCSCopyTextDefinition(DICTIONARY, word, word_range)
# 該当する単語が見つからなかった場合は空文字列を返す
except IndexError as e:
word_definition = ''
return word_definition
if __name__ == "__main__":
# 日本語の単語の場合はデコードしないと辞書で正しく引けないので utf-8 でデコードする
for word in get_stdin_with_encoding(ENCODING):
if config['print_word']:
print(word.encode(ENCODING))
print(get_dict_definition(word).encode(ENCODING))
@planeticus
Copy link

planeticus commented Jun 19, 2021

Hello,

I'm trying to use this code to look into the japanese dictionary.
However, I have a big problem with words that are written the same; the result of DCSCopyTextDefinition will inevitably be the first entry in gojuuon order.
For example, I tried looking for '先生' as in 'センセイ' and I got:
'シーサン 1【先生】〔中国語。上海地方の訛りから〕中国で,男子一般の名につけた敬称。呼び掛けにも用いた。'

Is there a way around it?

@gh640
Copy link
Author

gh640 commented Jun 19, 2021

Hi @planeticus,

Unfortunately I haven't found a way to work around the problem. It looks like the API doesn't provide a way as you may have already know:

https://developer.apple.com/documentation/coreservices/1446842-dcscopytextdefinition

I searched for the solution at the time but I couldn't find.

BTW, I myself didn't tried but someone made an effort to reverse-engineer the dictionary. Please take a look if you are interested:

https://fmentzer.github.io/posts/2020/dictionary/

The conversation in the following issue might be your help, too:

gh640/SublimeMacDictionary#10

@planeticus
Copy link

planeticus commented Sep 29, 2021

Hi @gh640,

sorry it took this long for me to tell you, but thanks so much!
Your comment made my day, and I managed to do what I wanted to do.

@gh640
Copy link
Author

gh640 commented Sep 29, 2021

@planeticus, thank you, too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment