public void highlight(String name,
InputStream in,
OutputStream out,
String encoding,
boolean fragment) throws IOException {
ExplicitStateHighlighter highlighter = getHighlighter();
Reader isr;
Writer osw;
if (null == encoding)
{
isr = new InputStreamReader(in);
osw = new OutputStreamWriter(out);
}
else
{
isr = new InputStreamReader(in, encoding);
osw = new OutputStreamWriter(out, encoding);
}
BufferedReader r = new BufferedReader(isr);
BufferedWriter w = new BufferedWriter(osw);
if (fragment)
{
// w.write(getXhtmlHeaderFragment(name));
}
else
{
w.write(getXhtmlHeader(name));
}
String line;
String token;
int length;
int style;
String css_class;
int previous_style = 0;
boolean newline = false;
StringBuffer buf = new StringBuffer();
int c = 0;
while ((c = r.read()) != -1) {
buf.append((char) c);
}
String allLines = buf.toString();
String[] lines = allLines.split("\n");
// for (int jj=0; jj < lines.length; jj++) {
// System.out.println("Line: " + lines[jj]);
// }
// We get a new instance of this class each time we parse a programlisting so we can
// can use an instance variable to detect if it's the first time we've been called.
// This will allow us to put < br/ > before each line so that the callout extension will work correctly.
for (int i=0; i < lines.length; i ++) {
line = lines[i];
lineNo++;
line = StringUtils.convertTabsToSpaces(line, 4);
// should be optimized by reusing a custom LineReader class
Reader lineReader = new StringReader(line);
highlighter.setReader(lineReader);
int index = 0;
while (index < line.length())
{
style = highlighter.getNextToken();
length = highlighter.getTokenLength();
token = line.substring(index, index + length);
if (style != previous_style || newline) // assume we have a new style if there is a newline
{
css_class = getCssClass(style);
if (css_class != null)
{
if (previous_style != 0 && !newline) // each token will potentially have a different style
{
w.write("< /span >");
}
// Write the start tag for the < span > element representing the style
if (lineNo == 1) {
w.write("< !-- < br/ > -- >< span class=\"" + css_class + "\" >"); // the 1st line doesn't have a linebreak
} else if (!newline) {
w.write("< span class=\"" + css_class + "\" >"); // we're in the middle of a line
}
else if (newline && lineNo != 1) {
w.write("< !-- -- >< br/ >< span class=\"" + css_class + "\" >"); // we're at the start of a new line
}
previous_style = style;
}
}
newline = false; // if we've just started processing a new line we need to know
w.write(StringUtils.replace(StringUtils.encodeHtml(StringUtils.replace(token, "\n", "")), " ", " "));
index += length;
}
// Write a newline character if we're not on the last line or we are and there was a newline at the end anyway
if ((i != lines.length -1) || (i == lines.length - 1 && allLines.endsWith("\n"))) {
w.write("< /span >\n");
} else {
w.write("< /span >");
}
newline = true;
}
if (!fragment) w.write(getXhtmlFooter());
w.flush();
w.close();
}
Transforms source code that's provided through an
InputStream to highlighted syntax in XHTML and writes it
back to an OutputStream.
If the highlighting has to become a fragment, no CSS styles will be
generated.
For complete documents, there's a collection of default styles that
will be included. It's possible to override these by changing the
provided jhighlight.properties file. It's best to look at
this file in the JHighlight archive and modify the styles that are
there already. |