Dsl: Allow dsl tags before subcard '@' sign

This commit is contained in:
Abs62 2017-07-04 17:41:38 +03:00
parent 5a0a8102b7
commit fd28252253
3 changed files with 19 additions and 41 deletions

35
dsl.cc
View file

@ -714,18 +714,8 @@ void DslDictionary::loadArticle( uint32_t address,
wstring str = wstring( articleData, pos, hpos - pos );
hpos = str.find( L'@');
if( hpos == wstring::npos || str[ hpos - 1 ] == L'\\' )
if( hpos == wstring::npos || str[ hpos - 1 ] == L'\\' || !isAtSignFirst( str ) )
break;
else
{
// Check for unescaped '@' inside string
size_t i;
for( i = 0; i < hpos; i++ )
if( !isDslWs( str[ i ] ) )
break;
if( i < hpos )
break;
}
}
else
break;
@ -1410,18 +1400,8 @@ void DslDictionary::getArticleText( uint32_t articleAddress, QString & headword,
wstring str = wstring( articleData, pos, hpos - pos );
hpos = str.find( L'@');
if( hpos == wstring::npos || str[ hpos - 1 ] == L'\\' )
if( hpos == wstring::npos || str[ hpos - 1 ] == L'\\' || !isAtSignFirst( str ) )
break;
else
{
// Check for unescaped '@' inside string
size_t i;
for( i = 0; i < hpos; i++ )
if( !isDslWs( str[ i ] ) )
break;
if( i < hpos )
break;
}
}
else
break;
@ -2306,16 +2286,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries(
else
{
// Embedded card tag must be placed at first position in line after spaces
bool isEmbeddedCard = true;
for( wstring::size_type i = 0; i < n; i++ )
{
if( !isDslWs( curString[ i ] ) )
{
isEmbeddedCard = false;
break;
}
}
if( !isEmbeddedCard )
if( !isAtSignFirst( curString ) )
{
gdWarning( "Unescaped '@' symbol at line %i", scanner.getLinesRead() - 1 );

View file

@ -139,6 +139,13 @@ string findCodeForDslId( int id )
return string();
}
bool isAtSignFirst( wstring const & str )
{
// Test if '@' is first in string except spaces and dsl tags
QRegExp reg( "[ \\t]*(?:\\[[^\\]]+\\][ \\t]*)*@", Qt::CaseInsensitive, QRegExp::RegExp2 );
return reg.indexIn( gd::toQString( str ) ) == 0;
}
/////////////// ArticleDom
wstring ArticleDom::Node::renderAsText( bool stripTrsTag ) const
@ -182,7 +189,7 @@ ArticleDom::ArticleDom( wstring const & str, string const & dictName,
if ( ch == L'@' && !escaped )
{
if( !firstInLine() )
if( !atSignFirstInLine() )
{
// Not insided card
if( dictName.empty() )
@ -262,7 +269,7 @@ ArticleDom::ArticleDom( wstring const & str, string const & dictName,
// Skip to next '@'
while( !( ch == L'@' && !escaped && firstInLine() ) )
while( !( ch == L'@' && !escaped && atSignFirstInLine() ) )
nextChar();
stringPos--;
@ -777,15 +784,13 @@ void ArticleDom::nextChar() throw( eot )
lineStartPos = stringPos;
}
bool ArticleDom::firstInLine()
bool ArticleDom::atSignFirstInLine()
{
// Check if current position is first after '\n' and leading spaces
// Check if '@' sign is first after '\n', leading spaces and dsl tags
if( stringPos <= lineStartPos )
return true;
for( wchar const * pch = lineStartPos; pch < stringPos - 1; pch++ )
if( *pch != ' ' && *pch != '\t' )
return false;
return true;
return isAtSignFirst( wstring( lineStartPos ) );
}
/////////////// DslScanner

View file

@ -40,6 +40,8 @@ struct DSLLangCode
string findCodeForDslId( int id );
bool isAtSignFirst( wstring const & str );
/// Parses the DSL language, representing it in its structural DOM form.
struct ArticleDom
{
@ -82,7 +84,7 @@ private:
void closeTag( wstring const & name, list< Node * > & stack,
bool warn = true );
bool firstInLine();
bool atSignFirstInLine();
wchar const * stringPos, * lineStartPos;