From 44b5524a9155db990ebcb29dc5c9277b6ba82630 Mon Sep 17 00:00:00 2001 From: Konstantin Isakov Date: Thu, 7 May 2009 14:54:26 +0000 Subject: [PATCH] *! Close any previously opened 'm' tag before opening another one. --- src/dsl_details.cc | 150 +++++++++++++++++++++++++-------------------- src/dsl_details.hh | 3 + 2 files changed, 85 insertions(+), 68 deletions(-) diff --git a/src/dsl_details.cc b/src/dsl_details.cc index c43c9551..5c63f107 100644 --- a/src/dsl_details.cc +++ b/src/dsl_details.cc @@ -134,6 +134,12 @@ ArticleDom::ArticleDom( wstring const & str ): if ( !isClosing ) { + if ( name.size() == 2 && name[ 0 ] == L'm' && iswdigit( name[ 1 ] ) ) + { + // Opening an 'mX' tag closes any previous 'm' tag + closeTag( GD_NATIVE_TO_WS( L"m" ), stack, false ); + } + Node node( Node::Tag(), name, attrs ); if ( stack.empty() ) @@ -149,74 +155,7 @@ ArticleDom::ArticleDom( wstring const & str ): } else { - // Find the tag which is to be closed - - list< Node * >::reverse_iterator n; - - for( n = stack.rbegin(); n != stack.rend(); ++n ) - { - if ( (*n)->tagName == name || checkM( (*n)->tagName, name ) ) - { - // Found it - break; - } - } - - if ( n != stack.rend() ) - { - // If there is a corresponding tag, close all tags above it, - // then close the tag itself, then reopen all the tags which got - // closed. - - list< Node > nodesToReopen; - - while( stack.size() ) - { - bool found = stack.back()->tagName == name || - checkM( stack.back()->tagName, name ); - - if ( !found ) - nodesToReopen.push_back( Node( Node::Tag(), stack.back()->tagName, - stack.back()->tagAttrs ) ); - - if ( stack.back()->empty() ) - { - // Empty nodes are deleted since they're no use - - stack.pop_back(); - - Node * parent = stack.size() ? stack.back() : &root; - - parent->pop_back(); - } - else - stack.pop_back(); - - if ( found ) - break; - } - - while( nodesToReopen.size() ) - { - if ( stack.empty() ) - { - root.push_back( nodesToReopen.back() ); - stack.push_back( &root.back() ); - } - else - { - stack.back()->push_back( nodesToReopen.back() ); - stack.push_back( &stack.back()->back() ); - } - - nodesToReopen.pop_back(); - } - } - else - { - fprintf( stderr, "Warning: no corresponding opening tag for closing tag \"/%ls\" found.\n", - name.c_str() ); - } + closeTag( name, stack ); } // if ( isClosing ) continue; } // if ( ch == '[' ) @@ -401,6 +340,81 @@ ArticleDom::ArticleDom( wstring const & str ): fprintf( stderr, "Warning: %u tags were unclosed.\n", stack.size() ); } +void ArticleDom::closeTag( wstring const & name, + list< Node * > & stack, + bool warn ) +{ + // Find the tag which is to be closed + + list< Node * >::reverse_iterator n; + + for( n = stack.rbegin(); n != stack.rend(); ++n ) + { + if ( (*n)->tagName == name || checkM( (*n)->tagName, name ) ) + { + // Found it + break; + } + } + + if ( n != stack.rend() ) + { + // If there is a corresponding tag, close all tags above it, + // then close the tag itself, then reopen all the tags which got + // closed. + + list< Node > nodesToReopen; + + while( stack.size() ) + { + bool found = stack.back()->tagName == name || + checkM( stack.back()->tagName, name ); + + if ( !found ) + nodesToReopen.push_back( Node( Node::Tag(), stack.back()->tagName, + stack.back()->tagAttrs ) ); + + if ( stack.back()->empty() ) + { + // Empty nodes are deleted since they're no use + + stack.pop_back(); + + Node * parent = stack.size() ? stack.back() : &root; + + parent->pop_back(); + } + else + stack.pop_back(); + + if ( found ) + break; + } + + while( nodesToReopen.size() ) + { + if ( stack.empty() ) + { + root.push_back( nodesToReopen.back() ); + stack.push_back( &root.back() ); + } + else + { + stack.back()->push_back( nodesToReopen.back() ); + stack.push_back( &stack.back()->back() ); + } + + nodesToReopen.pop_back(); + } + } + else + if ( warn ) + { + fprintf( stderr, "Warning: no corresponding opening tag for closing tag \"/%ls\" found.\n", + name.c_str() ); + } +} + void ArticleDom::nextChar() throw( eot ) { if ( !*stringPos ) diff --git a/src/dsl_details.hh b/src/dsl_details.hh index 30c1ad55..daf90f88 100644 --- a/src/dsl_details.hh +++ b/src/dsl_details.hh @@ -68,6 +68,9 @@ struct ArticleDom private: + void closeTag( wstring const & name, list< Node * > & stack, + bool warn = true ); + wchar const * stringPos; class eot {};