#include "xslt.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 ¶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 p = params; p.append( NULL ); xmlDocPtr res = xsltApplyStylesheet(style_sheet, doc, const_cast(&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("", index); int startindex = parsed.indexOf(" 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(" 0) { int endindex = filedata.lastIndexOf(""); 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( "" ), QString( "" ).arg( name ) ); }