checkpoint
authoradam <adam@megacz.com>
Sat, 8 Jul 2006 08:17:31 +0000 (04:17 -0400)
committeradam <adam@megacz.com>
Sat, 8 Jul 2006 08:17:31 +0000 (04:17 -0400)
darcs-hash:20060708081731-5007d-927f08c5435080dea31eb86a9b79f06151f43299.gz

src/edu/berkeley/sbp/tib/TibDoc.java
src/edu/berkeley/sbp/util/ToHTML.java
tests/tib.in [new file with mode: 0644]
tests/tibdoc.g

index 469c166..5901fcc 100644 (file)
@@ -335,18 +335,42 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
         public @bind static class Doc extends Dump implements ToHTML {
             public @bind.arg Header head;
             public @bind.arg Body body;
-            public void toHTML(HTML h) { body.toHTML(h); }
+            public void toHTML(HTML h) {
+                h.tag("html", new ToHTML[] { head, body });
+            }
         }
 
-        public @bind static class Header extends Dump {
+        public @bind static class Header extends Dump implements ToHTML {
             public @bind.arg KeyVal[] attrs;
+            public Text[] get(String key) {
+                for(KeyVal kv : attrs)
+                    if (kv.key.equals(key))
+                        return kv.val;
+                return null;
+            }
+            public void toHTML(HTML h) {
+                h.openTag("head");
+                h.tag("title", get("title"));
+                h.tag("style", stylesheet);
+                h.closeTag("head");
+            }
             // FIXME: it would be nice to be able to
             // void KeyVal(String, String) { ... } imperatively
         }
         
         public @bind static class Body extends Dump implements ToHTML {
             public Section[] sections;
-            public void toHTML(HTML h) { for(Section s : sections) s.toHTML(h); }
+            public void toHTML(HTML h) {
+                h.openTag("body");
+                h.openTag("center");
+                h.openTag("table", new Object[] { "width", "600px" });
+                h.openTag("tr");
+                h.tag("td", sections);
+                h.closeTag("tr");
+                h.closeTag("table");
+                h.closeTag("center");
+                h.closeTag("body");
+            }
         }
         
         public @bind.as("Section") static class Section extends Dump implements ToHTML {
@@ -360,7 +384,7 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
         
         public @bind static class KeyVal extends Dump {
             public @bind.arg String key;
-            public @bind.arg Object val;
+            public @bind.arg Text[] val;
         }
 
         public abstract static class Paragraph extends Dump implements ToHTML { }
@@ -369,6 +393,7 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
             public Text[] text;
             public P() { }
             public P(Text[] text) { this.text = text; }
+            public P(String string) { this.text = new Text[] { new Chars(string) }; }
             public void toHTML(HTML h) { if (text != null) for (Text t : text) if (t != null) t.toHTML(h); }
             public String toString() {
                 StringBuffer sb = new StringBuffer();
@@ -378,7 +403,6 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
             }
         }
 
-        public @bind.as("email") static Object email(@bind.arg Object a, @bind.arg Object c) { return null; }
         public static @bind class Login {
             public @bind.arg String username;
             public @bind.arg String password;
@@ -392,10 +416,10 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
             public @bind.arg Text[][] points;
             public abstract String tag();
             public void toHTML(ToHTML.HTML sb) {
-                sb.append("<"+tag()+">\n");
+                sb.openTag(tag());
                 for(Text[] t : points)
                     sb.tag("li", t);
-                sb.append("</"+tag()+">\n");
+                sb.closeTag(tag());
             }
         }
         public static @bind class OL extends List { public String tag() { return "ol"; } }
@@ -433,7 +457,11 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
         }
         public @bind static class Block extends Text {
             public Text[] text;
-            public void toHTML(HTML h) { for(Text t : text) t.toHTML(h); }
+            public void toHTML(HTML h) {
+                for(Text t : text)
+                    if (t != null)
+                        t.toHTML(h);
+            }
         }
         public static class TextWrap extends Text {
             public @bind.arg Text[] text;
@@ -449,7 +477,22 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
             public String   htmlTag() { return null; }
             public Object[] htmlTagParams() { return null; }
         }
