filters

textzone.cpp
1/* MEMO: to see the unicode table
2 * xset +fp /usr/X11R6/lib/X11/fonts/ucs/
3 * xfd -fn '-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1'
4 */
5/*
6** A program to convert the XML rendered by KWord into LATEX.
7**
8** Copyright (C) 2000 - 2003 Robert JACOLIN
9**
10** This library is free software; you can redistribute it and/or
11** modify it under the terms of the GNU Library General Public
12** License as published by the Free Software Foundation; either
13** version 2 of the License, or (at your option) any later version.
14**
15** This library is distributed in the hope that it will be useful,
16** but WITHOUT ANY WARRANTY; without even the implied warranty of
17** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18** Library General Public License for more details.
19**
20** To receive a copy of the GNU Library General Public License, write to the
21** Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23**
24*/
25
26#include <kdebug.h> /* for kdDebug() stream */
27#include <tqregexp.h> /* for TQRegExp() --> escapeLatin1 */
28
29#include "textzone.h"
30#include "para.h"
31
32#define CSTART 0x00C0
33
34/*******************************************/
35/* TextZone */
36/*******************************************/
38{
39 setPara(para);
40 if(para != NULL)
41 {
42 setSize(para->getSize());
43 setWeight(para->getWeight());
44 setItalic(para->isItalic());
45 setUnderlined(para->getUnderlineType());
46 setStrikeout(para->isStrikeout());
47 }
48}
49
50/*******************************************/
51/* TextZone */
52/*******************************************/
53TextZone::TextZone(TQString texte, Para *para): _texte(texte)
54{
55 setPara(para);
56 if(para != NULL)
57 {
58 setSize(para->getSize());
59 setWeight(para->getWeight());
60 setItalic(para->isItalic());
61 setUnderlined(para->getUnderlineType());
62 setStrikeout(para->isStrikeout());
63 }
64}
65
66/*******************************************/
67/* ~TextZone */
68/*******************************************/
69TextZone::~TextZone()
70{
71 kdDebug(30522) << "Destruction of a area" << endl;
72}
73
74/*******************************************/
75/* useFormat */
76/*******************************************/
77/* Use the format only if the user wants */
78/* that and it's not a title. */
79/*******************************************/
81{
82 return !getPara()->isChapter();
83}
84
85/*******************************************/
86/* escapeLatin1 */
87/*******************************************/
88/* Convert special caracters (unicode) in */
89/* latex usable caracters. */
90/*******************************************/
91TQString TextZone::escapeLatin1(TQString text)
92{
93 static const char *escapes[64] =
94 {
95 "\\`{A}", "\\'{A}", "\\^{A}", "\\~{A}",
96 "\\\"{A}", "\\AA", "\\AE", "\\c{C}",
97 "\\`{E}", "\\'{E}", "\\^{E}", "\\\"{E}",
98 "\\`{I}", "\\'{I}", "\\^{I}", "\\\"{I}",
99
100 "\\DH{}", "\\~{N}", "\\`{O}", "\\'{O}",
101 "\\^{O}", "\\~{O}", "\\\"{O}", "\\texttimes{}",
102 "\\O{}", "\\`{U}", "\\'{U}", "\\^{U}",
103 "\\\"{U}", "\\'{Y}", "\\TH{}", "\\ss{}",
104
105 "\\`{a}", "\\'{a}", "\\^{a}", "\\~{a}",
106 "\\\"{a}", "\\aa", "\\ae{}", "\\c{c}",
107 "\\`{e}", "\\'{e}", "\\^{e}", "\\\"{e}",
108 "\\`{\\i}", "\\'{\\i}", "\\^{\\i}", "\\\"{\\i}",
109
110 "\\dh{}", "\\~{n}", "\\`{o}", "\\'{o}",
111 "\\^{o}", "\\~{o}", "\\\"{o}", "\\textdiv{}",
112 "\\o{}", "\\`{u}", "\\'{u}", "\\^{u}",
113 "\\\"{u}", "\\'{y}", "\\th{}", "\\\"{y}"
114 };
115
116 TQString escapedText;
117 int unicode; /* the character to be escaped */
118
119 escapedText = text; /* copy input text */
120
121 /***************************************************************************
122 * Escape the special punctuation and other symbols in the Latin1 supplement
123 ****************************************************************************/
124 /* We must begin by this char because else, all special char will
125 * be backslahed !
126 */
127 convert(escapedText, 0X005C, "\\textbackslash{}");
128
129 //convert(escapedText, 0X22, "\\textquotestraightdblbase");/* textcomp */
130 convert(escapedText, 0X0023, "\\#{}");
131 convert(escapedText, 0X0024, "\\${}"); /* add a \$ at the end of the paragraphes ! */
132 convert(escapedText, 0X0025, "\\%{}");
133 convert(escapedText, 0X0026, "\\&{}");
134 //convert(escapedText, 0X0027, "\\textquotestraightbase"); /* textcomp */
135// convert(escapedText, 0X002A, "\\textasteriskcentered"); /* textcomp */
136
137 convert(escapedText, 0X003C, "\\textless{}");
138 convert(escapedText, 0X003E, "\\textgreater{} ");
139
140 convert(escapedText, 0X005E, "\\^{}");
141 convert(escapedText, 0X005F, "\\_{}");
142
143 convert(escapedText, 0X007B, "\\{");
144 convert(escapedText, 0X007C, "\\textbar{}");
145 convert(escapedText, 0X007D, "\\}");
146 convert(escapedText, 0X007E, "\\textasciitilde{}");
147
148 convert(escapedText, 0X00A1, "!`{}");
149 convert(escapedText, 0X00A2, "\\textcent{}"); /* textcomp */
150 convert(escapedText, 0X00A3, "\\pounds{}");
151 convert(escapedText, 0X00A4, "\\textcurrency{}"); /* textcomp */
152 convert(escapedText, 0X00A5, "\\textyen{}"); /* textcomp */
153 convert(escapedText, 0X00A6, "\\textbrokenbar{}");
154 convert(escapedText, 0X00A7, "\\S{}");
155 convert(escapedText, 0X00A8, "\\textasciidieresis{}"); /*? not good */
156 convert(escapedText, 0X00A9, "\\copyright{}");
157 convert(escapedText, 0X00AA, "\\textordfeminine{}"); /* textcomp */
158 convert(escapedText, 0X00AB, "\\guillemotleft{}"); /* textcomp */
159 convert(escapedText, 0X00AC, "\\textlnot{}"); /* textcomp */
160
161 convert(escapedText, 0X00AE, "\\textregistered{}");
162 convert(escapedText, 0X00AF, "\\textmacron{}"); /* textcomp */
163 convert(escapedText, 0X00B0, "\\textdegree{}"); /* textcomp */
164 convert(escapedText, 0X00B1, "\\textpm{}"); /* textcomp */
165 convert(escapedText, 0X00B2, "\\texttwosuperior{}"); /* textcomp */
166 convert(escapedText, 0X00B3, "\\textthreesuperior{}"); /* textcomp */
167 convert(escapedText, 0X00B4, "' "); /* textcomp */
168 convert(escapedText, 0X00B5, "\\textmu{}"); /* textcomp */
169 convert(escapedText, 0X00B6, "\\P{}");
170 convert(escapedText, 0X00B7, "\\textperiodcentered{}"); /* not good textcomp */
171// convert(escapedText, 0X00B8, "\\textthreesuperior{}"); /* textcomp */
172 convert(escapedText, 0X00B9, "\\textonesuperior{}"); /* textcomp */
173 convert(escapedText, 0X00BA, "\\textordmasculine{}"); /* textcomp */
174 convert(escapedText, 0X00BB, "\\guillemotright{}"); /* textcomp */
175 convert(escapedText, 0X00BC, "\\textonequarter{}"); /* textcomp */
176 convert(escapedText, 0X00BD, "\\textonehalf{}"); /* textcomp */
177 convert(escapedText, 0X00BE, "\\textthreequarters{}"); /* textcomp */
178 convert(escapedText, 0X00BF, "?`{}");
179
180
181 /* begin making escape sequences for the 64 consecutive letters starting at C0
182 * LaTeX has a different escape code when a char is followed by a space so
183 * two escape sequences are needed for each character.
184 */
185
186 for(int index = 0; index < 64; index++)
187 {
188 unicode = CSTART + index;
189 convert(escapedText, unicode, escapes[index]);
190 }
191
192 convert(escapedText, 0X2020, "\\textdied{}"); /* textcomp */
193 convert(escapedText, 0X2021, "\\textdaggerdbl{}"); /* textcomp */
194 convert(escapedText, 0X2022, "'' "); /* textcomp */
195 convert(escapedText, 0X2023, "\\textdaggerdbl{}"); /* textcomp */
196 convert(escapedText, 0X2024, "\\textdaggerdbl{}"); /* textcomp */
197 convert(escapedText, 0X2025, "\\textdaggerdbl{}"); /* textcomp */
198 convert(escapedText, 0X2026, "\\&{}"); /* textcomp */
199 convert(escapedText, 0X2027, "\\textperiodcentered{}"); /* textcomp */
200 convert(escapedText, 0X2030, "\\textperthousand{}"); /* textcomp */
201 convert(escapedText, 0X2031, "\\textpertenthousand{}"); /* textcomp */
202 convert(escapedText, 0X2032, "\\textasciiacute{}"); /* textcomp */
203 convert(escapedText, 0X2033, "\\textgravedbl{}"); /* textcomp */
204 convert(escapedText, 0X2034, "\\textdaggerdbl{}"); /* textcomp */
205 convert(escapedText, 0X2035, "\\textasciigrave{}"); /* textcomp */
206 convert(escapedText, 0X2036, "\\textacutedbl{}"); /* textcomp */
207 convert(escapedText, 0X2037, "\\textdaggerdbl{}"); /* textcomp */
208 convert(escapedText, 0X2038, "\\textdaggerdbl{}"); /* textcomp */
209 convert(escapedText, 0X2039, "\\textdaggerdbl{}"); /* textcomp */
210 convert(escapedText, 0X203A, "\\textdaggerdbl{}"); /* textcomp */
211 convert(escapedText, 0X203B, "\\textreferencemark{}"); /* textcomp */
212 convert(escapedText, 0X203D, "\\textinterrobang{}"); /* textcomp */
213
214 convert(escapedText, 0X2045, "\\textlquill{}"); /* textcomp */
215 convert(escapedText, 0X2046, "\\textrquill{}"); /* textcomp */
216
217
218 convert(escapedText, 0X2080, "\\textzerooldstyle{}"); /* textcomp */
219 convert(escapedText, 0X2081, "\\textoneoldstyle{}"); /* textcomp */
220 convert(escapedText, 0X2082, "\\texttwooldstyle{}"); /* textcomp */
221 convert(escapedText, 0X2083, "\\textthreeoldstyle{}"); /* textcomp */
222 convert(escapedText, 0X2084, "\\textfouroldstyle{}"); /* textcomp */
223 convert(escapedText, 0X2085, "\\textfiveoldstyle{}"); /* textcomp */
224 convert(escapedText, 0X2086, "\\textsixoldstyle{}"); /* textcomp */
225 convert(escapedText, 0X2087, "\\textsevenoldstyle{}"); /* textcomp */
226 convert(escapedText, 0X2088, "\\texteightoldstyle{}"); /* textcomp */
227 convert(escapedText, 0X2089, "\\textnineoldstyle{}"); /* textcomp */
228 convert(escapedText, 0X208C, "\\textdblhyphen{}"); /* textcomp */
229
230 convert(escapedText, 0X20A4, "\\textsterling{}"); /* textcomp */
231 convert(escapedText, 0X20A6, "\\textnaria{}"); /* textcomp */
232 convert(escapedText, 0X20AA, "\\textwon{}"); /* textcomp */
233 convert(escapedText, 0X20AB, "\\textdong{}"); /* textcomp */
234 convert(escapedText, 0X20AC, "\\texteuro{}"); /* textcomp */
235
236 convert(escapedText, 0X2103, "\\textcelsius{}"); /* textcomp */
237 convert(escapedText, 0X2116, "\\textnumero{}"); /* textcomp */
238 convert(escapedText, 0X2117, "\\textcircledP{}"); /* textcomp */
239 convert(escapedText, 0X2120, "\\textservicemark{}"); /* textcomp */
240 convert(escapedText, 0X2122, "\\texttrademark{}"); /* textcomp */
241 convert(escapedText, 0X2126, "\\textohm{}"); /* textcomp */
242 convert(escapedText, 0X2127, "\\textmho{}"); /* textcomp */
243 convert(escapedText, 0X212E, "\\textestimated{}"); /* textcomp */
244
245 convert(escapedText, 0X2190, "\\textleftarrow{}"); /* textcomp */
246 convert(escapedText, 0X2191, "\\textuparrow{}"); /* textcomp */
247 convert(escapedText, 0X2192, "\\textrightarrow{}"); /* textcomp */
248 convert(escapedText, 0X2193, "\\textdownarrow{}"); /* textcomp */
249// convert(escapedText, 0X2194, "\\texteuro{}"); /* textcomp */
250// convert(escapedText, 0X2195, "\\texteuro{}"); /* textcomp */
251// convert(escapedText, 0X2196, "\\texteuro{}"); /* textcomp */
252
253 return escapedText;
254}
255
256/*******************************************/
257/* convert */
258/*******************************************/
259/* Convert all the instance of one */
260/* character in latex usable caracter. */
261/*******************************************/
262void TextZone::convert(TQString& text, int unicode, const char* escape)
263{
264 TQString expression;
265 TQString value;
266
267 expression = TQString("\\x") + value.setNum(unicode, 16);
268
269 if( !TQString(escape).isEmpty() )
270 {
271 /*1. translate special characters with a space after. */
272 text = text.replace( TQRegExp( expression), TQString(escape));
273 }
274}
275
276/*******************************************/
277/* analyse */
278/*******************************************/
279/* Analyse a text format, get the text used*/
280/* by this format. */
281/*******************************************/
282void TextZone::analyse(const TQDomNode balise)
283{
284 kdDebug(30522) << "FORMAT" << endl;
285 /* Get header information (size, position)
286 * Get infos. to format the text
287 */
288 //if(balise != 0)
289 analyseFormat(balise);
290
291 /* Format the text */
292 setTexte(getTexte().mid(getPos(), getLength()));
293
294 kdDebug(30522) << getTexte().length() << endl;
295 kdDebug(30522) << getTexte().latin1() << endl;
296 kdDebug(30522) << "END FORMAT" << endl;
297}
298
299/*******************************************/
300/* analyse */
301/*******************************************/
302/* Analyse a text format, get the text used*/
303/* by this format. */
304/*******************************************/
306{
307 kdDebug(30522) << "ZONE" << endl;
308
309 /* Format the text */
310 setTexte(getTexte().mid(getPos(), getLength()));
311
312 kdDebug(30522) << "String of " << getTexte().length() << " caracters :" << endl;
313 kdDebug(30522) << getTexte().latin1() << endl;
314 kdDebug(30522) << "END ZONE" << endl;
315}
316
317/*******************************************/
318/* generate */
319/*******************************************/
320/* Generate the text formated (if needed). */
321/*******************************************/
322void TextZone::generate(TQTextStream &out)
323{
324
325 if(useFormat())
326 generate_format_begin(out);
327
328 /* Display the text */
329 if(Config::instance()->getEncoding() == "latin1")
330 display(_texte, out);
331 else if(Config::instance()->mustUseUnicode())
332 display(_texte, out);
333 else
334 display(escapeLatin1(_texte), out);
335
336 if(useFormat())
337 generate_format_end(out);
338}
339
340/*******************************************/
341/* display */
342/*******************************************/
343/* Trunc the text in about 80 caracters of */
344/* width except if there are not spaces. */
345/*******************************************/
346void TextZone::display(TQString texte, TQTextStream& out)
347{
348 TQString line;
349 int index = 0, end = 0;
350 end = texte.find(' ', 60, false);
351 if(end != -1)
352 line = texte.mid(index, end - index);
353 else
354 line = texte;
355 while(end < (signed int) texte.length() && end != -1)
356 {
357 /* There are something to display */
358 if(Config::instance()->mustUseUnicode())
359 out << line.utf8() << endl;
360 else if(Config::instance()->mustUseLatin1())
361 out << line << endl;
362 Config::instance()->writeIndent(out);
363 index = end;
364 end = texte.find(' ', index + 60, false);
365 line = texte.mid(index, end - index);
366 }
367 kdDebug(30522) << line << endl;
368 if(Config::instance()->mustUseUnicode())
369 out << line.utf8();
370 else if(Config::instance()->getEncoding() == "ascii")
371 out << line.ascii();
372 else
373 out << line;
374}
375
376/*******************************************/
377/* generate_format_begin */
378/*******************************************/
379/* Write the begining format markup. */
380/*******************************************/
381void TextZone::generate_format_begin(TQTextStream & out)
382{
383 kdDebug(30522) << "GENERATE FORMAT BEGIN" << endl;
384
385 /* Bold, Italic or underlined */
386 if(getWeight() > 50)
387 out << "\\textbf{";
388 if(isItalic())
389 out << "\\textit{";
390 if(getUnderlineType() == UNDERLINE_SIMPLE)
391 out << "\\uline{";
392 else if(getUnderlineType() == UNDERLINE_DOUBLE)
393 out << "\\uuline{";
394 else if(getUnderlineType() == UNDERLINE_WAVE)
395 out << "\\uwave{";
396 if (isStrikeout())
397 out << "\\sout{";
398
399 /* Size */
400 if(getSize() != Config::instance()->getDefaultFontSize() &&
401 Config::instance()->isKwordStyleUsed())
402 {
403 out << "\\fontsize{" << getSize() << "}{1}%" << endl;
404 Config::instance()->writeIndent(out);
405 out << "\\selectfont" << endl;
406 Config::instance()->writeIndent(out);
407 }
408
409 /* background color */
410 if(isBkColored())
411 {
412 float red, green, blue;
413
414 red = ((float) getBkColorRed()) / 255;
415 green = ((float) getBkColorGreen()) / 255;
416 blue = ((float) getBkColorBlue()) / 255;
417
418 out << "\\colorbox[rgb]{";
419 out << red << ", " << green << ", " << blue << "}{";
420 }
421
422 /* Color */
423 if(isColor())
424 {
425 float red, green, blue;
426
427 red = ((float) getColorRed()) / 255;
428 green = ((float) getColorGreen()) / 255;
429 blue = ((float) getColorBlue()) / 255;
430
431 out << "\\textcolor[rgb]{";
432 out << red << ", " << green << ", " << blue << "}{";
433 }
434
435 /* Alignement */
436 switch(getAlign())
437 {
438 case EA_NONE:
439 break;
440 case EA_SUB: /* pass in math mode !! */
441 out << "$_{";
442 break;
443 case EA_SUPER:
444 out << "\\textsuperscript{";
445 break;
446 }
447}
448
449/*******************************************/
450/* generate_format_end */
451/*******************************************/
452/* Write the format end markup. */
453/*******************************************/
454void TextZone::generate_format_end(TQTextStream & out)
455{
456 kdDebug(30522) << "GENERATE FORMAT END" << endl;
457
458 /* Alignement */
459 if(getAlign() == EA_SUPER)
460 out << "}";
461 if(getAlign() == EA_SUB)
462 out << "}$";
463
464 /* Color */
465 if(isColor() || isBkColored())
466 out << "}";
467
468 /* Size */
469 if(getSize() != Config::instance()->getDefaultFontSize() && Config::instance()->isKwordStyleUsed())
470 {
471 out << "\\fontsize{" << Config::instance()->getDefaultFontSize() << "}{1}%" << endl;
472 Config::instance()->writeIndent(out);
473 out << "\\selectfont" << endl;
474 Config::instance()->writeIndent(out);
475 }
476
477 /* Bold, Italic or underlined */
478 if(isUnderlined())
479 out << "}";
480 if(isItalic())
481 out << "}";
482 if(getWeight() > 50)
483 out << "}";
484 if(isStrikeout())
485 out << "}";
486}
487
488TQString convertSpecialChar(int c)
489{
490 TQString output;
491
492 switch(c)
493 {
494 case 183: return output = "\\textminus";
495 break;
496 default: return output.setNum(c);
497 }
498}
This class hold a real paragraph.
Definition para.h:59
TQString escapeLatin1(TQString)
convert a unicode text in latin1 enconding ala latex.
Definition textzone.cpp:91
bool useFormat() const
Definition textzone.cpp:80
void analyse(const TQDomNode)
Helpfull functions.
Definition textzone.cpp:282
TextZone(Para *para=0)
Creates a new instance of TextZone.
Definition textzone.cpp:37