1 #include <libxslt/xsltconfig.h>
2 #include <libxslt/xsltInternals.h>
3 #include <libxslt/transform.h>
4 #include <libxslt/xsltutils.h>
5 #include <libxml/xmlIO.h>
6 #include <libxml/parserInternals.h>
7 #include <libxml/catalog.h>
9 #include <kstandarddirs.h>
13 #include <kinstance.h>
14 #include "tdeio_help.h"
15 #include <tdelocale.h>
17 #include <kfilterbase.h>
18 #include <kfilterdev.h>
19 #include <tqtextcodec.h>
23 #include <klibloader.h>
24 #include <kcharsets.h>
25 #include <gzip/kgzipfilter.h>
26 #include <bzip2/kbzip2filter.h>
27 #include <klibloader.h>
28 #include <tqvaluevector.h>
30 #if !defined( SIMPLE_XSLT )
31 extern HelpProtocol *slave;
32 #define INFO( x ) if (slave) slave->infoMessage(x);
37 int writeToQString(
void * context,
const char * buffer,
int len)
39 TQString *t = (TQString*)context;
40 *t += TQString::fromUtf8(buffer, len);
44 int closeQString(
void * context) {
45 TQString *t = (TQString*)context;
50 TQString transform(
const TQString &pat,
const TQString& tss,
51 const TQValueVector<const char *> ¶ms )
55 INFO(i18n(
"Parsing stylesheet"));
57 xsltStylesheetPtr style_sheet =
58 xsltParseStylesheetFile((
const xmlChar *)tss.latin1());
64 if (style_sheet->indent == 1)
65 xmlIndentTreeOutput = 1;
67 xmlIndentTreeOutput = 0;
69 INFO(i18n(
"Parsing document"));
71 xmlDocPtr doc = xmlParseFile( pat.latin1() );
72 xsltTransformContextPtr ctxt;
74 ctxt = xsltNewTransformContext(style_sheet, doc);
78 INFO(i18n(
"Applying stylesheet"));
79 TQValueVector<const char *> p = params;
81 xmlDocPtr res = xsltApplyStylesheet(style_sheet, doc,
const_cast<const char **
>(&p[0]));
84 xmlOutputBufferPtr outp = xmlOutputBufferCreateIO(writeToQString, (xmlOutputCloseCallback)closeQString, &parsed, 0);
86 INFO(i18n(
"Writing document"));
87 xsltSaveResultTo ( outp, res, style_sheet );
88 xmlOutputBufferFlush(outp);
91 xsltFreeStylesheet(style_sheet);
133 TQString splitOut(
const TQString &parsed,
int index)
135 int start_index = index + 1;
136 while (parsed.at(start_index - 1) !=
'>') start_index++;
143 int endindex = parsed.find(
"</FILENAME>", index);
144 int startindex = parsed.find(
"<FILENAME ", index) + 1;
148 if (startindex > 0) {
149 if (startindex < endindex) {
151 index = startindex + 8;
154 index = endindex + 8;
159 index = endindex + 1;
163 filedata = parsed.mid(start_index, endindex - start_index);
169 index = filedata.find(
"<FILENAME ");
172 int endindex = filedata.findRev(
"</FILENAME>");
173 while (filedata.at(endindex) !=
'>') endindex++;
175 filedata = filedata.left(index) + filedata.mid(endindex);
182 void fillInstance(TDEInstance &ins,
const TQString &srcdir) {
185 if ( srcdir.isEmpty() ) {
186 catalogs += ins.dirs()->findResource(
"data",
"ksgmltools2/customization/catalog.xml");
188 catalogs += ins.dirs()->findResource(
"data",
"ksgmltools2/docbook/xml-dtd-4.2/catalog.xml");
189 ins.dirs()->addResourceType(
"dtd", TDEStandardDirs::kde_default(
"data") +
"ksgmltools2");
191 catalogs += srcdir +
"/customization/catalog.xml:" + srcdir +
"/docbook/xml-dtd-4.2/catalog.xml";
192 ins.dirs()->addResourceDir(
"dtd", srcdir);
195 xmlLoadCatalogs(catalogs.latin1());
198 extern "C" void *init_kbzip2filter();
200 static TQIODevice *getBZip2device(
const TQString &fileName )
202 TQFile * f =
new TQFile( fileName );
203 KLibFactory * factory =
static_cast<KLibFactory*
>(init_kbzip2filter());
204 KFilterBase * base =
static_cast<KFilterBase*
>( factory->create(0,
"bzip2" ) );
208 base->setDevice(f,
true);
209 return new KFilterDev(base,
true);
214 bool saveToCache(
const TQString &contents,
const TQString &filename )
216 TQIODevice *fd = ::getBZip2device(filename);
220 if (!fd->open(IO_WriteOnly))
226 fd->writeBlock( contents.utf8() );
232 static bool readCache(
const TQString &filename,
233 const TQString &cache, TQString &output)
235 kdDebug( 7119 ) <<
"verifyCache " << filename <<
" " << cache << endl;
236 if ( !compareTimeStamps( filename, cache ) )
238 if ( !compareTimeStamps( locate(
"dtd",
"customization/tde-chunk.xsl"), cache ) )
241 kdDebug( 7119 ) <<
"create filter" << endl;
242 TQIODevice *fd = ::getBZip2device(cache);
246 if (!fd->open(IO_ReadOnly))
249 TQFile::remove(cache);
253 kdDebug( 7119 ) <<
"reading" << endl;
259 while ( ( n = fd->readBlock(buffer, 31900) ) > 0)
264 kdDebug( 7119 ) <<
"read " << text.length() << endl;
267 output = TQString::fromUtf8( text );
273 kdDebug( 7119 ) <<
"finished " << endl;
278 TQString lookForCache(
const TQString &filename )
280 kdDebug() <<
"lookForCache " << filename << endl;
281 assert( filename.endsWith(
".docbook" ) );
282 assert( filename.at( 0 ) ==
'/' );
284 TQString cache = filename.left( filename.length() - 7 );
286 if ( readCache( filename, cache +
"cache.bz2", output) )
288 if ( readCache( filename,
289 locateLocal(
"cache",
290 "tdeio_help" + cache +
291 "cache.bz2" ), output ) )
294 return TQString::null;
297 bool compareTimeStamps(
const TQString &older,
const TQString &newer )
299 TQFileInfo _older( older );
300 TQFileInfo _newer( newer );
301 assert( _older.exists() );
302 if ( !_newer.exists() )
304 return ( _newer.lastModified() > _older.lastModified() );
307 TQCString fromUnicode(
const TQString &data )
309 TQTextCodec *locale = TQTextCodec::codecForLocale();
315 const int part_len = 5000;
319 while ( offset < data.length() )
321 part = data.mid( offset, part_len );
322 TQCString test = locale->fromUnicode( part );
323 if ( locale->toUnicode( test ) == part ) {
330 for ( uint i = 0; i < len; i++ ) {
331 TQCString test = locale->fromUnicode( part.mid( i, 1 ) );
332 if ( locale->toUnicode( test ) == part.mid( i, 1 ) ) {
333 if (buffer_len + test.length() + 1 >
sizeof(buffer))
335 strcpy( buffer + buffer_len, test.data() );
336 buffer_len += test.length();
339 res.sprintf(
"&#%d;", TQChar(part.at( i )).unicode() );
340 test = locale->fromUnicode( res );
341 if (buffer_len + test.length() + 1 >
sizeof(buffer))
343 strcpy( buffer + buffer_len, test.data() );
344 buffer_len += test.length();
347 result += TQCString( buffer, buffer_len + 1);
353 void replaceCharsetHeader( TQString &output )
355 TQString name = TQTextCodec::codecForLocale()->name();
356 name.replace( TQString(
"ISO " ),
"iso-" );
357 output.replace( TQString(
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">" ),
358 TQString(
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\">" ).arg( name ) );