KDocTools
docbookl10nhelper.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 Copyright (C) 2010 Luigi Toscano <luigi.toscano@tiscali.it> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2.1 of the License, or (at your option) version 3, or any 00008 later version accepted by the membership of KDE e.V. (or its 00009 successor approved by the membership of KDE e.V.), which shall 00010 act as a proxy defined in Section 6 of version 3 of the license. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include <QCoreApplication> 00022 #include <QDebug> 00023 #include <QDir> 00024 #include <QFile> 00025 #include <QIODevice> 00026 #include <QList> 00027 #include <QPair> 00028 #include <QRegExp> 00029 #include <QStringList> 00030 #include <QTextStream> 00031 00032 00033 class LangListType: public QList<QPair<QString,QString> > 00034 { 00035 public: 00036 int searchLang( QString el ) { 00037 00038 for ( int i = 0; i < size(); ++i ) { 00039 if ( at( i ).first == el ) 00040 return i; 00041 } 00042 return -1; 00043 } 00044 }; 00045 00046 int writeLangFile( const QString &fname, const QString &dtdPath, 00047 const LangListType &langMap ) { 00048 00049 QFile outFile( fname ); 00050 if ( ! outFile.open( QIODevice::WriteOnly ) ) { 00051 qCritical() << QString( "Could not write %1" ) 00052 .arg( outFile.fileName() ); 00053 return( 1 ); 00054 } 00055 00056 QTextStream outStream( &outFile ); 00057 outStream << "<?xml version='1.0'?>" << endl; 00058 outStream << QString( "<!DOCTYPE l:i18n SYSTEM \"%1\" [" ) 00059 .arg( dtdPath ) << endl; 00060 00061 LangListType::const_iterator i = langMap.constBegin(); 00062 while ( i != langMap.constEnd() ) { 00063 //qDebug() << (*i).first << ": " << (*i).second; 00064 outStream << QString( "<!ENTITY %1 SYSTEM \"%2\">" ) 00065 .arg( (*i).first ).arg( (*i).second ) << endl; 00066 ++i; 00067 } 00068 outStream << "]>" << endl; 00069 00070 if ( langMap.size() > 0 ) { 00071 outStream 00072 << "<l:i18n xmlns:l=\"http://docbook.sourceforge.net/xmlns/l10n/1.0\">" 00073 << endl; 00074 i = langMap.constBegin(); 00075 while ( i != langMap.constEnd() ) { 00076 outStream << QString( "&%1;" ) 00077 .arg( (*i).first ) << endl; 00078 ++i; 00079 } 00080 outStream << "</l:i18n>" << endl; 00081 } 00082 00083 outFile.close(); 00084 00085 return( 0 ); 00086 } 00087 00088 inline const QString addTrailingSlash( const QString &p ) { 00089 return p.endsWith( "/" ) ? p : p + "/"; 00090 } 00091 00092 int main( int argc, char **argv ) { 00093 QCoreApplication app( argc, argv ); 00094 00095 const QStringList arguments = app.arguments(); 00096 if ( arguments.count() != 4 ) { 00097 qCritical() << "wrong argument count"; 00098 return ( 1 ); 00099 } 00100 00101 const QString l10nDir = addTrailingSlash( arguments[1] ); 00102 const QString l10nCustomDir = addTrailingSlash( arguments[2] ); 00103 const QString destDir = addTrailingSlash( arguments[3] ); 00104 00105 QFile i18nFile( l10nDir + "common/l10n.xml" ); 00106 00107 if ( ! i18nFile.open( QIODevice::ReadOnly ) ) { 00108 qCritical() << i18nFile.fileName() << " not found"; 00109 return( 1 ); 00110 } 00111 00112 const QString all10nFName = destDir + "all-l10n.xml"; 00113 const QString customl10nFName = destDir + "kde-custom-l10n.xml"; 00114 00115 /* 00116 * for each language defined in the original l10n.xml, copy 00117 * it into all-l10n.xml and store it in a list; 00118 **/ 00119 QRegExp rxEntity, rxEntity2, rxDocType, rxDocType2; 00120 rxDocType.setPattern("^\\s*<!DOCTYPE\\s+l:i18n\\s+SYSTEM\\s+\"l10n\\.dtd\"\\s+\\[\\s*$"); 00121 rxDocType2.setPattern("^\\s*<!DOCTYPE\\s+l:i18n\\s+SYSTEM\\s+\"l10n\\.dtd\"\\s*>$"); 00122 rxEntity.setPattern("^\\s*<!ENTITY\\s+([^\\s]+)\\s+SYSTEM\\s+\"([^\\s]+)\">\\s*$"); 00123 rxEntity2.setPattern("^\\s*<l:l10n language=\"([^\\s]+)\"\\s+href=\"([^\\s]+)\"/>\\s*$"); 00124 QTextStream inStream( &i18nFile ); 00125 int parsingState = 0; 00126 00127 LangListType allLangs, customLangs; 00128 00129 bool foundRxEntity = false; 00130 bool foundRxEntity2 = false; 00131 while ( ! inStream.atEnd() ) { 00132 QString line = inStream.readLine(); 00133 00134 switch ( parsingState ) { 00135 case 0: 00136 if ( rxDocType.indexIn( line ) != -1 ) { 00137 parsingState = 1; 00138 //qDebug() << "DTD found"; 00139 } else if ( rxDocType2.indexIn( line ) != -1 ) { 00140 parsingState = 1; 00141 //qDebug() << "DTD found"; 00142 } 00143 break; 00144 case 1: 00145 QString langCode, langFile; 00146 if ( rxEntity.indexIn( line ) != -1 && !foundRxEntity2 ) { 00147 foundRxEntity = true; 00148 langCode = rxEntity.cap( 1 ); 00149 langFile = l10nDir + "common/" + rxEntity.cap( 2 ); 00150 allLangs += qMakePair( langCode, langFile ); 00151 //qDebug() << langCode << " - " << langFile; 00152 } else if ( rxEntity2.indexIn( line ) != -1 && !foundRxEntity ) { 00153 foundRxEntity2 = true; 00154 langCode = rxEntity2.cap( 1 ); 00155 langFile = l10nDir + "common/" + rxEntity2.cap( 2 ); 00156 allLangs += qMakePair( langCode, langFile ); 00157 //qDebug() << langCode << " - " << langFile; 00158 } 00159 break; 00160 } 00161 00162 } 00163 i18nFile.close(); 00164 00165 /* read the list of locally-available custom languages */ 00166 QDir outDir( l10nCustomDir ); 00167 00168 QStringList dirFileFilters; 00169 dirFileFilters << "*.xml"; 00170 QStringList customLangFiles = outDir.entryList( dirFileFilters, 00171 QDir::Files|QDir::NoSymLinks, QDir::Name ); 00172 /* the following two calls to removeOne should not be needed, as 00173 * the customization directory from the sources should not contain 00174 * those files 00175 */ 00176 customLangFiles.removeOne( "all-l10n.xml" ); 00177 customLangFiles.removeOne( "kde-custom-l10n.xml" ); 00178 //qDebug() << "customLangFiles:" << customLangFiles; 00179 00180 /* 00181 * for each custom language (from directory listing), if it is not 00182 * in the list of upstream languages, add it to all-l10n.xml, 00183 * otherwise add it to kde-custom-l10n.xml 00184 */ 00185 QStringList::const_iterator i = customLangFiles.constBegin(); 00186 while ( i != customLangFiles.constEnd() ) { 00187 QString langFile = (*i); 00188 /* remove trailing .xml */ 00189 QString langCode = langFile.left( langFile.length() - 4 ); 00190 00191 QPair<QString,QString> cl = qMakePair( langCode, langFile ); 00192 if ( ( allLangs.searchLang( langCode ) ) > 0 ) { 00193 /* custom language found in upstream list */ 00194 customLangs += cl; 00195 } else { 00196 /* custom language not found in upstream list */ 00197 allLangs += cl; 00198 } 00199 ++i; 00200 } 00201 00202 00203 int res = writeLangFile( all10nFName, l10nDir + "common/l10n.dtd", 00204 allLangs ); 00205 res += writeLangFile( customl10nFName, l10nDir + "common/l10n.dtd", 00206 customLangs ); 00207 00208 return( res ); 00209 }
KDE 4.6 API Reference