-        public static @bind class Verbatim   extends Text { public char[] c; public void toHTML(HTML h) { } }
+        public static @bind class Verbatim   extends Text {
+            public @bind.arg String s;
+            public void toHTML(HTML h) {
+                h.openTag("div", new Object[] { "class", "terminal" });
+                for(int i=0; i<s.length(); i++) {
+                    char c = s.charAt(i);
+                    switch(c) {
+                        case '\r': break;
+                        case '\n': h.tag("br"); break;
+                        case ' ': h.appendLiterally("&nbsp;"); break;
+                        default: h.appendText(c+""); break;
+                    }
+                }
+                h.closeTag("div");
+            }
+        }
         //public @bind class Blockquote extends TextWrap { }
         public static @bind class Underline extends TextWrap { public String htmlTag() { return "u"; } }
         public static @bind class Footnote extends TextWrap { public String htmlTag() { return "small"; } }
@@ -467,14 +510,109 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
         public static @bind class Today extends Command { public void toHTML(HTML h) { } }
         public static @bind class LineBreak extends Command { public void toHTML(HTML h) { h.tag("br"); } }
 
-        public abstract static class Glyph extends Text { }
+        public static abstract class Glyph extends Text implements ToHTML { }
         public static @bind.as("emdash") class Emdash extends Glyph { public void toHTML(HTML h) { h.appendLiterally("&mdash;"); } }
+        public static @bind.as("ellipses") class Ellipses extends Glyph { public void toHTML(HTML h) { h.appendLiterally("&#8230;"); } }
+        public static @bind.as("r") class RegTm extends Glyph { public void toHTML(HTML h) { h.appendLiterally("&#xAE;"); } }
+        public static @bind.as("c") class Copyright extends Glyph { public void toHTML(HTML h) { h.appendLiterally("&#xA9;"); } }
+        public static @bind.as("tm") class Tm extends Glyph { public void toHTML(HTML h) { h.appendLiterally("&;"); } }
+        public static @bind.as("euro") class Euro extends Glyph { public void toHTML(HTML h) { h.appendLiterally("&euro;"); } }
+
+        public static class Entity extends Text implements ToHTML {
+            public int code;
+            public String name;
+            public Entity(String name, int code) { this.name = name; this.code = code; }
+            public Entity(String name, String abbrev, int code) { this(name, code); }
+            public void toHTML(HTML h) {
+                h.appendLiterally("&#x"+Integer.toString(code, 16)+";");
+            }
+        }
+
+        public static Entity[] entities = new Entity[] {
+            new Entity("tm",    0x2122),
+            new Entity("alef",  0x2135),
+            new Entity("leftArrow", "<--", 0x2190),
+            new Entity("rightArrow", "-->", 0x2192),
+            new Entity("leftDoubleArrow", "<==", 0x21D0),
+            new Entity("rightDoubleArrow", "==>", 0x21D2),
+            new Entity("doubleLeftRightArrow", "<==>", 0x21D4),
+            new Entity("upArrow", 0x2191),
+            new Entity("downArrow", 0x2193),
+            new Entity("upDoubleArrow", 0x21D1),
+            new Entity("downDoubleArrow", 0x21D3),
+            new Entity("forall", 0x2200),
+            new Entity("exists", 0x2203),
+            new Entity("emptySet", 0x2205),
+            new Entity("in", 0x2208),
+            new Entity("cent", 0xA2),
+            new Entity("pi", 0x220F),
+            new Entity("sigma", 0x2211),
+            new Entity("infinity", 0x221E),
+            new Entity("proportional", 0x221D),
+            new Entity("check", 0x221A),
+            new Entity("asterisk", 0x2217),
+            new Entity("minus", 0x2212),
+            new Entity("angle", 0x2220),
+            new Entity("and", 0x2227),
+            new Entity("or", 0x2228),
+            new Entity("intersection", 0x2229),
+            new Entity("union", 0x222A),
+            new Entity("integral", 0x222B),
+            new Entity("therefore", 0x2234),
+            new Entity("congruent", 0x2245),
+            new Entity("similarTo", 0x2248),
+            new Entity("identical", 0x2261),
+            new Entity("neq", 0x2260),
+            new Entity("subset", 0x2282),
+            new Entity("superset", 0x2283),
+            new Entity("notSubset", 0x2284),
+            new Entity("subsetEq", 0x2286),
+            new Entity("supersetEq", 0x2287),
+            new Entity("circlePlus", 0x2295),
+            new Entity("circleTimes", 0x2297),
+            new Entity("bottom", 0x22A5),
+            new Entity("cdot", 0x22C5),
+            new Entity("openDiamonds", 0x25CA),
+            new Entity("spade", 0x2660),
+            new Entity("clubs", 0x2663),
+            new Entity("hearts", 0x2665),
+            new Entity("diamonds", 0x2666),
+            new Entity("prime", 0x2032),
+            new Entity("reals", 0x211C),
+            new Entity("powerSet", 0x2118),
+            new Entity("overScore", 0x203E),
+            new Entity("yen", 0xA5),
+            new Entity("plusminus", 0xB1),
+            new Entity("micro", 0xB5),
+            new Entity("superScriptOne", 0xB9),
+            new Entity("superScriptTwo", 0xB2),
+            new Entity("superScriptThree", 0xB3),
+            new Entity("oneQuarter", 0xBC),
+            new Entity("oneHalf", 0xBD),
+            new Entity("threeQuarters", 0xBE),
+            new Entity("paragraphSymbol", 0xB6),
+            new Entity("times", 0xD7),
+            new Entity("daggar", 0x86),
+            new Entity("sectionSymbol", 0xA7),
+            new Entity("not", 0xAC),
+            new Entity("cr", 0x2193),
+            new Entity("dot", 0xB7),
+        };
+
+        public static @bind Object command(String s) {
+            if (s.equals("br")) return new LineBreak();
+            if (s.equals("today")) return new Today();
+            for(Entity e : entities)
+                if (e.name.equals(s))
+                    return e;
+            return null;
+        }
 
         public static class Link extends Text {
             public Text[] t;
             public Url u;
-            public @bind.as("LinkText") Link(Text[] t, Url u)  { this.t = t; this.u = u; }
-            public @bind.as("LinkChars") Link(String s, Url u) { this(new Text[] { new Chars(s) }, u); }
+            public @bind.as("link")  Link(@bind.arg Text[] t, @bind.arg Url u)  { this.t = t; this.u = u; }
+            public Link(String s, Url u) { this(new Text[] { new Chars(s) }, u); }
             public void toHTML(HTML h) {
                 h.tag("a",
                       new Object[] { "href", u==null ? "" : u.toString() },
@@ -494,6 +632,10 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
                 }
             }
             public @bind.as("IP")  Host(int a, int b, int c, int d) { name = a+"."+b+"."+c+"."+d; }
+            public Host(String hostname) {
+                this.name = hostname;
+            }
+
         }
 
         public static class Url extends Text {
@@ -511,16 +653,30 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
                 this.port = port;
                 this.path = path;
             }
