From e9ce9c89e83f84f07ded0a8c0eb5c64891bf91d9 Mon Sep 17 00:00:00 2001 From: Abs62 Date: Fri, 8 Nov 2013 16:53:22 +0400 Subject: [PATCH] DSL: Avoid breaking of [m] tag by closing some other tag --- dsl_details.cc | 80 ++++++++++++++++++++++++++++++++++++++++++-------- dsl_details.hh | 2 ++ 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/dsl_details.cc b/dsl_details.cc index 752015a0..bb9ccca6 100644 --- a/dsl_details.cc +++ b/dsl_details.cc @@ -229,19 +229,7 @@ ArticleDom::ArticleDom( wstring const & str ): // Opening an 'mX' or 'm' tag closes any previous 'm' tag closeTag( GD_NATIVE_TO_WS( L"m" ), stack, false ); } - - Node node( Node::Tag(), name, attrs ); - - if ( stack.empty() ) - { - root.push_back( node ); - stack.push_back( &root.back() ); - } - else - { - stack.back()->push_back( node ); - stack.push_back( &stack.back()->back() ); - } + openTag( name, attrs, stack ); } else { @@ -474,6 +462,72 @@ ArticleDom::ArticleDom( wstring const & str ): } } +void ArticleDom::openTag( wstring const & name, + wstring const & attrs, + list &stack ) +{ + list< Node > nodesToReopen; + + if( name == GD_NATIVE_TO_WS( L"m" ) || checkM( name, GD_NATIVE_TO_WS( L"m" ) ) ) + { + // All tags above [m] tag will be closed and reopened after + // to avoid break this tag by closing some other tag. + + while( stack.size() ) + { + 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(); + } + } + + // Add tag + + Node node( Node::Tag(), name, attrs ); + + if ( stack.empty() ) + { + root.push_back( node ); + stack.push_back( &root.back() ); + } + else + { + stack.back()->push_back( node ); + stack.push_back( &stack.back()->back() ); + } + + // Reopen tags if needed + + 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(); + } + +} + void ArticleDom::closeTag( wstring const & name, list< Node * > & stack, bool warn ) diff --git a/dsl_details.hh b/dsl_details.hh index b2d7cc92..9bcc1a8b 100644 --- a/dsl_details.hh +++ b/dsl_details.hh @@ -69,6 +69,8 @@ struct ArticleDom private: + void openTag( wstring const & name, wstring const & attr, list< Node * > & stack ); + void closeTag( wstring const & name, list< Node * > & stack, bool warn = true );