mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 19:24:08 +00:00
*! Close any previously opened 'm' tag before opening another one.
This commit is contained in:
parent
cb512b9b11
commit
44b5524a91
|
@ -134,6 +134,12 @@ ArticleDom::ArticleDom( wstring const & str ):
|
||||||
|
|
||||||
if ( !isClosing )
|
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 );
|
Node node( Node::Tag(), name, attrs );
|
||||||
|
|
||||||
if ( stack.empty() )
|
if ( stack.empty() )
|
||||||
|
@ -149,74 +155,7 @@ ArticleDom::ArticleDom( wstring const & str ):
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Find the tag which is to be closed
|
closeTag( name, stack );
|
||||||
|
|
||||||
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() );
|
|
||||||
}
|
|
||||||
} // if ( isClosing )
|
} // if ( isClosing )
|
||||||
continue;
|
continue;
|
||||||
} // if ( ch == '[' )
|
} // if ( ch == '[' )
|
||||||
|
@ -401,6 +340,81 @@ ArticleDom::ArticleDom( wstring const & str ):
|
||||||
fprintf( stderr, "Warning: %u tags were unclosed.\n", stack.size() );
|
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 )
|
void ArticleDom::nextChar() throw( eot )
|
||||||
{
|
{
|
||||||
if ( !*stringPos )
|
if ( !*stringPos )
|
||||||
|
|
|
@ -68,6 +68,9 @@ struct ArticleDom
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void closeTag( wstring const & name, list< Node * > & stack,
|
||||||
|
bool warn = true );
|
||||||
|
|
||||||
wchar const * stringPos;
|
wchar const * stringPos;
|
||||||
|
|
||||||
class eot {};
|
class eot {};
|
||||||
|
|
Loading…
Reference in a new issue