root/tags/release-0.6.2/doc/Plugin-HOWTO.html

Revision 5, 15.2 kB (checked in by mjoc, 2 years ago)

Project website changed to http://opendict.inhangar.com, some text
modifications.

Line 
1 <html>
2 <head>
3    <meta http-equiv="Content-Type" content="text/html;
4    charset=UTF-8"/>
5    <title>OpenDict Add-Ons Development HOWTO</title>
6 </head>
7 <style>
8 body
9 {
10     font-family: Verdana, Arial, Sans, sans-serif;
11     font-size: 12px;
12     color: #555;
13 }
14
15 h1
16 {
17     font-size: 26px;
18     text-align: center;
19     font-weight: normal;
20     color: #2b4d85;
21 }
22
23 h2
24 {
25     color: #2b4d85;
26     border-bottom: 1px dashed #2b4d85;
27     margin: 0px;
28     margin-top: 20px;
29     margin-bottom: 10px;
30 }
31
32 div.footer
33 {
34     text-align: center;
35     font-size: 10px;
36     background-color: #EEE;
37     border: 1px solid #D9D9D9;
38     color: #AAA;
39 }
40
41 a
42 {
43     color: #2b4d85;
44 }
45
46 a:active, a:hover
47 {
48     background-color: #DDD;
49 }
50
51 pre.file-contents
52 {
53     border: 1px solid #AAA;
54     margin-left: 30px;
55     width: 600px;
56     background-color: #EEE;
57 }
58
59 table
60 {
61     font: inherit;
62     border: 1px solid #AAA;
63     border-collapse: collapse;
64     margin-left: 30px;
65     width: 600px;
66 }
67
68 table td, table, th
69 {
70     border: 1px solid #DDD;
71     padding: 5px;
72 }
73 </style>
74 <body>
75 <h1>OpenDict Add-Ons Development HOWTO</h1>
76
77 <h2>Introduction</h2>
78 <p>
79 OpenDict is free multiplatform dictionary. More information about it
80 can be found on <a href="http://opendict.inhangar.com">OpenDict website</a>.
81 </p>
82 <p>
83 This document is written for developers who want to make
84 easy-installable OpenDict dictionaries.
85 </p>
86 <p>
87 <i><b>Warning:</b> It is not necessary to make OpenDict dictionary if you
88 have a dictionary file in Slowo, Mova or DICT format. Such
89 dictionaries can be used right now by selecting <u>Dictionaries ->
90 Install Dictionary from File</u> from OpenDict menu.</i>
91 </p>
92
93 <h2>Types of OpenDict Dictionaries</h2>
94 <p>
95 OpenDict has two types of dictionaries: <i>plain</i> (simple) dictionaries and
96 <i>plugin</i> (complex)
97 dictionaries. <i>Plain</i> dictionaries consists of dictionary file (type of
98 that dictionary must be supported by OpenDict) and description file in
99 XML format. <i>Plugin</i> dictionaries consists of Python module with code
100 that handles search process and description file in XML format; it
101 may also have dictionary file which is processed by Python module
102 mentioned above.
103 </p>
104 <p>
105 Plain dictionaries are simple and handy. It is very easy to install
106 them using OpenDict itself. If you have dictionary file (format of
107 that dictionary must be supported by OpenDict) and want to attach some
108 information to it, like the name, the author, the description, you may
109 want to make <i>plain</i> dictionary.
110 </p>
111 <p>
112 If you have more complex task, like search the web, etc, you may want
113 to make a <i>plugin</i> for OpenDict. The plugin is a chunk of code
114 written in <a href="http://www.python.org">Python</a> programming
115 language that OpenDict attaches to itself at runtime.
116 </p>
117 <p>
118 The next sections of this document will describe how to make
119 <i>plain</i> dictionaries and <i>plugins</i>.
120 </p>
121
122 <h2>Plain Dictionary Example</h2>
123 <p>
124 Assume we have a small dictionary file named <i>mydict.dwa</i> in Slowo
125 format:
126 </p>
127
128 <pre class="file-contents">
129 above = ant ; virš ;
130 abroad = visur ; užsienyje ;
131 acoustic = akustinis ;
132 acquaint = pranešti ;
133 </pre>
134
135 <p>
136 Say we want to call this dictionary "My Personal Dictionary" and
137 attacht a description "This is my personal dictionary. It is very
138 small, but it is not the size that matters :)" to it.
139 <i>Each</i> plain dictionary must have XML description file named
140 <i>config.xml</i>, otherwise it will be treated as invalid dictionary. So we
141 write an XML file called config.xml with our favorite text or XML editor:
142 </p>
143
144 <pre class="file-contents">
145 &lt;?xml version='1.0' encoding='UTF-8'?&gt;
146 &lt;plain-dictionary&gt;
147   &lt;format&gt;slowo&lt;/format&gt;
148   &lt;name&gt;My Personal Dictionarys&lt;/name&gt;
149   &lt;version&gt;0.1&lt;/version&gt;
150   &lt;authors&gt;
151      &lt;author name="Your Name" email="your@email.tdl"/&gt;
152   &lt;/authors&gt;
153   &lt;path&gt;mydict.dwa&lt;/path&gt;
154   &lt;md5&gt;9c62810c32ca20fe018b79987789daef&lt;/md5&gt;
155   &lt;encoding&gt;UTF-8&lt;/encoding&gt;
156   &lt;description&gt;&lt;![CDATA[
157      This is my personal dictionary. It is very small, but it is not the
158      size that matters :)
159   ]]&gt;
160   &lt;/description&gt;
161 &lt;/plain-dictionary&gt;
162 </pre>
163
164 <p>
165 As you can see, a little more information must be added to description
166 (i.e. configuration) file. Here is a short description of each section:
167 </p>
168
169 <table>
170 <tr>
171     <th>XML tag</th>
172     <th>Description</th>
173 </tr>
174 <tr>
175     <td>format</td>
176     <td>Dictionary format. OpenDict supports the following formats:
177         <ul>
178             <li>slowo -- Slowo format</li>
179             <li>mova -- Mova format</li>
180             <li>dict -- DICT format</li>
181         </ul>
182         <i>TODO: describe all supported format somewhere</i>
183     </td>
184 </tr>
185 <tr>
186     <td>name</td>
187     <td>Name of the dictionary. It will be shown in the
188     <i>Dictionaries</i> menu in OpenDict window.
189 </td>
190 </tr>
191 <tr>
192     <td>version</td>
193     <td>Version value is very important. It shows the freshness of
194     your dictionary. The more recent the dictionary, the greater
195     version value must be set. For example: 0.1, 0.2, 0.3, etc; or 1,
196     2, 3, etc.</td>
197 </tr>
198 <tr>
199     <td>author</td>
200     <td>
201     <p>The author of the dictionary. Notice that <i>author</i> tag is
202     inside <i>authors</i> tag, because there may be several
203     authors of the dictionary. So add as may <i>author</i> tags as you
204     want, but make them the childs of the <i>authors</i> tag.</p>
205
206     <p>This tag is a bit complicated, because you may not be the
207     author of the dictionary file you are using. If so, you may treat
208     the <i>author</i> tag as maintainance tag and write your <i>as
209     maintainer</i> name inside it. In addition to this, you should
210     write the name of the author in the <i>description</i> tag
211     mentioned below.
212 </td>
213 </tr>
214 <tr>
215     <td>path</td>
216     <td>Path to the dictionary file. It may be an absolute (i.e. full)
217     path to the dictionary file or relative path. If you write full
218     path, dictionary would be taken from there. Buf if you write only
219     the name of the dictionary (i.e. mydict.dwa), the dictionary will
220     be treated to be located at <i>$DICTDIR/file/mydict.dwa</i>, where
221     $DICTDIR is directory where you dictionary is located, for example
222     <i>/home/mjoc/.opendict/dictionaries/plain/mydict.dwa/file/mydict.dwa</i>.
223     If you are going to distribute dictionary file <i>with OpenDict
224     plain dictionary</i>, you want to write only the file name inside
225     <i>path</i> tag.
226 </td>
227 </tr>
228 <tr>
229     <td>md5</td>
230     <td>This is an MD5 checksum value of the dictionary file
231     (i.e. mydict.dwa). This MD5 code is used to determine changes
232     of the dictionary file. That means user is able to modify
233     dictionary file and OpenDict will recreate <i>index table</i>
234     before using that dictionary next time. If you want to get MD5
235     checksum value of you dictionary file, execute the following
236     command on your system (Linux, BSD) shell:
237     <pre>
238         $ md5sum myfile.dwa
239         9c62810c32ca20fe018b79987789daef  myfile.dwa
240     </pre>
241     You can see the command and the output above. Just copy that
242     32-chars checksum to your XML file. <i>This is quite unfriendly,
243     so I will think about easer ways some day. Nevertheless, we are
244     developers today.</i>
245     </td>
246 </tr>
247 <tr>
248     <td>encoding</td>
249     <td>Character encoding of the dictionary file. Examples: UTF-8,
250     UTF-16, ISO-8859-1, ISO-8859-13, etc.</td>
251 </tr>
252 <tr>
253     <td>description</td>
254     <td>Description of your dictionary. You should not remove that
255     <i>&lt;![CDATA[ ... ]]&gt;</i> tag, because it lets you to write
256     any text inside using even XML (HTML) tags like <i>1 + 1 &lt;
257     1</i> or <i>&lt;myemail@abcdef.tdl&gt;</i>
258 </td>
259 </tr>
260 </table>
261
262 <p>
263 The last file you need is an <i>index</i> file. This file contains
264 index table of the dictionary describing in what position what letter
265 begins. Index makes search <i>a lot faster</i>.
266 </p>
267
268 <p>
269 I do not recommend writing index file using your fingers and the
270 keyboard :), so we will use OpenDict to make one for ourselves. Lets
271 now make a directory tree containing these files and directories:
272 </p>
273
274 <pre>
275 mydict.dwa/
276     |
277     +-- conf/
278     |     |
279     |     +-- config.xml
280     |
281     +-- data/
282     |     
283     |
284     +-- file/
285           |
286           +-- mydict.dwa
287 </pre>
288
289 <p>
290 As you see, the root direcory is called <i>mydict.dwa</i>, the same as
291 dictionary file is called. This is <i>the rule</i>. Now move that
292 directory to the directory where all the plain dictionaries are
293 located. On my machine I would do:
294 </p>
295
296 <pre>
297     mjoc@kumo:~/tmp/dict-factory$ <i>mv mydict.dwa/ ~/.opendict/dictionaries/plain/</i>
298 </pre>
299
300 <p>
301 After that you should start OpenDict and load the dictionary you've
302 just made. If everything goes well, you will be informed about
303 reindexing the dictionary. Press <i>OK</i> and, if everything goes
304 well, you will have index.xml file located at data/ directory. On my
305 machine the full path would be
306 <i>/home/mjoc/.opendict/dictionaries/plain/mydict.dwa/data/index.xml</i>.
307 Now the directory tree look in a way like that:
308 </p>
309
310 <pre>
311 mydict.dwa/
312     |
313     +-- conf/
314     |     |
315     |     +-- config.xml
316     |
317     +-- data/
318     |     |
319     |     +-- index.xml
320     |
321     +-- file/
322           |
323           +-- mydict.dwa
324 </pre>
325
326 <p>
327 Now we have all the files needed. They are located at $DICTDIR. The
328 last step is to make a ZIP archive of that directory. Notice that that
329 ZIP file must contain the dictionary directory (i.e. mydict.dwa/)
330 itself, not only files inside it. To zip the directory, I would do:
331 </p>
332
333 <pre>
334     mjoc@kumo:~/tmp/dict-factory$ cd ~/.opendict/dictionaries/plain/
335     mjoc@kumo:~/.opendict/dictionaries/plain$ zip -r MyDictionary-0.1.zip mydict.dwa/
336     mjoc@kumo:~/.opendict/dictionaries/plain$ mv MyDictionary-0.1.zip ~
337     mjoc@kumo:~/.opendict/dictionaries/plain$ cd
338 </pre>
339
340 <p>
341 Now file <i>MyDictionary-0.1.zip</i> can be found at my home direcory
342 (/home/mjoc/). That's all. Now you have made a dictionary that can be
343 installed by everyone using OpenDict by selecting <i>Dictionaries ->
344 Install Dictionary from File</i> from the menu.
345 </p>
346
347 <h2>Simple Plugin Example</h2>
348 <p>
349 In this section I am going to give an example of simple OpenDict
350 plugin dictionary. Good example is a network dictionary plugin that
351 fetches translations from the web and processed them locally.
352 </p>
353
354 <p>
355 At first we have to create file called <i>plugin.xml</i>. The contents
356 of this file may be similar to this one:
357 </p>
358
359 <pre class="file-contents">
360 &lt;?xml version="1.0" encoding="UTF-8"?&gt;
361 &lt;plugin type="dictionary"&gt;
362    &lt;name&gt;Network Test&lt;/name&gt;
363    &lt;version&gt;0.1&lt;/version&gt;
364    &lt;authors&gt;
365       &lt;author name="Martynas Jocius" email="mjoc@akl.lt" /&gt;
366    &lt;/authors&gt;
367    &lt;module lang="Python"&gt;mydict.py&lt;/module&gt;
368    &lt;encoding&gt;UTF-8&lt;/encoding&gt;
369    &lt;uses-word-list&gt;False&lt;/uses-word-list&gt;
370    &lt;opendict-version&gt;0.5.7&lt;/opendict-version&gt;
371    &lt;python-version&gt;2.3&lt;/python-version&gt;
372    &lt;platforms&gt;
373       &lt;platform name="Linux" /&gt;
374       &lt;platform name="BSD" /&gt;
375       &lt;platform name="Windows" /&gt;
376    &lt;/platforms&gt;
377    &lt;description&gt;
378    Example plugin dictioary. Does nothing.
379    &lt;/description&gt;
380 &lt;/plugin&gt;
381 </pre>
382
383 <p>
384 As you may already noticed, some XML tags are the same as in the
385 previous <i>config.xml</i> example. There is the description of new
386 tags, like <i>encoding</i>, <i>module</i>, etc.
387 </p>
388
389 <table>
390 <tr>
391     <th>XML tag</th>
392     <th>Description</th>
393 </tr>
394 <tr>
395     <td>module</td>
396     <td>Main <a href="http://www.python.org">Python</a> module file name.</td>
397 </tr>
398 <tr>
399     <td>encoding</td>
400     <td>Character encoding of the result string that plugin module
401     returns (examples include UTF-8, ISO-8859-15, etc)</td>
402 </tr>
403 <tr>
404     <td>uses-word-list</td>
405     <td>This should be set to <i>True</i> if dictionary needs word
406     list to be shown, <i>False</i> otherwise. If dictionary uses word
407     list, it must return a list of alternative words in addition with
408     translation string (<i>see below for more information</i>)</td>
409 </tr>
410 <tr>
411     <td>opendict-version</td>
412     <td>The lowest OpenDict version plugin requires, for example
413     0.5.1, 0.5.7, etc. This is important when plugin structure is
414     different from one that old OpenDict versions provide (for example 0.5.1
415     and 0.5.7 plugin structure differs a lot)</td>
416 </tr>
417 <tr>
418     <td>python-version</td>
419     <td>The lowest Python version that plugin requires.</td>
420 </tr>
421 <tr>
422     <td>python-version</td>
423     <td>The lowest Python version that plugin requires.</td>
424 </tr>
425 <tr>
426     <td>platforms</td>
427     <td>Parent node for <i>platform</i> tag.</td>
428 </tr>
429 <tr>
430     <td>platform</td>
431     <td>This tag with attribute <i>name</i> value X means that this
432     plugin is tested and works on platform X. For example, Linux, BSD,
433     MacOS. <i>Currently not used</i></td>
434 </tr>
435 </table>
436
437 <p>
438 Now we should write the main module in Python programming
439 language. Module file name is <i>mydict.py</i> as we called it in
440 <i>plugin.xml</i>. The following code might be correct OpenDict plugin:
441 </p>
442
443 <pre class="file-contents">
444 #!/usr/bin/env python
445
446 #
447 # MyDict 0.1
448 # Copyright (c) 2005 Matynas Jocius &lt;mjoc@akl.lt&gt;
449 #
450 # Simple plugin dictionary for OpenDict.
451 #
452 # This code is licensed under the GNU GPL v2.
453 #
454
455 """
456 Simple OpenDict plugin module
457 """
458
459 import sys
460 import httplib
461 import urllib
462
463
464 def init(libraryPath):
465     """Return dictionary instance"""
466
467     sys.path.insert(0, libraryPath)
468
469     return MyDict()
470
471
472
473 class MyDict:
474     """MyDict plugin class"""
475    
476     def __init__(self):
477         """Initialize variables"""
478
479         # This trick is needed to have accessible modules from
480         # OpenDict library
481         from lib import errortype, meta
482
483         self.errorModule = errortype
484         self.metaModule = meta
485
486        
487     def search(self, word):
488         """Search and return HTML code."""
489
490         print type(word), len(word)
491
492         result = self.metaModule.SearchResult()
493
494         try:
495             self.conn = httplib.HTTPConnection("mjoc.sig.lt")
496             self.conn.request("GET", "/index.html")
497             response = self.conn.getresponse()
498             data = response.read()
499
500             trans = "&lt;html&gt;&lt;body&gt;&lt;h3&gt;"
501
502             if word in data:
503                 trans += "Word &lt;i&gt;%s&lt;/i&gt; was found on " \
504                          "http://mjoc.sig.lt/index.html" % word
505             else:
506                 trans += "Word &lt;i&gt;%s&lt;/i&gt; was not found on " \
507                          "http://mjoc.sig.lt/index.html" % word
508
509             trans += "&lt;/h3&gt;&lt;/body&gt;&lt;/html&gt;"
510
511             result.setTranslation(trans)
512
513         except Exception, e:
514             import traceback
515             traceback.print_exc()
516
517             result.setError(self.errorModule.INTERNAL_ERROR)
518
519             return result
520
521         return result
522
523 </pre>
524
525 <p>
526 <i>TODO: describe how to write the class and other details.</i>
527 </p>
528
529 <p>
530 To make an installable plugin file in ZIP archive format, move
531 <i>plugin.xml</i> and <i>mydict.py</i> into some directory
532 (i.e. <i>mydict-0.1</i>) and zip that directory. After performing
533 these actions your new OpenDict plugin will be ready to be installed.
534 </p>
535
536
537 <h2>Conclusion</h2>
538 <p>
539 <i>TODO: This document is very short and fuzzy. It must be improved in
540 the future.</i>
541 </p>
542
543 <div class="footer">Copyright &copy; 2005
544 <a href="mailto:mjoc@akl.lt">Martynas Jocius</a>
545  -- Last modified: 2005-09-06 22:57
546 </div>
547
548 </body>
549 </html>
Note: See TracBrowser for help on using the browser.