1 package net.sf.tomp.highlight.html;
2
3 import java.io.BufferedWriter;
4 import java.io.IOException;
5 import java.text.MessageFormat;
6
7 import de.java2html.Version;
8 import de.java2html.converter.JavaSourceConverter;
9 import de.java2html.javasource.JavaSource;
10 import de.java2html.javasource.JavaSourceIterator;
11 import de.java2html.javasource.JavaSourceRun;
12 import de.java2html.javasource.JavaSourceType;
13 import de.java2html.options.HorizontalAlignment;
14 import de.java2html.options.IHorizontalAlignmentVisitor;
15 import de.java2html.options.JavaSourceStyleEntry;
16 import de.java2html.util.HTMLTools;
17 import de.java2html.util.StringHolder;
18
19 /***
20 * This class is heavily based on work of Markus Gebhard, see the copyright
21 * notice below. It was taken and changed by Tomas Pitner, tomp@fi.muni.cz, July
22 * 28, 2004. The purpose is to produce a syntax-highlighted version of a Java
23 * source code.
24 *
25 * <br/>Algorithm and stuff for converting a
26 * {@link de.java2html.javasource.JavaSource}object to to a HTML string
27 * representation. The result is XHTML1.0 Transitional compliant. For questions,
28 * suggestions, bug-reports, enhancement-requests etc. I may be contacted at: <a
29 * href="mailto:markus@jave.de">markus@jave.de </a> The Java2html home page is
30 * located at: <a href="http://www.java2html.de"> http://www.java2html.de </a>
31 *
32 * @author <a href="mailto:markus@jave.de">Markus Gebhard </a> Copyright (C)
33 * Markus Gebhard 2000-2002 This program is free software; you can
34 * redistribute it and/or modify it under the terms of the GNU General
35 * Public License as published by the Free Software Foundation; either
36 * version 2 of the License, or (at your option) any later version. This
37 * program is distributed in the hope that it will be useful, but
38 * WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40 * General Public License for more details. You should have received a
41 * copy of the GNU General Public License along with this program; if
42 * not, write to the Free Software Foundation, Inc., 59 Temple Place -
43 * Suite 330, Boston, MA 02111-1307, USA.
44 */
45 public class JavaSource2HTMLConverter extends JavaSourceConverter {
46
47 /*** HTML-code for after the end of the block */
48 private final static String HTML_BLOCK_FOOTER =
49
50 "</table>\n"
51 + "</div>\n"
52 + "<!-- = END of automatically generated HTML code = -->\n"
53 + "<!-- ======================================================== -->\n\n";
54
55 /*** HTML-Header for a block (!) of converted code */
56 private final static String HTML_BLOCK_HEADER = "\n\n"
57 + "<!-- ======================================================== -->\n"
58 + "<!-- = Java Sourcecode to HTML automatically converted code = -->\n"
59 + "<!-- = "
60 + Version.J2H_TITLE
61 + " "
62 + Version.YEAR
63 + " by Markus Gebhard markus@jave.de = -->\n"
64 + "<!-- = Further information: http://www.java2html.de = -->\n"
65 + "<div align=\"{0}\" class=\"java\">\n"
66 + "<table border=\"{1}\" cellpadding=\"3\" "
67 + "cellspacing=\"0\" bgcolor=\"{2}\">\n";
68
69 /*** Block seperator for between two blocks of converted source code */
70 private final static String HTML_BLOCK_SEPARATOR = "<p/>\n";
71
72 /***
73 * HTML-code for after the second column (contaning the converted source
74 * code)
75 */
76 private final static String HTML_COL2_END = "</code>\n" + " \n"
77 + " </td>\n" + " <!-- end source code -->\n";
78
79 /***
80 * HTML-code for before the second column (contaning the converted source
81 * code)
82 */
83 private final static String HTML_COL2_START = " <!-- start source code -->\n"
84 + " <td nowrap=\"nowrap\" valign=\"top\" align=\"left\">\n"
85 + " <code>\n";
86
87 /*** HTML-code for after the headline */
88 private final static String HTML_HEAD_END = " </b></code>\n"
89 + " </font></center>\n" + " </td>\n" + " </tr>\n"
90 + " <!-- end headline -->\n";
91
92 /*** HTML-code for before the headline */
93 private final static String HTML_HEAD_START = " <!-- start headline -->\n"
94 + " <tr>\n" + " <td colspan=\"2\">\n"
95 + " <center><font size=\"+2\">\n" + " <code><b>\n";
96
97 /***
98 * HTML-code for the bottom line (containing a little link to the
99 * java2html-homepage). Can be disabled by setting
100 * {@link #java2HtmlHomepageLinkEnabled}
101 */
102 private final static String HTML_LINK = " <!-- start Java2Html link -->\n"
103 + " <tr>\n"
104 + " <td align=\"right\">\n"
105 + "<small>\n"
106 + "<a href=\"http://www.java2html.de\" target=\"_blank\">Java2html</a>\n"
107 + "</small>\n" + " </td>\n" + " </tr>\n"
108 + " <!-- end Java2Html link -->\n";
109
110 /***
111 * Site footer for a html page. Is not used by this class, but can be used
112 * from outside to add it to one or more converted
113 */
114 private final static String HTML_SITE_FOOTER = "\n</body></html>";
115
116 /***
117 * Site header for a html page. Is not used by this class, but can be used
118 * from outside to add it to one or more converted
119 */
120 private final static String HTML_SITE_HEADER = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
121
122
123 + "<html><head>\n"
124 + "<title></title>\n"
125 + " <style type=\"text/css\">\n"
126 + " <!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->\n"
127 + " </style>\n"
128 + " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"/>\n"
129 + "</head><body>\n";
130
131 /***
132 * Flag indication whether html output contains a link to the
133 * Java2Html-Homepage or not.
134 *
135 * @deprecated As of Jan 2, 2004 (Markus Gebhard) replaced by
136 * {@link de.java2html.options.Java2HtmlConversionOptions#setShowJava2HtmlLink(boolean)}
137 */
138 public static boolean java2HtmlHomepageLinkEnabled = false;
139
140 /***
141 * The html representation of the colors used for different source
142 */
143
144 private int lineCifferCount;
145
146 public JavaSource2HTMLConverter() {
147 super();
148 }
149
150 public JavaSource2HTMLConverter(JavaSource source) {
151 super(source);
152 }
153
154 public void convert(BufferedWriter writer) throws IOException {
155 if (source == null) {
156 throw new IllegalStateException(
157 "Trying to write out converted code without having source set.");
158 }
159
160
161 String alignValue = getHtmlAlignValue(getConversionOptions()
162 .getHorizontalAlignment());
163 String bgcolorValue = getConversionOptions().getStyleTable().get(
164 JavaSourceType.BACKGROUND.getName()).getHtmlColor();
165 String borderValue = getConversionOptions().isShowTableBorder() ? "2"
166 : "0";
167
168 writer.write(MessageFormat.format(HTML_BLOCK_HEADER, new Object[] {
169 alignValue, borderValue, bgcolorValue }));
170
171 if (getConversionOptions().isShowFileName()
172 && source.getFileName() != null) {
173 writeFileName(writer);
174 }
175
176 writer.write(" <tr>");
177 writer.newLine();
178
179 writeSourceCode(writer);
180
181 writer.write(" </tr>");
182 writer.newLine();
183
184
185 if (getConversionOptions().isShowJava2HtmlLink()
186 || java2HtmlHomepageLinkEnabled) {
187 writer.write(HTML_LINK);
188 }
189 writer.write(HTML_BLOCK_FOOTER);
190 }
191
192 public String getBlockSeparator() {
193 return HTML_BLOCK_SEPARATOR;
194 }
195
196 public String getDefaultFileExtension() {
197 return "html";
198 }
199
200 public String getDocumentFooter() {
201 return HTML_SITE_FOOTER;
202 }
203
204 public String getDocumentHeader() {
205 return HTML_SITE_HEADER;
206 }
207
208 private String getHtmlAlignValue(HorizontalAlignment alignment) {
209 final StringHolder stringHolder = new StringHolder();
210 alignment.accept(new IHorizontalAlignmentVisitor() {
211
212 public void visitCenterAlignment(
213 HorizontalAlignment horizontalAlignment) {
214 stringHolder.setValue("center");
215 }
216
217 public void visitLeftAlignment(
218 HorizontalAlignment horizontalAlignment) {
219 stringHolder.setValue("left");
220 }
221
222 public void visitRightAlignment(
223 HorizontalAlignment horizontalAlignment) {
224 stringHolder.setValue("right");
225 }
226 });
227 return stringHolder.getValue();
228 }
229
230 protected void toHTML(JavaSourceRun run, BufferedWriter writer)
231 throws IOException {
232
233 JavaSourceStyleEntry style = getColorTable().get(
234 run.getType().getName());
235
236 writeStyleStart(writer, style);
237
238 String t = HTMLTools.encode(run.getCode(), "\n ");
239
240 for (int i = 0; i < t.length(); ++i) {
241 char ch = t.charAt(i);
242 if (ch == ' ')
243 writer.write(" ");
244 else
245 writer.write(ch);
246 }
247
248 writeStyleEnd(writer, style);
249 }
250
251 private void writeFileName(BufferedWriter writer) throws IOException {
252 writer.write(HTML_HEAD_START);
253 writer.write(source.getFileName());
254 writer.newLine();
255 writer.write(HTML_HEAD_END);
256 }
257
258 private void writeLineAnchorEnd(BufferedWriter writer) throws IOException {
259 writer.write("</a>");
260 }
261
262 private void writeLineAnchorStart(BufferedWriter writer, int lineNumber)
263 throws IOException {
264 writer.write("<a name=\"");
265 writer.write(getConversionOptions().getLineAnchorPrefix() + lineNumber);
266 writer.write("\">");
267 }
268
269 private void writeLineNumber(BufferedWriter writer, int lineNo)
270 throws IOException {
271 JavaSourceStyleEntry styleEntry = getConversionOptions()
272 .getStyleTable().get(JavaSourceType.LINE_NUMBERS);
273 writeStyleStart(writer, styleEntry);
274
275 String lineNumber = String.valueOf(lineNo);
276 int cifferCount = lineCifferCount - lineNumber.length();
277 while (cifferCount > 0) {
278 writer.write('0');
279 --cifferCount;
280 }
281
282 writer.write(lineNumber);
283 writeStyleEnd(writer, styleEntry);
284 writer.write(" ");
285 }
286
287 private void writeSourceCode(BufferedWriter writer) throws IOException {
288 writer.write(HTML_COL2_START);
289
290 lineCifferCount = String.valueOf(source.getLineCount()).length();
291
292 JavaSourceIterator iterator = source.getIterator();
293 int lineNumber = 1;
294 while (iterator.hasNext()) {
295 JavaSourceRun run = iterator.getNext();
296
297 if (run.isAtStartOfLine()) {
298 if (getConversionOptions().isAddLineAnchors()) {
299 writeLineAnchorStart(writer, lineNumber);
300 }
301 if (getConversionOptions().isShowLineNumbers()) {
302 writeLineNumber(writer, lineNumber);
303 }
304 if (getConversionOptions().isAddLineAnchors()) {
305 writeLineAnchorEnd(writer);
306 }
307 lineNumber++;
308 }
309
310 toHTML(run, writer);
311 if (run.isAtEndOfLine() && iterator.hasNext()) {
312 writer.write("<br/>");
313 writer.newLine();
314 }
315 }
316 writer.write(HTML_COL2_END);
317 }
318
319 private void writeStyleEnd(BufferedWriter writer, JavaSourceStyleEntry style)
320 throws IOException {
321 if (style.isItalic()) {
322 writer.write("</i>");
323 }
324 if (style.isBold()) {
325 writer.write("</b>");
326 }
327 writer.write("</font>");
328 }
329
330 private void writeStyleStart(BufferedWriter writer,
331 JavaSourceStyleEntry style) throws IOException {
332 writer.write("<font color=\"" + style.getHtmlColor() + "\">");
333 if (style.isBold()) {
334 writer.write("<b>");
335 }
336 if (style.isItalic()) {
337 writer.write("<i>");
338 }
339 }
340 }