Creating MacOS dictionary

I often use the vocabulary.com website, I find it very useful when I need to find a meaning of some word. However it is quite annoying to go there every time and I decided to create a local dictionary for MacOS. If you didn’t know you can get definition of almost any word just pressing Ctrl + Cmd + D.

I wrote a python script which received description of words from Vocabulary and put them into a file. I’m not going to share this script, because I respect Vocabulary team’s work and don’t want to spoil their work, so it’s up to you how you going to get the data. After that, I wrote a script that parsed that file and created xml file from it needed to compile MacOS dictionary:

import string
from bs4 import UnicodeDammit
try:
    from BeautifulSoup import BeautifulSoup
except ImportError:
    from bs4 import BeautifulSoup

HEADER = '''
<?xml version="1.0" encoding="UTF-8"?>
<d:dictionary xmlns="http://www.w3.org/1999/xhtml" xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng">
'''
FOOTER = '''
</d:dictionary>
'''

def create_entry(content, added):
    content = content.replace(' class="long"', '')
    content = content.replace(' class="short"', '')
    #content = content.replace('\xe2\x80\x94', ' - ')
    index = content.find(':')
    if index == -1:
        return 0
    word = content[:index]
    if word in added:
        return 0
    added.append(word)
    content = content[index+1:]
    index = content.find(':')
    if index == -1:
        return 0
    s = content[:index]
    l = content[index+1:]
    entry = '<d:entry id="' + word.replace(' ', '_') + '" d:title="' + word + '">'
    entry += '<d:index d:value="' + word + '"/>'
    entry += '<h1>' + word + '</h1>'
    entry += s
    entry += l
    entry += '</d:entry>'
    return entry


xml = HEADER
alphabet = list(string.ascii_lowercase)
added = []
for char in alphabet:
    print(char)
    f = open(char + '_full_vocabulary.txt', 'r')
    for line in f:
        entry = create_entry(line, added)
        if entry == 0:
            continue
        if entry == "":
            continue
        xml += entry
    f.close()


xml += FOOTER
newxml = UnicodeDammit(xml, ["windows-1252"], smart_quotes_to="ascii").unicode_markup
final_xml = BeautifulSoup(newxml, "lxml")
f = open('MyDictionary.xml', 'w')
f.write(final_xml.prettify())
f.close()

In case if someone is going to use this script, the create_entry function just takes a line from your raw file, parses it and then adds correct xml entry to the added list., then this list is assembled and written into the MyDictionary.xml file. Also, I must notice that in my case all the meanings are saved under [a-z]_full_vocabulary.txt files and the script opens them in order.

After you created your xml file you need to compile it into Apple Dictionary Format. Apple says that Dictionary Development Kit is part of Xcode, but I didn’t manage to find it. There’s the GitHub repo containing all the files. You need to copy your xml file to the folder and compile your dictionary.

git clone https://github.com/SebastianSzturo/Dictionary-Development-Kit
cd Dictionary-Development-Kit/project_templates/
cp [YOUR_PATH]/MyDictionary.xml ./

Open Makefile in any text editor and set the DICT_BUILD_TOOL_DIR variable to ../.

And then:

make
make install

After that you can open your Dictionary.app and turn your dictionary on.