/* This is RTF to HTML converter, implemented as a text filter, generally. Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. 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 */ /* ��� ��������� RTF � HTML, �������������, � ��������, ��� ��������� ������. Copyright (C) 2003 �������� ����������, vlavrinenko@users.sourceforge.net ������ ���������� �������� ��������� ����������� ������������. �� ������ �������������� �� �/��� �������������� � ������������ � ��������� ������ 2.1 ���� �� ������ ������ � ��������� ����� ������� ������ ����������� ������������ �������� ������������� ���������� GNU, �������������� Free Software Foundation. �� �������������� ��� ���������� � ������� �� ��, ��� ��� ����� ��� ��������, ������ �� ������������� �� ��� ������� ��������, � ��� ����� �������� ��������� ��������� ��� ������� � ����������� ��� ������������� � ���������� �����. ��� ��������� ����� ��������� ���������� ������������ �� ����������� ������������ ��������� ������������� ���������� GNU. ������ � ������ ����������� �� ������ ���� �������� ��������� ����������� ������������ �������� ������������� ���������� GNU. ���� �� ��� �� ��������, �������� �� ���� �� Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #include "rtf_table.h" #include "rtf_tools.h" #include "rtf_keyword.h" #include "fmt_opts.h" #include #include #include #include #include QString rtf2html(const QString& iString) { QString oString; try { std::string str_in = iString.toStdString(); 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; } 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<"); 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()+"

\n"; if (!bInTable) { html+=t_str; } else { if (cur_options.papInTbl) { tcCurCell->Text+=t_str; } else { html+=tblCurTable->make()+t_str; bInTable=false; delete tblCurTable; 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()+"

\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; } } 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++); } } QString qTitle(QString::fromStdString(title)); QString qHtml(QString::fromStdString(html)); oString = QString("" "%3\n" "%4" ) .arg(rint(iMarginLeft/20)) .arg(rint((iDocWidth/20))) .arg(qTitle) .arg(qHtml); delete tcCurCell; delete trCurRow; delete tblCurTable; delete tcdCurCellDef; return oString; } catch (std::exception &e) { std::cerr<<"Error: "<