+
+// FEATURE: <code type="c++"/> -- syntax highlighting
+// FEATURE: <code linenumbers="true"/> -- 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<e.getAttrLen(); i++) {
- if (e.getAttrKey(i).equals("title")) title = e.getAttrVal(i);
- if (e.getAttrKey(i).equals("author")) author = e.getAttrVal(i);
- if (e.getAttrKey(i).equals("email")) email = e.getAttrVal(i);
- if (e.getAttrKey(i).equals("subtitle")) subtitle = e.getAttrVal(i);
- }
- System.out.println("\\documentclass{article}");
- System.out.println("\\def\\ninept{\\def\\baselinestretch{.95}\\let\\normalsize\\small\\normalsize}");
- System.out.println("\\ninept");
- System.out.println("\\usepackage{graphicx}");
- System.out.println("\\usepackage{amssymb,amsmath,epsfig,alltt}");
- System.out.println("\\sloppy");
- System.out.println("\\usepackage{palatino}");
- System.out.println("\\usepackage{sectsty}");
- System.out.println("\\allsectionsfont{\\sffamily}");
- System.out.println("\\sectionfont{\\pagebreak\\leftskip=-2cm\\hrulefill\\\\\\sffamily\\bfseries\\raggedleft\\vspace{1cm}}");
- System.out.println("\\subsectionfont{\\dotfill\\\\\\sffamily\\raggedright\\hspace{-4cm}}");
- System.out.println("\\newdimen\\sectskip");
- System.out.println("\\newdimen\\subsectskip");
- System.out.println("\\newdimen\\saveskip");
- System.out.println("\\saveskip=\\leftskip");
- System.out.println("\\sectskip=-2cm");
- System.out.println("\\subsectskip=0cm");
- System.out.println("\\let\\oldsection\\section");
- System.out.println("\\let\\oldsubsection\\subsection");
- System.out.println("\\def\\subsection#1{\\leftskip=\\sectskip\\oldsubsection{#1}\\leftskip=0cm}");
- System.out.println("\\usepackage{parskip}");
- System.out.println("\\usepackage{tabularx}");
- System.out.println("\\usepackage{alltt}");
- System.out.println("\\usepackage[pdftex,bookmarks=true]{hyperref}");
- System.out.println("");
- System.out.println("\\begin{document}");
- System.out.println("");
- System.out.println("\\title{\\textbf{\\textsf{");
- System.out.println(title);
- if (subtitle != null) System.out.println("\\\\{\\large " + subtitle + "}");
- System.out.println("}}}");
- if (author != null) {
- System.out.println("\\author{");
- System.out.println(author);
- if (email != null) System.out.println("\\\\{\\tt " + email + "}");
- System.out.println("}");
- }
- System.out.println("");
- System.out.println("\\maketitle");
- System.out.println("\\clearpage");
- System.out.println("\\tableofcontents");
- System.out.println("\\clearpage");
- System.out.println("\\onecolumn");
- nodeStack.addElement(new Node());
- } else if (name.equals("section") || name.equals("appendix")) {
- String secname = "unknown";
- for(int i=0; i<e.getAttrLen(); i++) if (e.getAttrKey(i).equals("title")) secname = e.getAttrVal(i);
- nodeStack.addElement(new Section(secname, name.equals("appendix")));
- } else if (name.equals("b")) { nodeStack.addElement(new B());
- } else if (name.equals("i")) { nodeStack.addElement(new I());
- } else if (name.equals("tt")) { nodeStack.addElement(new TT());
- } else if (name.equals("list")) { nodeStack.addElement(new List());
- } else if (name.equals("pre")) { nodeStack.addElement(new PRE());
- } else if (name.equals("ref")) { buffer++;
- } else if (name.equals("link")) {
- buffer++;
- for(int i=0; i<e.getAttrLen(); i++) if (e.getAttrKey(i).equals("text")) addText(e.getAttrVal(i));
- } else if (name.equals("definition")) { buffer++;
- } else if (name.equals("property")) { buffer++;
- } else { System.err.println("warning: unknown tag " + name);
- buffer++;
+ if (newGuy != null) {
+ Node parent = (Node)nodeStack.lastElement();
+ if (parent != null) parent.addChild(newGuy);
+ nodeStack.addElement(newGuy);
}
}
-
- int buffer = 0;
- String pending = "";
+
public void whitespace(char[] ch, int start, int length) throws Exn, IOException { characters(ch, start, length); }
- void addText(String s) { ((Node)nodeStack.lastElement()).addText(s); }
public void endElement(Element e) throws Exn, IOException {
- if (buffer > 0) {
- buffer--;
- if (nodeStack.lastElement() instanceof PRE)
- ((PRE)nodeStack.lastElement()).addText("</" + e.getLocalName() + ">");
+ 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<children.size(); i++) {
- if (children.elementAt(i) instanceof String) {
- printText(p, (String)children.elementAt(i));
- } else {
- ((Node)children.elementAt(i)).dumpLatex(p);
- }
+ }
+
+
+ // Empty Nodes //////////////////////////////////////////////////////////////////////////////
+
+ class EmptyNode extends Node {
+ public EmptyNode() { }
+ public void addChild(Node o) { throw new RuntimeException(this.getClass().getName() + " cannot have children"); }
+ public void addText(String o) { throw new RuntimeException(this.getClass().getName() + " cannot have content"); }
+ public void dumpLatex(StringBuffer sb) { }
+ }
+
+ class Image extends EmptyNode {
+ public String url;
+ public Image(XML.Element e) { url = e.getAttrVal("url"); }
+ public void dumpLatex(StringBuffer sb) { sb.append("\\hyperimage{" + url + "}"); }
+ }
+
+ class Heading extends EmptyNode {
+ public String text;
+ public Heading(XML.Element e) { text = e.getAttrVal("title"); }
+ public void dumpLatex(StringBuffer sb) { sb.append("\\vspace{.6cm}\\hypertarget{" +
+ fixLatex(text) + "}{\\textbf{\\textsf{" +
+ fixLatex(text) + "}}}"); }
+ }
+
+ class LineBreak extends EmptyNode {
+ public LineBreak() { }
+ public void dumpLatex(StringBuffer sb) { sb.append("\\\n"); }
+ }
+
+ class ParagraphBreak extends EmptyNode {
+ public ParagraphBreak() { }
+ public void dumpLatex(StringBuffer sb) { sb.append("\n\n"); }
+ }
+
+
+
+ // Non-Paragraph Nodes //////////////////////////////////////////////////////////////////////////////
+
+ /** Nodes which contain only text; they split themselves if anything else is added */
+ class TextNode extends Node implements Cloneable {
+ protected String mytext = "";
+ private boolean canAcceptMoreText = true;
+ public void dumpLatex(StringBuffer sb) { sb.append(fixLatex(mytext)); }
+ public void addChild(Node o) { canAcceptMoreText = false; parent.addChild(o); }
+ public void addText(String o) {
+ if (canAcceptMoreText) {
+ mytext += (String)o;
+ String[] split = mytext.split("\\n\\s*\\n");
+ if (split.length <= 1) return;
+ canAcceptMoreText = false;
+ mytext = split[0];
+ parent.addChild(new ParagraphBreak());
+ o = "";
+ for(int i=1; i<split.length; i++) o += split[i];
+ }
+ try {
+ TextNode clone = (TextNode)clone();
+ clone.mytext = "";
+ clone.canAcceptMoreText = true;
+ clone.addText(o);
+ parent.addChild(clone);
+ } catch (CloneNotSupportedException cnse) {
+ throw new RuntimeException(cnse);
}
}
}
- class PRE extends Node {
- String myText = "";
- public void addText(String s) { myText += s; }
- public void dumpLatex(PrintStream p) {
- p.println("\n\\begin{verbatim}\n");
- p.print(myText);
- p.println("\n\\end{verbatim}\n");
+ class T extends TextNode {
+ public void dumpLatex(StringBuffer sb) {
+ sb.append("{\\texttt{");
+ super.dumpLatex(sb);
+ sb.append("}}");
+ } }
+ class B extends TextNode {
+ public void dumpLatex(StringBuffer sb) {sb.append("{\\textbf{"); super.dumpLatex(sb); sb.append("}}");}}
+ class I extends TextNode {
+ public void dumpLatex(StringBuffer sb) {sb.append("{\\it{"); super.dumpLatex(sb); sb.append("}}");}}
+ class Link extends TextNode {
+ public String url;
+ public String section;
+ public String appendix;
+ public String text;
+ public Link(XML.Element e) {
+ url = e.getAttrVal("url");
+ text = e.getAttrVal("text");
+ appendix = e.getAttrVal("appendix");
+ section = e.getAttrVal("section");
+ }
+ public void dumpLatex(StringBuffer sb) {
+ // FIXME: dotted underline for section/appendix, solid underline for url
+ String text = fixLatex(this.text);
+ if (text == null) text = "\\tt " + (url != null ? url : section != null ? section : appendix);
+ if (url != null) { sb.append("\\href{" + url + "}{\\uline{" + text + "}} ");
+ } else if (section != null) { sb.append("\\hyperlink{" + section + "}{\\uwave{" + text + "}} ");
+ } else if (appendix != null) { sb.append("\\hyperlink{" + appendix + "}{\\uwave{" + text + "}} ");
+ }
}
}
- class I extends Node { public void dumpLatex(PrintStream p) { p.print("{\\it "); super.dumpLatex(p); p.print("}"); } }
- class B extends Node { public void dumpLatex(PrintStream p) { p.print("{\\bf "); super.dumpLatex(p); p.print("}"); } }
- class TT extends Node { public void dumpLatex(PrintStream p) {
- p.print("{\\tt ");
- intt = true;
- super.dumpLatex(p);
- intt = false;
- p.print("}"); } }
+ class PRE extends TextNode {
+ public PRE(int start, int end) {
+ while(Character.isWhitespace(buffer[start])) start++;
+ while(buffer[start] != '\n') start--;
+ start++;
+ end -= 6; // ugly hack since </pre> 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<children.size(); i++) {
+ if (children.elementAt(i) instanceof String) sb.append(fixLatex(children.elementAt(i).toString()));
+ else ((Node)children.elementAt(i)).dumpLatex(sb);
+ }
+ }
+ }
+
+ class Property extends ParagraphNode {
+ String name = "";
+ String type = "";
+ String default_ = null;
+ public Property(XML.Element e) {
+ name = e.getAttrVal("name");
+ if (name == null || name.equals("")) name = "ERROR";
+ type = e.getAttrVal("type");
+ default_ = e.getAttrVal("default");
+ if (default_ != null && default_.trim().length() == 0) default_ = null;
+ }
+ 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);
+ String fname = fixLatex(name);
+ type = type == null || type.equals("") ? "" : "({\\it{" + fixLatex(type) + "}})";
+ if (name.trim().length() > 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<children.size(); i++) {
- if (children.elementAt(i) instanceof String) {
- acc += fix(children.elementAt(i).toString());
+ Object kid = children.elementAt(i);
+ if (kid instanceof ParagraphBreak || kid instanceof List) unusedItem = false;
+ if (kid instanceof String) {
+ if (kid.toString().trim().length() == 0) continue;
+ if (!unusedItem) { unusedItem = true; sb.append("\n\n\\item\n"); }
+ sb.append(children.elementAt(i));
} else {
- if (acc.length() > 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}");
+ }
+ }
}
+