File indexing completed on 2024-04-21 05:41:59

0001 #! /usr/bin/env perl
0002 
0003 # kdemangen.pl
0004 # Copyright (C)  2003  Dominique Devriese <devriese@kde.org>
0005 
0006 # This program is free software; you can redistribute it and/or
0007 # modify it under the terms of the GNU General Public License
0008 # as published by the Free Software Foundation; either version 2
0009 # of the License, or (at your option) any later version.
0010 
0011 # This program is distributed in the hope that it will be useful,
0012 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 # GNU General Public License for more details.
0015 
0016 # You should have received a copy of the GNU General Public License
0017 # along with this program; if not, write to the Free Software Foundation, Inc.,
0018 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0019 
0020 
0021 
0022 # Here's a little explanation about this script:
0023 # In order to fix long-standing Debian bug #116485, I've written a
0024 # script that takes a KDE app, and generates a nice man page..  It uses
0025 # the app's "--author" and "--help-all" output, along with a description
0026 # from Debian's control file to get the data.  I think the script works
0027 # great, the man pages look almost hand-written ;) I encourage you all
0028 # to try this out, and very much welcome any feedback, especially as to
0029 # how to integrate this into either the Debian KDE packaging system or
0030 # the KDE build system..
0031 
0032 # The idea to do this with a script allows us to easily keep the man
0033 # pages up to date, and is generally very low-trouble for the
0034 # developer...
0035 
0036 # The script is attached at the bottom..
0037 
0038 # USAGE:
0039 # Suppose you wanted to generate a man page for the KDE-Edu program
0040 # kalzium..  Then you would
0041 # 1 cd to /path/to/kde/srcs/kdeedu/debian  ( necessary so the script
0042 #   finds the Debian control file.. )
0043 # 2 run "/path/to/kdemangen.pl $(which kstars) > kstars.1"
0044 # 3 run "man ./kstars.1" to check out the generated page..
0045 
0046 # PROBLEMS:
0047 # Only works for full KDE applications that use KCmdLineArgs (
0048 # inherent to my approach, but most KDE apps fulfill this requirement
0049 # )
0050 
0051 use warnings;
0052 use strict;
0053 
0054 sub optionstonroff
0055   {
0056     my $options = shift;
0057     my $ret = "";
0058     foreach( split /\n/, $options )
0059       {
0060     if( /^  (--?[[:alpha:]]+, )?(--[[:alpha:]-]*|-[[:alpha:]])( <[[:alpha:] ]*>| [[:alpha:]]*)? *(.*)$/ )
0061       {
0062         my $short;
0063         my $long;
0064         my $arg;
0065         my $desc;
0066         if( $1 ) { $short = $1; } else { $short = ""; };
0067         if( $2 ) { $long = $2; } else { $long = ""; };
0068         if( $3 ) { $arg = $3; } else { $arg = ""; };
0069         if( $4 ) { $desc = $4; } else { $desc = ""; };
0070         $short =~ s/-/\\-/g;
0071         $long =~ s/-/\\-/g;
0072         $arg =~ s/-/\\-/g;
0073         $ret .= ".TP\n";
0074         $ret .= ".B $short $long $arg\n";
0075         $ret .= "$desc\n";
0076       }
0077     elsif( /^  ([[:alpha:]]+) +(.*)$/ )
0078       {
0079         $ret .= ".TP\n";
0080         $ret .= ".B $1\n";
0081         $ret .= "$2\n";
0082       }
0083     elsif( /^ +(.*)$/ )
0084       {
0085         $ret .= "$1\n";
0086       }
0087     elsif( /^(.*)$/ )
0088       {
0089         $ret .= ".SS $1\n";
0090         # this means a header like "Qt Options:" I'm wondering
0091         # what to do with this, I don't know enough nroff to
0092         # format it nicely, I'm affraid..
0093       }
0094       }
0095     return $ret;
0096   };
0097 
0098 sub sortoptionsfromnroff {
0099     # Zack Cerza
0100 
0101     # Rather than redo Dominique's optionstonroff(), I decided
0102     # to make this function to sort the options sections created
0103     # by his function.
0104 
0105     # What it does is read line-by-line and first determine which
0106     # section it's looking at via the ".SS <SECTION>" lines. Once
0107     # it knows, it sets a "$in_<SECTION>" variable to "1" and
0108     # begins to write the section data into $<SECTION>. When it
0109     # gets to a line that contains only ".SS ", it sets
0110     # $in_<SECTION> to "0" and continues.
0111 
0112     # It's a little messy, but it's the only way I could 
0113     # get it to work with what little knowledge I had.
0114 
0115     # This is the first time I've used Perl. Be kind.
0116 
0117     my $options = shift;
0118     my $ret="";
0119 
0120     my $in_gen_opts = "0";
0121     my $gen_opts = "";
0122     my $in_qt_opts = "0";
0123     my $qt_opts = "";
0124     my $in_kde_opts = "0";
0125     my $kde_opts = "";
0126     my $in_opts = "0";
0127     my $opts = "";
0128     my $in_args = "0";
0129     my $args = "";
0130 
0131     foreach ( split /\n/, $options ) {
0132         if( $in_gen_opts == "1" ) {
0133         if( /^(\.SS )$/ ) { $in_gen_opts = "0"; }
0134         $gen_opts .= $_;
0135         $gen_opts .= "\n";
0136     }
0137     if( /^(\.SS.+Generic options:)$/ ) 
0138       { $in_gen_opts = "1"; $gen_opts .= $1; $gen_opts .= "\n"; }
0139       
0140         if( $in_qt_opts == "1" ) {
0141         if( /^(\.SS )$/ ) { $in_qt_opts = "0"; }
0142         $qt_opts .= $_;
0143         $qt_opts .= "\n";
0144     }
0145         if( /^(\.SS.+Qt options:)$/ ) 
0146       { $in_qt_opts = "1"; $qt_opts .= $1; $qt_opts .= "\n"; }
0147 
0148         if( $in_kde_opts == "1" ) {
0149         if( /^(\.SS )$/ ) { $in_kde_opts = "0"; }
0150         $kde_opts .= $_;
0151         $kde_opts .= "\n";
0152     }
0153         if( /^(\.SS.+KDE options:)$/ ) 
0154       { $in_kde_opts = "1"; $kde_opts .= $1; $kde_opts .= "\n"; }
0155         
0156     if( $in_opts == "1" ) {
0157         if( /^(\.SS )$/ ) { $in_opts = "0"; }
0158         $opts .= $_;
0159         $opts .= "\n";
0160     }
0161         if( /^(\.SS.+Options:)$/ ) 
0162       { $in_opts = "1"; $opts .= $1; $opts .= "\n"; }
0163 
0164         if( $in_args == "1" ) {
0165         if( /^(\.SS )$/ ) { $in_args = "0"; }
0166         $args .= $_;
0167         $args .= "\n";
0168     }
0169         if( /^(\.SS.+Arguments:)$/ ) 
0170       { $in_args = "1"; $args .= ".SS\n"; $args .= $1; $args .= "\n"; }
0171       }
0172     $ret .= $args;
0173     $ret .= $opts;
0174     $ret .= $gen_opts;
0175     $ret .= $kde_opts;
0176     $ret .= $qt_opts;
0177     return $ret;
0178   };
0179 
0180 sub usage
0181   {
0182     print "This script generates a nice manual page for a KDE app which uses KCmdLineArgs..\n";
0183     print "USAGE: $0 app\n";
0184     print "There's more information about how to use this script in the comments at the front of the source..\n"
0185   };
0186 
0187 if( $#ARGV < 0 ){
0188   usage();
0189   exit 1;
0190 }
0191 
0192 my $runapp = "$ARGV[0]";
0193 if ( ! -x $runapp )
0194   {
0195     print "Error: $runapp is not executable.\n";
0196     exit 1;
0197   }
0198 else { $runapp = "KDE_LANG=en_US $runapp"; };
0199 
0200 my $shortdescription = `$runapp --help | sed -ne '3p'`;
0201 chomp $shortdescription;
0202 
0203 my $synopsis = `$runapp --help | sed -n '1p' | sed -e 's/[^:]*: //'`;
0204 chomp $synopsis;
0205 $synopsis =~ s/-/\\-/g;
0206 my $appname = $synopsis;
0207 $appname =~ s/ .*$//;
0208 my $ucappname = uc $appname;
0209 
0210 my $options = `$runapp --help-all | sed -e '1,4d'`;
0211 $options = optionstonroff( $options );
0212 $options = sortoptionsfromnroff( $options );
0213 
0214 my $timespec = ucfirst `date '+%b %G'`;
0215 chomp $timespec;
0216 
0217 my $description = $shortdescription;
0218 if( -r "control" )
0219   {
0220     $description = `cat control | sed -ne '/^Description:/,/^\$/p' | egrep -v '^\\w*:.*\$' | sed -e 's/^ //' | sed -e 's/^\\.//'`;
0221 # leads to problems in some cases :(
0222 #    $description =~ s/KDE ?/\n.SM KDE\n/g;
0223   }
0224 
0225 my $authors = `$runapp --author | sed -ne '2,\$p' | sed -e '\$d' | sed -e 's/^ *//'`;
0226 $authors =~ s/\n/\n.br\n/g;
0227 
0228 print <<EOF;
0229 .\\\" This file was generated by kdemangen.pl
0230 .TH $ucappname 1 \"$timespec\" \"KDE\" \"$shortdescription\"
0231 .SH NAME
0232 $appname
0233 \\- $shortdescription
0234 .SH SYNOPSIS
0235 $synopsis
0236 .SH DESCRIPTION
0237 $description
0238 .SH OPTIONS
0239 $options
0240 .SH SEE ALSO
0241 Full user documentation is available through the KDE Help Center.  You can also enter the URL
0242 .BR help:/$appname/
0243 directly into konqueror or you can run 
0244 .BR "`khelpcenter help:/$appname/'"
0245 from the command-line.
0246 .br
0247 .SH AUTHORS
0248 .nf
0249 $authors
0250 EOF