• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDocTools

meinproc.cpp

Go to the documentation of this file.
00001 #ifndef _WIN32
00002 extern "C" int xmlLoadExtDtdDefaultValue;
00003 #endif
00004 
00005 #include <QCoreApplication>
00006 #include <config-kdoctools.h>
00007 #include <config.h>
00008 #include <string.h>
00009 #include <sys/time.h>
00010 #include <unistd.h>
00011 #include <libxml/xmlversion.h>
00012 #include <libxml/xmlmemory.h>
00013 #include <libxml/debugXML.h>
00014 #include <libxml/HTMLtree.h>
00015 #include <libxml/xmlIO.h>
00016 #include <libxml/parserInternals.h>
00017 #include <libxslt/xsltconfig.h>
00018 #include <libxslt/xsltInternals.h>
00019 #include <libxslt/transform.h>
00020 #include <libxslt/xsltutils.h>
00021 #include <QtCore/QString>
00022 #include <kstandarddirs.h>
00023 #include <kcomponentdata.h>
00024 #include "xslt.h"
00025 #include <QtCore/QFile>
00026 #include <QtCore/QDir>
00027 #include <kcmdlineargs.h>
00028 #include <klocale.h>
00029 #include <kaboutdata.h>
00030 #include <stdlib.h>
00031 #include <kdebug.h>
00032 #include <QtCore/QTextCodec>
00033 #include <QtCore/QFileInfo>
00034 #include <kshell.h>
00035 #include <kurl.h>
00036 #include <QtCore/QList>
00037 
00038 class MyPair {
00039 public:
00040     QString word;
00041     int base;};
00042 
00043 typedef QList<MyPair> PairList;
00044 
00045 void parseEntry(PairList &list, xmlNodePtr cur, int base)
00046 {
00047     if ( !cur )
00048         return;
00049 
00050     base += atoi( ( const char* )xmlGetProp(cur, ( const xmlChar* )"header") );
00051     if ( base > 10 ) // 10 is the maximum
00052         base = 10;
00053 
00054     /* We don't care what the top level element name is */
00055     cur = cur->xmlChildrenNode;
00056     while (cur != NULL) {
00057 
00058         if ( cur->type == XML_TEXT_NODE ) {
00059             QString words = QString::fromUtf8( ( char* )cur->content );
00060             const QStringList wlist = words.simplified().split( ' ',QString::SkipEmptyParts );
00061             for ( QStringList::ConstIterator it = wlist.begin();
00062                   it != wlist.end(); ++it )
00063             {
00064                 MyPair m;
00065                 m.word = *it;
00066                 m.base = base;
00067                 list.append( m );
00068             }
00069         } else if ( !xmlStrcmp( cur->name, (const xmlChar *) "entry") )
00070             parseEntry( list, cur, base );
00071 
00072         cur = cur->next;
00073     }
00074 
00075 }
00076 
00077 int main(int argc, char **argv) {
00078 
00079     // xsltSetGenericDebugFunc(stderr, NULL);
00080 
00081     KCmdLineOptions options;
00082     options.add("stylesheet <xsl>", ki18n("Stylesheet to use"));
00083     options.add("stdout", ki18n("Output whole document to stdout"));
00084     options.add("o");
00085     options.add("output <file>", ki18n("Output whole document to file"));
00086     options.add("htdig", ki18n("Create a ht://dig compatible index"));
00087     options.add("check", ki18n("Check the document for validity"));
00088     options.add("cache <file>", ki18n("Create a cache file for the document"));
00089     options.add("srcdir <dir>", ki18n("Set the srcdir, for kdelibs"));
00090     options.add("param <key>=<value>", ki18n("Parameters to pass to the stylesheet"));
00091     options.add("+xml", ki18n("The file to transform"));
00092 
00093     KAboutData aboutData( "meinproc4", "kio_help4", ki18n("XML-Translator" ),
00094     "$Revision: 1002073 $",
00095     ki18n("KDE Translator for XML"));
00096 
00097     KCmdLineArgs::init(argc, argv, &aboutData, KCmdLineArgs::CmdLineArgKDE);
00098     KCmdLineArgs::addCmdLineOptions( options );
00099 
00100     QCoreApplication app( argc, argv );
00101     KComponentData ins("kio_help4");
00102     KGlobal::locale();
00103 
00104     KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00105     if ( args->count() != 1 ) {
00106         args->usage();
00107         return ( 1 );
00108     }
00109 
00110     // Need to set SRCDIR before calling fillInstance
00111     QString srcdir;
00112     if ( args->isSet( "srcdir" ) )
00113         srcdir = QDir( args->getOption( "srcdir" ) ).absolutePath();
00114     fillInstance(ins,srcdir);
00115 
00116     LIBXML_TEST_VERSION
00117 
00118     QString checkFilename = args->arg( 0 );
00119     QFileInfo checkFile(checkFilename);
00120     if (!checkFile.exists())
00121     {
00122         kError() << "File '" << checkFilename << "' does not exist." << endl;
00123         return ( 2 );
00124     }
00125     if (!checkFile.isFile())
00126     {
00127         kError() << "'" << checkFilename << "' is not a file." << endl;
00128         return ( 2 );
00129     }
00130     if (!checkFile.isReadable())
00131     {
00132         kError() << "File '" << checkFilename << "' is not readable." << endl;
00133         return ( 2 );
00134     }
00135 
00136     if ( args->isSet( "check" ) ) {
00137         QString pwd_buffer = QDir::currentPath();
00138         QFileInfo file( args->arg( 0 ) );
00139 
00140         QByteArray catalogs;
00141         catalogs += KUrl::fromLocalFile( KStandardDirs::locate( "dtd", "customization/catalog.xml" ) ).toEncoded();
00142         catalogs += ' ';
00143         catalogs += KUrl::fromLocalFile( KStandardDirs::locate( "dtd", "docbook/xml-dtd-4.1.2/catalog.xml" ) ).toEncoded();
00144 
00145         setenv( "XML_CATALOG_FILES", catalogs.constData(), 1 );
00146         QString exe;
00147 #if defined( XMLLINT )
00148         exe = XMLLINT;
00149 #endif
00150         if ( !QFileInfo( exe ).isExecutable() ) {
00151             exe = KStandardDirs::findExe( "xmllint" );
00152             if (exe.isEmpty())
00153                 exe = KStandardDirs::locate( "exe", "xmllint" );
00154         }
00155         if ( QFileInfo( exe ).isExecutable() ) {
00156             QDir::setCurrent( file.absolutePath() );
00157             QString cmd = exe;
00158             cmd += " --valid --noout ";
00159 #ifdef Q_OS_WIN
00160             cmd += file.fileName();
00161 #else
00162             cmd += KShell::quoteArg(file.fileName());
00163 #endif
00164             cmd += " 2>&1";
00165             FILE *xmllint = popen( QFile::encodeName( cmd ).constData(), "r" );
00166             char buf[ 512 ];
00167             bool noout = true;
00168             unsigned int n;
00169             while ( ( n = fread(buf, 1, sizeof( buf ) - 1, xmllint ) ) ) {
00170                 noout = false;
00171                 buf[ n ] = '\0';
00172                 fputs( buf, stderr );
00173             }
00174             pclose( xmllint );
00175             QDir::setCurrent( pwd_buffer );
00176             if ( !noout )
00177                 return 1;
00178         } else {
00179             kWarning() << "couldn't find xmllint";
00180         }
00181     }
00182 
00183     xmlSubstituteEntitiesDefault(1);
00184     xmlLoadExtDtdDefaultValue = 1;
00185 
00186     QVector<const char *> params;
00187 #ifndef Q_WS_WIN
00188     // libxslt parses the path given to outputFile as XPath expression which fails
00189     // see libxslt/xsltEvalUserParams
00190     // this parameter is used only by share/apps/ksgmltools2/docbook/xsl/html/math.xsl
00191     // and is not supported on windows yet
00192     if (args->isSet( "output" ) ) {
00193         params.append( qstrdup( "outputFile" ) );
00194         params.append( qstrdup( args->getOption( "output" ).toLocal8Bit() ) );
00195     }
00196 #endif
00197     {
00198         const QStringList paramList = args->getOptionList( "param" );
00199         QStringList::ConstIterator it = paramList.begin();
00200         QStringList::ConstIterator end = paramList.end();
00201         for ( ; it != end; ++it ) {
00202             const QString tuple = *it;
00203             const int ch = tuple.indexOf( '=' );
00204             if ( ch == -1 ) {
00205                 kError() << "Key-Value tuple '" << tuple << "' lacks a '='!" << endl;
00206                 return( 2 );
00207             }
00208             params.append( qstrdup( tuple.left( ch ).toUtf8() ) );
00209             params.append( qstrdup( tuple.mid( ch + 1 ).toUtf8() )  );
00210         }
00211     }
00212     params.append( NULL );
00213 
00214     bool index = args->isSet( "htdig" );
00215     QString tss = args->getOption( "stylesheet" );
00216     if ( tss.isEmpty() )
00217         tss =  "customization/kde-chunk.xsl";
00218     if ( index )
00219         tss = "customization/htdig_index.xsl" ;
00220 
00221     tss = KStandardDirs::locate( "dtd", tss );
00222 
00223     if ( index ) {
00224         xsltStylesheetPtr style_sheet =
00225             xsltParseStylesheetFile((const xmlChar *)tss.toLatin1().data());
00226 
00227         if (style_sheet != NULL) {
00228 
00229             xmlDocPtr doc = xmlReadFile( QFile::encodeName( args->arg( 0 ) ).constData(), NULL, XML_PARSE_NOENT|XML_PARSE_DTDLOAD|XML_PARSE_NONET );
00230 
00231             xmlDocPtr res = xsltApplyStylesheet(style_sheet, doc, &params[0]);
00232 
00233             xmlFreeDoc(doc);
00234             xsltFreeStylesheet(style_sheet);
00235             if (res != NULL) {
00236                 xmlNodePtr cur = xmlDocGetRootElement(res);
00237                 if (!cur || xmlStrcmp(cur->name, (const xmlChar *) "entry")) {
00238                     fprintf(stderr,"document of the wrong type, root node != entry");
00239                     xmlFreeDoc(res);
00240                     return(1);
00241                 }
00242                 PairList list;
00243                 parseEntry( list, cur, 0 );
00244                 int wi = 0;
00245                 for ( PairList::ConstIterator it = list.constBegin(); it != list.constEnd();
00246                       ++it, ++wi )
00247                     fprintf( stdout, "w\t%s\t%d\t%d\n", ( *it ).word.toUtf8().data(),
00248                              1000*wi/list.count(), ( *it ).base );
00249 
00250                 xmlFreeDoc(res);
00251             } else {
00252                 kDebug() << "couldn't parse document " << args->arg( 0 );
00253             }
00254         } else {
00255             kDebug() << "couldn't parse style sheet " << tss;
00256         }
00257 
00258     } else {
00259         QString output = transform(args->arg( 0 ) , tss, params);
00260         if (output.isEmpty()) {
00261             fprintf(stderr, "unable to parse %s\n", args->arg( 0 ).toLocal8Bit().data());
00262             return(1);
00263         }
00264 
00265         QString cache = args->getOption( "cache" );
00266         if ( !cache.isEmpty() ) {
00267             if ( !saveToCache( output, cache ) ) {
00268                 kError() << i18n( "Could not write to cache file %1." ,  cache ) << endl;
00269             }
00270             goto end;
00271         }
00272 
00273         if (output.indexOf( "<FILENAME " ) == -1 || args->isSet( "stdout" ) || args->isSet("output") )
00274         {
00275             QFile file;
00276             if (args->isSet( "stdout" ) ) {
00277                 file.open( stdout, QIODevice::WriteOnly );
00278             } else {
00279                 if (args->isSet( "output" ) )
00280                    file.setFileName( args->getOption( "output" ));
00281                 else
00282                    file.setFileName( "index.html" );
00283                 file.open(QIODevice::WriteOnly);
00284             }
00285             replaceCharsetHeader( output );
00286 #ifdef Q_WS_WIN
00287             QByteArray data = output.toUtf8();
00288 #else
00289             QByteArray data = output.toLocal8Bit();
00290 #endif
00291             file.write(data.data(), data.length());
00292             file.close();
00293         } else {
00294             int index = 0;
00295             while (true) {
00296                 index = output.indexOf("<FILENAME ", index);
00297                 if (index == -1)
00298                     break;
00299                 int filename_index = index + strlen("<FILENAME filename=\"");
00300 
00301                 QString filename = output.mid(filename_index,
00302                                               output.indexOf("\"", filename_index) -
00303                                               filename_index);
00304 
00305                 QString filedata = splitOut(output, index);
00306                 QFile file(filename);
00307                 file.open(QIODevice::WriteOnly);
00308                 replaceCharsetHeader( filedata );
00309                 QByteArray data = fromUnicode( filedata );
00310                 file.write(data.data(), data.length());
00311                 file.close();
00312 
00313                 index += 8;
00314             }
00315         }
00316     }
00317  end:
00318     xmlCleanupParser();
00319     xmlMemoryDump();
00320     return(0);
00321 }
00322 

KDocTools

Skip menu "KDocTools"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal