]> gitweb.fperrin.net Git - DictionaryPC.git/blob - src/com/hughes/android/dictionary/parser/enwiktionary/FunctionCallbacksDefault.java
Parse foreign text with new wiki parser.
[DictionaryPC.git] / src / com / hughes / android / dictionary / parser / enwiktionary / FunctionCallbacksDefault.java
1 package com.hughes.android.dictionary.parser.enwiktionary;
2
3 import java.util.Arrays;
4 import java.util.LinkedHashMap;
5 import java.util.LinkedHashSet;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9 import java.util.logging.Logger;
10
11 import com.hughes.android.dictionary.engine.EntryTypeName;
12 import com.hughes.android.dictionary.parser.WikiTokenizer;
13 import com.hughes.util.ListUtil;
14
15 public final class FunctionCallbacksDefault {
16   
17   static final Logger LOG = Logger.getLogger(EnWiktionaryXmlParser.class.getName());
18   
19   static final Map<String,FunctionCallback> DEFAULT = new LinkedHashMap<String, FunctionCallback>();
20   static {
21     FunctionCallback callback = new TranslationCallback();
22     DEFAULT.put("t", callback);
23     DEFAULT.put("t+", callback);
24     DEFAULT.put("t-", callback);
25     DEFAULT.put("tø", callback);
26     DEFAULT.put("apdx-t", callback);
27     
28     DEFAULT.put("qualifier", new QualifierCallback());
29
30     callback = new EncodingCallback();
31     Set<String> encodings = new LinkedHashSet<String>(Arrays.asList(
32         "zh-ts", "zh-tsp",
33         "sd-Arab", "ku-Arab", "Arab", "unicode", "Laoo", "ur-Arab", "Thai", 
34         "fa-Arab", "Khmr", "Cyrl", "IPAchar", "ug-Arab", "ko-inline", 
35         "Jpan", "Kore", "Hebr", "rfscript", "Beng", "Mong", "Knda", "Cyrs",
36         "yue-tsj", "Mlym", "Tfng", "Grek", "yue-yue-j"));
37     for (final String encoding : encodings) {
38       DEFAULT.put(encoding, callback);
39     }
40     
41     callback = new Gender();
42     DEFAULT.put("m", callback);
43     DEFAULT.put("f", callback);
44     DEFAULT.put("n", callback);
45     DEFAULT.put("p", callback);
46     DEFAULT.put("g", callback);
47
48     DEFAULT.put("l", new l());
49     DEFAULT.put("italbrac", new italbrac());
50     DEFAULT.put("gloss", new gloss());
51
52     callback = new AppendArg0();
53     DEFAULT.put("term", callback);
54
55     callback = new Ignore();
56     DEFAULT.put("trreq", callback);
57     DEFAULT.put("t-image", callback);
58     DEFAULT.put("defn", callback);
59     DEFAULT.put("rfdef", callback);
60     DEFAULT.put("attention", callback);
61     DEFAULT.put("zh-attention", callback);
62
63     DEFAULT.put("not used", new not_used());
64     DEFAULT.put("form of", new FormOf());
65     DEFAULT.put("wikipedia", new wikipedia());
66     
67     callback = new InflOrHead();
68     DEFAULT.put("infl", callback);
69     DEFAULT.put("head", callback);
70   }
71
72   
73   static final class NameAndArgs implements FunctionCallback {
74     @Override
75     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
76         final Map<String, String> namedArgs, final EnWiktionaryXmlParser parser,
77         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
78       
79       appendAndIndexWikiCallback.builder.append(name);
80       for (int i = 0; i < args.size(); ++i) {
81         if (args.get(i).length() > 0) {
82           appendAndIndexWikiCallback.builder.append("|");
83           appendAndIndexWikiCallback.dispatch(args.get(i), null, null);
84         }
85       }
86       for (final Map.Entry<String, String> entry : namedArgs.entrySet()) {
87         appendAndIndexWikiCallback.builder.append("|");
88         appendAndIndexWikiCallback.dispatch(entry.getKey(), null, null);
89         appendAndIndexWikiCallback.builder.append("=");
90         appendAndIndexWikiCallback.dispatch(entry.getValue(), null, null);
91       }
92       return true;
93     }
94   }
95   static NameAndArgs NAME_AND_ARGS = new NameAndArgs();
96
97   // ------------------------------------------------------------------
98
99   static final class TranslationCallback implements FunctionCallback {
100     @Override
101     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
102         final Map<String, String> namedArgs, final EnWiktionaryXmlParser parser,
103         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
104
105       final String transliteration = namedArgs.remove("tr");
106       namedArgs.keySet().removeAll(EnWiktionaryXmlParser.USELESS_WIKI_ARGS);
107       if (args.size() < 2) {
108         LOG.warning("{{t...}} with wrong args: title=" + parser.title);
109         return false;
110       }
111       final String langCode = ListUtil.get(args, 0);
112       final String word = ListUtil.get(args, 1);
113       final String gender = ListUtil.get(args, 2);
114       // TODO: deal with second (and third...) gender, and alt.
115       
116       appendAndIndexWikiCallback.dispatch(word, EntryTypeName.WIKTIONARY_TITLE_MULTI);
117       
118       if (gender != null) {
119         appendAndIndexWikiCallback.builder.append(String.format(" {%s}", gender));
120       }
121       if (transliteration != null) {
122         appendAndIndexWikiCallback.builder.append(" (tr. ");
123         appendAndIndexWikiCallback.dispatch(transliteration, EntryTypeName.WIKTIONARY_TRANSLITERATION);
124         appendAndIndexWikiCallback.builder.append(")");
125       }
126       return true;
127     }
128     
129   }
130
131   // ------------------------------------------------------------------
132   
133   static final class QualifierCallback implements FunctionCallback {
134     @Override
135     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
136         final Map<String, String> namedArgs,
137         final EnWiktionaryXmlParser parser,
138         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
139       if (args.size() != 1 || !namedArgs.isEmpty()) {
140         LOG.warning("weird qualifier: ");
141         return false;
142       }
143       String qualifier = args.get(0);
144       appendAndIndexWikiCallback.builder.append("(");
145       appendAndIndexWikiCallback.dispatch(qualifier, null);
146       appendAndIndexWikiCallback.builder.append(")");
147       return true;
148     }
149   }
150
151   // ------------------------------------------------------------------
152   
153   static final class EncodingCallback implements FunctionCallback {
154     @Override
155     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
156         final Map<String, String> namedArgs,
157         final EnWiktionaryXmlParser parser,
158         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
159       if (args.size() != 1 || !namedArgs.isEmpty()) {
160         LOG.warning("weird encoding: " + wikiTokenizer.token());
161       }
162       final String wikiText = args.get(0);
163       appendAndIndexWikiCallback.dispatch(wikiText, appendAndIndexWikiCallback.entryTypeName);
164       return true;
165     }
166   }
167
168   // ------------------------------------------------------------------
169   
170   static final class Gender implements FunctionCallback {
171     @Override
172     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
173         final Map<String, String> namedArgs,
174         final EnWiktionaryXmlParser parser,
175         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
176       if (!namedArgs.isEmpty()) {
177         return false;
178       }
179       appendAndIndexWikiCallback.builder.append("{");
180       appendAndIndexWikiCallback.builder.append(name);
181       for (int i = 0; i < args.size(); ++i) {
182         appendAndIndexWikiCallback.builder.append("|").append(args.get(i));
183       }
184       appendAndIndexWikiCallback.builder.append("}");
185       return true;
186     }
187   }
188
189   // ------------------------------------------------------------------
190   
191   static final class l implements FunctionCallback {
192     @Override
193     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
194         final Map<String, String> namedArgs,
195         final EnWiktionaryXmlParser parser,
196         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
197       // TODO: rewrite this!
198       // encodes text in various langs.
199       // lang is arg 0.
200       // 
201       final EntryTypeName entryTypeName;
202       switch (parser.state) {
203       case TRANSLATION_LINE: entryTypeName = EntryTypeName.WIKTIONARY_TRANSLATION_OTHER_TEXT; break;
204       case ENGLISH_DEF_OF_FOREIGN: entryTypeName = EntryTypeName.WIKTIONARY_ENGLISH_DEF_WIKI_LINK; break;
205       default: throw new IllegalStateException("Invalid enum value: " + parser.state);
206       }
207       final String langCode = args.get(0);
208       if ("en".equals(langCode)) {
209         appendAndIndexWikiCallback.dispatch(args.get(1), parser.enIndexBuilder, entryTypeName);
210       } else {
211         appendAndIndexWikiCallback.dispatch(args.get(1), parser.foreignIndexBuilder, entryTypeName);
212       }
213       // TODO: transliteration
214       return true;
215     }
216   }
217
218   // ------------------------------------------------------------------
219   
220   static final class AppendArg0 implements FunctionCallback {
221     @Override
222     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
223         final Map<String, String> namedArgs,
224         final EnWiktionaryXmlParser parser,
225         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
226       if (args.size() != 1 || !namedArgs.isEmpty()) {
227         return false;
228       }
229       appendAndIndexWikiCallback.dispatch(args.get(0), EntryTypeName.WIKTIONARY_TRANSLATION_OTHER_TEXT);
230       // TODO: transliteration
231       return true;
232     }
233   }
234
235   // ------------------------------------------------------------------
236   
237   static final class italbrac implements FunctionCallback {
238     @Override
239     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
240         final Map<String, String> namedArgs,
241         final EnWiktionaryXmlParser parser,
242         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
243       if (args.size() != 1 || !namedArgs.isEmpty()) {
244         return false;
245       }
246       appendAndIndexWikiCallback.builder.append("[");
247       appendAndIndexWikiCallback.dispatch(args.get(0), EntryTypeName.WIKTIONARY_TRANSLATION_OTHER_TEXT);
248       appendAndIndexWikiCallback.builder.append("]");
249       return true;
250     }
251   }
252
253   // ------------------------------------------------------------------
254   
255   static final class gloss implements FunctionCallback {
256     @Override
257     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
258         final Map<String, String> namedArgs,
259         final EnWiktionaryXmlParser parser,
260         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
261       if (args.size() != 1 || !namedArgs.isEmpty()) {
262         return false;
263       }
264       appendAndIndexWikiCallback.builder.append("[");
265       appendAndIndexWikiCallback.dispatch(args.get(0), EntryTypeName.WIKTIONARY_TRANSLATION_OTHER_TEXT);
266       appendAndIndexWikiCallback.builder.append("]");
267       return true;
268     }
269   }
270   
271   // ------------------------------------------------------------------
272   
273   static final class Ignore implements FunctionCallback {
274     @Override
275     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
276         final Map<String, String> namedArgs,
277         final EnWiktionaryXmlParser parser,
278         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
279       return true;
280     }
281   }
282
283   // ------------------------------------------------------------------
284   
285   static final class not_used implements FunctionCallback {
286     @Override
287     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
288         final Map<String, String> namedArgs,
289         final EnWiktionaryXmlParser parser,
290         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
291       appendAndIndexWikiCallback.builder.append("(not used)");
292       return true;
293     }
294   }
295
296   
297   // --------------------------------------------------------------------
298   // --------------------------------------------------------------------
299   
300
301   static final class FormOf implements FunctionCallback {
302     @Override
303     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
304         final Map<String, String> namedArgs,
305         final EnWiktionaryXmlParser parser,
306         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
307       String formName = name;
308       if (name.equals("form of")) {
309         formName = ListUtil.remove(args, 0, null);
310       }
311       if (formName == null) {
312         LOG.warning("Missing form name: " + parser.title);
313         formName = "form of";
314       }
315       String baseForm = ListUtil.get(args, 1, "");
316       if ("".equals(baseForm)) {
317         baseForm = ListUtil.get(args, 0, null);
318         ListUtil.remove(args, 1, "");
319       } else {
320         ListUtil.remove(args, 0, null);
321       }
322       namedArgs.keySet().removeAll(EnWiktionaryXmlParser.USELESS_WIKI_ARGS);
323       
324       appendAndIndexWikiCallback.builder.append("{");
325       NAME_AND_ARGS.onWikiFunction(wikiTokenizer, formName, args, namedArgs, parser, appendAndIndexWikiCallback);
326       appendAndIndexWikiCallback.builder.append("}");
327       if (baseForm != null && appendAndIndexWikiCallback.indexedEntry != null) {
328         parser.foreignIndexBuilder.addEntryWithString(appendAndIndexWikiCallback.indexedEntry, baseForm, EntryTypeName.WIKTIONARY_BASE_FORM_MULTI);
329       } else {
330         // null baseForm happens in Danish.
331         LOG.warning("Null baseform: " + parser.title);
332       }
333       return true;
334     }
335   }
336   
337   static final FormOf FORM_OF = new FormOf();
338   
339
340   // --------------------------------------------------------------------
341   // --------------------------------------------------------------------
342   
343   static final class wikipedia implements FunctionCallback {
344     @Override
345     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
346         final Map<String, String> namedArgs,
347         final EnWiktionaryXmlParser parser,
348         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
349       namedArgs.remove("lang");
350       if (args.size() > 1 || !namedArgs.isEmpty()) {
351         // Unindexed!
352         return false;
353       } else if (args.size() == 1) {
354         return false;
355       } else {
356         return true;
357       }
358     }
359   }
360
361   static final class InflOrHead implements FunctionCallback {
362     @Override
363     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
364         final Map<String, String> namedArgs,
365         final EnWiktionaryXmlParser parser,
366         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
367       // See: http://en.wiktionary.org/wiki/Template:infl
368       final String langCode = ListUtil.get(args, 0);
369       String head = namedArgs.remove("head");
370       if (head == null) {
371         head = namedArgs.remove("title"); // Bug
372       }
373       if (head == null) {
374         head = parser.title;
375       } else {
376         head = WikiTokenizer.toPlainText(head);
377       }
378       parser.titleAppended = true;
379       
380       namedArgs.keySet().removeAll(EnWiktionaryXmlParser.USELESS_WIKI_ARGS);
381
382       final String tr = namedArgs.remove("tr");
383       String g = namedArgs.remove("g");
384       if (g == null) {
385         g = namedArgs.remove("gender");
386       }
387       final String g2 = namedArgs.remove("g2");
388       final String g3 = namedArgs.remove("g3");
389
390       appendAndIndexWikiCallback.dispatch(head, EntryTypeName.WIKTIONARY_TITLE_MULTI);
391
392       if (g != null) {
393         appendAndIndexWikiCallback.builder.append(" {").append(g);
394         if (g2 != null) {
395           appendAndIndexWikiCallback.builder.append("|").append(g2);
396         }
397         if (g3 != null) {
398           appendAndIndexWikiCallback.builder.append("|").append(g3);
399         }
400         appendAndIndexWikiCallback.builder.append("}");
401       }
402
403       if (tr != null) {
404         appendAndIndexWikiCallback.builder.append(" (tr. ");
405         appendAndIndexWikiCallback.dispatch(tr, EntryTypeName.WIKTIONARY_TITLE_MULTI);
406         appendAndIndexWikiCallback.builder.append(")");
407         parser.wordForms.add(tr);
408       }
409
410       final String pos = ListUtil.get(args, 1);
411       if (pos != null) {
412         appendAndIndexWikiCallback.builder.append(" (").append(pos).append(")");
413       }
414       for (int i = 2; i < args.size(); i += 2) {
415         final String inflName = ListUtil.get(args, i);
416         final String inflValue = ListUtil.get(args, i + 1);
417         appendAndIndexWikiCallback.builder.append(", ");
418         appendAndIndexWikiCallback.dispatch(inflName, null, null);
419         if (inflValue != null && inflValue.length() > 0) {
420           appendAndIndexWikiCallback.builder.append(": ");
421           appendAndIndexWikiCallback.dispatch(inflValue, null, null);
422           parser.wordForms.add(inflValue);
423         }
424       }
425       for (final String key : namedArgs.keySet()) {
426         final String value = WikiTokenizer.toPlainText(namedArgs.get(key));
427         appendAndIndexWikiCallback.builder.append(" ");
428         appendAndIndexWikiCallback.dispatch(key, null, null);
429         appendAndIndexWikiCallback.builder.append("=");
430         appendAndIndexWikiCallback.dispatch(value, null, null);
431         parser.wordForms.add(value);
432       }
433       return true;
434     }
435   }
436   
437
438   static {
439     DEFAULT.put("it-noun", new it_noun());
440   } 
441   static final class it_noun implements FunctionCallback {
442     @Override
443     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
444         final Map<String, String> namedArgs,
445         final EnWiktionaryXmlParser parser,
446         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
447       parser.titleAppended = true;
448       final String base = ListUtil.get(args, 0);
449       final String gender = ListUtil.get(args, 1);
450       final String singular = base + ListUtil.get(args, 2, null);
451       final String plural = base + ListUtil.get(args, 3, null);
452       appendAndIndexWikiCallback.builder.append(" ");
453       appendAndIndexWikiCallback.dispatch(singular, null, null);
454       appendAndIndexWikiCallback.builder.append(" {").append(gender).append("}, ");
455       appendAndIndexWikiCallback.dispatch(plural, null, null);
456       appendAndIndexWikiCallback.builder.append(" {pl}");
457       parser.wordForms.add(singular);
458       parser.wordForms.add(plural);
459       if (!namedArgs.isEmpty() || args.size() > 4) {
460         LOG.warning("Invalid it-noun: " + wikiTokenizer.token());
461       }
462       return true;
463     }
464   }
465
466   static {
467     DEFAULT.put("it-proper noun", new it_proper_noun());
468   } 
469   static final class it_proper_noun implements FunctionCallback {
470     @Override
471     public boolean onWikiFunction(final WikiTokenizer wikiTokenizer, final String name, final List<String> args,
472         final Map<String, String> namedArgs,
473         final EnWiktionaryXmlParser parser,
474         final AppendAndIndexWikiCallback appendAndIndexWikiCallback) {
475       return false;
476     }
477   }
478
479 }