[xml/sgml-pkgs] Bug#253085: Please i18n/l10n docbook2man-spec.pl

Helge Kreutzmann Helge Kreutzmann <kreutzm@itp.uni-hannover.de>, 253085@bugs.debian.org
Mon, 7 Jun 2004 09:56:44 +0200


--raC6veAxrt5nqIoY
Content-Type: multipart/mixed; boundary="TakKZr9L6Hm6aLOc"
Content-Disposition: inline


--TakKZr9L6Hm6aLOc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Package: docbook-utils
Version: 0.6.9-12
Severity: wishlist
Tags: patch l10n

//Version: 0.5.1-6
//Package: docbook2man

//I wrote this with docbook2man still installed. I just looked at the
//latest version of docbook-utils, and saw that this issue is not
//addressed. I can update at home in the next days if you think this is
//sensible, though the issue at hand should not be touched by this
//package shift.

Hello,
as you know more and more parts in Debian are l10n and i18n'ed. I am
part of the german translation team and=20
Currently I translate some man pages written in SGML, which are
converted to nroff using docbook2man-spec.pl. A good part of SGML is
that repetitve/generic parts are autogenerated.=20

However, this generic parts have to be available in the language the
document is written in. Once this is done, it also eases the burden on
translators who do not have to care about those repetitive tasks
either.=20

Attached you find a very primitive solution, implemented for german.
Before starting to code, I think it is sensible to determine how this
should be done properly:

1. Best solution of course, would be to parse an attribute, i.e., in
   <!DOCTYPE RefEntry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
                                                         ~~~~
   and then the parser would choose the required strings and
   conventions. This, of course, would require proper support in the
   DTDs. Since Debian is a member in OASIS, such developments could be
   a medium to long-term solution.=20

2. The second best solution would be to enable the transforming script
   to receive additional options, in this case a language settings.
   The script would then choose the conventions/strings required for
   this language or english if the language is (still) unknown.
   Considering the parser at hand, this would require
   po-debconf-support for the strings involved. Also it requires some
   way to set the proper date-format within the man page.

3. The easiest to implement solution are seperate scripts for each
   language, with the strings replaced appropriately, and the date
   format (if necessary) adopted appropriately. This is the approach
   taken in the attached patch. I also only translated the strings
   written into the man page, assuming that at least initially only
   translators would use the tool, hence they would understand the
   error/status messages. Of course, in the long run ALL strings
   should be translated. I can of course, hand in the general strings
   in german as well. I marked the strings and other localizable parts
   (e.g. quoting signs) with # L10N

   Instead of giving it a different name, subdirectories could be used
   as well.

Before you implement a final solution, you should probably discuss the
issue on FIXME@list.debian.org. I sent there a question a while ago
(c.f. FIXME), but I guess if you ask for concret input on possible
zenarios, you will get valuable input. Especially, how to properly
encode the locale. This, eventually, will include the character set as
well.=20

To get translations started quickly, a possible solution would be to
implement 3. first, issuing warnings (and maybe using compatibility
links) when 2./1. are available.

Ceavat: I "only" translate to german, and I only "use" SGML, so there
might be hidden problems with non-western languages (e.g., chinese) I
am not aware of or technical SGML-constraints I am not aware of
either.

-- System Information:
Debian Release: testing/unstable
  APT prefers testing
  APT policy: (990, 'testing')
Architecture: alpha
Kernel: Linux 2.4.21-pre1
Locale: LANG=3Dde_DE@euro, LC_CTYPE=3Dde_DE@euro

Versions of packages docbook2man depends on:
ii  perl [perl5]                  5.8.3-3    Larry Wall's Practical Extract=
ion=20
ii  sgmlspl                       1.03ii-30  SGMLS-based example Perl scrip=
t fo

-- no debconf information
--=20
Helge Kreutzmann, Dipl.-Phys.               Helge.Kreutzmann@itp.uni-hannov=
er.de
  gpg signed mail preferred    gpg-key: finger kreutzm@zibal.itp.uni-hannov=
er.de
    64bit GNU powered                  http://www.itp.uni-hannover.de/~kreu=
tzm
       Help keep free software "libre": http://www.freepatents.org/

--TakKZr9L6Hm6aLOc
Content-Type: application/x-perl
Content-Disposition: attachment; filename="docbook2man-de-spec.pl"
Content-Transfer-Encoding: quoted-printable

=3Dhead1 NAME=0A=0Adocbook2man-spec - convert DocBook RefEntries to Unix ma=
npages=0A=0A=3Dhead1 SYNOPSIS=0A=0AThe SGMLSpm package from CPAN.  This con=
tains the sgmlspl script which=0Ais used to grok this file.  Use it like th=
is:=0A=0Ansgmls some-docbook-document.sgml | sgmlspl sgmlspl-specs/docbook2=
man-spec.pl=0A=0A=3Dhead1 OPTIONS=0A=0A=3Dover 4=0A=0A=3Ditem --section <la=
bel>=0A=0AUse the specified manpage section number,=0Aif not specified in <=
MANVOLNUM>. Default is one (1).=0A=0A=3Ditem --date <string>=0A=0AUse the s=
pecified date in the .TH header.=0ADefault is today.=0A=0A=3Ditem --lowerca=
se | --preserve-case=0A=0AConvert output file names and cross-references to=
 lower case.=0ADefault is to convert to upper case.=0A=0A=3Dhead1 DESCRIPTI=
ON=0A=0AThis is a sgmlspl spec file that produces Unix-style=0Amanpages fro=
m RefEntry markup.=0A=0ASee the accompanying RefEntry man page for 'plain n=
ew' documentation. :)=0A=0A=3Dhead1 LIMITATIONS=0A=0ATrying docbook2man on =
non-DocBook or non-conformant SGML results in=0Aundefined behavior. :-)=0A=
=0AThis program is a slow, dodgy Perl script.=0A=0AThis program does not co=
me close to supporting all the possible markup=0Ain DocBook, and will produ=
ce wrong output in some cases with supported=0Amarkup.=0A=0A=3Dhead1 TODO=
=0A=0AAdd new element handling and fix existing handling.  Be robust.=0APro=
duce cleanest, readable man output as possible (unlike some=0Aother convert=
ers).  Follow Linux man(7) convention.=0AIf this results in added logic in =
this script,=0Athat's okay.  The code should still be reasonably organized.=
=0A=0AMake it faster.  If Perl sucks port it to another language.=0A=0A=3Dh=
ead1 COPYRIGHT=0A=0ACopyright (C) 1998-1999 Steve Cheng <steve@ggi-project.=
org>=0A=0ACopyright (C) 1999 Thomas Lockhart <lockhart@alumni.caltech.edu>=
=0A=0AThis program is free software; you can redistribute it and/or modify =
it=0Aunder the terms of the GNU General Public License as published by the =
Free=0ASoftware Foundation; either version 2, or (at your option) any later=
=0Aversion.=0A=0AYou should have received a copy of the GNU General Public =
License along with=0Athis program; see the file COPYING.  If not, please wr=
ite to the Free=0ASoftware Foundation, 675 Mass Ave, Cambridge, MA 02139, U=
SA.=0A=0A=3Dcut=0A=0A# $Id: docbook2man-spec.pl,v 1.19 1999/08/09 21:39:59 =
steve Exp $=0A=0Ause SGMLS;			# Use the SGMLS package.=0Ause SGMLS::Output;=
		# Use stack-based output.=0Ause SGMLS::Refs;=0A=0A=0A####################=
