001 package de.java2html.converter;
002
003 import java.io.BufferedWriter;
004 import java.io.IOException;
005 import java.text.MessageFormat;
006
007 import de.java2html.Version;
008 import de.java2html.javasource.TypedSource;
009 import de.java2html.javasource.TypedSourceIterator;
010 import de.java2html.javasource.SourceRun;
011 import de.java2html.javasource.SourceType;
012 import de.java2html.options.HorizontalAlignment;
013 import de.java2html.options.IHorizontalAlignmentVisitor;
014 import de.java2html.options.JavaSourceConversionOptions;
015 import de.java2html.options.JavaSourceStyleEntry;
016 import de.java2html.options.JavaSourceStyleTable;
017 import de.java2html.util.HtmlUtilities;
018 import de.java2html.util.StringHolder;
019
020 /**
021 * Algorithm and stuff for converting a
022 * {@link de.java2html.javasource.TypedSource} object to to a HTML string
023 * representation.
024 *
025 * The result is XHTML1.0 Transitional compliant.
026 *
027 * For questions, suggestions, bug-reports, enhancement-requests etc. I may be
028 * contacted at: <a href="mailto:markus@jave.de">markus@jave.de</a>
029 *
030 * The Java2html home page is located at: <a href="http://www.java2html.de">
031 * http://www.java2html.de</a>
032 *
033 * @author <a href="mailto:markus@jave.de">Markus Gebhard</a>
034 *
035 * Copyright (C) Markus Gebhard 2000-2002
036 *
037 * This program is free software; you can redistribute it and/or modify it
038 * under the terms of the GNU General Public License as published by the Free
039 * Software Foundation; either version 2 of the License, or (at your option)
040 * any later version.
041 *
042 * This program is distributed in the hope that it will be useful, but WITHOUT
043 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
044 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
045 * more details.
046 *
047 * You should have received a copy of the GNU General Public License along with
048 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
049 * Place - Suite 330, Boston, MA 02111-1307, USA.
050 */
051 public class JavaSource2HTMLConverter extends AbstractJavaSourceConverter {
052 /**
053 * Flag indication whether html output contains a link to the
054 * Java2Html-Homepage or not.
055 *
056 * @deprecated As of Jan 2, 2004 (Markus Gebhard) replaced by
057 * {@link de.java2html.options.JavaSourceConversionOptions#setShowJava2HtmlLink(boolean)}
058 */
059 @Deprecated
060 public static boolean java2HtmlHomepageLinkEnabled = false;
061
062 /**
063 * Site header for a html page. Is not used by this class, but can be used
064 * from outside to add it to one or more converted
065 */
066 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"
067 // "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
068 // \"http://www.w3.org/TR/html4/loose.dtd\">\n"
069 + "<html><head>\n"
070 + "<title>{0}</title>\n"
071 + " <style type=\"text/css\">\n"
072 + " <!--code '{' font-family: Courier New, Courier; font-size: 10pt; margin: 0px; '}'-->\n"
073 + " </style>\n"
074 + " <meta http-equiv=\"Content-Type\" content=\"text/html; charset={1}\" />\n"
075 + "</head><body>\n";
076
077 /**
078 * Site footer for a html page. Is not used by this class, but can be used
079 * from outside to add it to one or more converted
080 */
081 private final static String HTML_SITE_FOOTER = "\n</body></html>";
082
083 /** Block seperator for between two blocks of converted source code */
084 private final static String HTML_BLOCK_SEPARATOR = "<p />\n";
085
086 /** HTML-Header for a block (!) of converted code */
087 private final static String HTML_BLOCK_HEADER = "\n\n"
088 + "<!-- ======================================================== -->\n"
089 + "<!-- = Java Sourcecode to HTML automatically converted code = -->\n"
090 + "<!-- = "
091 + Version.getJava2HtmlConverterTitle()
092 + " "
093 + Version.getBuildDate()
094 + " by Markus Gebhard markus@jave.de = -->\n"
095 + "<!-- = Further information: http://www.java2html.de = -->\n"
096 + "<div align=\"{0}\" class=\"java\">\n"
097 + "<table border=\"{1}\" cellpadding=\"3\" "
098 + "cellspacing=\"0\" bgcolor=\"{2}\">\n";
099
100 /** HTML-code for before the headline */
101 private final static String HTML_HEAD_START = " <!-- start headline -->\n"
102 + " <tr>\n"
103 + " <td colspan=\"2\">\n"
104 + " <center><font size=\"+2\">\n"
105 + " <code><b>\n";
106
107 /** HTML-code for after the headline */
108 private final static String HTML_HEAD_END = " </b></code>\n"
109 + " </font></center>\n"
110 + " </td>\n"
111 + " </tr>\n"
112 + " <!-- end headline -->\n";
113
114 /**
115 * HTML-code for before the second column (contaning the converted source
116 * code)
117 */
118 private final static String HTML_COL2_START = " <!-- start source code -->\n"
119 + " <td nowrap=\"nowrap\" valign=\"top\" align=\"left\">\n"
120 + " <code>\n";
121
122 /**
123 * HTML-code for after the second column (contaning the converted source
124 * code)
125 */
126 private final static String HTML_COL2_END = "</code>\n"
127 + " \n"
128 + " </td>\n"
129 + " <!-- end source code -->\n";
130
131 /**
132 * HTML-code for the bottom line (containing a little link to the
133 * java2html-homepage). Can be disabled by setting
134 * {@link #java2HtmlHomepageLinkEnabled}
135 */
136 private final static String HTML_LINK = " <!-- start Java2Html link -->\n"
137 + " <tr>\n"
138 + " <td align=\"right\">\n"
139 + "<small>\n"
140 + "<a href=\"http://www.java2html.de\" target=\"_blank\">Java2html</a>\n"
141 + "</small>\n"
142 + " </td>\n"
143 + " </tr>\n"
144 + " <!-- end Java2Html link -->\n";
145
146 /** HTML-code for after the end of the block */
147 private final static String HTML_BLOCK_FOOTER =
148 //"\n"+ sieht schoener aus, wenn kein Zeilenumbruch mehr!
149 "</table>\n"
150 + "</div>\n"
151 + "<!-- = END of automatically generated HTML code = -->\n"
152 + "<!-- ======================================================== -->\n\n";
153
154 /**
155 * The html representation of the colors used for different source
156 */
157
158 private int lineCifferCount;
159
160 public JavaSource2HTMLConverter() {
161 super(new ConverterMetaData("html", "XHTML 1.0 Transitional (inlined fonts)", "html"));
162 }
163
164 @Override
165 public String getDocumentHeader(JavaSourceConversionOptions options, String title) {
166 if (title == null) {
167 title = ""; //$NON-NLS-1$
168 }
169
170 return MessageFormat.format(HTML_SITE_HEADER, new Object[]{ title, options.getCharset() });
171 }
172
173 @Override
174 public String getDocumentFooter(JavaSourceConversionOptions options) {
175 return HTML_SITE_FOOTER;
176 }
177
178 @Override
179 public String getBlockSeparator(JavaSourceConversionOptions options) {
180 return HTML_BLOCK_SEPARATOR;
181 }
182
183 @Override
184 public void convert(TypedSource source, JavaSourceConversionOptions options, BufferedWriter writer)
185 throws IOException {
186 if (source == null) {
187 throw new IllegalStateException("Trying to write out converted code without having source set.");
188 }
189
190 //Header
191 final String alignValue = getHtmlAlignValue(options.getHorizontalAlignment());
192 final String bgcolorValue = options.getStyleTable().get(SourceType.BACKGROUND).getHtmlColor();
193 final String borderValue = options.isShowTableBorder() ? "2" : "0";
194
195 writer.write(MessageFormat.format(HTML_BLOCK_HEADER, new Object[]{ alignValue, borderValue, bgcolorValue }));
196
197 if (options.isShowFileName() && source.getFileName() != null) {
198 writeFileName(source, writer);
199 }
200
201 writer.write(" <tr>");
202 writer.write("\n");
203
204 writeSourceCode(source, options, writer);
205
206 writer.write(" </tr>");
207 writer.write("\n");
208
209 //5) Footer with link to web site
210 if (options.isShowJava2HtmlLink() || java2HtmlHomepageLinkEnabled) {
211 writer.write(HTML_LINK);
212 }
213 writer.write(HTML_BLOCK_FOOTER);
214 }
215
216 private String getHtmlAlignValue(HorizontalAlignment alignment) {
217 final StringHolder stringHolder = new StringHolder();
218 alignment.accept(new IHorizontalAlignmentVisitor() {
219 public void visitLeftAlignment(HorizontalAlignment horizontalAlignment) {
220 stringHolder.setValue("left");
221 }
222
223 public void visitRightAlignment(HorizontalAlignment horizontalAlignment) {
224 stringHolder.setValue("right");
225 }
226
227 public void visitCenterAlignment(HorizontalAlignment horizontalAlignment) {
228 stringHolder.setValue("center");
229 }
230 });
231 return stringHolder.getValue();
232 }
233
234 private void writeFileName(TypedSource source, BufferedWriter writer) throws IOException {
235 writer.write(HTML_HEAD_START);
236 writer.write(source.getFileName());
237 writer.write("\n");
238 writer.write(HTML_HEAD_END);
239 }
240
241 private void writeSourceCode(TypedSource source, JavaSourceConversionOptions options, BufferedWriter writer)
242 throws IOException {
243 writer.write(HTML_COL2_START);
244
245 lineCifferCount = String.valueOf(source.getLineCount()).length();
246
247 final TypedSourceIterator iterator = source.getIterator();
248 int lineNumber = 1;
249 while (iterator.hasNext()) {
250 final SourceRun run = iterator.getNext();
251
252 if (run.isAtStartOfLine()) {
253 if (options.isAddLineAnchors()) {
254 writeLineAnchorStart(options, writer, lineNumber);
255 }
256 if (options.isShowLineNumbers()) {
257 writeLineNumber(options, writer, lineNumber);
258 }
259 if (options.isAddLineAnchors()) {
260 writeLineAnchorEnd(writer);
261 }
262 lineNumber++;
263 }
264
265 toHTML(options.getStyleTable(), run, writer);
266 if (run.isAtEndOfLine() && iterator.hasNext()) {
267 writer.write("<br />");
268 writer.write("\n");
269 }
270 }
271 writer.write(HTML_COL2_END);
272 }
273
274 private void writeLineAnchorEnd(BufferedWriter writer) throws IOException {
275 writer.write("</a>");
276 }
277
278 private void writeLineAnchorStart(JavaSourceConversionOptions options, BufferedWriter writer, int lineNumber)
279 throws IOException {
280 writer.write("<a name=\"");
281 writer.write(options.getLineAnchorPrefix() + lineNumber);
282 writer.write("\">");
283 }
284
285 private void writeLineNumber(JavaSourceConversionOptions options, BufferedWriter writer, int lineNo)
286 throws IOException {
287 final JavaSourceStyleEntry styleEntry = options.getStyleTable().get(SourceType.LINE_NUMBERS);
288 writeStyleStart(writer, styleEntry);
289
290 final String lineNumber = String.valueOf(lineNo);
291 int cifferCount = lineCifferCount - lineNumber.length();
292 while (cifferCount > 0) {
293 writer.write('0');
294 --cifferCount;
295 }
296
297 writer.write(lineNumber);
298 writeStyleEnd(writer, styleEntry);
299 writer.write(" ");
300 }
301
302 private void toHTML(JavaSourceStyleTable styleTable, SourceRun run, BufferedWriter writer)
303 throws IOException {
304 // result.append(htmlColors[sourceTypes[start]]);
305 final JavaSourceStyleEntry style = styleTable.get(run.getType());
306
307 writeStyleStart(writer, style);
308
309 final String t = HtmlUtilities.encode(run.getCode(), "\n ");
310
311 for (int i = 0; i < t.length(); ++i) {
312 final char ch = t.charAt(i);
313 if (ch == ' ') {
314 writer.write(" ");
315 }
316 else {
317 writer.write(ch);
318 }
319 }
320
321 writeStyleEnd(writer, style);
322 }
323
324 private void writeStyleStart(BufferedWriter writer, JavaSourceStyleEntry style) throws IOException {
325 writer.write("<font color=\"" + style.getHtmlColor() + "\">");
326 if (style.isBold()) {
327 writer.write("<b>");
328 }
329 if (style.isItalic()) {
330 writer.write("<i>");
331 }
332 }
333
334 private void writeStyleEnd(BufferedWriter writer, JavaSourceStyleEntry style) throws IOException {
335 if (style.isItalic()) {
336 writer.write("</i>");
337 }
338 if (style.isBold()) {
339 writer.write("</b>");
340 }
341 writer.write("</font>");
342 }
343 }
|