001: package de.java2html.converter;
002:
003: import java.io.BufferedWriter;
004: import java.io.IOException;
005: import java.io.StringWriter;
006:
007: import de.java2html.Version;
008: import de.java2html.javasource.JavaSource;
009: import de.java2html.javasource.JavaSourceIterator;
010: import de.java2html.javasource.JavaSourceParser;
011: import de.java2html.javasource.JavaSourceRun;
012: import de.java2html.javasource.JavaSourceType;
013: import de.java2html.options.JavaSourceConversionOptions;
014: import de.java2html.options.JavaSourceStyleTable;
015: import de.java2html.util.RGB;
016:
017: /**
018: * Algorithm and stuff for converting a
019: * {@link de.java2html.javasource.JavaSource} object to to a TeX string
020: * representation (experimental!).
021: *
022: * For questions, suggestions, bug-reports, enhancement-requests etc. I may be
023: * contacted at: <a href="mailto:markus@jave.de">markus@jave.de</a>
024: *
025: * The Java2html home page is located at: <a href="http://www.java2html.de">
026: * http://www.java2html.de</a>
027: *
028: * @author <a href="mailto:markus@jave.de">Markus Gebhard</a>
029: * @version 2.0, 05/07/02
030: *
031: * Copyright (C) Markus Gebhard 2000-2002
032: *
033: * This program is free software; you can redistribute it and/or modify it
034: * under the terms of the GNU General Public License as published by the Free
035: * Software Foundation; either version 2 of the License, or (at your option)
036: * any later version.
037: *
038: * This program is distributed in the hope that it will be useful, but WITHOUT
039: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
040: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
041: * more details.
042: *
043: * You should have received a copy of the GNU General Public License along with
044: * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
045: * Place - Suite 330, Boston, MA 02111-1307, USA.
046: */
047: public class JavaSource2TeXConverter extends
048: AbstractJavaSourceConverter {
049: private static String[] texFormats;
050: static {
051: JavaSourceType[] allTypes = JavaSourceType.getAll();
052: texFormats = new String[allTypes.length];
053: for (int i = 0; i < allTypes.length; ++i) {
054: texFormats[i] = "\\jttstyle" + (char) ('a' + i) + " ";
055: }
056: }
057:
058: private String createFormatDefinition(
059: JavaSourceStyleTable styleTable) {
060: StringBuffer sb = new StringBuffer();
061: sb.append("%Java2TeX style definitions\n");
062: sb.append("%You can modify them to fit your needs\n");
063:
064: JavaSourceType[] allTypes = JavaSourceType.getAll();
065: for (int i = 0; i < allTypes.length; ++i) {
066: sb.append("\\newcommand{\\jttstyle");
067: sb.append((char) ('a' + i));
068: sb.append("}{\\color[rgb]{");
069:
070: RGB color = styleTable.get(allTypes[i]).getColor();
071: float[] cs = new float[] { color.getRed() / 255.0f,
072: color.getGreen() / 255.0f,
073: color.getBlue() / 255.0f, };
074: sb.append(floatToCharArray(cs[0]));
075: sb.append(',');
076: sb.append(floatToCharArray(cs[1]));
077: sb.append(',');
078: sb.append(floatToCharArray(cs[2]));
079:
080: sb.append("}} %");
081: sb.append(allTypes[i].getName());
082: sb.append('\n');
083:
084: }
085: sb.append('\n');
086: return sb.toString();
087: }
088:
089: /** Document header */
090: protected final static String DOCUMENT_HEADER = "\\documentclass[11pt,a4paper]{article}\n"
091: + "\n"
092: + "\\usepackage{color}\n"
093: + "\n"
094: + "\\begin{document}\n" + "\n";
095:
096: /** Document header */
097: protected final static String DOCUMENT_FOOTER = "\\end{document}";
098:
099: /** Block seperator for between two blocks of converted source code */
100: protected final static String DOCUMENT_BLOCK_SEPARATOR = "\n\n";
101:
102: protected final static String BLOCK_HEADER = "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
103: + "% Java Sourcecode to TeX automatically converted code\n"
104: + "% "
105: + Version.getJava2HtmlConverterTitle()
106: + " "
107: + Version.getBuildDate()
108: + "by Markus Gebhard markus@jave.de\n"
109: + "% Further information: http://www.java2html.de\n";
110:
111: public JavaSource2TeXConverter() {
112: super (new ConverterMetaData("tex", "TeX", "tex"));
113: }
114:
115: protected final static char[] floatToCharArray(float f) {
116: if (f >= 1.0) {
117: return new char[] { '1', '.', '0', '0' };
118: }
119:
120: return new char[] { '.', (char) ('0' + f * 10),
121: (char) ('0' + f * 100 % 10),
122: (char) ('0' + f * 1000 % 10) };
123: }
124:
125: public String getDocumentHeader(
126: JavaSourceConversionOptions options, String title) {
127: return DOCUMENT_HEADER
128: + createFormatDefinition(options.getStyleTable());
129: }
130:
131: public String getDocumentFooter(JavaSourceConversionOptions options) {
132: return DOCUMENT_FOOTER;
133: }
134:
135: public String getBlockSeparator(JavaSourceConversionOptions options) {
136: return DOCUMENT_BLOCK_SEPARATOR;
137: }
138:
139: /**
140: * Converts the parsed source code to HTML by adding color information,
141: * adding line breaks and replacing characters as needed for HTML. Also adds
142: * a table with line numbers etc.
143: */
144: public void convert(JavaSource source,
145: JavaSourceConversionOptions options, BufferedWriter writer)
146: throws IOException {
147: if (source == null) {
148: throw new IllegalStateException(
149: "Trying to write out converted code without having source set.");
150: }
151:
152: writer.write(BLOCK_HEADER);
153:
154: //1) Header with filename if available
155: if (options.isShowFileName() && source.getFileName() != null) {
156: //TODO: Pretty print file name
157: }
158:
159: writer.write("{");
160: writer.newLine();
161: writer.write("\\noindent \\ttfamily");
162: writer.newLine();
163:
164: int lineCount = source.getLineCount();
165: int lineNumber = 1;
166: JavaSourceIterator iterator = source.getIterator();
167: while (iterator.hasNext()) {
168: JavaSourceRun run = iterator.getNext();
169: if (run.isAtStartOfLine() && options.isShowLineNumbers()) {
170: writeLineNumber(writer, lineNumber++, lineCount);
171: }
172: toTeX(run, writer);
173: if (run.isAtEndOfLine()) {
174: writer.write("\\\\");
175: writer.newLine();
176: }
177: }
178:
179: writer.newLine();
180: writer.write("}");
181: writer.newLine();
182: }
183:
184: public void writeLineNumber(BufferedWriter writer, int lineNumber,
185: int lineCount) throws IOException {
186: writer.write(texFormats[JavaSourceType.LINE_NUMBERS.getID()]);
187: writer.write(leftSpace(lineNumber, lineCount));
188: writer.write(String.valueOf(lineNumber));
189: writer.write('~');
190: }
191:
192: protected void toTeX(JavaSourceRun run, BufferedWriter writer)
193: throws IOException {
194: writer.write(texFormats[run.getType().getID()]);
195:
196: //Replace white space by non-breaking space and line breaks by \\
197: //Also enclose special characters in \\verb# #
198: String text = run.getCode();
199: for (int i = 0; i < text.length(); ++i) {
200: char ch = text.charAt(i);
201: if (ch == ' ')
202: writer.write('~');
203: else if (ch == '_' || ch == '\\' || ch == '^' || ch == '~'
204: || ch == '\"' || ch == '|' || ch == '<'
205: || ch == '>' || ch == '*')
206: writer.write("\\verb#" + ch + "#");
207: else if (ch == '{' || ch == '}' || ch == '_' || ch == '&'
208: || ch == '%' || ch == '$' || ch == '#') {
209: writer.write("\\" + ch);
210: } else {
211: writer.write(ch);
212: }
213: }
214: }
215:
216: protected final static String[] WHITESPACES = { "", "~", "~~",
217: "~~~", "~~~~", };
218:
219: protected final static String whiteSpace(int size) {
220: if (size < WHITESPACES.length)
221: return WHITESPACES[size];
222:
223: char[] result = new char[size];
224: while (size > 0)
225: result[--size] = '~';
226:
227: return new String(result);
228: }
229:
230: protected final static String leftSpace(int num, int max) {
231: int count = (int) (Math.log(max) / Math.log(10))
232: - (int) (Math.log(num) / Math.log(10));
233:
234: return whiteSpace(count);
235: }
236:
237: //TODO Sep 13, 2004 (Markus Gebhard): Convert this into JDemo demos
238: public static void main(String args[]) throws IOException {
239: long time0 = System.currentTimeMillis();
240: JavaSource source = (new JavaSourceParser())
241: .parse(new java.io.File("JavaSourceParser.java"));
242:
243: long time1 = System.currentTimeMillis();
244: JavaSource2TeXConverter conn1 = new JavaSource2TeXConverter();
245: conn1.convert(source, JavaSourceConversionOptions.getDefault(),
246: new StringWriter());
247: long time2 = System.currentTimeMillis();
248: JavaSource2HTMLConverter conn2 = new JavaSource2HTMLConverter();
249: conn2.convert(source, JavaSourceConversionOptions.getDefault(),
250: new StringWriter());
251: long time3 = System.currentTimeMillis();
252:
253: System.out.println("Parse: " + (time1 - time0) + "ms");
254: System.out.println("toTeX: " + (time2 - time1) + "ms");
255: System.out.println("toHTML: " + (time3 - time2) + "ms");
256: }
257: }
|