From: adam Date: Thu, 25 Mar 2004 12:20:12 +0000 (+0000) Subject: ground-up rewrite of org.ibex.util.Doc X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=commitdiff_plain;h=94d57bfab114b397f94e7b2780fbef41fdc6c3bd ground-up rewrite of org.ibex.util.Doc darcs-hash:20040325122012-5007d-5bb81bca1b265ece2f6a704abf7649d10ba9f4db.gz --- diff --git a/src/org/ibex/util/Doc.java b/src/org/ibex/util/Doc.java index f2780b0..70ef527 100644 --- a/src/org/ibex/util/Doc.java +++ b/src/org/ibex/util/Doc.java @@ -1,226 +1,436 @@ + +// FEATURE: -- syntax highlighting +// FEATURE: -- LaTeX moreverb package can help +// FIXME: nest TextNodes within each other for bold+italic + package org.ibex.util; import java.util.*; import java.io.*; import org.ibex.util.*; public class Doc extends XML { + + Root root = null; + int skip = 0; + Vec nodeStack = new Vec(); + String pending = ""; + char[] buffer = new char[1024 * 1024]; + int preStart = -1; + + public Doc() { } + public static void main(String[] s) throws Exception { Doc d = new Doc(); - d.parse(new InputStreamReader(System.in)); - ((Node)d.nodeStack.elementAt(0)).dumpLatex(System.out); - System.out.println("\\end{document}"); + Reader r = new InputStreamReader(System.in); + int len = 0; + while(true) { + int numread = r.read(d.buffer, len, d.buffer.length - len); + if (numread == -1) break; + len += numread; + if (len >= d.buffer.length) { + char[] newbuffer = new char[d.buffer.length * 2]; + System.arraycopy(d.buffer, 0, newbuffer, 0, d.buffer.length); + d.buffer = newbuffer; + } + } + d.parse(new CharArrayReader(d.buffer)); + StringBuffer sb = new StringBuffer(); + d.root.dumpLatex(sb); + System.out.println(sb); } - - Vec top = new Vec(); - Vec nodeStack = new Vec(); - public Doc() { nodeStack.addElement(new Node()); } public void startElement(Element e) throws Exn { + if (preStart != -1) return; String name = e.getLocalName(); - if (nodeStack.lastElement() != null && (nodeStack.lastElement() instanceof PRE)) { - ((PRE)nodeStack.lastElement()).addText("<" + e.getQName() + ">"); - buffer++; - return; + Node newGuy = null; + if (name.equals("ibex-doc")) { newGuy = new Root(e); + } else if (name.equals("section")) { newGuy = new Section(e); + } else if (name.equals("heading")) { newGuy = new Heading(e); + } else if (name.equals("appendix")) { newGuy = new Appendix(e); + } else if (name.equals("list")) { newGuy = new List(); + + } else if (name.equals("pre")) { preStart = getGlobalOffset(); + + } else if (name.equals("definition")) { newGuy = new Definition(e); + } else if (name.equals("property")) { newGuy = new Property(e); + + } else if (name.equals("b")) { newGuy = new B(); + } else if (name.equals("i")) { newGuy = new I(); + } else if (name.equals("t")) { newGuy = new T(); + } else if (name.equals("link")) { newGuy = new Link(e); + } else if (name.equals("image")) { newGuy = new Image(e); + + } else { + System.err.println("warning: unknown tag " + name); + skip++; } - if (name.equals("ibex-doc")) { - String title = "You forgot the title, you idiot!"; - String author = "Your Mom"; - String email = null; - String subtitle = null; - for(int i=0; i 0) { - buffer--; - if (nodeStack.lastElement() instanceof PRE) - ((PRE)nodeStack.lastElement()).addText(""); + if (preStart != -1) { + if (!e.getLocalName().equals("pre")) return; + ((Node)nodeStack.lastElement()).addChild(new PRE(preStart, getGlobalOffset())); + preStart = -1; + } else if (skip > 0) { + skip--; + return; } else { nodeStack.setSize(nodeStack.size() - 1); } } public void characters(char[] ch, int start, int length) throws Exn, IOException { - Node n = ((Node)nodeStack.lastElement()); - if (n != null) n.addText(new String(ch, start, length)); - } - - boolean intt = false; - class Node { - Vec children = new Vec(); - final Node parent; - public Node() { this((Node)nodeStack.lastElement()); } - public Node(Node parent) { this.parent = parent; if (parent != null) parent.add(this); } - public void add(Node child) { children.addElement(child); } - public void addText(String s) { children.addElement(s); } - void printText(PrintStream p, String mt2) { p.print(fix(mt2)); } - String fix(String mt2) { - mt2 = mt2.replaceAll("\\\\", "\\backslash "); - mt2 = mt2.replaceAll("LaTeX", "\\LaTeX"); - mt2 = mt2.replaceAll("\\$", "\\\\\\$ "); - mt2 = mt2.replaceAll("\\%", "\\\\% "); - mt2 = mt2.replaceAll("#", "\\\\# "); - mt2 = mt2.replaceAll("\\{", "\\\\{ "); - mt2 = mt2.replaceAll("\\}", "\\\\} "); - mt2 = mt2.replaceAll("\\&", "\\\\& "); - mt2 = mt2.replaceAll("\\~", "\\\\~ "); - mt2 = mt2.replaceAll("_", "\\\\_"); - if (!intt) { - mt2 = mt2.replaceAll("\" ", "'' "); - mt2 = mt2.replaceAll("\"\n", "''\n"); + if (preStart != -1) return; + ((Node)nodeStack.lastElement()).addText(new String(ch, start, length)); + } + + abstract class Node { + public Node parent = null; + public abstract void addText(String s); + public abstract void addChild(Node s); + public abstract void dumpLatex(StringBuffer sb); + final String fixLatex(String s) { + if (s == null) return ""; + s = s.replaceAll("\\$", "\\\\\\$ "); + s = s.replaceAll("\\\\([^\\$])", "\\$\\\\backslash\\$\\1"); + s = s.replaceAll("LaTeX", "\\\\LaTeX"); + s = s.replaceAll("\\%", "\\\\% "); + s = s.replaceAll("#", "\\\\#"); + s = s.replaceAll("\\{", "\\\\{"); + s = s.replaceAll("\\}", "\\\\}"); + s = s.replaceAll("\\&", "\\\\&"); + s = s.replaceAll("\\~", "\\\\~"); + s = s.replaceAll("_", "\\\\_"); + if (!(this instanceof T)) { + s = s.replaceAll(" \"", " ``"); + s = s.replaceAll("\"", "''"); } - mt2 = mt2.replaceAll(" \"", " ``"); - mt2 = mt2.replaceAll("\"", "``"); - return mt2; + return s; } - public void dumpLatex(PrintStream p) { - for(int i=0; i is 6 chars long... + if (Character.isWhitespace(buffer[end])) { + while(Character.isWhitespace(buffer[end])) end--; + end++; + } + mytext = new String(buffer, start, end - start); + } + public void dumpLatex(StringBuffer sb) { + sb.append("\n\n\\begin{Verbatim}[fontfamily=courier,fontsize=\\footnotesize,frame=single,rulecolor=\\color{CodeBorder},resetmargins=true]\n"); + sb.append(mytext); + sb.append("\\end{Verbatim}\n\n"); + } + } - class Section extends Node { - String secname; - boolean appendix = false; - public Section(String secname, boolean appendix) { this.secname = secname; this.appendix = appendix;} - public void dumpLatex(PrintStream p) { - String secs = ""; - for(Node n = parent; n != null; n = n.parent) if (n instanceof Section) secs += "sub"; - if (appendix) { - p.println("\n\n\\appendix{"+secname+"}\n"); + + // Paragraph Nodes ////////////////////////////////////////////////////////////////////////////// + + class ParagraphNode extends Node { + protected Vec children = new Vec(); + public void addChild(Node n) { children.addElement(n); n.parent = this; } + public void addText(String s) { + if (children.size() == 0 || !(children.lastElement() instanceof String)) + children.addElement(s); + else + children.setElementAt(children.lastElement() + s, children.size() - 1); + } + public void dumpLatex(StringBuffer sb) { + for(int i=0; i 13) { + sb.append("\n\n{\\color{CodeBorder}\\hspace{-2cm}\\dotfill\\\\\\color{black}}"); + sb.append("\\marginpar{\\raggedleft{\\texttt{\\textbf{\\footnotesize{"+fname+"}}}}\\\\"+type+" }"); + sb.append("\\\\"); + sb.append(s); } else { - p.println("\n\n\\" + secs + "section{"+secname+"}\n"); + sb.append("\n\n{\\color{CodeBorder}\\hspace{-2cm}\\dotfill\\\\\\color{black}}"); + sb.append(s.substring(0, s.indexOf(' '))); + sb.append("\\marginpar{\\raggedleft{\\texttt{\\textbf{\\footnotesize{"+fname+"}}}}\\\\"+type+" }"); + sb.append(s.substring(s.indexOf(' '))); } - super.dumpLatex(p); + if (default_ != null) { + sb.append("\\\\{\\it default: }{\\texttt{" + fixLatex(default_) + "}}\n\n"); + } else { + sb.append("\n\n"); + } + } + } + + class Definition extends ParagraphNode { + String name = ""; + public Definition(XML.Element e) { name = e.getAttrVal("term"); } + public void dumpLatex(StringBuffer sb) { + StringBuffer sb2 = new StringBuffer(); + super.dumpLatex(sb2); + String s = sb2.toString(); + while(Character.isSpace(s.charAt(0))) s = s.substring(1); + sb.append(s.substring(0, s.indexOf(' '))); + sb.append("\\marginpar{\\raggedleft{\\textbf{"+fixLatex(name)+"}}}"); + sb.append(s.substring(s.indexOf(' '))); } } - class List extends Node { - boolean ordered = false; - public void dumpLatex(PrintStream p) { - p.println("\n\\begin{itemize}%\n"); - String acc = ""; - p.print("\n\\item%\n"); - boolean used = false; + class Section extends ParagraphNode { + String name; + public Section(XML.Element e) { name = e.getAttrVal("title"); } + public void dumpLatex(StringBuffer sb) { + String secs = ""; + String base = "section"; + for(Node n = parent; n != null; n = n.parent) + if (n instanceof Section || n instanceof Appendix) { + base = "section"; + secs += "sub"; + } + if (secs.length() == 0) + sb.append("\\newpage\n\n"); + sb.append("\n\n\\hypertarget{" + name + "}{\\" + secs + base + "{" + name + "}}\n\n"); + super.dumpLatex(sb); + } + } + + static boolean hitAppendix = false; + class Appendix extends Section { + public Appendix(XML.Element e) { super(e); } + public void dumpLatex(StringBuffer sb) { + if (!hitAppendix) sb.append("\\appendix\n"); + hitAppendix = true; + super.dumpLatex(sb); + } + } + + class List extends ParagraphNode { + Node textnode = null; + public List() { } + public void addText(String s) { + if (!(children.lastElement() == textnode) || (textnode == null && children.lastElement() == null)) + addChild(textnode = new TextNode()); + ((TextNode)children.lastElement()).addText(s); + } + public void dumpLatex(StringBuffer sb) { + sb.append("\n\\begin{itemize}%\n"); + boolean unusedItem = false; for(int i=0; i 0) { - if (!used) acc = acc.replaceAll("^\\s*", ""); - if (children.elementAt(i) instanceof List) acc = acc.replaceAll("\\n\\s*$", ""); - acc = acc.replaceAll("\\n\\s*\\n", "\n\n\\\\item "); - if (acc.trim().length() > 0) { - used = true; - p.print(acc); - } - acc = ""; + if (kid instanceof TextNode) { + if (((TextNode)kid).mytext.trim().length() == 0) continue; + if (!unusedItem) { unusedItem = true; sb.append("\n\n\\item\n"); } } - ((Node)children.elementAt(i)).dumpLatex(p); + ((Node)kid).dumpLatex(sb); } } - if (acc.length() > 0) { - if (!used) acc = acc.replaceAll("^\\s*", ""); - acc = acc.replaceAll("\\n\\s*$", ""); - p.print(acc.replaceAll("\\n\\s*\\n", "\n\n\\\\item ")); - acc = ""; - } - p.println("\n\\end{itemize}%\n"); + sb.append("\n\\end{itemize}%\n"); } } + class Root extends ParagraphNode { + String title = "You forgot the title, you idiot!"; + String author = "Your Mom"; + String email = null; + String subtitle = null; + public Root(XML.Element e) { + root = this; + title = e.getAttrVal("title"); + author = e.getAttrVal("author"); + email = e.getAttrVal("email"); + subtitle = e.getAttrVal("subtitle"); + } + public void dumpLatex(StringBuffer sb) { + sb.append("\\documentclass{article}\n"); + sb.append("\\def\\ninept{\\def\\baselinestretch{.95}\\let\\normalsize\\small\\normalsize}\n"); + sb.append("\\ninept\n"); + sb.append("\\usepackage{color}\n"); + sb.append("\\definecolor{CodeBorder}{rgb}{0.6,0.6,0.6}\n"); + sb.append("\\definecolor{CodeBackground}{rgb}{0.93,0.93,0.93}\n"); + sb.append("\\usepackage{graphicx}\n"); + sb.append("\\usepackage{courier}\n"); + sb.append("\\usepackage{fancyvrb}\n"); + sb.append("\\usepackage{fvrb-ex}\n"); + sb.append("\\usepackage{bold-extra}\n"); + sb.append("\\usepackage{ulem}\n"); + sb.append("\\usepackage{appendix}\n"); + sb.append("\\usepackage{amssymb,amsmath,epsfig,alltt}\n"); + sb.append("\\sloppy\n"); + sb.append("\\usepackage{palatino}\n"); + sb.append("\\usepackage{sectsty}\n"); + sb.append("\\allsectionsfont{\\sffamily}\n"); + sb.append("\\sectionfont{\\color{black}\\leftskip=-2cm\\hrulefill\\\\\\sffamily\\bfseries\\raggedleft\\vspace{1cm}}\n"); + sb.append("\\subsectionfont{\\color{black}\\dotfill\\\\\\sffamily\\raggedright\\hspace{-4cm}}\n"); + sb.append("\\newdimen\\sectskip\n"); + sb.append("\\newdimen\\subsectskip\n"); + sb.append("\\newdimen\\saveskip\n"); + sb.append("\\saveskip=\\leftskip\n"); + sb.append("\\sectskip=-2cm\n"); + sb.append("\\subsectskip=0cm\n"); + sb.append("\\let\\oldsection\\section\n"); + sb.append("\\let\\oldsubsection\\subsection\n"); + sb.append("\\def\\subsection#1{\\leftskip=\\sectskip\\oldsubsection{#1}\\leftskip=0cm}\n"); + sb.append("\\usepackage{parskip}\n"); + sb.append("\\usepackage{tabularx}\n"); + sb.append("\\usepackage{alltt}\n"); + sb.append("\\usepackage[pdftex,colorlinks=true,urlcolor=blue,linkcolor=blue,bookmarks=true]{hyperref}\n"); + // FIXME: pdfauthor, pdftitle, pdfsubject, pdfkeywords? + sb.append("\n"); + sb.append("\\begin{document}\n"); + sb.append("\\reversemarginpar\n"); + sb.append("\n"); + sb.append("\\title{\\textbf{\\textsf{\n"); + sb.append(title); + if (subtitle != null) sb.append("\\\\{\\large " + subtitle + "}\n"); + sb.append("}}}\n"); + if (author != null) { + sb.append("\\author{\n"); + sb.append(author); + if (email != null) sb.append("\\\\{\\tt " + email + "}\n"); + sb.append("}\n"); + } + sb.append("\n"); + sb.append("\\maketitle\n"); + sb.append("\\clearpage\n"); + sb.append("\\tableofcontents\n"); + sb.append("\\clearpage\n"); + sb.append("\\onecolumn\n"); + super.dumpLatex(sb); + sb.append("\\end{document}"); + } + } } +