HanDeDict für Apple Dictionary

Seit Mac OS X 10.5 Leopard kann man mit wenig Aufwand selbst Lexika erstellen, die dann genauso verwendet werden können wie die von Apple mitgelieferten.

Dieser Artikel zeigt, wie ein bestehendes Lexikons für Leopard konvertiert wird. Als Beispiel konvertieren wir das chinesisch-deutsche Lexikon HanDeDict. Der eigentliche Konvertierungsteil wird in Ruby implementiert.

Diejenigen, die lediglich das Lexikon verwenden wollen, können es hier herunterladen: HanDeDict.dictionary.zip (33,8 MB). (Update 20.04.2008:: Das jeweils aktuelle Download steht nun auf der HanDeDict-Downloadseite zur Verfügung!) Wer sich für die Erzeugung von Lexika für Apple Dictionary interessiert, sollte weiterlesen. :)

Projektsetup

Ausgangsbasis ist Mac OS X 10.5 mit installierten Development Tools. Zuerst kopieren wir uns das Projekt-Template aus dem Dictionary Development Kit:

cp /Developer/Extras/Dictionary\ Development\ Kit/project_templates/ ~/Desktop/HanDeDict

Von dem Inhalt des Verzeichnisses ~/Desktop/HanDeDict benötigen wir nur vier Dateien:

MyDictionary.xml
Diese Datei gibt ein Beispiel dafür, wie das XML-Format aussieht, aus dem ein Lexikon erstellt werden kann. Eine solche XML-Datei erzeugen wir später aus dem HanDeDict. Um das Projektsetup zu prüfen, lassen wir sie erst einmal bestehen. Allerdings geben wir ihr den Namen HanDeDict.xml.
MyDictionary.css
Für die Formatierung der Einträge im Lexikon wird CSS verwendet. Wir benennen diese Datei in HanDeDict.css um.
MyInfo.plist
In der Property List werden verschiedene Attribute unseres Lexikons beschrieben. Wir benennen diese Datei in HanDeDict.plist um.
Makefile
Das Makefile, mit dem wir unser Dictionary erstellen können. Innerhalb der Datei ändern wir die Dateinamen zu unseren Dateinamen, und geben den Namen unseres Lexikons an. Dazu ersetzen wir
DICT_NAME		=	"My Dictionary"
DICT_SRC_PATH		=	MyDictionary.xml
CSS_PATH		=	MyDictionary.css
PLIST_PATH		=	MyInfo.plist
durch
DICT_NAME		=	"HanDeDict"
DICT_SRC_PATH		=	HanDeDict.xml
CSS_PATH		=	HanDeDict.css
PLIST_PATH		=	HanDeDict.plist

Nun können wir das Lexikon testweise erstellen und installieren. Dazu verwenden wir make im Terminal. Mittels make install kopieren wir das erstellte Lexikon nach ~/Library/Dictionaries:

make && make install

In den Beispieldaten gibt es den Eintrag make, der nun im Lexikon (Dictionary.app) gefunden werden kann. Wird das Lexikon nicht angezeigt, muss es in den Einstellungen aktiviert werden.

Datenimport aus HanDeDict

In einem importer-Skript beginnen wir mit der Shebang-Zeile, die angibt, dass das Skript ein Ruby-Skript ist. danach schalten wir den UTF-8 Support von Ruby ein:

#!/usr/bin/env ruby
$KCODE = 'u'

Vom Terminal aus machen wir die Datei ausführbar:

chmod u+x importer

Zur Erzeugung der XML-Datei, aus der das Dictionary Development Kit den Inhalt des Lexikons liest, verwenden wir die Builder-Library von Jim Weirich. Sollte diese noch nicht installiert sein, hilft

sudo gem install builder

Dann importieren wir RubyGems und laden die Builder-Library:

require 'rubygems'
require 'builder'
Anschließend kopieren wir die UTF8-Version des HanDeDict namens handedict_nb.u8 in unser Projektverzeichnis, und lesen sie mittels Ruby-Code ein:
vocabulary = []

File.new(File.dirname(__FILE__) + '/handedict_nb.u8', 'r').each do |line|
  next if line !~ /^([^\s]+)\s+([^\s]+)\s+\[([^\]]+)\]\s+\/(.+)\/$/

  vocabulary << {:traditional => $1, 
    :simplified => $2, :pinyin => $3, :translations => $4.split('/')}
  end  
Um die XML-Datei zu erzeugen, verwenden wir die Builder-Library. Das Format schauen wir uns aus der umbenannten HanDeDict.xml ab:
File.open(File.dirname(__FILE__) + '/HanDeDict.xml', 'w') do |file|
  b = Builder::XmlMarkup.new(:target => file, :indent => 2)
  b.instruct!
  b.d :dictionary, :xmlns => "http://www.w3.org/1999/xhtml", 
      :'xmlns:d' => "http://www.apple.com/DTDs/DictionaryService-1.0.rng" do
    vocabulary.each_with_index do |entry, index|
      b.d :entry, :id => "handedict_#{index}", 
          :'d:title' => entry[:simplified] do
        b.d :index, :'d:value' => entry[:simplified]
        b.p do
          b.span entry[:simplified], :class => "entry_heading"
          b.text! " [#{entry[:pinyin]}]"
        end
        b.ol do
          entry[:translations].each do |translation|
            b.li translation
          end
        end
      end
    end
  end
