implementation for Markdown support

This commit is contained in:
stfm
2012-10-03 21:23:52 +02:00
parent 800bc73262
commit 2c2b90f129
3 changed files with 237 additions and 75 deletions

35
pom.xml
View File

@@ -21,12 +21,47 @@
</properties>
<repositories>
<repository>
<id>scala-tools</id>
<url>http://scala-tools.org/repo-releases</url>
</repository>
<repository>
<id>renejeschke-releases</id>
<url>http://maven.renejeschke.de</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.keypoint</groupId>
<artifactId>png-encoder</artifactId>
<version>1.5</version>
</dependency>
<!-- some mark down processors -->
<!--<dependency>
<groupId>org.markdownj</groupId>
<artifactId>markdownj</artifactId>
<version>0.3.0-1.0.2b4</version>
</dependency>-->
<!--<dependency>
<groupId>org.pegdown</groupId>
<artifactId>pegdown</artifactId>
<version>1.1.0</version>
</dependency>-->
<!--<dependency>
<groupId>org.tautua.markdownpapers</groupId>
<artifactId>markdownpapers-core</artifactId>
<version>1.2.7</version>
</dependency>-->
<dependency>
<groupId>com.github.rjeschke</groupId>
<artifactId>txtmark</artifactId>
<version>0.7</version>
</dependency>
</dependencies>
<build>

View File

