summaryrefslogtreecommitdiffstats
path: root/src/rtf2html/rtf_table.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 19:17:32 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 19:17:32 +0000
commite38d2351b83fa65c66ccde443777647ef5cb6cff (patch)
tree1897fc20e9f73a81c520a5b9f76f8ed042124883 /src/rtf2html/rtf_table.cpp
downloadtellico-e38d2351b83fa65c66ccde443777647ef5cb6cff.tar.gz
tellico-e38d2351b83fa65c66ccde443777647ef5cb6cff.zip
Added KDE3 version of Tellico
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/tellico@1097620 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/rtf2html/rtf_table.cpp')
-rw-r--r--src/rtf2html/rtf_table.cpp235
1 files changed, 235 insertions, 0 deletions
diff --git a/src/rtf2html/rtf_table.cpp b/src/rtf2html/rtf_table.cpp
new file mode 100644
index 0000000..b5cdf7b
--- /dev/null
+++ b/src/rtf2html/rtf_table.cpp
@@ -0,0 +1,235 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, [email protected]
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "rtf_table.h"
+#include <set>
+#include <ostream>
+#include <iostream>
+#include <stdexcept>
+#include <functional>
+#include <algorithm>
+
+using namespace rtf;
+
+typedef std::set<int> intset;
+
+template <class T, class C>
+std::basic_ostream<C>& operator<<(std::basic_ostream<C> &dest, std::set<T> &s)
+{
+ for (typename std::set<T>::iterator i=s.begin(); i!=s.end(); ++i)
+ dest<<*i<<" ";
+ return dest;
+}
+
+std::string table::make()
+{
+ std::string result;
+ intset pts;
+ iterator row, span_row, row2;
+ table_cell_defs::iterator cell_def, prev_cell_def, cell_def_2;
+ table_cells::iterator cell;
+ intset::iterator pt, ptp;
+ int left, right, colspan;
+ bool btop, bbottom, bleft, bright;
+ std::string style;
+ for (row=begin(); row!=end();)
+ {
+ if ((*row)->Cells.empty())
+ {
+ delete *row;
+ row=erase(row);
+ }
+ else
+ {
+ pts.insert((*row)->Left);
+ for (cell_def=(*row)->CellDefs->begin(); cell_def!=(*row)->CellDefs->end(); ++cell_def)
+ {
+ pts.insert((*cell_def)->Right);
+ }
+ ++row;
+ }
+ }
+ if (pts.empty())
+ {
+// throw std::logic_error("No CellDefs!");
+ }
+ pt=pts.begin();
+ ptp=pts.end();
+ ptp--;
+ result="<table border=0 width=";
+ result+=from_int((int)rint((*ptp-*pt)/15));
+ result+=" style=\"margin-left:";
+ result+=from_int((int)rint(*pt/15));
+ result+=";border-collapse: collapse;\">";
+ result+="<tr height=0>";
+ for (ptp=pt++=pts.begin(); pt!=pts.end(); ptp=pt++)
+ {
+ result+="<td width=";
+ result+=from_int((int)rint((*pt-*ptp)/15));
+ result+="></td>";
+ //coefficient may be different
+ }
+ result+="</tr>\n";
+
+ // first, we'll determine all the rowspans and leftsides
+ for (row=begin(); row!=end(); ++row)
+ {
+ if ((*row)->CellDefs->size()!=(*row)->Cells.size())
+// throw std::logic_error("Number of Cells and number of CellDefs are unequal!");
+ for (cell_def=(*row)->CellDefs->begin(), cell=(*row)->Cells.begin();
+ cell!=(*row)->Cells.end();
+ ++cell, prev_cell_def=cell_def++
+ )
+ {
+ if (cell_def==(*row)->CellDefs->begin())
+ (*cell_def)->Left=(*row)->Left;
+ else
+ (*cell_def)->Left=(*prev_cell_def)->Right;
+ if ((*cell_def)->FirstMerged)
+ {
+ for (span_row=row, ++span_row; span_row!=end();
+ ++span_row)
+ {
+ cell_def_2=
+ std::find_if((*span_row)->CellDefs->begin(),
+ (*span_row)->CellDefs->end(),
+ std::bind2nd(
+ std::mem_fun(&table_cell_def::right_equals),
+ (*cell_def)->Right));
+ if (cell_def_2==(*span_row)->CellDefs->end())
+ break;
+ if (!(*cell_def_2)->Merged)
+ break;
+ }
+ (*cell)->Rowspan=span_row-row;
+ }
+ }
+ }
+
+ for (row=begin(); row!=end(); ++row)
+ {
+ result+="<tr>";
+ pt=pts.find((*row)->Left);
+ if (pt==pts.end())
+// throw std::logic_error("No row.left point!");
+ if (pt!=pts.begin())
+ {
+ result+="<td colspan=";
+ result+=from_int(std::distance(pts.begin(), pt));
+ result+="></td>";
+ }
+ for (cell_def=(*row)->CellDefs->begin(), cell=(*row)->Cells.begin();
+ cell!=(*row)->Cells.end(); ++cell, ++cell_def)
+ {
+ ptp=pts.find((*cell_def)->Right);
+ if (ptp==pts.end())
+// throw std::logic_error("No celldef.right point!");
+ colspan=std::distance(pt, ptp);
+ pt=ptp;
+ if (!(*cell_def)->Merged)
+ {
+ result+="<td";
+ // analyzing borders
+ left=(*cell_def)->Left;
+ right=(*cell_def)->Right;
+ bbottom=(*cell_def)->BorderBottom;
+ btop=(*cell_def)->BorderTop;
+ bleft=(*cell_def)->BorderLeft;
+ bright=(*cell_def)->BorderRight;
+ span_row=row;
+ if ((*cell_def)->FirstMerged)
+ std::advance(span_row, (*cell)->Rowspan-1);
+ for (row2=row; row2!=span_row; ++row2)
+ {
+ cell_def_2=
+ std::find_if((*row2)->CellDefs->begin(),
+ (*row2)->CellDefs->end(),
+ std::bind2nd(
+ std::mem_fun(&table_cell_def::right_equals),
+ left));
+ if (cell_def_2!=(*row2)->CellDefs->end())
+ {
+ bleft=bleft && (*cell_def_2)->BorderRight;
+ }
+ cell_def_2=
+ std::find_if((*row2)->CellDefs->begin(),
+ (*row2)->CellDefs->end(),
+ std::bind2nd(
+ std::mem_fun(&table_cell_def::left_equals),
+ right));
+ if (cell_def_2!=(*row2)->CellDefs->end())
+ {
+ bright=bright && (*cell_def_2)->BorderLeft;
+ }
+ }
+
+ if (bbottom && btop && bleft && bright)
+ {
+ style="border:1px solid black;";
+ }
+ else
+ {
+ style="";
+ if (bbottom)
+ style+="border-bottom:1px solid black;";
+ if (btop)
+ style+="border-top:1px solid black;";
+ if (bleft)
+ style+="border-left:1px solid black;";
+ if (bright)
+ style+="border-right:1px solid black;";
+ }
+ if (!style.empty())
+ {
+ result+=" style=\"";
+ result+=style;
+ result+="\"";
+ }
+ if (colspan>1)
+ {
+ result+=" colspan=";
+ result+=from_int(colspan);
+ }
+ if ((*cell_def)->FirstMerged)
+ {
+ result+=" rowspan=";
+ result+=from_int((*cell)->Rowspan);
+ }
+
+ switch ((*cell_def)->VAlign)
+ {
+ case table_cell_def::valign_top:
+ result+=" valign=top";
+ break;
+ case table_cell_def::valign_bottom:
+ result+=" valign=bottom";
+ break;
+ default: break;
+ }
+
+ result+=">";
+ if ((*cell)->Text[0]>0)
+ result+=(*cell)->Text;
+ else
+ result+="&nbsp;";
+ result+="</td>";
+ }
+ }
+ result+="</tr>";
+ }
+ result+="</table>";
+ return result;
+}