1 | =head1 NAME |
---|
2 | |
---|
3 | docbook2man-spec.pl - convert DocBook RefEntries to Unix manpages |
---|
4 | |
---|
5 | =head1 SYNOPSIS |
---|
6 | |
---|
7 | The sgmlspl script from the SGMLSpm Perl module must be used to run |
---|
8 | this script. Use it like this: |
---|
9 | |
---|
10 | nsgmls some-docbook-document.sgml | sgmlspl docbook2man-spec.pl |
---|
11 | |
---|
12 | See man page or included DocBook documentation for details. |
---|
13 | |
---|
14 | =head1 DESCRIPTION |
---|
15 | |
---|
16 | This is a sgmlspl spec file that produces Unix-style |
---|
17 | man pages from DocBook RefEntry markup. |
---|
18 | |
---|
19 | =head1 COPYRIGHT |
---|
20 | |
---|
21 | Copyright (C) 1998-2001 Steve Cheng <stevecheng@users.sourceforge.net> |
---|
22 | |
---|
23 | Copyright (C) 1999 Thomas Lockhart <lockhart@alumni.caltech.edu> |
---|
24 | |
---|
25 | This program is free software; you can redistribute it and/or modify it |
---|
26 | under the terms of the GNU General Public License as published by the Free |
---|
27 | Software Foundation; either version 2, or (at your option) any later |
---|
28 | version. |
---|
29 | |
---|
30 | You should have received a copy of the GNU General Public License along with |
---|
31 | this program; see the file COPYING. If not, please write to the Free |
---|
32 | Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
33 | |
---|
34 | =cut |
---|
35 | |
---|
36 | # $Id: docbook2man-spec.pl,v 1.11 2010/10/04 10:23:31 ovasik Exp $ |
---|
37 | |
---|
38 | use SGMLS; # Use the SGMLS package. |
---|
39 | use SGMLS::Output; # Use stack-based output. |
---|
40 | use SGMLS::Refs; |
---|
41 | |
---|
42 | |
---|
43 | ######################################################################## |
---|
44 | # SGMLSPL script produced automatically by the script sgmlspl.pl |
---|
45 | # |
---|
46 | # Document Type: any, but processes only RefEntries |
---|
47 | # Edited by: me :) |
---|
48 | ######################################################################## |
---|
49 | |
---|
50 | |
---|
51 | $write_manpages = 0; |
---|
52 | $blank_xrefs = 0; |
---|
53 | |
---|
54 | $default_sect = "1"; |
---|
55 | $default_date = `date "+%d %B %Y"`; |
---|
56 | $cite_numeral_only = 1; |
---|
57 | |
---|
58 | while (@ARGV) { |
---|
59 | my $arg = shift @ARGV; |
---|
60 | if ($arg eq "--section") { |
---|
61 | $default_sect = shift @ARGV || die "$arg requires an argument\n"; |
---|
62 | } elsif ($arg eq "--date") { |
---|
63 | $default_date = shift @ARGV || die "$arg requires an argument\n"; |
---|
64 | } elsif ($arg eq "--lowercase") { |
---|
65 | $lowercase_names = 1; |
---|
66 | } elsif ($arg eq "--preserve-case") { |
---|
67 | $lowercase_names = 0; |
---|
68 | } elsif ($arg eq "--cite-numeral-only") { |
---|
69 | $cite_numeral_only = 1; |
---|
70 | } elsif ($arg eq "--nocite-numeral-only") { |
---|
71 | $cite_numeral_only = 0; |
---|
72 | } elsif ($arg eq "--help") { |
---|
73 | print "Usage: $0", |
---|
74 | " [ --section <label> ]", |
---|
75 | " [ --date <string> ]", |
---|
76 | " [ --lowercase | --preserve-case ]", |
---|
77 | " [ --cite-numeral-only | --nocite-numeral-only ]", |
---|
78 | "\n"; |
---|
79 | exit; |
---|
80 | } else { |
---|
81 | die "unrecognized switch $arg; try $0 --help\n"; |
---|
82 | } |
---|
83 | } |
---|
84 | |
---|
85 | sgml('start', sub { |
---|
86 | push_output('nul'); |
---|
87 | $raw_cdata = 1; # Makes it a bit faster. |
---|
88 | |
---|
89 | # Links file |
---|
90 | open(LINKSFILE, ">manpage.links"); |
---|
91 | |
---|
92 | $Refs = new SGMLS::Refs("manpage.refs", "manpage.log"); |
---|
93 | }); |
---|
94 | sgml('end', sub { |
---|
95 | close(LINKSFILE); |
---|
96 | |
---|
97 | # Explicitly invoke destructor, |
---|
98 | # otherwise cache file may not get written! |
---|
99 | # Thomas Lockhart, 1999-08-03, perl-5.004, RedHat5.2 |
---|
100 | undef $Refs; |
---|
101 | |
---|
102 | if($blank_xrefs) { |
---|
103 | warn "Warning: output contains unresolved XRefs\n"; |
---|
104 | } |
---|
105 | }); |
---|
106 | |
---|
107 | |
---|
108 | ######################################################################## |
---|
109 | # |
---|
110 | # Output helpers |
---|
111 | # |
---|
112 | ######################################################################## |
---|
113 | |
---|
114 | # Remove leading and trailing blanks. |
---|
115 | |
---|
116 | sub StripString |
---|
117 | { |
---|
118 | my $str = shift; |
---|
119 | |
---|
120 | $str = $1 if ($str =~ m#^\s*(\S.*)#); |
---|
121 | $str = $1 if ($str =~ m#^(.*\S)\s*$#); |
---|
122 | |
---|
123 | return $str; |
---|
124 | } |
---|
125 | |
---|
126 | # Generate a good file name, for given manpage title and manvolnum |
---|
127 | # (cdata content). |
---|
128 | # Cleanup whitespace and convert to lower case if required. |
---|
129 | |
---|
130 | sub FileInfo |
---|
131 | { |
---|
132 | my $title = StripString(shift); |
---|
133 | my $volnum = StripString(shift); |
---|
134 | |
---|
135 | $title = lc $title if $lowercase_names; |
---|
136 | |
---|
137 | $title =~ tr/ /_/; |
---|
138 | $volnum =~ tr/ /_/; |
---|
139 | |
---|
140 | my $sectcite = $volnum; |
---|
141 | # The 'package name' part of the section should |
---|
142 | # not be used when citing it. |
---|
143 | if ($cite_numeral_only) { |
---|
144 | $sectcite = $1 if ($volnum =~ /^([0-9]+)/); |
---|
145 | } |
---|
146 | |
---|
147 | return ("$title.$volnum", "$title($sectcite)"); |
---|
148 | } |
---|
149 | |
---|
150 | # Our own version of sgml() and output() to allow simple string output |
---|
151 | # to play well with roff's stupid whitespace rules. |
---|
152 | |
---|
153 | sub man_sgml |
---|
154 | { |
---|
155 | if(ref($_[1]) eq 'CODE') { |
---|
156 | return &sgml; |
---|
157 | } |
---|
158 | |
---|
159 | my $s = $_[1]; |
---|
160 | $s =~ s/\\/\\\\/g; |
---|
161 | $s =~ s/'/\\'/g; |
---|
162 | |
---|
163 | sgml($_[0], eval("sub { man_output '$s' }")); |
---|
164 | } |
---|
165 | |
---|
166 | sub man_output |
---|
167 | { |
---|
168 | if($separator eq 'full') { |
---|
169 | output "\n" unless $newline_last++; |
---|
170 | output ".PP\n"; |
---|
171 | $separator = ''; |
---|
172 | } |
---|
173 | |
---|
174 | $_ = shift; |
---|
175 | if(s/^\n//) { |
---|
176 | output "\n" unless $newline_last++; |
---|
177 | } |
---|
178 | return if $_ eq ''; |
---|
179 | |
---|
180 | output $_; |
---|
181 | |
---|
182 | if(@_) { |
---|
183 | output @_; |
---|
184 | $newline_last = (pop(@_) =~ /\n$/); |
---|
185 | } else { |
---|
186 | $newline_last = ($_ =~ /\n$/) |
---|
187 | } |
---|
188 | } |
---|
189 | |
---|
190 | # Fold lines into one, quote some characters |
---|
191 | sub fold_string |
---|
192 | { |
---|
193 | $_ = shift; |
---|
194 | |
---|
195 | s/\\/\\\\/g; |
---|
196 | s/"/""/g; |
---|
197 | |
---|
198 | # Change tabs and newlines to spaces |
---|
199 | # The newlines will be swallowed later while trimming |
---|
200 | tr/[\t\n]/ /; |
---|
201 | |
---|
202 | # Trim whitespace from beginning and end. |
---|
203 | s/^ +//; |
---|
204 | s/ +$//; |
---|
205 | |
---|
206 | return $_; |
---|
207 | } |
---|
208 | |
---|
209 | sub save_cdata() |
---|
210 | { |
---|
211 | $raw_cdata++; |
---|
212 | push_output('string'); |
---|
213 | } |
---|
214 | |
---|
215 | sub bold_on() |
---|
216 | { |
---|
217 | # If the last font is also bold, don't change anything. |
---|
218 | # Basically this is to just get more readable man output. |
---|
219 | if($fontstack[$#fontstack] ne 'bold') { |
---|
220 | if(!$raw_cdata) { |
---|
221 | output '\fB'; |
---|
222 | #$newline_last = 0; |
---|
223 | } |
---|
224 | } |
---|
225 | push(@fontstack, 'bold'); |
---|
226 | } |
---|
227 | |
---|
228 | sub italic_on() |
---|
229 | { |
---|
230 | # If the last font is also italic, don't change anything. |
---|
231 | if($fontstack[$#fontstack] ne 'italic') { |
---|
232 | if(!$raw_cdata) { |
---|
233 | output '\fI'; |
---|
234 | #$newline_last = 0; |
---|
235 | } |
---|
236 | } |
---|
237 | push(@fontstack, 'italic'); |
---|
238 | } |
---|
239 | |
---|
240 | sub font_off() |
---|
241 | { |
---|
242 | my $thisfont = pop(@fontstack); |
---|
243 | my $lastfont = $fontstack[$#fontstack]; |
---|
244 | |
---|
245 | # Only output font change if it is different |
---|
246 | if($thisfont ne $lastfont) { |
---|
247 | if($raw_cdata) { return; } |
---|
248 | elsif($lastfont eq 'bold') { output '\fB'; } |
---|
249 | elsif($lastfont eq 'italic') { output '\fI'; } |
---|
250 | else { output '\fR'; } |
---|
251 | |
---|
252 | #$newline_last = 0; |
---|
253 | } |
---|
254 | } |
---|
255 | |
---|
256 | |
---|
257 | ######################################################################## |
---|
258 | # |
---|
259 | # Manpage management |
---|
260 | # |
---|
261 | ######################################################################## |
---|
262 | |
---|
263 | sgml('<REFENTRY>', sub { |
---|
264 | # This will be overwritten at end of REFMETA, when we know the name of the page. |
---|
265 | pop_output(); |
---|
266 | |
---|
267 | $write_manpages = 1; # Currently writing manpage. |
---|
268 | |
---|
269 | $nocollapse_whitespace = 0; # Current whitespace collapse counter. |
---|
270 | $newline_last = 1; # At beginning of line? |
---|
271 | # Just a bit of warning, you will see this variable manipulated |
---|
272 | # manually a lot. It makes the code harder to follow but it |
---|
273 | # saves you from having to worry about collapsing at the end of |
---|
274 | # parse, stopping at verbatims, etc. |
---|
275 | $raw_cdata = 0; # Instructs certain output functions to |
---|
276 | # leave CDATA alone, so we can assign |
---|
277 | # it to a string and process it, etc. |
---|
278 | @fontstack = (); # Fonts being activated. |
---|
279 | |
---|
280 | $list_nestlevel = 0; # Indent certain nested content. |
---|
281 | |
---|
282 | # Separator to use between 'elements' in the content of a |
---|
283 | # paragraph (usually). This makes sure that PCDATA after a list |
---|
284 | # in a PARA gets a break in between and not become part of the |
---|
285 | # last listitem. Note that we can't do it after the list ends, |
---|
286 | # because often the list ends the paragraph and we'll get an |
---|
287 | # extra break. Anything that changes the separator status from |
---|
288 | # the default should also save its last state in the parent |
---|
289 | # element's ext, but I'm not going to explain further. It's a |
---|
290 | # gross hack and almost guaranteed to fail in unforseen cases. |
---|
291 | # The only way to avoid all this is to use a tree/grove model, which |
---|
292 | # we're _not_ doing. |
---|
293 | $separator = ''; |
---|
294 | |
---|
295 | $manpage_title = ''; # Needed for indexing. |
---|
296 | $manpage_sect = ''; |
---|
297 | @manpage_names = (); |
---|
298 | |
---|
299 | $manpage_misc = ''; |
---|
300 | |
---|
301 | # check refentry's language |
---|
302 | if(defined($_[0]->attribute('LANG')->value)) { |
---|
303 | $manpage_lang = $_[0]->attribute('LANG')->value; |
---|
304 | } |
---|
305 | else { |
---|
306 | $manpage_lang = ''; |
---|
307 | } |
---|
308 | }); |
---|
309 | sgml('</REFENTRY>', sub { |
---|
310 | if(!$newline_last) { |
---|
311 | output "\n"; |
---|
312 | } |
---|
313 | |
---|
314 | $raw_cdata = 1; |
---|
315 | push_output('nul'); |
---|
316 | |
---|
317 | $write_manpages = 0; |
---|
318 | }); |
---|
319 | |
---|
320 | sgml('</REFMETA>', sub { |
---|
321 | my ($filename, $citation) = |
---|
322 | FileInfo($manpage_title, $manpage_sect || $default_sect); |
---|
323 | |
---|
324 | push_output('file', $filename); |
---|
325 | |
---|
326 | output <<'_END_BANNER'; |
---|
327 | .\" auto-generated by docbook2man-spec from docbook-utils package |
---|
328 | _END_BANNER |
---|
329 | |
---|
330 | my $manpage_date = $_[0]->parent->ext->{'date'} || $default_date; |
---|
331 | |
---|
332 | output '.TH "'; |
---|
333 | |
---|
334 | # If the title is not mixed-case, convention says to |
---|
335 | # uppercase the whole title. (The canonical title is |
---|
336 | # lowercase.) |
---|
337 | if($manpage_title =~ /[A-Z]/) { |
---|
338 | output fold_string($manpage_title); |
---|
339 | } else { |
---|
340 | output uc(fold_string($manpage_title)); |
---|
341 | } |
---|
342 | |
---|
343 | output '" "', fold_string($manpage_sect), |
---|
344 | '" "', fold_string($manpage_date), |
---|
345 | '" "', $manpage_misc, |
---|
346 | '" "', $manpage_manual, |
---|
347 | "\"\n"; |
---|
348 | |
---|
349 | $newline_last = 1; |
---|
350 | |
---|
351 | # References to this RefEntry. |
---|
352 | if(defined($_[0]->parent->attribute('ID')->value)) { |
---|
353 | my $id = $_[0]->parent->attribute('ID')->value; |
---|
354 | |
---|
355 | # Append XREFLABEL content to citations. |
---|
356 | if(defined($_[0]->parent->attribute('XREFLABEL')->value)) { |
---|
357 | $citation = $_[0]->parent->attribute('XREFLABEL')->value . |
---|
358 | ' [' . $citation . ']'; |
---|
359 | } |
---|
360 | |
---|
361 | $Refs->put("refentry:$id", $citation); |
---|
362 | } |
---|
363 | }); |
---|
364 | |
---|
365 | sgml('<REFENTRYTITLE>', sub { |
---|
366 | if($_[0]->in('REFMETA')) { |
---|
367 | save_cdata(); |
---|
368 | } else { |
---|
369 | # Manpage citations are in bold. |
---|
370 | bold_on(); |
---|
371 | } |
---|
372 | }); |
---|
373 | sgml('</REFENTRYTITLE>', sub { |
---|
374 | if($_[0]->in('REFMETA')) { |
---|
375 | $raw_cdata--; |
---|
376 | $manpage_title = pop_output(); |
---|
377 | } |
---|
378 | else { font_off(); } |
---|
379 | |
---|
380 | if (defined($_[0]->attribute('ID')->value)) { |
---|
381 | my $id = $_[0]->attribute('ID')->value; |
---|
382 | $Refs->put("refentrytitle:$id", $manpage_title); |
---|
383 | } |
---|
384 | }); |
---|
385 | |
---|
386 | sgml('<MANVOLNUM>', sub { |
---|
387 | if($_[0]->in('REFMETA')) { |
---|
388 | save_cdata(); |
---|
389 | } else { |
---|
390 | # Manpage citations use (). |
---|
391 | output '('; |
---|
392 | } |
---|
393 | }); |
---|
394 | sgml('</MANVOLNUM>', sub { |
---|
395 | if($_[0]->in('REFMETA')) { |
---|
396 | $raw_cdata--; |
---|
397 | $manpage_sect = pop_output(); |
---|
398 | } |
---|
399 | else { output ')' } |
---|
400 | }); |
---|
401 | |
---|
402 | sgml('<REFMISCINFO>', \&save_cdata); |
---|
403 | sgml('</REFMISCINFO>', sub { |
---|
404 | $raw_cdata--; |
---|
405 | $manpage_misc = fold_string(pop_output()); |
---|
406 | }); |
---|
407 | |
---|
408 | |
---|
409 | # NAME section |
---|
410 | #man_sgml('<REFNAMEDIV>', "\n.SH NAME\n"); |
---|
411 | man_sgml('<REFNAMEDIV>', sub { |
---|
412 | my %text = { fr=>'NOM', es=>'NOMBRE', pl=>'NAZWA' }; |
---|
413 | |
---|
414 | if(defined $text{lc($manpage_lang)}) |
---|
415 | { |
---|
416 | man_output "\n.SH " . $text{lc($manpage_lang)} . "\n"; |
---|
417 | } elsif(defined $_[0]->attribute('LANG') and |
---|
418 | defined $text{lc($_[0]->attribute('LANG')->value)}) |
---|
419 | { |
---|
420 | man_output "\n.SH " . $text{lc($_[0]->attribute('LANG'))} . "\n"; |
---|
421 | } else { |
---|
422 | man_output "\n.SH NAME\n"; |
---|
423 | } |
---|
424 | }); |
---|
425 | |
---|
426 | sgml('<REFNAME>', \&save_cdata); |
---|
427 | sgml('</REFNAME>', sub { |
---|
428 | $raw_cdata--; |
---|
429 | push(@manpage_names, pop_output()); |
---|
430 | }); |
---|
431 | |
---|
432 | sgml('<REFPURPOSE>', \&save_cdata); |
---|
433 | sgml('</REFPURPOSE>', sub { |
---|
434 | $raw_cdata--; |
---|
435 | my $manpage_purpose = fold_string(pop_output()); |
---|
436 | |
---|
437 | for(my $i = 0; $i < $#manpage_names; $i++) { |
---|
438 | output fold_string($manpage_names[$i]), ', '; |
---|
439 | } |
---|
440 | |
---|
441 | output fold_string($manpage_names[$#manpage_names]); |
---|
442 | output " \\- $manpage_purpose\n"; |
---|
443 | |
---|
444 | $newline_last = 1; |
---|
445 | |
---|
446 | foreach(@manpage_names) { |
---|
447 | # Don't link to itself |
---|
448 | if($_ ne $manpage_title) { |
---|
449 | print LINKSFILE "$manpage_title.$manpage_sect $_.$manpage_sect\n"; |
---|
450 | } |
---|
451 | } |
---|
452 | }); |
---|
453 | |
---|
454 | man_sgml('<REFCLASS>', "\n.sp\n"); |
---|
455 | |
---|
456 | #RefDescriptor |
---|
457 | |
---|
458 | |
---|
459 | ######################################################################## |
---|
460 | # |
---|
461 | # SYNOPSIS section and synopses |
---|
462 | # |
---|
463 | ######################################################################## |
---|
464 | |
---|
465 | #man_sgml('<REFSYNOPSISDIV>', "\n.SH SYNOPSIS\n"); |
---|
466 | man_sgml('<REFSYNOPSISDIV>', sub { |
---|
467 | if ($manpage_lang eq "pl") { man_output "\n.SH SK£ADNIA\n"; } |
---|
468 | # waits for another languages |
---|
469 | #elsif ($manpage_lang eq "xx") { man_output "\n.SH xxxxxxx\n"; } |
---|
470 | else { man_output "\n.SH SYNOPSIS\n"; } |
---|
471 | }); |
---|
472 | |
---|
473 | man_sgml('</REFSYNOPSISDIV>', "\n"); |
---|
474 | |
---|
475 | ## FIXME! Must be made into block elements!! |
---|
476 | #sgml('<FUNCSYNOPSIS>', \&bold_on); |
---|
477 | #sgml('</FUNCSYNOPSIS>', \&font_off); |
---|
478 | #sgml('<CMDSYNOPSIS>', \&bold_on); |
---|
479 | #sgml('</CMDSYNOPSIS>', \&font_off); |
---|
480 | |
---|
481 | man_sgml('<FUNCSYNOPSIS>', sub { |
---|
482 | man_output("\n.nf\n"); |
---|
483 | bold_on(); |
---|
484 | }); |
---|
485 | man_sgml('</FUNCSYNOPSIS>', sub { |
---|
486 | man_output("\n.fi"); |
---|
487 | font_off(); |
---|
488 | }); |
---|
489 | |
---|
490 | man_sgml('<CMDSYNOPSIS>', "\n.sp\n"); |
---|
491 | man_sgml('</CMDSYNOPSIS>', "\n"); |
---|
492 | |
---|
493 | man_sgml('<FUNCPROTOTYPE>', "\n.sp\n"); |
---|
494 | |
---|
495 | # Arguments to functions. This is C convention. |
---|
496 | #man_sgml('<PARAMDEF>', '('); |
---|
497 | #man_sgml('</PARAMDEF>', ");\n"); |
---|
498 | #man_sgml('<VOID>', "(void);\n"); |
---|
499 | sub paramdef |
---|
500 | { |
---|
501 | if($_[0]->parent->ext->{'inparams'}) { |
---|
502 | output ', '; |
---|
503 | } else { |
---|
504 | output ' ('; |
---|
505 | $_[0]->parent->ext->{'inparams'} = 1; |
---|
506 | } |
---|
507 | } |
---|
508 | man_sgml('<PARAMDEF>', \¶mdef); |
---|
509 | man_sgml('</FUNCPROTOTYPE>', ");\n"); |
---|
510 | man_sgml('<VOID>', "(void"); |
---|
511 | man_sgml('<VARARGS>', "(..."); |
---|
512 | |
---|
513 | |
---|
514 | sub arg_start |
---|
515 | { |
---|
516 | # my $choice = $_[0]->attribute('CHOICE')->value; |
---|
517 | |
---|
518 | # The content model for CmdSynopsis doesn't include #PCDATA, |
---|
519 | # so we won't see any of the whitespace in the source file, |
---|
520 | # so we have to add it after each component. |
---|
521 | man_output ' '; |
---|
522 | |
---|
523 | if($_[0]->attribute('CHOICE')->value =~ /opt/i) { |
---|
524 | man_output '[ '; |
---|
525 | } |
---|
526 | bold_on(); |
---|
527 | } |
---|
528 | sub arg_end |
---|
529 | { |
---|
530 | font_off(); |
---|
531 | if($_[0]->attribute('REP')->value =~ /^Repeat/i) { |
---|
532 | italic_on(); |
---|
533 | man_output '...'; |
---|
534 | font_off(); |
---|
535 | } |
---|
536 | if($_[0]->attribute('CHOICE')->value =~ /opt/i) { |
---|
537 | man_output ' ] '; |
---|
538 | } |
---|
539 | } |
---|
540 | |
---|
541 | sgml('<ARG>', \&arg_start); |
---|
542 | sgml('</ARG>', \&arg_end); |
---|
543 | sgml('<GROUP>', \&arg_start); |
---|
544 | sgml('</GROUP>', \&arg_end); |
---|
545 | |
---|
546 | sgml('<OPTION>', \&bold_on); |
---|
547 | sgml('</OPTION>', \&font_off); |
---|
548 | |
---|
549 | # FIXME: This is one _blank_ line. |
---|
550 | man_sgml('<SBR>', "\n\n"); |
---|
551 | |
---|
552 | |
---|
553 | ######################################################################## |
---|
554 | # |
---|
555 | # General sections |
---|
556 | # |
---|
557 | ######################################################################## |
---|
558 | |
---|
559 | # The name of the section is handled by TITLE. This just sets |
---|
560 | # up the roff markup. |
---|
561 | man_sgml('<REFSECT1>', sub { $separator = ''; man_output "\n.SH "}); |
---|
562 | man_sgml('<REFSECT2>', sub { $separator = ''; man_output "\n.SS "}); |
---|
563 | man_sgml('<REFSECT3>', sub { $separator = ''; man_output "\n.SS "}); |
---|
564 | |
---|
565 | |
---|
566 | ######################################################################## |
---|
567 | # |
---|
568 | # Titles, metadata. |
---|
569 | # |
---|
570 | ######################################################################## |
---|
571 | |
---|
572 | sgml('<TITLE>', sub { |
---|
573 | if($_[0]->in('REFERENCE') or $_[0]->in('BOOK')) { |
---|
574 | $write_manpages = 1; |
---|
575 | } |
---|
576 | save_cdata(); |
---|
577 | }); |
---|
578 | sgml('</TITLE>', sub { |
---|
579 | my ($element, $event) = @_; |
---|
580 | my $title = fold_string(pop_output()); |
---|
581 | $raw_cdata--; |
---|
582 | |
---|
583 | if($element->in('REFERENCE') or $element->in('BOOK')) { |
---|
584 | # We use TITLE of enclosing Reference or Book as manual name |
---|
585 | $manpage_manual = $title; |
---|
586 | $write_manpages = 0; |
---|
587 | } |
---|
588 | elsif(exists $element->parent->ext->{'title'}) { |
---|
589 | # By far the easiest case. Just fold the string as |
---|
590 | # above, and then set the parent element's variable. |
---|
591 | $_[0]->parent->ext->{'title'} = $title; |
---|
592 | } |
---|
593 | else { |
---|
594 | # If the parent element's handlers are lazy, |
---|
595 | # output the folded string for them :) |
---|
596 | # We assume they want uppercase and a newline. |
---|
597 | man_output '"', uc($title), "\"\n"; |
---|
598 | } |
---|
599 | |
---|
600 | if (defined($element->attribute('ID')->value)) { |
---|
601 | my $id = $_[0]->attribute('ID')->value; |
---|
602 | $Refs->put("title:$id", $title); |
---|
603 | } |
---|
604 | |
---|
605 | my ($filename, $citation) = |
---|
606 | FileInfo($manpage_title, $manpage_sect || $default_sect); |
---|
607 | my $parentid = $element->parent->attribute('ID')->value; |
---|
608 | if ($parentid and ($element->in('REFSECT1') or $element->in('REFSECT2') or $element->in('REFSECT3'))) { |
---|
609 | $Refs->put("refsect:$parentid", "$citation"); |
---|
610 | } |
---|
611 | }); |
---|
612 | |
---|
613 | sgml('<ATTRIBUTION>', sub { |
---|
614 | if($_[0]->in('BLOCKQUOTE')) { |
---|
615 | push_output('string'); |
---|
616 | } |
---|
617 | }); |
---|
618 | sgml('</ATTRIBUTION>', sub { |
---|
619 | if($_[0]->in('BLOCKQUOTE')) { |
---|
620 | $_[0]->parent->ext->{'attribution'} = pop_output(); |
---|
621 | } else { |
---|
622 | # For an Epigraph. |
---|
623 | man_output "\n\n"; |
---|
624 | } |
---|
625 | }); |
---|
626 | |
---|
627 | sgml('<DATE>', sub { |
---|
628 | save_cdata(); |
---|
629 | }); |
---|
630 | sgml('</DATE>', sub { |
---|
631 | $_[0]->parent->parent->ext->{'date'} = fold_string(pop_output()); |
---|
632 | $raw_cdata--; |
---|
633 | }); |
---|
634 | |
---|
635 | sub ignore_content { push_output 'nul'; } |
---|
636 | sub restore_content { pop_output(); } |
---|
637 | |
---|
638 | sgml('<DOCINFO>', \&ignore_content); |
---|
639 | sgml('</DOCINFO>', \&restore_content); |
---|
640 | sgml('<REFSYNOPSISDIVINFO>', \&ignore_content); |
---|
641 | sgml('</REFSYNOPSISDIVINFO>', \&restore_content); |
---|
642 | sgml('<REFSECT1INFO>', \&ignore_content); |
---|
643 | sgml('</REFSECT1INFO>', \&restore_content); |
---|
644 | sgml('<REFSECT2INFO>', \&ignore_content); |
---|
645 | sgml('</REFSECT2INFO>', \&restore_content); |
---|
646 | sgml('<REFSECT3INFO>', \&ignore_content); |
---|
647 | sgml('</REFSECT3INFO>', \&restore_content); |
---|
648 | |
---|
649 | sgml('<INDEXTERM>', \&ignore_content); |
---|
650 | sgml('</INDEXTERM>', \&restore_content); |
---|
651 | |
---|
652 | sgml('<AUTHORBLURB>', \&ignore_content); |
---|
653 | sgml('</AUTHORBLURB>', \&restore_content); |
---|
654 | |
---|
655 | |
---|
656 | ######################################################################## |
---|
657 | # |
---|
658 | # Set bold on enclosed content |
---|
659 | # |
---|
660 | ######################################################################## |
---|
661 | |
---|
662 | sgml('<APPLICATION>', \&bold_on); |
---|
663 | sgml('</APPLICATION>', \&font_off); |
---|
664 | |
---|
665 | sgml('<CLASSNAME>', \&bold_on); sgml('</CLASSNAME>', \&font_off); |
---|
666 | sgml('<STRUCTNAME>', \&bold_on); sgml('</STRUCTNAME>', \&font_off); |
---|
667 | sgml('<STRUCTFIELD>', \&bold_on); sgml('</STRUCTFIELD>', \&font_off); |
---|
668 | sgml('<SYMBOL>', \&bold_on); sgml('</SYMBOL>', \&font_off); |
---|
669 | sgml('<TYPE>', \&bold_on); sgml('</TYPE>', \&font_off); |
---|
670 | |
---|
671 | sgml('<ENVAR>', \&bold_on); sgml('</ENVAR>', \&font_off); |
---|
672 | |
---|
673 | sgml('<FUNCTION>', \&bold_on); sgml('</FUNCTION>', \&font_off); |
---|
674 | |
---|
675 | sgml('<EMPHASIS>', \&bold_on); sgml('</EMPHASIS>', \&font_off); |
---|
676 | |
---|
677 | sgml('<ERRORNAME>', \&bold_on); sgml('</ERRORNAME>', \&font_off); |
---|
678 | # ERRORTYPE |
---|
679 | |
---|
680 | sgml('<COMMAND>', \&bold_on); sgml('</COMMAND>', \&font_off); |
---|
681 | |
---|
682 | sgml('<GUIBUTTON>', \&bold_on); sgml('</GUIBUTTON>', \&font_off); |
---|
683 | sgml('<GUIICON>', \&bold_on); sgml('</GUIICON>', \&font_off); |
---|
684 | # GUILABEL |
---|
685 | # GUIMENU |
---|
686 | # GUIMENUITEM |
---|
687 | # GUISUBMENU |
---|
688 | # MENUCHOICE |
---|
689 | |
---|
690 | sgml('<ACCEL>', \&bold_on); sgml('</ACCEL>', \&font_off); |
---|
691 | # KEYCODE |
---|
692 | # SHORTCUT |
---|
693 | |
---|
694 | |
---|
695 | sgml('<KEYCOMBO>', sub { |
---|
696 | $separator = 'none'; |
---|
697 | $_[0]->ext->{'separator'} = 'none'; |
---|
698 | }); |
---|
699 | sgml('</KEYCOMBO>', sub { $separator = $_[0]->parent->ext->{'separator'}; }); |
---|
700 | |
---|
701 | sub _keycombo { |
---|
702 | if($_[0]->in('KEYCOMBO')) { |
---|
703 | if($separator eq 'none') { $separator = '' } |
---|
704 | else { man_output "+"; } |
---|
705 | } |
---|
706 | bold_on(); |
---|
707 | } |
---|
708 | sgml('<KEYCAP>', \&_keycombo); sgml('</KEYCAP>', \&font_off); |
---|
709 | sgml('<KEYSYM>', \&_keycombo); sgml('</KEYSYM>', \&font_off); |
---|
710 | sgml('<MOUSEBUTTON>', \&_keycombo); sgml('</MOUSEBUTTON>', \&font_off); |
---|
711 | |
---|
712 | |
---|
713 | sgml('<USERINPUT>', \&bold_on); sgml('</USERINPUT>', \&font_off); |
---|
714 | |
---|
715 | sgml('<INTERFACEDEFINITION>', \&bold_on); |
---|
716 | sgml('</INTERFACEDEFINITION>', \&font_off); |
---|
717 | |
---|
718 | # May need to look at the CLASS |
---|
719 | sgml('<SYSTEMITEM>', \&bold_on); |
---|
720 | sgml('</SYSTEMITEM>', \&font_off); |
---|
721 | |
---|
722 | |
---|
723 | ######################################################################## |
---|
724 | # |
---|
725 | # Set italic on enclosed content |
---|
726 | # |
---|
727 | ######################################################################## |
---|
728 | |
---|
729 | sgml('<FIRSTTERM>', \&italic_on); sgml('</FIRSTTERM>', \&font_off); |
---|
730 | |
---|
731 | sgml('<FILENAME>', \&italic_on); sgml('</FILENAME>', \&font_off); |
---|
732 | sgml('<PARAMETER>', \&italic_on); sgml('</PARAMETER>', \&font_off); |
---|
733 | sgml('<PROPERTY>', \&italic_on); sgml('</PROPERTY>', \&font_off); |
---|
734 | |
---|
735 | sgml('<REPLACEABLE>', sub { |
---|
736 | italic_on(); |
---|
737 | if($_[0]->in('TOKEN')) { |
---|
738 | # When tokenizing, follow more 'intuitive' convention |
---|
739 | output "<"; |
---|
740 | } |
---|
741 | }); |
---|
742 | sgml('</REPLACEABLE>', sub { |
---|
743 | if($_[0]->in('TOKEN')) { |
---|
744 | output ">"; |
---|
745 | } |
---|
746 | font_off(); |
---|
747 | }); |
---|
748 | |
---|
749 | sgml('<CITETITLE>', \&italic_on); sgml('</CITETITLE>', \&font_off); |
---|
750 | sgml('<FOREIGNPHRASE>', \&italic_on); sgml('</FOREIGNPHRASE>', \&font_off); |
---|
751 | |
---|
752 | sgml('<LINEANNOTATION>', \&italic_on); sgml('</LINEANNOTATION>', \&font_off); |
---|
753 | |
---|
754 | |
---|
755 | ######################################################################## |
---|
756 | # |
---|
757 | # Other 'inline' elements |
---|
758 | # |
---|
759 | ######################################################################## |
---|
760 | |
---|
761 | man_sgml('<EMAIL>', '<'); |
---|
762 | man_sgml('</EMAIL>', '>'); |
---|
763 | man_sgml('<OPTIONAL>', '['); |
---|
764 | man_sgml('</OPTIONAL>', ']'); |
---|
765 | |
---|
766 | man_sgml('</TRADEMARK>', "\\u\\s-2TM\\s+2\\d"); |
---|
767 | |
---|
768 | man_sgml('<COMMENT>', "[Comment: "); |
---|
769 | man_sgml('</COMMENT>', "]"); |
---|
770 | |
---|
771 | man_sgml('<QUOTE>', "``"); |
---|
772 | man_sgml('</QUOTE>', "''"); |
---|
773 | |
---|
774 | #man_sgml('<LITERAL>', '"'); |
---|
775 | #man_sgml('</LITERAL>', '"'); |
---|
776 | # There doesn't seem to be a good way to represent LITERAL in -man |
---|
777 | # ComputerOutput, SGMLTag, Markup are the same thing. |
---|
778 | |
---|
779 | # These create spaces between content in special elements |
---|
780 | # without PCDATA content. |
---|
781 | man_sgml('</HONORIFIC>', " "); |
---|
782 | man_sgml('</FIRSTNAME>', " "); |
---|
783 | man_sgml('</SURNAME>', " "); |
---|
784 | man_sgml('</LINEAGE>', " "); |
---|
785 | man_sgml('</OTHERNAME>', " "); |
---|
786 | |
---|
787 | man_sgml('<AFFILIATION>', "("); |
---|
788 | man_sgml('</AFFILIATION>', ") "); |
---|
789 | man_sgml('<CONTRIB>', "("); |
---|
790 | man_sgml('</CONTRIB>', ") "); |
---|
791 | |
---|
792 | man_sgml('</STREET>', " "); |
---|
793 | man_sgml('</POB>', " "); |
---|
794 | man_sgml('</POSTCODE>', " "); |
---|
795 | man_sgml('</CITY>', " "); |
---|
796 | man_sgml('</STATE>', " "); |
---|
797 | man_sgml('</COUNTRY>', " "); |
---|
798 | man_sgml('</PHONE>', " "); |
---|
799 | man_sgml('</FAX>', " "); |
---|
800 | man_sgml('</OTHERADDRESS>', " "); |
---|
801 | |
---|
802 | man_sgml('</ALT>', ": "); |
---|
803 | man_sgml('<GRAPHIC>', " [GRAPHIC] "); |
---|
804 | |
---|
805 | # No special presentation: |
---|
806 | |
---|
807 | # AUTHORINITIALS |
---|
808 | |
---|
809 | # ABBREV |
---|
810 | # ACTION |
---|
811 | # ACRONYM |
---|
812 | # CITATION |
---|
813 | # PHRASE |
---|
814 | # QUOTE |
---|
815 | # WORDASWORD |
---|
816 | |
---|
817 | # PROMPT |
---|
818 | # RETURNVALUE |
---|
819 | # TOKEN |
---|
820 | |
---|
821 | # DATABASE |
---|
822 | # HARDWARE |
---|
823 | # INTERFACE |
---|
824 | # MEDIALABEL |
---|
825 | |
---|
826 | |
---|
827 | ######################################################################## |
---|
828 | # |
---|
829 | # Paragraph and paragraph-like elements |
---|
830 | # |
---|
831 | ######################################################################## |
---|
832 | |
---|
833 | sub para_start { |
---|
834 | if($separator eq '' or $separator eq 'full') { |
---|
835 | $separator = ''; |
---|
836 | man_output "\n.PP\n"; |
---|
837 | } elsif($separator eq 'blank') { |
---|
838 | man_output "\n\n"; |
---|
839 | } elsif($separator eq 'none' ) { |
---|
840 | $_[0]->parent->ext->{'separator'} = 'blank'; |
---|
841 | $separator = 'blank'; |
---|
842 | } |
---|
843 | } |
---|
844 | # Actually applies to a few other block elements as well |
---|
845 | sub para_end { |
---|
846 | $separator = $_[0]->parent->ext->{'separator'}; |
---|
847 | man_output "\n"; |
---|
848 | } |
---|
849 | |
---|
850 | sgml('<PARA>', \¶_start); |
---|
851 | sgml('</PARA>', \¶_end); |
---|
852 | sgml('<SIMPARA>', \¶_start); |
---|
853 | sgml('</SIMPARA>', \¶_end); |
---|
854 | |
---|
855 | # Nothing special, except maybe FIXME set nobreak. |
---|
856 | sgml('<INFORMALEXAMPLE>', \¶_start); |
---|
857 | sgml('</INFORMALEXAMPLE>', \¶_end); |
---|
858 | |
---|
859 | |
---|
860 | ######################################################################## |
---|
861 | # |
---|
862 | # Blocks using SS sections |
---|
863 | # |
---|
864 | ######################################################################## |
---|
865 | |
---|
866 | # FIXME: We need to consider the effects of SS |
---|
867 | # in a hanging tag :( |
---|
868 | |
---|
869 | # Complete with the optional-title dilemma (again). |
---|
870 | sgml('<ABSTRACT>', sub { |
---|
871 | $_[0]->ext->{'title'} = 'ABSTRACT'; |
---|
872 | output "\n" unless $newline_last++; |
---|
873 | push_output('string'); |
---|
874 | }); |
---|
875 | sgml('</ABSTRACT>', sub { |
---|
876 | my $content = pop_output(); |
---|
877 | |
---|
878 | # As ABSTRACT is never on the same level as RefSect1, |
---|
879 | # this leaves us with only .SS in terms of -man macros. |
---|
880 | output ".SS \"", uc($_[0]->ext->{'title'}), "\"\n"; |
---|
881 | |
---|
882 | output $content; |
---|
883 | output "\n" unless $newline_last++; |
---|
884 | }); |
---|
885 | |
---|
886 | |
---|
887 | |
---|
888 | # Ah, I needed a break. Example always has a title. |
---|
889 | sgml('<EXAMPLE>', sub { $separator = ''; man_output "\n.SS "}); |
---|
890 | sgml('</EXAMPLE>', \¶_end); |
---|
891 | |
---|
892 | # Same with sidebar. |
---|
893 | sgml('<SIDEBAR>', sub { $separator = ''; man_output "\n.SS "}); |
---|
894 | sgml('</SIDEBAR>', \¶_end); |
---|
895 | |
---|
896 | sgml('<FORMALPARA>', sub { $separator = ''; man_output "\n.SS "}); |
---|
897 | sgml('</FORMALPARA>', \¶_end); |
---|
898 | |
---|
899 | sgml('<FIGURE>', sub { $separator = ''; man_output "\n.SS "}); |
---|
900 | sgml('</FIGURE>', \¶_end); |
---|
901 | |
---|
902 | |
---|
903 | |
---|
904 | # NO title. |
---|
905 | sgml('<HIGHLIGHTS>', sub { $separator = ''; man_output "\n.SS HIGHLIGHTS\n"}); |
---|
906 | sgml('</HIGHLIGHTS>', \¶_end); |
---|
907 | |
---|
908 | |
---|
909 | ######################################################################## |
---|
910 | # |
---|
911 | # Indented 'Block' elements |
---|
912 | # |
---|
913 | ######################################################################## |
---|
914 | |
---|
915 | sub indent_block_start |
---|
916 | { |
---|
917 | $separator = ''; |
---|
918 | man_output "\n.sp\n.RS\n"; |
---|
919 | } |
---|
920 | sub indent_block_end |
---|
921 | { |
---|
922 | $separator = $_[0]->parent->ext->{'separator'}; |
---|
923 | man_output "\n.RE\n.sp\n"; |
---|
924 | } |
---|
925 | |
---|
926 | sgml('<ADDRESS>', sub { |
---|
927 | &indent_block_start; |
---|
928 | if($_[0]->attribute('FORMAT')->type eq 'NOTATION' |
---|
929 | and $_[0]->attribute('FORMAT')->value->name eq 'LINESPECIFIC') { |
---|
930 | &verbatim_start; |
---|
931 | } |
---|
932 | }); |
---|
933 | sgml('</ADDRESS>', sub { |
---|
934 | if($_[0]->attribute('FORMAT')->type eq 'NOTATION' |
---|
935 | and $_[0]->attribute('FORMAT')->value->name eq 'LINESPECIFIC') { |
---|
936 | &verbatim_end; |
---|
937 | } |
---|
938 | &indent_block_end; |
---|
939 | }); |
---|
940 | |
---|
941 | # This element is almost like an admonition (below), |
---|
942 | # only the default title is blank :) |
---|
943 | |
---|
944 | sgml('<BLOCKQUOTE>', sub { |
---|
945 | $_[0]->ext->{'title'} = ''; |
---|
946 | &indent_block_start; |
---|
947 | push_output('string'); |
---|
948 | }); |
---|
949 | sgml('</BLOCKQUOTE>', sub { |
---|
950 | my $content = pop_output(); |
---|
951 | |
---|
952 | if($_[0]->ext->{'title'}) { |
---|
953 | output ".B \"", $_[0]->ext->{'title'}, ":\"\n"; |
---|
954 | } |
---|
955 | |
---|
956 | output $content; |
---|
957 | |
---|
958 | if($_[0]->ext->{'attribution'}) { |
---|
959 | man_output "\n\n -- ", |
---|
960 | $_[0]->ext->{'attribution'}, "\n"; |
---|
961 | } |
---|
962 | |
---|
963 | &indent_block_end; |
---|
964 | }); |
---|
965 | |
---|
966 | # Set off admonitions from the rest of the text by indenting. |
---|
967 | # FIXME: Need to check if this works inside paragraphs, not enclosing them. |
---|
968 | sub admonition_end { |
---|
969 | my $content = pop_output(); |
---|
970 | |
---|
971 | # When the admonition is only one paragraph, |
---|
972 | # it looks nicer if the title was inline. |
---|
973 | my $num_para; |
---|
974 | while ($content =~ /^\.PP/gm) { $num_para++ } |
---|
975 | if($num_para==1) { |
---|
976 | $content =~ s/^\.PP\n//; |
---|
977 | } |
---|
978 | |
---|
979 | output ".B \"" . $_[0]->ext->{'title'} . ":\"\n"; |
---|
980 | output $content; |
---|
981 | |
---|
982 | &indent_block_end; |
---|
983 | } |
---|
984 | |
---|
985 | sgml('<NOTE>', sub { |
---|
986 | # We can't see right now whether or not there is a TITLE |
---|
987 | # element, so we have to save the output now and add it back |
---|
988 | # at the end of this admonition. |
---|
989 | $_[0]->ext->{'title'} = 'Note'; |
---|
990 | |
---|
991 | &indent_block_start; |
---|
992 | |
---|
993 | push_output('string'); |
---|
994 | }); |
---|
995 | sgml('</NOTE>', \&admonition_end); |
---|
996 | |
---|
997 | # Same as above. |
---|
998 | sgml('<WARNING>', sub { |
---|
999 | $_[0]->ext->{'title'} = 'Warning'; |
---|
1000 | &indent_block_start; |
---|
1001 | push_output('string'); |
---|
1002 | }); |
---|
1003 | sgml('</WARNING>', \&admonition_end); |
---|
1004 | |
---|
1005 | sgml('<TIP>', sub { |
---|
1006 | $_[0]->ext->{'title'} = 'Tip'; |
---|
1007 | &indent_block_start; |
---|
1008 | push_output('string'); |
---|
1009 | }); |
---|
1010 | sgml('</TIP>', \&admonition_end); |
---|
1011 | sgml('<CAUTION>', sub { |
---|
1012 | $_[0]->ext->{'title'} = 'Caution'; |
---|
1013 | &indent_block_start; |
---|
1014 | push_output('string'); |
---|
1015 | }); |
---|
1016 | sgml('</CAUTION>', \&admonition_end); |
---|
1017 | |
---|
1018 | sgml('<IMPORTANT>', sub { |
---|
1019 | $_[0]->ext->{'title'} = 'Important'; |
---|
1020 | &indent_block_start; |
---|
1021 | push_output('string'); |
---|
1022 | }); |
---|
1023 | sgml('</IMPORTANT>', \&admonition_end); |
---|
1024 | |
---|
1025 | |
---|
1026 | ######################################################################## |
---|
1027 | # |
---|
1028 | # Verbatim displays. |
---|
1029 | # |
---|
1030 | ######################################################################## |
---|
1031 | |
---|
1032 | sub verbatim_start { |
---|
1033 | $separator = ''; |
---|
1034 | man_output "\n.sp\n"; |
---|
1035 | man_output "\n.nf\n" unless $nocollapse_whitespace++; |
---|
1036 | } |
---|
1037 | |
---|
1038 | sub verbatim_end { |
---|
1039 | man_output "\n.sp\n"; |
---|
1040 | man_output "\n.fi\n" unless --$nocollapse_whitespace; |
---|
1041 | $separator = $_[0]->parent->ext->{'separator'}; |
---|
1042 | } |
---|
1043 | |
---|
1044 | sgml('<PROGRAMLISTING>', \&verbatim_start); |
---|
1045 | sgml('</PROGRAMLISTING>', \&verbatim_end); |
---|
1046 | |
---|
1047 | sgml('<SCREEN>', \&verbatim_start); |
---|
1048 | sgml('</SCREEN>', \&verbatim_end); |
---|
1049 | |
---|
1050 | sgml('<LITERALLAYOUT>', \&verbatim_start); |
---|
1051 | sgml('</LITERALLAYOUT>', \&verbatim_end); |
---|
1052 | |
---|
1053 | sgml('<SYNOPSIS>', sub { |
---|
1054 | my $format = $_[0]->attribute('FORMAT'); |
---|
1055 | |
---|
1056 | if($format->type eq 'NOTATION' |
---|
1057 | and $format->value->name eq 'LINESPECIFIC') |
---|
1058 | { |
---|
1059 | &verbatim_start; |
---|
1060 | } else { |
---|
1061 | $separator = ''; |
---|
1062 | man_output "\n.sp\n"; |
---|
1063 | } |
---|
1064 | }); |
---|
1065 | |
---|
1066 | sgml('</SYNOPSIS>', sub { |
---|
1067 | my $format = $_[0]->attribute('FORMAT'); |
---|
1068 | |
---|
1069 | if($format->type eq 'NOTATION' |
---|
1070 | and $format->value->name eq 'LINESPECIFIC') |
---|
1071 | { |
---|
1072 | &verbatim_end; |
---|
1073 | } else { |
---|
1074 | man_output "\n"; |
---|
1075 | $_[0]->parent->ext->{'separator'} = 'full'; |
---|
1076 | $separator = 'full'; |
---|
1077 | } |
---|
1078 | }); |
---|
1079 | |
---|
1080 | |
---|
1081 | ######################################################################## |
---|
1082 | # |
---|
1083 | # Lists |
---|
1084 | # |
---|
1085 | ######################################################################## |
---|
1086 | |
---|
1087 | # Indent nested lists. |
---|
1088 | sub list_start { |
---|
1089 | man_output "\n.RS\n" if $list_nestlevel++; |
---|
1090 | } |
---|
1091 | sub list_end { |
---|
1092 | man_output "\n.RE\n" if --$list_nestlevel; |
---|
1093 | $_[0]->parent->ext->{'separator'} = 'full'; |
---|
1094 | $separator = 'full'; |
---|
1095 | } |
---|
1096 | |
---|
1097 | sgml('<VARIABLELIST>', \&list_start); |
---|
1098 | sgml('</VARIABLELIST>', \&list_end); |
---|
1099 | sgml('<ITEMIZEDLIST>', \&list_start); |
---|
1100 | sgml('</ITEMIZEDLIST>', \&list_end); |
---|
1101 | sgml('<ORDEREDLIST>', sub { |
---|
1102 | &list_start; |
---|
1103 | $_[0]->ext->{'count'} = 1; |
---|
1104 | }); |
---|
1105 | sgml('</ORDEREDLIST>', \&list_end); |
---|
1106 | |
---|
1107 | # Output content on one line, bolded. |
---|
1108 | sgml('<TERM>', sub { |
---|
1109 | man_output "\n.TP\n"; |
---|
1110 | bold_on(); |
---|
1111 | push_output('string'); |
---|
1112 | }); |
---|
1113 | sgml('</TERM>', sub { |
---|
1114 | my $term = StripString(pop_output()); |
---|
1115 | $term =~ tr/\n/ /; |
---|
1116 | output $term; |
---|
1117 | font_off(); |
---|
1118 | output "\n"; |
---|
1119 | $newline_last = 1; |
---|
1120 | }); |
---|
1121 | |
---|
1122 | sgml('<LISTITEM>', sub { |
---|
1123 | # A bulleted list. |
---|
1124 | if($_[0]->in('ITEMIZEDLIST')) { |
---|
1125 | man_output "\n.TP 0.2i\n\\(bu\n"; |
---|
1126 | } |
---|
1127 | |
---|
1128 | # Need numbers. |
---|
1129 | # Assume Arabic numeration for now. |
---|
1130 | elsif($_[0]->in('ORDEREDLIST')) { |
---|
1131 | man_output "\n.IP ", $_[0]->parent->ext->{'count'}++, ". \n"; |
---|
1132 | } |
---|
1133 | |
---|
1134 | $_[0]->ext->{'separator'} = 'none'; |
---|
1135 | $separator = 'none'; |
---|
1136 | }); |
---|
1137 | |
---|
1138 | sgml('<SIMPLELIST>', sub { |
---|
1139 | $_[0]->ext->{'first_member'} = 1; |
---|
1140 | }); |
---|
1141 | sgml('<MEMBER>', sub { |
---|
1142 | my $parent = $_[0]->parent; |
---|
1143 | |
---|
1144 | if($parent->attribute('TYPE')->value =~ /Inline/i) { |
---|
1145 | if($parent->ext->{'first_member'}) { |
---|
1146 | # If this is the first member don't put any commas |
---|
1147 | $parent->ext->{'first_member'} = 0; |
---|
1148 | } else { |
---|
1149 | man_output ", "; |
---|
1150 | } |
---|
1151 | |
---|
1152 | # We don't really have Horiz rendering, so it's the same |
---|
1153 | # as Vert. |
---|
1154 | } else { |
---|
1155 | man_output "\n\n"; |
---|
1156 | } |
---|
1157 | }); |
---|
1158 | |
---|
1159 | # We implement Procedures as indent and lists |
---|
1160 | |
---|
1161 | sgml('<PROCEDURE>', sub { |
---|
1162 | $_[0]->ext->{'count'} = 1; |
---|
1163 | &indent_block_start; |
---|
1164 | }); |
---|
1165 | sgml('</PROCEDURE>', sub { |
---|
1166 | &indent_block_end; |
---|
1167 | $_[0]->parent->ext->{'separator'} = 'full'; |
---|
1168 | $separator = 'full'; |
---|
1169 | }); |
---|
1170 | |
---|
1171 | sgml('<STEP>', sub { |
---|
1172 | man_output "\n.IP ", $_[0]->parent->ext->{'count'}++, ". \n"; |
---|
1173 | $_[0]->ext->{'separator'} = 'none'; |
---|
1174 | $separator = 'none'; |
---|
1175 | }); |
---|
1176 | |
---|
1177 | |
---|
1178 | ######################################################################## |
---|
1179 | # |
---|
1180 | # Linkage, cross references |
---|
1181 | # |
---|
1182 | ######################################################################## |
---|
1183 | |
---|
1184 | # Print the URL |
---|
1185 | sgml('</ULINK>', sub { |
---|
1186 | man_output ' <URL:', $_[0]->attribute('URL')->value, '>'; |
---|
1187 | }); |
---|
1188 | |
---|
1189 | # If cross reference target is a RefEntry, |
---|
1190 | # output CiteRefEntry-style references. |
---|
1191 | sgml('<XREF>', sub { |
---|
1192 | my $id = $_[0]->attribute('LINKEND')->value; |
---|
1193 | |
---|
1194 | my $manref = $Refs->get("refentry:$id") || $Refs->get("refsect:$id"); |
---|
1195 | if(!defined $manref) { |
---|
1196 | $blank_xrefs++ if $write_manpages; |
---|
1197 | man_output "[XRef to $id]"; |
---|
1198 | return; |
---|
1199 | } |
---|
1200 | |
---|
1201 | # Limited ENDTERM support. |
---|
1202 | if(defined $_[0]->attribute('ENDTERM')->value) { |
---|
1203 | my $endterm = $_[0]->attribute('ENDTERM')->value; |
---|
1204 | my $content = $Refs->get("title:$endterm") || |
---|
1205 | $Refs->get("refentrytitle:$endterm"); |
---|
1206 | man_output $content, ' ['; |
---|
1207 | } |
---|
1208 | |
---|
1209 | # This also displays the XREFLABEL (as bold)... |
---|
1210 | # It's not worth the bother to fix it though, there |
---|
1211 | # are better tools for this. |
---|
1212 | my ($title, $sect) = ($manref =~ /(.*)(\(.*\))/); |
---|
1213 | bold_on(); |
---|
1214 | man_output $title; |
---|
1215 | font_off(); |
---|
1216 | man_output $sect; |
---|
1217 | |
---|
1218 | if(defined $_[0]->attribute('ENDTERM')->value) { |
---|
1219 | man_output ']'; |
---|
1220 | } |
---|
1221 | }); |
---|
1222 | |
---|
1223 | # Anchor |
---|
1224 | |
---|
1225 | ######################################################################## |
---|
1226 | # |
---|
1227 | # SDATA |
---|
1228 | # |
---|
1229 | ######################################################################## |
---|
1230 | |
---|
1231 | man_sgml('|[lt ]|', '<'); |
---|
1232 | man_sgml('|[equals]|', '='); |
---|
1233 | man_sgml('|[gt ]|', '>'); |
---|
1234 | man_sgml('|[plus ]|', '\(pl'); |
---|
1235 | man_sgml('|[dollar]|', '$'); |
---|
1236 | man_sgml('|[num ]|', '#'); |
---|
1237 | man_sgml('|[percnt]|', '%'); |
---|
1238 | man_sgml('|[amp ]|', '&'); |
---|
1239 | man_sgml('|[commat]|', '@'); |
---|
1240 | man_sgml('|[lsqb ]|', '['); |
---|
1241 | man_sgml('|[bsol ]|', '\e'); |
---|
1242 | man_sgml('|[rsqb ]|', ']'); |
---|
1243 | man_sgml('|[lcub ]|', '{'); |
---|
1244 | man_sgml('|[verbar]|', '\(or'); |
---|
1245 | man_sgml('|[rcub ]|', '}'); |
---|
1246 | man_sgml('|[excl ]|', '!'); |
---|
1247 | man_sgml('|[quot ]|', '"'); |
---|
1248 | man_sgml('|[apos ]|', '\\&\''); |
---|
1249 | man_sgml('|[lpar ]|', '('); |
---|
1250 | man_sgml('|[rpar ]|', ')'); |
---|
1251 | man_sgml('|[comma ]|', ','); |
---|
1252 | man_sgml('|[lowbar]|', '_'); |
---|
1253 | man_sgml('|[period]|', '.'); |
---|
1254 | man_sgml('|[sol ]|', '/'); |
---|
1255 | man_sgml('|[colon ]|', ':'); |
---|
1256 | man_sgml('|[semi ]|', ';'); |
---|
1257 | man_sgml('|[quest ]|', '?'); |
---|
1258 | man_sgml('|[grave ]|', '`'); |
---|
1259 | man_sgml('|[tilde ]|', '~'); |
---|
1260 | man_sgml('|[half ]|', '\(12'); |
---|
1261 | man_sgml('|[frac12]|', '\(12'); |
---|
1262 | man_sgml('|[frac14]|', '\(14'); |
---|
1263 | man_sgml('|[frac34]|', '\(34'); |
---|
1264 | man_sgml('|[frac18]|', '1/8'); |
---|
1265 | man_sgml('|[frac38]|', '3/8'); |
---|
1266 | man_sgml('|[frac58]|', '5/8'); |
---|
1267 | man_sgml('|[frac78]|', '7/8'); |
---|
1268 | man_sgml('|[sup1 ]|', '\u1\l'); |
---|
1269 | man_sgml('|[sup2 ]|', '\u2\l'); |
---|
1270 | man_sgml('|[sup3 ]|', '\u3\l'); |
---|
1271 | man_sgml('|[plusmn]|', '\(+-'); |
---|
1272 | man_sgml('|[divide]|', '\(di'); |
---|
1273 | man_sgml('|[times ]|', '\(ti'); |
---|
1274 | man_sgml('|[pound ]|', '#'); |
---|
1275 | man_sgml('|[cent ]|', '\(ct'); |
---|
1276 | man_sgml('|[yen ]|', 'yen'); |
---|
1277 | man_sgml('|[ast ]|', '*'); |
---|
1278 | man_sgml('|[horbar]|', '_'); |
---|
1279 | man_sgml('|[micro ]|', '\(*m'); |
---|
1280 | man_sgml('|[ohm ]|', '\(*W'); |
---|
1281 | man_sgml('|[deg ]|', '\(de'); |
---|
1282 | man_sgml('|[sect ]|', '\(sc'); |
---|
1283 | man_sgml('|[larr ]|', '\(<-'); |
---|
1284 | man_sgml('|[rarr ]|', '\(->'); |
---|
1285 | man_sgml('|[uarr ]|', '\(ua'); |
---|
1286 | man_sgml('|[darr ]|', '\(da'); |
---|
1287 | man_sgml('|[copy ]|', '\(co'); |
---|
1288 | man_sgml('|[reg ]|', '\(rg'); |
---|
1289 | man_sgml('|[trade ]|', '\(tm'); |
---|
1290 | man_sgml('|[brvbar]|', '|'); |
---|
1291 | man_sgml('|[not ]|', '\(no'); |
---|
1292 | man_sgml('|[hyphen]|', '\-'); |
---|
1293 | man_sgml('|[laquo ]|', '<<'); |
---|
1294 | man_sgml('|[raquo ]|', '>>'); |
---|
1295 | man_sgml('|[lsquo ]|', '`'); |
---|
1296 | man_sgml('|[rsquo ]|', '\&\''); |
---|
1297 | man_sgml('|[ldquo ]|', '"'); |
---|
1298 | man_sgml('|[rdquo ]|', '"'); |
---|
1299 | man_sgml('|[nbsp ]|', '\ '); |
---|
1300 | man_sgml('|[shy ]|', '\%'); |
---|
1301 | man_sgml('|[emsp ]|', '\ \ '); |
---|
1302 | man_sgml('|[ensp ]|', '\ '); |
---|
1303 | man_sgml('|[emsp3 ]|', '\ '); |
---|
1304 | man_sgml('|[emsp4 ]|', '\ '); |
---|
1305 | man_sgml('|[numsp ]|', '\0'); |
---|
1306 | man_sgml('|[puncsp]|', '\|'); |
---|
1307 | man_sgml('|[thinsp]|', '\!'); |
---|
1308 | man_sgml('|[hairsp]|', '\\^'); |
---|
1309 | man_sgml('|[mdash ]|', '\(em'); |
---|
1310 | man_sgml('|[ndash ]|', '-'); |
---|
1311 | man_sgml('|[dash ]|', '-'); |
---|
1312 | man_sgml('|[blank ]|', '\ '); |
---|
1313 | man_sgml('|[hellip]|', '\&...'); |
---|
1314 | man_sgml('|[nldr ]|', '\&..'); |
---|
1315 | man_sgml('|[frac13]|', '1/3'); |
---|
1316 | man_sgml('|[frac23]|', '2/3'); |
---|
1317 | man_sgml('|[frac15]|', '1/5'); |
---|
1318 | man_sgml('|[frac25]|', '2/5'); |
---|
1319 | man_sgml('|[frac35]|', '3/5'); |
---|
1320 | man_sgml('|[frac45]|', '4/5'); |
---|
1321 | man_sgml('|[frac16]|', '1/6'); |
---|
1322 | man_sgml('|[frac56]|', '5/6'); |
---|
1323 | man_sgml('|[cir ]|', '\(ci'); |
---|
1324 | man_sgml('|[squ ]|', '\(sq'); |
---|
1325 | man_sgml('|[star ]|', '\(**'); |
---|
1326 | man_sgml('|[bull ]|', '\(bu'); |
---|
1327 | man_sgml('|[dagger]|', '\(dg'); |
---|
1328 | man_sgml('|[Dagger]|', '\(dd'); |
---|
1329 | man_sgml('|[caret ]|', '\^'); |
---|
1330 | man_sgml('|[lsquor]|', '`'); |
---|
1331 | man_sgml('|[ldquor]|', '``'); |
---|
1332 | man_sgml('|[fflig ]|', '\(ff'); |
---|
1333 | man_sgml('|[filig ]|', '\(fi'); |
---|
1334 | man_sgml('|[ffilig]|', '\(Fi'); |
---|
1335 | man_sgml('|[ffllig]|', '\(Fl'); |
---|
1336 | man_sgml('|[fllig ]|', '\(fl'); |
---|
1337 | man_sgml('|[rdquor]|', '\&\'\''); |
---|
1338 | man_sgml('|[rsquor]|', '\&\''); |
---|
1339 | man_sgml('|[vellip]|', '\&...'); |
---|
1340 | man_sgml('|[aacute]|', '\(a\''); |
---|
1341 | man_sgml('|[Aacute]|', '\(A\''); |
---|
1342 | man_sgml('|[acirc ]|', '\(a^'); |
---|
1343 | man_sgml('|[Acirc ]|', '\(A^'); |
---|
1344 | man_sgml('|[agrave]|', '\(a`'); |
---|
1345 | man_sgml('|[Agrave]|', '\(A`'); |
---|
1346 | man_sgml('|[auml ]|', '\(a:'); |
---|
1347 | man_sgml('|[aelig ]|', '\(ae'); |
---|
1348 | man_sgml('|[AElig ]|', '\(AE'); |
---|
1349 | man_sgml('|[eacute]|', '\(e\''); |
---|
1350 | man_sgml('|[Eacute]|', '\(E\''); |
---|
1351 | man_sgml('|[egrave]|', '\(e`'); |
---|
1352 | man_sgml('|[Egrave]|', '\(E`'); |
---|
1353 | man_sgml('|[iacute]|', '\(i\''); |
---|
1354 | man_sgml('|[Iacute]|', '\(I\''); |
---|
1355 | man_sgml('|[igrave]|', '\(i`'); |
---|
1356 | man_sgml('|[Igrave]|', '\(I`'); |
---|
1357 | man_sgml('|[ntilde]|', '\(n~'); |
---|
1358 | man_sgml('|[Ntilde]|', '\(N~'); |
---|
1359 | man_sgml('|[oacute]|', '\(o\''); |
---|
1360 | man_sgml('|[Oacute]|', '\(O\''); |
---|
1361 | man_sgml('|[ograve]|', '\(o`'); |
---|
1362 | man_sgml('|[Ograve]|', '\(O`'); |
---|
1363 | man_sgml('|[oslash]|', '\(o/'); |
---|
1364 | man_sgml('|[Oslash]|', '\(O/'); |
---|
1365 | man_sgml('|[szlig ]|', '\(ss'); |
---|
1366 | man_sgml('|[thorn ]|', '\(th'); |
---|
1367 | man_sgml('|[uacute]|', '\(u\''); |
---|
1368 | man_sgml('|[Uacute]|', '\(U\''); |
---|
1369 | man_sgml('|[ugrave]|', '\(u`'); |
---|
1370 | man_sgml('|[Ugrave]|', '\(U`'); |
---|
1371 | man_sgml('|[aogon ]|', '\(ao'); |
---|
1372 | man_sgml('|[agr ]|', '\(*a'); |
---|
1373 | man_sgml('|[Agr ]|', '\(*A'); |
---|
1374 | man_sgml('|[bgr ]|', '\(*b'); |
---|
1375 | man_sgml('|[Bgr ]|', '\(*B'); |
---|
1376 | man_sgml('|[ggr ]|', '\(*g'); |
---|
1377 | man_sgml('|[Ggr ]|', '\(*G'); |
---|
1378 | man_sgml('|[dgr ]|', '\(*d'); |
---|
1379 | man_sgml('|[Dgr ]|', '\(*D'); |
---|
1380 | man_sgml('|[egr ]|', '\(*e'); |
---|
1381 | man_sgml('|[Egr ]|', '\(*E'); |
---|
1382 | man_sgml('|[zgr ]|', '\(*z'); |
---|
1383 | man_sgml('|[Zgr ]|', '\(*Z'); |
---|
1384 | man_sgml('|[eegr ]|', '\(*y'); |
---|
1385 | man_sgml('|[EEgr ]|', '\(*Y'); |
---|
1386 | man_sgml('|[thgr ]|', '\(*h'); |
---|
1387 | man_sgml('|[THgr ]|', '\(*H'); |
---|
1388 | man_sgml('|[igr ]|', '\(*i'); |
---|
1389 | man_sgml('|[Igr ]|', '\(*I'); |
---|
1390 | man_sgml('|[kgr ]|', '\(*k'); |
---|
1391 | man_sgml('|[Kgr ]|', '\(*K'); |
---|
1392 | man_sgml('|[lgr ]|', '\(*l'); |
---|
1393 | man_sgml('|[Lgr ]|', '\(*L'); |
---|
1394 | man_sgml('|[mgr ]|', '\(*m'); |
---|
1395 | man_sgml('|[Mgr ]|', '\(*M'); |
---|
1396 | man_sgml('|[ngr ]|', '\(*n'); |
---|
1397 | man_sgml('|[Ngr ]|', '\(*N'); |
---|
1398 | man_sgml('|[xgr ]|', '\(*c'); |
---|
1399 | man_sgml('|[Xgr ]|', '\(*C'); |
---|
1400 | man_sgml('|[ogr ]|', '\(*o'); |
---|
1401 | man_sgml('|[Ogr ]|', '\(*O'); |
---|
1402 | man_sgml('|[pgr ]|', '\(*p'); |
---|
1403 | man_sgml('|[Pgr ]|', '\(*P'); |
---|
1404 | man_sgml('|[rgr ]|', '\(*r'); |
---|
1405 | man_sgml('|[Rgr ]|', '\(*R'); |
---|
1406 | man_sgml('|[sgr ]|', '\(*s'); |
---|
1407 | man_sgml('|[Sgr ]|', '\(*S'); |
---|
1408 | man_sgml('|[sfgr ]|', '\(ts'); |
---|
1409 | man_sgml('|[tgr ]|', '\(*t'); |
---|
1410 | man_sgml('|[Tgr ]|', '\(*T'); |
---|
1411 | man_sgml('|[ugr ]|', '\(*u'); |
---|
1412 | man_sgml('|[Ugr ]|', '\(*U'); |
---|
1413 | man_sgml('|[phgr ]|', '\(*f'); |
---|
1414 | man_sgml('|[PHgr ]|', '\(*F'); |
---|
1415 | man_sgml('|[khgr ]|', '\(*x'); |
---|
1416 | man_sgml('|[KHgr ]|', '\(*X'); |
---|
1417 | man_sgml('|[psgr ]|', '\(*q'); |
---|
1418 | man_sgml('|[PSgr ]|', '\(*Q'); |
---|
1419 | man_sgml('|[ohgr ]|', '\(*w'); |
---|
1420 | man_sgml('|[OHgr ]|', '\(*W'); |
---|
1421 | man_sgml('|[alpha ]|', '\(*a'); |
---|
1422 | man_sgml('|[beta ]|', '\(*b'); |
---|
1423 | man_sgml('|[gamma ]|', '\(*g'); |
---|
1424 | man_sgml('|[Gamma ]|', '\(*G'); |
---|
1425 | man_sgml('|[delta ]|', '\(*d'); |
---|
1426 | man_sgml('|[Delta ]|', '\(*D'); |
---|
1427 | man_sgml('|[epsi ]|', '\(*e'); |
---|
1428 | man_sgml('|[epsis ]|', '\(*e'); |
---|
1429 | man_sgml('|[zeta ]|', '\(*z'); |
---|
1430 | man_sgml('|[eta ]|', '\(*y'); |
---|
1431 | man_sgml('|[thetas]|', '\(*h'); |
---|
1432 | man_sgml('|[Theta ]|', '\(*H'); |
---|
1433 | man_sgml('|[iota ]|', '\(*i'); |
---|
1434 | man_sgml('|[kappa ]|', '\(*k'); |
---|
1435 | man_sgml('|[lambda]|', '\(*l'); |
---|
1436 | man_sgml('|[Lambda]|', '\(*L'); |
---|
1437 | man_sgml('|[mu ]|', '\(*m'); |
---|
1438 | man_sgml('|[nu ]|', '\(*n'); |
---|
1439 | man_sgml('|[xi ]|', '\(*c'); |
---|
1440 | man_sgml('|[Xi ]|', '\(*C'); |
---|
1441 | man_sgml('|[pi ]|', '\(*p'); |
---|
1442 | man_sgml('|[Pi ]|', '\(*P'); |
---|
1443 | man_sgml('|[rho ]|', '\(*r'); |
---|
1444 | man_sgml('|[sigma ]|', '\(*s'); |
---|
1445 | man_sgml('|[Sigma ]|', '\(*S'); |
---|
1446 | man_sgml('|[tau ]|', '\(*t'); |
---|
1447 | man_sgml('|[upsi ]|', '\(*u'); |
---|
1448 | man_sgml('|[Upsi ]|', '\(*U'); |
---|
1449 | man_sgml('|[phis ]|', '\(*f'); |
---|
1450 | man_sgml('|[Phi ]|', '\(*F'); |
---|
1451 | man_sgml('|[chi ]|', '\(*x'); |
---|
1452 | man_sgml('|[psi ]|', '\(*q'); |
---|
1453 | man_sgml('|[Psi ]|', '\(*X'); |
---|
1454 | man_sgml('|[omega ]|', '\(*w'); |
---|
1455 | man_sgml('|[Omega ]|', '\(*W'); |
---|
1456 | man_sgml('|[ap ]|', '\(ap'); |
---|
1457 | man_sgml('|[equiv ]|', '\(=='); |
---|
1458 | man_sgml('|[ge ]|', '\(>='); |
---|
1459 | man_sgml('|[infin ]|', '\(if'); |
---|
1460 | man_sgml('|[isin ]|', '\(sb'); |
---|
1461 | man_sgml('|[le ]|', '\(<='); |
---|
1462 | man_sgml('|[minus ]|', '\(mi'); |
---|
1463 | man_sgml('|[ne ]|', '\(!='); |
---|
1464 | man_sgml('|[prop ]|', '\(pt'); |
---|
1465 | man_sgml('|[square]|', '\(sq'); |
---|
1466 | man_sgml('|[sub ]|', '\(sb'); |
---|
1467 | man_sgml('|[sube ]|', '\(ib'); |
---|
1468 | man_sgml('|[sup ]|', '\(sp'); |
---|
1469 | man_sgml('|[supe ]|', '\(ip'); |
---|
1470 | man_sgml('|[acute ]|', '\&\''); |
---|
1471 | man_sgml('|[breve ]|', '\(be'); |
---|
1472 | man_sgml('|[caron ]|', '\(hc'); |
---|
1473 | man_sgml('|[cedil ]|', '\(cd'); |
---|
1474 | man_sgml('|[dot ]|', '\(dt'); |
---|
1475 | man_sgml('|[macr ]|', '\(ma'); |
---|
1476 | man_sgml('|[ogon ]|', '\(og'); |
---|
1477 | man_sgml('|[ring ]|', '\(ri'); |
---|
1478 | man_sgml('|[uml ]|', '\(..'); |
---|
1479 | |
---|
1480 | sgml('sdata',sub { |
---|
1481 | my ($element, $event) = @_; |
---|
1482 | my ($file, $line) = ($event->file, $event->line); |
---|
1483 | man_output "|[", $_[0], "]|"; |
---|
1484 | warn "Warning: unrecognized SDATA '$_[0]'" |
---|
1485 | . ($file && $line ? " in $file on line $line" : "") |
---|
1486 | . ": please add definition to docbook2man-spec.pl\n"; |
---|
1487 | }); |
---|
1488 | |
---|
1489 | # |
---|
1490 | # Default handlers (uncomment these if needed). Right now, these are set |
---|
1491 | # up to gag on any unrecognised elements, sdata, processing-instructions, |
---|
1492 | # or entities. |
---|
1493 | # |
---|
1494 | # sgml('start_element',sub { die "Unknown element: " . $_[0]->name; }); |
---|
1495 | # sgml('end_element',''); |
---|
1496 | |
---|
1497 | # This is for weeding out and escaping certain characters. |
---|
1498 | # This looks like it's inefficient since it's done on every line, but |
---|
1499 | # in reality, SGMLSpm and sgmlspl parsing ESIS takes _much_ longer. |
---|
1500 | |
---|
1501 | sgml('cdata', sub |
---|
1502 | { |
---|
1503 | if(!$write_manpages) { return; } |
---|
1504 | elsif($raw_cdata) { output $_[0]; return; } |
---|
1505 | |
---|
1506 | if($separator eq 'full') { |
---|
1507 | output "\n" unless $newline_last++; |
---|
1508 | output ".PP\n"; |
---|
1509 | $separator = ''; |
---|
1510 | } |
---|
1511 | |
---|
1512 | # Escape backslashes |
---|
1513 | $_[0] =~ s/\\/\\\\/g; |
---|
1514 | |
---|
1515 | # Escape dots and single quotes in column 1 |
---|
1516 | $_[0] =~ s/^[ \t]*\./\\\&\./; |
---|
1517 | $_[0] =~ s/^[ \t]*\'/\\\&\'/; |
---|
1518 | |
---|
1519 | |
---|
1520 | # In non-'pre'-type elements: |
---|
1521 | if(!$nocollapse_whitespace) { |
---|
1522 | # Change tabs to spaces |
---|
1523 | $_[0] =~ tr/\t / /s; |
---|
1524 | |
---|
1525 | # Do not allow indents at beginning of line |
---|
1526 | # groff chokes on that. |
---|
1527 | if($newline_last) { |
---|
1528 | $_[0] =~ s/^ //; |
---|
1529 | |
---|
1530 | # If the line is all blank, don't do anything. |
---|
1531 | if($_[0] eq '') { return; } |
---|
1532 | |
---|
1533 | $_[0] =~ s/^\./\\\&\./; |
---|
1534 | |
---|
1535 | # Argh... roff doesn't like ' for some unknown reason |
---|
1536 | $_[0] =~ s/^\'/\\\&\'/; |
---|
1537 | } |
---|
1538 | } |
---|
1539 | |
---|
1540 | $newline_last = 0; |
---|
1541 | |
---|
1542 | output $_[0]; |
---|
1543 | }); |
---|
1544 | |
---|
1545 | |
---|
1546 | # When in whitespace-collapsing mode, we disallow consecutive newlines. |
---|
1547 | |
---|
1548 | sgml('re', sub |
---|
1549 | { |
---|
1550 | if($nocollapse_whitespace || !$newline_last) { |
---|
1551 | output "\n"; |
---|
1552 | } |
---|
1553 | |
---|
1554 | $newline_last = 1; |
---|
1555 | }); |
---|
1556 | |
---|
1557 | sgml('pi', sub {}); |
---|
1558 | sgml('entity',sub { die "Unknown external entity: " . $_[0]->name; }); |
---|
1559 | sgml('start_subdoc',sub { die "Unknown subdoc entity: " . $_[0]->name; }); |
---|
1560 | sgml('end_subdoc',sub{}); |
---|
1561 | sgml('conforming',sub{}); |
---|
1562 | |
---|
1563 | 1; |
---|
1564 | |
---|