summaryrefslogtreecommitdiffstats
path: root/filters/kword/latex/export/para.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'filters/kword/latex/export/para.cpp')
-rw-r--r--filters/kword/latex/export/para.cpp680
1 files changed, 680 insertions, 0 deletions
diff --git a/filters/kword/latex/export/para.cpp b/filters/kword/latex/export/para.cpp
new file mode 100644
index 000000000..9cc829b57
--- /dev/null
+++ b/filters/kword/latex/export/para.cpp
@@ -0,0 +1,680 @@
+/*
+** A program to convert the XML rendered by KWord into LATEX.
+**
+** Copyright (C) 2000, 2001, 2002 Robert JACOLIN
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Library General Public
+** License as published by the Free Software Foundation; either
+** version 2 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
+** Library General Public License for more details.
+**
+** To receive a copy of the GNU Library General Public License, write to the
+** Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+**
+*/
+
+#include <stdlib.h> /* for atoi function */
+#include <kdebug.h> /* for kdDebug() stream */
+#include "para.h"
+#include "textFrame.h" /* father class. */
+#include "format.h" /* children classes. */
+//#include "picturezone.h"
+#include "fileheader.h"
+#include "textzone.h"
+#include "variablezone.h"
+#include "footnote.h"
+#include "anchor.h"
+
+/* static data */
+TQPtrStack<EType> Para::_historicList;
+int Para::_tabulation = 0;
+
+/*******************************************/
+/* Constructor */
+/*******************************************/
+Para::Para(TextFrame* textFrame)
+{
+ _element = textFrame;
+ _lines = 0;
+ _name = 0;
+ _info = EP_NONE; /* the parag is not a footnote */
+ //_hardbrk = EP_FLOW; /* and it's not a new page */
+ _currentPos = 0; /* At the beginning of the paragraph */
+ _tabulation = 0;
+ _text = "";
+}
+
+/*******************************************/
+/* Destructor */
+/*******************************************/
+Para::~Para()
+{
+ kdDebug(30522) << "Destruction of a parag." << endl;
+ if(_lines != 0)
+ delete _lines;
+}
+
+/*******************************************/
+/* GetFrameType */
+/*******************************************/
+/* To know if it's the text or it's a */
+/* header or a footer. */
+/*******************************************/
+SSect Para::getFrameType() const
+{
+ return _element->getSection();
+}
+
+/*******************************************/
+/* getTypeFormat */
+/*******************************************/
+/* To know if the zone is a textzone, a */
+/* footnote, a picture, a variable. */
+/*******************************************/
+EFormat Para::getTypeFormat(const TQDomNode balise) const
+{
+ //<FORMAT id="1" ...>
+
+ return (EFormat) getAttr(balise, "id").toInt();
+}
+
+/*******************************************/
+/* getNbCharPara */
+/*******************************************/
+/* To know the size of a paragraph. */
+/*******************************************/
+int Para::getNbCharPara() const
+{
+ int nb = 0;
+ Format* zone = 0;
+
+ if(_lines != 0)
+ {
+ kdDebug(30522) << " NB ZONE : " << _lines->count() << endl;
+
+ for(zone = _lines->first(); zone != 0; zone = _lines->next())
+ {
+ switch(zone->getId())
+ {
+ case EF_TEXTZONE:
+ nb = nb + ((TextZone*) zone)->getSize();
+ break;
+ case EF_PICTURE:
+ break;
+ case EF_TABULATOR:
+ break;
+ case EF_VARIABLE:
+ break;
+ case EF_FOOTNOTE:
+ break;
+ case EF_ANCHOR:
+ break;
+ case EF_ERROR:
+ break;
+ }
+ }
+ }
+ return nb;
+}
+
+/*******************************************/
+/* Analyse */
+/*******************************************/
+void Para::analyse(const TQDomNode balise)
+{
+ /* MARKUP TYPE : PARAGRAPH */
+
+ kdDebug(30522) << "**** PARAGRAPH ****" << endl;
+
+ /* Analyse of the children markups */
+ for(int index = 0; index < getNbChild(balise); index++)
+ {
+ if(getChildName(balise, index).compare("TEXT")== 0)
+ {
+ _text = getData(balise, index);
+ kdDebug(30522) << "TEXT : " << _text << endl;
+ }
+ else if(getChildName(balise, index).compare("NAME")== 0)
+ {
+ analyseName(getChild(balise, index));
+ }
+ else if(getChildName(balise, index).compare("INFO")== 0)
+ {
+ analyseInfo(getChild(balise, index));
+ }
+ /*else if(getChildName(balise, index).compare("HARDBRK")== 0)
+ {
+ analyseBrk(getChild(balise, index));
+ }*/
+ else if(getChildName(balise, index).compare("FORMATS")== 0)
+ {
+ // IMPORTANT ==> police + style
+ kdDebug(30522) << "FORMATS" << endl;
+ analyseFormats(getChild(balise, index));
+
+ }
+ else if(getChildName(balise, index).compare("LAYOUT")== 0)
+ {
+ kdDebug(30522) << "LAYOUT" << endl;
+ analyseLayoutPara(getChild(balise, index));
+ }
+ }
+ kdDebug(30522) << " **** END PARAGRAPH ****" << endl;
+}
+
+/*******************************************/
+/* AnalyseName */
+/*******************************************/
+/* If a footnote have a name : it's a */
+/* footnote/endnote. */
+/*******************************************/
+void Para::analyseName(const TQDomNode balise)
+{
+ /* <NAME name="Footnote/Endnote_1"> */
+
+ _name = new TQString(getAttr(balise, "NAME"));
+}
+
+/*******************************************/
+/* AnalyseInfo */
+/*******************************************/
+/* Type of the parag. : if info is 1, it's */
+/* a footnote/endnote (so it have a name). */
+/*******************************************/
+void Para::analyseInfo(const TQDomNode balise)
+{
+ /* <INFO info="1"> */
+
+ _info = (EP_INFO) getAttr(balise, "INFO").toInt();
+}
+
+/*******************************************/
+/* AnalyseBrk */
+/*******************************************/
+/* There is a new page before this */
+/* paragraph. */
+/*******************************************/
+/*void Para::analyseBrk(const TQDomNode balise)
+{
+ //<NAME name="Footnote/Endnote_1">
+
+ _hardbrk = (EP_HARDBRK) getAttr(balise, "FRAME").toInt();
+}*/
+
+/*******************************************/
+/* AnalyseLayoutPara */
+/*******************************************/
+/* Analyse the layout of a para. */
+/* For each format, keep the type (picture,*/
+/* text, variable, footnote) and put the */
+/* zone in a list. */
+/*******************************************/
+void Para::analyseLayoutPara(const TQDomNode balise)
+{
+ Format* zone = 0;
+
+ analyseLayout(balise);
+ for(int index= 0; index < getNbChild(balise); index++)
+ {
+ if(getChildName(balise, index).compare("FORMAT")== 0)
+ {
+ //analyseFormat(balise);
+ /* No more format : verify if all the text zone has been formated */
+ if(_currentPos != _text.length())
+ {
+ zone = new TextZone(_text, this);
+ ((TextZone*) zone)->setPos(_currentPos);
+ ((TextZone*) zone)->setLength(_currentPos - _text.length());
+ ((TextZone*) zone)->analyse();
+ if(_lines == 0)
+ _lines = new TQPtrList<Format>;
+ /* add the text */
+ _lines->append(zone);
+ _currentPos = _currentPos + ((TextZone*) zone)->getLength();
+
+ }
+ }
+ /*else
+ kdDebug(30522) << " FORMAT FIELD UNKNOWN" << endl;*/
+ }
+}
+
+/*******************************************/
+/* AnalyseFormats */
+/*******************************************/
+/* Analyse several formats. */
+/* keep the type (picture, text, variable,*/
+/* footnote) and put the zone in a list. */
+/*******************************************/
+void Para::analyseFormats(const TQDomNode balise)
+{
+ for(int index= 0; index < getNbChild(balise, "FORMAT"); index++)
+ {
+ if(getChildName(balise, index).compare("FORMAT")== 0)
+ {
+ kdDebug(30522) << "A FORMAT !!!" << endl;
+ analyseFormat(getChild(balise, index));
+ }
+ else
+ kdDebug(30522) << " FORMAT UNUSEFULL HERE" << endl;
+ }
+}
+
+/*******************************************/
+/* AnalyseFormat */
+/*******************************************/
+/* Analyse one format. */
+/* keep the type (picture, text, variable,*/
+/* footnote) and put the zone in a list. */
+/*******************************************/
+void Para::analyseFormat(const TQDomNode balise)
+{
+ Format *zone = 0;
+ Format *zoneFirst = 0;
+
+ kdDebug(30522) << "ANALYSE FORMAT BODY" << endl;
+ switch(getTypeFormat(balise))
+ {
+ case EF_ERROR: kdDebug(30522) << "Id format error" << endl;
+ break;
+ case EF_TEXTZONE: /* It's a text line (1) */
+ zone = new TextZone(_text, this);
+ if(_currentPos != _text.length())
+ {
+ zone->analyse(balise);
+ if(zone->getPos() != _currentPos)
+ {
+ if(_lines == 0)
+ _lines = new TQPtrList<Format>;
+ /* Create first a default format */
+ zoneFirst = new TextZone(_text, this);
+ zoneFirst->setPos(_currentPos);
+ zoneFirst->setLength(zone->getPos() - _currentPos);
+ ((TextZone*) zoneFirst)->analyse();
+
+ /* Add the text without format */
+ _lines->append(zoneFirst);
+ _currentPos = _currentPos + ((TextZone*) zoneFirst)->getLength();
+ }
+ }
+ break;
+ case EF_PICTURE: /* It's a picture (2) */
+ /*zone = new PictureZone(this);
+ zone->analyse(balise);*/
+ break;
+ case EF_VARIABLE: /* It's a variable (4) */
+ zone = new VariableZone(this);
+ zone->analyse(balise);
+ break;
+ case EF_FOOTNOTE: /* It's a footnote (5) */
+ zone = new Footnote(this);
+ zone->analyse(balise);
+ break;
+ case EF_ANCHOR: /* It's an anchor (6) */
+ zone = new Anchor(this);
+ zone->analyse(balise);
+ break;
+ default: /* Unknown */
+ kdDebug(30522) << "Format not yet supported" << endl;
+ }
+
+ if(zone->getPos() != _currentPos)
+ {
+ if(_lines == 0)
+ _lines = new TQPtrList<Format>;
+ /* Create first a default format */
+ zoneFirst = new TextZone(_text, this);
+ zoneFirst->setPos(_currentPos);
+ zoneFirst->setLength(zone->getPos() - _currentPos);
+ ((TextZone*) zoneFirst)->analyse();
+ kdDebug(30522) << "pos courante : " << _currentPos << endl;
+ /* Add the text without format */
+ _lines->append(zoneFirst);
+ _currentPos = _currentPos + zoneFirst->getLength();
+ }
+
+ if(zone != 0)
+ {
+ if(_lines == 0)
+ _lines = new TQPtrList<Format>;
+
+ /* add the text */
+ _lines->append(zone);
+ _currentPos = _currentPos + zone->getLength();
+ }
+}
+
+/*******************************************/
+/* Generate */
+/*******************************************/
+/* Generate each text zone with the parag. */
+/* markup. */
+/*******************************************/
+void Para::generate(TQTextStream &out)
+{
+
+ kdDebug(30522) << " GENERATION PARA" << endl;
+
+ if(getInfo() != EP_FOOTNOTE && getFrameType() != SS_HEADERS &&
+ getFrameType() != SS_FOOTERS)
+ {
+ /* We generate center, itemize tag and new page only for
+ * parag not for footnote
+ * If a parag. have a special format (begining)
+ */
+ if(isHardBreak())
+ out << "\\newpage" << endl;
+ generateDebut(out);
+ }
+
+ /* If text is a \n, then it's a break line. */
+ if(_text == "\n")
+ out << "\\\\" << endl;
+ else if(_lines != 0)
+ {
+ Format* zone = 0;
+ kdDebug(30522) << " NB ZONE : " << _lines->count() << endl;
+
+ for(zone = _lines->first(); zone != 0; zone = _lines->next())
+ {
+ zone->generate(out);
+ }
+ /* To separate the text zones. */
+ }
+
+ if(getInfo() != EP_FOOTNOTE && getFrameType() != SS_HEADERS &&
+ getFrameType() != SS_FOOTERS)
+ {
+ /* id than above : a parag. have a special format. (end)
+ * only it's not a header, nor a footer nor a footnote/endnote
+ */
+ generateFin(out);
+ if(isHardBreakAfter())
+ out << "\\newpage" << endl;
+ }
+ kdDebug(30522) << "PARA GENERATED" << endl;
+}
+
+/*******************************************/
+/* GenerateDebut */
+/*******************************************/
+/* Generate the begining paragraph markup. */
+/*******************************************/
+void Para::generateDebut(TQTextStream &out)
+{
+ /* Be careful we are in a table !
+ * You can't use directly environment, ...
+ */
+ if(getFrameType() == SS_TABLE)
+ {
+ //int sizeCell = 5;
+ /* first number depends with the cell size (next number}
+ * and with the number of characters in the para.
+ * It can be 20 char. / 5 cm = 4 char / cm so */
+ /* nbLines = nb_char_para / (4 * cell size) + 1 */
+ //sizeCell = (_element->getRight() - _element->getLeft()) / 27;
+ //kdDebug(30522) << "SIZE OF CELL : " << sizeCell << endl;
+ // TODO : arrondir au superieur avec tgmath.h ??
+ //_nbLines = ((_element->getBottom() - _element->getTop()) / 27) + 1;
+ //kdDebug(30522) << "NB OF LINES : " << _nbLines << endl;
+ /* 2 at least, 1 for the line, 1 for the space line */
+ /*if(_nbLines < 2)
+ _nbLines = 2;
+ out << "\\multirow{" << _nbLines << "}{"<< sizeCell << "cm}{" << endl;*/
+ }
+ /* if it's a chapter */
+ if(isChapter())
+ {
+ /* switch the type, the depth do */
+ generateTitle(out);
+ Config::instance()->indent();
+ }
+ else if(isEnum())
+ {
+ Config::instance()->writeIndent(out);
+ out << "\\item ";
+ }
+ else
+ Config::instance()->writeIndent(out);
+}
+
+void Para::generateBeginEnv(TQTextStream &out)
+{
+ kdDebug(30522) << "Begin new Env : " << getEnv() << endl;
+
+ Config::instance()->writeIndent(out);
+
+ switch(getEnv())
+ {
+ case ENV_LEFT: out << "\\begin{flushleft}" << endl;
+ break;
+ case ENV_RIGHT: out << "\\begin{flushright}" << endl;
+ break;
+ case ENV_CENTER: out << "\\begin{center}" << endl;
+ break;
+ case ENV_JUSTIFY: out << endl;
+ break;
+ case ENV_NONE:
+ break;
+ }
+
+ Config::instance()->indent();
+}
+
+/*******************************************/
+/* openList */
+/*******************************************/
+/* Generate the markup to begin a list and */
+/* push the type in the historic stack. */
+/*******************************************/
+void Para::openList(TQTextStream &out)
+{
+ EType *type_temp = 0;
+
+ Config::instance()->writeIndent(out);
+
+ switch(getCounterType())
+ {
+ case TL_NONE:
+ break;
+ case TL_ARABIC:
+ out << "\\begin{enumerate}" << endl;
+ break;
+ case TL_LLETTER: /* a, b, ... */
+ out << "\\begin{enumerate}[a]" << endl;
+ break;
+ case TL_CLETTER: /* A, B, ... */
+ out << "\\begin{enumerate}[A]" << endl;
+ break;
+ case TL_LLNUMBER: /* i, ii, ... */
+ out << "\\begin{enumerate}[i]" << endl;
+ break;
+ case TL_CLNUMBER: /* I, II, ... */
+ out << "\\begin{enumerate}[I]" << endl;
+ break;
+ case TL_CUSTOM_SIMPLE: /* - */
+ out << "\\begin{enumerate}[" << convertSpecialChar(getCounterBullet()) << "]" << endl;
+ break;
+ case TL_CUSTOM_COMPLEX: /* - */
+ out << "\\begin{enumerate}[" << convertSpecialChar(getCounterBullet()) << "]" << endl;
+ break;
+ case TL_CIRCLE_BULLET:
+ out << "\\begin{itemize}" << endl;
+ break;
+ case TL_SQUARE_BULLET:
+ out << "\\begin{itemize}" << endl;
+ break;
+ case TL_DISC_BULLET:
+ out << "\\begin{itemize}" << endl;
+ break;
+ default:
+ out << "\\begin{itemize}[SPECIAL]" << endl;
+ }
+
+ Config::instance()->indent();
+
+ /* Keep the list type */
+ type_temp = new EType(getCounterType());
+ kdDebug(30522) << " type list to open : " << *type_temp << endl;
+ _historicList.push(type_temp);
+}
+
+/*******************************************/
+/* GenerateFin */
+/*******************************************/
+/* Generate the closing paragraph markup. */
+/*******************************************/
+void Para::generateFin(TQTextStream &out)
+{
+ /* Close a title of chapter */
+ if(isChapter())
+ out << "}";
+}
+
+/*******************************************/
+/* GenerateEndEnv */
+/*******************************************/
+/* Generate the closing environment markup.*/
+/*******************************************/
+void Para::generateEndEnv(TQTextStream &out)
+{
+ kdDebug(30522) << "end of an environment : " << getEnv() << endl;
+
+ Config::instance()->desindent();
+
+ switch(getEnv())
+ {
+ case ENV_LEFT:
+ out << endl;
+ Config::instance()->writeIndent(out);
+ out << "\\end{flushleft}";
+ break;
+ case ENV_RIGHT:
+ out << endl;
+ Config::instance()->writeIndent(out);
+ out << "\\end{flushright}";
+ break;
+ case ENV_CENTER:
+ out << endl;
+ Config::instance()->writeIndent(out);
+ out << "\\end{center}";
+ break;
+ case ENV_JUSTIFY:
+ break;
+ case ENV_NONE:
+ break;
+ }
+
+ Config::instance()->desindent();
+}
+
+/*******************************************/
+/* closeList */
+/*******************************************/
+/* Generate the closing list markup for a */
+/* list type (letter, custom, ...) and */
+/* remove the last list saved. */
+/*******************************************/
+void Para::closeList(TQTextStream &out, Para* next)
+{
+ closeList(getCounterType(), out);
+
+ if(((getCounterDepth() - 1) >= 0) && ((next!= 0 && !next->isEnum()) || next == 0))
+ {
+ /* We must close all the lists since
+ * after this paragraph it's a normal paragraph.
+ */
+ kdDebug(30522) << "lists to close" << endl;
+ while(!_historicList.isEmpty())
+ {
+ EType *type_temp = 0;
+ type_temp = _historicList.pop();
+ if(type_temp != 0)
+ closeList(*type_temp, out);
+ }
+ }
+}
+
+/*******************************************/
+/* closeList */
+/*******************************************/
+/* Generate the closing list markup for a */
+/* list type (letter, custom, ...) and */
+/* remove the last list saved. */
+/*******************************************/
+void Para::closeList(EType type, TQTextStream &out)
+{
+ //out << endl;
+ kdDebug(30522) << " type list to close : " << type << endl;
+
+ /* Because of a new markup, we need a new line. */
+ out << endl;
+
+ Config::instance()->desindent();
+ Config::instance()->writeIndent(out);
+
+ /* but the next parag is not a same list */
+ switch(type)
+ {
+ case TL_NONE: //out << endl;
+ break;
+ case TL_ARABIC:
+ case TL_LLETTER: /* a, b, ... */
+ case TL_CLETTER: /* A, B, ... P. 250*/
+ case TL_LLNUMBER: /* i, ii, ... */
+ case TL_CLNUMBER: /* I, II, ... */
+ case TL_CUSTOM_SIMPLE: /* - */
+ case TL_CUSTOM_COMPLEX: /* - */
+ out << "\\end{enumerate}" << endl;
+ break;
+ case TL_CIRCLE_BULLET:
+ out << "\\end{itemize}" << endl;
+ break;
+ case TL_SQUARE_BULLET:
+ case TL_DISC_BULLET:
+ out << "\\end{itemize}" << endl;
+ break;
+ default:
+ out << "no suported" << endl;
+ }
+
+ Config::instance()->writeIndent(out);
+
+ /* Pop the list which has been closed */
+ _historicList.remove();
+ kdDebug(30522) << "removed" << endl;
+}
+
+/*******************************************/
+/* GenerateTitle */
+/*******************************************/
+void Para::generateTitle(TQTextStream &out)
+{
+ switch(getCounterDepth())
+ {
+ case 0:
+ out << "\\section{";
+ break;
+ case 1:
+ out << "\\subsection{";
+ break;
+ case 2:
+ out << "\\subsubsection{";
+ break;
+ case 3:
+ out << "\\paragraph{";
+ break;
+ case 4:
+ out << "\\subparagraph{";
+ break;
+ case 5:
+ out << "% section too deep" << endl;
+ out << "\\textbf{";
+ }
+}