]> gitweb.fperrin.net Git - DictionaryPC.git/blob - src/com/hughes/android/dictionary/parser/EnWiktionaryXmlParser.java
cb9f3f5aa41d54beebd15516fc001f160d5b6120
[DictionaryPC.git] / src / com / hughes / android / dictionary / parser / EnWiktionaryXmlParser.java
1 package com.hughes.android.dictionary.parser;
2
3 import java.io.BufferedInputStream;
4 import java.io.DataInputStream;
5 import java.io.EOFException;
6 import java.io.File;
7 import java.io.FileInputStream;
8 import java.io.IOException;
9 import java.util.Arrays;
10 import java.util.LinkedHashSet;
11 import java.util.Set;
12 import java.util.regex.Pattern;
13
14 import com.hughes.android.dictionary.engine.DictionaryBuilder;
15 import com.hughes.android.dictionary.engine.IndexBuilder;
16
17 public class EnWiktionaryXmlParser {
18   
19   static final Pattern partOfSpeechHeader = Pattern.compile(
20       "Noun|Verb|Adjective|Adverb|Pronoun|Conjunction|Interjection|" +
21       "Preposition|Proper noun|Article|Prepositional phrase|Acronym|" +
22       "Abbreviation|Initialism|Contraction|Prefix|Suffix|Symbol|Letter|" +
23       "Ligature|Idiom|Phrase|" +
24       // These are @deprecated:
25       "Noun form|Verb form|Adjective form|Nominal phrase|Noun phrase|" +
26       "Verb phrase|Transitive verb|Intransitive verb|Reflexive verb|" +
27       // These are extras I found:
28       "Determiner|Numeral|Number|Cardinal number|Ordinal number|Proverb|" +
29       "Particle|Interjection|Pronominal adverb" +
30       "Han character|Hanzi|Hanja|Kanji|Katakana character|Syllable");
31
32   final DictionaryBuilder dictBuilder;
33   
34   final IndexBuilder[] indexBuilders;
35   final Pattern langPattern;
36   final Pattern langCodePattern;
37   final int enIndexBuilder;
38
39   public EnWiktionaryXmlParser(final DictionaryBuilder dictBuilder, final Pattern langPattern, final Pattern langCodePattern, final int enIndexBuilder) {
40     this.dictBuilder = dictBuilder;
41     this.indexBuilders = dictBuilder.indexBuilders.toArray(new IndexBuilder[0]);
42     this.langPattern = langPattern;
43     this.langCodePattern = langCodePattern;
44     this.enIndexBuilder = enIndexBuilder;
45   }
46
47   
48   public void parse(final File file, final int pageLimit) throws IOException {
49     int pageCount = 0;
50     final DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
51     while (true) {
52       if (pageLimit >= 0 && pageCount >= pageLimit) {
53         return;
54       }
55       
56       final String title;
57       try {
58         title = dis.readUTF();
59       } catch (EOFException e) {
60         dis.close();
61         return;
62       }
63       final String heading = dis.readUTF();
64       final int bytesLength = dis.readInt();
65       final byte[] bytes = new byte[bytesLength];
66       dis.readFully(bytes);
67       final String text = new String(bytes, "UTF8");
68       
69       parseSection(title, heading, text);
70
71       ++pageCount;
72       if (pageCount % 1000 == 0) {
73         System.out.println("pageCount=" + pageCount);
74       }
75     }
76   }
77   
78   private void parseSection(final String title, final String heading, final String text) {
79     if (title.startsWith("Wiktionary:") ||
80         title.startsWith("Template:") ||
81         title.startsWith("Appendix:") ||
82         title.startsWith("Category:") ||
83         title.startsWith("Index:") ||
84         title.startsWith("MediaWiki:") ||
85         title.startsWith("TransWiki:") ||
86         title.startsWith("Citations:") ||
87         title.startsWith("Concordance:") ||
88         title.startsWith("Help:")) {
89       return;
90     }
91     
92     if (heading.replaceAll("=", "").equals("English")) {
93       doEnglishWord(title, text);
94     } else {
95       //doForeignWord(title, text);
96     }
97         
98   }  // endPage()
99   
100   // -------------------------------------------------------------------------
101   
102   String pos = null;
103   int posDepth = -1;
104
105   private void doEnglishWord(String title, String text) {
106     final WikiLineReader wikiLineReader = new WikiLineReader(text);
107     String line;
108     while ((line = wikiLineReader.readLine()) != null) {
109       final WikiHeading wikiHeading = WikiHeading.getHeading(line);
110       if (wikiHeading != null) {
111         
112         if (wikiHeading.depth <= posDepth) {
113           pos = null;
114           posDepth = -1;
115         }
116         
117         if (partOfSpeechHeader.matcher(wikiHeading.name).matches()) {
118           posDepth = wikiHeading.depth;
119           pos = wikiHeading.name;
120         } else if (wikiHeading.name.equals("Translations")) {
121           doTranslations(title, wikiLineReader);
122         } else if (wikiHeading.name.equals("Pronunciation")) {
123           //doPronunciation(wikiLineReader);
124         }
125       }
126     }
127   }
128
129
130   private static Set<String> encodings = new LinkedHashSet<String>(Arrays.asList("zh-ts",
131       "sd-Arab", "ku-Arab", "Arab", "unicode", "Laoo", "ur-Arab", "Thai", 
132       "fa-Arab", "Khmr", "zh-tsp", "Cyrl", "IPAchar", "ug-Arab", "ko-inline", 
133       "Jpan", "Kore", "Hebr", "rfscript", "Beng", "Mong", "Knda", "Cyrs",
134       "yue-tsj", "Mlym", "Tfng", "Grek", "yue-yue-j"));
135   
136   private void doTranslations(final String title, final WikiLineReader wikiLineReader) {
137     String line;
138     String sense = null;
139     boolean done = false;
140     while ((line = wikiLineReader.readLine()) != null) {
141       if (WikiHeading.getHeading(line) != null) {
142         wikiLineReader.stuffLine(line);
143         return;
144       }
145       if (done) {
146         continue;
147       }
148       
149       // Check whether we care about this line:
150       
151       //line = WikiLineReader.removeSquareBrackets(line);
152       
153       if (line.startsWith("{{")) {
154         
155         WikiFunction wikiFunction;
156         while ((wikiFunction = WikiFunction.getFunction(line)) != null) {
157           if (wikiFunction.name.equals("trans-top")) {
158             sense = null;
159             if (wikiFunction.args.size() >= 2) {
160               sense = wikiFunction.args.get(1);
161               //System.out.println("Sense: " + sense);
162             }
163           } else if (wikiFunction.name.equals("trans-bottom")) {
164             sense = null;
165           } else if (wikiFunction.name.equals("trans-mid")) {
166           } else if (wikiFunction.name.equals("trans-see")) {
167           } else if (wikiFunction.name.startsWith("checktrans")) {
168             done = true;
169           } else {
170             System.err.println("Unexpected translation wikifunction: " + line + ", title=" + title);
171           }
172           line = wikiFunction.replaceWith(line, "");
173           
174         }
175         
176       } else if (line.startsWith("*")) {
177         // This line could produce an output...
178         
179         // First strip the language and check whether it matches.
180         // And hold onto it for sub-lines.
181         final int colonIndex = line.indexOf(":");
182         if (colonIndex == -1) {
183           continue;
184         }
185         final String lang = line.substring(0, colonIndex);
186         if (!this.langPattern.matcher(lang).find()) {
187           continue;
188         }
189         
190         String rest = line.substring(colonIndex + 1);
191         final StringBuilder lineText = new StringBuilder();
192         
193         final 
194         
195         boolean ttbc = false;
196         WikiFunction wikiFunction;
197         while ((wikiFunction = WikiFunction.getFunction(line)) != null) {
198           if (wikiFunction.name.equals("t") || wikiFunction.name.equals("t+") || wikiFunction.name.equals("t-") || wikiFunction.name.equals("tø")) {
199             if (wikiFunction.args.size() < 2) {
200               System.err.println("{{t}} with too few args: " + line + ", title=" + title);
201               continue;
202             }
203             final String langCode = wikiFunction.getArg(0);
204             if (this.langCodePattern.matcher(langCode).matches()) {
205               final String word = wikiFunction.getArg(1);
206               final String gender = wikiFunction.getArg(2);
207               final String transliteration = wikiFunction.getNamedArg("tr");
208             }
209           } else if (wikiFunction.name.equals("qualifier")) {
210             qualifier = wikiFunction.getArg(0);
211           } else if (encodings.contains(wikiFunction.name)) {
212             rest = wikiFunction.replaceWith(rest, wikiFunction.getArg(0));
213             wikiFunction = null;
214           } else if (wikiFunction.name.equals("m") || wikiFunction.name.equals("f") || wikiFunction.name.equals("n")) {
215             String gender = wikiFunction.name;
216             for (int i = 0; i < wikiFunction.args.size(); ++i) {
217               gender += "|" + wikiFunction.getArg(i);
218             }
219             rest = wikiFunction.replaceWith(rest, "{" + wikiFunction.name + "}");
220             wikiFunction = null;
221           } else if (wikiFunction.name.equals("g")) {
222             rest = wikiFunction.replaceWith(rest, "{g}");
223             wikiFunction = null;
224           } else if (wikiFunction.name.equals("l")) {
225             // encodes text in various langs.
226             rest = wikiFunction.replaceWith(rest, wikiFunction.getArg(1));
227             // TODO: transliteration
228             wikiFunction = null;
229           } else if (wikiFunction.name.equals("term")) {
230             // cross-reference to another dictionary
231             rest = wikiFunction.replaceWith(rest, wikiFunction.getArg(0));
232             // TODO: transliteration
233             wikiFunction = null;
234           } else if (wikiFunction.name.equals("italbrac") || wikiFunction.name.equals("gloss")) {
235             // TODO: put this text aside to use it.
236             rest = wikiFunction.replaceWith(rest, "[" + wikiFunction.getArg(0) + "]");
237             wikiFunction = null;
238           } else if (wikiFunction.name.equals("ttbc")) {
239             ttbc = true;
240           } else if (wikiFunction.name.equals("trreq")) {
241           } else if (wikiFunction.name.equals("not used")) {
242             rest = wikiFunction.replaceWith(rest, "[not used]");
243             wikiFunction = null;
244           } else if (wikiFunction.name.equals("t-image")) {
245             // American sign language
246           } else if (wikiFunction.args.isEmpty() && wikiFunction.namedArgs.isEmpty()) {
247             rest = wikiFunction.replaceWith(rest, "{" + wikiFunction.name + "}");
248             wikiFunction = null;
249           } else {
250             System.err.println("Unexpected t+- wikifunction: " + line + ", title=" + title);
251           }
252           if (wikiFunction != null) {
253             rest = wikiFunction.replaceWith(rest, "");
254           }
255         }
256       } else if (line.equals("")) {
257       } else if (line.startsWith(":")) {
258       } else if (line.startsWith("[[") && line.endsWith("]]")) {
259       } else if (line.startsWith("''See''")) {
260       } else if (line.startsWith("''")) {
261       } else if (line.equals("----")) {
262       } else {
263         System.err.println("Unexpected translation line: " + line + ", title=" + title);
264       }
265       
266     }
267     
268   }
269   
270   // -------------------------------------------------------------------------
271   
272   private void doForeignWord(String title, String text) {
273     final WikiLineReader wikiLineReader = new WikiLineReader(text);
274     String line;
275     while ((line = wikiLineReader.readLine()) != null) {
276       final WikiHeading wikiHeading = WikiHeading.getHeading(line);
277       if (wikiHeading != null) {
278         
279         if (wikiHeading.name.equals("Translations")) {
280           System.err.println("Translations not in English section: " + title);
281         } else if (wikiHeading.name.equals("Pronunciation")) {
282           //doPronunciation(wikiLineReader);
283         } else if (partOfSpeechHeader.matcher(wikiHeading.name).matches()) {
284           
285         }
286       }
287     }
288   }
289
290   
291 }