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

KDocTools

meinproc.cpp

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

KDocTools

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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