mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 18:32:49 +00:00
247 lines
7.8 KiB
C++
247 lines
7.8 KiB
C++
|
|
#include <config-kdoctools.h>
|
|
#include <config.h>
|
|
#include "xslt.h"
|
|
#include "meinproc_common.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QtCore/QString>
|
|
#include <QtCore/QFile>
|
|
#include <QtCore/QDir>
|
|
#include <QtCore/QTextCodec>
|
|
#include <QtCore/QFileInfo>
|
|
#include <QtCore/QList>
|
|
|
|
#include <kaboutdata.h>
|
|
#include <kcomponentdata.h>
|
|
#include <kcmdlineargs.h>
|
|
#include <kdebug.h>
|
|
#include <klocale.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kshell.h>
|
|
#include <kurl.h>
|
|
|
|
#include <libxml/xmlversion.h>
|
|
#include <libxml/xmlmemory.h>
|
|
#include <libxml/debugXML.h>
|
|
#include <libxml/HTMLtree.h>
|
|
#include <libxml/xmlIO.h>
|
|
#include <libxml/parserInternals.h>
|
|
#include <libxslt/xsltconfig.h>
|
|
#include <libxslt/xsltInternals.h>
|
|
#include <libxslt/transform.h>
|
|
#include <libxslt/xsltutils.h>
|
|
#include <libexslt/exslt.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
|
|
#ifndef _WIN32
|
|
extern "C" int xmlLoadExtDtdDefaultValue;
|
|
#endif
|
|
|
|
class MyPair {
|
|
public:
|
|
QString word;
|
|
int base;};
|
|
|
|
typedef QList<MyPair> PairList;
|
|
|
|
void parseEntry(PairList &list, xmlNodePtr cur, int base)
|
|
{
|
|
if ( !cur )
|
|
return;
|
|
|
|
base += atoi( ( const char* )xmlGetProp(cur, ( const xmlChar* )"header") );
|
|
if ( base > 10 ) // 10 is the maximum
|
|
base = 10;
|
|
|
|
/* We don't care what the top level element name is */
|
|
cur = cur->xmlChildrenNode;
|
|
while (cur != NULL) {
|
|
|
|
if ( cur->type == XML_TEXT_NODE ) {
|
|
QString words = QString::fromUtf8( ( char* )cur->content );
|
|
const QStringList wlist = words.simplified().split( ' ',QString::SkipEmptyParts );
|
|
for ( QStringList::ConstIterator it = wlist.begin();
|
|
it != wlist.end(); ++it )
|
|
{
|
|
MyPair m;
|
|
m.word = *it;
|
|
m.base = base;
|
|
list.append( m );
|
|
}
|
|
} else if ( !xmlStrcmp( cur->name, (const xmlChar *) "entry") )
|
|
parseEntry( list, cur, base );
|
|
|
|
cur = cur->next;
|
|
}
|
|
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
// xsltSetGenericDebugFunc(stderr, NULL);
|
|
|
|
KCmdLineOptions options;
|
|
options.add("stylesheet <xsl>", ki18n("Stylesheet to use"));
|
|
options.add("stdout", ki18n("Output whole document to stdout"));
|
|
options.add("o");
|
|
options.add("output <file>", ki18n("Output whole document to file"));
|
|
options.add("htdig", ki18n("Create a ht://dig compatible index"));
|
|
options.add("check", ki18n("Check the document for validity"));
|
|
options.add("cache <file>", ki18n("Create a cache file for the document"));
|
|
options.add("srcdir <dir>", ki18n("Set the srcdir, for kdelibs"));
|
|
options.add("param <key>=<value>", ki18n("Parameters to pass to the stylesheet"));
|
|
options.add("+xml", ki18n("The file to transform"));
|
|
|
|
KAboutData aboutData( "meinproc4", "kio_help4", ki18n("XML-Translator" ),
|
|
"$Revision$",
|
|
ki18n("KDE Translator for XML"));
|
|
|
|
KCmdLineArgs::init(argc, argv, &aboutData, KCmdLineArgs::CmdLineArgKDE);
|
|
KCmdLineArgs::addCmdLineOptions( options );
|
|
|
|
QCoreApplication app( argc, argv );
|
|
KComponentData ins("kio_help4");
|
|
KGlobal::locale();
|
|
|
|
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
|
if ( args->count() != 1 ) {
|
|
args->usage();
|
|
return ( 1 );
|
|
}
|
|
|
|
exsltRegisterAll();
|
|
|
|
// Need to set SRCDIR before calling fillInstance
|
|
QString srcdir;
|
|
if ( args->isSet( "srcdir" ) )
|
|
srcdir = QDir( args->getOption( "srcdir" ) ).absolutePath();
|
|
fillInstance(ins,srcdir);
|
|
|
|
LIBXML_TEST_VERSION
|
|
|
|
const QString checkFilename = args->arg( 0 );
|
|
CheckFileResult ckr = checkFile( checkFilename );
|
|
if ( ckr != CheckFileSuccess )
|
|
{
|
|
if ( ckr == CheckFileDoesNotExist ) kError() << "File '" << checkFilename << "' does not exist.";
|
|
else if ( ckr == CheckFileIsNotFile ) kError() << "'" << checkFilename << "' is not a file.";
|
|
else if ( ckr == CheckFileIsNotReadable ) kError() << "File '" << checkFilename << "' is not readable.";
|
|
return ( 2 );
|
|
}
|
|
|
|
if ( args->isSet( "check" ) ) {
|
|
|
|
QByteArray catalogs;
|
|
catalogs += KUrl::fromLocalFile( KStandardDirs::locate( "dtd", "customization/catalog.xml" ) ).toEncoded();
|
|
|
|
QString exe;
|
|
#if defined( XMLLINT )
|
|
exe = XMLLINT;
|
|
#endif
|
|
if ( !QFileInfo( exe ).isExecutable() ) {
|
|
exe = KStandardDirs::findExe( "xmllint" );
|
|
if (exe.isEmpty())
|
|
exe = KStandardDirs::locate( "exe", "xmllint" );
|
|
}
|
|
|
|
CheckResult cr = check( checkFilename, exe, catalogs );
|
|
if ( cr != CheckSuccess )
|
|
{
|
|
if ( cr == CheckNoXmllint ) kWarning() << "couldn't find xmllint";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
QVector<const char *> params;
|
|
{
|
|
const QStringList paramList = args->getOptionList( "param" );
|
|
QStringList::ConstIterator it = paramList.begin();
|
|
QStringList::ConstIterator end = paramList.end();
|
|
for ( ; it != end; ++it ) {
|
|
const QString tuple = *it;
|
|
const int ch = tuple.indexOf( '=' );
|
|
if ( ch == -1 ) {
|
|
kError() << "Key-Value tuple '" << tuple << "' lacks a '='!" << endl;
|
|
return( 2 );
|
|
}
|
|
params.append( qstrdup( tuple.left( ch ).toUtf8() ) );
|
|
params.append( qstrdup( tuple.mid( ch + 1 ).toUtf8() ) );
|
|
}
|
|
}
|
|
params.append( NULL );
|
|
|
|
bool index = args->isSet( "htdig" );
|
|
QString tss = args->getOption( "stylesheet" );
|
|
if ( tss.isEmpty() )
|
|
tss = "customization/kde-chunk.xsl";
|
|
if ( index )
|
|
tss = "customization/htdig_index.xsl" ;
|
|
|
|
tss = KStandardDirs::locate( "dtd", tss );
|
|
const QString cache = args->getOption( "cache" );
|
|
const bool usingStdOut = args->isSet( "stdout" );
|
|
const bool usingOutput = args->isSet("output");
|
|
const QString outputOption = args->getOption( "output" );
|
|
|
|
if ( index ) {
|
|
xsltStylesheetPtr style_sheet =
|
|
xsltParseStylesheetFile((const xmlChar *)tss.toLatin1().data());
|
|
|
|
if (style_sheet != NULL) {
|
|
|
|
xmlDocPtr doc = xmlReadFile( QFile::encodeName( checkFilename ).constData(),
|
|
NULL, XML_PARSE_NOENT|XML_PARSE_DTDLOAD|XML_PARSE_NONET );
|
|
xmlDocPtr res = xsltApplyStylesheet(style_sheet, doc, ¶ms[0]);
|
|
|
|
xmlFreeDoc(doc);
|
|
xsltFreeStylesheet(style_sheet);
|
|
if (res != NULL) {
|
|
xmlNodePtr cur = xmlDocGetRootElement(res);
|
|
if (!cur || xmlStrcmp(cur->name, (const xmlChar *) "entry")) {
|
|
fprintf(stderr,"document of the wrong type, root node != entry");
|
|
xmlFreeDoc(res);
|
|
return(1);
|
|
}
|
|
PairList list;
|
|
parseEntry( list, cur, 0 );
|
|
int wi = 0;
|
|
for ( PairList::ConstIterator it = list.constBegin(); it != list.constEnd();
|
|
++it, ++wi )
|
|
fprintf( stdout, "w\t%s\t%d\t%d\n", ( *it ).word.toUtf8().data(),
|
|
1000*wi/list.count(), ( *it ).base );
|
|
|
|
xmlFreeDoc(res);
|
|
} else {
|
|
kDebug() << "couldn't parse document " << checkFilename;
|
|
}
|
|
} else {
|
|
kDebug() << "couldn't parse style sheet " << tss;
|
|
}
|
|
|
|
} else {
|
|
QString output = transform(checkFilename , tss, params);
|
|
if (output.isEmpty()) {
|
|
fprintf(stderr, "unable to parse %s\n", checkFilename.toLocal8Bit().data());
|
|
return(1);
|
|
}
|
|
|
|
if ( !cache.isEmpty() ) {
|
|
if ( !saveToCache( output, cache ) ) {
|
|
kError() << i18n( "Could not write to cache file %1." , cache ) << endl;
|
|
}
|
|
goto end;
|
|
}
|
|
|
|
doOutput(output, usingStdOut, usingOutput, outputOption, true /* replaceCharset */);
|
|
}
|
|
end:
|
|
xmlCleanupParser();
|
|
xmlMemoryDump();
|
|
return(0);
|
|
}
|
|
|