mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 10:22:50 +00:00
236 lines
6.8 KiB
C++
236 lines
6.8 KiB
C++
#include "xslt.h"
|
|
|
|
#include <libxslt/xsltconfig.h>
|
|
#include <libxslt/xsltInternals.h>
|
|
#include <libxslt/transform.h>
|
|
#include <libxslt/xsltutils.h>
|
|
#include <libxml/xmlIO.h>
|
|
#include <libxml/parserInternals.h>
|
|
#include <libxml/catalog.h>
|
|
#include <QtCore/QDate>
|
|
#include <QtCore/QDir>
|
|
#include <QtCore/QRegExp>
|
|
#include <QtCore/QTextCodec>
|
|
#include <klocale.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
|
|
#define INFO( x )
|
|
|
|
int writeToQString(void * context, const char * buffer, int len)
|
|
{
|
|
QString *t = (QString*)context;
|
|
*t += QString::fromUtf8(buffer, len);
|
|
return len;
|
|
}
|
|
|
|
int closeQString(void * context) {
|
|
QString *t = (QString*)context;
|
|
*t += '\n';
|
|
return 0;
|
|
}
|
|
|
|
QString transform( const QString &pat, const QString& tss,
|
|
const QVector<const char *> ¶ms )
|
|
{
|
|
QString parsed;
|
|
|
|
INFO(i18n("Parsing stylesheet"));
|
|
xsltStylesheetPtr style_sheet =
|
|
xsltParseStylesheetFile((const xmlChar *)QFile::encodeName(tss).constData());
|
|
|
|
if ( !style_sheet ) {
|
|
return parsed;
|
|
}
|
|
if (style_sheet->indent == 1)
|
|
xmlIndentTreeOutput = 1;
|
|
else
|
|
xmlIndentTreeOutput = 0;
|
|
|
|
INFO(i18n("Parsing document"));
|
|
|
|
xmlParserCtxtPtr pctxt;
|
|
|
|
pctxt = xmlNewParserCtxt();
|
|
if ( pctxt == NULL ) {
|
|
return parsed;
|
|
}
|
|
|
|
xmlDocPtr doc = xmlCtxtReadFile(pctxt, QFile::encodeName(pat), NULL,
|
|
XML_PARSE_NOENT|XML_PARSE_DTDLOAD|XML_PARSE_NONET);
|
|
/* Check both the returned doc (for parsing errors) and the context
|
|
(for validation errors) */
|
|
if (doc == NULL) {
|
|
return parsed;
|
|
} else {
|
|
if (pctxt->valid == 0) {
|
|
xmlFreeDoc(doc);
|
|
return parsed;
|
|
}
|
|
}
|
|
|
|
xsltTransformContextPtr ctxt;
|
|
|
|
ctxt = xsltNewTransformContext(style_sheet, doc);
|
|
if (ctxt == NULL)
|
|
return parsed;
|
|
|
|
INFO(i18n("Applying stylesheet"));
|
|
QVector<const char *> p = params;
|
|
p.append( NULL );
|
|
xmlDocPtr res = xsltApplyStylesheet(style_sheet, doc, const_cast<const char **>(&p[0]));
|
|
xmlFreeDoc(doc);
|
|
if (res != NULL) {
|
|
xmlOutputBufferPtr outp = xmlOutputBufferCreateIO(writeToQString, (xmlOutputCloseCallback)closeQString, &parsed, 0);
|
|
outp->written = 0;
|
|
INFO(i18n("Writing document"));
|
|
xsltSaveResultTo ( outp, res, style_sheet );
|
|
xmlOutputBufferFlush(outp);
|
|
xmlFreeDoc(res);
|
|
}
|
|
xsltFreeStylesheet(style_sheet);
|
|
|
|
if (parsed.isEmpty())
|
|
parsed = ' '; // avoid error message
|
|
return parsed;
|
|
}
|
|
|
|
/*
|
|
xmlParserInputPtr meinExternalEntityLoader(const char *URL, const char *ID,
|
|
xmlParserCtxtPtr ctxt) {
|
|
xmlParserInputPtr ret = NULL;
|
|
|
|
// fprintf(stderr, "loading %s %s %s\n", URL, ID, ctxt->directory);
|
|
|
|
if (URL == NULL) {
|
|
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
|
ctxt->sax->warning(ctxt,
|
|
"failed to load external entity \"%s\"\n", ID);
|
|
return(NULL);
|
|
}
|
|
if (!qstrcmp(ID, "-//OASIS//DTD DocBook XML V4.1.2//EN"))
|
|
URL = "docbook/xml-dtd-4.1.2/docbookx.dtd";
|
|
if (!qstrcmp(ID, "-//OASIS//DTD XML DocBook V4.1.2//EN"))
|
|
URL = "docbook/xml-dtd-4.1.2/docbookx.dtd";
|
|
|
|
QString file;
|
|
if (KGlobal::dirs()->exists( QDir::currentPath() + "/" + URL ) )
|
|
file = QDir::currentPath() + "/" + URL;
|
|
else
|
|
file = locate("dtd", URL);
|
|
|
|
ret = xmlNewInputFromFile(ctxt, file.toLatin1().constData());
|
|
if (ret == NULL) {
|
|
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
|
|
ctxt->sax->warning(ctxt,
|
|
|
|
"failed to load external entity \"%s\"\n", URL);
|
|
}
|
|
return(ret);
|
|
}
|
|
*/
|
|
|
|
QString splitOut(const QString &parsed, int index)
|
|
{
|
|
int start_index = index + 1;
|
|
while (parsed.at(start_index - 1) != '>') start_index++;
|
|
|
|
int inside = 0;
|
|
|
|
QString filedata;
|
|
|
|
while (true) {
|
|
int endindex = parsed.indexOf("</FILENAME>", index);
|
|
int startindex = parsed.indexOf("<FILENAME ", index) + 1;
|
|
|
|
// kDebug() << "FILENAME " << startindex << " " << endindex << " " << inside << " " << parsed.mid(startindex + 18, 15)<< " " << parsed.length();
|
|
|
|
if (startindex > 0) {
|
|
if (startindex < endindex) {
|
|
// kDebug() << "finding another";
|
|
index = startindex + 8;
|
|
inside++;
|
|
} else {
|
|
index = endindex + 8;
|
|
inside--;
|
|
}
|
|
} else {
|
|
inside--;
|
|
index = endindex + 1;
|
|
}
|
|
|
|
if (inside == 0) {
|
|
filedata = parsed.mid(start_index, endindex - start_index);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
index = filedata.indexOf("<FILENAME ");
|
|
|
|
if (index > 0) {
|
|
int endindex = filedata.lastIndexOf("</FILENAME>");
|
|
while (filedata.at(endindex) != '>') endindex++;
|
|
endindex++;
|
|
filedata = filedata.left(index) + filedata.mid(endindex);
|
|
}
|
|
|
|
// filedata.replace(QRegExp(">"), "\n>");
|
|
return filedata;
|
|
}
|
|
|
|
QByteArray fromUnicode( const QString &data )
|
|
{
|
|
QTextCodec *locale = QTextCodec::codecForLocale();
|
|
QByteArray result;
|
|
char buffer[30000];
|
|
uint buffer_len = 0;
|
|
uint len = 0;
|
|
int offset = 0;
|
|
const int part_len = 5000;
|
|
|
|
QString part;
|
|
|
|
while ( offset < data.length() )
|
|
{
|
|
part = data.mid( offset, part_len );
|
|
QByteArray test = locale->fromUnicode( part );
|
|
if ( locale->toUnicode( test ) == part ) {
|
|
result += test;
|
|
offset += part_len;
|
|
continue;
|
|
}
|
|
len = part.length();
|
|
buffer_len = 0;
|
|
for ( uint i = 0; i < len; i++ ) {
|
|
QByteArray test = locale->fromUnicode( part.mid( i, 1 ) );
|
|
if ( locale->toUnicode( test ) == part.mid( i, 1 ) ) {
|
|
if (buffer_len + test.length() + 1 > sizeof(buffer))
|
|
break;
|
|
strcpy( buffer + buffer_len, test.data() );
|
|
buffer_len += test.length();
|
|
} else {
|
|
QString res;
|
|
res.sprintf( "&#%d;", part.at( i ).unicode() );
|
|
test = locale->fromUnicode( res );
|
|
if (buffer_len + test.length() + 1 > sizeof(buffer))
|
|
break;
|
|
strcpy( buffer + buffer_len, test.data() );
|
|
buffer_len += test.length();
|
|
}
|
|
}
|
|
result += QByteArray( buffer, buffer_len + 1);
|
|
offset += part_len;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void replaceCharsetHeader( QString &output )
|
|
{
|
|
QString name;
|
|
name = QTextCodec::codecForLocale()->name();
|
|
name.replace( QString( "ISO " ), "iso-" );
|
|
output.replace( QString( "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">" ),
|
|
QString( "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\">" ).arg( name ) );
|
|
}
|