end

Die Struktur ist recht einfach: Ein Lexikon dictionary enhält Einträge entry mit eindeutiger ID (Attribut id) und Titel (Attribut title). Innerhalb eines entry befinden sich ein oder mehrere Index-Einträge index (mit Attribut value) sowie der Inhalt des Eintrags. Das Dictionary Services Programming Guide gibt einen kompletten Überblick über das XML-Format.

Nun können wir die XML-Datei durch Aufruf des Skripts aufbauen und anschließend installieren:

./importer && make && make install

Leider hat diese Lösung noch ein Problem: UTF-8 Zeichen werden von der Builder-Library codiert (z.B. &#21621; statt 呵). Damit kann das Dictionary Development Kit nicht umgehen. Abhilfe schafft die neuste Version der Builder-Library aus dem Repository, die UTF-8 Zeichen unverändert lässt:

svn export svn://rubyforge.org/var/svn/builder/trunk builder
cd builder
rake builder:gem
sudo gem install pkg/builder-2.2.0.gem
cd ..

Nach einem erneuten ./importer && make && make install ist das Lexikon einsatzbereit.

Feinschliff

Vor der Veröffentlichung des Lexikons sollten wir noch einige Korrekturen durchführen: Die Einträge werden zu klein angezeigt, und wir müssen noch das Copyright angeben.

Um die Einträge größer anzuzeigen, ändern wir HanDeDict.css ab, so dass die Bereiche mit der CSS-Klasse entry_heading größer angezeigt werden. Mit dieser Klasse haben wir die Einträge im XML markiert.

@charset "UTF-8";
@namespace d url(http://www.apple.com/DTDs/DictionaryService-1.0.rng);

span.entry_heading {
  font-size: 150%;
  font-weight: bold;
}

In der Property List HanDeDict.plist setzen wir Attribute wie den Bundle Identifier, den Bundle Name, die Version und die Copyright-Information, und löschen nicht verwendete Attribute:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>Germany</string>
	<key>CFBundleIdentifier</key>
	<string>de.tammofreese.dictionary.HanDeDict</string>
	<key>CFBundleName</key>
	<string>HanDeDict</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>DCSDictionaryCopyright</key>
	<string>© 2003-2008 Chinesisch-Deutsche Gesellschaft e.V. Hamburg, Tammo Freese. Some rights reserved. See http://creativecommons.org/licenses/by-sa/2.0/de/</string>
	<key>DCSDictionaryManufacturerName</key>
	<string>Chinesisch-Deutsche Gesellschaft e.V. Hamburg, Tammo Freese</string>
</dict>
</plist>

Weitere, hier nicht im Detail gezeigte Korrekturen sind die Darstellung der Tonangaben mit Tonzeichen statt Zahlen (z.B. guó statt guo2), und die Indizierung und Anzeige der traditionellen Schreibweise der chinesischen Zeichen (falls vorhanden).

Jetzt erzeugen wir das Lexikon neu und haben eine zur Veröffentlichung geeignete Version.

Download

Das HanDeDict für Apple Dictionary kann hier heruntergeladen werden: HanDeDict.dictionary.zip (33,8 MB). Zur Installation muss das Verzeichnis HanDeDict.dictionary nach ~/Library/Dictionaries oder nach /Library/Dictionaries kopiert werden. Wird es nach ~/Library/Dictionaries kopiert, ist das Lexikon nur für den aktuellen Benutzer verfügbar. Das Kopieren in das Verzeichnis /Library/Dictionaries stellt das Lexikon für alle Benutzer zur Verfügung, allerdings sind für den Kopiervorgang Administratorrechte erforderlich. Wird das Lexikon nicht angezeigt, muss man es noch in den Einstellungen von Dictionary.app aktivieren.

Verwendung des HanDeDict für Apple Dictionary

Lexika sind ein schönes Beispiel dafür, wie weit Apple die Integration von Daten innerhalb des Systems treibt:

  1. Das Lexikon kann in der Lexikon-Applikation (Dictionary.app) verwendet werden:
  2. Auch im Dashboard-Widget steht es zur Verfügung:
  3. Über die Spotlight-Suche werden die Einträge im Lexikon ebenfalls gefunden:
  4. Über das Kontextmenü in Safari und vielen anderen Anwendungen kann mittels Look Up in Dictionary in den Lexika gesucht werden:
  5. Schließlich kann über das Tastaturkürzel ctrl-command-d das Wort unter dem Mauszeiger im Lexikon gesucht werden. Zur Anzeige dient hier nicht Dictionary.app, sondern ein Popup. Das Kürzel funktioniert auch in Anwendungen, in denen dem Kontextmenü der Menüpunkt Look Up in Dictionary fehlt: