]> gitweb.fperrin.net Git - DictionaryPC.git/blobdiff - src/com/hughes/android/dictionary/parser/WikiTokenizer.java
Refactoring wiki parsing, bigtime. Underway, so lots of errors....
[DictionaryPC.git] / src / com / hughes / android / dictionary / parser / WikiTokenizer.java
index f80605d791b8dd63bd792f6dc9f6f2ac47ac9f15..6c81749006ea96d5dfe362459206d9ded25cf7e0 100644 (file)
@@ -22,7 +22,19 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 public final class WikiTokenizer {
-
+  
+  public static interface Callback {
+    void onPlainText(WikiTokenizer wikiTokenizer);
+    void onMarkup(WikiTokenizer wikiTokenizer);
+    void onWikiLink(WikiTokenizer wikiTokenizer);
+    void onNewline(WikiTokenizer wikiTokenizer);
+    void onFunction(String functionName, List<String> functionPositionArgs,
+        Map<String, String> functionNamedArgs);
+    void onHeading(WikiTokenizer wikiTokenizer);
+    void onListItem(WikiTokenizer wikiTokenizer);
+    void onComment(WikiTokenizer wikiTokenizer);
+  }
+  
   //private static final Pattern wikiTokenEvent = Pattern.compile("($)", Pattern.MULTILINE);
   private static final Pattern wikiTokenEvent = Pattern.compile("(" +
                "\\{\\{|\\}\\}|" +
@@ -93,6 +105,30 @@ public final class WikiTokenizer {
     namedArgs.clear();
   }
   
+  public void dispatch(final Callback callback) {
+    while (nextToken() != null) {
+      if (isPlainText()) {
+        callback.onPlainText(this);
+      } else if (isMarkup()) {
+        callback.onMarkup(this);
+      } else if (isWikiLink) {
+        callback.onWikiLink(this);
+      } else if (isNewline()) {
+        callback.onNewline(this);
+      } else if (isFunction()) {
+        callback.onFunction(functionName(), functionPositionArgs(), functionNamedArgs());
+      } else if (isHeading()) {
+        callback.onHeading(this);
+      } else if (isListItem()) {
+        callback.onListItem(this);
+      } else if (isComment()) {
+        callback.onComment(this);
+      } else {
+        throw new IllegalStateException("Unknown wiki state.");
+      }
+    }
+  }
+  
   public boolean isNewline() {
     return justReturnedNewline;
   }
@@ -173,6 +209,7 @@ public final class WikiTokenizer {
     if (lastUnescapedPipePos != -1) {
       return wikiText.substring(lastUnescapedPipePos + 1, end - 2);
     }
+    assert start + 2 < wikiText.length() && end >= 2: wikiText;
     return wikiText.substring(start + 2, end - 2);
   }
 
@@ -337,7 +374,7 @@ public final class WikiTokenizer {
   
   public String token() {
     final String token = wikiText.substring(start, end);
-    assert token.equals("\n") || !token.endsWith("\n") : token;
+    assert token.equals("\n") || !token.endsWith("\n") : "token='" + token + "'";
     return token;
   }
   
@@ -347,6 +384,7 @@ public final class WikiTokenizer {
     final boolean insideFunction = toFind.equals("}}");
     
     int end = start;
+    int firstNewline = -1;
     while (end < wikiText.length()) {
       if (matcher.find(end)) {
         final String matchText = matcher.group();
@@ -355,6 +393,9 @@ public final class WikiTokenizer {
         assert matcher.end() > end || matchText.length() == 0: "Group=" + matcher.group();
         if (matchText.length() == 0) {
           assert matchStart == wikiText.length() || wikiText.charAt(matchStart) == '\n';
+          if (firstNewline == -1) {
+            firstNewline = matcher.end();
+          }
           if (tokenStack.isEmpty() && toFind.equals("\n")) {
             return matchStart;
           }
@@ -413,6 +454,14 @@ public final class WikiTokenizer {
       // Inside the while loop.  Just go forward.
       end = Math.max(end, matcher.end());
     }
+    if (toFind.equals("\n") && tokenStack.isEmpty()) {
+      // We were looking for the end, we got it.
+      return end;
+    }
+    if (firstNewline != -1) {
+      errors.add("Couldn't find: " + toFind + ", "+ wikiText.substring(start));
+      return firstNewline;
+    }
     return end;
   }
 
@@ -445,8 +494,8 @@ public final class WikiTokenizer {
     return s.length();
   }
 
-  public static String toPlainText(String sense) {
-    final WikiTokenizer wikiTokenizer = new WikiTokenizer(sense);
+  public static String toPlainText(final String wikiText) {
+    final WikiTokenizer wikiTokenizer = new WikiTokenizer(wikiText);
     final StringBuilder builder = new StringBuilder();
     while (wikiTokenizer.nextToken() != null) {
       if (wikiTokenizer.isPlainText()) {
@@ -462,4 +511,16 @@ public final class WikiTokenizer {
     return builder.toString();
   }
 
+  public static StringBuilder appendFunction(final StringBuilder builder, final String name, List<String> args,
+      final Map<String, String> namedArgs) {
+    builder.append(name);
+    for (final String arg : args) {
+      builder.append("|").append(arg);
+    }
+    for (final Map.Entry<String, String> entry : namedArgs.entrySet()) {
+      builder.append("|").append(entry.getKey()).append("=").append(entry.getValue());
+    }
+    return builder;
+  }
+
 }