tdehtmlreader.cpp
1/***************************************************************************
2 tdehtmlreader.cpp - description
3 -------------------
4 begin : Sun Sep 9 2001
5 copyright : (C) 2001 by Frank Dekervel
6 email : Frank.Dekervel@student.kuleuven.ac.be
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU lesser General Public License as *
13 * published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#include "tdehtmlreader.h"
20
21#include "tdehtmlreader.moc"
22#include <kdebug.h>
23#include <dom/dom_text.h>
24#include <dom/dom2_views.h>
25#include <dom/dom_doc.h>
26#include <tqcolor.h>
27#include <dom/dom_element.h>
28#include <dom/html_table.h>
29#include <tdehtmlview.h>
30#include <tqwidget.h>
31#include <tdeapplication.h>
32#include <dom/html_misc.h>
33#include <tqregexp.h>
34
35TDEHTMLReader::TDEHTMLReader(KWDWriter *w)
36{
37 _html=new TDEHTMLPart();
38 _writer=w;
39 _it_worked=false;
40}
41
42// if a troll ever sees this, he can't kill me anyway. (and he should kill dfaure first)
43void tqt_enter_modal( TQWidget *widget );
44void tqt_leave_modal( TQWidget *widget );
45
46
47bool TDEHTMLReader::filter(KURL url)
48{
49 kdDebug(30503) << "TDEHTMLReader::filter" << endl;
50 TQObject::connect(_html,TQ_SIGNAL(completed()),this,TQ_SLOT(completed()));
51
52 _state.clear();
53 _list_depth=0;
54
55 _html->view()->resize(600,530);
56 _html->setAutoloadImages(false);
57 _html->setJScriptEnabled(false);
58 _html->setPluginsEnabled(false);
59 _html->setJavaEnabled(false);
60 _html->setMetaRefreshEnabled(false);
61 if (_html->openURL(url) == false)
62 {
63 kdWarning(30503) << "openURL returned false" << endl;
64 return false;
65 }
66
67 //FIXME use synchronous IO instead of this hack if possible.
68 TQWidget dummy(0,0,WType_Dialog | WShowModal);
69 tqt_enter_modal(&dummy);
70 tqApp->enter_loop();
71 tqt_leave_modal(&dummy);
72 return _it_worked;
73}
74
75HTMLReader_state *TDEHTMLReader::state()
76{
77 if (_state.count() == 0)
78 {
79 HTMLReader_state *s=new HTMLReader_state;
80 s->frameset=_writer->mainFrameset();
81 s->paragraph = _writer->addParagraph(s->frameset);
82 s->format=_writer->currentFormat(s->paragraph,true);
83 s->layout=_writer->currentLayout(s->paragraph);
84 s->in_pre_mode = false;
85 _state.push(s);
86 }
87 return _state.top();
88}
89
90HTMLReader_state *TDEHTMLReader::pushNewState()
91{
92 HTMLReader_state *s=new HTMLReader_state;
93 s->frameset=state()->frameset;
94 s->paragraph=state()->paragraph;
95 s->format=state()->format;
96 s->layout=state()->layout;
97 s->in_pre_mode=state()->in_pre_mode;
98 _writer->cleanUpParagraph(s->paragraph);
99 _state.push(s);
100 return s;
101}
102
103
104void TDEHTMLReader::popState()
105{
106 kdDebug(30503) << "Entering popState" << endl;
107
108 HTMLReader_state *s=_state.pop();
109
118 if (s->frameset == state()->frameset)
119 {
120 state()->paragraph=s->paragraph;
121 if ((state()->layout != s->layout))
122 {
123 if (_writer->getText(state()->paragraph).length()!=0) startNewLayout(false,state()->layout);
124 }
125 state()->format=_writer->startFormat(state()->paragraph, state()->format);
126 }
127 delete(s);
128}
129
130void TDEHTMLReader::startNewLayout(bool startNewFormat)
131{
132 TQDomElement layout;
133 startNewLayout(startNewFormat,layout);
134}
135
136void TDEHTMLReader::startNewLayout(bool startNewFormat, TQDomElement layout)
137{
138 kdDebug() << "entering startNewLayout" << endl;
139 startNewParagraph(startNewFormat,true);
140 state()->layout=_writer->setLayout(state()->paragraph,layout);
141}
142
143void TDEHTMLReader::completed()
144{
145 kdDebug(30503) << "TDEHTMLReader::completed" << endl;
146 tqApp->exit_loop();
147 DOM::Document doc=_html->document(); // FIXME parse <HEAD> too
148 DOM::NodeList list=doc.getElementsByTagName("body");
149 DOM::Node docbody=list.item(0);
150
151 if (docbody.isNull())
152 {
153 kdWarning(30503) << "no <BODY>, giving up" << endl;
154 _it_worked=false;
155 return;
156 }
157
158
159 parseNode(docbody); // start here (keyword: main)
160
161 list = doc.getElementsByTagName("head");
162 DOM::Node dochead=list.item(0);
163 if (!dochead.isNull())
164 parse_head(dochead);
165 else
166 kdWarning(30503) << "WARNING: no html <HEAD> section" << endl;
167
168 _writer->cleanUpParagraph(state()->paragraph);
169 _it_worked=_writer->writeDoc();
170}
171
172
173void TDEHTMLReader::parseNode(DOM::Node node)
174{
175 kdDebug(30503) << "Entering parseNode" << endl;
176 // check if this is a text node.
177 DOM::Text t=node;
178 if (!t.isNull())
179 {
180 _writer->addText(state()->paragraph,t.data().string(),1,state()->in_pre_mode);
181 return; // no children anymore...
182 }
183
184 // is this really needed ? it can't do harm anyway.
185 state()->format=_writer->currentFormat(state()->paragraph,true);
186 state()->layout=_writer->currentLayout(state()->paragraph);
187 pushNewState();
188
189 DOM::Element e=node;
190
191 bool go_recursive=true;
192
193 if (!e.isNull())
194 {
195 // get the CSS information
196 parseStyle(e);
197 // get the tag information
198 go_recursive=parseTag(e);
199 }
200 if (go_recursive)
201 {
202 for (DOM::Node q=node.firstChild(); !q.isNull(); q=q.nextSibling())
203 {
204 parseNode(q);
205 }
206 }
207 popState();
208}
209
210void TDEHTMLReader::parse_head(DOM::Element e)
211{
212 for (DOM::Element items=e.firstChild();!items.isNull();items=items.nextSibling()) {
213 if (items.tagName().string().lower() == "title") {
214 DOM::Text t=items.firstChild();
215 if (!t.isNull()) {
216 _writer->createDocInfo("HTML import filter",t.data().string());
217 }
218 }
219 }
220}
221
222#define _PF(x,a,b,c) { \
223 if (e.tagName().lower() == #x) \
224 { \
225 _writer->formatAttribute(state()->paragraph, #a,#b,#c); \
226 return true; \
227 } \
228 }
229
230// the state->layout=_writer->setLayout is meant to tell popState something changed in the layout, and a new
231// layout should probably be started after closing.
232
233#define _PL(x,a,b,c) { \
234 if (e.tagName().lower() == #x) \
235 { \
236 state()->layout=_writer->setLayout(state()->paragraph,state()->layout);\
237 if (!(_writer->getText(state()->paragraph).isEmpty())) \
238 startNewParagraph(false,false); \
239 _writer->layoutAttribute(state()->paragraph, #a,#b,#c); \
240 return true; \
241 } \
242 }
243
244
245bool TDEHTMLReader::parseTag(DOM::Element e)
246{
247 kdDebug(30503) << "Entering parseTag for " << e.tagName().lower() << endl;
248 if (e.tagName().lower()=="a") { return parse_a(e); }
249 if (e.tagName().lower()=="p") { return parse_p(e); }
250 if (e.tagName().lower()=="br") { return parse_br(e); }
251 if (e.tagName().lower()=="ul") { return parse_ul(e); }
252 if (e.tagName().lower()=="ol") { return parse_ol(e); }
253 if (e.tagName().lower()=="hr") { return parse_hr(e); }
254 if (e.tagName().lower()=="pre") { return parse_pre(e); }
255 if (e.tagName().lower()=="font") { return parse_font(e); }
256 if (e.tagName().lower()=="table") { return parse_table(e); }
257
258 // FIXME we can get rid of these, make things tons more simple
259 // when tdehtml finally implements getComputedStyle
260 _PF(b,WEIGHT,value,75);
261 _PF(strong,WEIGHT,value,75);
262 _PF(u,UNDERLINE,value,1);
263 _PF(i,ITALIC,value,1);
264
265 _PL(center,FLOW,align,center);
266 _PL(right,FLOW,align,right);
267 _PL(left,FLOW,align,left);
268
269 _PL(h1,NAME,value,h1);
270 _PL(h2,NAME,value,h2);
271 _PL(h3,NAME,value,h3);
272 _PL(h4,NAME,value,h4);
273 _PL(h5,NAME,value,h5);
274 _PL(h6,NAME,value,h6);
275 kdDebug(30503) << "Leaving parseTag" << endl;
276
277 // Don't handle the content of comment- or script-nodes.
278 if(e.nodeType() == DOM::Node::COMMENT_NODE || e.tagName().lower() == "script")
279 {
280 return false;
281 }
282
283 return true;
284}
285
286void TDEHTMLReader::startNewParagraph(bool startnewformat, bool startnewlayout)
287{
288 kdDebug() << "Entering startNewParagraph" << endl;
289
290 TQDomElement qf=state()->format;
291 TQDomElement ql=state()->layout;
292
293 _writer->cleanUpParagraph(state()->paragraph);
294
295 if ((startnewlayout==true) || ql.isNull())
296 {state()->paragraph=_writer->addParagraph(state()->frameset);}
297 else
298 {state()->paragraph=
299 _writer->addParagraph(state()->frameset,state()->layout);}
300
301
302
303 if (qf.isNull() || (startnewformat==true))
304 {
305 state()->format=_writer->startFormat(state()->paragraph/*,state()->format*/);
306 }
307 else
308 {
309 state()->format=_writer->startFormat(state()->paragraph,qf);
310 }
311
317 TQString ct=_writer->getLayoutAttribute(state()->paragraph,"COUNTER","type");
318 if ((!ct.isNull()) && (ct != "0"))
319 {
320 _writer->layoutAttribute(state()->paragraph,"COUNTER","type","0");
321 _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","0");
322 _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext","");
323 int currdepth=(_writer->getLayoutAttribute(state()->paragraph,"COUNTER","depth")).toInt();
324 _writer->layoutAttribute(state()->paragraph,"COUNTER","depth",TQString("%1").arg(currdepth+1));
325 }
326}
327
328TDEHTMLReader::~TDEHTMLReader(){
329 delete _html;
330}
331
332
333
334
335
336
337//==============================================================
338// tag parsing
339//==============================================================
340
341
342bool TDEHTMLReader::parse_CommonAttributes(DOM::Element e)
343{
344 kdDebug(30503) << "entering TDEHTMLReader::parse_CommonAttributes" << endl;
345 kdDebug(30503) << "tagName is " << e.tagName().string() << endl;
346 TQString s=e.getAttribute("align").string();
347 if (!s.isEmpty())
348 {
349 _writer->formatAttribute(state()->paragraph,"FLOW","align",s);
350 }
351 TQRegExp rx( "h[0-9]+" );
352 if ( 0 == rx.search( e.getAttribute("class").string() ) )
353 // example: <p class="h1" style="text-align:left; ">
354 {
355 kdDebug(30503) << "laying out with " << e.getAttribute("class").string() << endl;
356 _writer->layoutAttribute(state()->paragraph,"NAME","value",e.getAttribute("class").string());
357 }
358 if ( e.getAttribute("class").string()=="Standard" )
359 {
360 kdDebug(30503) << "laying out with " << e.getAttribute("class").string() << endl;
361 _writer->layoutAttribute(state()->paragraph,"NAME","value",e.getAttribute("class").string());
362 }
363 kdDebug(30503) << "leaving parse_CommonAttributes" << endl;
364 return true;
365}
366
367bool TDEHTMLReader::parse_a(DOM::Element e) {
368 TQString url = e.getAttribute("href").string();
369 if (!url.isEmpty())
370 {
371 TQString linkName;
372 DOM::Text t = e.firstChild();
373 if (t.isNull()) {
374 /* Link without text -> just drop it*/
375 return false; /* stop parsing recursively */
376 }
377 linkName = t.data().string().simplifyWhiteSpace();
378 t.setData(DOM::DOMString("#")); // replace with '#'
379 _writer->createLink(state()->paragraph, linkName, url);
380 }
381 return true; /* stop parsing recursively */
382}
383
384bool TDEHTMLReader::parse_p(DOM::Element e)
385{
386 // For every starting paragraph, a line break has to be inserted.
387 // exception: the first paragraph, e.g. if the <body> starts with a <p>.
388 kdDebug() << "entering parse_p" << endl;
389 if (!(_writer->getText(state()->paragraph).isEmpty()))
390 startNewParagraph(false,false);
391 parse_CommonAttributes(e);
392 kdDebug() << "leaving parse_p" << endl;
393 return true;
394}
395
396bool TDEHTMLReader::parse_hr(DOM::Element /*e*/)
397{
398 startNewParagraph();
399 _writer->createHR(state()->paragraph);
400 startNewParagraph();
401 return true;
402}
403
404bool TDEHTMLReader::parse_br(DOM::Element /*e*/)
405{
406 startNewParagraph(false,false); //keep the current format and layout
407 return false; // a BR tag has no childs.
408}
409
410static const TQColor parsecolor(const TQString& colorstring)
411{
412 TQColor color;
413 if (colorstring[0]=='#')
414 {
415 color.setRgb(
416 colorstring.mid(1,2).toInt(0,16),
417 colorstring.mid(3,2).toInt(0,16),
418 colorstring.mid(5,2).toInt(0,16)
419 );
420 }
421 else
422 {
423 TQString colorlower=colorstring.lower();
424 // Grays
425 if (colorlower=="black")
426 color.setRgb(0,0,0);
427 else if (colorlower=="white")
428 color.setRgb(255,255,255);
429 else if (colorlower=="silver")
430 color.setRgb(0xc0,0xc0,0xc0);
431 else if (colorlower=="gray")
432 color.setRgb(128,128,128);
433 // "full" colors
434 else if (colorlower=="red")
435 color.setRgb(255,0,0);
436 else if (colorlower=="lime")
437 color.setRgb(0,255,0);
438 else if (colorlower=="blue")
439 color.setRgb(0,0,255);
440 else if (colorlower=="yellow")
441 color.setRgb(255,255,0);
442 else if (colorlower=="fuchsia")
443 color.setRgb(255,0,255);
444 else if (colorlower=="aqua")
445 color.setRgb(0,255,255);
446 // "half" colors
447 else if (colorlower=="maroon")
448 color.setRgb(128,0,0);
449 else if (colorlower=="green")
450 color.setRgb(0,128,0);
451 else if (colorlower=="navy")
452 color.setRgb(0,0,128);
453 else if (colorlower=="olive")
454 color.setRgb(128,128,0);
455 else if (colorlower=="purple")
456 color.setRgb(128,0,128);
457 else if (colorlower=="teal")
458 color.setRgb(0,128,128);
459 else
460 {
461 // H'm, we have still not found the color!
462 // Let us see if TQt can do better!
463 color.setNamedColor(colorstring);
464 }
465 }
466 return colorstring;
467}
468
469void TDEHTMLReader::parseStyle(DOM::Element e)
470{
471 // styles are broken broken broken broken broken broken.
472 //FIXME: wait until getComputedStyle is more than
473 // 'return 0' in tdehtml
474 kdDebug(30503) << "entering parseStyle" << endl;
475 DOM::CSSStyleDeclaration s1=e.style();
476 DOM::Document doc=_html->document();
477 DOM::CSSStyleDeclaration s2=doc.defaultView().getComputedStyle(e,"");
478 kdDebug(30503) << "font-weight=" << s1.getPropertyValue("font-weight").string() << endl;
479 if ( s1.getPropertyValue("font-weight").string() == "bolder" )
480 {
481 _writer->formatAttribute(state()->paragraph,"WEIGHT","value","75");
482 }
483 if ( s1.getPropertyValue("font-weight").string() == "bold" )
484 {
485 _writer->formatAttribute(state()->paragraph,"WEIGHT","value","75");
486 }
487
488 // process e.g. <style="color: #ffffff">
489 if ( s1.getPropertyValue("color").string() != TQString() )
490 {
491 TQColor c=parsecolor(s1.getPropertyValue("color").string());
492 _writer->formatAttribute(state()->paragraph,"COLOR","red",TQString::number(c.red()));
493 _writer->formatAttribute(state()->paragraph,"COLOR","green",TQString::number(c.green()));
494 _writer->formatAttribute(state()->paragraph,"COLOR","blue",TQString::number(c.blue()));
495 }
496 // done
497 // process e.g. <style="font-size: 42">
498 if ( s1.getPropertyValue("font-size").string() != TQString() )
499 {
500 TQString size=s1.getPropertyValue("font-size").string();
501 if (size.endsWith("pt"))
502 {
503 size=size.left(size.length()-2);
504 }
505 _writer->formatAttribute(state()->paragraph,"SIZE","value",size);
506 }
507 // done
508 // process e.g. <style="text-align: center">this is in the center</style>
509 if ( s1.getPropertyValue("text-align").string() != TQString() && s1.getPropertyValue("text-align").string() != TQString("left") )
510 {
511 state()->layout=_writer->setLayout(state()->paragraph,state()->layout);
512 _writer->layoutAttribute(state()->paragraph, "FLOW","align",s1.getPropertyValue("text-align").string());
513 }
514 // done
515
516 /*if (DOM::PROPV("font-weight") == "bolder")
517 _writer->formatAttribute(state()->paragraph,"WEIGHT","value","75");
518 */
519/*
520 // debugging code.
521 kdDebug(30503) << "e.style()" << endl;
522 for (unsigned int i=0;i<s1.length();i++) {
523 kdDebug(30503) << TQString("%1: %2").arg(s1.item(i).string()).arg(s1.getPropertyValue(s1.item(i)).string()) << endl;
524 }
525 kdDebug(30503) << "override style" << endl;
526 for (unsigned int i=0;i<s2.length();i++) {
527 kdDebug(30503) << TQString("%1: %2").arg(s2.item(i).string()).arg(s2.getPropertyValue(s2.item(i)).string()) << endl;
528 }
529*/
530}
531
532bool TDEHTMLReader::parse_table(DOM::Element e)
533{
534 if(_writer->isInTable()) {
535 // We are already inside of a table. Tables in tables are not supported
536 // yet. So, just add that table-content as text.
537 for (DOM::Node rows=e.firstChild().firstChild();!rows.isNull();rows=rows.nextSibling())
538 if (!rows.isNull() && rows.nodeName().string().lower() == "tr")
539 for (DOM::Node cols=rows.firstChild();!cols.isNull();cols=cols.nextSibling())
540 if (!cols.isNull())
541 parseNode(cols);
542 return false;
543 }
544
545 DOM::Element table_body=e.firstChild();
546 if(table_body.isNull()) {
547 // If the table_body is empty, we don't continue cause else
548 // TDEHTML will throw a DOM::DOMException if we try to access
549 // the null element.
550 return true;
551 }
552
553 int tableno=_writer->createTable();
554 int nrow=0;
555 int ncol=0;
556 bool has_borders=false;
557 TQColor bgcolor=parsecolor("#FFFFFF");
558
559 if (!table_body.getAttribute("bgcolor").string().isEmpty())
560 bgcolor=parsecolor(table_body.getAttribute("bgcolor").string());
561 if ((e.getAttribute("border").string().toInt() > 0))
562 has_borders=true;
563
564 // fixme rewrite this proper
565 //(maybe using computed sizes from tdehtml if thats once exported)
566 for (DOM::Node rowsnode=table_body.firstChild();!rowsnode.isNull();rowsnode=rowsnode.nextSibling()) {
567 DOM::Element rows = rowsnode;
568 if (!rows.isNull() && rows.tagName().string().lower() == "tr") {
569 TQColor obgcolor=bgcolor;
570 if (!rows.getAttribute("bgcolor").string().isEmpty())
571 bgcolor=parsecolor(rows.getAttribute("bgcolor").string());
572
573 ncol=0;
574 for (DOM::Node colsnode=rows.firstChild();!colsnode.isNull();colsnode=colsnode.nextSibling()) {
575 DOM::Element cols = colsnode;
576 const TQString nodename = cols.isNull() ? TQString() : cols.nodeName().string().lower();
577 if (nodename == "td" || nodename == "th") {
578 TQColor bbgcolor=bgcolor;
579 if (!cols.getAttribute("bgcolor").string().isEmpty())
580 bgcolor=parsecolor(cols.getAttribute("bgcolor").string());
581
582 pushNewState();
583 TQRect colrect=cols.getRect();
584 state()->frameset=_writer->createTableCell(tableno,nrow,ncol,1,colrect);
585 state()->frameset.firstChild().toElement().setAttribute("bkRed",bgcolor.red());
586 state()->frameset.firstChild().toElement().setAttribute("bkGreen",bgcolor.green());
587 state()->frameset.firstChild().toElement().setAttribute("bkBlue",bgcolor.blue());
588 if (has_borders) {
589 state()->frameset.firstChild().toElement().setAttribute("lWidth",1);
590 state()->frameset.firstChild().toElement().setAttribute("rWidth",1);
591 state()->frameset.firstChild().toElement().setAttribute("bWidth",1);
592 state()->frameset.firstChild().toElement().setAttribute("tWidth",1);
593 }
594
595 // fixme don't guess. get it right.
596 state()->paragraph=_writer->addParagraph(state()->frameset);
597 parseNode(cols);
598 _writer->cleanUpParagraph(state()->paragraph);
599 popState();
600 ncol++;
601 bgcolor=bbgcolor;
602 }
603 }
604 nrow++;
605 bgcolor=obgcolor;
606 }
607 }
608 _writer->finishTable(tableno/*,0,0,r.right()-r.left(),r.bottom()-r.top()*/); // FIXME find something better.
609 startNewParagraph(false,false);
610 _writer->createInline(state()->paragraph,_writer->fetchTableCell(tableno,0,0));
611 startNewParagraph(false,false);
612 return false; // we do our own recursion
613}
614
615bool TDEHTMLReader::parse_img(DOM::Element /*e*/)
616{
617 //TQRect e=e.getRect();
618 return true;
619}
620
621bool TDEHTMLReader::parse_pre(DOM::Element e)
622{
623#if 0 // see Bug #74601 (normal): kword doesn't recognize PRE-tags in HTML
624 //pushNewState();
626 DOM::HTMLElement htmlelement(e);
627 if(! htmlelement.isNull())
628 _writer->addText(state()->paragraph,htmlelement.innerHTML().string(),1);
629 startNewParagraph();
630 //popState();
631 return false; // children are already handled.
632#else
633 pushNewState();
634 state()->in_pre_mode=true;
635 TQString face=e.getAttribute("face").string();
636 _writer->formatAttribute(state()->paragraph,"FONT","name",TQString("Courier"));
637 for (DOM::Node q=e.firstChild(); !q.isNull(); q=q.nextSibling())
638 {
639 parseNode(q); // parse everything...
640 }
641 popState();
642 _writer->formatAttribute(state()->paragraph,"FONT","name",face);
643 return false; // children are already handled.
644#endif
645}
646
647bool TDEHTMLReader::parse_ol(DOM::Element e)
648{
649 return parse_ul(e);
650}
651
652bool TDEHTMLReader::parse_font(DOM::Element e)
653{
654 kdDebug(30503) << "Entering parse_font" << endl;
655 // fixme don't hardcode 12 font size ...
656 TQString face=e.getAttribute("face").string();
657 TQColor color=parsecolor("#000000");
658 if (!e.getAttribute("color").string().isEmpty())
659 color=parsecolor(e.getAttribute("color").string());
660 TQString size=e.getAttribute("size").string();
661 int isize=-1;
662 if (size.startsWith("+"))
663 isize=12+size.right(size.length()-1).toInt();
664 else if (size.startsWith("-"))
665 isize=12-size.right(size.length()-1).toInt();
666 else
667 isize=12+size.toInt();
668
669 _writer->formatAttribute(state()->paragraph,"FONT","name",face);
670 if ((isize>=0) && (isize != 12))
671 _writer->formatAttribute(state()->paragraph,"SIZE","value",TQString("%1").arg(isize));
672
673 _writer->formatAttribute(state()->paragraph,"COLOR","red",TQString("%1").arg(color.red()));
674 _writer->formatAttribute(state()->paragraph,"COLOR","green",TQString("%1").arg(color.green()));
675 _writer->formatAttribute(state()->paragraph,"COLOR","blue",TQString("%1").arg(color.blue()));
676 return true;
677}
678
679bool TDEHTMLReader::parse_ul(DOM::Element e)
680{
681// Parse the tag ul and all its subnodes. Take special care for the li tag.
682 kdDebug(30503) << "Entering TDEHTMLReader::parse_ul" << endl;
683 kdDebug(30503) << "_writer->getText(state()->paragraph)=" << _writer->getText(state()->paragraph) << endl;
684 _list_depth++;
685 if (e.firstChild().nodeName().string().lower() == "#text") // e.g. <ul>this is indented<li>first listitem</li></ul>
686 {
687 _writer->layoutAttribute(state()->paragraph,"COUNTER","depth",TQString("%1").arg(_list_depth-1)); // indent
688 startNewLayout();
689 }
690 for (DOM::Node items=e.firstChild();!items.isNull();items=items.nextSibling())
691 {
692 if (items.nodeName().string().lower() == "li")
693 {
694 if (!(_writer->getText(state()->paragraph).isEmpty())) startNewLayout();
695 _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","1");
696 _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext",".");
697 if (e.tagName().string().lower() == "ol")
698 {
699 _writer->layoutAttribute(state()->paragraph,"COUNTER","type","1");
700 _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","1");
701 _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext",".");
702 }
703 else
704 {
705 _writer->layoutAttribute(state()->paragraph,"COUNTER","type","10");
706 _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","");
707 _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext","");
708 }
709 _writer->layoutAttribute(state()->paragraph,"COUNTER","depth",TQString("%1").arg(_list_depth-1)); // indent
710 }
711 parseNode(items);
712 }
713 _list_depth--;
714 kdDebug(30503) << "Leaving TDEHTMLReader::parse_ul" << endl;
715 return false;
716}
717