Open Source Repository

Home /web/java2html | Repository Home


de/java2html/converter/JavaSource2TeXConverter.java
package de.java2html.converter;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringWriter;

import de.java2html.Version;
import de.java2html.javasource.JavaSource;
import de.java2html.javasource.JavaSourceIterator;
import de.java2html.javasource.JavaSourceParser;
import de.java2html.javasource.JavaSourceRun;
import de.java2html.javasource.JavaSourceType;
import de.java2html.options.JavaSourceConversionOptions;
import de.java2html.options.JavaSourceStyleTable;
import de.java2html.util.RGB;

/**
 * Algorithm and stuff for converting a
 {@link de.java2html.javasource.JavaSource} object to to a TeX string
 * representation (experimental!).
 
 * For questions, suggestions, bug-reports, enhancement-requests etc. I may be
 * contacted at: <a href="mailto:[email protected]">[email protected]</a>
 
 * The Java2html home page is located at: <a href="http://www.java2html.de">
 * http://www.java2html.de</a>
 
 @author <a href="mailto:[email protected]">Markus Gebhard</a>
 @version 2.0, 05/07/02
 
 * Copyright (C) Markus Gebhard 2000-2002
 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307, USA.
 */
public class JavaSource2TeXConverter extends AbstractJavaSourceConverter {
  private static String[] texFormats;
  static {
    JavaSourceType[] allTypes = JavaSourceType.getAll();
    texFormats = new String[allTypes.length];
    for (int i = 0; i < allTypes.length; ++i) {
      texFormats[i"\\jttstyle" (char) ('a' + i" ";
    }
  }

  private String createFormatDefinition(JavaSourceStyleTable styleTable) {
    StringBuffer sb = new StringBuffer();
    sb.append("%Java2TeX style definitions\n");
    sb.append("%You can modify them to fit your needs\n");

    JavaSourceType[] allTypes = JavaSourceType.getAll();
    for (int i = 0; i < allTypes.length; ++i) {
      sb.append("\\newcommand{\\jttstyle");
      sb.append((char) ('a' + i));
      sb.append("}{\\color[rgb]{");

      RGB color = styleTable.get(allTypes[i]).getColor();
      float[] cs = new float[]{ color.getRed() 255.0f, color.getGreen() 255.0f, color.getBlue() 255.0f};
      sb.append(floatToCharArray(cs[0]));
      sb.append(',');
      sb.append(floatToCharArray(cs[1]));
      sb.append(',');
      sb.append(floatToCharArray(cs[2]));

      sb.append("}} %");
      sb.append(allTypes[i].getName());
      sb.append('\n');

    }
    sb.append('\n');
    return sb.toString();
  }

  /** Document header */
  protected final static String DOCUMENT_HEADER = "\\documentclass[11pt,a4paper]{article}\n"
      "\n"
      "\\usepackage{color}\n"
      "\n"
      "\\begin{document}\n"
      "\n";

  /** Document header */
  protected final static String DOCUMENT_FOOTER = "\\end{document}";

  /** Block seperator for between two blocks of converted source code */
  protected final static String DOCUMENT_BLOCK_SEPARATOR = "\n\n";

  protected final static String BLOCK_HEADER = "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
      "%  Java Sourcecode to TeX automatically converted code\n"
      "%  "
      + Version.getJava2HtmlConverterTitle()
      " "
      + Version.getBuildDate()
      "by Markus Gebhard  [email protected]\n"
      "%     Further information: http://www.java2html.de\n";

  public JavaSource2TeXConverter() {
    super(new ConverterMetaData("tex""TeX""tex"));
  }

  protected final static char[] floatToCharArray(float f) {
    if (f >= 1.0) {
      return new char[]{ '1''.''0''0' };
    }

    return new char[]{ '.'(char) ('0' + f * 10)(char) ('0' + f * 100 10)(char) ('0' + f * 1000 10) };
  }

  public String getDocumentHeader(JavaSourceConversionOptions options, String title) {
    return DOCUMENT_HEADER + createFormatDefinition(options.getStyleTable());
  }

  public String getDocumentFooter(JavaSourceConversionOptions options) {
    return DOCUMENT_FOOTER;
  }

  public String getBlockSeparator(JavaSourceConversionOptions options) {
    return DOCUMENT_BLOCK_SEPARATOR;
  }

  /**
   * Converts the parsed source code to HTML by adding color information,
   * adding line breaks and replacing characters as needed for HTML. Also adds
   * a table with line numbers etc.
   */
  public void convert(JavaSource source, JavaSourceConversionOptions options, BufferedWriter writer)
      throws IOException {
    if (source == null) {
      throw new IllegalStateException("Trying to write out converted code without having source set.");
    }

    writer.write(BLOCK_HEADER);

    //1) Header with filename if available
    if (options.isShowFileName() && source.getFileName() != null) {
      //TODO: Pretty print file name
    }

    writer.write("{");
    writer.newLine();
    writer.write("\\noindent \\ttfamily");
    writer.newLine();

    int lineCount = source.getLineCount();
    int lineNumber = 1;
    JavaSourceIterator iterator = source.getIterator();
    while (iterator.hasNext()) {
      JavaSourceRun run = iterator.getNext();
      if (run.isAtStartOfLine() && options.isShowLineNumbers()) {
        writeLineNumber(writer, lineNumber++, lineCount);
      }
      toTeX(run, writer);
      if (run.isAtEndOfLine()) {
        writer.write("\\\\");
        writer.newLine();
      }
    }

    writer.newLine();
    writer.write("}");
    writer.newLine();
  }

  public void writeLineNumber(BufferedWriter writer, int lineNumber, int lineCountthrows IOException {
    writer.write(texFormats[JavaSourceType.LINE_NUMBERS.getID()]);
    writer.write(leftSpace(lineNumber, lineCount));
    writer.write(String.valueOf(lineNumber));
    writer.write('~');
  }

  protected void toTeX(JavaSourceRun run, BufferedWriter writerthrows IOException {
    writer.write(texFormats[run.getType().getID()]);

    //Replace white space by non-breaking space and line breaks by \\
    //Also enclose special characters in \\verb# #
    String text = run.getCode();
    for (int i = 0; i < text.length(); ++i) {
      char ch = text.charAt(i);
      if (ch == ' ')
        writer.write('~');
      else if (ch == '_'
          || ch == '\\'
          || ch == '^'
          || ch == '~'
          || ch == '\"'
          || ch == '|'
          || ch == '<'
          || ch == '>'
          || ch == '*')
        writer.write("\\verb#" + ch + "#");
      else if (ch == '{' || ch == '}' || ch == '_' || ch == '&' || ch == '%' || ch == '$' || ch == '#') {
        writer.write("\\" + ch);
      }
      else {
        writer.write(ch);
      }
    }
  }

  protected final static String[] WHITESPACES = """~""~~""~~~""~~~~"};

  protected final static String whiteSpace(int size) {
    if (size < WHITESPACES.length)
      return WHITESPACES[size];

    char[] result = new char[size];
    while (size > 0)
      result[--size'~';

    return new String(result);
  }

  protected final static String leftSpace(int num, int max) {
    int count = (int) (Math.log(max/ Math.log(10)) (int) (Math.log(num/ Math.log(10));

    return whiteSpace(count);
  }

  //TODO Sep 13, 2004 (Markus Gebhard): Convert this into JDemo demos
  public static void main(String args[]) throws IOException {
    long time0 = System.currentTimeMillis();
    JavaSource source = (new JavaSourceParser()).parse(new java.io.File("JavaSourceParser.java"));

    long time1 = System.currentTimeMillis();
    JavaSource2TeXConverter conn1 = new JavaSource2TeXConverter();
    conn1.convert(source, JavaSourceConversionOptions.getDefault()new StringWriter());
    long time2 = System.currentTimeMillis();
    JavaSource2HTMLConverter conn2 = new JavaSource2HTMLConverter();
    conn2.convert(source, JavaSourceConversionOptions.getDefault()new StringWriter());
    long time3 = System.currentTimeMillis();

    System.out.println("Parse:  " (time1 - time0"ms");
    System.out.println("toTeX:  " (time2 - time1"ms");
    System.out.println("toHTML: " (time3 - time2"ms");
  }
}