-            public @bind.as("Mailto") Url(String email) { this("mailto", null, null, "25", email); }
             public void toHTML(HTML h) { new Link(toString(), this).toHTML(h); }
             public String toString() {
                 return method + "://" + host + "/" + path;
             }
         }
+        public static class Email extends Url {
+            public @bind.as("Mailto") Email(String email) {
+                super("mailto", null, new Host(email.substring(email.indexOf('@'))), "25", email.substring(email.indexOf('@')));
+            }
+            public @bind.as("email")  Email(String user, Host host) {
+                super("mailto", null, host, "25", user);
+            }
+            public void toHTML(HTML h) {
+                h.tag("a",
+                      new Object[] { "href", "mailto:"+path+"@"+host },
+                      new P(toString()));
+            }
+            public String toString() { return path+"@"+host; }
+        }
+
         public static @bind.as("lf")        String lf() { return "\r"; }
         public static @bind.as("cr")        String cr() { return "\n"; }
         public static @bind.as("\"\"")      String empty() { return ""; }
-        public static @bind.as("urlescape") String urlescape(char a, char b) { return ((char)((a-'0') * 16 + (b-'0')))+""; }
+        public static @bind.as("urlescape") char urlescape(char a, char b) { return ((char)((a-'0') * 16 + (b-'0'))); }
     }
 
     public static void main(String[] s) throws Exception {
@@ -583,5 +739,53 @@ toContex ll = prefix ++ (concatMap tl ll) ++ suffix
 
     }
 
-}
 
