diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 19:17:32 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 19:17:32 +0000 |
commit | e38d2351b83fa65c66ccde443777647ef5cb6cff (patch) | |
tree | 1897fc20e9f73a81c520a5b9f76f8ed042124883 /src/rtf2html | |
download | tellico-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')
-rw-r--r-- | src/rtf2html/Makefile.am | 15 | ||||
-rw-r--r-- | src/rtf2html/common.h | 38 | ||||
-rw-r--r-- | src/rtf2html/dbg_iter.h | 67 | ||||
-rw-r--r-- | src/rtf2html/fmt_opts.cpp | 221 | ||||
-rw-r--r-- | src/rtf2html/fmt_opts.h | 154 | ||||
-rw-r--r-- | src/rtf2html/rtf2html.cpp | 531 | ||||
-rw-r--r-- | src/rtf2html/rtf2html.h | 28 | ||||
-rw-r--r-- | src/rtf2html/rtf_keyword.cpp | 107 | ||||
-rw-r--r-- | src/rtf2html/rtf_keyword.h | 1 | ||||
-rw-r--r-- | src/rtf2html/rtf_table.cpp | 235 | ||||
-rw-r--r-- | src/rtf2html/rtf_table.h | 90 | ||||
-rw-r--r-- | src/rtf2html/rtf_tools.h | 65 |
12 files changed, 1552 insertions, 0 deletions
diff --git a/src/rtf2html/Makefile.am b/src/rtf2html/Makefile.am new file mode 100644 index 0000000..ea3d39f --- /dev/null +++ b/src/rtf2html/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = $(all_includes) + +noinst_LIBRARIES = librtf2html.a +librtf2html_a_SOURCES = fmt_opts.cpp rtf2html.cpp rtf_keyword.cpp rtf_table.cpp + +librtf2html_a_METASOURCES = AUTO + +KDE_OPTIONS = noautodist + +EXTRA_DIST = common.h dbg_iter.h fmt_opts.h fmt_opts.cpp \ +rtf2html.h rtf2html.cpp rtf_keyword.h rtf_keyword.cpp \ +rtf_table.h rtf_table.cpp rtf_tools.h + +CLEANFILES = *~ + diff --git a/src/rtf2html/common.h b/src/rtf2html/common.h new file mode 100644 index 0000000..01b1f5b --- /dev/null +++ b/src/rtf2html/common.h @@ -0,0 +1,38 @@ +/* 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; * + * * + ***************************************************************************/ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include <string> +#include <sstream> +#include <iomanip> + +inline std::string from_int(int value) +{ + std::ostringstream buf; + buf<<value; + return buf.str(); +} + +inline std::string hex(unsigned int value) +{ + std::ostringstream buf; + buf<<std::setw(2)<<std::setfill('0')<<std::hex<<value; + return buf.str(); +} + +#endif diff --git a/src/rtf2html/dbg_iter.h b/src/rtf2html/dbg_iter.h new file mode 100644 index 0000000..dfbccf2 --- /dev/null +++ b/src/rtf2html/dbg_iter.h @@ -0,0 +1,67 @@ +/* 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; * + * * + ***************************************************************************/ + +namespace rtf { + +template <class T> +class dbg_iter_mixin : public virtual T +{ + public: + int offset; + dbg_iter_mixin(const T& t) : T(t) + {} + T& operator=(const T& t) + { + return T::operator=(t); + } + dbg_iter_mixin& operator++ () + { + ++offset; + T::operator++(); + return *this; + } + dbg_iter_mixin operator++ (int i) + { + ++offset; + return T::operator++(i); + } + char operator *() const + { + T::value_type c=T::operator*(); +// std::cerr<<offset<<":"<<c<<std::endl; + return c; + } +}; + +template <class T> +class dbg_iter : public dbg_iter_mixin<T> +{ + public: + dbg_iter(const T& t) : dbg_iter_mixin<T>(t) + {} +}; + +template<class T> +class dbg_iter<std::istreambuf_iterator<T> > : + public virtual std::istreambuf_iterator<T>, + public dbg_iter_mixin<std::istreambuf_iterator<T> > +{ + public: + dbg_iter(std::basic_streambuf<T> *buf) : std::istreambuf_iterator<T>(buf) + {} +}; + +}
\ No newline at end of file diff --git a/src/rtf2html/fmt_opts.cpp b/src/rtf2html/fmt_opts.cpp new file mode 100644 index 0000000..25a2f24 --- /dev/null +++ b/src/rtf2html/fmt_opts.cpp @@ -0,0 +1,221 @@ +/* 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 "fmt_opts.h" + +using namespace rtf; + +std::string formatting_options::get_par_str() const +{ + std::string style; + switch (papAlign) + { + case formatting_options::align_right: + style+="text-align:right;"; + break; + case formatting_options::align_center: + style+="text-align:center;"; + break; + case formatting_options::align_justify: + style+="text-align:justify;"; + default: break; + } + if (papFirst!=0) + { + style+="text-indent:"; + style+=from_int(papFirst); + style+="pt;"; + } + if (papLeft!=0) + { + style+="margin-left:"; + style+=from_int(papLeft); + style+="pt;"; + } + if (papRight!=0) + { + style+="margin-right:"; + style+=from_int(papRight); + style+="pt;"; + } + if (papBefore!=0) + { + style+="margin-top:"; + style+=from_int(papBefore); + style+="pt;"; + } + if (papAfter!=0) + { + style+="margin-bottom:"; + style+=from_int(papAfter); + style+="pt;"; + } + if (style.empty()) + return std::string("<p>"); + else + { + style.insert(0, "<p style=\""); + return style+"\">"; + } +} + +std::string formatter::format(const formatting_options &_opt) +{ + formatting_options last_opt, opt(_opt); + std::string result; + if (!opt_stack.empty()) + { + int cnt=0; + fo_deque::reverse_iterator i; + for (i=opt_stack.rbegin(); i!=opt_stack.rend(); ++i) + { + if (*i==opt) + break; + ++cnt; + } + if (cnt==0) + return ""; + if (i!=opt_stack.rend()) + { + while (cnt--) + { + result+="</span>"; + opt_stack.pop_back(); + } + return result; + } + last_opt=opt_stack.back(); + } + if (last_opt.chpVAlign!=formatting_options::va_normal + && last_opt.chpVAlign!=opt.chpVAlign) + { + int cnt=0; + fo_deque::reverse_iterator i; + for (i=opt_stack.rbegin(); i!=opt_stack.rend(); ++i) + { + if (i->chpVAlign==formatting_options::va_normal) + break; + ++cnt; + } + while (cnt--) + { + result+="</span>"; + opt_stack.pop_back(); + } + last_opt=opt_stack.empty()?formatting_options():opt_stack.back(); + } + std::string style; + if (opt.chpBold!=last_opt.chpBold) + { + style+="font-weight:"; + style+=opt.chpBold?"bold":"normal"; + style+=";"; + } + if (opt.chpItalic!=last_opt.chpItalic) + { + style+="font-style:"; + style+=opt.chpItalic?"italic":"normal"; + style+=";"; + } + if (opt.chpUnderline!=last_opt.chpUnderline) + { + style+="text-decoration:"; + style+=opt.chpUnderline?"underline":"none"; + style+=";"; + } + if (opt.chpVAlign!=formatting_options::va_normal) + opt.chpFontSize=(int)(0.7*(opt.chpFontSize?opt.chpFontSize:24)); + if (opt.chpFontSize!=last_opt.chpFontSize) + { + style+="font-size:"; + style+=from_int(opt.chpFontSize/2); + style+="pt;"; + } + if (opt.chpVAlign!=last_opt.chpVAlign) + { + style+="vertical-align:"; + style+=opt.chpVAlign==formatting_options::va_sub?"sub":"super"; + style+=";"; + } + if (opt.chpFColor!=last_opt.chpFColor) + { + style+="color:"; + style+=opt.chpFColor.r>0?"#"+hex(opt.chpFColor.r&0xFF) + +hex(opt.chpFColor.g&0xFF) + +hex(opt.chpFColor.b&0xFF) + :"WindowText"; + style+=";"; + } + if (opt.chpBColor!=last_opt.chpBColor) + { + style+="background-color:"; + style+=opt.chpBColor.r>0?"#"+hex(opt.chpBColor.r&0xFF) + +hex(opt.chpBColor.g&0xFF) + +hex(opt.chpBColor.b&0xFF) + :"Window"; + style+=";"; + } + if (opt.chpHighlight!=last_opt.chpHighlight) + { + style+="background-color:"; + switch (opt.chpHighlight) + { + case 0: style+="Window"; break; + case 1: style+="black"; break; + case 2: style+="blue"; break; + case 3: style+="aqua"; break; + case 4: style+="lime"; break; + case 5: style+="fuchsia"; break; + case 6: style+="red"; break; + case 7: style+="yellow"; break; + case 9: style+="navy"; break; + case 10: style+="teal"; break; + case 11: style+="green"; break; + case 12: style+="purple"; break; + case 13: style+="maroon"; break; + case 14: style+="olive"; break; + case 15: style+="gray"; break; + case 16: style+="silver"; break; + } + style+=";"; + } + if (opt.chpFont!=last_opt.chpFont) + { + style+="font-family:'"; + style+=opt.chpFont.name.empty()?"serif":opt.chpFont.name; + style+="'"; + switch (opt.chpFont.family) + { + case font::ff_serif: style+=", serif"; break; + case font::ff_sans_serif: style+=", sans-serif"; break; + case font::ff_cursive: style+=", cursive"; break; + case font::ff_fantasy: style+=", fantasy"; break; + case font::ff_monospace: style+=", monospace"; break; + default: break; + } + style+=";"; + } + opt_stack.push_back(opt); + return result+"<span style=\""+style+"\">"; +} + +std::string formatter::close() +{ + std::string result; + for (fo_deque::iterator i=opt_stack.begin(); i!=opt_stack.end(); ++i) + result+="</span>"; + return result; +} diff --git a/src/rtf2html/fmt_opts.h b/src/rtf2html/fmt_opts.h new file mode 100644 index 0000000..6845d60 --- /dev/null +++ b/src/rtf2html/fmt_opts.h @@ -0,0 +1,154 @@ +/* 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; * + * * + ***************************************************************************/ + +#ifndef __FMT_OPTS_H__ +#define __FMT_OPTS_H__ + +#include "common.h" +#include <stack> +#include <vector> +#include <deque> +#include <map> + +namespace rtf { + +struct color { + int r, g, b; + color() : r(-1), g(-1), b(-1) {} + bool operator==(const color &clr) + { + return r==clr.r && g==clr.g && b==clr.b; + } + bool operator!=(const color &clr) + { + return !(*this==clr); + } + color &operator=(const color &clr) + { + r=clr.r; g=clr.g; b=clr.b; + return *this; + } +}; + +typedef std::vector<color> colorvect; + +struct font { + enum font_family {ff_none, ff_serif, ff_sans_serif, ff_cursive, + ff_fantasy, ff_monospace}; + font_family family; + std::string name; + int pitch; + int charset; + font() : family(ff_none), name(), pitch(0), charset(0) {} + bool operator==(const font &f) + { + return family==f.family && name==f.name; + } + bool operator!=(const font &f) + { + return !(*this==f); + } + font &operator=(const font &f) + { + family=f.family; name=f.name; pitch=f.pitch; charset=f.charset; + return *this; + } +}; + +typedef std::map<int, font> fontmap; + +struct formatting_options +{ + enum halign {align_left, align_right, align_center, align_justify, align_error}; + enum valign {va_normal, va_sub, va_sup}; + bool chpBold, chpItalic, chpUnderline; + valign chpVAlign; + int chpFontSize, chpHighlight; + color chpFColor, chpBColor; + font chpFont; + int papLeft, papRight, papFirst; + int papBefore, papAfter; + halign papAlign; + bool papInTbl; + formatting_options() + { + chpBold=chpItalic=chpUnderline=false; + chpVAlign=va_normal; + chpFontSize=chpHighlight=0; + papLeft=papRight=papFirst=papBefore=papAfter=0; + papAlign=align_left; + papInTbl=false; + } + bool operator==(const formatting_options &opt) // tests only for character options + { + return chpBold==opt.chpBold && chpItalic==opt.chpItalic + && chpUnderline==opt.chpUnderline && chpVAlign==opt.chpVAlign + && chpFontSize==opt.chpFontSize + && chpFColor==opt.chpFColor && chpBColor==opt.chpBColor + && chpHighlight==opt.chpHighlight && chpFont==opt.chpFont; + } + bool operator!=(const formatting_options &opt) // tests only for character options + { + return !(*this==opt); + } + formatting_options &operator=(const formatting_options &opt) + { + chpBold=opt.chpBold; chpItalic=opt.chpItalic; + chpUnderline=opt.chpUnderline; chpVAlign=opt.chpVAlign; + chpFontSize=opt.chpFontSize; + chpFColor=opt.chpFColor; chpBColor=opt.chpBColor; + chpHighlight=opt.chpHighlight; chpFont=opt.chpFont; + papLeft=opt.papLeft; papRight=opt.papRight; + papFirst=opt.papFirst; papBefore=opt.papBefore; papAfter=opt.papAfter; + papAlign=opt.papAlign; papInTbl=opt.papInTbl; + return *this; + } + std::string get_par_str() const; +}; + +typedef std::stack<formatting_options> fo_stack; + +typedef std::deque<formatting_options> fo_deque; + +class formatter { + private: + fo_deque opt_stack; + public: + std::string format(const formatting_options &opt); + std::string close(); + void clear() { opt_stack.clear(); } +}; + +class html_text { + private: + const formatting_options &opt; + formatter fmt; + std::string text; + public: + html_text(const formatting_options &_opt) : opt(_opt) {} + const std::string &str() { return text; } + template <class T> void write(T s) + { + text+=fmt.format(opt)+s; + } + std::string close() { return fmt.close(); } +// void write(char c) { write(std::string()+c); } + void clear() { text.clear(); fmt.clear(); } +}; + +} +#endif + diff --git a/src/rtf2html/rtf2html.cpp b/src/rtf2html/rtf2html.cpp new file mode 100644 index 0000000..4f29fe7 --- /dev/null +++ b/src/rtf2html/rtf2html.cpp @@ -0,0 +1,531 @@ +/* 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 "rtf2html.h" +#include "rtf_table.h" +#include "rtf_tools.h" +#include "rtf_keyword.h" +#include "fmt_opts.h" + +#include <cstdlib> +#include <stdexcept> +#include <fstream> +#include <iostream> +#include <string> + +using Tellico::RTF2HTML; +using namespace rtf; + +RTF2HTML::RTF2HTML(const QString& text) : m_text(text) { +} + +QString RTF2HTML::toHTML() const { + std::string str_in = m_text; + + std::string::iterator buf_in=str_in.begin(), buf_in_end=str_in.end(); + colorvect colortbl; + fontmap fonttbl; + std::string title; + + bool bAsterisk=false; + fo_stack foStack; + formatting_options cur_options; + std::string html; + html_text par_html(cur_options); + + /* CellDefs in rtf are really queer. We'll keep a list of them in main() + and will give an iterator into this list to a row */ + table_cell_defs_list CellDefsList; + table_cell_defs_list::iterator CurCellDefs; + table_cell_def* tcdCurCellDef=new table_cell_def; + table_cell* tcCurCell=new table_cell; + table_row* trCurRow=new table_row; + table* tblCurTable=new table; + int iLastRowLeft=0, iLastRowHeight=0; + std::string t_str; + + bool bInTable=false; + int iDocWidth=12240; + int iMarginLeft=1800; + while(buf_in!=buf_in_end) + { + switch (*buf_in) + { + case '\\': + { + rtf_keyword kw(++buf_in); + if (kw.is_control_char()) + switch (kw.control_char()) + { + case '\\': case '{': case '}': + par_html.write(kw.control_char()); + break; + case '\'': + { + std::string stmp(1,*buf_in++); + stmp+=*buf_in++; + int code=std::strtol(stmp.c_str(), NULL, 16); + switch (code) + { + case 167: + par_html.write("•"); + break; + case 188: + par_html.write("…"); + break; + default: + par_html.write((char)code); + } + break; + } + case '*': + bAsterisk=true; + break; + case '~': + par_html.write(" "); + break; + case '\n': + par_html.write("<br><br>"); + break; + } + else //kw.is_control_char + if (bAsterisk) + { + bAsterisk=false; + skip_group(buf_in); + } + else + { + switch (kw.keyword()) + { + case rtf_keyword::rkw_filetbl: + case rtf_keyword::rkw_stylesheet: + case rtf_keyword::rkw_header: + case rtf_keyword::rkw_footer: case rtf_keyword::rkw_headerf: + case rtf_keyword::rkw_footerf: case rtf_keyword::rkw_pict: + case rtf_keyword::rkw_object: + // we'll skip such groups + skip_group(buf_in); + break; + // document title + case rtf_keyword::rkw_info: + { + int depth=1; + bool in_title=false; + while (depth>0) + { +// std::cout<<std::string(buf_in).substr(0,20)<<"\t"<<depth<<std::endl; + switch (*buf_in) + { + case '\\': + { + rtf_keyword kw(++buf_in); + if (kw.keyword()==rtf_keyword::rkw_title) + in_title=true; + break; + } + case '{': ++depth; ++buf_in; break; + case '}': --depth; ++buf_in; in_title=false; break; + default: if (in_title) title+=*buf_in; ++buf_in; break; + } + } + break; + } + // color table + case rtf_keyword::rkw_colortbl: + { + color clr; + while (*buf_in!='}') + { + switch (*buf_in) + { + case '\\': + { + rtf_keyword kw(++buf_in); + switch (kw.keyword()) + { + case rtf_keyword::rkw_red: + clr.r=kw.parameter(); + break; + case rtf_keyword::rkw_green: + clr.g=kw.parameter(); + break; + case rtf_keyword::rkw_blue: + clr.b=kw.parameter(); + break; + default: break; + } + break; + } + case ';': + colortbl.push_back(clr); + ++buf_in; + break; + default: + ++buf_in; + break; + } + } + ++buf_in; + break; + } + // font table + case rtf_keyword::rkw_fonttbl: + { + font fnt; + int font_num; + bool full_name=false; + bool in_font=false; + while (! (*buf_in=='}' && !in_font)) + { + switch (*buf_in) + { + case '\\': + { + rtf_keyword kw(++buf_in); + if (kw.is_control_char() && kw.control_char()=='*') + skip_group(buf_in); + else + switch (kw.keyword()) + { + case rtf_keyword::rkw_f: + font_num=kw.parameter(); + break; + case rtf_keyword::rkw_fprq: + fnt.pitch=kw.parameter(); + break; + case rtf_keyword::rkw_fcharset: + fnt.charset=kw.parameter(); + break; + case rtf_keyword::rkw_fnil: + fnt.family=font::ff_none; + break; + case rtf_keyword::rkw_froman: + fnt.family=font::ff_serif; + break; + case rtf_keyword::rkw_fswiss: + fnt.family=font::ff_sans_serif; + break; + case rtf_keyword::rkw_fmodern: + fnt.family=font::ff_monospace; + break; + case rtf_keyword::rkw_fscript: + fnt.family=font::ff_cursive; + break; + case rtf_keyword::rkw_fdecor: + fnt.family=font::ff_fantasy; + break; + default: break; + } + break; + } + case '{': + in_font=true; + ++buf_in; + break; + case '}': + in_font=false; + fonttbl.insert(std::make_pair(font_num, fnt)); + fnt=font(); + full_name=false; + ++buf_in; + break; + case ';': + full_name=true; + ++buf_in; + break; + default: + if (!full_name && in_font) + fnt.name+=*buf_in; + ++buf_in; + break; + } + } + ++buf_in; + break; + } + // special characters + case rtf_keyword::rkw_line: case rtf_keyword::rkw_softline: + par_html.write("<br>"); + break; + case rtf_keyword::rkw_tab: + par_html.write(" "); // maybe, this can be done better + break; + case rtf_keyword::rkw_enspace: case rtf_keyword::rkw_emspace: + par_html.write(" "); + break; + case rtf_keyword::rkw_qmspace: + par_html.write(" "); + break; + case rtf_keyword::rkw_endash: + par_html.write("–"); + break; + case rtf_keyword::rkw_emdash: + par_html.write("—"); + break; + case rtf_keyword::rkw_bullet: + par_html.write("•"); + break; + case rtf_keyword::rkw_lquote: + par_html.write("‘"); + break; + case rtf_keyword::rkw_rquote: + par_html.write("’"); + break; + case rtf_keyword::rkw_ldblquote: + par_html.write("“"); + break; + case rtf_keyword::rkw_rdblquote: + par_html.write("”"); + break; + // paragraph formatting + case rtf_keyword::rkw_ql: + cur_options.papAlign=formatting_options::align_left; + break; + case rtf_keyword::rkw_qr: + cur_options.papAlign=formatting_options::align_right; + break; + case rtf_keyword::rkw_qc: + cur_options.papAlign=formatting_options::align_center; + break; + case rtf_keyword::rkw_qj: + cur_options.papAlign=formatting_options::align_justify; + break; + case rtf_keyword::rkw_fi: + cur_options.papFirst=(int)rint(kw.parameter()/20); + break; + case rtf_keyword::rkw_li: + cur_options.papLeft=(int)rint(kw.parameter()/20); + break; + case rtf_keyword::rkw_ri: + cur_options.papRight=(int)rint(kw.parameter()/20); + break; + case rtf_keyword::rkw_sb: + cur_options.papBefore=(int)rint(kw.parameter()/20); + break; + case rtf_keyword::rkw_sa: + cur_options.papAfter=(int)rint(kw.parameter()/20); + break; + case rtf_keyword::rkw_pard: + cur_options.papBefore=cur_options.papAfter=0; + cur_options.papLeft=cur_options.papRight=0; + cur_options.papFirst=0; + cur_options.papAlign=formatting_options::align_left; + cur_options.papInTbl=false; + break; + case rtf_keyword::rkw_par: + case rtf_keyword::rkw_sect: + t_str=cur_options.get_par_str()+par_html.str() + +" "+par_html.close()+"</p>\n"; + if (!bInTable) + { + html+=t_str; + } + else + { + if (cur_options.papInTbl) + { + tcCurCell->Text+=t_str; + } + else + { + html+=tblCurTable->make()+t_str; + bInTable=false; + tblCurTable=new table; + } + } + par_html.clear(); + break; + // character formatting + case rtf_keyword::rkw_super: + cur_options.chpVAlign= + kw.parameter()==0?formatting_options::va_normal + :formatting_options::va_sup; + break; + case rtf_keyword::rkw_sub: + cur_options.chpVAlign= + kw.parameter()==0?formatting_options::va_normal + :formatting_options::va_sub; + break; + case rtf_keyword::rkw_b: + cur_options.chpBold=!(kw.parameter()==0); + break; + case rtf_keyword::rkw_i: + cur_options.chpItalic=!(kw.parameter()==0); + break; + case rtf_keyword::rkw_ul: + cur_options.chpUnderline=!(kw.parameter()==0); + break; + case rtf_keyword::rkw_ulnone: + cur_options.chpUnderline=false; + break; + case rtf_keyword::rkw_fs: + cur_options.chpFontSize=kw.parameter(); + break; + case rtf_keyword::rkw_cf: + cur_options.chpFColor=colortbl[kw.parameter()]; + break; + case rtf_keyword::rkw_cb: + cur_options.chpBColor=colortbl[kw.parameter()]; + break; + case rtf_keyword::rkw_highlight: + cur_options.chpHighlight=kw.parameter(); + break; + case rtf_keyword::rkw_f: + cur_options.chpFont=fonttbl[kw.parameter()]; + break; + case rtf_keyword::rkw_plain: + cur_options.chpBold=cur_options.chpItalic + =cur_options.chpUnderline=false; + cur_options.chpVAlign=formatting_options::va_normal; + cur_options.chpFontSize=cur_options.chpHighlight=0; + cur_options.chpFColor=cur_options.chpBColor=color(); + cur_options.chpFont=font(); + break; + // table formatting + case rtf_keyword::rkw_intbl: + cur_options.papInTbl=true; + break; + case rtf_keyword::rkw_trowd: + CurCellDefs=CellDefsList.insert(CellDefsList.end(), + table_cell_defs()); + case rtf_keyword::rkw_row: + if (!trCurRow->Cells.empty()) + { + trCurRow->CellDefs=CurCellDefs; + if (trCurRow->Left==-1000) + trCurRow->Left=iLastRowLeft; + if (trCurRow->Height==-1000) + trCurRow->Height=iLastRowHeight; + tblCurTable->push_back(trCurRow); + trCurRow=new table_row; + } + bInTable=true; + break; + case rtf_keyword::rkw_cell: + t_str=cur_options.get_par_str()+par_html.str() + +" "+par_html.close()+"</p>\n"; + tcCurCell->Text+=t_str; + par_html.clear(); + trCurRow->Cells.push_back(tcCurCell); + tcCurCell=new table_cell; + break; + case rtf_keyword::rkw_cellx: + tcdCurCellDef->Right=kw.parameter(); + CurCellDefs->push_back(tcdCurCellDef); + tcdCurCellDef=new table_cell_def; + break; + case rtf_keyword::rkw_trleft: + trCurRow->Left=kw.parameter(); + iLastRowLeft=kw.parameter(); + break; + case rtf_keyword::rkw_trrh: + trCurRow->Height=kw.parameter(); + iLastRowHeight=kw.parameter(); + break; + case rtf_keyword::rkw_clvmgf: + tcdCurCellDef->FirstMerged=true; + break; + case rtf_keyword::rkw_clvmrg: + tcdCurCellDef->Merged=true; + break; + case rtf_keyword::rkw_clbrdrb: + tcdCurCellDef->BorderBottom=true; + tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderBottom); + break; + case rtf_keyword::rkw_clbrdrt: + tcdCurCellDef->BorderTop=true; + tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderTop); + break; + case rtf_keyword::rkw_clbrdrl: + tcdCurCellDef->BorderLeft=true; + tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderLeft); + break; + case rtf_keyword::rkw_clbrdrr: + tcdCurCellDef->BorderRight=true; + tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderRight); + break; + case rtf_keyword::rkw_brdrnone: + if (tcdCurCellDef->ActiveBorder!=NULL) + { + *(tcdCurCellDef->ActiveBorder)=false; + } + break; + case rtf_keyword::rkw_clvertalt: + tcdCurCellDef->VAlign=table_cell_def::valign_top; + break; + case rtf_keyword::rkw_clvertalc: + tcdCurCellDef->VAlign=table_cell_def::valign_center; + break; + case rtf_keyword::rkw_clvertalb: + tcdCurCellDef->VAlign=table_cell_def::valign_bottom; + break; + // page formatting + case rtf_keyword::rkw_paperw: + iDocWidth=kw.parameter(); + break; + case rtf_keyword::rkw_margl: + iMarginLeft=kw.parameter(); + break; + default: break; + } + } + break; + } + case '{': + // perform group opening actions here + foStack.push(cur_options); + ++buf_in; + break; + case '}': + // perform group closing actions here + cur_options=foStack.top(); + foStack.pop(); + ++buf_in; + break; + case 13: + case 10: + ++buf_in; + break; + case '<': + par_html.write("<"); + ++buf_in; + break; + case '>': + par_html.write(">"); + ++buf_in; + break; +/* case ' ': + par_html.write(" "); + ++buf_in; + break;*/ + default: + par_html.write(*buf_in++); + } + } + + t_str=cur_options.get_par_str()+par_html.str() + +" "+par_html.close()+"</p>\n"; + html+=t_str; + + delete tcCurCell; + delete trCurRow; + delete tblCurTable; + delete tcdCurCellDef; + + return html; +} + diff --git a/src/rtf2html/rtf2html.h b/src/rtf2html/rtf2html.h new file mode 100644 index 0000000..a4e1d2f --- /dev/null +++ b/src/rtf2html/rtf2html.h @@ -0,0 +1,28 @@ +/*************************************************************************** + copyright : (C) 2007 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 <qstring.h> + +namespace Tellico { + +class RTF2HTML { +public: + RTF2HTML(const QString& text); + + QString toHTML() const; + +private: + QString m_text; +}; + +} diff --git a/src/rtf2html/rtf_keyword.cpp b/src/rtf2html/rtf_keyword.cpp new file mode 100644 index 0000000..ee4774c --- /dev/null +++ b/src/rtf2html/rtf_keyword.cpp @@ -0,0 +1,107 @@ +/* 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_keyword.h" + +using namespace rtf; + +rtf_keyword::keyword_map::keyword_map() : base_class() +{ + insert(value_type("b", rkw_b)); + insert(value_type("bin", rkw_bin)); + insert(value_type("blue", rkw_blue)); + insert(value_type("brdrnone", rkw_brdrnone)); + insert(value_type("bullet", rkw_bullet)); + insert(value_type("cb", rkw_cb)); + insert(value_type("cell", rkw_cell)); + insert(value_type("cellx", rkw_cellx)); + insert(value_type("cf", rkw_cf)); + insert(value_type("clbrdrb", rkw_clbrdrb)); + insert(value_type("clbrdrl", rkw_clbrdrl)); + insert(value_type("clbrdrr", rkw_clbrdrr)); + insert(value_type("clbrdrt", rkw_clbrdrt)); + insert(value_type("clvertalb", rkw_clvertalb)); + insert(value_type("clvertalc", rkw_clvertalc)); + insert(value_type("clvertalt", rkw_clvertalt)); + insert(value_type("clvmgf", rkw_clvmgf)); + insert(value_type("clvmrg", rkw_clvmrg)); + insert(value_type("colortbl", rkw_colortbl)); + insert(value_type("emdash", rkw_emdash)); + insert(value_type("emspace", rkw_emspace)); + insert(value_type("endash", rkw_endash)); + insert(value_type("enspace", rkw_enspace)); + insert(value_type("f", rkw_f)); + insert(value_type("fprq", rkw_fprq)); + insert(value_type("fcharset", rkw_fcharset)); + insert(value_type("fnil", rkw_fnil)); + insert(value_type("froman", rkw_froman)); + insert(value_type("fswiss", rkw_fswiss)); + insert(value_type("fmodern", rkw_fmodern)); + insert(value_type("fscript", rkw_fscript)); + insert(value_type("fdecor", rkw_fdecor)); + insert(value_type("ftech", rkw_ftech)); + insert(value_type("fbidi", rkw_fbidi)); + insert(value_type("field", rkw_field)); + insert(value_type("filetbl", rkw_filetbl)); + insert(value_type("fldrslt", rkw_fldrslt)); + insert(value_type("fonttbl", rkw_fonttbl)); + insert(value_type("footer", rkw_footer)); + insert(value_type("footerf", rkw_footerf)); + insert(value_type("fs", rkw_fs)); + insert(value_type("green", rkw_green)); + insert(value_type("header", rkw_header)); + insert(value_type("headerf", rkw_headerf)); + insert(value_type("highlight", rkw_highlight)); + insert(value_type("i", rkw_i)); + insert(value_type("info", rkw_info)); + insert(value_type("intbl", rkw_intbl)); + insert(value_type("ldblquote", rkw_ldblquote)); + insert(value_type("li", rkw_li)); + insert(value_type("line", rkw_line)); + insert(value_type("lquote", rkw_lquote)); + insert(value_type("margl", rkw_margl)); + insert(value_type("object", rkw_object)); + insert(value_type("paperw", rkw_paperw)); + insert(value_type("par", rkw_par)); + insert(value_type("pard", rkw_pard)); + insert(value_type("pict", rkw_pict)); + insert(value_type("plain", rkw_plain)); + insert(value_type("qc", rkw_qc)); + insert(value_type("qj", rkw_qj)); + insert(value_type("ql", rkw_ql)); + insert(value_type("qr", rkw_qr)); + insert(value_type("rdblquote", rkw_rdblquote)); + insert(value_type("red", rkw_red)); + insert(value_type("ri", rkw_ri)); + insert(value_type("row", rkw_row)); + insert(value_type("rquote", rkw_rquote)); + insert(value_type("sa", rkw_sa)); + insert(value_type("sb", rkw_sb)); + insert(value_type("sect", rkw_sect)); + insert(value_type("softline", rkw_softline)); + insert(value_type("stylesheet", rkw_stylesheet)); + insert(value_type("sub", rkw_sub)); + insert(value_type("super", rkw_super)); + insert(value_type("tab", rkw_tab)); + insert(value_type("title", rkw_title)); + insert(value_type("trleft", rkw_trleft)); + insert(value_type("trowd", rkw_trowd)); + insert(value_type("trrh", rkw_trrh)); + insert(value_type("ul", rkw_ul)); + insert(value_type("ulnone", rkw_ulnone)); +} + +rtf_keyword::keyword_map rtf_keyword::keymap; diff --git a/src/rtf2html/rtf_keyword.h b/src/rtf2html/rtf_keyword.h new file mode 100644 index 0000000..c510ea0 --- /dev/null +++ b/src/rtf2html/rtf_keyword.h @@ -0,0 +1 @@ +/* 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; *
* *
***************************************************************************/
#ifndef __RTF_KEYWORD_H__
#define __RTF_KEYWORD_H__
#include <string>
#include <map>
#include <ctype.h>
#include <cstdlib>
namespace rtf {
class rtf_keyword{
public:
enum keyword_type {rkw_unknown,
rkw_b, rkw_bin, rkw_blue, rkw_brdrnone, rkw_bullet,
rkw_cb, rkw_cell, rkw_cellx, rkw_cf, rkw_clbrdrb, rkw_clbrdrl,
rkw_clbrdrr, rkw_clbrdrt, rkw_clvertalb, rkw_clvertalc,
rkw_clvertalt, rkw_clvmgf, rkw_clvmrg, rkw_colortbl,
rkw_emdash, rkw_emspace, rkw_endash, rkw_enspace,
rkw_fi, rkw_field, rkw_filetbl,
rkw_f, rkw_fprq, rkw_fcharset,
rkw_fnil, rkw_froman, rkw_fswiss, rkw_fmodern,
rkw_fscript, rkw_fdecor, rkw_ftech, rkw_fbidi,
rkw_fldrslt, rkw_fonttbl, rkw_footer, rkw_footerf, rkw_fs,
rkw_green,
rkw_header, rkw_headerf, rkw_highlight,
rkw_i, rkw_info, rkw_intbl,
rkw_ldblquote, rkw_li, rkw_line, rkw_lquote,
rkw_margl,
rkw_object,
rkw_paperw, rkw_par, rkw_pard, rkw_pict, rkw_plain,
rkw_qc, rkw_qj, rkw_ql, rkw_qmspace, rkw_qr,
rkw_rdblquote, rkw_red, rkw_ri, rkw_row, rkw_rquote,
rkw_sa, rkw_sb, rkw_sect, rkw_softline, rkw_stylesheet,
rkw_sub, rkw_super,
rkw_tab, rkw_title, rkw_trleft, rkw_trowd, rkw_trrh,
rkw_ul, rkw_ulnone
};
private:
class keyword_map : public std::map<std::string, keyword_type>
{
private:
typedef std::map<std::string, keyword_type> base_class;
public:
keyword_map();
};
private:
static keyword_map keymap;
std::string s_keyword;
keyword_type e_keyword;
int param;
char ctrl_chr;
bool is_ctrl_chr;
public:
// iter must point after the backslash starting the keyword. We don't check it.
// after construction, iter points at the char following the keyword
template <class InputIter> explicit rtf_keyword(InputIter &iter);
bool is_control_char() const
{ return is_ctrl_chr; }
const std::string &keyword_str() const
{ return s_keyword; }
keyword_type keyword() const
{ return e_keyword; }
int parameter() const
{ return param; }
char control_char() const
{ return ctrl_chr; }
};
template <class InputIter>
rtf_keyword::rtf_keyword(InputIter &iter)
{
char curchar=*iter;
is_ctrl_chr=!isalpha(curchar);
if (is_ctrl_chr)
{
ctrl_chr=curchar;
++iter;
}
else
{
do
s_keyword+=curchar;
while (isalpha(curchar=*++iter));
std::string param_str;
while (isdigit(curchar)||curchar=='-')
{
param_str+=curchar;
curchar=*++iter;
}
if (param_str.empty())
param=-1;
else
param=std::atoi(param_str.c_str());
if (curchar==' ')
++iter;
keyword_map::iterator kw_pos=keymap.find(s_keyword);
if (kw_pos==keymap.end())
e_keyword=rkw_unknown;
else
e_keyword=kw_pos->second;
}
}
}
#endif
\ No newline at end of file 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+=" "; + result+="</td>"; + } + } + result+="</tr>"; + } + result+="</table>"; + return result; +} diff --git a/src/rtf2html/rtf_table.h b/src/rtf2html/rtf_table.h new file mode 100644 index 0000000..927cc40 --- /dev/null +++ b/src/rtf2html/rtf_table.h @@ -0,0 +1,90 @@ +/* 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; * + * * + ***************************************************************************/ + +#ifndef __RTF_H__ +#define __RTF_H__ + +#include "common.h" +#include <vector> +#include <cmath> +#include <list> +#include <cstdlib> + +namespace rtf { + +struct table_cell +{ + int Rowspan; + std::string Text; + table_cell() : Rowspan(0) {} +}; + +struct table_cell_def +{ + enum valign {valign_top, valign_bottom, valign_center}; + bool BorderTop, BorderBottom, BorderLeft, BorderRight; + bool *ActiveBorder; + int Right, Left; + bool Merged, FirstMerged; + valign VAlign; + table_cell_def() + { + BorderTop=BorderBottom=BorderLeft=BorderRight=Merged=FirstMerged=false; + ActiveBorder=NULL; + Right=Left=0; + VAlign=valign_top; + } + bool right_equals(int x) { return x==Right; } + bool left_equals(int x) { return x==Left; } +}; + +template <class T> +class killing_ptr_vector : public std::vector<T*> +{ + public: + ~killing_ptr_vector() + { + for (typename killing_ptr_vector<T>::iterator i=this->begin(); i!=this->end(); ++i) + delete *i; + } +}; + +typedef killing_ptr_vector<table_cell> table_cells; +typedef killing_ptr_vector<table_cell_def> table_cell_defs; + +typedef std::list<table_cell_defs> table_cell_defs_list; + +struct table_row +{ + table_cells Cells; + table_cell_defs_list::iterator CellDefs; + int Height; + int Left; + table_row() : Height(-1000), Left(-1000) {} +}; + +class table : public killing_ptr_vector<table_row> +{ + private: + typedef killing_ptr_vector<table_row> base_class; + public: + table() : base_class() {} + std::string make(); +}; + +} + +#endif diff --git a/src/rtf2html/rtf_tools.h b/src/rtf2html/rtf_tools.h new file mode 100644 index 0000000..528549e --- /dev/null +++ b/src/rtf2html/rtf_tools.h @@ -0,0 +1,65 @@ +/* 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; * + * * + ***************************************************************************/ + +#ifndef __RTF_TOOLS_H__ +#define __RTF_TOOLS_H__ + +#include "common.h" +#include "rtf_keyword.h" + +namespace rtf { + +template <class InputIter> +void skip_group(InputIter &iter); + + +/**************************************** +function assumes that file pointer points AFTER the opening brace +and that the group is really closed. cs is caller's curchar. +Returns the character that comes after the enclosing brace. +*****************************************/ + +template <class InputIter> +void skip_group(InputIter &iter) +{ + int cnt=1; + while (cnt) + { + switch (*iter++) + { + case '{': + cnt++; + break; + case '}': + cnt--; + break; + case '\\': + { + rtf_keyword kw(iter); + if (!kw.is_control_char() && kw.keyword()==rtf_keyword::rkw_bin + && kw.parameter()>0) + { + std::advance(iter, kw.parameter()); + } + break; + } + } + } +} + +} + +#endif |