From 661dd4d1403d88ede7d0d7cdf2a9ec936059daef Mon Sep 17 00:00:00 2001 From: Abs62 Date: Thu, 19 Jan 2023 17:57:47 +0300 Subject: [PATCH] XDXF: Add support for draft revision 034 (issue #1600) --- xdxf.cc | 72 ++++++++++++++++++++++++++++++++++++++++++---------- xdxf.hh | 2 ++ xdxf2html.cc | 31 ++++++++++++++++++++-- 3 files changed, 90 insertions(+), 15 deletions(-) diff --git a/xdxf.cc b/xdxf.cc index b3010c44..141a7407 100644 --- a/xdxf.cc +++ b/xdxf.cc @@ -62,6 +62,22 @@ using BtreeIndexing::WordArticleLink; using BtreeIndexing::IndexedWords; using BtreeIndexing::IndexInfo; +quint32 getLanguageId( const QString & lang ) +{ + QString lstr = lang.left( 3 ); + + if( lstr.endsWith( QChar( '-' ) ) ) + lstr.chop( 1 ); + + switch( lstr.size() ) + { + case 2: return LangCoder::code2toInt( lstr.toLatin1().data() ); + case 3: return LangCoder::findIdForLanguageCode3( lstr.toLatin1().data() ); + } + + return 0; +} + namespace { DEF_EX_STR( exCantReadFile, "Can't read file", Dictionary::Ex ) @@ -72,7 +88,7 @@ DEF_EX_STR( exDictzipError, "DICTZIP error", Dictionary::Ex ) enum { Signature = 0x46584458, // XDXF on little-endian, FXDX on big-endian - CurrentFormatVersion = 5 + BtreeIndexing::FormatVersion + Folding::Version + CurrentFormatVersion = 6 + BtreeIndexing::FormatVersion + Folding::Version }; enum ArticleFormat @@ -1241,25 +1257,19 @@ vector< sptr< Dictionary::Class > > makeDictionaries( // Read the xdxf string str = stream.attributes().value( "lang_from" ).toString().toLatin1().data(); - - if ( str.size() > 3 ) - str.resize( 3 ); - - idxHeader.langFrom = LangCoder::findIdForLanguageCode3( str.c_str() ); + if( !str.empty() ) + idxHeader.langFrom = getLanguageId( str.c_str() ); str = stream.attributes().value( "lang_to" ).toString().toLatin1().data(); - - if ( str.size() > 3 ) - str.resize( 3 ); - - idxHeader.langTo = LangCoder::findIdForLanguageCode3( str.c_str() ); - - bool isLogical = ( stream.attributes().value( "format" ) == "logical" ); + if( !str.empty() ) + idxHeader.langTo = getLanguageId( str.c_str() ); QRegExp regNum( "\\d+" ); regNum.indexIn( stream.attributes().value( "revision" ).toString() ); idxHeader.revisionNumber = regNum.cap().toUInt(); + bool isLogical = ( stream.attributes().value( "format" ) == "logical" || idxHeader.revisionNumber >= 34 ); + idxHeader.articleFormat = isLogical ? Logical : Visual; unsigned articleCount = 0, wordCount = 0; @@ -1302,6 +1312,12 @@ vector< sptr< Dictionary::Class > > makeDictionaries( // todo implement adding other information to the description like , , , , , , , QString desc = readXhtmlData( stream ); + if( isLogical ) + { + desc = desc.simplified(); + desc.replace( QRegExp( "\\s*
" ), QChar( '\n' ) ); + } + if ( dictionaryDescription.isEmpty() ) { dictionaryDescription = desc; @@ -1319,6 +1335,36 @@ vector< sptr< Dictionary::Class > > makeDictionaries( } } else + if( stream.name() == "languages" ) + { + while( !( stream.isEndElement() && stream.name() == "languages" ) && !stream.atEnd() ) + { + if( !stream.readNext() ) + break; + if ( stream.isStartElement() ) + { + if( stream.name() == "from" ) + { + if( idxHeader.langFrom == 0 ) + { + QString lang = stream.attributes().value( "xml:lang" ).toString(); + idxHeader.langFrom = getLanguageId( lang ); + } + } + else if( stream.name() == "to" ) + { + if( idxHeader.langTo == 0 ) + { + QString lang = stream.attributes().value( "xml:lang" ).toString(); + idxHeader.langTo = getLanguageId( lang ); + } + } + } + else if ( stream.isEndElement() && stream.name() == "languages" ) + break; + } + } + else if ( stream.name() == "abbreviations" ) { QString s; diff --git a/xdxf.hh b/xdxf.hh index 880b2b50..e418d190 100644 --- a/xdxf.hh +++ b/xdxf.hh @@ -12,6 +12,8 @@ namespace Xdxf { using std::vector; using std::string; +quint32 getLanguageId( const QString & lang ); + vector< sptr< Dictionary::Class > > makeDictionaries( vector< string > const & fileNames, string const & indicesDir, diff --git a/xdxf2html.cc b/xdxf2html.cc index 99724256..d2575654 100644 --- a/xdxf2html.cc +++ b/xdxf2html.cc @@ -14,6 +14,7 @@ #include "htmlescape.hh" #include "qt4x5.hh" #include +#include "xdxf.hh" #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) #include @@ -233,8 +234,20 @@ string convert( string const & in, DICT_TYPE type, map < string, string > const el.setTagName( "div" ); el.setAttribute( "class", "xdxf_headwords" ); - if( dictPtr->isFromLanguageRTL() != dictPtr->isToLanguageRTL() ) - el.setAttribute( "dir", dictPtr->isFromLanguageRTL() ? "rtl" : "ltr" ); + bool isLanguageRtl = dictPtr->isFromLanguageRTL(); + if( el.hasAttribute( "xml:lang" ) ) + { + // Change xml-attribute "xml:lang" to html-attribute "lang" + QString lang = el.attribute( "xml:lang" ); + el.removeAttribute( "xml:lang" ); + el.setAttribute( "lang", lang ); + + quint32 langID = Xdxf::getLanguageId( lang ); + if( langID ) + isLanguageRtl = LangCoder::isLanguageRTL( langID ); + } + if( isLanguageRtl != dictPtr->isToLanguageRTL() ) + el.setAttribute( "dir", isLanguageRtl ? "rtl" : "ltr" ); } } @@ -329,6 +342,20 @@ string convert( string const & in, DICT_TYPE type, map < string, string > const QDomElement el = nodes.at( 0 ).toElement(); el.setTagName( "span" ); el.setAttribute( "class", "xdxf_def" ); + bool isLanguageRtl = dictPtr->isToLanguageRTL(); + if( el.hasAttribute( "xml:lang" ) ) + { + // Change xml-attribute "xml:lang" to html-attribute "lang" + QString lang = el.attribute( "xml:lang" ); + el.removeAttribute( "xml:lang" ); + el.setAttribute( "lang", lang ); + + quint32 langID = Xdxf::getLanguageId( lang ); + if( langID ) + isLanguageRtl = LangCoder::isLanguageRTL( langID ); + } + if( isLanguageRtl != dictPtr->isToLanguageRTL() ) + el.setAttribute( "dir", isLanguageRtl ? "rtl" : "ltr" ); } }