]> gitweb.fperrin.net Git - DictionaryPC.git/blob - src/com/hughes/android/dictionary/parser/WikiLineReader.java
go
[DictionaryPC.git] / src / com / hughes / android / dictionary / parser / WikiLineReader.java
1 package com.hughes.android.dictionary.parser;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.regex.Matcher;
6 import java.util.regex.Pattern;
7
8 public class WikiLineReader {
9   
10   private final List<String> lineStack = new ArrayList<String>();
11   
12   private final String wikiText;
13   private int lineStart = 0;
14   
15   private static final Pattern wikiLineEvent = Pattern.compile("$|\\{\\{|\\[\\[|\\}\\}|\\]\\]|<!--|<pre>|<math>", Pattern.MULTILINE);
16
17   private static final Pattern whitespace = Pattern.compile("\\s+");
18   
19   public WikiLineReader(final String wikiText) {
20     this.wikiText = wikiText;
21   }
22
23   public String readLine() {
24     if (stuffedLine != null) {
25       final String line = stuffedLine;
26       stuffedLine = null;
27       return line;
28     }
29     while (lineStart < wikiText.length() && 
30         Character.isWhitespace(wikiText.charAt(lineStart)) && 
31         wikiText.charAt(lineStart) != '\n') {
32       ++lineStart;
33     }
34     if (lineStart >= wikiText.length()) {
35       return null;
36     }
37
38     int lineEnd = lineStart;
39     lineStack.clear();
40     int firstNewline = -1;
41     final Matcher matcher = wikiLineEvent.matcher(wikiText);
42     while (lineEnd < wikiText.length()) {
43       if (!matcher.find(lineEnd)) {
44         lineEnd = wikiText.length();
45         break;
46       }
47       lineEnd = matcher.end();
48       if (lineEnd == wikiText.length()) {
49         break;
50       }
51       if (matcher.group().equals("")) {
52         assert (wikiText.charAt(matcher.start()) == '\n'): "Invalid: " + wikiText.substring(matcher.start());
53         ++lineEnd;
54         if (lineStack.size() == 0) {
55           break;
56         } else {
57           if (firstNewline == -1) {
58             firstNewline = matcher.end();
59           }
60         }
61       }
62       
63       if (matcher.group().equals("[[") || matcher.group().equals("{{")) {
64         lineStack.add(matcher.group());
65       } else if (matcher.group().equals("}}") || matcher.group().equals("]]")) {
66         if (lineStack.size() > 0) {
67           final String removed = lineStack.remove(lineStack.size() - 1);
68           if (removed.equals("{{") && !matcher.group().equals("}}")) {
69             System.err.println("Unmatched {{ error: " + wikiText.substring(lineStart));
70           }
71           if (removed.equals("[[") && !matcher.group().equals("]]")) {
72             System.err.println("Unmatched [[ error: " + wikiText.substring(lineStart));
73           }
74         } else {
75           System.err.println("Pop too many error: " + wikiText.substring(lineStart).replaceAll("\n", "\\n"));
76         }
77       } else if (matcher.group().equals("<!--")) {
78         lineEnd = safeIndexOf(wikiText, lineEnd, "-->", "\n");
79       } else if (matcher.group().equals("<pre>")) {
80         lineEnd = safeIndexOf(wikiText, lineEnd, "</pre>", "\n");
81       } else if (matcher.group().equals("<math>")) {
82         lineEnd = safeIndexOf(wikiText, lineEnd, "</math>", "\n");
83       }
84     }
85     if (lineStack.size() > 0 && firstNewline != -1) {
86       lineEnd = firstNewline + 1;
87     }
88     final String result = wikiText.substring(lineStart, lineEnd);
89     lineStart = lineEnd;
90     return cleanUpLine(result);
91   }
92     
93     
94   static int safeIndexOf(final String s, final int start, final String target, final String backup) {
95     int close = s.indexOf(target, start);
96     if (close != -1) {
97       return close + target.length();
98     }
99     close = s.indexOf(backup, start);
100     if (close != -1) {
101       return close + backup.length();
102     }
103     return s.length();
104   }
105   
106   public static String cleanUpLine(String line) {
107     int pos;
108     while ((pos = line.indexOf("<!--")) != -1) {
109       int end = line.indexOf("-->");
110       if (end != -1) {
111         line = line.substring(0, pos) + line.substring(end + 3);
112       }
113     }
114     final Matcher matcher = whitespace.matcher(line);
115     line = matcher.replaceAll(" ");
116     line = line.trim();
117     return line;
118   }
119
120   String stuffedLine = null;
121   public void stuffLine(final String line) {
122     assert stuffedLine == null;
123     stuffedLine = line;
124   }
125   
126   
127
128 }