filters

para.cpp
1/*
2** A program to convert the XML rendered by KWord into LATEX.
3**
4** Copyright (C) 2000, 2001, 2002 Robert JACOLIN
5**
6** This library is free software; you can redistribute it and/or
7** modify it under the terms of the GNU Library General Public
8** License as published by the Free Software Foundation; either
9** version 2 of the License, or (at your option) any later version.
10**
11** This library is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** Library General Public License for more details.
15**
16** To receive a copy of the GNU Library General Public License, write to the
17** Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19**
20*/
21
22#include <stdlib.h> /* for atoi function */
23#include <kdebug.h> /* for kdDebug() stream */
24#include "para.h"
25#include "textFrame.h" /* father class. */
26#include "format.h" /* children classes. */
27//#include "picturezone.h"
28#include "fileheader.h"
29#include "textzone.h"
30#include "variablezone.h"
31#include "footnote.h"
32#include "anchor.h"
33
34/* static data */
35TQPtrStack<EType> Para::_historicList;
36int Para::_tabulation = 0;
37
38/*******************************************/
39/* Constructor */
40/*******************************************/
42{
43 _element = textFrame;
44 _lines = 0;
45 _name = 0;
46 _info = EP_NONE; /* the parag is not a footnote */
47 //_hardbrk = EP_FLOW; /* and it's not a new page */
48 _currentPos = 0; /* At the beginning of the paragraph */
49 _tabulation = 0;
50 _text = "";
51}
52
53/*******************************************/
54/* Destructor */
55/*******************************************/
56Para::~Para()
57{
58 kdDebug(30522) << "Destruction of a parag." << endl;
59 if(_lines != 0)
60 delete _lines;
61}
62
63/*******************************************/
64/* GetFrameType */
65/*******************************************/
66/* To know if it's the text or it's a */
67/* header or a footer. */
68/*******************************************/
69SSect Para::getFrameType() const
70{
71 return _element->getSection();
72}
73
74/*******************************************/
75/* getTypeFormat */
76/*******************************************/
77/* To know if the zone is a textzone, a */
78/* footnote, a picture, a variable. */
79/*******************************************/
80EFormat Para::getTypeFormat(const TQDomNode balise) const
81{
82 //<FORMAT id="1" ...>
83
84 return (EFormat) getAttr(balise, "id").toInt();
85}
86
87/*******************************************/
88/* getNbCharPara */
89/*******************************************/
90/* To know the size of a paragraph. */
91/*******************************************/
93{
94 int nb = 0;
95 Format* zone = 0;
96
97 if(_lines != 0)
98 {
99 kdDebug(30522) << " NB ZONE : " << _lines->count() << endl;
100
101 for(zone = _lines->first(); zone != 0; zone = _lines->next())
102 {
103 switch(zone->getId())
104 {
105 case EF_TEXTZONE:
106 nb = nb + ((TextZone*) zone)->getSize();
107 break;
108 case EF_PICTURE:
109 break;
110 case EF_TABULATOR:
111 break;
112 case EF_VARIABLE:
113 break;
114 case EF_FOOTNOTE:
115 break;
116 case EF_ANCHOR:
117 break;
118 case EF_ERROR:
119 break;
120 }
121 }
122 }
123 return nb;
124}
125
126/*******************************************/
127/* Analyse */
128/*******************************************/
129void Para::analyse(const TQDomNode balise)
130{
131 /* MARKUP TYPE : PARAGRAPH */
132
133 kdDebug(30522) << "**** PARAGRAPH ****" << endl;
134
135 /* Analyse of the children markups */
136 for(int index = 0; index < getNbChild(balise); index++)
137 {
138 if(getChildName(balise, index).compare("TEXT")== 0)
139 {
140 _text = getData(balise, index);
141 kdDebug(30522) << "TEXT : " << _text << endl;
142 }
143 else if(getChildName(balise, index).compare("NAME")== 0)
144 {
145 analyseName(getChild(balise, index));
146 }
147 else if(getChildName(balise, index).compare("INFO")== 0)
148 {
149 analyseInfo(getChild(balise, index));
150 }
151 /*else if(getChildName(balise, index).compare("HARDBRK")== 0)
152 {
153 analyseBrk(getChild(balise, index));
154 }*/
155 else if(getChildName(balise, index).compare("FORMATS")== 0)
156 {
157 // IMPORTANT ==> police + style
158 kdDebug(30522) << "FORMATS" << endl;
159 analyseFormats(getChild(balise, index));
160
161 }
162 else if(getChildName(balise, index).compare("LAYOUT")== 0)
163 {
164 kdDebug(30522) << "LAYOUT" << endl;
165 analyseLayoutPara(getChild(balise, index));
166 }
167 }
168 kdDebug(30522) << " **** END PARAGRAPH ****" << endl;
169}
170
171/*******************************************/
172/* AnalyseName */
173/*******************************************/
174/* If a footnote have a name : it's a */
175/* footnote/endnote. */
176/*******************************************/
177void Para::analyseName(const TQDomNode balise)
178{
179 /* <NAME name="Footnote/Endnote_1"> */
180
181 _name = new TQString(getAttr(balise, "NAME"));
182}
183
184/*******************************************/
185/* AnalyseInfo */
186/*******************************************/
187/* Type of the parag. : if info is 1, it's */
188/* a footnote/endnote (so it have a name). */
189/*******************************************/
190void Para::analyseInfo(const TQDomNode balise)
191{
192 /* <INFO info="1"> */
193
194 _info = (EP_INFO) getAttr(balise, "INFO").toInt();
195}
196
197/*******************************************/
198/* AnalyseBrk */
199/*******************************************/
200/* There is a new page before this */
201/* paragraph. */
202/*******************************************/
203/*void Para::analyseBrk(const TQDomNode balise)
204{
205 //<NAME name="Footnote/Endnote_1">
206
207 _hardbrk = (EP_HARDBRK) getAttr(balise, "FRAME").toInt();
208}*/
209
210/*******************************************/
211/* AnalyseLayoutPara */
212/*******************************************/
213/* Analyse the layout of a para. */
214/* For each format, keep the type (picture,*/
215/* text, variable, footnote) and put the */
216/* zone in a list. */
217/*******************************************/
218void Para::analyseLayoutPara(const TQDomNode balise)
219{
220 Format* zone = 0;
221
222 analyseLayout(balise);
223 for(int index= 0; index < getNbChild(balise); index++)
224 {
225 if(getChildName(balise, index).compare("FORMAT")== 0)
226 {
227 //analyseFormat(balise);
228 /* No more format : verify if all the text zone has been formated */
229 if(_currentPos != _text.length())
230 {
231 zone = new TextZone(_text, this);
232 ((TextZone*) zone)->setPos(_currentPos);
233 ((TextZone*) zone)->setLength(_currentPos - _text.length());
234 ((TextZone*) zone)->analyse();
235 if(_lines == 0)
236 _lines = new TQPtrList<Format>;
237 /* add the text */
238 _lines->append(zone);
239 _currentPos = _currentPos + ((TextZone*) zone)->getLength();
240
241 }
242 }
243 /*else
244 kdDebug(30522) << " FORMAT FIELD UNKNOWN" << endl;*/
245 }
246}
247
248/*******************************************/
249/* AnalyseFormats */
250/*******************************************/
251/* Analyse several formats. */
252/* keep the type (picture, text, variable,*/
253/* footnote) and put the zone in a list. */
254/*******************************************/
255void Para::analyseFormats(const TQDomNode balise)
256{
257 for(int index= 0; index < getNbChild(balise, "FORMAT"); index++)
258 {
259 if(getChildName(balise, index).compare("FORMAT")== 0)
260 {
261 kdDebug(30522) << "A FORMAT !!!" << endl;
262 analyseFormat(getChild(balise, index));
263 }
264 else
265 kdDebug(30522) << " FORMAT UNUSEFULL HERE" << endl;
266 }
267}
268
269/*******************************************/
270/* AnalyseFormat */
271/*******************************************/
272/* Analyse one format. */
273/* keep the type (picture, text, variable,*/
274/* footnote) and put the zone in a list. */
275/*******************************************/
276void Para::analyseFormat(const TQDomNode balise)
277{
278 Format *zone = 0;
279 Format *zoneFirst = 0;
280
281 kdDebug(30522) << "ANALYSE FORMAT BODY" << endl;
282 switch(getTypeFormat(balise))
283 {
284 case EF_ERROR: kdDebug(30522) << "Id format error" << endl;
285 break;
286 case EF_TEXTZONE: /* It's a text line (1) */
287 zone = new TextZone(_text, this);
288 if(_currentPos != _text.length())
289 {
290 zone->analyse(balise);
291 if(zone->getPos() != _currentPos)
292 {
293 if(_lines == 0)
294 _lines = new TQPtrList<Format>;
295 /* Create first a default format */
296 zoneFirst = new TextZone(_text, this);
297 zoneFirst->setPos(_currentPos);
298 zoneFirst->setLength(zone->getPos() - _currentPos);
299 ((TextZone*) zoneFirst)->analyse();
300
301 /* Add the text without format */
302 _lines->append(zoneFirst);
303 _currentPos = _currentPos + ((TextZone*) zoneFirst)->getLength();
304 }
305 }
306 break;
307 case EF_PICTURE: /* It's a picture (2) */
308 /*zone = new PictureZone(this);
309 zone->analyse(balise);*/
310 break;
311 case EF_VARIABLE: /* It's a variable (4) */
312 zone = new VariableZone(this);
313 zone->analyse(balise);
314 break;
315 case EF_FOOTNOTE: /* It's a footnote (5) */
316 zone = new Footnote(this);
317 zone->analyse(balise);
318 break;
319 case EF_ANCHOR: /* It's an anchor (6) */
320 zone = new Anchor(this);
321 zone->analyse(balise);
322 break;
323 default: /* Unknown */
324 kdDebug(30522) << "Format not yet supported" << endl;
325 }
326
327 if(zone->getPos() != _currentPos)
328 {
329 if(_lines == 0)
330 _lines = new TQPtrList<Format>;
331 /* Create first a default format */
332 zoneFirst = new TextZone(_text, this);
333 zoneFirst->setPos(_currentPos);
334 zoneFirst->setLength(zone->getPos() - _currentPos);
335 ((TextZone*) zoneFirst)->analyse();
336 kdDebug(30522) << "pos courante : " << _currentPos << endl;
337 /* Add the text without format */
338 _lines->append(zoneFirst);
339 _currentPos = _currentPos + zoneFirst->getLength();
340 }
341
342 if(zone != 0)
343 {
344 if(_lines == 0)
345 _lines = new TQPtrList<Format>;
346
347 /* add the text */
348 _lines->append(zone);
349 _currentPos = _currentPos + zone->getLength();
350 }
351}
352
353/*******************************************/
354/* Generate */
355/*******************************************/
356/* Generate each text zone with the parag. */
357/* markup. */
358/*******************************************/
359void Para::generate(TQTextStream &out)
360{
361
362 kdDebug(30522) << " GENERATION PARA" << endl;
363
364 if(getInfo() != EP_FOOTNOTE && getFrameType() != SS_HEADERS &&
365 getFrameType() != SS_FOOTERS)
366 {
367 /* We generate center, itemize tag and new page only for
368 * parag not for footnote
369 * If a parag. have a special format (begining)
370 */
371 if(isHardBreak())
372 out << "\\newpage" << endl;
373 generateDebut(out);
374 }
375
376 /* If text is a \n, then it's a break line. */
377 if(_text == "\n")
378 out << "\\\\" << endl;
379 else if(_lines != 0)
380 {
381 Format* zone = 0;
382 kdDebug(30522) << " NB ZONE : " << _lines->count() << endl;
383
384 for(zone = _lines->first(); zone != 0; zone = _lines->next())
385 {
386 zone->generate(out);
387 }
388 /* To separate the text zones. */
389 }
390
391 if(getInfo() != EP_FOOTNOTE && getFrameType() != SS_HEADERS &&
392 getFrameType() != SS_FOOTERS)
393 {
394 /* id than above : a parag. have a special format. (end)
395 * only it's not a header, nor a footer nor a footnote/endnote
396 */
397 generateFin(out);
398 if(isHardBreakAfter())
399 out << "\\newpage" << endl;
400 }
401 kdDebug(30522) << "PARA GENERATED" << endl;
402}
403
404/*******************************************/
405/* GenerateDebut */
406/*******************************************/
407/* Generate the begining paragraph markup. */
408/*******************************************/
409void Para::generateDebut(TQTextStream &out)
410{
411 /* Be careful we are in a table !
412 * You can't use directly environment, ...
413 */
414 if(getFrameType() == SS_TABLE)
415 {
416 //int sizeCell = 5;
417 /* first number depends with the cell size (next number}
418 * and with the number of characters in the para.
419 * It can be 20 char. / 5 cm = 4 char / cm so */
420 /* nbLines = nb_char_para / (4 * cell size) + 1 */
421 //sizeCell = (_element->getRight() - _element->getLeft()) / 27;
422 //kdDebug(30522) << "SIZE OF CELL : " << sizeCell << endl;
423 // TODO : arrondir au superieur avec tgmath.h ??
424 //_nbLines = ((_element->getBottom() - _element->getTop()) / 27) + 1;
425 //kdDebug(30522) << "NB OF LINES : " << _nbLines << endl;
426 /* 2 at least, 1 for the line, 1 for the space line */
427 /*if(_nbLines < 2)
428 _nbLines = 2;
429 out << "\\multirow{" << _nbLines << "}{"<< sizeCell << "cm}{" << endl;*/
430 }
431 /* if it's a chapter */
432 if(isChapter())
433 {
434 /* switch the type, the depth do */
435 generateTitle(out);
436 Config::instance()->indent();
437 }
438 else if(isEnum())
439 {
440 Config::instance()->writeIndent(out);
441 out << "\\item ";
442 }
443 else
444 Config::instance()->writeIndent(out);
445}
446
447void Para::generateBeginEnv(TQTextStream &out)
448{
449 kdDebug(30522) << "Begin new Env : " << getEnv() << endl;
450
451 Config::instance()->writeIndent(out);
452
453 switch(getEnv())
454 {
455 case ENV_LEFT: out << "\\begin{flushleft}" << endl;
456 break;
457 case ENV_RIGHT: out << "\\begin{flushright}" << endl;
458 break;
459 case ENV_CENTER: out << "\\begin{center}" << endl;
460 break;
461 case ENV_JUSTIFY: out << endl;
462 break;
463 case ENV_NONE:
464 break;
465 }
466
467 Config::instance()->indent();
468}
469
470/*******************************************/
471/* openList */
472/*******************************************/
473/* Generate the markup to begin a list and */
474/* push the type in the historic stack. */
475/*******************************************/
476void Para::openList(TQTextStream &out)
477{
478 EType *type_temp = 0;
479
480 Config::instance()->writeIndent(out);
481
482 switch(getCounterType())
483 {
484 case TL_NONE:
485 break;
486 case TL_ARABIC:
487 out << "\\begin{enumerate}" << endl;
488 break;
489 case TL_LLETTER: /* a, b, ... */
490 out << "\\begin{enumerate}[a]" << endl;
491 break;
492 case TL_CLETTER: /* A, B, ... */
493 out << "\\begin{enumerate}[A]" << endl;
494 break;
495 case TL_LLNUMBER: /* i, ii, ... */
496 out << "\\begin{enumerate}[i]" << endl;
497 break;
498 case TL_CLNUMBER: /* I, II, ... */
499 out << "\\begin{enumerate}[I]" << endl;
500 break;
501 case TL_CUSTOM_SIMPLE: /* - */
502 out << "\\begin{enumerate}[" << convertSpecialChar(getCounterBullet()) << "]" << endl;
503 break;
504 case TL_CUSTOM_COMPLEX: /* - */
505 out << "\\begin{enumerate}[" << convertSpecialChar(getCounterBullet()) << "]" << endl;
506 break;
507 case TL_CIRCLE_BULLET:
508 out << "\\begin{itemize}" << endl;
509 break;
510 case TL_SQUARE_BULLET:
511 out << "\\begin{itemize}" << endl;
512 break;
513 case TL_DISC_BULLET:
514 out << "\\begin{itemize}" << endl;
515 break;
516 default:
517 out << "\\begin{itemize}[SPECIAL]" << endl;
518 }
519
520 Config::instance()->indent();
521
522 /* Keep the list type */
523 type_temp = new EType(getCounterType());
524 kdDebug(30522) << " type list to open : " << *type_temp << endl;
525 _historicList.push(type_temp);
526}
527
528/*******************************************/
529/* GenerateFin */
530/*******************************************/
531/* Generate the closing paragraph markup. */
532/*******************************************/
533void Para::generateFin(TQTextStream &out)
534{
535 /* Close a title of chapter */
536 if(isChapter())
537 out << "}";
538}
539
540/*******************************************/
541/* GenerateEndEnv */
542/*******************************************/
543/* Generate the closing environment markup.*/
544/*******************************************/
545void Para::generateEndEnv(TQTextStream &out)
546{
547 kdDebug(30522) << "end of an environment : " << getEnv() << endl;
548
549 Config::instance()->desindent();
550
551 switch(getEnv())
552 {
553 case ENV_LEFT:
554 out << endl;
555 Config::instance()->writeIndent(out);
556 out << "\\end{flushleft}";
557 break;
558 case ENV_RIGHT:
559 out << endl;
560 Config::instance()->writeIndent(out);
561 out << "\\end{flushright}";
562 break;
563 case ENV_CENTER:
564 out << endl;
565 Config::instance()->writeIndent(out);
566 out << "\\end{center}";
567 break;
568 case ENV_JUSTIFY:
569 break;
570 case ENV_NONE:
571 break;
572 }
573
574 Config::instance()->desindent();
575}
576
577/*******************************************/
578/* closeList */
579/*******************************************/
580/* Generate the closing list markup for a */
581/* list type (letter, custom, ...) and */
582/* remove the last list saved. */
583/*******************************************/
584void Para::closeList(TQTextStream &out, Para* next)
585{
586 closeList(getCounterType(), out);
587
588 if(((getCounterDepth() - 1) >= 0) && ((next!= 0 && !next->isEnum()) || next == 0))
589 {
590 /* We must close all the lists since
591 * after this paragraph it's a normal paragraph.
592 */
593 kdDebug(30522) << "lists to close" << endl;
594 while(!_historicList.isEmpty())
595 {
596 EType *type_temp = 0;
597 type_temp = _historicList.pop();
598 if(type_temp != 0)
599 closeList(*type_temp, out);
600 }
601 }
602}
603
604/*******************************************/
605/* closeList */
606/*******************************************/
607/* Generate the closing list markup for a */
608/* list type (letter, custom, ...) and */
609/* remove the last list saved. */
610/*******************************************/
611void Para::closeList(EType type, TQTextStream &out)
612{
613 //out << endl;
614 kdDebug(30522) << " type list to close : " << type << endl;
615
616 /* Because of a new markup, we need a new line. */
617 out << endl;
618
619 Config::instance()->desindent();
620 Config::instance()->writeIndent(out);
621
622 /* but the next parag is not a same list */
623 switch(type)
624 {
625 case TL_NONE: //out << endl;
626 break;
627 case TL_ARABIC:
628 case TL_LLETTER: /* a, b, ... */
629 case TL_CLETTER: /* A, B, ... P. 250*/
630 case TL_LLNUMBER: /* i, ii, ... */
631 case TL_CLNUMBER: /* I, II, ... */
632 case TL_CUSTOM_SIMPLE: /* - */
633 case TL_CUSTOM_COMPLEX: /* - */
634 out << "\\end{enumerate}" << endl;
635 break;
636 case TL_CIRCLE_BULLET:
637 out << "\\end{itemize}" << endl;
638 break;
639 case TL_SQUARE_BULLET:
640 case TL_DISC_BULLET:
641 out << "\\end{itemize}" << endl;
642 break;
643 default:
644 out << "no suported" << endl;
645 }
646
647 Config::instance()->writeIndent(out);
648
649 /* Pop the list which has been closed */
650 _historicList.remove();
651 kdDebug(30522) << "removed" << endl;
652}
653
654/*******************************************/
655/* GenerateTitle */
656/*******************************************/
657void Para::generateTitle(TQTextStream &out)
658{
659 switch(getCounterDepth())
660 {
661 case 0:
662 out << "\\section{";
663 break;
664 case 1:
665 out << "\\subsection{";
666 break;
667 case 2:
668 out << "\\subsubsection{";
669 break;
670 case 3:
671 out << "\\paragraph{";
672 break;
673 case 4:
674 out << "\\subparagraph{";
675 break;
676 case 5:
677 out << "% section too deep" << endl;
678 out << "\\textbf{";
679 }
680}
void generate(TQTextStream &out, Column *col=NULL, Row *row=NULL)
Generate the cell format inherited from the row or the colum format or use its own format.
EFormat getId() const
Accessors.
virtual void analyse(const TQDomNode)
Helpfull functions.
Format()
Constructors.
void analyseLayout(const TQDomNode)
Helpfull functions.
Definition layout.cpp:55
bool isChapter() const
Accessors.
Definition layout.h:102
void analyse(const TQDomNode)
Modifiers.
Definition para.cpp:129
SSect getFrameType() const
Definition para.cpp:69
Para(TextFrame *textFrame=0)
Constructors.
Definition para.cpp:41
void openList(TQTextStream &)
Write the markup to begin a list.
Definition para.cpp:476
void generateBeginEnv(TQTextStream &)
If the paragraph has a different environment, change it.
Definition para.cpp:447
EP_INFO getInfo() const
Definition para.h:114
void generate(TQTextStream &)
Write the paragraph in a file.
Definition para.cpp:359
void generateEndEnv(TQTextStream &)
If the next paragraph has a different environment, close it.
Definition para.cpp:545
int getNbCharPara() const
Definition para.cpp:92
EFormat getTypeFormat(const TQDomNode) const
Definition para.cpp:80
void closeList(TQTextStream &, Para *)
Write the markup to close a list.
Definition para.cpp:584
void generateTitle(TQTextStream &)
If the paragraph is a title, generate the command.
Definition para.cpp:657
This class hold 2 lists of paragraphs for the text and for the footnotes.
Definition textFrame.h:40
This class hold a zone of text with only one formating.
Definition textzone.h:41