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