Blame helpers/docbook2man-spec.pl

Packit 7a7948
=head1 NAME
Packit 7a7948
Packit 7a7948
docbook2man-spec - convert DocBook RefEntries to Unix manpages
Packit 7a7948
Packit 7a7948
=head1 SYNOPSIS
Packit 7a7948
Packit 7a7948
The SGMLSpm package from CPAN.  This contains the sgmlspl script which
Packit 7a7948
is used to grok this file.  Use it like this:
Packit 7a7948
Packit 7a7948
nsgmls some-docbook-document.sgml | sgmlspl docbook2man-spec.pl
Packit 7a7948
Packit 7a7948
=head1 DESCRIPTION
Packit 7a7948
Packit 7a7948
This is a sgmlspl spec file that produces Unix-style
Packit 7a7948
manpages from RefEntry markup.
Packit 7a7948
Packit 7a7948
See the accompanying RefEntry man page for 'plain new' documentation. :)
Packit 7a7948
Packit 7a7948
=head1 LIMITATIONS
Packit 7a7948
Packit 7a7948
Trying docbook2man on non-DocBook or non-conformant SGML results in
Packit 7a7948
undefined behavior. :-)
Packit 7a7948
Packit 7a7948
This program is a slow, dodgy Perl script.
Packit 7a7948
Packit 7a7948
This program does not come close to supporting all the possible markup
Packit 7a7948
in DocBook, and will produce wrong output in some cases with supported
Packit 7a7948
markup.
Packit 7a7948
Packit 7a7948
=head1 TODO
Packit 7a7948
Packit 7a7948
Add new element handling and fix existing handling.  Be robust.
Packit 7a7948
Produce cleanest, readable man output as possible (unlike some
Packit 7a7948
other converters).  Follow Linux man(7) convention.
Packit 7a7948
If this results in added logic in this script,
Packit 7a7948
that's okay.  The code should still be reasonably organized.
Packit 7a7948
Packit 7a7948
Make it faster.  If Perl sucks port it to another language.
Packit 7a7948
Packit 7a7948
=head1 COPYRIGHT
Packit 7a7948
Packit 7a7948
Copyright (C) 1998-1999 Steve Cheng <steve@ggi-project.org>
Packit 7a7948
Packit 7a7948
This program is free software; you can redistribute it and/or modify it
Packit 7a7948
under the terms of the GNU General Public License as published by the Free
Packit 7a7948
Software Foundation; either version 2, or (at your option) any later
Packit 7a7948
version.
Packit 7a7948
Packit 7a7948
You should have received a copy of the GNU General Public License along with
Packit 7a7948
this program; see the file COPYING.  If not, please write to the Free
Packit 7a7948
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
Packit 7a7948
Packit 7a7948
=cut
Packit 7a7948
Packit 7a7948
# $Id: docbook2man-spec.pl,v 1.10 2003/06/10 08:30:30 twaugh Exp $
Packit 7a7948
Packit 7a7948
use SGMLS;			# Use the SGMLS package.
Packit 7a7948
use SGMLS::Output;		# Use stack-based output.
Packit 7a7948
use SGMLS::Refs;
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
# SGMLSPL script produced automatically by the script sgmlspl.pl
Packit 7a7948
#
Packit 7a7948
# Document Type: any, but processes only RefEntries
Packit 7a7948
# Edited by: me :)
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
$write_manpages = 0;
Packit 7a7948
$blank_xrefs = 0;
Packit 7a7948
Packit 7a7948
sgml('start', sub { 
Packit 7a7948
	push_output('nul');
Packit 7a7948
	$raw_cdata = 1;			# Makes it a bit faster.
Packit 7a7948
	
Packit 7a7948
	# Links file
Packit 7a7948
	open(LINKSFILE, ">manpage.links");
Packit 7a7948
Packit 7a7948
	$Refs = new SGMLS::Refs("manpage.refs");
Packit 7a7948
});
Packit 7a7948
sgml('end', sub {
Packit 7a7948
	close(LINKSFILE);
Packit 7a7948
	if($blank_xrefs) {
Packit 7a7948
		print STDERR "Warning: output contains unresolved XRefs\n";
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Output helpers 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
# Our own version of sgml() and output() to allow simple string output
Packit 7a7948
# to play well with roff's stupid whitespace rules. 
Packit 7a7948
Packit 7a7948
sub man_sgml
Packit 7a7948
{
Packit 7a7948
	if(ref($_[1]) eq 'CODE') {
Packit 7a7948
		return &sgml;
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	my $s = $_[1];
Packit 7a7948
Packit 7a7948
	$s =~ s/\\/\\\\/g;
Packit 7a7948
	$s =~ s/'/\\'/g;
Packit 7a7948
Packit 7a7948
	# \n at the beginning means start at beginning of line
Packit 7a7948
	if($s =~ s/^\n//) {
Packit 7a7948
		$sub = 'sub { output "\n" unless $newline_last++; ';
Packit 7a7948
		if($s eq '') { 
Packit 7a7948
			sgml($_[0], eval('sub { output "\n" unless $newline_last++; }'));
Packit 7a7948
		} elsif($s =~ /\n$/) {
Packit 7a7948
			sgml($_[0], eval("sub { output \"\\n\" unless \$newline_last++; output '$s'; }"));
Packit 7a7948
		} else {
Packit 7a7948
			sgml($_[0], eval("sub { output \"\\n\" unless \$newline_last; output '$s'; \$newline_last = 0; }"));
Packit 7a7948
		}
Packit 7a7948
	} else {
Packit 7a7948
		if($s =~ /\n$/) {
Packit 7a7948
			sgml($_[0], eval("sub { output '$s'; \$newline_last = 1; }"));
Packit 7a7948
		} else {
Packit 7a7948
			sgml($_[0], eval("sub { output '$s'; \$newline_last = 0; }"));
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sub man_output
Packit 7a7948
{
Packit 7a7948
	$_ = shift;
Packit 7a7948
	if(s/^\n//) {
Packit 7a7948
		output "\n" unless $newline_last++;
Packit 7a7948
	}
Packit 7a7948
	return if $_ eq '';
Packit 7a7948
	
Packit 7a7948
	output $_;
Packit 7a7948
Packit 7a7948
	if(@_) {
Packit 7a7948
		output @_;
Packit 7a7948
		$newline_last = (pop(@_) =~ /\n$/);
Packit 7a7948
	} else {
Packit 7a7948
		$newline_last = ($_ =~ /\n$/)
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
# Fold lines into one, quote some characters
Packit 7a7948
sub fold_string
Packit 7a7948
{
Packit 7a7948
	$_ = shift;
Packit 7a7948
	
Packit 7a7948
	s/\\/\\\\/g;
Packit 7a7948
	s/"/\\\&"/g;
Packit 7a7948
Packit 7a7948
	# Change tabs to spaces
Packit 7a7948
	tr/\t\n/  /;
Packit 7a7948
Packit 7a7948
	# Trim whitespace from beginning and end.
Packit 7a7948
	s/^ +//;
Packit 7a7948
	s/ +$//;
Packit 7a7948
Packit 7a7948
	return $_;
Packit 7a7948
}
Packit 7a7948
	
Packit 7a7948
sub save_cdata()
Packit 7a7948
{
Packit 7a7948
	$raw_cdata++;
Packit 7a7948
	push_output('string');
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sub bold_on()
Packit 7a7948
{
Packit 7a7948
	# If the last font is also bold, don't change anything.
Packit 7a7948
	# Basically this is to just get more readable man output.
Packit 7a7948
	if($fontstack[$#fontstack] ne 'bold') {
Packit 7a7948
		if(!$raw_cdata) {
Packit 7a7948
			output '\fB';
Packit 7a7948
			$newline_last = 0;
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
	push(@fontstack, 'bold');
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sub italic_on()
Packit 7a7948
{
Packit 7a7948
	# If the last font is also italic, don't change anything.
Packit 7a7948
	if($fontstack[$#fontstack] ne 'italic') {
Packit 7a7948
		if(!$raw_cdata) {
Packit 7a7948
			output '\fI';
Packit 7a7948
			$newline_last = 0;
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
	push(@fontstack, 'italic');
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sub font_off()
Packit 7a7948
{
Packit 7a7948
	my $thisfont = pop(@fontstack);
Packit 7a7948
	my $lastfont = $fontstack[$#fontstack];
Packit 7a7948
	
Packit 7a7948
	# Only output font change if it is different
Packit 7a7948
	if($thisfont ne $lastfont) {
Packit 7a7948
		if($raw_cdata)			{ return; }
Packit 7a7948
		elsif($lastfont eq 'bold') 	{ output '\fB'; }
Packit 7a7948
		elsif($lastfont eq 'italic')	{ output '\fI'; }
Packit 7a7948
		else				{ output '\fR'; }
Packit 7a7948
	
Packit 7a7948
		$newline_last = 0;
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Manpage management
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
sgml('<REFENTRY>', sub { 
Packit 7a7948
	# This will be overwritten at end of REFMETA, when we know the name of the page.
Packit 7a7948
	pop_output();
Packit 7a7948
	
Packit 7a7948
	$write_manpages = 1;		# Currently writing manpage.
Packit 7a7948
	
Packit 7a7948
	$nocollapse_whitespace = 0;	# Current whitespace collapse counter.
Packit 7a7948
	$newline_last = 1;		# At beginning of line?
Packit 7a7948
		# Just a bit of warning, you will see this variable manipulated
Packit 7a7948
		# manually a lot.  It makes the code harder to follow but it
Packit 7a7948
		# saves you from having to worry about collapsing at the end of
Packit 7a7948
		# parse, stopping at verbatims, etc.
Packit 7a7948
	$raw_cdata = 0;                 # Instructs certain output functions to
Packit 7a7948
					# leave CDATA alone, so we can assign
Packit 7a7948
					# it to a string and process it, etc.
Packit 7a7948
	@fontstack = ();		# Fonts being activated.
Packit 7a7948
	
Packit 7a7948
	$manpage_title = '';		# Needed for indexing.
Packit 7a7948
	$manpage_sect = '';
Packit 7a7948
	@manpage_names = ();
Packit 7a7948
	
Packit 7a7948
	$manpage_misc = '';
Packit 7a7948
	
Packit 7a7948
	$list_nestlevel = 0;		# Indent certain nested content.
Packit 7a7948
Packit 7a7948
	# check refentry's language
Packit 7a7948
	if(defined($_[0]->attribute('LANG')->value)) {
Packit 7a7948
	  $manpage_lang = $_[0]->attribute('LANG')->value;
Packit 7a7948
	}
Packit 7a7948
	else {
Packit 7a7948
	  $manpage_lang = '';
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
sgml('</REFENTRY>', sub {
Packit 7a7948
	if(!$newline_last) {
Packit 7a7948
		output "\n";
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	$write_manpages = 0;
Packit 7a7948
	$raw_cdata = 1;
Packit 7a7948
	push_output('nul');
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('</REFMETA>', sub {
Packit 7a7948
	if ($manpage_lang) {
Packit 7a7948
		push_output('file', "$manpage_title.$manpage_lang.$manpage_sect");
Packit 7a7948
	} else {
Packit 7a7948
		push_output('file', "$manpage_title.$manpage_sect");
Packit 7a7948
	}
Packit 7a7948
Packit 7a7948
	output <<_END_BANNER;
Packit 7a7948
.\\" This manpage has been automatically generated by docbook2man 
Packit 7a7948
.\\" from a DocBook document.  This tool can be found at:
Packit 7a7948
.\\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> 
Packit 7a7948
.\\" Please send any bug reports, improvements, comments, patches, 
Packit 7a7948
.\\" etc. to Steve Cheng <steve\@ggi-project.org>.
Packit 7a7948
_END_BANNER
Packit 7a7948
Packit 7a7948
	my $manpage_date = `date "+%d %B %Y"`;
Packit 7a7948
		
Packit 7a7948
	output '.TH "';
Packit 7a7948
	
Packit 7a7948
	# If the title is not mixed-case, convention says to
Packit 7a7948
	# uppercase the whole title.  (The canonical title is
Packit 7a7948
	# lowercase.)
Packit 7a7948
	if($manpage_title =~ /[A-Z]/) {
Packit 7a7948
		output fold_string($manpage_title);
Packit 7a7948
	} else {
Packit 7a7948
		output uc(fold_string($manpage_title));
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	output  '" "', fold_string($manpage_sect), 
Packit 7a7948
		'" "', fold_string(`date "+%d %B %Y"`), 
Packit 7a7948
		'" "', $manpage_misc, 
Packit 7a7948
		'" "', $manpage_manual, 
Packit 7a7948
		"\"\n";
Packit 7a7948
Packit 7a7948
	$newline_last = 1;
Packit 7a7948
Packit 7a7948
	# References to this RefEntry.
Packit 7a7948
	my $id = $_[0]->parent->attribute('ID')->value;
Packit 7a7948
	if($id ne '') {
Packit 7a7948
		# The 'package name' part of the section should
Packit 7a7948
		# not be used when citing it.
Packit 7a7948
		my ($sectnum) = ($manpage_sect =~ /([0-9]*)/);
Packit 7a7948
		
Packit 7a7948
		if($_[0]->parent->attribute('XREFLABEL')->value eq '') {
Packit 7a7948
			$Refs->put("refentry:$id", "$manpage_title($sectnum)");
Packit 7a7948
		} else {
Packit 7a7948
			$Refs->put("refentry:$id",
Packit 7a7948
				$_[0]->parent->attribute('XREFLABEL')->value . 
Packit 7a7948
				"($sectnum)");
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<REFENTRYTITLE>', sub { 
Packit 7a7948
	if($_[0]->in('REFMETA')) { 
Packit 7a7948
		save_cdata();
Packit 7a7948
	} else { 
Packit 7a7948
		# Manpage citations are in bold.
Packit 7a7948
		bold_on();
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
sgml('</REFENTRYTITLE>', sub { 
Packit 7a7948
	if($_[0]->in('REFMETA')) {
Packit 7a7948
		$raw_cdata--;
Packit 7a7948
		$manpage_title = pop_output();
Packit 7a7948
	}
Packit 7a7948
	else { font_off(); }
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<MANVOLNUM>', sub { 
Packit 7a7948
	if($_[0]->in('REFMETA')) { 
Packit 7a7948
		save_cdata();	
Packit 7a7948
	} else {
Packit 7a7948
		# Manpage citations use ().
Packit 7a7948
		output '(';
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
sgml('</MANVOLNUM>', sub { 
Packit 7a7948
	if($_[0]->in('REFMETA')) {
Packit 7a7948
		$raw_cdata--;
Packit 7a7948
		$manpage_sect = pop_output();
Packit 7a7948
	}
Packit 7a7948
	else { output ')' }
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<REFMISCINFO>', \&save_cdata);
Packit 7a7948
sgml('</REFMISCINFO>', sub { 
Packit 7a7948
	$raw_cdata--;
Packit 7a7948
	$manpage_misc = fold_string(pop_output());
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
Packit 7a7948
# NAME section
Packit 7a7948
man_sgml('<REFNAMEDIV>', sub {
Packit 7a7948
	my %words = qw( fr NOM es NOMBRE de NAME );
Packit 7a7948
	if (defined($_[0]->attribute('LANG')->value)) {
Packit 7a7948
	my $id = $_[0]->attribute('LANG')->value;
Packit 7a7948
	my $ad = $words{$id};
Packit 7a7948
	output("\n.SH $ad\n");}
Packit 7a7948
	else {output("\n.SH NAME\n");}
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<REFNAME>', \&save_cdata);
Packit 7a7948
sgml('</REFNAME>', sub { 
Packit 7a7948
	$raw_cdata--;
Packit 7a7948
	push(@manpage_names, pop_output());
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<REFPURPOSE>', \&save_cdata);
Packit 7a7948
sgml('</REFPURPOSE>', sub { 
Packit 7a7948
	$raw_cdata--;
Packit 7a7948
	my $manpage_purpose = fold_string(pop_output());
Packit 7a7948
	
Packit 7a7948
	for(my $i = 0; $i < $#manpage_names; $i++) {
Packit 7a7948
		output fold_string($manpage_names[$i]), ', ';
Packit 7a7948
	}
Packit 7a7948
Packit 7a7948
	output fold_string($manpage_names[$#manpage_names]);
Packit 7a7948
	output " \\- $manpage_purpose\n";
Packit 7a7948
Packit 7a7948
	$newline_last = 1;
Packit 7a7948
Packit 7a7948
	foreach(@manpage_names) {
Packit 7a7948
		# Don't link to itself
Packit 7a7948
		if($_ ne $manpage_title) {
Packit 7a7948
			print LINKSFILE "$manpage_title.$manpage_sect	$_.$manpage_sect\n";
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
	
Packit 7a7948
man_sgml('<REFCLASS>', "\n.sp\n");
Packit 7a7948
Packit 7a7948
#RefDescriptor
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# SYNOPSIS section and synopses
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
man_sgml('<REFSYNOPSISDIV>', "\n.SH SYNOPSIS\n");
Packit 7a7948
man_sgml('</REFSYNOPSISDIV>', "\n");
Packit 7a7948
Packit 7a7948
## FIXME! Must be made into block elements!!
Packit 7a7948
#sgml('<FUNCSYNOPSIS>', \&bold_on);
Packit 7a7948
#sgml('</FUNCSYNOPSIS>', \&font_off);
Packit 7a7948
#sgml('<CMDSYNOPSIS>', \&bold_on);
Packit 7a7948
#sgml('</CMDSYNOPSIS>', \&font_off);
Packit 7a7948
Packit 7a7948
man_sgml('<FUNCSYNOPSIS>', sub {
Packit 7a7948
	man_output("\n.sp\n");
Packit 7a7948
	bold_on();
Packit 7a7948
});
Packit 7a7948
man_sgml('</FUNCSYNOPSIS>', sub {
Packit 7a7948
	font_off();
Packit 7a7948
	man_output("\n");
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
man_sgml('<CMDSYNOPSIS>', "\n\n");
Packit 7a7948
man_sgml('</CMDSYNOPSIS>', "\n\n");
Packit 7a7948
Packit 7a7948
man_sgml('<FUNCPROTOTYPE>', "\n.sp\n");
Packit 7a7948
Packit 7a7948
# Arguments to functions.  This is C convention.
Packit 7a7948
sub paramdef
Packit 7a7948
{
Packit 7a7948
	if($_[0]->parent->ext->{'inparams'}) {
Packit 7a7948
		output ', ';
Packit 7a7948
	} else {
Packit 7a7948
		output ' (';
Packit 7a7948
		$_[0]->parent->ext->{'inparams'} = 1;
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
man_sgml('<PARAMDEF>', \&paramdef);
Packit 7a7948
man_sgml('</FUNCPROTOTYPE>', ");\n");
Packit 7a7948
man_sgml('<VOID>', "(void");
Packit 7a7948
man_sgml('<VARARGS>', "(...");
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
sub group_start
Packit 7a7948
{
Packit 7a7948
	if(not $_[0]->parent->in('TERM')) {
Packit 7a7948
		if($_[0]->attribute('CHOICE')->value =~ /opt/i) {
Packit 7a7948
			output ' [';
Packit 7a7948
		} elsif($_[0]->attribute('CHOICE')->value =~ /req/i) {
Packit 7a7948
			output ' {';
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
	$_[0]->ext->{'count'} = 1;
Packit 7a7948
}
Packit 7a7948
sub group_end
Packit 7a7948
{
Packit 7a7948
	if($_[0]->attribute('REP')->value =~ /^Repeat/i) {
Packit 7a7948
		italic_on();
Packit 7a7948
		output ' ...';
Packit 7a7948
		font_off();
Packit 7a7948
	}
Packit 7a7948
	if(not $_[0]->parent->in('TERM')) {
Packit 7a7948
		if($_[0]->attribute('CHOICE')->value =~ /opt/i) {
Packit 7a7948
			output ' ]';
Packit 7a7948
		} elsif($_[0]->attribute('CHOICE')->value =~ /req/i) {
Packit 7a7948
			output ' }';
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sub arg_start
Packit 7a7948
{
Packit 7a7948
	# my $choice = $_[0]->attribute('CHOICE')->value;
Packit 7a7948
Packit 7a7948
	# The content model for CmdSynopsis doesn't include #PCDATA,
Packit 7a7948
	# so we won't see any of the whitespace in the source file,
Packit 7a7948
	# so we have to add it after each component.
Packit 7a7948
	output ' ';
Packit 7a7948
Packit 7a7948
	if($_[0]->in('GROUP')) {
Packit 7a7948
		output '| ' if $_[0]->parent->ext->{'count'} > 1;
Packit 7a7948
		$_[0]->parent->ext->{'count'}++;
Packit 7a7948
	} elsif($_[0]->attribute('CHOICE')->value =~ /opt/i) {
Packit 7a7948
		output '[ ';
Packit 7a7948
	}
Packit 7a7948
	bold_on();
Packit 7a7948
}
Packit 7a7948
sub arg_end
Packit 7a7948
{
Packit 7a7948
	font_off();
Packit 7a7948
	if($_[0]->attribute('REP')->value =~ /^Repeat/i) {
Packit 7a7948
		italic_on();
Packit 7a7948
		output ' ...';
Packit 7a7948
		font_off();
Packit 7a7948
	}
Packit 7a7948
	if($_[0]->attribute('CHOICE')->value =~ /opt/i and
Packit 7a7948
           not $_[0]->in('GROUP')) {
Packit 7a7948
		output ' ]';
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sgml('<ARG>', \&arg_start);
Packit 7a7948
sgml('</ARG>', \&arg_end);
Packit 7a7948
sgml('<GROUP>', \&group_start);
Packit 7a7948
sgml('</GROUP>', \&group_end);
Packit 7a7948
Packit 7a7948
sgml('<OPTION>', \&bold_on);
Packit 7a7948
sgml('</OPTION>', \&font_off);
Packit 7a7948
Packit 7a7948
man_sgml('<SBR>', "\n   ");
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# General sections
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
# The name of the section is handled by TITLE.  This just sets
Packit 7a7948
# up the roff markup.
Packit 7a7948
man_sgml('<REFSECT1>', "\n.SH ");
Packit 7a7948
man_sgml('<REFSECT2>', "\n.SS ");
Packit 7a7948
man_sgml('<REFSECT3>', "\n.SS ");
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Titles, metadata.
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
sgml('<TITLE>', sub {
Packit 7a7948
	if($_[0]->in('REFERENCE') or $_[0]->in('BOOK')) {
Packit 7a7948
		$write_manpages = 1;
Packit 7a7948
	}
Packit 7a7948
	save_cdata();
Packit 7a7948
});
Packit 7a7948
sgml('</TITLE>', sub { 
Packit 7a7948
	my $title = fold_string(pop_output());
Packit 7a7948
	$raw_cdata--;
Packit 7a7948
	
Packit 7a7948
	if($_[0]->in('REFERENCE') or $_[0]->in('BOOK')) {
Packit 7a7948
		# We use TITLE of enclosing Reference or Book as manual name
Packit 7a7948
		$manpage_manual = $title;
Packit 7a7948
		$write_manpages = 0;
Packit 7a7948
	}
Packit 7a7948
	elsif(exists $_[0]->parent->ext->{'title'}) {
Packit 7a7948
		# By far the easiest case.  Just fold the string as
Packit 7a7948
		# above, and then set the parent element's variable.
Packit 7a7948
		$_[0]->parent->ext->{'title'} = $title;
Packit 7a7948
	}
Packit 7a7948
	else {
Packit 7a7948
		# If the parent element's handlers are lazy, 
Packit 7a7948
		# output the folded string for them :)
Packit 7a7948
		# We assume they want uppercase and a newline.
Packit 7a7948
		output '"', uc($title), "\"\n";
Packit 7a7948
		$newline_last = 1;
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<ATTRIBUTION>', sub { push_output('string') });
Packit 7a7948
sgml('</ATTRIBUTION>', sub { $_[0]->parent->ext->{'attribution'} = pop_output(); });
Packit 7a7948
Packit 7a7948
Packit 7a7948
# IGNORE.
Packit 7a7948
sgml('<DOCINFO>', sub { push_output('nul'); });
Packit 7a7948
sgml('</DOCINFO>', sub { pop_output(); });
Packit 7a7948
sgml('<REFSECT1INFO>', sub { push_output('nul'); });
Packit 7a7948
sgml('</REFSECT1INFO>', sub { pop_output(); });
Packit 7a7948
sgml('<REFSECT2INFO>', sub { push_output('nul'); });
Packit 7a7948
sgml('</REFSECT2INFO>', sub { pop_output(); });
Packit 7a7948
sgml('<REFSECT3INFO>', sub { push_output('nul'); });
Packit 7a7948
sgml('</REFSECT3INFO>', sub { pop_output(); });
Packit 7a7948
Packit 7a7948
sgml('<INDEXTERM>', sub { push_output('nul'); });
Packit 7a7948
sgml('</INDEXTERM>', sub { pop_output(); });
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Set bold on enclosed content 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
sgml('<APPLICATION>', \&bold_on);	sgml('</APPLICATION>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<CLASSNAME>', \&bold_on);		sgml('</CLASSNAME>', \&font_off);
Packit 7a7948
sgml('<STRUCTNANE>', \&bold_on);	sgml('</STRUCTNAME>', \&font_off);
Packit 7a7948
sgml('<STRUCTFIELD>', \&bold_on);	sgml('</STRUCTFIELD>', \&font_off);
Packit 7a7948
sgml('<SYMBOL>', \&bold_on);		sgml('</SYMBOL>', \&font_off);
Packit 7a7948
sgml('<TYPE>', \&bold_on);		sgml('</TYPE>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<ENVAR>', \&bold_on);	sgml('</ENVAR>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<FUNCTION>', \&bold_on);	sgml('</FUNCTION>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<EMPHASIS>', \&bold_on);	sgml('</EMPHASIS>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<ERRORNAME>', \&bold_on);	sgml('</ERRORNAME>', \&font_off);
Packit 7a7948
# ERRORTYPE
Packit 7a7948
Packit 7a7948
sgml('<COMMAND>', \&bold_on);	sgml('</COMMAND>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<GUIBUTTON>', \&bold_on);	sgml('</GUIBUTTON>', \&font_off);
Packit 7a7948
sgml('<GUIICON>', \&bold_on);	sgml('</GUIICON>', \&font_off);
Packit 7a7948
# GUILABEL
Packit 7a7948
# GUIMENU
Packit 7a7948
# GUIMENUITEM
Packit 7a7948
# GUISUBMENU
Packit 7a7948
# MENUCHOICE
Packit 7a7948
# MOUSEBUTTON
Packit 7a7948
Packit 7a7948
sgml('<ACCEL>', \&bold_on);	sgml('</ACCEL>', \&font_off);
Packit 7a7948
sgml('<KEYCAP>', \&bold_on);	sgml('</KEYCAP>', \&font_off);
Packit 7a7948
sgml('<KEYSYM>', \&bold_on);	sgml('</KEYSYM>', \&font_off);
Packit 7a7948
# KEYCODE
Packit 7a7948
# KEYCOMBO
Packit 7a7948
# SHORTCUT
Packit 7a7948
Packit 7a7948
sgml('<USERINPUT>', \&bold_on);	sgml('</USERINPUT>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<INTERFACEDEFINITION>', \&bold_on);
Packit 7a7948
sgml('</INTERFACEDEFINITION>', \&font_off);
Packit 7a7948
Packit 7a7948
# May need to look at the CLASS
Packit 7a7948
sgml('<SYSTEMITEM>', \&bold_on);
Packit 7a7948
sgml('</SYSTEMITEM>', \&font_off);
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Set italic on enclosed content 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
sgml('<FIRSTTERM>', \&italic_on);	sgml('</FIRSTTERM>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<FILENAME>', \&italic_on);	sgml('</FILENAME>', \&font_off);
Packit 7a7948
sgml('<PARAMETER>', \&italic_on);	sgml('</PARAMETER>', \&font_off);
Packit 7a7948
sgml('<PROPERTY>', \&italic_on);	sgml('</PROPERTY>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<REPLACEABLE>', sub {
Packit 7a7948
	italic_on();
Packit 7a7948
	if($_[0]->in('TOKEN')) {
Packit 7a7948
		# When tokenizing, follow more 'intuitive' convention
Packit 7a7948
		output "<";
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
sgml('</REPLACEABLE>', sub {
Packit 7a7948
	if($_[0]->in('TOKEN')) {
Packit 7a7948
		output ">";
Packit 7a7948
	}
Packit 7a7948
	font_off();
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<CITETITLE>', \&italic_on);	sgml('</CITETITLE>', \&font_off);
Packit 7a7948
sgml('<FOREIGNPHRASE>', \&italic_on);	sgml('</FOREIGNPHRASE>', \&font_off);
Packit 7a7948
Packit 7a7948
sgml('<LINEANNOTATION>', \&italic_on);	sgml('</LINEANNOTATION>', \&font_off);
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Other 'inline' elements 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
man_sgml('<EMAIL>', '<');
Packit 7a7948
man_sgml('</EMAIL>', '>');
Packit 7a7948
man_sgml('<OPTIONAL>', '[');
Packit 7a7948
man_sgml('</OPTIONAL>', ']');
Packit 7a7948
Packit 7a7948
man_sgml('</TRADEMARK>', "\\u\\s-2TM\\s+2\\d");
Packit 7a7948
Packit 7a7948
man_sgml('<COMMENT>', "[Comment: ");
Packit 7a7948
man_sgml('</COMMENT>', "]");
Packit 7a7948
Packit 7a7948
man_sgml('<QUOTE>', "``");
Packit 7a7948
man_sgml('</QUOTE>', "''");
Packit 7a7948
Packit 7a7948
#man_sgml('<LITERAL>', '"');
Packit 7a7948
#man_sgml('</LITERAL>', '"');
Packit 7a7948
Packit 7a7948
# No special presentation:
Packit 7a7948
Packit 7a7948
# AUTHOR
Packit 7a7948
# AUTHORINITIALS
Packit 7a7948
Packit 7a7948
# ABBREV
Packit 7a7948
# ACTION
Packit 7a7948
# ACRONYM
Packit 7a7948
# ALT
Packit 7a7948
# CITATION
Packit 7a7948
# PHRASE
Packit 7a7948
# QUOTE
Packit 7a7948
# WORDASWORD
Packit 7a7948
Packit 7a7948
# COMPUTEROUTPUT
Packit 7a7948
# MARKUP
Packit 7a7948
# PROMPT
Packit 7a7948
# RETURNVALUE
Packit 7a7948
# SGMLTAG
Packit 7a7948
# TOKEN
Packit 7a7948
Packit 7a7948
# DATABASE
Packit 7a7948
# HARDWARE
Packit 7a7948
# INTERFACE
Packit 7a7948
# MEDIALABEL
Packit 7a7948
Packit 7a7948
# There doesn't seem to be a good way to represent LITERAL in -man
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Paragraph and paragraph-like elements 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
sub para_start {
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
Packit 7a7948
	# In lists, etc., don't start paragraph with .PP since
Packit 7a7948
	# the indentation will be gone.
Packit 7a7948
Packit 7a7948
	if($_[0]->parent->ext->{'nobreak'}==1) {
Packit 7a7948
		# Usually this is the FIRST element of
Packit 7a7948
		# a hanging tag, so we MUST not do a full
Packit 7a7948
		# paragraph break.
Packit 7a7948
		$_[0]->parent->ext->{'nobreak'} = 2;
Packit 7a7948
	} elsif($_[0]->parent->ext->{'nobreak'}==2) {
Packit 7a7948
		# Usually these are the NEXT elements of
Packit 7a7948
		# a hanging tag.  If we break using a blank
Packit 7a7948
		# line, we're okay.
Packit 7a7948
		output "\n";
Packit 7a7948
	} else {
Packit 7a7948
		# Normal case. (For indented blocks too, at least
Packit 7a7948
		# -man isn't so braindead in this area.)
Packit 7a7948
		output ".PP\n";
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
# Actually applies to a few other block elements as well
Packit 7a7948
sub para_end {
Packit 7a7948
	output "\n" unless $newline_last++; 
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sgml('<PARA>', \&para_start);
Packit 7a7948
sgml('</PARA>', \&para_end);
Packit 7a7948
sgml('<SIMPARA>', \&para_start);
Packit 7a7948
sgml('</SIMPARA>', \&para_end);
Packit 7a7948
Packit 7a7948
# Nothing special, except maybe FIXME set nobreak.
Packit 7a7948
sgml('<INFORMALEXAMPLE>', \&para_start);
Packit 7a7948
sgml('</INFORMALEXAMPLE>', \&para_end);
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Blocks using SS sections
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
# FIXME: We need to consider the effects of SS
Packit 7a7948
# in a hanging tag :(
Packit 7a7948
Packit 7a7948
# Complete with the optional-title dilemma (again).
Packit 7a7948
sgml('<ABSTRACT>', sub {
Packit 7a7948
	$_[0]->ext->{'title'} = 'ABSTRACT';
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</ABSTRACT>', sub {
Packit 7a7948
	my $content = pop_output();
Packit 7a7948
	
Packit 7a7948
	# As ABSTRACT is never on the same level as RefSect1,
Packit 7a7948
	# this leaves us with only .SS in terms of -man macros.
Packit 7a7948
	output ".SS \"", uc($_[0]->ext->{'title'}), "\"\n";
Packit 7a7948
Packit 7a7948
	output $content;
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
# Ah, I needed a break.  Example always has a title.
Packit 7a7948
man_sgml('<EXAMPLE>', "\n.SS ");
Packit 7a7948
sgml('</EXAMPLE>', \&para_end);
Packit 7a7948
Packit 7a7948
# Same with sidebar.
Packit 7a7948
man_sgml('<SIDEBAR>', "\n.SS ");
Packit 7a7948
sgml('</SIDEBAR>', \&para_end);
Packit 7a7948
Packit 7a7948
# NO title.
Packit 7a7948
man_sgml('<HIGHLIGHTS>', "\n.SS HIGHLIGHTS\n");
Packit 7a7948
sgml('</HIGHLIGHTS>', \&para_end);
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Indented 'Block' elements 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
sub indent_block_start
Packit 7a7948
{
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	output ".sp\n.RS\n";
Packit 7a7948
}
Packit 7a7948
sub indent_block_end
Packit 7a7948
{
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	output ".RE\n";
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
# This element is almost like an admonition (below),
Packit 7a7948
# only the default title is blank :)
Packit 7a7948
Packit 7a7948
sgml('
', sub {
Packit 7a7948
	$_[0]->ext->{'title'} = ''; 
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('', sub {
Packit 7a7948
	my $content = pop_output();
Packit 7a7948
Packit 7a7948
	indent_block_start();
Packit 7a7948
	
Packit 7a7948
	if($_[0]->ext->{'title'}) {
Packit 7a7948
		output ".B \"", $_[0]->ext->{'title'}, ":\"\n";
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	output $content;
Packit 7a7948
Packit 7a7948
	if($_[0]->ext->{'attribution'}) {
Packit 7a7948
		output "\n" unless $newline_last++;
Packit 7a7948
		# One place where roff's space-sensitivity makes sense :)
Packit 7a7948
		output "\n                -- ";
Packit 7a7948
		output $_[0]->ext->{'attribution'} . "\n";
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	indent_block_end();
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
# Set off admonitions from the rest of the text by indenting.
Packit 7a7948
# FIXME: Need to check if this works inside paragraphs, not enclosing them.
Packit 7a7948
sub admonition_end {
Packit 7a7948
	my $content = pop_output();
Packit 7a7948
Packit 7a7948
	indent_block_start();
Packit 7a7948
	
Packit 7a7948
	# When the admonition is only one paragraph,
Packit 7a7948
	# it looks nicer if the title was inline.
Packit 7a7948
	my $num_para;
Packit 7a7948
	while ($content =~ /^\.PP/gm) { $num_para++ }
Packit 7a7948
	if($num_para==1) {
Packit 7a7948
		$content =~ s/^\.PP\n//;
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	output ".B \"" . $_[0]->ext->{'title'} . ":\"\n";
Packit 7a7948
	output $content;
Packit 7a7948
	
Packit 7a7948
	indent_block_end();
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sgml('<NOTE>', sub {
Packit 7a7948
	# We can't see right now whether or not there is a TITLE
Packit 7a7948
	# element, so we have to save the output now and add it back
Packit 7a7948
	# at the end of this admonition.
Packit 7a7948
	$_[0]->ext->{'title'} = 'Note';
Packit 7a7948
Packit 7a7948
	# Although admonition_end's indent_block_start will do this,
Packit 7a7948
	# we need to synchronize the output _now_
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</NOTE>', \&admonition_end);
Packit 7a7948
Packit 7a7948
# Same as above.
Packit 7a7948
sgml('<WARNING>', sub { 
Packit 7a7948
	$_[0]->ext->{'title'} = 'Warning'; 
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</WARNING>', \&admonition_end);
Packit 7a7948
Packit 7a7948
sgml('<TIP>', sub {
Packit 7a7948
	$_[0]->ext->{'title'} = 'Tip';
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</TIP>', \&admonition_end);
Packit 7a7948
sgml('<CAUTION>', sub {
Packit 7a7948
	$_[0]->ext->{'title'} = 'Caution';
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</CAUTION>', \&admonition_end);
Packit 7a7948
Packit 7a7948
sgml('<IMPORTANT>', sub {
Packit 7a7948
	$_[0]->ext->{'title'} = 'Important';
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</IMPORTANT>', \&admonition_end);
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Verbatim displays. 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
sub verbatim_start {
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	
Packit 7a7948
	if($_[0]->parent->ext->{'nobreak'}==1) {
Packit 7a7948
		# Usually this is the FIRST element of
Packit 7a7948
		# a hanging tag, so we MUST not do a full
Packit 7a7948
		# paragraph break.
Packit 7a7948
		$_[0]->parent->ext->{'nobreak'} = 2;
Packit 7a7948
	} else {
Packit 7a7948
		output "\n";
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	output(".nf\n") unless $nocollapse_whitespace++;
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sub verbatim_end {
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	output(".fi\n") unless --$nocollapse_whitespace;
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sgml('<PROGRAMLISTING>', \&verbatim_start); 
Packit 7a7948
sgml('</PROGRAMLISTING>', \&verbatim_end);
Packit 7a7948
Packit 7a7948
sgml('<SCREEN>', \&verbatim_start); 
Packit 7a7948
sgml('</SCREEN>', \&verbatim_end);
Packit 7a7948
Packit 7a7948
sgml('<LITERALLAYOUT>', \&verbatim_start); 
Packit 7a7948
sgml('</LITERALLAYOUT>', \&verbatim_end);
Packit 7a7948
Packit 7a7948
#sgml('<SYNOPSIS>', sub {
Packit 7a7948
#	if($_[0]->attribute('FORMAT')->value =~ /linespecific/i) {
Packit 7a7948
#		&verbatim_start;
Packit 7a7948
#	} else {
Packit 7a7948
#		roffcmd("");
Packit 7a7948
#	}
Packit 7a7948
#});
Packit 7a7948
#
Packit 7a7948
#sgml('</SYNOPSIS>', sub {
Packit 7a7948
#	if($_[0]->attribute('FORMAT')->value =~ /linespecific/i) {
Packit 7a7948
#		&verbatim_end;
Packit 7a7948
#	}
Packit 7a7948
#	else {
Packit 7a7948
#		roffcmd("");# not sure about this.
Packit 7a7948
#	}
Packit 7a7948
#});
Packit 7a7948
sgml('<SYNOPSIS>', \&verbatim_start);
Packit 7a7948
sgml('</SYNOPSIS>', \&verbatim_end);
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Lists
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
# Indent nested lists.
Packit 7a7948
sub indent_list_start {
Packit 7a7948
	if($list_nestlevel++) {
Packit 7a7948
		output "\n" unless $newline_last++;
Packit 7a7948
		output ".RS\n";
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
sub indent_list_end {
Packit 7a7948
	if(--$list_nestlevel) {
Packit 7a7948
		output "\n" unless $newline_last++;
Packit 7a7948
		output ".RE\n";
Packit 7a7948
	}
Packit 7a7948
}
Packit 7a7948
Packit 7a7948
sgml('<VARIABLELIST>', \&indent_list_start);
Packit 7a7948
sgml('</VARIABLELIST>', \&indent_list_end);
Packit 7a7948
sgml('<ITEMIZEDLIST>', \&indent_list_start);
Packit 7a7948
sgml('</ITEMIZEDLIST>', \&indent_list_end);
Packit 7a7948
sgml('<ORDEREDLIST>', sub { 
Packit 7a7948
	indent_list_start();
Packit 7a7948
	$_[0]->ext->{'count'} = 1;
Packit 7a7948
});
Packit 7a7948
sgml('</ORDEREDLIST>', \&indent_list_end);
Packit 7a7948
sgml('<GLOSSLIST>', \&indent_list_start);
Packit 7a7948
sgml('</GLOSSLIST>', \&indent_list_end);
Packit 7a7948
		
Packit 7a7948
# Output content on one line, bolded.
Packit 7a7948
sgml('<TERM>', sub { 
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	output ".TP\n";
Packit 7a7948
	bold_on();
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</TERM>', sub { 
Packit 7a7948
	my $term = pop_output();
Packit 7a7948
	$term =~ tr/\n/ /;
Packit 7a7948
	output $term;
Packit 7a7948
	font_off();
Packit 7a7948
	output "\n";
Packit 7a7948
	$newline_last = 1;
Packit 7a7948
});
Packit 7a7948
sgml('<GLOSSTERM>', sub { 
Packit 7a7948
	output "\n" unless $newline_last++;
Packit 7a7948
	output ".TP\n";
Packit 7a7948
	bold_on();
Packit 7a7948
	push_output('string');
Packit 7a7948
});
Packit 7a7948
sgml('</GLOSSTERM>', sub { 
Packit 7a7948
	my $term = pop_output();
Packit 7a7948
	$term =~ tr/\n/ /;
Packit 7a7948
	output $term;
Packit 7a7948
	font_off();
Packit 7a7948
	output "\n";
Packit 7a7948
	$newline_last = 1;
Packit 7a7948
});
Packit 7a7948
	
Packit 7a7948
sgml('<LISTITEM>', sub {
Packit 7a7948
	# A bulleted list.
Packit 7a7948
	if($_[0]->in('ITEMIZEDLIST')) {
Packit 7a7948
		output "\n" unless $newline_last++;
Packit 7a7948
		output ".TP 0.2i\n\\(bu\n";
Packit 7a7948
	}
Packit 7a7948
Packit 7a7948
	# Need numbers.
Packit 7a7948
	# Assume Arabic numeration for now.
Packit 7a7948
	elsif($_[0]->in('ORDEREDLIST')) {
Packit 7a7948
		output "\n" unless $newline_last++;
Packit 7a7948
		output ".TP 3\n", $_[0]->parent->ext->{'count'}++, ". \n";
Packit 7a7948
	}
Packit 7a7948
	
Packit 7a7948
	$_[0]->ext->{'nobreak'} = 1;
Packit 7a7948
});
Packit 7a7948
sgml('<GLOSSDEF>', sub {
Packit 7a7948
	$_[0]->ext->{'nobreak'} = 1;
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<SIMPLELIST>', sub {
Packit 7a7948
	$_[0]->ext->{'first_member'} = 1;
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('<MEMBER>', sub {
Packit 7a7948
	my $parent = $_[0]->parent;
Packit 7a7948
	
Packit 7a7948
	if($parent->attribute('TYPE')->value =~ /Inline/i) {
Packit 7a7948
		if($parent->ext->{'first_member'}) { 
Packit 7a7948
			# If this is the first member don't put any commas
Packit 7a7948
			$parent->ext->{'first_member'} = 0;
Packit 7a7948
		} else {
Packit 7a7948
			output ", ";
Packit 7a7948
		}
Packit 7a7948
	} elsif($parent->attribute('TYPE')->value =~ /Vert/i) {
Packit 7a7948
		output "\n" unless $newline_last++;
Packit 7a7948
		output "\n";
Packit 7a7948
	}
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Stuff we don't know how to handle (yet) 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
# Address blocks:
Packit 7a7948
Packit 7a7948
# Credit stuff:
Packit 7a7948
# ACKNO
Packit 7a7948
# ADDRESS
Packit 7a7948
# AFFILIATION
Packit 7a7948
# ARTPAGENUMS
Packit 7a7948
# ATTRIBUTION
Packit 7a7948
# AUTHORBLURB
Packit 7a7948
# AUTHORGROUP
Packit 7a7948
# OTHERCREDIT
Packit 7a7948
# HONORIFIC
Packit 7a7948
Packit 7a7948
# Areas:
Packit 7a7948
# AREA
Packit 7a7948
# AREASET
Packit 7a7948
# AREASPEC
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Linkage, cross references
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
# Print the URL
Packit 7a7948
sgml('</ULINK>', sub {
Packit 7a7948
	output ' <URL:', $_[0]->attribute('URL')->value, '>';
Packit 7a7948
	$newline_last = 0;
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
# If cross reference target is a RefEntry, 
Packit 7a7948
# output CiteRefEntry-style references.
Packit 7a7948
sgml('<XREF>', sub {
Packit 7a7948
	my $id = $_[0]->attribute('LINKEND')->value;
Packit 7a7948
	my $manref = $Refs->get("refentry:$id");
Packit 7a7948
Packit 7a7948
	if($manref) {
Packit 7a7948
		my ($title, $sect) = ($manref =~ /(.*)(\(.*\))/);
Packit 7a7948
		bold_on();
Packit 7a7948
		output $title;
Packit 7a7948
		font_off();
Packit 7a7948
		output $sect;
Packit 7a7948
	} else {
Packit 7a7948
		$blank_xrefs++ if $write_manpages;
Packit 7a7948
		output "[XRef to $id]";
Packit 7a7948
	}
Packit 7a7948
Packit 7a7948
	$newline_last = 0;
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
# Anchor
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
Packit 7a7948
########################################################################
Packit 7a7948
#
Packit 7a7948
# Other handlers 
Packit 7a7948
#
Packit 7a7948
########################################################################
Packit 7a7948
Packit 7a7948
man_sgml('|[lt    ]|', '<');
Packit 7a7948
man_sgml('|[gt    ]|', '>');
Packit 7a7948
man_sgml('|[amp   ]|', '&';;
Packit 7a7948
man_sgml('|[minus ]|', '-');
Packit 7a7948
man_sgml('|[copy  ]|', '(C)');
Packit 7a7948
man_sgml('|[nbsp  ]|', '\~');
Packit 7a7948
man_sgml('|[thinsp]|', '\~');
Packit 7a7948
Packit 7a7948
#
Packit 7a7948
# Default handlers (uncomment these if needed).  Right now, these are set
Packit 7a7948
# up to gag on any unrecognised elements, sdata, processing-instructions,
Packit 7a7948
# or entities.
Packit 7a7948
#
Packit 7a7948
# sgml('start_element',sub { die "Unknown element: " . $_[0]->name; });
Packit 7a7948
# sgml('end_element','');
Packit 7a7948
Packit 7a7948
# This is for weeding out and escaping certain characters.
Packit 7a7948
# This looks like it's inefficient since it's done on every line, but
Packit 7a7948
# in reality, SGMLSpm and sgmlspl parsing ESIS takes _much_ longer.
Packit 7a7948
Packit 7a7948
sgml('cdata', sub
Packit 7a7948
{ 
Packit 7a7948
	if(!$write_manpages) { return; }
Packit 7a7948
	elsif($raw_cdata) { output $_[0]; return; }
Packit 7a7948
	
Packit 7a7948
	# Escape backslashes
Packit 7a7948
	$_[0] =~ s/\\/\\\\/g;
Packit 7a7948
Packit 7a7948
	# Escape dots and single quotes in column 1
Packit 7a7948
	$_[0] =~ s/^\./\\\&\./;
Packit 7a7948
	$_[0] =~ s/^\'/\\\&\'/;
Packit 7a7948
Packit 7a7948
	# In non-'pre'-type elements:
Packit 7a7948
	if(!$nocollapse_whitespace) {
Packit 7a7948
		# Change tabs to spaces
Packit 7a7948
		$_[0] =~ tr/\t/ /;
Packit 7a7948
Packit 7a7948
		# Do not allow indents at beginning of line
Packit 7a7948
		# groff chokes on that.
Packit 7a7948
		if($newline_last) { 
Packit 7a7948
			$_[0] =~ s/^ +//;
Packit 7a7948
Packit 7a7948
			# If the line is all blank, don't do anything.
Packit 7a7948
			if($_[0] eq '') { return; }
Packit 7a7948
		}
Packit 7a7948
	}
Packit 7a7948
Packit 7a7948
	$newline_last = 0;
Packit 7a7948
Packit 7a7948
	output $_[0];
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
Packit 7a7948
# When in whitespace-collapsing mode, we disallow consecutive newlines.
Packit 7a7948
Packit 7a7948
sgml('re', sub
Packit 7a7948
{
Packit 7a7948
	if($nocollapse_whitespace || !$newline_last) {
Packit 7a7948
		output "\n";
Packit 7a7948
	}
Packit 7a7948
Packit 7a7948
	$newline_last = 1;
Packit 7a7948
});
Packit 7a7948
Packit 7a7948
sgml('sdata',sub
Packit 7a7948
{
Packit 7a7948
	die "Unknown SDATA: " . $_[0];
Packit 7a7948
});
Packit 7a7948
sgml('pi',sub { die "Unknown processing instruction: " . $_[0]; });
Packit 7a7948
sgml('entity',sub { die "Unknown external entity: " . $_[0]->name; });
Packit 7a7948
sgml('start_subdoc',sub { die "Unknown subdoc entity: " . $_[0]->name; });
Packit 7a7948
sgml('end_subdoc','');
Packit 7a7948
sgml('conforming','');
Packit 7a7948
Packit 7a7948
1;
Packit 7a7948