From fd282522530f74722f5d4e00b487131b23bfdb70 Mon Sep 17 00:00:00 2001 From: Abs62 Date: Tue, 4 Jul 2017 17:41:38 +0300 Subject: [PATCH] Dsl: Allow dsl tags before subcard '@' sign --- dsl.cc | 35 +++-------------------------------- dsl_details.cc | 21 +++++++++++++-------- dsl_details.hh | 4 +++- 3 files changed, 19 insertions(+), 41 deletions(-) diff --git a/dsl.cc b/dsl.cc index e5366a81..3cc03a6e 100644 --- a/dsl.cc +++ b/dsl.cc @@ -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 ); diff --git a/dsl_details.cc b/dsl_details.cc index f7142d28..1d078713 100644 --- a/dsl_details.cc +++ b/dsl_details.cc @@ -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 diff --git a/dsl_details.hh b/dsl_details.hh index e86e3523..719479f2 100644 --- a/dsl_details.hh +++ b/dsl_details.hh @@ -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;