package org.oddjob.tools.includes;
//java2html.java
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
/**
* I found this little gem at
* http://www.geocities.com/SiliconValley/Horizon/6481/Java2HTML.html
* and modified it slightly to add unique colours for strings
* and the two different comment types both of which are also italicized.
* All default colours are websafe and can be customized by
* specifying an optimal colours property file.
*
* @author Melinda Green - Superliminal Software
*/
public class Java2HTML
{
private static final String keywords[] =
{
"abstract", "default", "if", "private", "throw",
"boolean", "do", "implements", "protected", "throws",
"break", "double", "import", "public", "transient",
"byte", "else", "instanceof", "return", "try",
"case", "extends", "int", "short", "void",
"catch", "final", "interface", "static", "volatile",
"char", "finally", "long", "super", "while",
"class", "float", "native", "switch",
"const", "for", "new", "synchronized",
"continue", "goto", "package", "this"
};
private static List<String> keyw = new ArrayList<String>(keywords.length);
static
{
for (int i = 0; i < keywords.length; i++)
keyw.add(keywords[i]);
}
private int tabsize = 4;
private String
kwcolor = "0000FF", // blue
cmcolor = "009900", // dark faded green
c2color = "999999", // light gray
stcolor = "FF0000"; // red
public String convert(String input) throws IOException
{
Reader in = new StringReader(input);
StringWriter string = new StringWriter();
PrintWriter out = new PrintWriter(string);
out.println("<pre class=\"code\">");
StringBuffer buf = new StringBuffer(2048);
int c = 0, kwl = 0, bufl = 0;
int nexttolast = 0; // just for handling case of >> "\\" << which is not escaping a double quote
char ch = 0, lastch = 0;
int s_normal = 0;
int s_string = 1;
int s_char = 2;
int s_comline = 3;
int s_comment = 4;
int state = s_normal;
while (c != -1)
{
c = in.read();
nexttolast = lastch;
lastch = ch;
ch = c >= 0 ? (char) c : 0;
if (state == s_normal)
if (kwl == 0 && Character.isJavaIdentifierStart(ch)
&& !Character.isJavaIdentifierPart(lastch)
|| kwl > 0 && Character.isJavaIdentifierPart(ch))
{
buf.append(ch);
bufl++;
kwl++;
continue;
} else
if (kwl > 0)
{
String kw = buf.toString().substring(buf.length() - kwl);
if (keyw.contains(kw))
{
buf.insert(buf.length() - kwl,
"<font color=\"" + kwcolor + "\">");
buf.append("</font>");
}
kwl = 0;
}
switch (ch)
{
case '&':
buf.append("&");
bufl++;
break;
case '\"': // double quote
buf.append(""");
bufl++;
if (state == s_normal) { // start string
state = s_string;
buf.insert(buf.length() - """.length(),
"<font color=\"" + stcolor + "\"><i>");
}
else
if (state == s_string && ((lastch != '\\') || (lastch == '\\' && nexttolast == '\\'))) {
// inside a string and found either a non-escaped closing double quote,
// so close the string.
buf.append("</i></font>");
state = s_normal;
}
break;
case '\'': // single quote
buf.append("\'");
bufl++;
if (state == s_normal)
state = s_char;
else
if (state == s_char && lastch != '\\')
state = s_normal;
break;
case '\\': // backslash
buf.append("\\");
bufl++;
if(lastch == '\\')
nexttolast = '\\';
if (lastch == '\\' && (state == s_string || state == s_char))
;//lastch = 0;
break;
case '/': // forward slash
buf.append("/");
bufl++;
if(state == s_string || state == s_comline)
break;
if (state == s_comment && lastch == '*') // star slash ends c++ comment
{
buf.append("</i></font>");
state = s_normal;
}
if(state == s_comment)
break;
if (lastch == '/') // second forward slash starts line comment
{
buf.insert(buf.length() - 2,
"<font color=\"" + cmcolor + "\"><i>");
state = s_comline;
}
break;
case '*':
buf.append("*");
bufl++;
if (state == s_normal && lastch == '/') // slash star starts c++ comment
{
buf.insert(buf.length() - 2,
"<font color=\"" + c2color + "\"><i>");
state = s_comment;
}
break;
case '<':
buf.append("<");
bufl++;
break;
case '>':
buf.append(">");
bufl++;
break;
case '\t':
int n = bufl / tabsize * tabsize + tabsize;
while (bufl < n)
{
buf.append(' ');
bufl++;
}
break;
case '\r':
case '\n':
if (state == s_comline) // EOL ends line comment
{
buf.append("</i></font>");
state = s_normal;
}
buf.append(ch);
if (buf.length() >= 1024)
{
out.write(buf.toString());
buf.setLength(0);
}
bufl = 0;
if (kwl != 0)
kwl = 0; // This should never execute
if (state != s_normal && state != s_comment)
state = s_normal; // Syntax Error
break;
case 0:
if (c < 0)
{
if (state == s_comline)
{
buf.append("</font>");
state = s_normal;
}
out.write(buf.toString());
buf.setLength(0);
bufl = 0;
if (state == s_comment)
{
// Syntax Error
buf.append("</font>");
state = s_normal;
}
break;
}
default:
bufl++;
buf.append(ch);
}
}
out.println("</pre>");
in.close();
out.close();
return string.toString();
}
public int getTabsize() {
return tabsize;
}
public void setTabsize(int tabsize) {
this.tabsize = tabsize;
}
public String getKwcolor() {
return kwcolor;
}
public void setKwcolor(String kwcolor) {
this.kwcolor = kwcolor;
}
public String getCmcolor() {
return cmcolor;
}
public void setCmcolor(String cmcolor) {
this.cmcolor = cmcolor;
}
public String getC2color() {
return c2color;
}
public void setC2color(String c2color) {
this.c2color = c2color;
}
public String getStcolor() {
return stcolor;
}
public void setStcolor(String stcolor) {
this.stcolor = stcolor;
}
}