]> code.delx.au - pulseaudio/blob - man/xmltoman
pactl: Stop parsing option when the first non-option is encountered
[pulseaudio] / man / xmltoman
1 #!/usr/bin/perl -w
2
3 # xmltoman - simple xml to man converter
4 # Copyright (C) 2000-2002 Oliver Kurth <oku@masqmail.cx>
5 # 2003 Lennart Poettering <mzkzygbzna@0pointer.de>
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21 use XML::Parser;
22
23 my $buffer = "";
24 my $break_req = 0;
25
26 my @stack;
27 my $stack_n = 0;
28
29 my $para = 0;
30
31 sub out {
32 my $t = shift;
33
34 if ($t ne "") {
35 print $t;
36 $break_req=1;
37 }
38 }
39
40 sub out_buf {
41 local $_;
42
43 my $space = shift;
44
45 $_ = $buffer;
46 $buffer = "";
47
48 s/\n/\ /gm;
49 s/\s+/\ /gm;
50 s/^\s*//gm if (!$break_req);
51 s/^\s$//gm if (!$space);
52
53 out($_);
54 }
55
56 sub stack_push {
57 my $a = shift;
58
59 if ($stack_n == 0 or $a ne $stack[$stack_n-1]) {
60 out("\\fB") if $a =~ /^bold$/;
61 out("\\fI") if $a =~ /^italic$/;
62 }
63
64 $stack[$stack_n++] = $a;
65 }
66
67 sub stack_pop {
68 local $_;
69
70 if ($stack_n > 0) {
71 $stack_n--;
72
73 if ($stack_n > 0) {
74 $a = $stack[$stack_n-1];
75 out("\\fB") if $a =~ /^bold$/;
76 out("\\fI") if $a =~ /^italic$/;
77 } else {
78 out("\\f1");
79 }
80 }
81 }
82
83 sub handle_start {
84 local $_;
85 my $expat = shift;
86 my $element = shift;
87 my %attr = @_;
88
89 $_ = $element;
90
91 if (/^manpage$/) {
92 out_buf(0);
93 print "\n" if ($break_req);
94 print ".TH " . $attr{name} . " " . $attr{section} . " User Manuals\n";
95 print ".SH NAME\n";
96 print $attr{name} . " \\- " . $attr{desc} . "\n";
97 $break_req = 0;
98 } elsif (/^synopsis$/) {
99 out_buf(0);
100 print "\n" if ($break_req);
101 print ".SH SYNOPSIS\n";
102 $section = $element;
103 $break_req = 0;
104 stack_push("bold");
105 } elsif (/^description$/) {
106 out_buf(0);
107 print "\n" if ($break_req);
108 print ".SH DESCRIPTION\n";
109 $section = $element;
110 $break_req = 0;
111 } elsif (/^options$/) {
112 out_buf(0);
113 print "\n" if ($break_req);
114 print ".SH OPTIONS\n";
115 $section = $element;
116 $break_req = 0;
117 } elsif (/^seealso$/) {
118 out_buf(0);
119 print "\n" if ($break_req);
120 print ".SH SEE ALSO\n";
121 $section = $element;
122 $break_req = 0;
123 } elsif (/^section$/) {
124 out_buf(0);
125 print "\n" if ($break_req);
126 print ".SH ".uc($attr{name})."\n";
127 $section = $attr{name};
128 $break_req = 0;
129 } elsif (/^option$/) {
130 out_buf(0);
131 print "\n" if ($break_req);
132 print ".TP\n";
133 $break_req = 0;
134 } elsif (/^p$/ or /^cmd$/) {
135 out_buf(0);
136 print "\n" if ($para);
137 $break_req = 0;
138 } elsif (/^optdesc$/) {
139 out_buf(0);
140 $break_req = 0;
141 } elsif (/^arg$/ or /^file$/) {
142 out_buf(1);
143 stack_push("italic");
144 } elsif (/^opt$/) {
145 out_buf(1);
146 stack_push("bold");
147 } elsif (/^manref$/) {
148 out_buf(1);
149 stack_push("bold");
150 out($attr{name} ."(" . $attr{section} . ")");
151 stack_pop();
152 } elsif (/^url$/) {
153 out_buf(1);
154 stack_push("bold");
155 out($attr{href});
156 stack_pop();
157 };
158
159 $para = 0;
160 }
161
162 sub handle_end {
163 local $_;
164 my $expat = shift;
165 my $element = shift;
166
167 $_ = $element;
168
169 $para = 0;
170
171 if (/^description$/ or /^options$/ or /^section$/ or /^seealso$/) {
172 out_buf(0);
173 } elsif (/^p$/ or /^cmd$/) {
174 out_buf(0);
175 print "\n" if ($break_req);
176 $para = 1;
177 $break_req = 0;
178 } elsif (/^synopsis$/) {
179 out_buf(0);
180 stack_pop();
181 } elsif (/^opt$/ or /^arg$/ or /^file$/) {
182 out_buf(1);
183 stack_pop();
184 } elsif (/^manpage$/) {
185 out_buf(0);
186 print "\n" if $break_req;
187 $break_req = 0;
188 } elsif (/^optdesc$/ or /^cmd$/ or /^option$/) {
189 # Simply ignore
190 } else {
191 out_buf(1);
192 }
193 };
194
195 sub handle_char {
196 local $_;
197 my $expat = shift;
198 my $string = shift;
199
200 $buffer .= $string;
201 }
202
203 MAIN:{
204 my $file = shift;
205
206 if (!$file) {
207 print STDERR "You need to specify a file to parse\n";
208 exit(1);
209 }
210
211 my $parser = new XML::Parser(Handlers => {
212 Start => \&handle_start,
213 End => \&handle_end,
214 Char => \&handle_char});
215
216 $parser->parsefile($file, ProtocolEncoding => 'ISO-8859-1');
217 }