/** * Copyright (c) 2003-2005 Fernando Dobladez * * This file is part of AntDoclet. * * AntDoclet 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. * * AntDoclet 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 AntDoclet; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ package com.neuroning.antdoclet.latex; import javax.swing.text.html.*; import javax.swing.text.*; /** * This source files was part of an old version of Gregg Wonderly's Texdoclet * (http://texdoclet.dev.java.net/) * * Fernando Dobladez <dobladez@gmail.com> * * @see com.neuroning.antdoclet.latex.HTML2Latex * * * * This class provides support for converting HTML tables into * <TEX txt="\LaTeX{}">LaTeX</TEX> tables. * Some of the things <b>NOT</b> implemented include the following: * <ul> * <li>valign attributes are not processed, but align= is. * <li>rowspan attributes are not processed, but colspan= is. * <li>the argument to border= in the table tag is not used to control line size * </ul> * <br> * Here is an example table. * <p> * <table border bgcolor="#AAAAAA"> * <tr><th>Column 1 Heading<th>Column two heading<th>Column three heading * <tr><td>data<td colspan=2>Span two columns * <tr><td><i>more data</i><td align=right>right<td align=left>left * <tr><td colspan=3><table border=5 bgcolor="#CCCCCC"> * <tr><th colspan=3>A nested table example * <tr><th>Column 1 Heading</th><th>Coludliadfuapfd a fia fopia foipapio dupoau foapoifd pdpfiu apsd oipoioaofiduaopiufopiiiiiiiiiimn two heading</th><th>Column three heading</th> * <tr><td>data</td><td colspan=2>Span two columns</td> * <tr><td><i>more data</i></td><td align=right>right</td><td align=left>left</td> * <tr><td><pre> * 1 * 2 * 3 * 4 * </pre> * </td> * <td><pre> * first line * second line * third line * fourth line * </pre></td> * </table> * </table> * */ public class TableInfo { private StringBuffer originalBuffer; private StringBuffer ret; private int colcnt = 0; private int rowcnt = 0; private int totalcolcnt = 0; private boolean border = false; //private Properties props; private int bordwid; private boolean parboxed; private double red = -1.0; private double blue = -1.0; private double green = -1.0; static int tblcnt; int tblno; String tc; HTML.Tag lastTag; int hasNumAttr(HTML.Attribute attr, MutableAttributeSet attrSet) { String val = (String) attrSet.getAttribute(attr); if( val == null ) return -1; try { return Integer.parseInt(val); } catch( Exception ex ) { return -1; } } /** * Constructs a new table object and starts processing of the table by * scanning the <code><table></code> passed to count columns. * * @param p properties found on the <code><table></code> tag * @param ret the result buffer that will contain the output * @param table the input string that has the entire table definition in it. * @param off the offset into <code><table></code> where scanning should start */ public StringBuffer startTable(StringBuffer org, MutableAttributeSet attrSet) { originalBuffer = org; ret = new StringBuffer(); tblno = tblcnt++; tc = ""+(char)('a'+(tblno/(26*26)))+ (char)((tblno/26)+'a')+ (char)((tblno%26)+'a'); String val = (String)attrSet.getAttribute(HTML.Attribute.BORDER); border = false; if( val != null ) { border = true; bordwid = 2; if( val.equals("") == false ) { try { bordwid = Integer.parseInt( val ); } catch( Exception ex ) { } if( bordwid == 0 ) border = false; } } String bgcolor = (String)attrSet.getAttribute(HTML.Attribute.BGCOLOR); if (bgcolor != null) { try { if (bgcolor.length() != 7 && bgcolor.charAt(0) == '#') throw new NumberFormatException(); red = Integer.decode("#"+bgcolor.substring(1,3)).doubleValue(); blue = Integer.decode("#"+bgcolor.substring(3,5)).doubleValue(); green = Integer.decode("#"+bgcolor.substring(5,7)).doubleValue(); red /= 255.0; blue /= 255.0; green /= 255.0; } catch (NumberFormatException e) { red = 1.0; blue = 1.0; green = 1.0; } } return ret; } /** * Ends the table, closing the last row as needed * @param ret The output buffer to put <TEX txt="\LaTeXe{}">LaTeX2e</TEX> into. */ public StringBuffer endTable() { originalBuffer.append("\n% Table #"+tblno+"\n"); int col = totalcolcnt; if ( col == 0 ) col = 1; for( int i = 0; i < col; ++i ) { String cc = ""+(char)('a'+(i/(26*26)))+ (char)((i/26)+'a')+ (char)((i%26)+'a'); originalBuffer.append("\\newlength{\\tbl"+tc+"c"+cc+"w}\n"); //originalBuffer.append("\\setlength{\\tbl"+tc+"c"+cc+"w}{"+(1.0/col)+"\\hsize}\n"); originalBuffer.append("\\setlength{\\tbl"+tc+"c"+cc+"w}{"+(1.0/col)+"\\linewidth}\n"); } if (red != -1.0 && green != -1.0 && blue != -1.0) originalBuffer.append("\\colorbox[rgb]{" + Double.toString(red) + "," + Double.toString(blue) + ","+ Double.toString(green) + "}{"); originalBuffer.append("\\begin{tabular}{"); if( border ) originalBuffer.append("|"); for( int i = 0; i < col; ++i ) { String cc = ""+(char)('a'+(i/(26*26)))+ (char)((i/26)+'a')+ (char)((i%26)+'a'); originalBuffer.append("p{\\tbl"+tc+"c"+cc+"w}"); if( border ) originalBuffer.append("|"); } originalBuffer.append("}\n"); //Append the cached table originalBuffer.append(ret); originalBuffer.append("\\end{tabular}\n"); if (red != -1.0 && green != -1.0 && blue != -1.0) originalBuffer.append("}\n"); return originalBuffer; } /** * Starts a new column, possibly closing the current column if needed * * @param ret The output buffer to put <TEX txt="\LaTeXe{}">LaTeX2e</TEX> into. * @param p the properties from the <code><td></code> tag */ public void startCol(MutableAttributeSet attrSet) { int span = hasNumAttr(HTML.Attribute.COLSPAN, attrSet); if( colcnt > 0 ) { ret.append(" & " ); } String align = (String)attrSet.getAttribute(HTML.Attribute.ALIGN); if( align != null && span < 0 ) span = 1; if( span > 0 ) { ret.append("\\multicolumn{"+span+"}{" ); if( border && colcnt == 0) ret.append("|"); String cc = ""+(char)('a'+(colcnt/(26*26)))+ (char)((colcnt/26)+'a')+ (char)((colcnt%26)+'a'); if( align != null ) { String h = align.substring(0,1); if( "rR".indexOf(h) >= 0 ) ret.append("r"); else if( "lL".indexOf(h) >= 0 ) ret.append("p{\\tbl"+tc+"c"+cc+"w}"); else if( "cC".indexOf(h) >= 0 ) ret.append("p{\\tbl"+tc+"c"+cc+"w}"); } else ret.append("p{\\tbl"+tc+"c"+cc+"w}"); if( border ) ret.append("|"); ret.append("}"); } String wid = (String)attrSet.getAttribute("texwidth"); ret.append("{"); if( wid != null ) { ret.append("\\parbox{"+wid+"}{\\vskip 1ex "); parboxed = true; } colcnt++; totalcolcnt = totalcolcnt > colcnt ? totalcolcnt : colcnt; } /** * Starts a new Heading column, possibly closing the current column * if needed. A Heading column has a Bold Face font directive around * it. * @param ret The output buffer to put <TEX txt="\LaTeXe{}">LaTeX2e</TEX> into. * @param p The properties from the <code><th></code> tag */ public void startHeadCol(MutableAttributeSet attrSet) { startCol(attrSet); ret.append("\\bf "); } /** * Ends the current column. * @param ret The output buffer to put <TEX txt="\LaTeXe{}">LaTeX2e</TEX> into. */ public void endCol() { if(parboxed) ret.append("\\vskip 1ex}"); parboxed = false; ret.append("}"); } /** * Starts a new row, possibly closing the current row if needed * @param ret The output buffer to put <TEX txt="\LaTeX{}">LaTeX</TEX> into. * @param p The properties from the <code><tr></code> tag */ public void startRow(MutableAttributeSet attrSet) { if( rowcnt == 0 ) { if( border ) ret.append(" \\hline " ); } colcnt = 0; ++rowcnt; } /** * Ends the current row. * @param ret The output buffer to put <TEX txt="\LaTeXe{}">LaTeX2e</TEX> into. */ public void endRow() { ret.append( " \\\\" ); if( border ) ret.append( " \\hline" ); ret.append("\n"); } }