/************************************************************************ * * TableFormatter.java * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Copyright: 2002-2009 by Henrik Just * * All Rights Reserved. * * Version 1.0 (2009-02-19) * */ package writer2latex.latex; import org.w3c.dom.Element; import org.w3c.dom.Node; import writer2latex.util.*; import writer2latex.office.*; import writer2latex.latex.util.BeforeAfter; import writer2latex.latex.util.Context; /** *

This class converts OOo table styles to LaTeX.

*

In OOo the table style is distributed on table, column and cell styles. *

In LaTeX we have to rearrange this information slightly, so this class * takes care of that.

*/ public class TableFormatter extends ConverterHelper { //private boolean bApplyCellFormat; private TableReader table; private char[][] cAlign; private char[] cGlobalAlign; private boolean[][] bHBorder; private boolean[][] bVBorder; private boolean[] bGlobalVBorder; private String[] sRowColor; private String[][] sCellColor; private String[] sColumnWidth; private boolean bIsLongtable; private boolean bIsSupertabular; private boolean bIsTabulary; private boolean bIsColortbl; private boolean bIsSimple; /**

Constructor: Create from a TableReader.

*/ public TableFormatter(OfficeReader ofr, LaTeXConfig config, ConverterPalette palette, TableReader table, boolean bAllowPageBreak, boolean bIsInTable) { super(ofr,config,palette); this.table = table; //bApplyCellFormat = config.formatting()>=LaTeXConfig.CONVERT_MOST; int nRowCount = table.getRowCount(); int nColCount = table.getColCount(); int nSimpleTableLimit = config.getSimpleTableLimit(); // Step 1: Collect alignment and identify simple tables bIsSimple = true; cAlign = new char[nRowCount][nColCount]; cGlobalAlign = new char[nColCount]; // Keep track of characters to be counted int[] nPendingChars = new int[nRowCount]; int[] nPendingColSpan = new int[nRowCount]; int nTableWidth = 0; for (int nCol=0; nCol=1) { nPendingChars[nRow] = Math.max(0, nPendingChars[nRow]-nColChars); nPendingColSpan[nRow]--; } } } if (nTableWidth>nSimpleTableLimit) bIsSimple = false; // Step 2: Create global alignment for (int nCol=0; nColnLeft) { if (nRight>nLeft) { cGlobalAlign[nCol] = 'r'; } else { cGlobalAlign[nCol] = 'c'; } } else if (nRight>nLeft) { cGlobalAlign[nCol] = 'r'; } } // Step 3: Initialize borders: bHBorder = new boolean[nRowCount+1][nColCount]; for (int nRow=0; nRow<=nRowCount; nRow++) { for (int nCol=0; nCol0); } } // Step 5: Create global vertical borders based on simple majority // (in order to minimize the number of \multicolum{1} entries) bGlobalVBorder = new boolean[nColCount+1]; for (int nCol=0; nCol<=nColCount; nCol++) { int nBalance = 0; for (int nRow=0; nRow0; } // Step 6: Get background colors sRowColor = new String[nRowCount]; sCellColor = new String[nRowCount][nColCount]; if (config.useColortbl()) { // Table background String sTableColor = null; StyleWithProperties tableStyle = ofr.getTableStyle(table.getTableStyleName()); if (tableStyle!=null) { sTableColor = tableStyle.getProperty(XMLString.FO_BACKGROUND_COLOR); } // Row background for (int nRow=0; nRowCreate table environment based on table style.

*

Returns eg. "\begin{longtable}{m{2cm}|m{4cm}}", "\end{longtable}".

*/ public void applyTableStyle(BeforeAfter ba, BeforeAfter baAlign) { // Read formatting info from table style // Only supported properties are alignment and may-break-between-rows. String sStyleName = table.getTableStyleName(); StyleWithProperties style = ofr.getTableStyle(sStyleName); char cAlign = 'c'; if (style!=null && !table.isSubTable()) { String s = style.getProperty(XMLString.TABLE_ALIGN); if ("left".equals(s)) { cAlign='l'; } else if ("right".equals(s)) { cAlign='r'; } } String sAlign="center"; switch (cAlign) { case 'c': sAlign="center"; break; case 'r': sAlign="flushright"; break; case 'l': sAlign="flushleft"; } // Create table alignment (for supertabular, tabular and tabulary) if (!bIsLongtable && !table.isSubTable()) { baAlign.add("\\begin{"+sAlign+"}\n","\\end{"+sAlign+"}\n"); } // Create table declaration if (bIsLongtable) { ba.add("\\begin{longtable}["+cAlign+"]", "\\end{longtable}"); } else if (bIsSupertabular) { ba.add("\\begin{supertabular}","\\end{supertabular}"); } else if (bIsTabulary) { ba.add("\\begin{tabulary}{"+table.getTableWidth()+"}","\\end{tabulary}"); } else if (!table.isSubTable()) { ba.add("\\begin{tabular}","\\end{tabular}"); } else { // subtables should occupy the entire width, including padding! ba.add("\\hspace*{-\\tabcolsep}\\begin{tabular}", "\\end{tabular}\\hspace*{-\\tabcolsep}"); } // columns ba.add("{",""); if (bGlobalVBorder[0]) { ba.add("|",""); } int nColCount = table.getColCount(); for (int nCol=0; nColCreate interrow material

*/ public String getInterrowMaterial(int nRow) { int nColCount = table.getColCount(); int nCount = 0; for (int nCol=0; nColGet material to put before a table row (background color) */ public void applyRowStyle(int nRow, BeforeAfter ba, Context context) { palette.getColorCv().applyBgColor("\\rowcolor",sRowColor[nRow],ba,context); } /** Get material to put before and after a table cell. * In case of columnspan or different borders this will contain a \multicolumn command. */ public void applyCellStyle(int nRow, int nCol, BeforeAfter ba, Context context) { Node cell = table.getCell(nRow,nCol); int nColSpan = Misc.getPosInteger(Misc.getAttribute(cell, XMLString.TABLE_NUMBER_COLUMNS_SPANNED),1); // Construct column declaration as needed boolean bNeedLeft = (nCol==0) && (bVBorder[nRow][0]!=bGlobalVBorder[0]); boolean bNeedRight = bVBorder[nRow][nCol+1]!=bGlobalVBorder[nCol+1]; boolean bNeedAlign = bIsSimple && cGlobalAlign[nCol]!=cAlign[nRow][nCol]; // calculate column width String sTotalColumnWidth = sColumnWidth[nCol]; for (int i=nCol+1; i1) { ba.add("\\multicolumn{"+nColSpan+"}{",""); if (nCol==0 && bVBorder[nRow][0]) { ba.add("|",""); } if (bIsSimple) { ba.add(Character.toString(cAlign[nRow][nCol]),""); } else { ba.add("m{"+sTotalColumnWidth+"}",""); } if (bVBorder[nRow][nCol+nColSpan]) { ba.add("|",""); } ba.add("}{","}"); } palette.getColorCv().applyBgColor("\\cellcolor",sCellColor[nRow][nCol],ba,context); } }