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.
5 package edu.berkeley.sbp.tib;
6 import edu.berkeley.sbp.*;
7 import edu.berkeley.sbp.misc.*;
8 import edu.berkeley.sbp.util.*;
9 import edu.berkeley.sbp.chr.*;
12 import static edu.berkeley.sbp.misc.Demo.*;
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); }
22 // Template Classes //////////////////////////////////////////////////////////////////////////////
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 {
29 public String tag() { return null; }
30 public void toHTML(ToHTML.HTML sb) { sb.tag(tag(), text); }
32 public static class TextArray extends Text {
34 public String tag() { return null; }
35 public void toHTML(ToHTML.HTML sb) { sb.tag(tag(), t); }
40 // Structural //////////////////////////////////////////////////////////////////////////////
42 public static class Doc implements ToHTML {
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); }
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 {
55 public Paragraph[] paragraphs;
56 public void toHTML(ToHTML.HTML sb) {
58 sb.append(paragraphs);
65 // Paragraph //////////////////////////////////////////////////////////////////////////////
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"; } }
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");
83 public static class OL extends List { public String tag() { return "ol"; } }
84 public static class UL extends List { public String tag() { return "ul"; } }
88 // Tags //////////////////////////////////////////////////////////////////////////////
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 {
109 public void toHTML(ToHTML.HTML sb) { sb.tag("a", new Object[] { "href", href }, text); }
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); }
118 // Network //////////////////////////////////////////////////////////////////////////////
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]);
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); }
134 public static interface URI extends ToHTML {
135 public static final Class[] subclasses = new Class[] { URL.class, Email.class };
137 public static class URL extends Text implements URI {
138 public String method;
143 public void toHTML(ToHTML.HTML sb) {
146 // login.toHTML(sb); FIXME
148 // sb.append(":"); FIXME
154 public static class Email extends Text implements URI {
157 public void toHTML(ToHTML.HTML sb) {
164 public static class Login {
165 public String username;
166 public String password;
167 public void toHTML(ToHTML.HTML sb) {
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");
213 public static void suffix(PrintWriter p) {
214 p.println("\\stoptext");
216 static String[] packages = new String[] { "supp-fun", "bib", "href" };
222 import Data.Array.IArray
230 toContex ll = prefix ++ (concatMap tl ll) ++ suffix
232 packages = [ "[supp-fun]",
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" ++
244 " before=\\blank\\hairline\\nowhitespace,\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" ++
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" ++
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"++
270 "\\switchtobodyfont[small]\n"
271 suffix = "\n\\stoptext\n"
272 addItem i = "\\item " ++ (striptrail $ boost 8 $ wrap $ striplead $ tl i)
274 escapify ('%':t) = '\\':'%':(escapify t)
275 escapify ('$':t) = '\\':'$':(escapify t)
276 escapify (h:t) = h:(escapify t)
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)++"})"
315 tl (BlankLine _) = "\n\n"
316 tl (Block _ l) = concatMap tl l
317 tl (Letter _ c) = escapify [c]
325 // Main //////////////////////////////////////////////////////////////////////////////
327 public static class Dump implements Reflection.Show {
328 public String toString() { return Reflection.show((Reflection.Show)this); }
331 public static class TD {
333 public @nonterminal static class Doc extends Dump {
334 public @arg Header head;
335 public @arg Body body;
338 public @nonterminal static class Header extends Dump {
339 public @arg KeyVal[] attrs;
340 // FIXME: it would be nice to be able to
341 // void KeyVal(String, String) { ... } imperatively
344 public @nonterminal static class Body extends Dump {
345 public Section[] sections;
348 public @nonterminal("Section") static class Section extends Dump {
349 public String header;
350 public Paragraph[] paragraphs;
353 public @nonterminal static class KeyVal extends Dump {
354 public @arg String key;
355 public @arg Object val;
358 public abstract static class Paragraph extends Dump implements ToHTML { }
360 public @tag("P") static class P extends Paragraph {
363 public P(Text[] text) { this.text = text; }
364 public void toHTML(HTML h) { if (text != null) for (Text t : text) if (t != null) t.toHTML(h); }
365 public String toString() {
366 StringBuffer sb = new StringBuffer();
367 ToHTML.HTML h = new ToHTML.HTML(sb);
369 return sb.toString();
373 public @tag("HR") static class HR extends Paragraph {
374 public void toHTML(HTML h) { h.tag("hr"); }
377 public @tag("Blockquote") static class Blockquote extends Paragraph {
379 public void toHTML(HTML h) { h.tag("blockquote", new P(text)); }
382 public abstract static class Text extends Dump implements ToHTML { }
383 public @tag static class Chars extends Text {
386 public Chars(String text) { this.text = text; }
387 public void toHTML(HTML h) { h.appendText(" " + text + " "); }
388 public String toString() { return text; }
390 public @tag static class Block extends Text {
392 public void toHTML(HTML h) { for(Text t : text) t.toHTML(h); }
394 public static class TextWrap extends Text {
396 public void toHTML(HTML h) {
398 h.tag(htmlTag(), htmlTagParams(), text);
402 public String htmlTag() { return null; }
403 public Object[] htmlTagParams() { return null; }
405 public static @tag class Verbatim extends Text { public char[] c; public void toHTML(HTML h) { } }
406 //public @tag class Blockquote extends TextWrap { }
407 public static @tag class Underline extends TextWrap { public String htmlTag() { return "u"; } }
408 public static @tag class Footnote extends TextWrap { public String htmlTag() { return "small"; } }
409 public static @tag class TT extends TextWrap { public String htmlTag() { return "tt"; } }
410 //public @tag class Citation extends Text { "[" word "]" }
411 public static @tag class Strikethrough extends TextWrap { public String htmlTag() { return "strikethrough"; } }
412 public static @tag class Superscript extends TextWrap { public String htmlTag() { return "sup"; } }
413 public static @tag class Subscript extends TextWrap { public String htmlTag() { return "sub"; } }
414 public static @tag class Smallcap extends TextWrap { public String htmlTag() { return "sc"; } }
415 public static @tag class Keyword extends TextWrap { public String htmlTag() { return "sc"; } }
416 public static @tag class Bold extends TextWrap { public String htmlTag() { return "b"; } }
417 public static @tag class Italic extends TextWrap { public String htmlTag() { return "i"; } }
419 public abstract static class Command extends Text { }
420 public static @tag class Today extends Command { public void toHTML(HTML h) { } }
421 public static @tag class LineBreak extends Command { public void toHTML(HTML h) { h.tag("br"); } }
423 public abstract static class Glyph extends Text { }
424 public static @tag("emdash") class Emdash extends Glyph { public void toHTML(HTML h) { h.append("&emdash;"); } }
426 public static class Link extends Text {
429 public @tag("LinkText") Link(Text[] t, Url u) { this.t = t; this.u = u; }
430 public @tag("LinkChars") Link(String s, Url u) { this(new Text[] { new Chars(s) }, u); }
431 public void toHTML(HTML h) {
433 new Object[] { "href", u==null ? "" : u.toString() },
438 public static class Host {
440 public String toString() { return name; }
441 public @tag("DNS") Host(String[][] parts) {
443 for(String[] s : parts) {
449 public @tag("IP") Host(int a, int b, int c, int d) { name = a+"."+b+"."+c+"."+d; }
452 public static class Url extends Text {
453 public String method;
459 public @tag("URL") Url(String method, String[] login, Host host, String port, String path) {
460 this.method = method;
461 this.user = login==null ? null : login.length >= 1 ? login[0] : null;
462 this.pass = login==null ? null : login.length >= 2 ? login[1] : null;
467 public @tag("Mailto") Url(String email) { this("mailto", null, null, "25", email); }
468 public void toHTML(HTML h) { new Link(toString(), this).toHTML(h); }
469 public String toString() {
470 return method + "://" + host + "/" + path;
473 public static @tag("lf") String lf() { return "\r"; }
474 public static @tag("cr") String cr() { return "\n"; }
475 public static @tag("\"\"") String empty() { return ""; }
476 public static @tag("urlescape") String urlescape(char a, char b) { return ((char)((a-'0') * 16 + (b-'0')))+""; }
479 public static void main(String[] s) throws Exception {
482 Demo.ReflectiveMeta m =
483 new Demo.ReflectiveMeta(TibDoc.TD.class,
486 TibDoc.TD.Header.class,
487 TibDoc.TD.Section.class,
489 TibDoc.TD.Host.class,
490 TibDoc.TD.Link.class,
491 TibDoc.TD.Body.class,
492 TibDoc.TD.Paragraph.class,
495 TibDoc.TD.Blockquote.class,
496 TibDoc.TD.KeyVal.class,
497 TibDoc.TD.Text.class,
498 TibDoc.TD.TextWrap.class,
499 TibDoc.TD.Verbatim.class,
500 TibDoc.TD.Blockquote.class,
501 TibDoc.TD.Underline.class,
502 TibDoc.TD.Footnote.class,
504 TibDoc.TD.Strikethrough.class,
505 TibDoc.TD.Superscript.class,
506 TibDoc.TD.Subscript.class,
507 TibDoc.TD.Smallcap.class,
508 TibDoc.TD.Bold.class,
509 TibDoc.TD.Keyword.class,
510 TibDoc.TD.Italic.class,
511 TibDoc.TD.Today.class,
512 TibDoc.TD.LineBreak.class,
513 TibDoc.TD.Chars.class,
514 TibDoc.TD.Emdash.class,
516 Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
517 MetaGrammar.Meta.MetaGrammarFile mgf = m.new MetaGrammarFile(res);
518 MetaGrammar.BuildContext bc = new MetaGrammar.BuildContext(mgf);
519 Union tibgram = mgf.get("s").build(bc);
521 System.err.println("parsing " + s[1]);
522 Tree t = new CharParser(tibgram).parse(new Tib(new FileInputStream(s[1]))).expand1();
523 System.out.println("tree:\n" + t.toPrettyString());
525 Object result = ((Functor)t.head()).invoke(t);
526 System.out.println((TD.Doc)result);
528 System.out.println("parsing " + s[0]);
529 Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
530 MetaGrammar gram = new Tib.Grammar(TibDoc.class);
531 gram = (MetaGrammar)gram.walk(res);
532 System.out.println("\nparsing " + s[1]);
533 Forest f = new CharParser(gram.done()).parse(new Tib(new FileInputStream(s[1])));
534 System.out.println();
535 System.out.println(f.expand1().toPrettyString());
536 System.out.println();
537 Doc doc = (Doc)new ReflectiveGrammar(TibDoc.class).build(f.expand1());
538 System.out.println(doc);
539 System.out.println();
540 System.out.println();
541 System.out.println();
542 System.out.println();
543 StringBuffer sb = new StringBuffer();
544 doc.toHTML(new ToHTML.HTML(sb));
545 System.out.println(sb);
547 FileOutputStream fos = new FileOutputStream("out.html");
548 PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
553 } catch (Ambiguous a) {
554 FileOutputStream fos = new FileOutputStream("/Users/megacz/Desktop/out.dot");
555 PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
556 GraphViz gv = new GraphViz();
557 a.ambiguity.toGraphViz(gv);
563 } catch (Exception e) {