View Javadoc

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      //"\n"+ sieht schoener aus, wenn kein Zeilenumbruch mehr!
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             //     "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
122             // \"http://www.w3.org/TR/html4/loose.dtd\">\n"
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         //Header
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         //5) Footer with link to web site
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         //  result.append(htmlColors[sourceTypes[start]]);
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("&#160;");
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("&#160;");
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 }