Trên một luồng nhận xét khá mơ hồ, ai đó đã giải thích nơi bạn có thể tìm thấy danh sách từ mà Apple sử dụng để cấp nguồn cho trình bảo vệ màn hình. Đó là tại /System/Library/Graphics/Quartz\ Composer\ Plug-Ins/WOTD.plugin/Contents/Resources/NOAD_wotd_list.txt
. Các tập tin trông như thế này:
m_en_us1282510 quinsy
m_en_us1273791 orbicular
m_en_us1220945 alimony
m_en_us1250517 genome
Nó là một danh sách các mục được phân tách bằng tab. Ở bên phải bạn có từ và bên trái, trông giống như một ID. Nhưng ID đó dùng để làm gì và làm thế nào bạn có thể tìm thấy nó cho một từ khác chưa có trong danh sách?
Như bạn có thể mong đợi, ID đề cập đến một mục trong từ điển mặc định của Apple, "Từ điển Oxford Mỹ mới". (Đó là những gì "NOAD" đại diện cho đường dẫn danh sách từ ở trên.)
Làm thế nào để tìm ID cho các từ khác?
Một đồng nghiệp tên Joseph Gentle, trong một loạt các bài đăng trên blog, cho thấy cách lấy dữ liệu dựa trên từ điển của Apple. Trong bài đăng "Từ điển Apple, phần 2" của mình, ông chỉ ra mã giải nén tệp nhị phân có liên quan (được lưu trữ /Library/Dictionaries
) thành XML. Sử dụng các tệp dedict.c
và strip.c
tệp được tìm thấy ở đây và theo ví dụ của Gentle, tôi đã sử dụng các lệnh bash sau để lấy XML của NOAD (các lệnh này được chạy từ thư mục nơi bạn đã tải xuống tệp dedict.c
và strip.c
tệp):
clang dedict.c -Wall -lz -o dedict
clang strip.c -Wall -lz -o strip
./dedict "New Oxford American Dictionary" | ./strip > dict.xml
Khi tôi head
đọc vài dòng đầu tiên của dict.xml
tập tin, tôi thấy một cái gì đó đầy hứa hẹn, với các mục giống như thế này:
<d:entry xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng" id="m_en_us1219333" d:title="abode" class="entry">
Lưu ý rằng id
param ... đó là một mã định danh trông giống hệt như trong danh sách từ của trình bảo vệ màn hình!
Tôi đã viết tập lệnh Ruby sau để phân tích cú pháp XML và sau đó, bằng cách sử dụng danh sách từ của riêng tôi, tạo một tệp bảo vệ màn hình mới ánh xạ các từ của riêng tôi sang ID của chúng trong từ điển:
raw = File.open("./dict.xml").read
my_words = File.open("./word_list.csv").readlines.map { |line| line.split(',')[1] }
word_id_map = {}
raw.scan(/<d:entry .*? id="(.*?)" d:title="(.*?)" class="entry">/).each do |entry|
word_id_map[entry[1]] = entry[0]
end
my_words.each do |word|
if id = word_id_map[word]
puts [id, word].join(' ')
end
end
Khi tôi thay thế tệp bảo vệ màn hình gốc bằng tệp mới này, nó đã hoạt động. Bây giờ bạn có thể có một trình bảo vệ màn hình "Word of the Day" cung cấp các định nghĩa cho các từ bạn chọn.