]> gitweb.fperrin.net Git - DictionaryPC.git/blob - src/com/hughes/android/dictionary/parser/wiktionary/EnTranslationToTranslationParser.java
EnTranslationToTranslationParser
[DictionaryPC.git] / src / com / hughes / android / dictionary / parser / wiktionary / EnTranslationToTranslationParser.java
1 // Copyright 2012 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package com.hughes.android.dictionary.parser.wiktionary;
16
17 import java.util.List;
18 import java.util.Map;
19 import java.util.regex.Pattern;
20
21 import com.hughes.android.dictionary.engine.EntryTypeName;
22 import com.hughes.android.dictionary.engine.IndexBuilder;
23 import com.hughes.android.dictionary.engine.IndexedEntry;
24 import com.hughes.android.dictionary.engine.PairEntry;
25 import com.hughes.android.dictionary.engine.PairEntry.Pair;
26 import com.hughes.android.dictionary.parser.WikiTokenizer;
27
28 public final class EnTranslationToTranslationParser extends AbstractWiktionaryParser {
29   
30     final IndexBuilder[] indexBuilders;
31     final Pattern[] namePatterns;
32
33     public EnTranslationToTranslationParser(final IndexBuilder[] indexBuilders,
34         final Pattern[] namePatterns) {
35       this.indexBuilders = indexBuilders;
36       this.namePatterns = namePatterns;
37     }
38     
39     @Override
40     void removeUselessArgs(Map<String, String> namedArgs) {
41       namedArgs.keySet().removeAll(EnParser.USELESS_WIKI_ARGS);
42     }
43
44     @Override
45     void parseSection(String heading, String text) {
46       if (EnParser.isIgnorableTitle(title)) {
47         return;
48       }
49       final WikiTokenizer wikiTokenizer = new WikiTokenizer(text);
50       while (wikiTokenizer.nextToken() != null) {
51         if (wikiTokenizer.isHeading()) {
52           final String headerName = wikiTokenizer.headingWikiText();
53           if (headerName.equals("Translations")) {
54             doTranslations(wikiTokenizer);
55           }
56         }  else {
57           // TODO: optimization: skip to next heading, or even skip to translations.
58         }
59       }
60     }
61
62     private void doTranslations(final WikiTokenizer wikiTokenizer) {
63       String topLevelLang = null;
64       boolean done = false;
65       StringBuilder[] builders;
66       while (wikiTokenizer.nextToken() != null) {
67         if (wikiTokenizer.isHeading()) {
68           wikiTokenizer.returnToLineStart();
69           return;
70         }
71         if (done) {
72           continue;
73         }
74         
75         // Check whether we care about this line:
76         if (wikiTokenizer.isFunction()) {
77           final String functionName = wikiTokenizer.functionName();
78           final List<String> positionArgs = wikiTokenizer.functionPositionArgs();
79           
80           if (functionName.equals("trans-top")) {
81             if (wikiTokenizer.functionPositionArgs().size() >= 1) {
82               builders = new StringBuilder[] {new StringBuilder(), new StringBuilder()};
83             }
84           } else if (functionName.equals("trans-bottom")) {
85             builders = null;
86           } else if (functionName.equals("trans-mid")) {
87           } else if (functionName.equals("trans-see")) {
88           } else if (functionName.startsWith("picdic")) {
89           } else if (functionName.startsWith("checktrans")) {
90             done = true;
91           } else if (functionName.startsWith("ttbc")) {
92             wikiTokenizer.nextLine();
93             // TODO: would be great to handle ttbc
94             // TODO: Check this: done = true;
95           } else {
96             LOG.warning("Unexpected translation wikifunction: " + wikiTokenizer.token() + ", title=" + title);
97           }
98         } else if (wikiTokenizer.isListItem()) {
99           final String line = wikiTokenizer.listItemWikiText();
100           // This line could produce an output...
101
102           // First strip the language and check whether it matches.
103           // And hold onto it for sub-lines.
104           final int colonIndex = line.indexOf(":");
105           if (colonIndex == -1) {
106             continue;
107           }
108           
109           final String lang = trim(WikiTokenizer.toPlainText(line.substring(0, colonIndex)));
110           incrementCount("tCount:" + lang);
111           
112           
113           final boolean appendLang;
114           if (wikiTokenizer.listItemPrefix().length() == 1) {
115             topLevelLang = lang;
116             final boolean thisFind = langPattern.matcher(lang).find();
117             if (!thisFind) {
118               continue;
119             }
120             appendLang = !langPattern.matcher(lang).matches();
121           } else if (topLevelLang == null) {
122             continue;
123           } else {
124             // Two-level -- the only way we won't append is if this second level matches exactly.
125             if (!langPattern.matcher(lang).matches() && !langPattern.matcher(topLevelLang).find()) {
126               continue;
127             }
128             appendLang = !langPattern.matcher(lang).matches();
129           }
130           
131           String rest = line.substring(colonIndex + 1).trim();
132           if (rest.length() > 0) {
133             doTranslationLine(line, appendLang ? lang : null, rest);
134           }
135         }
136       }
137     }
138     
139     private void doTranslationLine(final String line, final String lang, final String pos, final String sense, final String rest) {
140       state = State.TRANSLATION_LINE;
141       // Good chance we'll actually file this one...
142       final PairEntry pairEntry = new PairEntry(entrySource);
143       final IndexedEntry indexedEntry = new IndexedEntry(pairEntry);
144       
145       final StringBuilder foreignText = new StringBuilder();
146       appendAndIndexWikiCallback.reset(foreignText, indexedEntry);
147       appendAndIndexWikiCallback.dispatch(rest, foreignIndexBuilder, EntryTypeName.WIKTIONARY_TRANSLATION_OTHER_TEXT);
148       
149       if (foreignText.length() == 0) {
150         LOG.warning("Empty foreignText: " + line);
151         incrementCount("WARNING: Empty foreignText" );
152         return;
153       }
154       
155       if (lang != null) {
156         foreignText.insert(0, String.format("(%s) ", lang));
157       }
158       
159       StringBuilder englishText = new StringBuilder();
160       
161       englishText.append(title);
162       if (sense != null) {
163         englishText.append(" (").append(sense).append(")");
164         enIndexBuilder.addEntryWithString(indexedEntry, sense, EntryTypeName.WIKTIONARY_TRANSLATION_SENSE);
165       }
166       if (pos != null) {
167         englishText.append(" (").append(pos.toLowerCase()).append(")");
168       }
169       enIndexBuilder.addEntryWithString(indexedEntry, title, EntryTypeName.WIKTIONARY_TITLE_MULTI);
170       
171       final Pair pair = new Pair(trim(englishText.toString()), trim(foreignText.toString()), swap);
172       pairEntry.pairs.add(pair);
173       if (!pairsAdded.add(pair.toString())) {
174         LOG.warning("Duplicate pair: " + pair.toString());
175         incrementCount("WARNING: Duplicate pair" );
176       }
177     }
178
179   }