+    private static final String[] stylesheet = new String[] {
+        "H1 {",
+        "  margin-left: -20px;",
+        "  margin-top: 30px;",
+        "  font-family: helvetica, verdana, arial, sans-serif;",
+        "  font-size: 14pt;",
+        "  font-weight: bold;",
+        "  text-align: left;",
+        "  width : 100%;",
+        "  border-top-width: 2pt;",
+        "  border-top-style: solid;",
+        "} ",
+        "",
+        "H2 {",
+        "  font-family: helvetica, verdana, arial, sans-serif;",
+        "  font-size: 12pt;",
+        "  font-weight: bold;",
+        "} ",
+        "",
+        "H3 {",
+        "  margin-left: -10px;",
+        "  font-family: helvetica, verdana, arial, sans-serif;",
+        "  font-size: 12pt;",
+        "  font-weight: bold;",
+        "} ",
+        "",
+        "TH, TD, P, LI {",
+        "  font-family: helvetica, verdana, arial, sans-serif;",
+        "  font-size: 13px;  ",
+        "  text-decoration:none; ",
+        "}",
+        "",
+        "LI { margin-top: 5px; }",
+        "div.terminal {",
+        "    text-align: left;",
+        "    font-family: monospace;",
+        "    border-style: solid;",
+        "    border-width: 2px 2px 2px 2px;",
+        "    white-space: pre;",
+        "    border-color: #6666aa;",
+        "    color: #FFFFFF;",
+        "    background-color: #000000;",
+        "    margin-bottom: 25px;",
+        "    margin-right: 25px;",
+        "    margin-left: 25px;",
+        "    padding: 10px;",
+        "}"
+    };
+}
index 88e4f57..3d52562 100644 (file)
@@ -9,30 +9,45 @@ public interface ToHTML {
         private final StringBuffer sb;
         public HTML(StringBuffer sb) { this.sb = sb; }
 
-        public void appendLiterally(String s) {
-            sb.append(s);
-        }
-        public void append(String s) {
-            /* FIXME */
-            sb.append(s);
-        }
+        public void appendLiterally(String s) { sb.append(s); }
+        public void appendLiterally(char c) { sb.append(c); }
 
         public void appendText(String s) {
-            /* FIXME: escapify this!!! */
-            sb.append(s);
+            sb.append(escapify(s));
+        }
+
+        public String escapify(String s) {
+            StringBuffer sb = new StringBuffer();
+            for(int i=0; i<s.length(); i++) {
+                char c = s.charAt(i);
+                switch(c) {
+                    case '&':  sb.append("&amp;"); break;
+                    case '<':  sb.append("&lt;"); break;
+                    case '>':  sb.append("&gt;"); break;
+                    case '\'': sb.append("&apos;"); break;
+                    case '\"': sb.append("&quot;"); break;
+                    default:
+                        if (c < 32 || c >= 127) {
+                            sb.append("&#x" + Integer.toString((int)(c & 0xffff), 16) + ";");
+                        } else {
+                            sb.append(c);
+                        }
+                }
+            }
+            return sb.toString();
         }
 
-        public void entity(int entity) { sb.append("&#"+entity+";"); }
-        public void entity(String entity) { sb.append("&"+entity+";"); }
+        public void entity(int entity) { appendLiterally("&#"+entity+";"); }
+        public void entity(String entity) { appendLiterally("&"+entity+";"); }
 
         public void append(Object o) {
-            if (o==null)                    append("<tt><font color=red>null</font></tt>");
+            if (o==null)                    appendLiterally("<tt><font color=red>null</font></tt>");
             else if (o instanceof ToHTML)   ((ToHTML)o).toHTML(this);
             else if (o instanceof Object[]) append((Object[])o);
-            else                            append(o.toString());
+            else                            appendText(o.toString());
         }
         public void append(int i) { sb.append(i); }
-        public void append(char c) { sb.append(c); }
+        public void append(char c) { append(""+c); }
 
         public void append(Object[] o) {
             for(int i=0; i<o.length; i++) {
@@ -42,36 +57,37 @@ public interface ToHTML {
         }
 
         public void tag(String s) {
-            sb.append("<");
-            append(s);
-            sb.append("/>");
+            appendLiterally("<");
+            appendLiterally(s);
+            appendLiterally("/>");
         }
+        public void openTag(String s) { openTag(s, null); }
         public void openTag(String s, Object[] attrs) {
-                sb.append("<");
-                append(s);
-                if (attrs != null)
-                    for(int i=0; i<attrs.length; i+=2) {
-                        sb.append(' ');
-                        append(attrs[i]);
-                        sb.append("=\'");
-                        append(attrs[i+1]);
-                        sb.append("\'");
-                    }
-                sb.append(">");
+            appendLiterally("<");
+            appendLiterally(s);
+            if (attrs != null)
+                for(int i=0; i<attrs.length; i+=2) {
+                    appendLiterally(' ');
+                    append(attrs[i]);
+                    appendLiterally("=\'");
+                    append(attrs[i+1]);
+                    appendLiterally("\'");
+                }
+            appendLiterally(">");
         }
         public void closeTag(String s) {
-            sb.append("<");
-            append(s);
-            sb.append(">");
+            appendLiterally("</");
+            appendLiterally(s);
+            appendLiterally(">");
         }
         public void tag(String s, Object o) { tag(s, null, o); }
         public void tag(String s, Object[] attrs, Object o) {
             if (s != null) openTag(s, attrs);
             append(o);
             if (s != null) {
-                sb.append("</");
-                append(s);
-                sb.append(">");
+                appendLiterally("</");
+                appendLiterally(s);
+                appendLiterally(">");
             }
         }
 
diff --git a/tests/tib.in b/tests/tib.in
new file mode 100644 (file)
index 0000000..0ce866c
--- /dev/null
@@ -0,0 +1,43 @@
+\header
+  author   = Adam Megacz
+  title    = my cool document
+  comment  = my homepage is at http://www.megacz.com you should it out
+
+== Introduction ==
+
+  this is the body adam@megacz.com text \today You can visit {my
+  website}->http://www.slashdot.org/foo%30bar/ with -- a !!hyperlink
+  to it!!
+
+  The following 100\forall cool\cent demonstrates stuff [[Knu68]], as
+  well \br as \br a \br footnote ((like)) because
+  \doubleLeftRightArrow are ... coool in an O(n^^3) way.
+
+  even moreso, [verbatim]
+    this is the body adam@megacz.com text \today You can
+    visit->http://www.slashdot.org/foo%30bar/ with -- a !!hyperlink to
+    it!!  The following 100\forall cool\cent demonstrates stuff
+    [[Knu68]], as well \br as \br a \br footnote ((like)) because
+    \doubleLeftRightArrow are ... coool in an O(n^^3) way.
+
+  yep.
+
+== Conclusion ==
+
+  Furthermore we can try things like
+
+    *  trhis is fun
+    *  this
+    *  this
+      * that
+      * that
+          * these
+      * that
+          1. them
+          #  thar
+          45) dorks
+    *  this
+    *  this
+
+  this stuff  
index f93c5dd..a1414d0 100644 (file)
@@ -57,7 +57,7 @@ nw         = ~[\r\n\ ]
 s                   = Doc
 
 Doc                 = head:Header ws! body:Body
-Header              = { "header" { KeyVal */ ws } /ws }
+Header              = { "\\header" { KeyVal */ ws } /ws }
 Body                = { Section } */ws
 Section             = SectionHeader ws! Paragraph*
 SectionHeader       = "==" SectionHeaderBody "=="
@@ -87,7 +87,7 @@ Item*/ws     =
                blockquote
              > { UL:: uli+/ws }           
              | { OL:: oli+/ws }           
-             > pre                        
+             > Verbatim
              > link                       
              > structured                 
              > styled                     
@@ -101,7 +101,7 @@ word = Chars:: bareword
 blockquote = "adsfafewag"
 //blockquote   = Blockquote:: "\"\"" (block | text "\"\"")
              
-pre          = Verbatim:: "[verbatim]" { ~[]+ } /ws   // FIXME doesn't work
+Verbatim     = "[verbatim]" ws! { (~[])++ }
 
 styled       = Underline::     "__" text "__"      
              | Footnote::      "((" text "))"      
@@ -117,18 +117,22 @@ styled       = Underline::     "__" text "__"
 
 block         = { text }
 
-link          = LinkText:: text:({ text })      "->" href:(url|email)
-              > LinkChars:: text:alphanum++  ws! "->" href:(url|email)
+link          = text:({ text }|word)  "->" href:(url|email)
 
 structured    = command & "\\" ([a-zA-Z0-9]++)! block?
               > glyph
               > email
               > url
 
-glyph        = Euro:: "(e)" | "(r)" | "(c)" | "(tm)" | emdash:: "--" | "..."
+glyph        = euro::     "(e)"
+             | r::        "(r)"
+             | c::        "(c)"
+             | tm::       "(tm)"
+             | emdash::   "--"
+             | ellipses:: "..."
+             | cent::     "\\cent"
 
-command      = Today::     "\\today"
-             | LineBreak:: "\\br"
+command      = "\\" [a-z]++
 
 // URLs //////////////////////////////////////////////////////////////////////////////