summaryrefslogtreecommitdiffstats
path: root/kioslave/info
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit4aed2c8219774f5d797760606b8489a92ddc5163 (patch)
tree3f8c130f7d269626bf6a9447407ef6c35954426a /kioslave/info
downloadtdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz
tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kioslave/info')
-rw-r--r--kioslave/info/LICENSE22
-rw-r--r--kioslave/info/Makefile.am21
-rw-r--r--kioslave/info/info.cc261
-rw-r--r--kioslave/info/info.h36
-rw-r--r--kioslave/info/info.protocol11
-rwxr-xr-xkioslave/info/kde-info2html1031
-rw-r--r--kioslave/info/kde-info2html.conf43
7 files changed, 1425 insertions, 0 deletions
diff --git a/kioslave/info/LICENSE b/kioslave/info/LICENSE
new file mode 100644
index 000000000..9cb70ac77
--- /dev/null
+++ b/kioslave/info/LICENSE
@@ -0,0 +1,22 @@
+The following license is applicable to all files in this directory, with the
+exception of kde-info2html and kde-info2html.conf which are licensed under the GPL,
+since they are based on GPL work.
+
+LICENSE:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/kioslave/info/Makefile.am b/kioslave/info/Makefile.am
new file mode 100644
index 000000000..8db4a20ec
--- /dev/null
+++ b/kioslave/info/Makefile.am
@@ -0,0 +1,21 @@
+## Makefile.am of kdebase/kioslave/info
+
+INCLUDES = $(all_includes)
+
+METASOURCES = AUTO
+
+####### Files
+
+kde_module_LTLIBRARIES = kio_info.la
+
+kio_info_la_SOURCES = info.cc
+kio_info_la_LIBADD = $(LIB_KIO)
+kio_info_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+noinst_HEADERS = info.h
+
+kdelnk_DATA = info.protocol
+kdelnkdir = $(kde_servicesdir)
+
+kio_info_data_DATA = kde-info2html.conf
+kio_info_data_SCRIPTS = kde-info2html
+kio_info_datadir = $(kde_datadir)/kio_info
diff --git a/kioslave/info/info.cc b/kioslave/info/info.cc
new file mode 100644
index 000000000..6b829ec1c
--- /dev/null
+++ b/kioslave/info/info.cc
@@ -0,0 +1,261 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#include <kdebug.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <klocale.h>
+
+#include "info.h"
+
+using namespace KIO;
+
+InfoProtocol::InfoProtocol( const QCString &pool, const QCString &app )
+ : SlaveBase( "info", pool, app )
+ , m_page( "" )
+ , m_node( "" )
+{
+ kdDebug( 7108 ) << "InfoProtocol::InfoProtocol" << endl;
+
+ m_perl = KGlobal::dirs()->findExe( "perl" );
+ m_infoScript = locate( "data", "kio_info/kde-info2html" );
+ m_infoConf = locate("data", "kio_info/kde-info2html.conf");
+
+ if( m_perl.isNull() || m_infoScript.isNull() || m_infoConf.isNull() ) {
+ kdError( 7108 ) << "Critical error: Cannot locate files for HTML-conversion" << endl;
+ QString errorStr;
+ if ( m_perl.isNull() ) {
+ errorStr = "perl.";
+ } else {
+ QString missing =m_infoScript.isNull() ? "kio_info/kde-info2html" : "kio_info/kde-info2html.conf";
+ errorStr = "kde-info2html" + i18n( "\nUnable to locate file %1 which is necessary to run this service. "
+ "Please check your software installation" ).arg( missing );
+ }
+ error( KIO::ERR_CANNOT_LAUNCH_PROCESS, errorStr );
+ exit();
+ }
+
+ kdDebug( 7108 ) << "InfoProtocol::InfoProtocol - done" << endl;
+}
+
+InfoProtocol::~InfoProtocol()
+{
+ kdDebug( 7108 ) << "InfoProtocol::~InfoProtocol" << endl;
+
+ kdDebug( 7108 ) << "InfoProtocol::~InfoProtocol - done" << endl;
+}
+
+void InfoProtocol::get( const KURL& url )
+{
+ kdDebug( 7108 ) << "InfoProtocol::get" << endl;
+ kdDebug( 7108 ) << "URL: " << url.prettyURL() << " , Path :" << url.path() << endl;
+
+ if (url.path()=="/")
+ {
+ KURL newUrl("info:/dir");
+ redirection(newUrl);
+ finished();
+ return;
+ };
+
+ // some people write info://autoconf instead of info:/autoconf
+ if (!url.host().isEmpty()) {
+ KURL newURl(url);
+ newURl.setPath(url.host()+url.path());
+ newURl.setHost(QString::null);
+ redirection(newURl);
+ finished();
+ return;
+ }
+
+ if ( url.path().right(1) == "/" )
+ {
+ // Trailing / are not supported, so we need to remove them.
+ KURL newUrl( url );
+ QString newPath( url.path() );
+ newPath.truncate( newPath.length()-1 );
+ newUrl.setPath( newPath );
+ redirection( newUrl );
+ finished();
+ return;
+ }
+
+ mimeType("text/html");
+ // extract the path and node from url
+ decodeURL( url );
+
+ QString path = KGlobal::iconLoader()->iconPath("up", KIcon::Toolbar, true);
+ int revindex = path.findRev('/');
+ path = path.left(revindex);
+
+ QString cmd = KProcess::quote(m_perl);
+ cmd += " ";
+ cmd += KProcess::quote(m_infoScript);
+ cmd += " ";
+ cmd += KProcess::quote(m_infoConf);
+ cmd += " ";
+ cmd += KProcess::quote(path);
+ cmd += " ";
+ cmd += KProcess::quote(m_page);
+ cmd += " ";
+ cmd += KProcess::quote(m_node);
+
+ kdDebug( 7108 ) << "cmd: " << cmd << endl;
+
+ FILE *file = popen( QFile::encodeName(cmd), "r" );
+ if ( !file ) {
+ kdDebug( 7108 ) << "InfoProtocol::get popen failed" << endl;
+ error( ERR_CANNOT_LAUNCH_PROCESS, cmd );
+ return;
+ }
+
+ char buffer[ 4096 ];
+ QByteArray array;
+
+ bool empty = true;
+ while ( !feof( file ) )
+ {
+ int n = fread( buffer, 1, sizeof( buffer ), file );
+ if ( !n && feof( file ) && empty ) {
+ error( ERR_CANNOT_LAUNCH_PROCESS, cmd );
+ return;
+ }
+ if ( n < 0 )
+ {
+ // ERROR
+ kdDebug( 7108 ) << "InfoProtocol::get ERROR!" << endl;
+ pclose( file );
+ return;
+ }
+
+ empty = false;
+ array.setRawData( buffer, n );
+ data( array );
+ array.resetRawData( buffer, n );
+ }
+
+ pclose( file );
+
+ finished();
+
+ kdDebug( 7108 ) << "InfoProtocol::get - done" << endl;
+}
+
+void InfoProtocol::mimetype( const KURL& /* url */ )
+{
+ kdDebug( 7108 ) << "InfoProtocol::mimetype" << endl;
+
+ // to get rid of those "Open with" dialogs...
+ mimeType( "text/html" );
+
+ // finish action
+ finished();
+
+ kdDebug( 7108 ) << "InfoProtocol::mimetype - done" << endl;
+}
+
+void InfoProtocol::decodeURL( const KURL &url )
+{
+ kdDebug( 7108 ) << "InfoProtocol::decodeURL" << endl;
+
+ /* Notes:
+ *
+ * I cleaned up the URL decoding and chose not to support URLs in the
+ * form "info:/usr/local/share/info/libc.info.gz" or similar which the
+ * older code attempted (and failed, maybe it had worked once) to do.
+ *
+ * The reason is that an obvious use such as viewing a info file off your
+ * infopath would work for the first page, but then all the links would be
+ * wrong. Of course, one could change kde-info2html to make it work, but I don't
+ * think it worthy, others are free to disagree and write the necessary code ;)
+ *
+ * luis pedro
+ */
+
+ if ( url == KURL( "info:/browse_by_file?special=yes" ) ) {
+ m_page = "#special#";
+ m_node = "browse_by_file";
+ kdDebug( 7108 ) << "InfoProtocol::decodeURL - special - browse by file" << endl;
+ return;
+ }
+
+ decodePath( url.path() );
+
+ kdDebug( 7108 ) << "InfoProtocol::decodeURL - done" << endl;
+}
+
+void InfoProtocol::decodePath( QString path )
+{
+ kdDebug( 7108 ) << "InfoProtocol::decodePath(-" <<path<<"-)"<< endl;
+
+ m_page = "dir"; //default
+ m_node = "";
+
+ // remove leading slash
+ if ('/' == path[0]) {
+ path = path.mid( 1 );
+ }
+ //kdDebug( 7108 ) << "Path: " << path << endl;
+
+ int slashPos = path.find( "/" );
+
+ if( slashPos < 0 )
+ {
+ m_page = path;
+ m_node = "Top";
+ return;
+ }
+
+ m_page = path.left( slashPos );
+
+ // remove leading+trailing whitespace
+ m_node = path.right( path.length() - slashPos - 1).stripWhiteSpace ();
+
+ kdDebug( 7108 ) << "InfoProtocol::decodePath - done" << endl;
+}
+
+// A minimalistic stat with only the file type
+// This seems to be enough for konqueror
+void InfoProtocol::stat( const KURL & )
+{
+ UDSEntry uds_entry;
+ UDSAtom uds_atom;
+
+ // Regular file with rwx permission for all
+ uds_atom.m_uds = KIO::UDS_FILE_TYPE;
+ uds_atom.m_long = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO;
+
+ uds_entry.append( uds_atom );
+
+ statEntry( uds_entry );
+
+ finished();
+}
+
+extern "C" { int KDE_EXPORT kdemain( int argc, char **argv ); }
+
+int kdemain( int argc, char **argv )
+{
+ KInstance instance( "kio_info" );
+
+ kdDebug() << "kio_info starting " << getpid() << endl;
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "Usage: kio_info protocol domain-socket1 domain-socket2\n");
+ exit(-1);
+ }
+
+ InfoProtocol slave( argv[2], argv[3] );
+ slave.dispatchLoop();
+
+ return 0;
+}
diff --git a/kioslave/info/info.h b/kioslave/info/info.h
new file mode 100644
index 000000000..ccf41fc5e
--- /dev/null
+++ b/kioslave/info/info.h
@@ -0,0 +1,36 @@
+#ifndef __info_h__
+#define __info_h__
+
+#include <qobject.h>
+
+#include <kio/slavebase.h>
+
+class KProcess;
+
+class InfoProtocol : public KIO::SlaveBase
+{
+public:
+
+ InfoProtocol( const QCString &pool, const QCString &app );
+ virtual ~InfoProtocol();
+
+ virtual void get( const KURL& url );
+ virtual void stat( const KURL& url );
+ virtual void mimetype( const KURL& url );
+
+protected:
+
+ void decodeURL( const KURL &url );
+ void decodePath( QString path );
+
+private:
+
+ QString m_page;
+ QString m_node;
+
+ QString m_perl;
+ QString m_infoScript;
+ QString m_infoConf;
+};
+
+#endif // __info_h__
diff --git a/kioslave/info/info.protocol b/kioslave/info/info.protocol
new file mode 100644
index 000000000..3bb600aea
--- /dev/null
+++ b/kioslave/info/info.protocol
@@ -0,0 +1,11 @@
+[Protocol]
+exec=kio_info
+protocol=info
+input=none
+output=filesystem
+reading=true
+defaultMimetype=text/html
+determineMimetypeFromExtension=false
+DocPath=kioslave/info.html
+Icon=help_index
+Class=:local
diff --git a/kioslave/info/kde-info2html b/kioslave/info/kde-info2html
new file mode 100755
index 000000000..428d65dbb
--- /dev/null
+++ b/kioslave/info/kde-info2html
@@ -0,0 +1,1031 @@
+#!/usr/bin/perl
+#---------------------------------------------------------
+# info2html
+#---------------------------------------------------------
+#
+# PURPOSE
+# This perl script converts info nodes to HTML format.
+# The node is specified on the command line using the
+# syntax
+# (<infofile>)<tag>
+# If <infofile> and/or <tag> are missing, (dir)Top is assumed.
+#
+# AUTHOR
+# Karl Guggisberg <guggis@iam.unibe.ch>
+#
+# Changes for the KDE Help Center (c) 1999 Matthias ELter
+# (me@kde.org)
+#
+# LICENSE
+# GPL
+#
+# HISTORY
+# 11.10.93 V 1.0
+# 14.10.93 V 1.0a some comments added
+# 15.10.93 V 1.0b file for configuration settings
+# 16.10.93 V 1.0c multiple info path possible
+# some bugs in escaping references removed
+# 28.6.94 V 1.0d some minor changes
+# 8.4.95 V 1.1 bug fixes by Tim Witham
+# <twitham@eng.fm.intel.com>
+# March 1999 Changes for use in KDE Help Center
+# February 2000 Changes for bzip2 format
+# Sept. 4 2002 Updated to the KDE look
+# by Hisham Muhammad <hisham@apple2.com>
+# January 30 2003 Ported Hisham's work to HEAD
+# by David Pashley <david@davidpashley.com>
+# March 6 2003 Substitute use of absolute fixed file URLs to images with help:common URLs
+# for the images and style sheet. By Luis Pedro Coelho
+# March 9 2003 Add support for browsing by file. by Luis Pedro Coelho
+# June 11 2003 Update the layout of the sides to the new infopageslayout.
+# by Sven Leiber <s.leiber@web.de>
+#
+#-------------------------------------------------------
+
+use strict;
+
+# set here the full path of the info2html.conf
+push @INC, $1 if $0 =~ m!(.*/)[^/]+$!; # full path of config file is passed in ARGV[1] by caller but let's clean this anyway
+my $IMAGEDIR = "file:$ARGV[1]/"; # TV: broken, broken, not passed
+my $config_file = $ARGV[0];
+delete $ENV{CDPATH};
+delete $ENV{ENV};
+require $config_file; #-- configuration settings
+
+my $STYLESHEET_KDE = "<link rel=\"stylesheet\" href=\"help:common/kde-default.css\" type=\"text/css\"/>";
+my $LOGO_KDE = "<img src=\"help:/common/kde_logo.png\" alt=\"KDE - The K Desktop Environment\" width=\"296\" height=\"79\" border=\"0\">";
+
+# the use of a query should make sure it never conflicts with a "real" path
+my $BROWSE_BY_FILE_PATH = '/browse_by_file?special=yes';
+
+
+my $DONTPRINTYET = 'DONTPRINTYET ';
+
+#-- patterns
+my $NODEBORDER = '\037\014?'; #-- delimiter of an info node
+my $REDIRSEP = '\177'; #-- delimiter in tag tables
+my $WS = '[ \t]+'; #-- white space +
+my $WSS = '[ \t]*'; #-- white space *
+my $TE = '[\t\,\.]'; #-- end of a tag
+my $TAG = '[^\t\,\.]+'; #-- pattern for a tag
+my $FTAG = '[^\)]+'; #-- pattern for a file name in
+ #-- a cross reference
+
+#---------------------------------------------------------
+# DieFileNotFound
+#---------------------------------------------------------
+# Replies and error message if the file '$FileName' is
+# not accessible.
+#---------------------------------------------------------
+sub DieFileNotFound {
+ my ($FileName) = @_;
+ $FileName =~ s/&/&amp;/g;
+ $FileName =~ s/>/&gt;/g;
+ $FileName =~ s/</&lt;/g;
+
+ #-- TEXT : error message if a file could not be opened
+ print <<EOF;
+<head>
+<title>Info: (no page found)</title>
+</head>
+<body>
+<h1>KDE Info Pages Viewer Error</h1>
+ No info page for topic <code>"$FileName"</code> found.<br>
+ You may find what you are looking for at the <a href="man:$FileName">$FileName manpage</a>.
+</body>
+EOF
+ die "\n";
+}
+
+#---------------------------------------------------------
+# Redirect
+#---------------------------------------------------------
+# Since we can't do a kioslave redirection from here, we resort to an HTML
+# redirection.
+#
+# It could be simpler to just output the correct page, but that would leave the
+# the browser URL indication a bit wrong and more importantly we might mess up relative links.
+# Therefore, I implemented it like this which is simpler if not as nice on the end user
+# who sees a flicker.
+#---------------------------------------------------------
+
+sub Redirect {
+ my ($File,$Tag) = @_;
+ print <<EOF;
+ <html><head><title>Doing redirection</title>
+ <meta http-equiv="refresh" content="0; url=info:$File/$Tag">
+ <body>
+ <h1>Redirecting .... </h1>
+ <p>If you are not automatically taken to a new page, <a href="info:$File/$Tag">click here</a> to continue.
+ </body>
+ </html>
+EOF
+
+ exit 0;
+}
+
+#---------------------------------------------------------
+# FileNotFound
+#---------------------------------------------------------
+# If the file is not found and the node is '', try to go through
+# dir entries.
+# This deals with cases like info:ls should open "coreutils/ls invocation"
+#---------------------------------------------------------
+sub FileNotFound {
+ my ($FileName,$NodeName) = @_;
+ DieFileNotFound($FileName) if $NodeName ne 'Top' || $FileName eq 'dir';
+ # Try to find it in dir
+
+ my $DirFileName = &FindFile('dir');
+ if ($DirFileName =~ m/.info.bz2$/ ) {
+ open DIR, "-|", "bzcat", $DirFileName;
+ }
+ elsif ($DirFileName =~ m/.info.gz$/ ) {
+ open DIR, "-|", "gzip", "-dc", $DirFileName;
+ }
+ else {
+ open DIR, $DirFileName;
+ }
+ my $looking = 1;
+ while (<DIR>) {
+ next if $looking && !/\* Menu/;
+ $looking = 0;
+ my @item = &ParseMenuItem($_,'dir');
+ if (!defined(@item)) { next }
+ my ($MenuLinkTag, $MenuLinkFile, $MenuLinkRef, $MenuLinkText) = @item;
+ if ($MenuLinkRef eq $FileName) {
+ &Redirect($MenuLinkFile, $MenuLinkTag);
+ exit 0;
+ }
+ }
+ &DieFileNotFound($FileName);
+}
+
+#---------------------------------------------------------
+# Escape
+#---------------------------------------------------------
+# This procedures escapes some special characeters. The
+# escape sequence follows the WWW guide for escaped
+# characters in URLs
+#---------------------------------------------------------
+sub Escape {
+ my ($Tag) = @_;
+ #-- escaping is not needed anymore KG/28.6.94
+ #-- it is, for "?" %3f (info:/cvs/What is CVS?), kaper/23.7.02
+ $Tag =~ s/ /%20/g; # space
+ $Tag =~ s/\?$/%3f/g; # space
+ $Tag =~ s/\"/%22/g; # space
+ $Tag =~ s/\#/%23/g;
+# $Tag =~ s/\+/%AB/g; # +
+ $Tag;
+}
+
+#----------------------------------------------------------
+# DirnameCheck
+# TV: This is totally broken.
+# I don't know what was the original attempt but that code
+# cannot work ! we cannot match the info name (which has no full path)
+# with the info path ...
+# The only thing i can see (guessed from the || part of the caller)
+# is that we try to reject files with "/" in their name, guessing
+# we pass a man page full path instead of a info file name ...
+# In *that* case, the flow logic is inverted and we should have used "&&"
+# instead of "||"
+#
+# Thus the commented out call...
+#----------------------------------------------------------
+#sub DirnameCheck {
+# my ($Base) = @_;
+# my $Dir = $Base;
+#
+# $Base =~ s!.*/!!g;
+# $Dir =~ s!\Q$Base\E!!;
+#
+# foreach (@info2html::config::INFODIR) {
+# return 1 if $Dir =~ /^$_/;
+# }
+#
+# foreach my $i (split(/:/, $ENV{INFOPATH})) {
+# return 1 if $Dir =~ /^$i/;
+# }
+#
+# return 0;
+#}
+
+#----------------------------------------------------------
+# DeEscape
+#----------------------------------------------------------
+#sub DeEscape {
+# my ($Tag) = @_;
+# #-- deescaping is not needed anymore. KG/28.6.94
+# $Tag =~ s/%AB/+/g;
+# $Tag =~ s/%20/ /g;
+# $Tag =~ s/\.\.\///g;
+# $Tag =~ s/\.\.//g;
+# $Tag =~ s/\.\///g;
+# $Tag;
+#}
+
+sub infocat {
+# Collect them all into an array that can be sorted
+
+ my %InfoFile;
+ my %LinkText;
+ my @dirs;
+
+ foreach my $dir (@info2html::config::INFODIR) {
+ push @dirs, $dir;
+ }
+ if ($ENV{'INFOPATH'}) {
+ foreach my $dir (split(/:/, $ENV{INFOPATH})) {
+ push @dirs, $dir;
+ }
+ }
+
+ foreach my $dir (@dirs) {
+ opendir DIR, $dir;
+ my ($infofile,$filedesc);
+ while ($infofile = readdir(DIR)) {
+ if ($infofile =~ m/.info.bz2$/ ) {
+ open INFOFILE, "-|", "bzcat", "$dir/$infofile";
+ }
+ elsif ($infofile =~ m/.info.gz$/ ) {
+ open INFOFILE, "-|", "gzip", "-dc", "$dir/$infofile";
+ }
+ elsif ($infofile =~ m/.info$/) {
+ open INFOFILE, "-|", "$dir/$infofile";
+ }
+ else {
+ next;
+ }
+ $filedesc = '';
+ my $collect = 0;
+ my $empty = 1;
+ while (<INFOFILE>) {
+ last if (m/END-INFO-DIR-ENTRY/);
+ s/^\* //;
+ chomp;
+ next if /^\s*$/;
+ if ($collect) {
+ $filedesc .= "\n<br>" if ($collect < 16);
+ $filedesc .= $_;
+ --$collect;
+ $empty = 0;
+ } elsif (!$empty && !$collect) {
+ $filedesc .= "<br><b>...</b>\n";
+ last;
+ }
+ $collect=16 if (m/START-INFO-DIR-ENTRY/);
+ }
+ if ($empty) { $filedesc .= 'no description available'; }
+ close INFOFILE;
+ $filedesc .= $infofile if ($filedesc eq "");
+# Add to the hash
+ $LinkText{$filedesc} = "$dir/$infofile";
+ $InfoFile{$filedesc} = "$infofile";
+ }
+ }
+
+# Now output the list
+ my @sorted = sort { lc($a) cmp lc($b) } keys %InfoFile;
+
+ print '<dl>';
+ foreach my $description ( @sorted ) {
+ print <<EOF;
+ <dt> <a href="info:$InfoFile{$description}/Top">$LinkText{$description}</a>
+ <dd>$description
+
+EOF
+ }
+ print '</dl>';
+}
+
+#----------------------------------------------------------
+# ParsHeaderToken
+#----------------------------------------------------------
+# Parses the header line of an info node for a specific
+# link directive (e.g. Up, Prev)
+#
+# Returns a link as (InfoFile,Tag).
+#----------------------------------------------------------
+sub ParsHeaderToken {
+ my ($HeaderLine, $Token) = @_;
+ return ("", "") if $HeaderLine !~ /$Token:/; #-- token not available
+ my ($InfoFile, $node, $Temp);
+ if ($HeaderLine =~ m!$Token:$WS(\(($FTAG)\))!) {
+ $InfoFile = $2;
+ $Temp = $2 ne "" ? '\(' . $2 . '\)' : "";
+ }
+ $node = $1 if $HeaderLine =~ m!$Token:$WS$Temp$WSS([^\t,\n]+)?([\t,\.\n])!;
+ $node ||= "Top";
+ return $InfoFile, $node;
+}
+
+#---------------------------------------------------------
+# ParsHeaderLine
+#--------------------------------------------------------
+# Parses the header line on an info node for all link
+# directives allowed in a header line.
+# Sometimes the keyword 'Previous' is found in stead of
+# 'Prev'. Thats why the redirection line is checked
+# against both of these keywords.
+#-------------------------------------------------------
+sub ParsHeaderLine {
+ my ($HL) = @_;
+ my @LinkList;
+ #-- Node
+ push(@LinkList, &ParsHeaderToken($HL, "Node"));
+ #-- Next
+ push(@LinkList, &ParsHeaderToken($HL, "Next"));
+ #-- Up
+ push(@LinkList, &ParsHeaderToken($HL, "Up"));
+ #-- Prev or Previous
+ my @LinkInfo = &ParsHeaderToken($HL, "Prev");
+ &ParsHeaderToken($HL, "Previous") if $LinkInfo[0] eq "" && $LinkInfo[1] eq "";
+ push(@LinkList, @LinkInfo);
+ return @LinkList;
+}
+
+############################################################
+# turn tabs into correct number of spaces
+#
+sub Tab2Space {
+ my ($line) = @_;
+ $line =~ s/^\t/ /; # 8 leading spaces if initial tab
+ while ($line =~ s/^([^\t]+)(\t)/$1 . ' ' x (8 - length($1) % 8)/e) {
+ } # replace each tab with right num of spaces
+ return $line;
+}
+
+#--------------------------------------------------------
+# ParseMenuItem
+#--------------------------------------------------------
+# Takes a line containing a Menu item and returns a list of
+# ($MenuLinkTag, $MenuLinkFile, $MenuLinkRef, $MenuLinkText)
+# or undef if the parsing fails
+#-------------------------------------------------------
+
+sub ParseMenuItem {
+ my ($Line,$BaseInfoFile) = @_;
+ my ($MenuLinkTag, $MenuLinkFile, $MenuLinkRef, $MenuLinkText);
+ $Line = &Tab2Space($Line); # make sure columns line up well
+
+ if ($Line =~ /\* ([^:]+)::/) { # -- is a simple entry ending with :: ?
+ $MenuLinkTag = $1;
+ $MenuLinkRef = $1;
+ $MenuLinkText = $'; #' --just to help emacs perl-mode
+ $MenuLinkFile = &Escape($BaseInfoFile);
+ } elsif ($Line =~ /\* ([^:]+):(\s*\(($FTAG)\)($TAG)?$TE\.?)?(.*)$/) {
+ $MenuLinkFile = $BaseInfoFile;
+ $MenuLinkRef = $1;
+ $MenuLinkText = $5;
+ if ($2) {
+ $MenuLinkFile = $3;
+ $MenuLinkTag = $4 || 'Top';
+ $MenuLinkText = ($2 ? ' ' x (length($2)+1) : '') . "$5\n";
+ } else {
+ $Line = "$5\n";
+ if ($Line =~ /( *($TAG)?$TE(.*))$/) {
+ $MenuLinkTag = $2;
+ $MenuLinkText = $Line;
+ }
+ }
+ } else {
+ return undef;
+ }
+ $MenuLinkTag = &Escape($MenuLinkTag); # -- escape special chars
+ $MenuLinkText =~ s/^ *//;
+ return ($MenuLinkTag, $MenuLinkFile, $MenuLinkRef, $MenuLinkText);
+}
+
+#--------------------------------------------------------
+# MenuItem2HTML
+#--------------------------------------------------------
+# Transform an info menu item in HTML with references
+#-------------------------------------------------------
+sub MenuItem2HTML {
+ my ($Line, $BaseInfoFile) = @_;
+ my @parse_results = &ParseMenuItem($Line, $BaseInfoFile);
+ if (!defined (@parse_results)) { return $Line; }
+ my ($MenuLinkTag, $MenuLinkFile, $MenuLinkRef, $MenuLinkText) = @parse_results;
+ #-- produce a HTML line
+ return "<tr class=\"infomenutr\"><td class=\"infomenutd\" width=\"30%\"><ul><li><a href=\"info:/$MenuLinkFile/$MenuLinkTag\">$MenuLinkRef</a></ul></td><td class=\"infomenutd\">$MenuLinkText";
+}
+
+#-------------------------------------------------------------
+# ReadIndirectTable
+#------------------------------------------------------------
+# Scans an info file for the occurence of an 'Indirect:'
+# table. Scans the entrys and returns two lists with the
+# filenames and the global offsets.
+#---------------------------------------------------------
+sub ReadIndirectTable {
+ my ($FileName, $FileNames, $Offsets) = @_;
+
+ local *FH1;
+ if ($FileName =~ /\.gz$/) {
+ open FH1, "-|", "gunzip", "-q", "-d", "-c", $FileName || &DieFileNotFound($FileName);
+ } elsif ($FileName =~ /\.bz2$/) {
+ open FH1, "-|", "bunzip2", "-q", "-d", "-c", $FileName || &DieFileNotFound($FileName);
+ } else {
+ open(FH1, $FileName) || &DieFileNotFound($FileName);
+ }
+ #-- scan for start of Indirect: Table
+ local $_;
+ while (<FH1>) {
+ my $Next = <FH1> if /$NODEBORDER/;
+ last if $Next =~ /^Indirect:/i;
+ }
+ #-- scan the entrys and setup the arrays
+ local $_;
+ while (<FH1>) {
+ last if /$NODEBORDER/;
+ if (/([^:]+):[ \t]+(\d+)/) {
+ push(@$FileNames, $1);
+ push(@$Offsets, $2);
+ }
+ }
+ close(FH1);
+}
+
+#---------------------------------------------------------
+# ReadTagTable
+#--------------------------------------------------------
+# Reads in a tag table from an info file.
+# Returns an assoziative array with the tags found.
+# Tags are transformed to lower case (info is not
+# case sensitive for tags).
+# The entrys in the assoziative Array are of the
+# form
+# <file>#<offset>
+# <file> may be empty if an indirect table is
+# present or if the node is located in the
+# main file.
+# 'Exists' indicates if a tag table has been found.
+# 'IsIndirect' indicates if the tag table is based
+# on a indirect table.
+#--------------------------------------------------------
+sub ReadTagTable {
+ my ($FileName, $TagList, $Exists, $IsIndirect) = @_;
+
+ local *FH;
+ if ($FileName =~ /\.gz$/) {
+ open FH, "-|", "gunzip", "-q", "-d", "-c", $FileName || &DieFileNotFound($FileName);
+ } elsif ($FileName =~ /\.bz2$/) {
+ open FH, "-|", "bunzip2", "-q", "-d", "-c", $FileName || &DieFileNotFound($FileName);
+ } else {
+ open FH, $FileName || &DieFileNotFound($FileName);
+ }
+ ($$Exists, $$IsIndirect) = (0, 0);
+ #-- scan for start of tag table
+ local $_;
+ while (<FH>) {
+ if (/$NODEBORDER/) {
+ if (<FH> =~ /^Tag table:/i) {
+ $$Exists = 1;
+ last;
+ }
+ }
+ }
+ #-- scan the entrys
+ local $_;
+ while (<FH>) {
+ $$IsIndirect = 1 if /^\(Indirect\)/i;
+ last if /$NODEBORDER/;
+ if (/Node:[ \t]+([^$REDIRSEP]+)$REDIRSEP(\d+)/) {
+ my ($Tag, $Offset) = (lc($1), $2);
+ my $File = $1 if /File:[ \t]+([^\t,]+)/;
+ $TagList->{$Tag} = $File."#".$Offset;
+ }
+ }
+ close(FH);
+}
+
+#----------------------------------------------------------
+# ParsCrossRefs
+#----------------------------------------------------------
+# scans a line for the existence of cross references and
+# transforms them to HTML using a little icon
+#----------------------------------------------------------
+sub ParsCrossRefs {
+ my ($prev, $Line, $BaseInfoFile) = @_;
+ my ($NewLine, $Token);
+ my ($CrossRef, $CrossRefFile, $CrossRefTag, $CrossRefRef, $CrossRefText);
+ $Line = " " . $Line;
+ if ($prev =~ /\*Note([^\t\,\.]*)$/mi) {
+ $Line = "$prev-NEWLINE-$Line" if $Line =~ /^$TAG$TE/m;
+ }
+ my @Tokens = split(/(\*Note)/i, $Line); # -- split the line
+ while ($Token = shift @Tokens) {
+ $CrossRefTag = $CrossRefRef = $CrossRefFile = $CrossRefText = '';
+ if ($Token !~ /^\*Note/i) { #-- this part is pure text
+ $NewLine .= $Token;
+ next; #-- ... take the next part
+ }
+ $CrossRef = shift(@Tokens);
+ if ($CrossRef !~ /:/) { #-- seems not to be a valid cross ref.
+ $NewLine .= $Token.$CrossRef;
+ next; # -- ... take the next one
+ }
+ if ($CrossRef =~ /^([^:]+)::/) { # -- a simple cross ref..
+ $CrossRefTag = $1;
+ $CrossRefText = $';
+ $CrossRefRef = $CrossRefTag;
+ $CrossRefTag =~ s/-NEWLINE-/ /g;
+ $CrossRefTag =~ s/^\s+//;
+ $CrossRefTag =~ s/\s+/ /g;
+ $CrossRefRef =~ s/-NEWLINE-/\n/g;
+ $CrossRefTag = &Escape($CrossRefTag); # -- escape specials
+ $BaseInfoFile = &Escape($BaseInfoFile);
+ $NewLine .= "<a href=\"info:/$BaseInfoFile/$CrossRefTag\">";
+ $NewLine .= "$CrossRefRef</a>$CrossRefText";
+ next; # -- .. take the next one
+ }
+ if ($CrossRef !~ /$TE/) { # never mind if tag doesn't end on this line
+ $NewLine .= $Token.$CrossRef;
+ next;
+ }
+#print "--- Com. CR : $CrossRef --- \n";
+ if ($CrossRef =~ /([^:]+):/) { #-- A more complicated one ..
+ $CrossRefRef = $1;
+ $CrossRef = $';
+ $CrossRefText = $CrossRef;
+ }
+ if ($CrossRef =~ /^(\s|\n|-NEWLINE-)*\(($FTAG)\)/) { #-- .. with another file ?
+ $CrossRefFile = $2;
+ $CrossRef = $';
+ }
+ $CrossRefTag = $2 if $CrossRef =~ /^(\s|\n|-NEWLINE-)*($TAG)?($TE)/; #-- ... and a tag ?
+ if ($CrossRefTag eq "" && $CrossRefFile eq "") {
+ $NewLine .= "*Note : $CrossRefText$3";
+ next;
+ }
+
+ $CrossRefTag =~ s/-NEWLINE-/ /g;
+ $CrossRefTag =~ s/^\s+//;
+ $CrossRefTag =~ s/\s+/ /g;
+ $CrossRefRef =~ s/-NEWLINE-/\n/g;
+ $CrossRefText =~ s/-NEWLINE-/\n/g;
+ $CrossRefFile = $BaseInfoFile if $CrossRefFile eq "";
+ $CrossRefTag = "Top" if $CrossRefTag eq "";
+ $CrossRefRef = "($CrossRefFile)$CrossRefTag" if $CrossRefRef eq '';
+ $CrossRefTag = &Escape($CrossRefTag); #-- escape specials
+ $CrossRefFile = &Escape($CrossRefFile);
+ #-- append the HTML text
+ $NewLine .= "<a href=\"info:/$CrossRefFile/$CrossRefTag\">";
+ $NewLine .= "$CrossRefRef</a>$CrossRefText";
+ }
+ if ($NewLine =~ /\*Note([^\t\,\.]*)$/i) {
+ return "$DONTPRINTYET$NewLine";
+ } else {
+ $NewLine; #-- return the new line
+ }
+}
+
+
+#-------------------------------------------------------------
+# PrintLinkInfo
+#-------------------------------------------------------------
+# prints the HTML text for a link information in the
+# header of an info node. Uses some icons URLs of icons
+# are specified in 'info2html.conf'.
+#------------------------------------------------------------
+sub PrintLinkInfo {
+ my ($LinkType, $LinkFile, $LinkTag, $BaseInfoFile) = @_;
+ my ($LinkFileEsc, $LinkTypeText);
+ return if $LinkFile eq "" && $LinkTag eq "";
+
+ #-- If no auxiliary file specified use the current info file
+ $LinkFile ||= $BaseInfoFile;
+ my $LinkRef = $LinkTag;
+ $LinkTag = &Escape($LinkTag);
+ $LinkFileEsc = &Escape($LinkFile);
+ #-- print the HTML Text
+ print <<EOF;
+<a href="info:/$LinkFileEsc/$LinkTag">
+ $LinkTypeText
+ <strong>$LinkRef</strong>
+</a>
+EOF
+}
+
+#-------------------------------------------------------------
+# PrintHeader
+#-------------------------------------------------------------
+# Prints the header for an info node in HTML format
+#------------------------------------------------------------
+sub PrintHeader {
+ my ($LinkList, $BaseInfoFile) = @_;
+ my @LinkList = @{$LinkList};
+
+ my $UpcaseInfoFile = $BaseInfoFile;
+ $UpcaseInfoFile =~ tr/a-z/A-Z/;
+ #-- TEXT for the header of an info node
+ print <<EOF;
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>Info: ($BaseInfoFile) $LinkList[1]</title>
+ $STYLESHEET_KDE
+ </head>
+ <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<!--header start-->
+<div style="background-image: url(help:/common/top-middle.png); width: 100%; height: 131px;">
+<div style="position: absolute; right: 0px;">
+<img src="help:/common/top-right-konqueror.png" style="margin: 0px" alt="" />
+</div>
+<div style="position: absolute; left: 0px;">
+<img src="help:/common/top-left.png" style="margin: 0px" alt="" />
+</div>
+<div style="position: absolute; top: 25px; right: 100px; text-align: right; font-size: xx-large; font-weight: bold; text-shadow: #fff 0px 0px 5px; color: #444">
+$UpcaseInfoFile: $LinkList[1]</div>
+</div>
+<div class="header" style="border: none">
+EOF
+ common_headers($LinkList, $BaseInfoFile);
+print <<EOF;
+</div>
+ <div id="contents">
+ <div class="chapter">
+EOF
+}
+
+sub common_headers {
+ my ($LinkList, $BaseInfoFile) = @_;
+ my @LinkList = @{$LinkList};
+ print <<EOF;
+ <tr><td width="33%" align="left" valign="top" class="navLeft">
+EOF
+ &PrintLinkInfo("Prev", $LinkList[6], $LinkList[7], $BaseInfoFile);
+ print <<EOF;
+ </td><td width="34%" align="center" valign="top" class="navCenter">
+EOF
+ &PrintLinkInfo("Up", $LinkList[4], $LinkList[5], $BaseInfoFile);
+ print <<EOF;
+ </td><td width="33%" align="right" valign="top" class="navRight">
+EOF
+ &PrintLinkInfo("Next", $LinkList[2], $LinkList[3], $BaseInfoFile);
+}
+
+#---------------------------------------------------------
+# PrintFooter
+#---------------------------------------------------------
+# prints the footer for an info node in HTML format
+#---------------------------------------------------------
+sub PrintFooter {
+ my ($LinkList, $BaseInfoFile, $LinkFile) = @_;
+
+ $LinkFile ||= $BaseInfoFile;
+
+ #-- TEXT for the footer of an info node
+ print <<EOF;
+ </div>
+ <em>Automatically generated by a version of
+ <a href="$info2html::config::DOC_URL">
+ <b>info2html</b>
+ </a> modified for <a href="http://www.kde.org/">KDE</a></em>.
+ <div class="bottom-nav">
+EOF
+ common_headers($LinkList, $BaseInfoFile);
+ print <<EOF;
+ <!--<br />--><em>$LinkFile</em>
+ </div>
+ </body>
+</html>
+EOF
+}
+
+#----------------------------------------------------------
+# ReplyNotFoundMessage
+#----------------------------------------------------------
+sub ReplyNotFoundMessage {
+ my ($FileName, $Tag) = @_;
+ print <<EOF;
+<head>
+<title>Info Files - Error Message</title>
+</head>
+<h1>Error</h1>
+<body>
+The Info node <em>$Tag</em> in Info file <em>$FileName</em>
+does not exist.
+</body>
+EOF
+}
+
+sub PrintByFileLink {
+ print <<EOF
+
+ <hr width="80%"/>
+ <p>If you did not find what you were looking for try <a href="info:$BROWSE_BY_FILE_PATH">browsing by file</a> to
+ see files from packages which did not update the directory.
+EOF
+}
+
+#-----------------------------------------------------------
+# BrowseByFile
+#-----------------------------------------------------------
+# Shows a list of available files in the system with a short
+# description of them.
+#------------------------------------------------------------
+
+sub BrowseByFile {
+ my @LinkList = ('', '', '', '',
+ 'dir', 'Top', '','',''); # set LinkList[4] & LinkList[5], of course ;)
+ my $BaseInfoFile = 'Available Files';
+ &PrintHeader(\@LinkList, $BaseInfoFile);
+ print <<EOF;
+<h2>Available Files</h2>
+EOF
+ &infocat;
+ &PrintFooter(\@LinkList, $BaseInfoFile);
+}
+
+#-----------------------------------------------------------
+# InfoNode2HTML
+#-----------------------------------------------------------
+# scans an info file for the node with the name '$Tag'
+# starting at the postion '$Offset'.
+# If found the node is tranlated to HTML and printed.
+#------------------------------------------------------------
+sub InfoNode2HTML {
+ my ($FileName, $Offset, $Tag, $BaseInfoFile) = @_;
+
+ local *FH2;
+ if ($FileName =~ /\.gz$/) {
+ open FH2, "-|", "gunzip", "-q", "-d", "-c", $FileName || &DieFileNotFound($FileName);
+ } elsif ($FileName =~ /\.bz2$/) {
+ open FH2, "-|", "bunzip2", "-q", "-d", "-c", $FileName || &DieFileNotFound($FileName);
+ } else {
+ open FH2, $FileName || &DieFileNotFound($FileName);
+ }
+ seek(FH2, $Offset, 0);
+ $Tag =~ tr/A-Z/a-z/; # -- to lowercase
+ #-- scan for the node start
+ my ($Found, @LinkList);
+ local $_;
+ while (<FH2>) {
+ if (/$NODEBORDER/) {
+ my $line = <FH2>;
+ @LinkList = &ParsHeaderLine($line);
+ my $CompareTag = $Tag;
+ $CompareTag =~ s/([^0-9A-Za-z])/\\$1/g; #-- escape special chars !
+ my $Temp = $LinkList[1];
+ $Temp =~ tr/A-Z/a-z/; #-- to lower case
+ if ($Temp =~ /^\s*$CompareTag\s*$/) { #-- node start found ?
+ $Found = 1;
+ last;
+ }
+ }
+ }
+
+ return &ReplyNotFoundMessage($FileName, $Tag) unless $Found; # -- break if not found;
+
+ &PrintHeader(\@LinkList, $BaseInfoFile);
+ my $InMenu = 0;
+ my $prev;
+ my $LineCount = 0;
+ my $Entries = 0;
+ my $Par = 0;
+ my @ParLines = ();
+ my $ParLine=0;
+ my $MayBeText=0;
+ my $MayBeTitle=0;
+ my $Line;
+ my $PrevMenu;
+ local $_;
+ while (<FH2>) {
+ $LineCount++;
+ last if /$NODEBORDER/;
+ #-- replace meta characters
+ #s/"`"([^"'"]*)"'"/"<span class=\"option\">"$1"</span>"/g;
+ s/&/&amp;/g;
+ s/>/&gt;/g;
+ s/</&lt;/g;
+
+ my $Length = length($_);
+ if ($LineCount == 3 && $InMenu == 0 && length($_) == $Length && $Length > 1){ #-- an underline ?
+ if (/^\**$/) {
+ print "<h2>$prev</h2>\n";
+ $prev = "";
+ next;
+ }
+ elsif (/^=*$/) {
+ print "<h3>$prev</h3>\n";
+ $prev = "";
+ next;
+ }
+ else {
+ print "<h4>$prev</h4>\n";
+ $prev = "";
+ next;
+ }
+ }
+
+ if (/^\* Menu/ && $InMenu == 0) { # -- start of menu section ?
+ $InMenu = 1;
+ print "<h3>Menu</h3>\n";
+ }
+ elsif ($InMenu == 1) {
+ # This is pretty crappy code.
+ # A lot of logic (like the ParsCrossRefs and tranforming Variable: etc) is repeated below.
+ # There have been a few bugs which were fixed in one branch of the code and left in the other.
+ # This should be refactored.
+ # LPC (16 March 2003)
+ if (/^\* /) { #-- a menu entry ?
+ if ($Entries == 0) {
+ $Entries = 1;
+ print "<table class=\"infomenutable\">";
+ }
+ print &MenuItem2HTML($_,$BaseInfoFile);
+ }
+ elsif (/^$/) { #-- empty line
+ if ($Entries == 1) {
+ print "</td></tr></table>";
+ $Entries = 0;
+ }
+ print "<br>";
+ }
+ else {
+ $Line = &ParsCrossRefs($prev,$_,$BaseInfoFile);
+ if ($Line =~ /^$DONTPRINTYET/) {
+ $prev = $Line;
+ $prev =~ s/^$DONTPRINTYET//;
+ chomp $prev;
+ }
+ elsif ($LineCount == 2) {
+ $prev = $Line;
+ } else {
+ $prev = $Line;
+ $Line =~ s#- (Variable|Function|Macro|Command|Special Form|User Option|Data Type):.*$#<em><strong>$&</strong></em>#;
+ $Line =~ s/^[ \t]*//;
+ print $Line;
+ }
+ }
+ }
+ else {
+ if (/^ *$/) {
+ if ($MayBeText == 1) {
+ print "<p>$Par</p>"
+ } else {
+ print "<pre>";
+ foreach (@ParLines) {
+ print $_;
+ }
+ print "\n";
+ print "</pre>";
+ }
+ @ParLines = ();
+ $ParLine = 1;
+ $MayBeText = 1;
+ $MayBeTitle = 1;
+ $Par = "";
+ } else {
+ if ($ParLine == 1) {
+ if (!/^ {1,4}[^ ]/ || /[^ ] [^ ]/) {
+ $MayBeText = 0;
+ }
+ } else {
+ if (!/^ ?[^ ]/ || /[^ ] [^ ]/) {
+ $MayBeText = 0;
+ }
+ }
+ $Line = &ParsCrossRefs($prev,$_,$BaseInfoFile);
+ if ($Line =~ /^$DONTPRINTYET/) {
+ $prev = $Line;
+ $prev =~ s/^$DONTPRINTYET//;
+ chomp $prev;
+ } elsif ($LineCount == 2) {
+ $prev = $Line;
+ } else {
+ $prev = $Line;
+ $Line =~ s#- (Variable|Function|Macro|Command|Special Form|User Option):.*$#<strong>$&</strong>#;
+ $Line =~ s/`([^']*)'/`<span class="option">$1<\/span>'/g; #'
+ $Line =~ s/((news|ftp|http):\/\/[A-Za-z0-9\.\/\#\-_\~]*)/<a href="$1">$1<\/a>/g;
+ $Line =~ s/([A-Za-z0-9\.\/\#\-_\~]*\@[A-Za-z0-9\.\/\#\-_\~]*\.[A-Za-z]{2,3})/<a href="mailto:$1">$1<\/a>/g;
+ $Par = $Par . $Line;
+ $ParLines[$ParLine] = $Line;
+ $ParLine++;
+ }
+ }
+ }
+ }
+ if ($Entries == 1) {
+ print "</table>"
+ }
+ if ($PrevMenu =~ "") {
+ print &MenuItem2HTML($PrevMenu,$BaseInfoFile);
+ }
+
+ close(FH2);
+
+ if ($BaseInfoFile =~ m/dir/i
+ && $Tag =~ m/Top/i) {
+ &PrintByFileLink;
+ }
+
+ &PrintFooter(\@LinkList, $BaseInfoFile);
+}
+
+#-------------------------------------------------------------
+# max
+#------------------------------------------------------------
+sub max {
+ my ($a, $b) = @_;
+ return $a >= $b ? $a : $b;
+}
+
+#-----------------------------------------------------------
+# GetFileAndOffset
+#------------------------------------------------------------
+# This procedure locates a specific node in a info file
+# The location is based on the tag and indirect table in
+# basic info file if such tables are available.
+# Because the offsets specified in the tag and in the
+# indirect table are more or less inacurate the computet
+# offset is set back 100 bytes. From this position
+# the specified node will looked for sequentially
+#------------------------------------------------------------
+sub GetFileAndOffset {
+ my ($BaseInfoFile, $NodeName) = @_;
+ my ($Exists, $IsIndirect, $File, $Offset, $FileOffset, %TagList, @FileNames, @Offsets);
+ $NodeName =~ tr/A-Z/a-z/;
+ &ReadIndirectTable($BaseInfoFile, \@FileNames, \@Offsets);
+
+
+# This looks wastefull:
+# We build a whole TagList hash and then use it to lookup the tag info.
+# Why not pass $NodeName to ReadTagTable and let it return just the desired info?
+# lpc (16 March 2003)
+ &ReadTagTable($BaseInfoFile, \%TagList, \$Exists, \$IsIndirect);
+ return "", 0 unless $Exists; #-- no tag table available
+ return "", 0 unless defined $TagList{$NodeName}; #-- tag is not in the tag table
+ ($File, $Offset) = split(/#/, $TagList{$NodeName});
+ return $File, &max($Offset - 100, 0) if $File; #-- there is an explicite
+ #-- not in the tag table
+
+ if ($IsIndirect == 1) {
+ foreach my $i (0..$#Offsets) {
+ $FileOffset = $Offsets[$i] if $Offsets[$i] <= $Offset;
+ $File = $FileNames[$i] if $Offsets[$i] <= $Offset;
+ }
+ return $File, &max($Offset - $FileOffset - 100,0); #-- be safe (-100!)
+ } else {
+ return "", &max($Offset - 100, 0);
+ }
+}
+
+# FindFile: find the given file on the infopath, return full name or "".
+# Let filenames optionally have .info suffix. Try named version first.
+# Handle gzipped file too.
+sub FindFile {
+ my ($File) = @_;
+ return "" if ($File =~ /\.\./);
+ my $Alt = $File =~ /^(.+)\.info$/ ? $1 : $File . '.info';
+ foreach my $Name ($File, $Alt) {
+ my $gzName = $Name . '.gz';
+ my $bz2Name = $Name . '.bz2';
+
+ foreach (@info2html::config::INFODIR) {
+ return "$_/$Name" if -e "$_/$Name";
+ return "$_/$gzName" if -e "$_/$gzName";
+ return "$_/$bz2Name" if -e "$_/$bz2Name";
+ }
+ next unless $ENV{INFOPATH};
+ foreach my $i (split(/:/, $ENV{INFOPATH})) {
+ return "$i/$Name" if -e "$i/$Name";
+ return "$i/$gzName" if -e "$i/$gzName";
+ return "$i/$bz2Name" if -e "$i/$bz2Name";
+ }
+ }
+ return "";
+}
+
+#-------------------------------------------------------
+#
+#------------------- MAIN -----------------------------
+#
+# called as
+# perl /path/kde-info2html config_file image_base_path BaseInfoFile NodeName
+#
+# BaseInfoFile eq '#special#' to pass special args through NodeName (yes, it is a hack).
+#
+
+my $PROGRAM = $0; # determine our basename and version
+$PROGRAM =~ s!.*/!!;
+my ($BaseInfoFile, $NodeName) = ($ARGV[2], $ARGV[3]);
+#&DirnameCheck($BaseInfoFile) || &DieFileNotFound($BaseInfoFile);
+
+if ($BaseInfoFile eq '#special#' && $NodeName eq 'browse_by_file') {
+ &BrowseByFile;
+ exit 0;
+}
+
+$BaseInfoFile = "dir" if $BaseInfoFile =~ /^dir$/i;
+my $FileNameFull = &FindFile($BaseInfoFile) || &FileNotFound($BaseInfoFile,$NodeName);
+my ($File, $Offset) = &GetFileAndOffset($FileNameFull, $NodeName);
+$File ||= $BaseInfoFile;
+$FileNameFull = &FindFile($File);
+&InfoNode2HTML($FileNameFull, $Offset, $NodeName, $BaseInfoFile);
+
+exit 0;
diff --git a/kioslave/info/kde-info2html.conf b/kioslave/info/kde-info2html.conf
new file mode 100644
index 000000000..260d2b336
--- /dev/null
+++ b/kioslave/info/kde-info2html.conf
@@ -0,0 +1,43 @@
+# -*- perl -*-
+package info2html::config;
+#-----------------------------------------------------------------
+# info2html.conf
+#-----------------------------------------------------------------
+# PURPOSE
+# configuration settings for the 'info2html' script.
+#
+# AUTHOR
+# Karl Guggisberg <guggis@iam.unibe.ch>
+#
+# HISTORY
+# 15.10.93 V 1.0b
+# 16.10.93 V 1.0c multple info files possible
+# 28.6.94 V 1.0d some minor changes
+# 8.4.95 V 1.1 some changements
+#----------------------------------------------------------------
+
+use strict;
+#use vars qw(@ISA @EXPORT);
+#
+#@ISA = qw(Exporter);
+#@EXPORT = qw(@INFODIR $DOC_URL);
+
+
+#-- location of info files.
+our @INFODIR = (
+ "/usr/share/info",
+ "/usr/info",
+ "/usr/lib/info",
+# "/usr/lib/teTeX/info",
+ "/usr/local/info",
+ "/usr/local/lib/info",
+ "/usr/X11R6/info",
+ "/usr/X11R6/lib/info",
+ "/usr/X11R6/lib/xemacs/info"
+ );
+
+
+#-- URL for documentation of info2html
+our $DOC_URL = 'http://info2html.sourceforge.net/';
+
+1;