filters
wmlparser.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qstring.h>
00021 #include <qxml.h>
00022 #include <qfile.h>
00023 #include <qvaluestack.h>
00024
00025 #include <wmlparser.h>
00026
00027 class WMLParseState
00028 {
00029 public:
00030 unsigned tableRow, tableCol;
00031 WMLFormat currentFormat;
00032 WMLFormatList formatList;
00033 WMLLayout currentLayout;
00034 WMLParseState();
00035 WMLParseState( const WMLParseState& );
00036 WMLParseState& operator=( const WMLParseState& );
00037 void assign( const WMLParseState& );
00038 };
00039
00040 WMLParseState::WMLParseState()
00041 {
00042 tableRow = tableCol = 0;
00043 }
00044
00045 WMLParseState::WMLParseState( const WMLParseState& state )
00046 {
00047 assign( state );
00048 }
00049
00050 WMLParseState& WMLParseState::operator=( const WMLParseState& state )
00051 {
00052 assign( state );
00053 return *this ;
00054 }
00055
00056 void WMLParseState::assign( const WMLParseState& state )
00057 {
00058 tableRow = state.tableRow;
00059 tableCol = state.tableCol;
00060 currentFormat = state.currentFormat;
00061 formatList = state.formatList;
00062 currentLayout = state.currentLayout;
00063 }
00064
00065
00066 class WMLHandler: public QXmlDefaultHandler
00067 {
00068 public:
00069
00070 WMLHandler( WMLParser *parser ){ m_parser = parser; }
00071
00072 bool startDocument();
00073 bool startElement( const QString&, const QString&, const QString& ,
00074 const QXmlAttributes& );
00075 bool endElement( const QString&, const QString&, const QString& );
00076 bool characters( const QString& ch );
00077
00078 private:
00079
00080 WMLParser *m_parser;
00081
00082 bool m_inBlock;
00083 QString m_text;
00084
00085 bool m_inLink;
00086 QString m_link;
00087 QString m_href;
00088
00089 WMLParseState m_state;
00090 QValueStack<WMLParseState> m_stateStack;
00091
00092 bool flushParagraph();
00093 void pushState();
00094 void popState();
00095 };
00096
00097 bool WMLHandler::startDocument()
00098 {
00099 m_text = "";
00100 m_inBlock = false;
00101
00102 m_link = "";
00103 m_href = "";
00104
00105 return true;
00106 }
00107
00108 bool WMLHandler::startElement( const QString&, const QString&,
00109 const QString& qName,
00110 const QXmlAttributes& attr )
00111 {
00112 QString tag = qName.lower();
00113
00114 if( tag == "wml" )
00115 return m_parser->doOpenDocument();
00116
00117 if( tag == "card" )
00118 {
00119 m_state = WMLParseState();
00120 QString card_id = attr.value("id");
00121 QString card_title = attr.value("title");
00122 return m_parser->doOpenCard( card_id, card_title );
00123 }
00124
00125 if( tag == "p" )
00126 {
00127 m_state.currentLayout = WMLLayout();
00128 m_inBlock = TRUE;
00129 if( m_state.currentFormat.bold ||
00130 m_state.currentFormat.italic ||
00131 m_state.currentFormat.underline ||
00132 (m_state.currentFormat.fontsize != WMLFormat::Normal) )
00133 m_state.formatList.append( m_state.currentFormat );
00134
00135 QString align = attr.value("align").lower();
00136 if( align == "right" )
00137 m_state.currentLayout.align = WMLLayout::Right;
00138 if( align == "center" )
00139 m_state.currentLayout.align = WMLLayout::Center;
00140
00141 return TRUE;
00142 }
00143
00144 if(( tag == "b" ) || (tag == "strong") )
00145 {
00146 m_state.currentFormat.bold = TRUE;
00147 m_state.currentFormat.pos = m_text.length();
00148 m_state.formatList.append( m_state.currentFormat );
00149 return TRUE;
00150 }
00151
00152 if(( tag == "i" ) || (tag == "em") )
00153 {
00154 m_state.currentFormat.italic = TRUE;
00155 m_state.currentFormat.pos = m_text.length();
00156 m_state.formatList.append( m_state.currentFormat );
00157 return TRUE;
00158 }
00159
00160 if( tag == "u" )
00161 {
00162 m_state.currentFormat.underline = TRUE;
00163 m_state.currentFormat.pos = m_text.length();
00164 m_state.formatList.append( m_state.currentFormat );
00165 return TRUE;
00166 }
00167
00168 if( tag == "big" )
00169 {
00170 m_state.currentFormat.fontsize = WMLFormat::Big;
00171 m_state.currentFormat.pos = m_text.length();
00172 m_state.formatList.append( m_state.currentFormat );
00173 return TRUE;
00174 }
00175
00176 if( tag == "small" )
00177 {
00178 m_state.currentFormat.fontsize = WMLFormat::Small;
00179 m_state.currentFormat.pos = m_text.length();
00180 m_state.formatList.append( m_state.currentFormat );
00181 return TRUE;
00182 }
00183
00184 if( tag == "a" )
00185 {
00186 QString href = attr.value("href");
00187 if( !href.isEmpty() )
00188 {
00189 m_inBlock = false;
00190 m_inLink = true;
00191 m_state.currentFormat.link = "";
00192 m_state.currentFormat.href = href;
00193 m_state.currentFormat.pos = m_text.length();
00194 m_state.currentFormat.len = 1;
00195 m_text.append( "#" );
00196 return true;
00197 }
00198 }
00199
00200
00201 if( tag == "table" )
00202 {
00203 pushState();
00204 return m_parser->doBeginTable();
00205 }
00206
00207
00208 if( tag == "tr" )
00209 {
00210 m_state.tableRow++;
00211 return TRUE;
00212 }
00213
00214
00215 if( tag == "td" )
00216 {
00217 m_state.tableCol++;
00218 m_state.currentLayout = WMLLayout();
00219 m_inBlock = TRUE;
00220 m_state.formatList.append( m_state.currentFormat );
00221 return m_parser->doTableCell( m_state.tableRow, m_state.tableCol );
00222 }
00223
00224
00225 return TRUE;
00226 }
00227
00228 bool WMLHandler::endElement( const QString&, const QString&,
00229 const QString& qName )
00230 {
00231 QString tag = qName.lower();
00232
00233 if( tag == "wml" )
00234 return m_parser->doCloseDocument();
00235
00236 if( tag == "card" )
00237 {
00238
00239 m_inBlock = FALSE;
00240 if( !m_text.isEmpty() )
00241 flushParagraph();
00242 return m_parser->doCloseCard();
00243 }
00244
00245 if( tag == "p" )
00246 {
00247 m_inBlock = FALSE;
00248 return flushParagraph();
00249 }
00250
00251 if(( tag == "b" ) || (tag == "strong") )
00252 {
00253 m_state.currentFormat.bold = FALSE;
00254 m_state.currentFormat.pos = m_text.length();
00255 m_state.formatList.append( m_state.currentFormat );
00256 return TRUE;
00257 }
00258
00259 if(( tag == "i" ) || (tag == "em") )
00260 {
00261 m_state.currentFormat.italic = FALSE;
00262 m_state.currentFormat.pos = m_text.length();
00263 m_state.formatList.append( m_state.currentFormat );
00264 return TRUE;
00265 }
00266
00267 if( tag == "u" )
00268 {
00269 m_state.currentFormat.underline = FALSE;
00270 m_state.currentFormat.pos = m_text.length();
00271 m_state.formatList.append( m_state.currentFormat );
00272 return TRUE;
00273 }
00274
00275 if( tag == "big" )
00276 {
00277 m_state.currentFormat.fontsize = WMLFormat::Normal;
00278 m_state.currentFormat.pos = m_text.length();
00279 m_state.formatList.append( m_state.currentFormat );
00280 return TRUE;
00281 }
00282
00283 if( tag == "small" )
00284 {
00285 m_state.currentFormat.fontsize = WMLFormat::Normal;
00286 m_state.currentFormat.pos = m_text.length();
00287 m_state.formatList.append( m_state.currentFormat );
00288 return TRUE;
00289 }
00290
00291 if( tag == "a" )
00292 {
00293 m_inBlock = true;
00294 m_inLink = false;
00295 m_state.formatList.append( m_state.currentFormat );
00296 return true;
00297 }
00298
00299
00300 if( tag == "table" )
00301 {
00302 popState();
00303 return m_parser->doEndTable();
00304 }
00305
00306
00307 if( tag == "tr" )
00308 return TRUE;
00309
00310
00311 if( tag == "td" )
00312 {
00313 m_inBlock = FALSE;
00314 return flushParagraph();
00315 }
00316
00317
00318 return TRUE;
00319 }
00320
00321 bool WMLHandler::characters( const QString& ch )
00322 {
00323 if( m_inBlock )
00324 m_text.append( ch );
00325
00326 if( m_inLink )
00327 m_state.currentFormat.link.append( ch );
00328
00329 return TRUE;
00330 }
00331
00332 bool WMLHandler::flushParagraph()
00333 {
00334
00335 for( unsigned i=0; i<m_state.formatList.count(); i++ )
00336 {
00337 int nextpos;
00338 WMLFormat& format = m_state.formatList[i];
00339 if( i < m_state.formatList.count()-1 )
00340 {
00341 WMLFormat& nextformat = m_state.formatList[i+1];
00342 nextpos = nextformat.pos;
00343 }
00344 else nextpos = m_text.length();
00345 if( format.len <= 0 )
00346 format.len = nextpos - format.pos;
00347 }
00348
00349 bool result = m_parser->doParagraph( m_text, m_state.formatList, m_state.currentLayout );
00350
00351
00352 m_text = "";
00353 m_state.formatList.clear();
00354 m_state.currentLayout = WMLLayout();
00355
00356
00357
00358
00359 return result;
00360 }
00361
00362 void WMLHandler::pushState()
00363 {
00364 m_stateStack.push( m_state );
00365 }
00366
00367 void WMLHandler::popState()
00368 {
00369 if( !m_stateStack.isEmpty() )
00370 m_state = m_stateStack.pop();
00371 }
00372
00373
00374 WMLFormat::WMLFormat()
00375 {
00376 pos = len = 0;
00377 fontsize = Normal;
00378 bold = italic = underline = FALSE;
00379 link = "";
00380 href = "";
00381 }
00382
00383 void WMLFormat::assign( const WMLFormat& f )
00384 {
00385 pos = f.pos;
00386 len = f.len;
00387 bold = f.bold;
00388 italic = f.italic;
00389 underline = f.underline;
00390 fontsize = f.fontsize;
00391 link = f.link;
00392 href= f.href;
00393 }
00394
00395 WMLFormat::WMLFormat( const WMLFormat& f )
00396 {
00397 assign( f );
00398 }
00399
00400 WMLFormat& WMLFormat::operator=( const WMLFormat& f )
00401 {
00402 assign( f );
00403 return *this;
00404 }
00405
00406
00407 WMLLayout::WMLLayout()
00408 {
00409 align = Left;
00410 }
00411
00412 void WMLLayout::assign( const WMLLayout& l )
00413 {
00414 align = l.align;
00415 }
00416
00417 WMLLayout::WMLLayout( const WMLLayout& l )
00418 {
00419 assign( l );
00420 }
00421
00422 WMLLayout& WMLLayout::operator=( const WMLLayout& l )
00423 {
00424 assign( l );
00425 return *this;
00426 }
00427
00428
00429 void WMLParser::parse( const char* filename )
00430 {
00431 QFile f( filename );
00432 QXmlInputSource source( &f );
00433 QXmlSimpleReader reader;
00434 WMLHandler handler( this );
00435 reader.setContentHandler( &handler );
00436 reader.parse( source );
00437 }
00438
00439 bool WMLParser::doOpenDocument()
00440 {
00441 return TRUE;
00442 }
00443
00444 bool WMLParser::doCloseDocument()
00445 {
00446 return TRUE;
00447 }
00448
00449 bool WMLParser::doOpenCard( QString, QString )
00450 {
00451 return TRUE;
00452 }
00453
00454 bool WMLParser::doCloseCard()
00455 {
00456 return TRUE;
00457 }
00458
00459 bool WMLParser::doParagraph( QString, WMLFormatList, WMLLayout )
00460 {
00461 return TRUE;
00462 }
00463
00464 bool WMLParser::doBeginTable()
00465 {
00466 return TRUE;
00467 }
00468
00469 bool WMLParser::doEndTable()
00470 {
00471 return TRUE;
00472 }
00473
00474 bool WMLParser::doTableCell( unsigned, unsigned )
00475 {
00476 return TRUE;
00477 }
|