blob: 92422f03744b8837e5f03ad844a9aec95ab7a9ca [file] [log] [blame]
#!/usr/bin/perl -w
# xmltoman - simple xml to man converter
# Copyright (C) 2000-2002 Oliver Kurth <oku@masqmail.cx>
# 2003 Lennart Poettering <mzkzygbzna@0pointer.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
use XML::Parser;
my $buffer = "";
my $break_req = 0;
my @stack;
my $stack_n = 0;
my $para = 0;
sub out {
my $t = shift;
if ($t ne "") {
print $t;
$break_req=1;
}
}
sub out_buf {
local $_;
my $space = shift;
$_ = $buffer;
$buffer = "";
s/\n/\ /gm;
s/\s+/\ /gm;
s/^\s*//gm if (!$break_req);
s/^\s$//gm if (!$space);
out($_);
}
sub stack_push {
my $a = shift;
if ($stack_n == 0 or $a ne $stack[$stack_n-1]) {
out("\\fB") if $a =~ /^bold$/;
out("\\fI") if $a =~ /^italic$/;
}
$stack[$stack_n++] = $a;
}
sub stack_pop {
local $_;
if ($stack_n > 0) {
$stack_n--;
if ($stack_n > 0) {
$a = $stack[$stack_n-1];
out("\\fB") if $a =~ /^bold$/;
out("\\fI") if $a =~ /^italic$/;
} else {
out("\\f1");
}
}
}
sub handle_start {
local $_;
my $expat = shift;
my $element = shift;
my %attr = @_;
$_ = $element;
if (/^manpage$/) {
out_buf(0);
print "\n" if ($break_req);
print ".TH " . $attr{name} . " " . $attr{section} . " User Manuals\n";
print ".SH NAME\n";
print $attr{name} . " \\- " . $attr{desc} . "\n";
$break_req = 0;
} elsif (/^synopsis$/) {
out_buf(0);
print "\n" if ($break_req);
print ".SH SYNOPSIS\n";
$section = $element;
$break_req = 0;
stack_push("bold");
} elsif (/^description$/) {
out_buf(0);
print "\n" if ($break_req);
print ".SH DESCRIPTION\n";
$section = $element;
$break_req = 0;
} elsif (/^options$/) {
out_buf(0);
print "\n" if ($break_req);
print ".SH OPTIONS\n";
$section = $element;
$break_req = 0;
} elsif (/^seealso$/) {
out_buf(0);
print "\n" if ($break_req);
print ".SH SEE ALSO\n";
$section = $element;
$break_req = 0;
} elsif (/^section$/) {
out_buf(0);
print "\n" if ($break_req);
print ".SH ".uc($attr{name})."\n";
$section = $attr{name};
$break_req = 0;
} elsif (/^option$/) {
out_buf(0);
print "\n" if ($break_req);
print ".TP\n";
$break_req = 0;
} elsif (/^p$/ or /^cmd$/) {
out_buf(0);
print "\n" if ($para);
$break_req = 0;
} elsif (/^optdesc$/) {
out_buf(0);
$break_req = 0;
} elsif (/^arg$/ or /^file$/) {
out_buf(1);
stack_push("italic");
} elsif (/^opt$/) {
out_buf(1);
stack_push("bold");
} elsif (/^manref$/) {
out_buf(1);
stack_push("bold");
out($attr{name} ."(" . $attr{section} . ")");
stack_pop();
} elsif (/^url$/) {
out_buf(1);
stack_push("bold");
out($attr{href});
stack_pop();
};
$para = 0;
}
sub handle_end {
local $_;
my $expat = shift;
my $element = shift;
$_ = $element;
$para = 0;
if (/^description$/ or /^options$/ or /^section$/ or /^seealso$/) {
out_buf(0);
} elsif (/^p$/ or /^cmd$/) {
out_buf(0);
print "\n" if ($break_req);
$para = 1;
$break_req = 0;
} elsif (/^synopsis$/) {
out_buf(0);
stack_pop();
} elsif (/^opt$/ or /^arg$/ or /^file$/) {
out_buf(1);
stack_pop();
} elsif (/^manpage$/) {
out_buf(0);
print "\n" if $break_req;
$break_req = 0;
} elsif (/^optdesc$/ or /^cmd$/ or /^option$/) {
# Simply ignore
} else {
out_buf(1);
}
};
sub handle_char {
local $_;
my $expat = shift;
my $string = shift;
$buffer .= $string;
}
MAIN:{
my $file = shift;
if (!$file) {
print STDERR "You need to specify a file to parse\n";
exit(1);
}
my $parser = new XML::Parser(Handlers => {
Start => \&handle_start,
End => \&handle_end,
Char => \&handle_char});
$parser->parsefile($file, ProtocolEncoding => 'ISO-8859-1');
}