Member m = member(normalize(tag), 0, false);
if (m!=null) Reflection.fuzzyInvoke(target, m);
}
+ protected Object defaultWalk(String tag, Object[] argo) { return super.walk(tag, argo); }
public Object walk(String tag, Object[] argo) {
if (argo.length==0) return super.walk(tag, argo);
if (argo==null) return tag;
if (tag==null || "".equals(tag)) return argo;
- Member m = tag==null ? null : member(normalize(tag), argo.length, argo.length>0);
- if (m==null) return super.walk(tag, argo);
+ Member m = tag==null ? null : member(normalize(tag), argo.length, false);
+ if (m==null) return defaultWalk(tag, argo);
//System.out.println("preparing to invoke method " + (m==null ? "null" : (m.toString())) + " for sequence " + (owner()+"."+tag));
if (m != null) return Reflection.fuzzyInvoke(target, m, argo);
if (argo.length==0) return null;
System.out.println("\nparsing " + s[1]);
Forest f = new CharToken.CharToStringParser(mg).parse(new Tib(new FileInputStream(s[1])));
+
+ System.out.println();
System.out.println(f);
- //System.out.println(((Tree)new StringifyWalker().walk(f.expand1())).toPrettyString());
- System.out.println(((Tree)new HTMLWalker().walk(f.expand1())).toPrettyString());
+ System.out.println();
+ System.out.println(((Tree)new StringifyWalker().walk(f.expand1())).toPrettyString());
+
+ String st = new HTMLWalker().walk(f.expand1()).toString();
+ System.out.println(st);
+ FileOutputStream fos = new FileOutputStream("out.html");
+ PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
+ p.println(st);
+ p.flush();
+ p.close();
}
public static class StringifyWalker extends ReflectiveWalker {
}
}
+ public static String join(String[] sa, String sep) {
+ StringBuffer ret = new StringBuffer();
+ boolean first = true;
+ for(String s : sa) {
+ if (!first) ret.append(sep);
+ first = false;
+ ret.append(s);
+ }
+ return ret.toString();
+ }
+
public static class HTMLWalker extends ReflectiveWalker {
//public void header() { throw new Error(); }
- public String ul(Object o) { return "<ul>"+o+"</ul>"; }
- private Tree<String> lone(String s) {
+ public String li(Object o) { return "<li>"+o+"</li>"; }
+ public String ul(String[] li) { return "<ul>"+join(li,"")+"</ul>"; }
+ public String ol(String[] li) { return "<ol>"+join(li,"")+"</ol>"; }
+ public String hr() { return "\n<hr/>\n"; }
+ public String it(Object o) { return "<i>"+o+"</i>"; }
+ public String tt(Object o) { return "<tt>"+o+"</tt>"; }
+ public String underline(Object o) { return "<ul>"+o+"</ul>"; }
+ public String p(Object o) { return "<p>"+o+"</p>"; }
+ public String smallcap(Object o) { return "<span style='font-variant: small-caps'>"+o+"</span>"; }
+ public String blockquote(Object o) { return "<blockquote>"+o+"</blockquote>"; }
+ public String superscript(Object o) { return "<sup>"+o+"</sup>"; }
+ public String subscript(Object o) { return "<sub>"+o+"</sub>"; }
+ public String bold(Object o) { return "<b>"+o+"</b>"; }
+ public String strikethrough(Object o) { throw new Error();/*return "<b>"+o+"</b>";*/ }
+ public Object top(Object o) { return "<html><body>"+o+"</body></html>"; }
+ public Object doc(Object header, Object body) { return body; }
+ public String text(Object[] body) {
+ StringBuffer ret = new StringBuffer();
+ for(Object o : body) { ret.append(o); ret.append(" "); }
+ return ret.toString();
+ }
+ public String body(String[] sections) { return join(sections, "\n\n"); }
+ public String domain(String[] parts) { return join(parts, "."); }
+ public String ip(String[] parts) { return join(parts, "."); }
+ public String emailaddr(String user, String host) {
+ return link(user+"@"+host, "mailto:"+user+"@"+host);
+ }
+ //public String url(String method) {
+ public String link(Object text, Object target) {
+ return "<a href='"+target+"'>"+text+"</a>";
+ }
+ public String section(Object header, Object[] body) {
+ StringBuffer ret = new StringBuffer();
+ ret.append(header);
+ ret.append(" ");
+ for(Object o : body) ret.append(o);
+ return ret.toString();
+ }
+ private String escapify(Object o) {
+ String s = o==null ? "" : o.toString();
StringBuffer sb = new StringBuffer();
for(int i=0; i<s.length(); i++) {
switch(s.charAt(i)) {
default: sb.append(s.charAt(i)); break;
}
}
- return new Tree<String>(null, sb.toString(), new Tree[0]);
+ return sb.toString();
+ }
+ private Tree<String> lone(String s) {
+ return new Tree<String>(null, s, new Tree[0]);
}
public Object walk(Tree<String> t) {
String head = t.head();
if ("stringify".equals(head)) {
StringBuffer ret = new StringBuffer();
for(Tree<String> child : t.child(0)) ret.append(child);
- return lone(ret.toString());
+ return ret.toString();
}
return super.walk(t);
}
- public Object walk(String head, Object[] children) {
+ protected Object defaultWalk(String head, Object[] children) {
Tree<String>[] kids = new Tree[children.length];
for(int i=0; i<children.length; i++) {
if (children[i]==null) kids[i]=null;
- else if (children[i] instanceof String) kids[i] = lone((String)children[i]);
- else kids[i] = (Tree<String>)children[i];
+ else if (children[i] instanceof String) kids[i] = lone(escapify((String)children[i]));
+ else if (children[i] instanceof Tree) kids[i] = (Tree<String>)children[i];
+ else kids[i] = lone(children[i].toString());
}
return new Tree<String>(null, head, kids);
}
Doc ::= {Header} Body /ws => doc
Header ::= "header" { kv */ ws } /ws => header
-Body ::= Section*/ws => body
+Body ::= Section*/ws => body
Section ::= { SectionHeader Paragraph* /ws => section }
SectionHeader ::= "==" SectionHeaderBody "=="
SectionHeaderBody ::= "=" SectionHeaderBody "="
blank ::= sp "\n" sp "\n" ws
kv ::= word "=" text /ws => kv1
-
+wp !::= w++
num !::= [0-9]++
-Paragraph ::= { "\"\"" ws text } => "blockquote"
- > { "*" " " ws text } => "ul"
- > { "#" " " ws text } => "ol"
+Paragraph ::= { "\"\"" ws text } => "blockquote"
+ > uli+/ws => "ul"
+ > { "# " text } => "ol"
> { num " " ws text } => "ol"
> { "---" "-"* } => "hr"
> { text } => "p"
+uli ::= { "* " text } => "li"
-text ::= Item
-Itemx ::= ws Item | ()
+text ::= Item => text
+Itemx ::= ws Item
+ | ()
Item ::= blockquote
- > pre Itemx => []
- > structured Itemx => []
- > structuredx Itemx => []
- > styled Itemx => []
- > qtext Itemx => []
+ > pre Itemx => []
+ > structured Itemx => []
+ > structuredx Itemx => []
+ > styled Itemx => []
+ > qtext Itemx => []
> (alphanum++ => stringify) Itemx => []
- > symbol Itemx => []
-// > sym++ Itemx => []
- > Paragraph Itemx => []
-
-symbol ::= sym++
+ > symbol Itemx => []
+ > (sym++ => stringify) Itemx => []
+ > Paragraph => ""
+ > Paragraph Itemx => []
blockquote ::= "\"\"" text "\"\"" => "blockquote"
| "\"\"" block => "blockquote"
qtext ::= "\"" text "\"" => "quoted"
pre ::= "[verbatim]" { ~[]+ } /ws => "verbatim" // FIXME doesn't work
-styled ::= "__" text "__" => ul
+styled ::= "__" text "__" => underline
| "((" text "))" => footnote
| ( "[[" text "]]" => tt
> "[" word "]" => citation
// only gets parsed once
urlpath ::= urlchar*
-username ::= [a-zA-Z0-9;/?:&=$\-_.+]++
-password ::= [a-zA-Z0-9;/?:&=$\-_.+]++
+username ::= [a-zA-Z0-9;/?:&=$\-_.+]++ => stringify
+password ::= [a-zA-Z0-9;/?:&=$\-_.+]++ => stringify
urlchar ::= [a-zA-Z0-9;/?:&=$\-_.+@]
| "%" [0-9] [0-9] => "%"
url ::= "mailto" ":" email
- > method "://" url_login? host (":" port)? ("/" urlpath)? => "url"
-url_login ::= username (":" password) "@" => "login"
-method ::= [+\-.a-z0-9]+
-port ::= [0-9]+
-
-domain ::= (part +/ ".") -> ~"."
-part ::= [a-zA-Z0-9\-]++ // interesting use of boolean grammars
+ > method "://" url_login? host (":" nums)? ("/" urlpath)? => "url"
+url_login ::= username (":" password) "@" => "login"
+method ::= [+\-.a-z0-9]+ => stringify
+domain ::= (part +/ ".") -> ~"." => domain
+part ::= [a-zA-Z0-9\-]++ => stringify
+// interesting use of boolean grammars
// &~ ([\-0-9] ~[]* | ~[]* [\-0-9])
email ::= username "@" host -> ~[.] => emailaddr
-host ::= [0-9]+ "." [0-9]+ "." [0-9]+ "." [0-9]+ => "ip"
+nums ::= [0-9]++ => stringify
+host ::= nums "." nums "." nums "." nums => "ip"
| domain