copyright notices/updates
[sbp.git] / src / edu / berkeley / sbp / tib / TibDoc.java
1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
2
3 package edu.berkeley.sbp.tib;
4 import edu.berkeley.sbp.*;
5 import edu.berkeley.sbp.misc.*;
6 import edu.berkeley.sbp.meta.*;
7 import edu.berkeley.sbp.util.*;
8 import edu.berkeley.sbp.chr.*;
9 import edu.berkeley.sbp.bind.*;
10 import java.util.*;
11 import java.io.*;
12 import static edu.berkeley.sbp.meta.MetaGrammar.*;
13
14 public class TibDoc {
15     /*
16     public static Text lf()     { Chars ret = new Chars(); ret.text = "\n"; return ret; }
17     public static Text cr()     { Chars ret = new Chars(); ret.text = "\r"; return ret; }
18     public static Text emdash() { return new Entity("mdash"); }
19     public static char urlescape(int a, int b) { return (char)(10*a+b); }
20
21
22     // Template Classes //////////////////////////////////////////////////////////////////////////////
23
24     public static abstract class Text implements ToHTML {
25         public static final Class[] subclasses = new Class[] { Chars.class, URL.class, Email.class };
26         public void toHTML(ToHTML.HTML sb) { }
27         public static class TextString extends Text {
28             public String text;
29             public String tag() { return null; }
30             public void toHTML(ToHTML.HTML sb) { sb.tag(tag(), text); }
31         }
32         public static class TextArray extends Text {
33             public Text[] t;
34             public String tag() { return null; }
35             public void toHTML(ToHTML.HTML sb) { sb.tag(tag(), t); }
36         }
37     }
38
39
40     // Structural //////////////////////////////////////////////////////////////////////////////
41
42     public static class Doc implements ToHTML {
43         public Header head;
44         public Body   body;
45         public void toHTML(ToHTML.HTML sb) { sb.tag("html", body); }
46         public static class Header extends HashMap<String, Text[]> {
47             public static class KeyVal { public String key; public Text[] val; }
48             public void attrs(KeyVal[] KeyVals) { for(int i=0; i<KeyVals.length; i++) this.put(KeyVals[i].key, KeyVals[i].val); }
49         }
50         public static class Body implements ToHTML {
51             public Section[] sections;
52             public void toHTML(ToHTML.HTML sb) { sb.append(sections); }
53             public static class Section implements ToHTML {
54                 public Text header;
55                 public Paragraph[] paragraphs;
56                 public void toHTML(ToHTML.HTML sb) {
57                     sb.tag("h3", header);
58                     sb.append(paragraphs);
59                 }
60             }
61         }
62     }
63
64
65     // Paragraph //////////////////////////////////////////////////////////////////////////////
66
67     public static interface Paragraph extends ToHTML {
68         public static final Class[] subclasses = new Class[] { Blockquote.class, P.class, HR.class };
69         public static class HR                                implements Paragraph { public void toHTML(ToHTML.HTML sb) { sb.append("\n<hr>\n"); } }
70         public static class P          extends Text.TextArray implements Paragraph { public String tag() { return "p"; } }
71         public static class Blockquote extends Text.TextArray implements Paragraph { public String tag() { return "blockquote"; } }
72     }
73
74     public static abstract class List extends Text {
75         public Text[][] points;
76         public abstract String tag();
77         public void toHTML(ToHTML.HTML sb) {
78             sb.append("<"+tag()+">\n");
79             for(Text[] t : points) sb.tag("li", t);
80             sb.append("</"+tag()+">\n");
81         }
82     }
83     public static class OL extends List { public String tag() { return "ol"; } }
84     public static class UL extends List { public String tag() { return "ul"; } }
85
86
87
88     // Tags //////////////////////////////////////////////////////////////////////////////
89
90     public static class Chars         extends Text.TextString { }
91     public static class Symbol        extends Text.TextString { }
92     public static class Keyword       extends Text.TextString { public String tag() { return "tt"; } }
93     public static class Subscript     extends Text.TextString { public String tag() { return "sub"; } }
94     public static class Superscript   extends Text.TextString { public String tag() { return "super"; } }
95     public static class Bold          extends Text.TextArray  { public String tag() { return "b"; } }
96     public static class Smallcap      extends Text.TextArray  { public String tag() { return "sc"; } }
97     public static class Strikethrough extends Text.TextArray  { public String tag() { return "strike"; } }
98     public static class TT            extends Text.TextArray  { public String tag() { return "tt"; } }
99     public static class Underline     extends Text.TextArray  { public String tag() { return "u"; } }
100     public static class Italic        extends Text.TextArray  { public String tag() { return "i"; } }
101     public static class Citation      extends Text.TextArray  { } // FIXME
102     public static class Footnote      extends Text.TextArray  { } // FIXME
103     public static class LineBreak     extends Text            { public void toHTML(ToHTML.HTML sb) { sb.tag("br"); } }
104     public static class Today         extends Text            { }
105     public static class Euro          extends Text            { public void toHTML(ToHTML.HTML sb) { sb.entity(8364); } }
106     public static class Link          extends Text {
107         public Text[] text;
108         public URI href;
109         public void toHTML(ToHTML.HTML sb) { sb.tag("a", new Object[] { "href", href }, text); }
110     }
111     public static class Entity        extends Text {
112         public final String entity;
113         public Entity(String entity) { this.entity = entity; }
114         public void toHTML(ToHTML.HTML sb) { sb.entity(entity); }
115     }
116
117
118     // Network //////////////////////////////////////////////////////////////////////////////
119
120     public static interface Host extends ToHTML {
121         public static class DNS implements Host {
122             public String[] part;
123             public void toHTML(ToHTML.HTML sb) {
124                 for(int i=0; i<part.length; i++)
125                     sb.append((i==0 ? "" : ".")+part[i]);
126             }
127         }
128         public static class IP  implements Host {
129             public int a, b, c, d;
130             public void toHTML(ToHTML.HTML sb) { sb.append(a+"."+b+"."+c+"."+d); }
131         }
132     }
133
134     public static interface URI extends ToHTML {
135         public static final Class[] subclasses = new Class[] { URL.class, Email.class };
136     }
137     public static class URL extends Text    implements URI {
138         public String method;
139         public Login login;
140         public Host host;
141         public int port;
142         public String path;
143         public void toHTML(ToHTML.HTML sb) {
144             sb.append(method);
145             sb.append("://");
146             // login.toHTML(sb);   FIXME
147             host.toHTML(sb);
148             // sb.append(":");     FIXME
149             // sb.append(port);
150             sb.append("/");
151             sb.append(path);
152         }
153     }
154     public static class Email extends Text  implements URI {
155         public String user;
156         public Host host;
157         public void toHTML(ToHTML.HTML sb) {
158             sb.append(user);
159             sb.append('@');
160             host.toHTML(sb);
161         }
162     }
163
164     public static class Login {
165         public String username;
166         public String password;
167         public void toHTML(ToHTML.HTML sb) {
168             sb.append(username);
169             sb.append(':');
170             sb.append(password);
171             sb.append('@');
172         }        
173     }
174
175
176
177
178     */
179     /*
180         public static void prefix(PrintWriter p) {
181             p.println("% generated by TIBDOC");
182             for(int i=0; i<packages.length; i++) p.println("\\usemodule["+packages[i]+"]");
183             p.println("\\setuppapersize[letter]");
184             p.println("\\setuppagenumbering[location=]");
185             p.println("\\setupcolors[state=start]");
186             //"\\setupinteraction[title={Title},author={Me},"++
187             //"subtitle={Deez Nutz},keywords={blargh},color=blue]\n" ++
188             //"\\setuppublications[database={me},numbering=yes,sort=author]\n" ++
189             p.println("\\setuphead[section][style={\\ss\\bfa},number=no,before=\\blank\\hairline\\nowhitespace]");
190             p.println("\\definelayout[mypage][backspace=1.75in,cutspace=1.75in,width=5in]");
191             p.println("\\setuplayout[mypage]");
192             p.println("\\definetypeface[myface][rm][Xserif][Warnock Pro]");
193             p.println("\\definetypeface[myface][tt][Xmono][CMU Typewriter Text Regular][default]");
194             p.println("\\definetypeface[myface][ss][Xsans][Myriad Pro][default]");
195             p.println("\\usesymbols[uni]");
196             p.println("\\definesymbol[1][{\\USymbCharZapf{39}{164}}]");
197             p.println("\\setupbodyfont[myface, 11pt]");
198             p.println("\\setupwhitespace[7pt]");
199             p.println("\\def\\MyDroppedCaps%");
200             p.println("    {\\DroppedCaps");
201             p.println("        {} {Serif} {2\\baselineskip} {2pt} {1\\baselineskip} {2}}");
202             p.println("\\starttext");
203             p.println("\\switchtobodyfont[16pt]\\midaligned{\\ss\\bfa{Title}}\\switchtobodyfont[10pt]");
204             p.println("\\midaligned{Adam Megacz}\n\n\\nowhitespace\\midaligned{\\tt{adam@megacz.com}}");
205             p.println("\\blank[1cm,force]");
206             //p.println("\\defineparagraphs[mypar][n=2,before={\\blank},after={\\blank}");
207             //p.println("\\setupparagraphs[mypar][1][width=.45\\textwidth");
208             //p.println("\\setupparagraphs[mypar][2][width=.55\\textwidth");
209             //p.println("\\startmypa");
210             //p.println("\\switchtobodyfont[sma");
211         }
212
213         public static void suffix(PrintWriter p) {
214             p.println("\\stoptext");
215         }
216         static String[] packages = new String[] { "supp-fun", "bib", "href" };
217     }
218
219     // ConTex
220
221 module Contex where
222 import Data.Array.IArray
223 import Data.Char
224 import Util
225 import Lexer
226 import IR
227 import Data.List
228 import Beautify
229
230 toContex ll = prefix ++ (concatMap tl ll) ++ suffix
231  where
232   packages                         = [ "[supp-fun]",
233                                        "[bib]",
234                                        "[href]" ]
235   prefix                           = (concatMap (\x -> "\\usemodule"++x++"\n") packages) ++
236                                      "\\setuppapersize[letter]\n" ++
237                                      "\\setuppagenumbering[location=]\n" ++
238                                      "\\setupcolors[state=start]\n" ++
239                                      --"\\setupinteraction[title={Title},author={Me},"++
240                                      --"subtitle={Deez Nutz},keywords={blargh},color=blue]\n" ++
241                                      --"\\setuppublications[database={me},numbering=yes,sort=author]\n" ++
242                                      "\\setuphead[section][style={\\ss\\bfa},\n" ++
243                                      "                     number=no,\n" ++
244                                      "                     before=\\blank\\hairline\\nowhitespace,\n" ++
245                                      "                     ]\n" ++
246                                      "\\definelayout[mypage][\n" ++
247                                      " backspace=1.75in, % the space for margin notes\n" ++
248                                      " cutspace=1.75in, % the space for right margin notes\n" ++
249                                      " width=5in" ++
250                                      "]\n" ++
251                                      "\\setuplayout[mypage]\n" ++
252                                      "\\definetypeface[myface][rm][Xserif][Warnock Pro]\n" ++
253                                      "\\definetypeface[myface][tt][Xmono][CMU Typewriter Text Regular][default]\n" ++
254                                      "\\definetypeface[myface][ss][Xsans][Myriad Pro][default]\n" ++
255                                      "\\usesymbols[uni]\n" ++
256                                      "\\definesymbol[1][{\\USymbCharZapf{39}{164}}]\n" ++
257                                      "\\setupbodyfont[myface, 11pt]\n" ++
258                                      "\\setupwhitespace[7pt]\n" ++
259                                      "\\def\\MyDroppedCaps%\n" ++
260                                      "    {\\DroppedCaps\n" ++
261                                      "        {} {Serif} {2\\baselineskip} {2pt} {1\\baselineskip} {2}}\n" ++
262                                      "\\starttext\n" ++
263                                      "\\switchtobodyfont[16pt]\\midaligned{\\ss\\bfa{Hi5 Replicated Server Infrastructure}}\\switchtobodyfont[10pt]\n"++ 
264                                      "\\midaligned{Adam Megacz}\n\n\\nowhitespace\\midaligned{\\tt{adam@megacz.com}}\n\n"++
265                                      "\\blank[1cm,force]\n" ++
266                                      "\\defineparagraphs[mypar][n=2,before={\\blank},after={\\blank}]\n"++
267                                      "\\setupparagraphs[mypar][1][width=.45\\textwidth]\n"++
268                                      "\\setupparagraphs[mypar][2][width=.55\\textwidth]\n"++
269                                      "\\startmypar"++
270                                      "\\switchtobodyfont[small]\n"
271   suffix                           = "\n\\stoptext\n"
272   addItem i                        = "\\item " ++ (striptrail $ boost 8 $ wrap $ striplead $ tl i)
273   escapify []                      = []
274   escapify ('%':t)                 = '\\':'%':(escapify t)
275   escapify ('$':t)                 = '\\':'$':(escapify t)
276   escapify (h:t)                   = h:(escapify t)
277   escapeMath s                     = s
278   tl (Special _ BulletList l)      = "\\startitemize[symbol]\n" ++ (concatMap addItem l) ++ "\\stopitemize\n"
279   tl (Special _ NumberList l)      = "\\startitemize[symbol]\n" ++ (concatMap addItem l) ++ "\\stopitemize\n"
280   tl (Special _ Section (h:t))     = "\\section{"++(tl h)++"}\n"++(concatMap tl t)
281   tl (Special _ NumberedSection (h:t)) = "\\section{"++(tl h)++"}\n"++(concatMap tl t)
282   tl (Special _ (Glyph EmDash) []) = "{\\emdash}"
283 --tl (Special _ Superscript l)     = 
284 --tl (Special _ Subscript l)       = 
285 --tl (Special _ (Image u) l)       = 
286 --tl (Special _ (Cite u) l)        = 
287   tl (Special _ BlockQuote l)      = "\n\n\\startquote\n     "++
288                                      (striptrail $ boost 4 $ wrap $ striplead $ concatMap tl l)++"\n\\stopquote\n\n"
289   tl (Special _ HorizontalRule []) = "\\\\\\rule{4in}{0.5pt}\\\\"
290   tl (Special _ Italic l)          = "{\\it{"++(concatMap tl l)++"}}"
291   tl (Special _ Bold l)            = "{\\bf{"++(concatMap tl l)++"}}"
292   tl (Special _ DropCap (h:t))     = "\\MyDroppedCaps{"++(tl h)++"}{\\sc "++(concatMap tl t)++"}"
293   tl (Special _ Typewriter l)      = "{\\tt{"++(concatMap tl l)++"}}"
294   tl (Special _ StrikeThrough l)   = "" --"\\sout{"++(concatMap tl l)++"}"
295   tl (Special _ Quotes l)          = "``"++(concatMap tl l)++"''"
296   tl (Special _ Underline l)       = "" --"\\uline{"++(concatMap tl l)++"}"
297   tl (Special _ Underline2 l)      = "" --"\\uuline{"++(concatMap tl l)++"}"
298   tl (Special _ (Math s) [])       = "\\placeformula\n$$\n" ++ (escapeMath s) ++ "\n$$\n"
299   tl (Special _ Footnote l)        = "\\footnote{"++(concatMap tl l)++"}"
300   tl (Special _ Float l)           = "" --"\n\n\\begin{wrapfigure}{r}{0.4\\textwidth} \\framebox[0.4\\textwidth]{"++
301                                      --(concatMap tl l)++"} \\label{x}\\end{wrapfigure}\n\n"
302 --tl (Special _ Figure l)          = "\\placefigure[][fig:church]{}{"++(concatMap tl l)++"}"
303   tl (Special _ Figure l)          = "\\startnarrower\n"++(concatMap tl l)++"\n\\stopnarrower\n"
304   tl (Special _ (Link u) l)        = "\\href{"++(escapify u)++"}{"++(concatMap tl l)++"}"
305   tl (Special _ (Verbatim s) [])   = "\\starttyping\n"++s++"\n\\stoptyping\n"
306 --  tl (Special _ TwoColumn l)       = "\\startcolumns[n=2]\n"++(concatMap tl l)++"\\stopcolumns"
307 --  tl (Special _ Title l)           = ""--"\\title{"++(concatMap tl l)++"}\n\\maketitle\n\n\n"
308   tl (Special _ Abstract l) =
309       "\\midaligned{\\ss\\bfa Abstract}\\par\n " ++
310       "\n\n"++(concatMap tl l)++"\\mypar" ++
311       "\\switchtobodyfont[8pt]{\\ss{\\placecontent}}\\switchtobodyfont[normal]\\stopmypar\n\n\\blank[1cm,force]"
312   tl (Special _ (Command c) l)     = "\\"++c++"["++(concatMap tl l)++"]"
313   tl (Special _ t l)               = error $ "formatting code "++(show t)++" not supported on {"++(concatMap show l)++"})"
314   tl (WS _)                        = " "
315   tl (BlankLine _)                 = "\n\n"
316   tl (Block _ l)                   = concatMap tl l
317   tl (Letter _ c)                  = escapify [c]
318   tl z                             = (show z)
319
320
321
322
323     */
324
325     // Main //////////////////////////////////////////////////////////////////////////////
326
327     public static class Dump implements Reflection.Show {
328         public String toString() { return Reflection.show((Reflection.Show)this); }
329     }
330
331     public static class TD {
332
333         public @bind static class Doc extends Dump implements ToHTML {
334             public @bind.arg Header head;
335             public @bind.arg Body body;
336             public void toHTML(HTML h) {
337                 h.tag("html", new ToHTML[] { head, body });
338             }
339         }
340
341         public @bind static class Header extends Dump implements ToHTML {
342             public @bind.arg KeyVal[] attrs;
343             public Text[] get(String key) {
344                 for(KeyVal kv : attrs)
345                     if (kv.key.equals(key))
346                         return kv.val;
347                 return null;
348             }
349             public void toHTML(HTML h) {
350                 h.openTag("head");
351                 h.tag("title", get("title"));
352                 h.tag("style", stylesheet);
353                 h.closeTag("head");
354             }
355             // FIXME: it would be nice to be able to
356             // void KeyVal(String, String) { ... } imperatively
357         }
358         
359         public @bind static class Body extends Dump implements ToHTML {
360             public Section[] sections;
361             public void toHTML(HTML h) {
362                 h.openTag("body");
363                 h.openTag("center");
364                 h.openTag("table", new Object[] { "width", "600px" });
365                 h.openTag("tr");
366                 h.tag("td", sections);
367                 h.closeTag("tr");
368                 h.closeTag("table");
369                 h.closeTag("center");
370                 h.closeTag("body");
371             }
372         }
373         
374         public @bind.as("Section") static class Section extends Dump implements ToHTML {
375             public String      header;
376             public Paragraph[] paragraphs;
377             public void toHTML(HTML h) {
378                 h.tag("h1", header);
379                 for(Paragraph p : paragraphs) h.tag("p", p);
380             }
381         }
382         
383         public @bind static class KeyVal extends Dump {
384             public @bind.arg String key;
385             public @bind.arg Text[] val;
386         }
387
388         public abstract static class Paragraph extends Dump implements ToHTML { }
389
390         public @bind.as("P") static class P extends Paragraph {
391             public Text[] text;
392             public P() { }
393             public P(Text[] text) { this.text = text; }
394             public P(String string) { this.text = new Text[] { new Chars(string) }; }
395             public void toHTML(HTML h) { if (text != null) h.append(text); }
396             public String toString() {
397                 StringBuffer sb = new StringBuffer();
398                 ToHTML.HTML h = new ToHTML.HTML(sb);
399                 toHTML(h);
400                 return sb.toString();
401             }
402         }
403
404         public static @bind class Login {
405             public @bind.arg String username;
406             public @bind.arg String password;
407         }
408
409         public static @bind.as("Citation") Object cite(Object o) { return new Chars("*cite*"); }
410         public static @bind.as("Symbol") Object sym(String s) { return new Chars(s); }
411
412         public static abstract class List extends Paragraph {
413             public @bind.arg Text[] preface;
414             public @bind.arg Text[][]  points;
415             public abstract String tag();
416             public void toHTML(ToHTML.HTML sb) {
417                 sb.append(preface);
418                 sb.openTag(tag());
419                 for(Text[] t : points)
420                     sb.tag("li", t);
421                 sb.closeTag(tag());
422             }
423         }
424         public static @bind class OL extends List { public String tag() { return "ol"; } }
425         public static @bind class UL extends List { public String tag() { return "ul"; } }
426
427         public static class HR extends Paragraph {
428             public @bind HR() { }
429             public @bind HR(Object o) { }
430             public void toHTML(HTML h) { h.tag("hr"); }
431         }
432
433        public static class Blockquote extends Paragraph {
434             Text[] text;
435             public @bind Blockquote(Text[] t) { this.text = t; }
436             public @bind Blockquote(Text[] t, Text[] t2) {
437                 if (t2==null) {
438                     this.text = t;
439                 } else {
440                     Text[] t3 = new Text[t.length + t2.length];
441                     System.arraycopy(t,  0, t3, 0, t.length);
442                     System.arraycopy(t2, 0, t3, t.length, t2.length);
443                     this.text = t3;
444                 }
445             }
446             public void toHTML(HTML h) { h.tag("blockquote", new P(text)); }
447         }
448
449         public abstract static class Text extends Dump implements ToHTML { }
450
451         public @bind static class Space extends Chars {
452             public Space() { super(" "); }
453         }
454         public @bind static class Chars extends Text {
455             public String text;
456             public Chars() { }
457             public Chars(String text) { this.text = text; }
458             public void toHTML(HTML h) { h.appendText(text); }
459             public String toString() { return text; }
460         }
461         public @bind static class Block extends Text {
462             public Text[] text;
463             public void toHTML(HTML h) { h.append(text); }
464         }
465         public static class TextWrap extends Text {
466             public @bind.arg Text[] text;
467             public void toHTML(HTML h) {
468                 if (htmlTag()!=null) {
469                     h.openTag(htmlTag(), htmlTagParams());
470                 }
471                 h.append(text);
472                 if (htmlTag()!=null) {
473                     h.closeTag(htmlTag());
474                 }
475             }
476             public String   htmlTag() { return null; }
477             public Object[] htmlTagParams() { return null; }
478         }
479
480         public static @bind class Verbatim  extends Text {
481             public @bind.arg String s;
482             public void toHTML(HTML h) {
483                 h.openTag("div", new Object[] { "class", "terminal" });
484                 for(int i=0; i<s.length(); i++) {
485                     char c = s.charAt(i);
486                     switch(c) {
487                         case '\r': break;
488                         case '\n': h.tag("br"); break;
489                         case ' ': h.appendLiterally("&nbsp;"); break;
490                         default: h.appendText(c+""); break;
491                     }
492                 }
493                 h.closeTag("div");
494             }
495         }
496
497         //public @bind class Blockquote extends TextWrap { }
498         public static @bind class Underline extends TextWrap { public String htmlTag() { return "u"; } }
499         public static @bind class Footnote extends TextWrap { public String htmlTag() { return "small"; } }
500         public static @bind class TT extends TextWrap { public String htmlTag() { return "tt"; } }
501         //public @bind class Citation extends Text {       "[" word "]" }
502         public static @bind class Strikethrough extends TextWrap { public String htmlTag() { return "strike"; } }
503         public static @bind class Superscript extends TextWrap { public String htmlTag() { return "sup"; } }
504         public static @bind class Subscript extends TextWrap { public String htmlTag() { return "sub"; } }
505         public static @bind class Smallcap extends TextWrap { public String htmlTag() { return "sc"; } }
506         public static @bind class Keyword extends TextWrap { public String htmlTag() { return "sc"; } }
507         public static @bind class Bold extends TextWrap { public String htmlTag() { return "b"; } }
508         public static @bind class Italic extends TextWrap { public String htmlTag() { return "i"; } }
509
510         public abstract static class Command extends Text { }
511         public static @bind class Today extends Command { public void toHTML(HTML h) { } }
512         public static @bind class LineBreak extends Command { public void toHTML(HTML h) { h.tag("br"); } }
513
514         public static @bind.as("emdash") Entity emdash() { return new Entity("mdash"); }
515         public static @bind.as("ellipses") Entity ellipses() { return new Entity("#8230"); }
516         public static @bind.as("r") Entity r() { return new Entity("#xAE"); }
517         public static @bind.as("c") Entity c() { return new Entity("#xA9"); }
518         public static @bind.as("tm") Entity tm() { return new Entity(""); }
519         public static @bind.as("euro") Entity euro() { return new Entity("euro"); }
520
521         public static class Entity extends Text implements ToHTML {
522             public String name;
523             public String code;
524             public Entity(String code) { this.name = ""; this.code = code; }
525             public Entity(String name, int code) { this.code = "#"+code; this.name = name; }
526             public Entity(String name, String abbrev, int code) { this(name, code); }
527             public void toHTML(HTML h) { h.appendLiterally("&"+code+";"); }
528         }
529
530         public static Entity[] entities = new Entity[] {
531             new Entity("tm",    0x2122),
532             new Entity("alef",  0x2135),
533             new Entity("leftArrow", "<--", 0x2190),
534             new Entity("rightArrow", "-->", 0x2192),
535             new Entity("leftDoubleArrow", "<==", 0x21D0),
536             new Entity("rightDoubleArrow", "==>", 0x21D2),
537             new Entity("doubleLeftRightArrow", "<==>", 0x21D4),
538             new Entity("upArrow", 0x2191),
539             new Entity("downArrow", 0x2193),
540             new Entity("upDoubleArrow", 0x21D1),
541             new Entity("downDoubleArrow", 0x21D3),
542             new Entity("forall", 0x2200),
543             new Entity("exists", 0x2203),
544             new Entity("emptySet", 0x2205),
545             new Entity("in", 0x2208),
546             new Entity("cent", 0xA2),
547             new Entity("pi", 0x220F),
548             new Entity("sigma", 0x2211),
549             new Entity("infinity", 0x221E),
550             new Entity("proportional", 0x221D),
551             new Entity("check", 0x221A),
552             new Entity("asterisk", 0x2217),
553             new Entity("minus", 0x2212),
554             new Entity("angle", 0x2220),
555             new Entity("and", 0x2227),
556             new Entity("or", 0x2228),
557             new Entity("intersection", 0x2229),
558             new Entity("union", 0x222A),
559             new Entity("integral", 0x222B),
560             new Entity("therefore", 0x2234),
561             new Entity("congruent", 0x2245),
562             new Entity("similarTo", 0x2248),
563             new Entity("identical", 0x2261),
564             new Entity("neq", 0x2260),
565             new Entity("subset", 0x2282),
566             new Entity("superset", 0x2283),
567             new Entity("notSubset", 0x2284),
568             new Entity("subsetEq", 0x2286),
569             new Entity("supersetEq", 0x2287),
570             new Entity("circlePlus", 0x2295),
571             new Entity("circleTimes", 0x2297),
572             new Entity("bottom", 0x22A5),
573             new Entity("cdot", 0x22C5),
574             new Entity("openDiamonds", 0x25CA),
575             new Entity("spade", 0x2660),
576             new Entity("clubs", 0x2663),
577             new Entity("hearts", 0x2665),
578             new Entity("diamonds", 0x2666),
579             new Entity("prime", 0x2032),
580             new Entity("reals", 0x211C),
581             new Entity("powerSet", 0x2118),
582             new Entity("overScore", 0x203E),
583             new Entity("yen", 0xA5),
584             new Entity("plusminus", 0xB1),
585             new Entity("micro", 0xB5),
586             new Entity("superScriptOne", 0xB9),
587             new Entity("superScriptTwo", 0xB2),
588             new Entity("superScriptThree", 0xB3),
589             new Entity("oneQuarter", 0xBC),
590             new Entity("oneHalf", 0xBD),
591             new Entity("threeQuarters", 0xBE),
592             new Entity("paragraphSymbol", 0xB6),
593             new Entity("times", 0xD7),
594             new Entity("daggar", 0x86),
595             new Entity("sectionSymbol", 0xA7),
596             new Entity("not", 0xAC),
597             new Entity("cr", 0x2193),
598             new Entity("dot", 0xB7),
599         };
600
601         public static @bind Object command(String s) {
602             if (s.equals("br")) return new LineBreak();
603             if (s.equals("today")) return new Today();
604             for(Entity e : entities)
605                 if (e.name.equals(s))
606                     return e;
607             return null;
608         }
609
610         public static @bind class Quotes extends Text {
611             public Text[] text;
612             public void toHTML(HTML h) {
613                 h.append("\"");
614                 h.append(text);
615                 h.append("\"");
616             }
617         }
618
619         public static class Link extends Text {
620             public Text[] t;
621             public Url u;
622             public @bind.as("link")  Link(@bind.arg Text[] t, @bind.arg Url u)  { this.t = t; this.u = u; }
623             public Link(String s, Url u) { this(new Text[] { new Chars(s) }, u); }
624             public void toHTML(HTML h) {
625                 h.tag("a",
626                       new Object[] { "href", u==null ? "" : u.toString() },
627                       new P(t));
628             }
629         }
630
631         public static class Host {
632             public String name;
633             public String toString() { return name; }
634             public @bind.as("DNS") Host(String[][] parts) {
635                 name = "";
636                 for(String[] s : parts) {
637                     for(String ss : s)
638                         name += ss;
639                     name += ".";
640                 }
641             }
642             public @bind.as("IP")  Host(int a, int b, int c, int d) { name = a+"."+b+"."+c+"."+d; }
643             public Host(String hostname) {
644                 this.name = hostname;
645             }
646
647         }
648
649         public static class Url extends Text {
650             public String   method;
651             public Host     host;
652             public String   user;
653             public String   pass;
654             public String   port;
655             public String   path;
656             public String   ref;
657             public @bind.as("URL") Url(String method, String[] login, Host host, String port, String path, String ref) {
658                 this.method = method;
659                 this.user = login==null ? null : login.length >= 1 ? login[0] : null;
660                 this.pass = login==null ? null : login.length >= 2 ? login[1] : null;
661                 this.host = host;
662                 this.port = port;
663                 this.path = path;
664                 this.ref  = ref;
665             }
666             public void toHTML(HTML h) { new Link(toString(), this).toHTML(h); }
667             public String toString() {
668                 return method + "://" + host + "/" + path + (ref==null ? "" : ("#"+ref));
669             }
670         }
671         public static class Email extends Url {
672             public @bind.as("Mailto") Email(String email) {
673                 super("mailto",
674                       null,
675                       new Host(email.substring(email.indexOf('@'))),
676                       "25",
677                       email.substring(email.indexOf('@')),
678                       null
679                       );
680             }
681             public @bind.as("email")  Email(String user, Host host) {
682                 super("mailto", null, host, "25", user, null);
683             }
684             public void toHTML(HTML h) {
685                 h.tag("a",
686                       new Object[] { "href", "mailto:"+path+"@"+host },
687                       new P(toString()));
688             }
689             public String toString() { return path+"@"+host; }
690         }
691
692         public static @bind.as("lf")        String lf() { return "\r"; }
693         public static @bind.as("cr")        String cr() { return "\n"; }
694         public static @bind.as("\"\"")      String empty() { return ""; }
695         public static @bind.as("urlescape") char   urlescape(char a, char b) { return ((char)((a-'0') * 16 + (b-'0'))); }
696         public static @bind String urlpath(String[] s) {
697             StringBuffer sb = new StringBuffer();
698             for(String st : s) sb.append(st);
699             return sb.toString();
700         }
701     }
702
703     public static void main(String[] s) throws Exception {
704
705         try {
706             Tree<String> res = new CharParser(MetaGrammar.newInstance()).parse(new FileInputStream(s[0])).expand1();
707             
708             AnnotationGrammarBindings resolver = new AnnotationGrammarBindings(TD.class);
709             resolver.add(MetaGrammarBindings.class, "meta");
710             Union tibgram = Grammar.create(res, "s", resolver);
711
712             System.err.println("parsing " + s[1]);
713             Tree t = new CharParser(tibgram).parse(new Tib(new FileInputStream(s[1]))).expand1();
714             System.out.println("tree:\n" + t.toPrettyString());
715             
716             Object result = ((Functor)t.head()).invoke(t);
717             TD.Doc doc = (TD.Doc)result;
718             System.out.println(doc);
719
720             StringBuffer sb = new StringBuffer();
721             ToHTML.HTML html = new ToHTML.HTML(sb);
722             doc.toHTML(html);
723             FileOutputStream fos = new FileOutputStream("out.html");
724             PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
725             p.println(sb);
726             p.flush();
727             p.close();
728         } catch (Ambiguous a) {
729             FileOutputStream fos = new FileOutputStream("/Users/megacz/Desktop/out.dot");
730             PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
731             GraphViz gv = new GraphViz();
732             a.getAmbiguity().toGraphViz(gv);
733             gv.dump(p);
734             p.flush();
735             p.close();
736             a.printStackTrace();
737             
738         } catch (Exception e) {
739             e.printStackTrace();
740         }
741
742     }
743
744
745     private static final String[] stylesheet = new String[] {
746         "H1 {",
747         "  margin-left: -20px;",
748         "  margin-top: 30px;",
749         "  font-family: helvetica, verdana, arial, sans-serif;",
750         "  font-size: 14pt;",
751         "  font-weight: bold;",
752         "  text-align: left;",
753         "  width : 100%;",
754         "  border-top-width: 2pt;",
755         "  border-top-style: solid;",
756         "} ",
757         "",
758         "H2 {",
759         "  font-family: helvetica, verdana, arial, sans-serif;",
760         "  font-size: 12pt;",
761         "  font-weight: bold;",
762         "} ",
763         "",
764         "H3 {",
765         "  margin-left: -10px;",
766         "  font-family: helvetica, verdana, arial, sans-serif;",
767         "  font-size: 12pt;",
768         "  font-weight: bold;",
769         "} ",
770         "",
771         "TH, TD, P, LI {",
772         "  font-family: helvetica, verdana, arial, sans-serif;",
773         "  font-size: 13px;  ",
774         "  text-decoration:none; ",
775         "}",
776         "",
777         "LI { margin-top: 5px; }",
778         "div.terminal {",
779         "    text-align: left;",
780         "    font-family: monospace;",
781         "    border-style: solid;",
782         "    border-width: 2px 2px 2px 2px;",
783         "    white-space: pre;",
784         "    border-color: #6666aa;",
785         "    color: #FFFFFF;",
786         "    background-color: #000000;",
787         "    margin-bottom: 25px;",
788         "    margin-right: 25px;",
789         "    margin-left: 25px;",
790         "    padding: 10px;",
791         "}"
792     };
793 }