####################################################=0A# SGMLSPL script pro=
duced automatically by the script sgmlspl.pl=0A#=0A# Document Type: any, bu=
t processes only RefEntries=0A# Edited by: me :)=0A########################=
################################################=0A=0A=0A$write_manpages =
=3D 0;=0A$blank_xrefs =3D 0;=0A=0A$default_sect =3D "1";=0A$default_date =
=3D `date "+%d %B %Y"`;   # L10N=0A=0Awhile (@ARGV) {=0A	my $arg =3D shift =
@ARGV;=0A	if ($arg eq "--section") {=0A		$default_sect =3D shift @ARGV || d=
ie "$arg requires an argument\n";   # L10N=0A	} elsif ($arg eq "--date") {=
=0A		$default_date =3D shift @ARGV || die "$arg requires an argument\n";   =
# L10N=0A	} elsif ($arg eq "--lowercase") {=0A		$lowercase_names =3D 1;=0A	=
} elsif ($arg eq "--preserve-case") {=0A		$lowercase_names =3D 0;=0A	} elsi=
f ($arg eq "--help") {=0A		print "Usage: $0",=0A			" [ --section <label> ]"=
,=0A			" [ --date <string> ]",=0A			" [ --lowercase | --preserve-case ]",=
=0A			"\n";=0A		exit;=0A	} else {=0A		die "unrecognized switch $arg; try $0=
 --help\n";   # L10N=0A	}=0A}=0A=0Asgml('start', sub { =0A	push_output('nul=
');=0A	$raw_cdata =3D 1;			# Makes it a bit faster.=0A	=0A	# Links file=0A	=
open(LINKSFILE, ">manpage.links");=0A=0A	$Refs =3D new SGMLS::Refs("manpage=
.refs", "manpage.log");=0A});=0Asgml('end', sub {=0A	close(LINKSFILE);=0A=
=0A	# Explicitly invoke destructor,=0A	# otherwise cache file may not get w=
ritten!=0A	# Thomas Lockhart, 1999-08-03, perl-5.004, RedHat5.2=0A	undef $R=
efs;=0A=0A	if($blank_xrefs) {=0A		warn "Warning: output contains unresolved=
 XRefs\n";  # L10N=0A	}=0A});=0A=0A=0A#####################################=
###################################=0A#=0A# Output helpers =0A#=0A#########=
###############################################################=0A=0A# Remo=
ve leading and trailing blanks.=0A=0Asub StripString=0A{=0A	my $str =3D shi=
ft;=0A=0A	$str =3D $1 if ($str =3D~ m#^\s*(\S.*)#);=0A	$str =3D $1 if ($str=
 =3D~ m#^(.*\S)\s*$#);=0A=0A	return $str;=0A}=0A=0A# Generate a good file n=
ame, for given manpage title and manvolnum=0A# (cdata content).=0A# Cleanup=
 whitespace and convert to lower case if required.=0A=0Asub FileInfo=0A{=0A=
	my $title =3D StripString(shift);=0A	my $volnum =3D StripString(shift);=0A=
=0A	$title =3D lc $title if $lowercase_names;=0A=0A	$title =3D~ tr/ /_/;=0A=
	$volnum =3D~ tr/ /_/;=0A=0A	# The 'package name' part of the section shoul=
d=0A	# not be used when citing it.=0A	my $sectcite =3D $1 if ($volnum =3D~ =
/([0-9]*)/);=0A	=0A	return ("$title.$volnum", "$title($sectcite)");=0A}=0A=
=0A# Our own version of sgml() and output() to allow simple string output=
=0A# to play well with roff's stupid whitespace rules. =0A=0Asub man_sgml=
=0A{=0A	if(ref($_[1]) eq 'CODE') {=0A		return &sgml;=0A	}=0A	=0A	my $s =3D =
$_[1];=0A	$s =3D~ s/\\/\\\\/g;=0A	$s =3D~ s/'/\\'/g;=0A=0A	sgml($_[0], eval=
("sub { man_output '$s' }"));=0A}=0A=0Asub man_output=0A{=0A	if($separator =
eq 'full') {=0A		output "\n" unless $newline_last++;=0A		output ".PP\n";=0A=
		$separator =3D '';=0A	}=0A	=0A	$_ =3D shift;=0A	if(s/^\n//) {=0A		output =
"\n" unless $newline_last++;=0A	}=0A	return if $_ eq '';=0A	=0A	output $_;=
=0A=0A	if(@_) {=0A		output @_;=0A		$newline_last =3D (pop(@_) =3D~ /\n$/);=
=0A	} else {=0A		$newline_last =3D ($_ =3D~ /\n$/)=0A	}=0A}=0A=0A# Fold lin=
es into one, quote some characters=0Asub fold_string=0A{=0A	$_ =3D shift;=
=0A	=0A	s/\\/\\\\/g;=0A	s/"/\\\&"/g;=0A=0A	# Change tabs and newlines to sp=
aces=0A	# The newlines will be swallowed later while trimming=0A	tr/[\t\n]/=
  /;=0A=0A	# Trim whitespace from beginning and end.=0A	s/^ +//;=0A	s/ +$//=
;=0A=0A	return $_;=0A}=0A	=0Asub save_cdata()=0A{=0A	$raw_cdata++;=0A	push_=
output('string');=0A}=0A=0Asub bold_on()=0A{=0A	# If the last font is also =
bold, don't change anything.=0A	# Basically this is to just get more readab=
le man output.=0A	if($fontstack[$#fontstack] ne 'bold') {=0A		if(!$raw_cdat=
a) {=0A			output '\fB';=0A			#$newline_last =3D 0;=0A		}=0A	}=0A	push(@font=
stack, 'bold');=0A}=0A=0Asub italic_on()=0A{=0A	# If the last font is also =
italic, don't change anything.=0A	if($fontstack[$#fontstack] ne 'italic') {=
=0A		if(!$raw_cdata) {=0A			output '\fI';=0A			#$newline_last =3D 0;=0A		}=
=0A	}=0A	push(@fontstack, 'italic');=0A}=0A=0Asub font_off()=0A{=0A	my $thi=
sfont =3D pop(@fontstack);=0A	my $lastfont =3D $fontstack[$#fontstack];=0A	=
=0A	# Only output font change if it is different=0A	if($thisfont ne $lastfo=
nt) {=0A		if($raw_cdata)			{ return; }=0A		elsif($lastfont eq 'bold') 	{ ou=
tput '\fB'; }=0A		elsif($lastfont eq 'italic')	{ output '\fI'; }=0A		else		=
		{ output '\fR'; }=0A	=0A		#$newline_last =3D 0;=0A	}=0A}=0A=0A=0A########=
################################################################=0A#=0A# Ma=
npage management=0A#=0A####################################################=
####################=0A=0Asgml('<REFENTRY>', sub { =0A	# This will be overw=
ritten at end of REFMETA, when we know the name of the page.=0A	pop_output(=
);=0A	=0A	$write_manpages =3D 1;		# Currently writing manpage.=0A	=0A	$noco=
llapse_whitespace =3D 0;	# Current whitespace collapse counter.=0A	$newline=
_last =3D 1;		# At beginning of line?=0A		# Just a bit of warning, you will=
 see this variable manipulated=0A		# manually a lot.  It makes the code har=
der to follow but it=0A		# saves you from having to worry about collapsing =
at the end of=0A		# parse, stopping at verbatims, etc.=0A	$raw_cdata =3D 0;=
                 # Instructs certain output functions to=0A					# leave CDA=
TA alone, so we can assign=0A					# it to a string and process it, etc.=0A	=
@fontstack =3D ();		# Fonts being activated.=0A	=0A	$list_nestlevel =3D 0;	=
	# Indent certain nested content.=0A=0A	# Separator to use between 'element=
s' in the content of a=0A	# paragraph (usually).  This makes sure that PCDA=
TA after a list=0A	# in a PARA gets a break in between and not become part =
of the=0A	# last listitem.  Note that we can't do it after the list ends,=
=0A	# because often the list ends the paragraph and we'll get an=0A	# extra=
 break.  Anything that changes the separator status from=0A	# the default s=
hould also save its last state in the parent=0A	# element's ext, but I'm no=
t going to explain further.  It's a=0A	# gross hack and almost guaranteed t=
o fail in unforseen cases.=0A	# The only way to avoid all this is to use a =
tree/grove model, which=0A	# we're _not_ doing.=0A	$separator =3D '';=0A	=
=0A	$manpage_title =3D '';		# Needed for indexing.=0A	$manpage_sect =3D '';=
=0A	@manpage_names =3D ();=0A	=0A	$manpage_misc =3D '';=0A});=0Asgml('</REF=
ENTRY>', sub {=0A	if(!$newline_last) {=0A		output "\n";=0A	}=0A	=0A	$raw_cd=
ata =3D 1;=0A	push_output('nul');=0A=0A	$write_manpages =3D 0;=0A});=0A=0As=
gml('</REFMETA>', sub {=0A	my ($filename, $citation) =3D =0A		FileInfo($man=
page_title, $manpage_sect || $default_sect);=0A=0A	push_output('file', $fil=
ename);=0A=0A	output <<_END_BANNER;=0A.\\" This manpage has been automatica=
lly generated by docbook2man-spec=0A.\\" from a DocBook document.  docbook2=
man-spec can be found at:=0A.\\" <http://shell.ipoline.com/~elmert/hacks/do=
cbook2X/> =0A.\\" Please send any bug reports, improvements, comments, patc=
hes, =0A.\\" etc. to Steve Cheng <steve\@ggi-project.org>.=0A_END_BANNER=0A=
=0A	my $manpage_date =3D $_[0]->parent->ext->{'date'} || $default_date;=0A=
=0A	output '.TH "';=0A=0A	# If the title is not mixed-case, convention says=
 to=0A	# uppercase the whole title.  (The canonical title is=0A	# lowercase=
.)=0A	if($manpage_title =3D~ /[A-Z]/) {=0A		output fold_string($manpage_tit=
le);=0A	} else {=0A		output uc(fold_string($manpage_title));=0A	}=0A	=0A	ou=
tput  '" "', fold_string($manpage_sect), =0A		'" "', fold_string($manpage_d=
ate),=0A		'" "', $manpage_misc, =0A		'" "', $manpage_manual, =0A		"\"\n";=
=0A=0A	$newline_last =3D 1;=0A=0A	# References to this RefEntry.=0A	if(defi=
ned($_[0]->parent->attribute('ID')->value)) {=0A		my $id =3D $_[0]->parent-=
>attribute('ID')->value;=0A=0A		# Append XREFLABEL content to citations.=0A=
		if(defined($_[0]->parent->attribute('XREFLABEL')->value)) {=0A			$citatio=
n =3D $_[0]->parent->attribute('XREFLABEL')->value .=0A					' [' . $citatio=
n . ']';=0A		}=0A=0A		$Refs->put("refentry:$id", $citation);=0A	}=0A});=0A=
=0Asgml('<REFENTRYTITLE>', sub { =0A	if($_[0]->in('REFMETA')) { =0A		save_c=
data();=0A	} else { =0A		# Manpage citations are in bold.=0A		bold_on();=0A=
	}=0A});=0Asgml('</REFENTRYTITLE>', sub { =0A	if($_[0]->in('REFMETA')) {=0A=
		$raw_cdata--;=0A		$manpage_title =3D pop_output();=0A	}=0A	else { font_of=
f(); }=0A=0A	if (defined($_[0]->attribute('ID')->value)) {=0A		my $id =3D $=
_[0]->attribute('ID')->value;=0A		my ($name, $citation) =3D FileInfo($manpa=
ge_title, $default_sect);=0A	=0A		$Refs->put("refentrytitle:$id", $citation=
);=0A	}=0A});=0A=0Asgml('<MANVOLNUM>', sub { =0A	if($_[0]->in('REFMETA')) {=
 =0A		save_cdata();	=0A	} else {=0A		# Manpage citations use ().=0A		output=
 '(';=0A	}=0A});=0Asgml('</MANVOLNUM>', sub { =0A	if($_[0]->in('REFMETA')) =
{=0A		$raw_cdata--;=0A		$manpage_sect =3D pop_output();=0A	}=0A	else { outp=
ut ')' }=0A});=0A=0Asgml('<REFMISCINFO>', \&save_cdata);=0Asgml('</REFMISCI=
NFO>', sub { =0A	$raw_cdata--;=0A	$manpage_misc =3D fold_string(pop_output(=
));=0A});=0A=0A=0A# NAME section=0Aman_sgml('<REFNAMEDIV>', "\n.SH NAME\n")=
;   # L10N=0A=0Asgml('<REFNAME>', \&save_cdata);=0Asgml('</REFNAME>', sub {=
 =0A	$raw_cdata--;=0A	push(@manpage_names, pop_output());=0A});=0A=0Asgml('=
<REFPURPOSE>', \&save_cdata);=0Asgml('</REFPURPOSE>', sub { =0A	$raw_cdata-=
-;=0A	my $manpage_purpose =3D fold_string(pop_output());=0A	=0A	for(my $i =
=3D 0; $i < $#manpage_names; $i++) {=0A		output fold_string($manpage_names[=
$i]), ', ';=0A	}=0A=0A	output fold_string($manpage_names[$#manpage_names]);=
=0A	output " \\- $manpage_purpose\n";=0A=0A	$newline_last =3D 1;=0A=0A	fore=
ach(@manpage_names) {=0A		# Don't link to itself=0A		if($_ ne $manpage_titl=
e) {=0A			print LINKSFILE "$manpage_title.$manpage_sect	$_.$manpage_sect\n"=
;=0A		}=0A	}=0A});=0A	=0Aman_sgml('<REFCLASS>', "\n.sp\n");=0A=0A#RefDescri=
ptor=0A=0A=0A##############################################################=
##########=0A#=0A# SYNOPSIS section and synopses=0A#=0A####################=
####################################################=0A=0Aman_sgml('<REFSYN=
OPSISDIV>', "\n.SH =DCBERSICHT\n");       # L10N=0Aman_sgml('</REFSYNOPSISD=
IV>', "\n");=0A=0A## FIXME! Must be made into block elements!!=0A#sgml('<FU=
NCSYNOPSIS>', \&bold_on);=0A#sgml('</FUNCSYNOPSIS>', \&font_off);=0A#sgml('=
<CMDSYNOPSIS>', \&bold_on);=0A#sgml('</CMDSYNOPSIS>', \&font_off);=0A=0Aman=
_sgml('<FUNCSYNOPSIS>', sub {=0A	#man_output("\n.sp\n");=0A	bold_on();=0A})=
;=0Aman_sgml('</FUNCSYNOPSIS>', sub {=0A	font_off();=0A	man_output "\n";=0A=
});=0A=0Aman_sgml('<CMDSYNOPSIS>', "\n.sp\n");=0Aman_sgml('</CMDSYNOPSIS>',=
 "\n");=0A=0Aman_sgml('<FUNCPROTOTYPE>', "\n.sp\n");=0A=0A# Arguments to fu=
nctions.  This is C convention.=0Aman_sgml('<PARAMDEF>', '(');=0Aman_sgml('=
</PARAMDEF>', ");\n");=0Aman_sgml('<VOID>', "(void);\n");=0A=0A=0Asub arg_s=
tart=0A{=0A	# my $choice =3D $_[0]->attribute('CHOICE')->value;=0A=0A	# The=
 content model for CmdSynopsis doesn't include #PCDATA,=0A	# so we won't se=
e any of the whitespace in the source file,=0A	# so we have to add it after=
 each component.=0A	man_output ' ';=0A=0A	if($_[0]->attribute('CHOICE')->va=
lue =3D~ /opt/i) {=0A		man_output '[ ';=0A	}=0A	bold_on();=0A}=0Asub arg_en=
d=0A{=0A	font_off();=0A	if($_[0]->attribute('REP')->value =3D~ /^Repeat/i) =
{=0A		italic_on();=0A		man_output '...';=0A		font_off();=0A	}=0A	if($_[0]->=
attribute('CHOICE')->value =3D~ /opt/i) {=0A		man_output ' ] ';=0A	}=0A}=0A=
=0Asgml('<ARG>', \&arg_start);=0Asgml('</ARG>', \&arg_end);=0Asgml('<GROUP>=
', \&arg_start);=0Asgml('</GROUP>', \&arg_end);=0A=0Asgml('<OPTION>', \&bol=
d_on);=0Asgml('</OPTION>', \&font_off);=0A=0A# FIXME: This is one _blank_ l=
ine.=0Aman_sgml('<SBR>', "\n\n");=0A=0A=0A#################################=
#######################################=0A#=0A# General sections=0A#=0A####=
####################################################################=0A=0A#=
 The name of the section is handled by TITLE.  This just sets=0A# up the ro=
ff markup.=0Aman_sgml('<REFSECT1>', sub { $separator =3D ''; man_output "\n=
.SH "});=0Aman_sgml('<REFSECT2>', sub { $separator =3D ''; man_output "\n.S=
S "});=0Aman_sgml('<REFSECT3>', sub { $separator =3D ''; man_output "\n.SS =
"});=0A=0A=0A##############################################################=
##########=0A#=0A# Titles, metadata.=0A#=0A################################=
########################################=0A=0Asgml('<TITLE>', sub {=0A	if($=
_[0]->in('REFERENCE') or $_[0]->in('BOOK')) {=0A		$write_manpages =3D 1;=0A=
	}=0A	save_cdata();=0A});=0Asgml('</TITLE>', sub { =0A	my $title =3D fold_s=
tring(pop_output());=0A	$raw_cdata--;=0A	=0A	if($_[0]->in('REFERENCE') or $=
_[0]->in('BOOK')) {=0A		# We use TITLE of enclosing Reference or Book as ma=
nual name=0A		$manpage_manual =3D $title;=0A		$write_manpages =3D 0;=0A	}=
=0A	elsif(exists $_[0]->parent->ext->{'title'}) {=0A		# By far the easiest =
case.  Just fold the string as=0A		# above, and then set the parent element=
's variable.=0A		$_[0]->parent->ext->{'title'} =3D $title;=0A	}=0A	else {=
=0A		# If the parent element's handlers are lazy, =0A		# output the folded =
string for them :)=0A		# We assume they want uppercase and a newline.=0A		m=
an_output '"', uc($title), "\"\n";=0A	}=0A=0A	if (defined($_[0]->attribute(=
'ID')->value)) {=0A		my $id =3D $_[0]->attribute('ID')->value;=0A		my ($nam=
e, $citation) =3D FileInfo($manpage_title, $default_sect);=0A	=0A		$Refs->p=
ut("title:$id", $citation);=0A	}=0A});=0A=0Asgml('<ATTRIBUTION>', sub { =0A=
	if($_[0]->in('BLOCKQUOTE')) {=0A		push_output('string');=0A	}=0A});=0Asgml=
('</ATTRIBUTION>', sub { =0A	if($_[0]->in('BLOCKQUOTE')) {=0A		$_[0]->paren=
t->ext->{'attribution'} =3D pop_output(); =0A	} else {=0A		# For an Epigrap=
h.=0A		man_output "\n\n";=0A	}=0A});=0A=0Asgml('<DATE>', sub {=0A      save=
_cdata();=0A});=0Asgml('</DATE>', sub {=0A      $_[0]->parent->parent->ext-=
>{'date'} =3D fold_string(pop_output());=0A      $raw_cdata--;=0A});=0A=0As=
ub ignore_content { push_output 'nul'; }=0Asub restore_content { pop_output=
(); }=0A=0Asgml('<DOCINFO>', \&ignore_content);=0Asgml('</DOCINFO>', \&rest=
ore_content);=0Asgml('<REFSYNOPSISDIVINFO>', \&ignore_content);=0Asgml('</R=
EFSYNOPSISDIVINFO>', \&restore_content);=0Asgml('<REFSECT1INFO>', \&ignore_=
content);=0Asgml('</REFSECT1INFO>', \&restore_content);=0Asgml('<REFSECT2IN=
FO>', \&ignore_content);=0Asgml('</REFSECT2INFO>', \&restore_content);=0Asg=
ml('<REFSECT3INFO>', \&ignore_content);=0Asgml('</REFSECT3INFO>', \&restore=
_content);=0A=0Asgml('<INDEXTERM>', \&ignore_content);=0Asgml('</INDEXTERM>=
', \&restore_content);=0A=0Asgml('<AUTHORBLURB>', \&ignore_content);=0Asgml=
('</AUTHORBLURB>', \&restore_content);=0A=0A=0A############################=
############################################=0A#=0A# Set bold on enclosed c=
ontent =0A#=0A#############################################################=
###########=0A=0Asgml('<APPLICATION>', \&bold_on);=0Asgml('</APPLICATION>',=
 \&font_off);=0A=0Asgml('<CLASSNAME>', \&bold_on);		sgml('</CLASSNAME>', \&=
font_off);=0Asgml('<STRUCTNAME>', \&bold_on);	sgml('</STRUCTNAME>', \&font_=
off);=0Asgml('<STRUCTFIELD>', \&bold_on);	sgml('</STRUCTFIELD>', \&font_off=
);=0Asgml('<SYMBOL>', \&bold_on);		sgml('</SYMBOL>', \&font_off);=0Asgml('<=
TYPE>', \&bold_on);		sgml('</TYPE>', \&font_off);=0A=0Asgml('<ENVAR>', \&bo=
ld_on);	sgml('</ENVAR>', \&font_off);=0A=0Asgml('<FUNCTION>', \&bold_on);	s=
gml('</FUNCTION>', \&font_off);=0A=0Asgml('<EMPHASIS>', \&bold_on);	sgml('<=
/EMPHASIS>', \&font_off);=0A=0Asgml('<ERRORNAME>', \&bold_on);	sgml('</ERRO=
RNAME>', \&font_off);=0A# ERRORTYPE=0A=0Asgml('<COMMAND>', \&bold_on);	sgml=
('</COMMAND>', \&font_off);=0A=0Asgml('<GUIBUTTON>', \&bold_on);	sgml('</GU=
IBUTTON>', \&font_off);=0Asgml('<GUIICON>', \&bold_on);	sgml('</GUIICON>', =
\&font_off);=0A# GUILABEL=0A# GUIMENU=0A# GUIMENUITEM=0A# GUISUBMENU=0A# ME=
NUCHOICE=0A=0Asgml('<ACCEL>', \&bold_on);	sgml('</ACCEL>', \&font_off);=0A#=
 KEYCODE=0A# SHORTCUT=0A=0A=0Asgml('<KEYCOMBO>', sub {=0A	$separator =3D 'n=
one';=0A	$_[0]->ext->{'separator'} =3D 'none';=0A});=0Asgml('</KEYCOMBO>', =
sub { $separator =3D $_[0]->parent->ext->{'separator'}; });=0A=0Asub _keyco=
mbo {=0A	if($_[0]->in('KEYCOMBO')) {=0A		if($separator eq 'none') { $separa=
tor =3D '' }=0A		else { man_output "+"; }=0A	}=0A	bold_on();=0A}=0Asgml('<K=
EYCAP>', \&_keycombo);	sgml('</KEYCAP>', \&font_off);=0Asgml('<KEYSYM>', \&=
_keycombo);	sgml('</KEYSYM>', \&font_off);=0Asgml('<MOUSEBUTTON>', \&_keyco=
mbo);	sgml('</MOUSEBUTTON>', \&font_off);=0A=0A=0Asgml('<USERINPUT>', \&bol=
d_on);	sgml('</USERINPUT>', \&font_off);=0A=0Asgml('<INTERFACEDEFINITION>',=
 \&bold_on);=0Asgml('</INTERFACEDEFINITION>', \&font_off);=0A=0A# May need =
to look at the CLASS=0Asgml('<SYSTEMITEM>', \&bold_on);=0Asgml('</SYSTEMITE=
M>', \&font_off);=0A=0A=0A#################################################=
#######################=0A#=0A# Set italic on enclosed content =0A#=0A#####=
###################################################################=0A=0Asg=
ml('<FIRSTTERM>', \&italic_on);	sgml('</FIRSTTERM>', \&font_off);=0A=0Asgml=
('<FILENAME>', \&italic_on);	sgml('</FILENAME>', \&font_off);=0Asgml('<PARA=
METER>', \&italic_on);	sgml('</PARAMETER>', \&font_off);=0Asgml('<PROPERTY>=
', \&italic_on);	sgml('</PROPERTY>', \&font_off);=0A=0Asgml('<REPLACEABLE>'=
, sub {=0A	italic_on();=0A	if($_[0]->in('TOKEN')) {=0A		# When tokenizing, =
follow more 'intuitive' convention=0A		output "<";=0A	}=0A});=0Asgml('</REP=
LACEABLE>', sub {=0A	if($_[0]->in('TOKEN')) {=0A		output ">";=0A	}=0A	font_=
off();=0A});=0A=0Asgml('<CITETITLE>', \&italic_on);	sgml('</CITETITLE>', \&=
font_off);=0Asgml('<FOREIGNPHRASE>', \&italic_on);	sgml('</FOREIGNPHRASE>',=
 \&font_off);=0A=0Asgml('<LINEANNOTATION>', \&italic_on);	sgml('</LINEANNOT=
ATION>', \&font_off);=0A=0A=0A#############################################=
###########################=0A#=0A# Other 'inline' elements =0A#=0A########=
################################################################=0A=0Aman_s=
gml('<EMAIL>', '<');=0Aman_sgml('</EMAIL>', '>');=0Aman_sgml('<OPTIONAL>', =
'[');=0Aman_sgml('</OPTIONAL>', ']');=0A=0Aman_sgml('</TRADEMARK>', "\\u\\s=
-2TM\\s+2\\d");      # L10N=0A=0Aman_sgml('<COMMENT>', "[Kommentar: ");    =
           # L10N=0Aman_sgml('</COMMENT>', "]");=0A=0Aman_sgml('<QUOTE>', "=
=BB");                            # L10N=0Aman_sgml('</QUOTE>', "=AB");    =
                       # L10N=0A=0A#man_sgml('<LITERAL>', '"');=0A#man_sgml=
('</LITERAL>', '"');=0A# There doesn't seem to be a good way to represent L=
ITERAL in -man=0A# ComputerOutput, SGMLTag, Markup are the same thing.=0A=
=0A# These create spaces between content in special elements=0A# without PC=
DATA content.=0Aman_sgml('</HONORIFIC>', " ");=0Aman_sgml('</FIRSTNAME>', "=
 ");=0Aman_sgml('</SURNAME>', " ");=0Aman_sgml('</LINEAGE>', " ");=0Aman_sg=
ml('</OTHERNAME>', " ");=0A=0Aman_sgml('<AFFILIATION>', "(");=0Aman_sgml('<=
/AFFILIATION>', ") ");=0Aman_sgml('<CONTRIB>', "(");=0Aman_sgml('</CONTRIB>=
', ") ");=0A=0Aman_sgml('</STREET>', " ");=0Aman_sgml('</POB>', " ");=0Aman=
_sgml('</POSTCODE>', " ");=0Aman_sgml('</CITY>', " ");=0Aman_sgml('</STATE>=
', " ");=0Aman_sgml('</COUNTRY>', " ");=0Aman_sgml('</PHONE>', " ");=0Aman_=
sgml('</FAX>', " ");=0Aman_sgml('</OTHERADDRESS>', " ");=0A=0Aman_sgml('</A=
LT>', ": ");=0Aman_sgml('<GRAPHIC>', " [GRAPHIK] ");        # L10N=0A=0A# N=
o special presentation:=0A=0A# AUTHORINITIALS=0A=0A# ABBREV=0A# ACTION=0A# =
ACRONYM=0A# CITATION=0A# PHRASE=0A# QUOTE=0A# WORDASWORD=0A=0A# PROMPT=0A# =
RETURNVALUE=0A# TOKEN=0A=0A# DATABASE=0A# HARDWARE=0A# INTERFACE=0A# MEDIAL=
ABEL=0A=0A=0A##############################################################=
##########=0A#=0A# Paragraph and paragraph-like elements =0A#=0A###########=
#############################################################=0A=0Asub para=
_start {=0A	if($separator eq '' or $separator eq 'full') {=0A		$separator =
=3D '';=0A		man_output "\n.PP\n";=0A	} elsif($separator eq 'blank') { =0A		=
man_output "\n\n";=0A	} elsif($separator eq 'none' ) {=0A		$_[0]->parent->e=
xt->{'separator'} =3D 'blank';=0A		$separator =3D 'blank';=0A	}=0A}=0A# Act=
ually applies to a few other block elements as well=0Asub para_end {=0A	$se=
parator =3D $_[0]->parent->ext->{'separator'};=0A	man_output "\n";=0A}=0A=
=0Asgml('<PARA>', \&para_start);=0Asgml('</PARA>', \&para_end);=0Asgml('<SI=
MPARA>', \&para_start);=0Asgml('</SIMPARA>', \&para_end);=0A=0A# Nothing sp=
ecial, except maybe FIXME set nobreak.=0Asgml('<INFORMALEXAMPLE>', \&para_s=
tart);=0Asgml('</INFORMALEXAMPLE>', \&para_end);=0A=0A=0A##################=
######################################################=0A#=0A# Blocks using=
 SS sections=0A#=0A########################################################=
################=0A=0A# FIXME: We need to consider the effects of SS=0A# in=
 a hanging tag :(=0A=0A# Complete with the optional-title dilemma (again).=
=0Asgml('<ABSTRACT>', sub {=0A	$_[0]->ext->{'title'} =3D 'ABSTRAKT';      #=
 L10N=0A	output "\n" unless $newline_last++;=0A	push_output('string');=0A})=
;=0Asgml('</ABSTRACT>', sub {=0A	my $content =3D pop_output();=0A	=0A	# As =
ABSTRACT is never on the same level as RefSect1,=0A	# this leaves us with o=
nly .SS in terms of -man macros.=0A	output ".SS \"", uc($_[0]->ext->{'title=
'}), "\"\n";=0A=0A	output $content;=0A	output "\n" unless $newline_last++;=
=0A});=0A=0A=0A=0A# Ah, I needed a break.  Example always has a title.=0Asg=
ml('<EXAMPLE>', sub { $separator =3D ''; man_output "\n.SS "});=0Asgml('</E=
XAMPLE>', \&para_end);=0A=0A# Same with sidebar.=0Asgml('<SIDEBAR>', sub { =
$separator =3D ''; man_output "\n.SS "});=0Asgml('</SIDEBAR>', \&para_end);=
=0A=0Asgml('<FORMALPARA>', sub { $separator =3D ''; man_output "\n.SS "});=
=0Asgml('</FORMALPARA>', \&para_end);=0A=0Asgml('<FIGURE>', sub { $separato=
r =3D ''; man_output "\n.SS "});=0Asgml('</FIGURE>', \&para_end);=0A=0A=0A=
=0A# NO title.               # L10N=0Asgml('<HIGHLIGHTS>', sub { $separator=
 =3D ''; man_output "\n.SS HIGHLIGHTS\n"});=0Asgml('</HIGHLIGHTS>', \&para_=
end);=0A=0A=0A#############################################################=
###########=0A#=0A# Indented 'Block' elements =0A#=0A######################=
##################################################=0A=0Asub indent_block_st=
art=0A{=0A	$separator =3D '';=0A	man_output "\n.sp\n.RS\n";=0A}=0Asub inden=
t_block_end=0A{=0A	$separator =3D $_[0]->parent->ext->{'separator'};=0A	man=
_output "\n.RE\n.sp\n";=0A}=0A=0Asgml('<ADDRESS>', sub {=0A	&indent_block_s=
tart;=0A	if($_[0]->attribute('FORMAT')->type eq 'NOTATION'=0A	   and $_[0]-=
>attribute('FORMAT')->value->name eq 'LINESPECIFIC') {=0A		&verbatim_start;=
=0A	}=0A});=0Asgml('</ADDRESS>', sub {=0A	if($_[0]->attribute('FORMAT')->ty=
pe eq 'NOTATION'=0A	   and $_[0]->attribute('FORMAT')->value->name eq 'LINE=
SPECIFIC') {=0A		&verbatim_end;=0A	}=0A	&indent_block_end;=0A});=0A	=0A# Th=
is element is almost like an admonition (below),=0A# only the default title=
 is blank :)=0A=0Asgml('<BLOCKQUOTE>', sub { =0A	$_[0]->ext->{'title'} =3D =
''; =0A	&indent_block_start;=0A	push_output('string');=0A});=0Asgml('</BLOC=
KQUOTE>', sub {=0A	my $content =3D pop_output();=0A=0A	if($_[0]->ext->{'tit=
le'}) {=0A		output ".B \"", $_[0]->ext->{'title'}, ":\"\n";=0A	}=0A	=0A	out=
put $content;=0A=0A	if($_[0]->ext->{'attribution'}) {=0A		man_output "\n\n =
               -- ",=0A				$_[0]->ext->{'attribution'}, "\n";=0A	}=0A	=0A	&=
indent_block_end;=0A});=0A=0A# Set off admonitions from the rest of the tex=
t by indenting.=0A# FIXME: Need to check if this works inside paragraphs, n=
ot enclosing them.=0Asub admonition_end {=0A	my $content =3D pop_output();=
=0A=0A	# When the admonition is only one paragraph,=0A	# it looks nicer if =
the title was inline.=0A	my $num_para;=0A	while ($content =3D~ /^\.PP/gm) {=
 $num_para++ }=0A	if($num_para=3D=3D1) {=0A		$content =3D~ s/^\.PP\n//;=0A	=
}=0A	=0A	output ".B \"" . $_[0]->ext->{'title'} . ":\"\n";=0A	output $conte=
nt;=0A	=0A	&indent_block_end;=0A}=0A=0Asgml('<NOTE>', sub {=0A	# We can't s=
ee right now whether or not there is a TITLE=0A	# element, so we have to sa=
ve the output now and add it back=0A	# at the end of this admonition.=0A	$_=
[0]->ext->{'title'} =3D 'Note';      # L10N=0A	=0A	&indent_block_start;=0A	=
=0A	push_output('string');=0A});=0Asgml('</NOTE>', \&admonition_end);=0A=0A=
# Same as above.=0Asgml('<WARNING>', sub { =0A	$_[0]->ext->{'title'} =3D 'W=
arnung';       # L10N=0A	&indent_block_start;=0A	push_output('string');=0A}=
);=0Asgml('</WARNING>', \&admonition_end);=0A=0Asgml('<TIP>', sub {=0A	$_[0=
]->ext->{'title'} =3D 'Tipp';           # L10N=0A	&indent_block_start;=0A	p=
ush_output('string');=0A});=0Asgml('</TIP>', \&admonition_end);=0Asgml('<CA=
UTION>', sub {=0A	$_[0]->ext->{'title'} =3D 'Caution';        # L10N=0A	&in=
dent_block_start;=0A	push_output('string');=0A});=0Asgml('</CAUTION>', \&ad=
monition_end);=0A=0Asgml('<IMPORTANT>', sub {=0A	$_[0]->ext->{'title'} =3D =
'Wichtig';         # L10N=0A	&indent_block_start;=0A	push_output('string');=
=0A});=0Asgml('</IMPORTANT>', \&admonition_end);=0A=0A=0A##################=
######################################################=0A#=0A# Verbatim dis=
plays. =0A#=0A#############################################################=
###########=0A=0Asub verbatim_start {=0A	$separator =3D '';=0A	man_output "=
\n.sp\n";=0A	man_output "\n.nf\n" unless $nocollapse_whitespace++;=0A}=0A=
=0Asub verbatim_end {=0A	man_output "\n.sp\n";=0A	man_output "\n.fi\n" unle=
ss --$nocollapse_whitespace;=0A	$separator =3D $_[0]->parent->ext->{'separa=
tor'};=0A}=0A=0Asgml('<PROGRAMLISTING>', \&verbatim_start); =0Asgml('</PROG=
RAMLISTING>', \&verbatim_end);=0A=0Asgml('<SCREEN>', \&verbatim_start); =0A=
sgml('</SCREEN>', \&verbatim_end);=0A=0Asgml('<LITERALLAYOUT>', \&verbatim_=
start); =0Asgml('</LITERALLAYOUT>', \&verbatim_end);=0A=0Asgml('<SYNOPSIS>'=
, sub {=0A	my $format =3D $_[0]->attribute('FORMAT');=0A=0A	if($format->typ=
e eq 'NOTATION'=0A	   and $format->value->name eq 'LINESPECIFIC')=0A	{=0A		=
&verbatim_start;=0A	} else {=0A		$separator =3D '';=0A		man_output "\n.sp\n=
";=0A	}=0A});=0A=0Asgml('</SYNOPSIS>', sub {=0A	my $format =3D $_[0]->attri=
bute('FORMAT');=0A	=0A	if($format->type eq 'NOTATION'=0A	   and $format->va=
lue->name eq 'LINESPECIFIC')=0A	{=0A		&verbatim_end;=0A	} else {=0A		man_ou=
tput "\n";=0A		$_[0]->parent->ext->{'separator'} =3D 'full';=0A		$separator=
 =3D 'full';=0A	}=0A});=0A=0A=0A###########################################=
#############################=0A#=0A# Lists=0A#=0A#########################=
###############################################=0A=0A# Indent nested lists.=
=0Asub list_start {=0A	man_output "\n.RS\n" if $list_nestlevel++;=0A}=0Asub=
 list_end {=0A	man_output "\n.RE\n" if --$list_nestlevel;=0A	$_[0]->parent-=
>ext->{'separator'} =3D 'full';=0A	$separator =3D 'full';=0A}=0A=0Asgml('<V=
ARIABLELIST>', \&list_start);=0Asgml('</VARIABLELIST>', \&list_end);=0Asgml=
('<ITEMIZEDLIST>', \&list_start);=0Asgml('</ITEMIZEDLIST>', \&list_end);=0A=
sgml('<ORDEREDLIST>', sub { =0A	&list_start;=0A	$_[0]->ext->{'count'} =3D 1=
;=0A});=0Asgml('</ORDEREDLIST>', \&list_end);=0A		=0A# Output content on on=
e line, bolded.=0Asgml('<TERM>', sub { =0A	man_output "\n.TP\n";=0A	bold_on=
();=0A	push_output('string');=0A});=0Asgml('</TERM>', sub { =0A	my $term =
=3D StripString(pop_output());=0A	$term =3D~ tr/\n/ /;=0A	output $term;=0A	=
font_off();=0A	output "\n";=0A	$newline_last =3D 1;=0A});=0A	=0Asgml('<LIST=
ITEM>', sub {=0A	# A bulleted list.=0A	if($_[0]->in('ITEMIZEDLIST')) {=0A		=
man_output "\n.TP 0.2i\n\\(bu\n";=0A	}=0A=0A	# Need numbers.=0A	# Assume Ar=
abic numeration for now.=0A	elsif($_[0]->in('ORDEREDLIST')) {=0A		man_outpu=
t "\n.IP ", $_[0]->parent->ext->{'count'}++, ". \n";=0A	}=0A	=0A	$_[0]->ext=
->{'separator'} =3D 'none';=0A	$separator =3D 'none';=0A});=0A=0Asgml('<SIM=
PLELIST>', sub {=0A	$_[0]->ext->{'first_member'} =3D 1;=0A});=0Asgml('<MEMB=
ER>', sub {=0A	my $parent =3D $_[0]->parent;=0A	=0A	if($parent->attribute('=
TYPE')->value =3D~ /Inline/i) {=0A		if($parent->ext->{'first_member'}) {=0A=
			# If this is the first member don't put any commas=0A			$parent->ext->{'=
first_member'} =3D 0;=0A		} else {=0A			man_output ", ";=0A		}=0A=0A	# We d=
on't really have Horiz rendering, so it's the same=0A	# as Vert.=0A	} else =
{=0A		man_output "\n\n";=0A	}=0A});=0A=0A# We implement Procedures as inden=
t and lists=0A=0Asgml('<PROCEDURE>', sub {=0A	$_[0]->ext->{'count'} =3D 1;=
=0A	&indent_block_start;=0A});=0Asgml('</PROCEDURE>', sub {=0A	&indent_bloc=
k_end;=0A	$_[0]->parent->ext->{'separator'} =3D 'full';=0A	$separator =3D '=
full';=0A});=0A=0Asgml('<STEP>', sub {=0A	man_output "\n.IP ", $_[0]->paren=
t->ext->{'count'}++, ". \n";=0A	$_[0]->ext->{'separator'} =3D 'none';=0A	$s=
eparator =3D 'none';=0A});=0A=0A=0A########################################=
################################=0A#=0A# Linkage, cross references=0A#=0A##=
######################################################################=0A=
=0A# Print the URL=0Asgml('</ULINK>', sub {=0A	man_output ' <URL:', $_[0]->=
attribute('URL')->value, '>';=0A});=0A=0A# If cross reference target is a R=
efEntry, =0A# output CiteRefEntry-style references.=0Asgml('<XREF>', sub {=
=0A	my $id;=0A=0A	$id =3D $_[0]->attribute('LINKEND')->value;=0A=0A	my $man=
ref =3D $Refs->get("refentry:$id");=0A	if(!defined $manref) {=0A		$blank_xr=
efs++ if $write_manpages;=0A		man_output "[XRef auf $id]";        # L10N=0A=
		return;=0A	}=0A=0A	# Limited ENDTERM support.=0A	if(defined $_[0]->attrib=
ute('ENDTERM')->value) {=0A		my $content =3D $Refs->get("title:$id") ||=0A	=
			$Refs->get("refentrytitle:$id");=0A		man_output $content, ' [';=0A	}=0A=
=0A	# This also displays the XREFLABEL (as bold)...=0A	# It's not worth the=
 bother to fix it though, there=0A	# are better tools for this.=0A	my ($tit=
le, $sect) =3D ($manref =3D~ /(.*)(\(.*\))/);=0A	bold_on();=0A	man_output $=
title;=0A	font_off();=0A	man_output $sect;=0A=0A	if(defined $_[0]->attribut=
e('ENDTERM')->value) {=0A		man_output ']';=0A	}=0A});=0A=0A# Anchor=0A=0A=
=0A########################################################################=
=0A#=0A# SDATA =0A#=0A#####################################################=
###################=0A=0Aman_sgml('|[lt    ]|', '<');=0Aman_sgml('|[gt    ]=
|', '>');=0Aman_sgml('|[amp   ]|', '&');=0A=0Aman_sgml('|[ndash ]|', '\(en'=
);=0Aman_sgml('|[mdash ]|', '\(em');=0A=0Asgml('sdata',sub { =0A	man_output=
 "|[", $_[0], "]|";=0A	warn "Warning: unrecognized SDATA: please add defini=
tion to docbook2man-spec.pl\n";   # L10N=0A});=0A=0A#=0A# Default handlers =
(uncomment these if needed).  Right now, these are set=0A# up to gag on any=
 unrecognised elements, sdata, processing-instructions,=0A# or entities.=0A=
#=0A# sgml('start_element',sub { die "Unknown element: " . $_[0]->name; });=
  # L10N=0A# sgml('end_element','');=0A=0A# This is for weeding out and esc=
aping certain characters.=0A# This looks like it's inefficient since it's d=
one on every line, but=0A# in reality, SGMLSpm and sgmlspl parsing ESIS tak=
es _much_ longer.=0A=0Asgml('cdata', sub=0A{ =0A	if(!$write_manpages) { ret=
urn; }=0A	elsif($raw_cdata) { output $_[0]; return; }=0A=0A	if($separator e=
q 'full') {=0A		output "\n" unless $newline_last++;=0A		output ".PP\n";=0A	=
	$separator =3D '';=0A	}=0A	=0A	# Escape backslashes=0A	$_[0] =3D~ s/\\/\\\=
\/g;=0A=0A	# In non-'pre'-type elements:=0A	if(!$nocollapse_whitespace) {=
=0A		# Change tabs to spaces=0A		$_[0] =3D~ tr/\t / /s;=0A=0A		# Do not all=
ow indents at beginning of line=0A		# groff chokes on that.=0A		if($newline=
_last) { =0A			$_[0] =3D~ s/^ //;=0A=0A			# If the line is all blank, don't=
 do anything.=0A			if($_[0] eq '') { return; }=0A			=0A			$_[0] =3D~ s/^\./=
\\\&\./;=0A	=0A			# Argh... roff doesn't like ' for some unknown reason =0A=
			$_[0] =3D~ s/^\'/\\\&\'/;=0A		}=0A	}=0A=0A	$newline_last =3D 0;=0A=0A	ou=
tput $_[0];=0A});=0A=0A=0A# When in whitespace-collapsing mode, we disallow=
 consecutive newlines.=0A=0Asgml('re', sub=0A{=0A	if($nocollapse_whitespace=
 || !$newline_last) {=0A		output "\n";=0A	}=0A=0A	$newline_last =3D 1;=0A})=
;=0A=0Asgml('pi', sub {});=0Asgml('entity',sub { die "Unknown external enti=
ty: " . $_[0]->name; });  # L10N=0Asgml('start_subdoc',sub { die "Unknown s=
ubdoc entity: " . $_[0]->name; });# L10N=0Asgml('end_subdoc',sub{});=0Asgml=
('conforming',sub{});=0A=0A1;=0A=0A
--TakKZr9L6Hm6aLOc--

--raC6veAxrt5nqIoY
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQFAxB+7RsxcY/MYpWoRAosgAKCt5acfPcH8ARDVtoeUNh/R7aAeKwCgpdYr
fBA142OQSOxV3/bMC5qGY44=
=oMHd
-----END PGP SIGNATURE-----

--raC6veAxrt5nqIoY--