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