153a5a1b3Sopenharmony_ci#!/usr/bin/perl -w
253a5a1b3Sopenharmony_ci
353a5a1b3Sopenharmony_ci#    xmltoman - simple xml to man converter
453a5a1b3Sopenharmony_ci#    Copyright (C) 2000-2002 Oliver Kurth <oku@masqmail.cx>
553a5a1b3Sopenharmony_ci#                       2003 Lennart Poettering <mzkzygbzna@0pointer.de>
653a5a1b3Sopenharmony_ci#
753a5a1b3Sopenharmony_ci#    This program is free software; you can redistribute it and/or modify
853a5a1b3Sopenharmony_ci#    it under the terms of the GNU General Public License as published by
953a5a1b3Sopenharmony_ci#    the Free Software Foundation; either version 2 of the License, or
1053a5a1b3Sopenharmony_ci#    (at your option) any later version.
1153a5a1b3Sopenharmony_ci#
1253a5a1b3Sopenharmony_ci#    This program is distributed in the hope that it will be useful,
1353a5a1b3Sopenharmony_ci#    but WITHOUT ANY WARRANTY; without even the implied warranty of
1453a5a1b3Sopenharmony_ci#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1553a5a1b3Sopenharmony_ci#    GNU General Public License for more details.
1653a5a1b3Sopenharmony_ci#
1753a5a1b3Sopenharmony_ci#    You should have received a copy of the GNU General Public License
1853a5a1b3Sopenharmony_ci#    along with this program; if not, see <http://www.gnu.org/licenses/>.
1953a5a1b3Sopenharmony_ci
2053a5a1b3Sopenharmony_ciuse XML::Parser;
2153a5a1b3Sopenharmony_ci
2253a5a1b3Sopenharmony_cimy $buffer = "";
2353a5a1b3Sopenharmony_cimy $break_req = 0;
2453a5a1b3Sopenharmony_ci
2553a5a1b3Sopenharmony_cimy @stack;
2653a5a1b3Sopenharmony_cimy $stack_n = 0;
2753a5a1b3Sopenharmony_ci
2853a5a1b3Sopenharmony_cimy $para = 0; 
2953a5a1b3Sopenharmony_ci
3053a5a1b3Sopenharmony_cisub out {
3153a5a1b3Sopenharmony_ci    my $t = shift;
3253a5a1b3Sopenharmony_ci
3353a5a1b3Sopenharmony_ci    if ($t ne "") {
3453a5a1b3Sopenharmony_ci        print $t;
3553a5a1b3Sopenharmony_ci        $break_req=1;
3653a5a1b3Sopenharmony_ci    }
3753a5a1b3Sopenharmony_ci}
3853a5a1b3Sopenharmony_ci
3953a5a1b3Sopenharmony_cisub out_buf {
4053a5a1b3Sopenharmony_ci    local $_;
4153a5a1b3Sopenharmony_ci
4253a5a1b3Sopenharmony_ci    my $space = shift;
4353a5a1b3Sopenharmony_ci
4453a5a1b3Sopenharmony_ci    $_ = $buffer;
4553a5a1b3Sopenharmony_ci    $buffer = "";
4653a5a1b3Sopenharmony_ci
4753a5a1b3Sopenharmony_ci    s/\n/\ /gm;
4853a5a1b3Sopenharmony_ci    s/\s+/\ /gm;
4953a5a1b3Sopenharmony_ci    s/^\s*//gm if (!$break_req);
5053a5a1b3Sopenharmony_ci    s/^\s$//gm if (!$space);
5153a5a1b3Sopenharmony_ci    
5253a5a1b3Sopenharmony_ci    out($_);
5353a5a1b3Sopenharmony_ci}
5453a5a1b3Sopenharmony_ci
5553a5a1b3Sopenharmony_cisub stack_push {
5653a5a1b3Sopenharmony_ci    my $a = shift;
5753a5a1b3Sopenharmony_ci
5853a5a1b3Sopenharmony_ci    if ($stack_n == 0 or $a ne $stack[$stack_n-1]) {
5953a5a1b3Sopenharmony_ci        out("\\fB") if $a =~ /^bold$/;
6053a5a1b3Sopenharmony_ci        out("\\fI") if $a =~ /^italic$/;
6153a5a1b3Sopenharmony_ci    }
6253a5a1b3Sopenharmony_ci
6353a5a1b3Sopenharmony_ci    $stack[$stack_n++] = $a;
6453a5a1b3Sopenharmony_ci}
6553a5a1b3Sopenharmony_ci
6653a5a1b3Sopenharmony_cisub stack_pop {
6753a5a1b3Sopenharmony_ci    local $_;
6853a5a1b3Sopenharmony_ci    
6953a5a1b3Sopenharmony_ci    if ($stack_n > 0) {
7053a5a1b3Sopenharmony_ci        $stack_n--;
7153a5a1b3Sopenharmony_ci
7253a5a1b3Sopenharmony_ci        if ($stack_n > 0) {
7353a5a1b3Sopenharmony_ci            $a = $stack[$stack_n-1];
7453a5a1b3Sopenharmony_ci            out("\\fB") if $a =~ /^bold$/;
7553a5a1b3Sopenharmony_ci            out("\\fI") if $a =~ /^italic$/;
7653a5a1b3Sopenharmony_ci        } else {
7753a5a1b3Sopenharmony_ci            out("\\f1");
7853a5a1b3Sopenharmony_ci        }
7953a5a1b3Sopenharmony_ci    }
8053a5a1b3Sopenharmony_ci}
8153a5a1b3Sopenharmony_ci
8253a5a1b3Sopenharmony_cisub handle_start {
8353a5a1b3Sopenharmony_ci    local $_;
8453a5a1b3Sopenharmony_ci    my $expat = shift;
8553a5a1b3Sopenharmony_ci    my $element = shift;
8653a5a1b3Sopenharmony_ci    my %attr = @_;
8753a5a1b3Sopenharmony_ci    
8853a5a1b3Sopenharmony_ci    $_ = $element;
8953a5a1b3Sopenharmony_ci
9053a5a1b3Sopenharmony_ci    if (/^manpage$/) {
9153a5a1b3Sopenharmony_ci        out_buf(0);
9253a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
9353a5a1b3Sopenharmony_ci        print ".TH " . $attr{name} . " " . $attr{section} . " User Manuals\n";
9453a5a1b3Sopenharmony_ci        print ".SH NAME\n";
9553a5a1b3Sopenharmony_ci        print $attr{name} . " \\- " . $attr{desc} . "\n";
9653a5a1b3Sopenharmony_ci        $break_req = 0;
9753a5a1b3Sopenharmony_ci    } elsif (/^synopsis$/) {
9853a5a1b3Sopenharmony_ci        out_buf(0);
9953a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
10053a5a1b3Sopenharmony_ci        print ".SH SYNOPSIS\n";
10153a5a1b3Sopenharmony_ci        $section = $element;
10253a5a1b3Sopenharmony_ci        $break_req = 0;
10353a5a1b3Sopenharmony_ci        stack_push("bold");
10453a5a1b3Sopenharmony_ci    } elsif (/^description$/) {
10553a5a1b3Sopenharmony_ci        out_buf(0);
10653a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
10753a5a1b3Sopenharmony_ci        print ".SH DESCRIPTION\n";
10853a5a1b3Sopenharmony_ci        $section = $element;
10953a5a1b3Sopenharmony_ci        $break_req = 0;
11053a5a1b3Sopenharmony_ci    } elsif (/^options$/) {
11153a5a1b3Sopenharmony_ci        out_buf(0);
11253a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
11353a5a1b3Sopenharmony_ci        print ".SH OPTIONS\n";
11453a5a1b3Sopenharmony_ci        $section = $element;
11553a5a1b3Sopenharmony_ci        $break_req = 0;
11653a5a1b3Sopenharmony_ci    } elsif (/^seealso$/) {
11753a5a1b3Sopenharmony_ci        out_buf(0);
11853a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
11953a5a1b3Sopenharmony_ci        print ".SH SEE ALSO\n";
12053a5a1b3Sopenharmony_ci        $section = $element;
12153a5a1b3Sopenharmony_ci        $break_req = 0;
12253a5a1b3Sopenharmony_ci    } elsif (/^section$/) {
12353a5a1b3Sopenharmony_ci        out_buf(0);
12453a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
12553a5a1b3Sopenharmony_ci        print ".SH ".uc($attr{name})."\n";
12653a5a1b3Sopenharmony_ci        $section = $attr{name};
12753a5a1b3Sopenharmony_ci        $break_req = 0;
12853a5a1b3Sopenharmony_ci    } elsif (/^option$/) {
12953a5a1b3Sopenharmony_ci        out_buf(0);
13053a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
13153a5a1b3Sopenharmony_ci        print ".TP\n";
13253a5a1b3Sopenharmony_ci        $break_req = 0;
13353a5a1b3Sopenharmony_ci    } elsif (/^p$/ or /^cmd$/) {
13453a5a1b3Sopenharmony_ci        out_buf(0);
13553a5a1b3Sopenharmony_ci        print "\n" if ($para);
13653a5a1b3Sopenharmony_ci        $break_req = 0;
13753a5a1b3Sopenharmony_ci    } elsif (/^optdesc$/) {
13853a5a1b3Sopenharmony_ci        out_buf(0);
13953a5a1b3Sopenharmony_ci        $break_req = 0;
14053a5a1b3Sopenharmony_ci    } elsif (/^arg$/ or /^file$/) {
14153a5a1b3Sopenharmony_ci        out_buf(1);
14253a5a1b3Sopenharmony_ci        stack_push("italic");
14353a5a1b3Sopenharmony_ci    } elsif (/^opt$/) {
14453a5a1b3Sopenharmony_ci        out_buf(1);
14553a5a1b3Sopenharmony_ci        stack_push("bold");
14653a5a1b3Sopenharmony_ci    } elsif (/^manref$/) {
14753a5a1b3Sopenharmony_ci        out_buf(1);
14853a5a1b3Sopenharmony_ci        stack_push("bold");
14953a5a1b3Sopenharmony_ci        out($attr{name} ."(" . $attr{section} . ")");
15053a5a1b3Sopenharmony_ci        stack_pop();
15153a5a1b3Sopenharmony_ci    } elsif (/^url$/) {
15253a5a1b3Sopenharmony_ci        out_buf(1);
15353a5a1b3Sopenharmony_ci        stack_push("bold");
15453a5a1b3Sopenharmony_ci        out($attr{href});
15553a5a1b3Sopenharmony_ci        stack_pop();
15653a5a1b3Sopenharmony_ci    };
15753a5a1b3Sopenharmony_ci
15853a5a1b3Sopenharmony_ci    $para = 0;
15953a5a1b3Sopenharmony_ci}
16053a5a1b3Sopenharmony_ci
16153a5a1b3Sopenharmony_cisub handle_end {
16253a5a1b3Sopenharmony_ci    local $_;
16353a5a1b3Sopenharmony_ci    my $expat = shift;
16453a5a1b3Sopenharmony_ci    my $element = shift;
16553a5a1b3Sopenharmony_ci    
16653a5a1b3Sopenharmony_ci    $_ = $element;
16753a5a1b3Sopenharmony_ci
16853a5a1b3Sopenharmony_ci    $para = 0;
16953a5a1b3Sopenharmony_ci
17053a5a1b3Sopenharmony_ci    if (/^description$/ or /^options$/ or /^section$/ or /^seealso$/) {
17153a5a1b3Sopenharmony_ci        out_buf(0);
17253a5a1b3Sopenharmony_ci    } elsif (/^p$/ or /^cmd$/) {
17353a5a1b3Sopenharmony_ci        out_buf(0);
17453a5a1b3Sopenharmony_ci        print "\n" if ($break_req);
17553a5a1b3Sopenharmony_ci        $para = 1;
17653a5a1b3Sopenharmony_ci        $break_req = 0;
17753a5a1b3Sopenharmony_ci    } elsif (/^synopsis$/) {
17853a5a1b3Sopenharmony_ci        out_buf(0);
17953a5a1b3Sopenharmony_ci        stack_pop();
18053a5a1b3Sopenharmony_ci    } elsif (/^opt$/ or /^arg$/ or /^file$/) {
18153a5a1b3Sopenharmony_ci        out_buf(1);
18253a5a1b3Sopenharmony_ci        stack_pop();
18353a5a1b3Sopenharmony_ci    } elsif (/^manpage$/) {
18453a5a1b3Sopenharmony_ci        out_buf(0);
18553a5a1b3Sopenharmony_ci        print "\n" if $break_req;
18653a5a1b3Sopenharmony_ci        $break_req = 0;
18753a5a1b3Sopenharmony_ci    } elsif (/^optdesc$/ or /^cmd$/ or /^option$/) {
18853a5a1b3Sopenharmony_ci        # Simply ignore
18953a5a1b3Sopenharmony_ci    } else {
19053a5a1b3Sopenharmony_ci        out_buf(1);
19153a5a1b3Sopenharmony_ci    }
19253a5a1b3Sopenharmony_ci};
19353a5a1b3Sopenharmony_ci
19453a5a1b3Sopenharmony_cisub handle_char {
19553a5a1b3Sopenharmony_ci    local $_;
19653a5a1b3Sopenharmony_ci    my $expat = shift;
19753a5a1b3Sopenharmony_ci    my $string = shift;
19853a5a1b3Sopenharmony_ci    
19953a5a1b3Sopenharmony_ci    $buffer .= $string;
20053a5a1b3Sopenharmony_ci}
20153a5a1b3Sopenharmony_ci
20253a5a1b3Sopenharmony_ciMAIN:{
20353a5a1b3Sopenharmony_ci    my $file = shift;
20453a5a1b3Sopenharmony_ci
20553a5a1b3Sopenharmony_ci    if (!$file) {
20653a5a1b3Sopenharmony_ci        print STDERR "You need to specify a file to parse\n";
20753a5a1b3Sopenharmony_ci        exit(1);
20853a5a1b3Sopenharmony_ci    }
20953a5a1b3Sopenharmony_ci    
21053a5a1b3Sopenharmony_ci    my $parser = new XML::Parser(Handlers => {
21153a5a1b3Sopenharmony_ci        Start => \&handle_start, 
21253a5a1b3Sopenharmony_ci        End => \&handle_end,
21353a5a1b3Sopenharmony_ci        Char => \&handle_char});
21453a5a1b3Sopenharmony_ci
21553a5a1b3Sopenharmony_ci    $parser->parsefile($file, ProtocolEncoding => 'ISO-8859-1');
21653a5a1b3Sopenharmony_ci}
217