@@ -13,6 +13,7 @@ import java.io.StringReader;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Hashtable;
import java.util.Scanner;
import java.util.Stack;
import javax.swing.ImageIcon;
@@ -21,6 +22,7 @@ import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import com.github.rjeschke.txtmark.Processor;
import com.keypoint.PngEncoder;
/**
@@ -40,6 +42,9 @@ import com.keypoint.PngEncoder;
*/
public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
private static final String MARKDOWN1 = "md";
private static final String MARKDOWN2 = "markdown";
private static final String IMAGES_DIR = "texdoclet_images";
/**
@@ -47,11 +52,11 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
*/
StringBuffer ret;
Stack tblstk = new Stack();
Stack<TableInfo> tblstk = new Stack<TableInfo>();
TableInfo tblinfo;
int verbat = 0;
int colIdx = 0;
Hashtable colors = new Hashtable(10);
Hashtable<String, String> colors = new Hashtable<String, String>(10);
String block = "";
String refurl = null;
String doPrintURL = null;
@@ -59,6 +64,7 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
String refimg = null;
boolean notex = false;
int imageindex = 0;
boolean inPreMarkdown = false;
/**
* Constructs a new instance.
@@ -78,8 +84,6 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
@Override
public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet attrSet,
int pos) {
String str = null;
int i = 0;
if (tag.toString().equalsIgnoreCase("tex")) {
if (attrSet.containsAttribute(HTML.Attribute.ENDTAG, "true")) {
notex = false;
@@ -210,13 +214,16 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
@Override
public void handleStartTag(HTML.Tag tag, MutableAttributeSet attrSet,
int pos) {
String str = null;
int i = 0;
if (notex) {
return;
} else if (tag == HTML.Tag.PRE) {
if (attrSet.containsAttribute("format", MARKDOWN1)
|| attrSet.containsAttribute("format", MARKDOWN2)) {
inPreMarkdown = true;
} else {
ret.append(TeXDoclet.TRUETYPE + "\\small\n\\mbox{}\\newline ");
verbat++;
}
} else if (tag == HTML.Tag.H1) {
ret.append("\\chapter*{");
} else if (tag == HTML.Tag.H2) {
@@ -261,8 +268,8 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
File file = new File(TeXDoclet.packageDir, refurl);
if (file.exists()) {
if (TeXDoclet.appendencies.contains(file.getPath())) {
refurl = (String) TeXDoclet.appendencies
.get(file.getPath());
refurl = TeXDoclet.appendencies.get(file
.getPath());
} else {
refurl = "appendix"
+ new Integer(
@@ -312,6 +319,8 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
ret.append("\\begin{itemize}");
} else if (tag == HTML.Tag.I) {
ret.append(TeXDoclet.ITALIC + " ");
} else if (tag == HTML.Tag.EM) {
ret.append(TeXDoclet.ITALIC + " ");
} else if (tag == HTML.Tag.TABLE) {
tblstk.push(tblinfo);
tblinfo = new TableInfo();
@@ -323,7 +332,7 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
} else if (tag == HTML.Tag.TR) {
tblinfo.startRow(attrSet);
} else if (tag == HTML.Tag.FONT) {
String sz = (String) attrSet.getAttribute(HTML.Attribute.SIZE);
// String sz = (String) attrSet.getAttribute(HTML.Attribute.SIZE);
String col = (String) attrSet.getAttribute(HTML.Attribute.COLOR);
ret.append("{");
if (col != null) {
@@ -332,8 +341,7 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
} else {
if ("abcdefABCDEF0123456789".indexOf(col.charAt(0)) != -1) {
Color cc = new Color((int) Long.parseLong(col, 16));
String name = (String) colors
.get("color" + cc.getRGB());
String name = colors.get("color" + cc.getRGB());
if (name == null) {
ret.append("\\definecolor{color" + colIdx
+ "}[rgb]{" + (cc.getRed() / 255.0) + ","
@@ -358,13 +366,15 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
*/
@Override
public void handleEndTag(HTML.Tag tag, int pos) {
int i = 0;
if (notex) {
return;
} else if (tag == HTML.Tag.PRE) {
if (!inPreMarkdown) {
verbat--;
ret.append("}\n");
} else {
inPreMarkdown = false;
}
} else if (tag == HTML.Tag.H1) {
ret.append("}");
} else if (tag == HTML.Tag.H2) {
@@ -437,9 +447,11 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
ret.append("\n\\end{itemize}\n");
} else if (tag == HTML.Tag.I) {
ret.append("}");
} else if (tag == HTML.Tag.EM) {
ret.append("}");
} else if (tag == HTML.Tag.TABLE) {
ret = tblinfo.endTable();
tblinfo = (TableInfo) tblstk.pop();
tblinfo = tblstk.pop();
} else if (tag == HTML.Tag.TH) {
tblinfo.endCol();
} else if (tag == HTML.Tag.TD) {
@@ -457,6 +469,50 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
@Override
public void handleText(char[] data, int pos) {
String str = new String(data);
if (inPreMarkdown) {
String html = "";
// usually java documentation has a leading space character in each
// line
// that is to remove for markdown processing !
if (str.startsWith(" ")) {
str = removeLeadingSpaces(str);
}
// test some Markdown processors here :
// 1. MarkdownJ
// MarkdownProcessor m = new MarkdownProcessor();
// html = m.markdown(str);
// 2. PegDown
// PegDownProcessor pp = new PegDownProcessor();
// html = pp.markdownToHtml(str);
// 3. MarkdownPapers
// Markdown md = new Markdown();
// StringWriter sw = new StringWriter();
// try {
// md.transform(new StringReader(str), sw);
// } catch (org.tautua.markdownpapers.parser.ParseException e) {
// e.printStackTrace();
// }
// html = sw.toString();
// 4. Txtmark
html = Processor.process(str);
String toAppend = HTMLtoLaTeXBackEnd.fixText(html);
ret.append(toAppend);
return;
}
for (int i = 0; i < str.length(); ++i) {
int c = str.charAt(i);
if (notex) {
@@ -621,4 +677,18 @@ public class HTMLtoLaTeXBackEnd extends HTMLEditorKit.ParserCallback {
return new String(result);
}
private String removeLeadingSpaces(String str) {
StringBuffer sb = new StringBuffer();
Scanner scanner = new Scanner(str);
while (scanner.hasNextLine()) {
String l = scanner.nextLine();
if (l.startsWith(" ")) {
sb.append(l.substring(1) + System.getProperty("line.separator"));
} else {
sb.append(l + System.getProperty("line.separator"));
}
}
return sb.toString();
}
}

View File

@@ -90,9 +90,10 @@ import com.sun.javadoc.Type;
* src="http://upload.wikimedia.org/wikipedia/commons/9/92/LaTeX_logo.svg">
* </dl>
*
* <H3>Extra tags</H3> A new tag is defined: <CODE>&lt;TEX&gt;</CODE>. This tag
* is useful for passing <TEX txt="\TeX{}">TeX</TEX> code directly to the <TEX
* txt="\TeX{}">TeX</TEX> compiler. The following code:
* <H3>Extra tags</H3> <H4>&lt;TEX&gt;</H4> A new tag is defined:
* <CODE>&lt;TEX&gt;</CODE>. This tag is useful for passing <TEX
* txt="\TeX{}">TeX</TEX> code directly to the <TEX txt="\TeX{}">TeX</TEX>
* compiler. The following code:
*
* <PRE>
*
@@ -111,12 +112,74 @@ import com.sun.javadoc.Type;
* </TEX> The "alternative" text is ignored by the TeXDoclet, but useful if you
* want to use both the TeXDoclet and a regular HTML based doclet.
*
* <H4>&lt;PRE format="markdown"&gt;</H4>
*
* Instead of writing your java documentation in often hard to read HTML code
* you can make use of <a
* href="http://en.wikipedia.org/wiki/Markdown">Markdown</a> syntax. The HTML
* <code>&lt;PRE&gt;</code> tag is used therefore to prevent your IDE from
* automatically reordering your Markdown documentation text. Markdown parsing
* is based on the <a href="https://github.com/sirthias/pegdown">Pegdown</a>
* implementation. The following code :
*
* <PRE>
*
* &lt;PRE format="markdown"&gt;
*
* some text some text some text some text some text some text some text
*
* ##### Lists
*
* - item1
* 1. item11
* 2. item12
* - item1
*
* ##### Text formatting
*
* _emphasis_ and __strong__ and some `code` :
*
* code line 1
* code line 2
*
* some text some text some text some text some text some text some text
*
* &lt;PRE&gt;
*
* </PRE>
*
* will produce the following : <br>
* <p>
*
* <PRE format="md">
*
* some text some text some text some text some text some text some text
*
* ##### Lists
*
* - item1
* 1. item11
* 2. item12
* - item1
*
* ##### Text formatting
*
* _emphasis_ and __strong__ and some `code` :
*
* code line 1
* code line 2
*
* some text some text some text some text some text some text some text
*
* </PRE>
*
* @see HTMLtoLaTeXBackEnd
* @see #start(RootDoc) start
* @author Gregg Wonderly - C2 Technologies Inc.
* @author Soeren Caspersen - XO Software.
* @author Stefan Marx
*/
@SuppressWarnings("restriction")
public class TeXDoclet extends Doclet {
private static final String OUT_FILENAME_DOCS_TEX = "docs.tex";
@@ -137,8 +200,8 @@ public class TeXDoclet extends Doclet {
/** Writer for writing to output file */
public static PrintWriter os = null;
static boolean inherited = true;
static Hashtable map2;
static Vector map;
static Hashtable<String, Package> map2;
static Vector<Package> map;
static ClassFilter clsFilt;
static RootDoc theroot;
static String docclass = "report";
@@ -162,9 +225,9 @@ public class TeXDoclet extends Doclet {
static String packageFile = "docpackage.tex";
static String preambleFile = "docinit.tex";
static File packageDir = null;
static Hashtable appendencies = new Hashtable();
static Hashtable refs = new Hashtable();
static Hashtable externalrefs = new Hashtable();
static Hashtable<String, String> appendencies = new Hashtable<String, String>();
static Hashtable<String, Hashtable<?, ?>> refs = new Hashtable<String, Hashtable<?, ?>>();
static Hashtable<String, Hashtable<?, ?>> externalrefs = new Hashtable<String, Hashtable<?, ?>>();
static boolean includeTexOutputInOtherTexFile = false;
static String sectionLevelMax = null;
@@ -382,7 +445,7 @@ public class TeXDoclet extends Doclet {
FileInputStream in = new FileInputStream(args[i][2]
+ ".map");
ObjectInputStream p = new ObjectInputStream(in);
Hashtable exref = (Hashtable) p.readObject();
Hashtable<?, ?> exref = (Hashtable<?, ?>) p.readObject();
externalrefs.put(args[i][1], exref);
} catch (Exception e) {
e.printStackTrace();
@@ -428,8 +491,8 @@ public class TeXDoclet extends Doclet {
public static void init() {
map2 = new Hashtable();
map = new Vector();
map2 = new Hashtable<String, Package>();
map = new Vector<Package>();
try {
os = new PrintWriter(new FileWriter(outfile));
} catch (Exception ex) {
@@ -559,8 +622,6 @@ public class TeXDoclet extends Doclet {
ClassDoc[] cls = root.classes();
ExecutableMemberDoc[] mems;
PackageDoc[] specifiedPackages = root.specifiedPackages();
System.out.println("specifiedPackages : " + specifiedPackages.length);
for (int i = 0; i < specifiedPackages.length; i++) {
@@ -586,7 +647,7 @@ public class TeXDoclet extends Doclet {
Package v;
PackageDoc pkgDoc = cd.containingPackage();
String pkg = pkgDoc.name();
if ((v = (Package) map2.get(pkg)) == null) {
if ((v = map2.get(pkg)) == null) {
v = new Package(pkg, pkgDoc);
map2.put(pkg, v);
map.add(v);
@@ -595,9 +656,9 @@ public class TeXDoclet extends Doclet {
}
// Sorting
Enumeration h = map.elements();
Enumeration<Package> h = map.elements();
while (h.hasMoreElements()) {
final Package pkg = (Package) h.nextElement();
final Package pkg = h.nextElement();
pkg.sort();
}
@@ -614,9 +675,9 @@ public class TeXDoclet extends Doclet {
// Packages
Enumeration e = map.elements();
Enumeration<Package> e = map.elements();
while (e.hasMoreElements()) {
final Package pkg = (Package) e.nextElement();
final Package pkg = e.nextElement();
// os.println( "\\newpage" );
@@ -697,10 +758,10 @@ public class TeXDoclet extends Doclet {
// i++;
// }
os.println("\\begin{appendix}");
Iterator it = appendencies.keySet().iterator();
Iterator<String> it = appendencies.keySet().iterator();
int i = 0;
while (it.hasNext()) {
String sfa = (String) it.next();
String sfa = it.next();
File f = new File(sfa);
String fname = f.getName().replace("_", "\\_");
System.out.println(fname);
@@ -888,7 +949,7 @@ public class TeXDoclet extends Doclet {
/**
* Produces a table-of-contents for classes.
*/
static void tocForClasses(String title, Vector v) {
static void tocForClasses(String title, Vector<ClassDoc> v) {
if (v.size() > 0) {
os.println("\\vskip .13in");
@@ -896,7 +957,7 @@ public class TeXDoclet extends Doclet {
+ HTMLtoLaTeXBackEnd.fixText(title) + "}}");
for (int i = 0; i < v.size(); ++i) {
ClassDoc cd = (ClassDoc) v.elementAt(i);
ClassDoc cd = v.elementAt(i);
os.print("\\entityintro{"
+ HTMLtoLaTeXBackEnd.fixText(cd.name()) + "}" + "{"
+ refName(makeRefKey(cd.qualifiedName())) + "}" + "{");
@@ -925,11 +986,11 @@ public class TeXDoclet extends Doclet {
// Classes
ClassHierachy classHierachy = new ClassHierachy();
Enumeration f = map.elements();
Enumeration<Package> f = map.elements();
while (f.hasMoreElements()) {
final Package pkg = (Package) f.nextElement();
final Package pkg = f.nextElement();
for (int i = 0; i < pkg.classes.size(); i++) {
classHierachy.add((ClassDoc) pkg.classes.get(i));
classHierachy.add(pkg.classes.get(i));
}
}
if (classHierachy.root.size() != 0) {
@@ -947,9 +1008,9 @@ public class TeXDoclet extends Doclet {
InterfaceHierachy interfaceHierachy = new InterfaceHierachy();
f = map.elements();
while (f.hasMoreElements()) {
final Package pkg = (Package) f.nextElement();
final Package pkg = f.nextElement();
for (int i = 0; i < pkg.interfaces.size(); i++) {
interfaceHierachy.add((ClassDoc) pkg.interfaces.get(i));
interfaceHierachy.add(pkg.interfaces.get(i));
}
}
if (interfaceHierachy.root.size() != 0) {
@@ -961,9 +1022,9 @@ public class TeXDoclet extends Doclet {
ClassHierachy exceptionHierachy = new ClassHierachy();
f = map.elements();
while (f.hasMoreElements()) {
final Package pkg = (Package) f.nextElement();
final Package pkg = f.nextElement();
for (int i = 0; i < pkg.exceptions.size(); i++) {
exceptionHierachy.add((ClassDoc) pkg.exceptions.get(i));
exceptionHierachy.add(pkg.exceptions.get(i));
}
}
if (exceptionHierachy.root.size() != 0) {
@@ -975,9 +1036,9 @@ public class TeXDoclet extends Doclet {
ClassHierachy errorHierachy = new ClassHierachy();
f = map.elements();
while (f.hasMoreElements()) {
final Package pkg = (Package) f.nextElement();
final Package pkg = f.nextElement();
for (int i = 0; i < pkg.errors.size(); i++) {
errorHierachy.add((ClassDoc) pkg.errors.get(i));
errorHierachy.add(pkg.errors.get(i));
}
}
if (errorHierachy.root.size() != 0) {
@@ -997,9 +1058,9 @@ public class TeXDoclet extends Doclet {
* @param classes
* Vector of the classes to be laid out.
*/
static void layoutClasses(String type, Vector classes) {
static void layoutClasses(String type, List<ClassDoc> classes) {
for (int i = 0; i < classes.size(); ++i) {
ClassDoc cd = (ClassDoc) classes.elementAt(i);
ClassDoc cd = classes.get(i);
// os.println(
// "\\gdef\\classname{"+HTMLtoLaTeXBackEnd.fixText(cd.name())+"}" );
@@ -1207,8 +1268,6 @@ public class TeXDoclet extends Doclet {
if (inherited == true) {
boolean yet = false;
if (!cd.isInterface()) {
ClassDoc par = cd.superclass();
@@ -1223,7 +1282,7 @@ public class TeXDoclet extends Doclet {
} else {
List superclasses = new Vector();
List<ClassDoc> superclasses = new Vector<ClassDoc>();
while (getSuperClass(cd, superclasses) != null) {
}
@@ -1231,7 +1290,7 @@ public class TeXDoclet extends Doclet {
for (int m = superclasses.size() - 1; m >= 0; m--) {
ClassDoc par = (ClassDoc) superclasses.get(m);
ClassDoc par = superclasses.get(m);
printInherited(par);
@@ -1251,7 +1310,7 @@ public class TeXDoclet extends Doclet {
* subsclass, that is not already in the list of superclasses adn adds it to
* the list if found
*/
static ClassDoc getSuperClass(ClassDoc subclass, List superclasses) {
static ClassDoc getSuperClass(ClassDoc subclass, List<ClassDoc> superclasses) {
ClassDoc[] cls = theroot.classes();
for (int n = 0; n < cls.length; ++n) {
ClassDoc cd2 = cls[n];
@@ -1265,16 +1324,16 @@ public class TeXDoclet extends Doclet {
return null;
}
static List sortSuperclasses(List superclasses) {
List result = new Vector();
static List<ClassDoc> sortSuperclasses(List<ClassDoc> superclasses) {
List<ClassDoc> result = new Vector<ClassDoc>();
int count = superclasses.size();
for (int k = 0; k < count; k++) {
for (int i = 0; i < superclasses.size(); i++) {
ClassDoc cd = (ClassDoc) superclasses.get(i);
ClassDoc cd = superclasses.get(i);
boolean isSubInterface = false;
for (int j = 0; j < superclasses.size(); j++) {
ClassDoc cd2 = (ClassDoc) superclasses.get(j);
ClassDoc cd2 = superclasses.get(j);
if (cd.subclassOf(cd2) && cd != cd2) {
isSubInterface = true;
break;
@@ -1379,12 +1438,11 @@ public class TeXDoclet extends Doclet {
}
os.println("\\" + sectionLevels[2] + "{" + title + "}{");
os.println("\\begin{verse}");
boolean first = true;
List l = Arrays.asList(dmems);
List<ExecutableMemberDoc> l = Arrays.asList(dmems);
Collections.sort(l);
Iterator itr = l.iterator();
Iterator<ExecutableMemberDoc> itr = l.iterator();
for (int i = 0; itr.hasNext(); ++i) {
ExecutableMemberDoc mem = (ExecutableMemberDoc) itr.next();
ExecutableMemberDoc mem = itr.next();
if (hyperref) {
os.print("\\hyperlink{"
+ refName(makeRefKey(mem.qualifiedName()
@@ -1418,12 +1476,11 @@ public class TeXDoclet extends Doclet {
}
os.println("\\" + sectionLevels[2] + "{" + title + "}{");
os.println("\\begin{verse}");
boolean first = true;
List l = Arrays.asList(dmems);
List<FieldDoc> l = Arrays.asList(dmems);
Collections.sort(l);
Iterator itr = l.iterator();
Iterator<FieldDoc> itr = l.iterator();
for (int i = 0; itr.hasNext(); ++i) {
FieldDoc mem = (FieldDoc) itr.next();
FieldDoc mem = itr.next();
if (hyperref) {
os.print("\\hyperlink{"
+ refName(makeRefKey(mem.qualifiedName())) + "}{");
@@ -1452,13 +1509,13 @@ public class TeXDoclet extends Doclet {
if (useHr) {
os.println("\\rule[1em]{\\hsize}{2pt}\\vskip -2em");
}
List l = Arrays.asList(dmems);
List<ExecutableMemberDoc> l = Arrays.asList(dmems);
Collections.sort(l);
Iterator itr = l.iterator();
Iterator<ExecutableMemberDoc> itr = l.iterator();
os.println("\\vskip -2em");
os.println("\\begin{itemize}");
for (int i = 0; itr.hasNext(); ++i) {
ExecutableMemberDoc mem = (ExecutableMemberDoc) itr.next();
ExecutableMemberDoc mem = itr.next();
if (i > 0) {
if (useHr) {
@@ -1794,14 +1851,14 @@ public class TeXDoclet extends Doclet {
if (useHr) {
os.println("\\rule[1em]{\\hsize}{2pt}\\vskip -2em");
}
List l = Arrays.asList(dmems);
List<MemberDoc> l = Arrays.asList(dmems);
Collections.sort(l);
Iterator itr = l.iterator();
Iterator<MemberDoc> itr = l.iterator();
if (shortInheritance) {
for (int i = 0; itr.hasNext(); ++i) {
MemberDoc mem = (MemberDoc) itr.next();
MemberDoc mem = itr.next();
// print only member names
if (i != 0) {
@@ -1817,7 +1874,7 @@ public class TeXDoclet extends Doclet {
os.println("\\vskip -2em");
os.println("\\begin{itemize}");
for (int i = 0; itr.hasNext(); ++i) {
MemberDoc mem = (MemberDoc) itr.next();
MemberDoc mem = itr.next();
// Print signature