Ack! I slightly broke the cross reference section numbers in my last
set of cleanups (so they came out empty). Here is a revised patch;
sorry for the duplication...
- Thomas
> I've been working some more on the perl-based man page utility at
>
> http://shell.ipoline.com/~elmert/hacks/docbook2X/
>
> Here are some patches (on the 1.17 release, the latest) which
> incorporate the following changes:
>
> o ID attributes on REFENTRY and REFENTRYTITLE are used to develop
> cross reference information, as Norm Walsh indicated he would expect
> the behavior to be. The original XREFLABEL functionality is also
> supported, so either style will work.
>
> o The section number for the man page output is determined in a
> subroutine ManPageSect(), since it is called from several places.
>
> o The output file name and citation name are determined in a
> subroutine FileInfo(), again since it is called from several places.
>
> o A new switch, --blockformat, is defined to specify that the SYNOPSIS
> should not be folded into a single line, but rather kept as a verbatim
> block. This behavior was already invoked if one had explicitly coded
> FORMAT attributes into the SYNOPSIS header, but now you don't have to
> do that if you specify the switch.
>
> o Cross references are resolved using both the LINKEND and ENDTERM
> attributes on the XREF tag. ENDTERM takes precedence, as in Norm's
> style sheets.
>
> o manpage.log is written to show changes to the cross-reference
> database. We might want to make this an option.
>
> o perldoc info has been updated to show command line options.
>
> o My last patches played around with trying to automatically determine
> the appropriate man page section number by looking for an APPLICATION
> tag in the REFENTRYNAME block. I've simplified the options, making it
> easier to just specify which section the doc should be in. The code
> still looks for the APPLICATION tag per Steve's fixes on my patches,
> but there may need to be another patch to get the options and code
> just right.
>
> This utility now produces man pages from PostgreSQL sgml docs of
> sufficient quality to replace our old hand-written pages (once I
> understand more about nsgmls; will ask on a separate thread).
--
Thomas Lockhart lockhart@alumni.caltech.edu
South Pasadena, California*** docbook2man-spec.pl.orig Fri Jul 30 21:57:12 1999
--- docbook2man-spec.pl Sat Aug 7 16:05:20 1999
***************
*** 9,14 ****
--- 9,38 ----
nsgmls some-docbook-document.sgml | sgmlspl docbook2man-spec.pl
+ =head1 OPTIONS
+
+ =over 4
+
+ =item --section <label>
+
+ Use the specified manpage section number,
+ if not specified in <MANVOLNUM>. Default is one (1).
+
+ =item --date <string>
+
+ Use the specified date in the .TH header.
+ Default is today.
+
+ =item --lowercase | --preserve-case
+
+ Convert output file names and cross-references to lower case.
+ Default is to convert to upper case.
+
+ =item --blockformat
+
+ Retain formatting of SYNOPSIS section from source file.
+ Default is to fold into a single line.
+
=head1 DESCRIPTION
This is a sgmlspl spec file that produces Unix-style
***************
*** 60,65 ****
--- 84,90 ----
use SGMLS::Output; # Use stack-based output.
use SGMLS::Refs;
+
########################################################################
# SGMLSPL script produced automatically by the script sgmlspl.pl
#
***************
*** 67,77 ****
# Edited by: me :)
########################################################################
$write_manpages = 0;
$blank_xrefs = 0;
$default_sect = "1";
! $lowercase_names = 0;
$default_date = `date "+%d %B %Y"`;
while (@ARGV) {
--- 92,103 ----
# Edited by: me :)
########################################################################
+
$write_manpages = 0;
$blank_xrefs = 0;
$default_sect = "1";
! $app_sect = "1";
$default_date = `date "+%d %B %Y"`;
while (@ARGV) {
***************
*** 81,99 ****
$app_sect = $default_sect;
} elsif ($arg eq "--appsection") {
$app_sect = shift @ARGV || die "$arg requires an argument\n";
- } elsif ($arg eq "--defsection") {
- $default_sect = shift @ARGV || die "$arg requires an argument\n";
} elsif ($arg eq "--date") {
$default_date = shift @ARGV || die "$arg requires an argument\n";
} elsif ($arg eq "--lowercase") {
$lowercase_names = 1;
} elsif ($arg eq "--preserve-case") {
$lowercase_names = 0;
} elsif ($arg eq "--help") {
! print "Usage: $0 [ --section <label> ] [ --appsection <label> ] [ --defsection <label> ] [ --date <string> ]
[--lowercase | --preserve-case ]\n";
exit;
} else {
! die "unrecognized switch $arg\n";
}
}
--- 107,130 ----
$app_sect = $default_sect;
} elsif ($arg eq "--appsection") {
$app_sect = shift @ARGV || die "$arg requires an argument\n";
} elsif ($arg eq "--date") {
$default_date = shift @ARGV || die "$arg requires an argument\n";
} elsif ($arg eq "--lowercase") {
$lowercase_names = 1;
} elsif ($arg eq "--preserve-case") {
$lowercase_names = 0;
+ } elsif ($arg eq "--blockformat") {
+ $blockformat = 1;
} elsif ($arg eq "--help") {
! print "Usage: $0",
! " [ --section <label> ]",
! " [ --date <string> ]",
! " [ --lowercase | --preserve-case ]",
! " [ --blockformat ]",
! "\n";
exit;
} else {
! die "unrecognized switch $arg; try $0 --help\n";
}
}
***************
*** 104,121 ****
# Links file
open(LINKSFILE, ">manpage.links");
! $Refs = new SGMLS::Refs("manpage.refs");
});
sgml('end', sub {
close(LINKSFILE);
if($blank_xrefs) {
print STDERR "Warning: output contains unresolved XRefs\n";
}
});
-
-
########################################################################
#
# Output helpers
--- 135,156 ----
# Links file
open(LINKSFILE, ">manpage.links");
! $Refs = new SGMLS::Refs("manpage.refs", "manpage.log");
});
sgml('end', sub {
close(LINKSFILE);
+
+ # Explicitly invoke destructor,
+ # otherwise cache file may not get written!
+ # Thomas Lockhart, 1999-08-03, perl-5.004, RedHat5.2
+ undef $Refs;
+
if($blank_xrefs) {
print STDERR "Warning: output contains unresolved XRefs\n";
}
});
########################################################################
#
# Output helpers
***************
*** 134,149 ****
return $str;
}
! # Cleanup whitespace and convert to lower case unless disallowed.
! sub FileName
{
! my $str = StripString(shift);
$str = lc $str if ($lowercase_names);
$str =~ tr/ /_/;
! return $str;
}
# Our own version of sgml() and output() to allow simple string output
--- 169,210 ----
return $str;
}
! sub ManPageSect
! {
! my $app_sect = shift @_;
! my $sect, $sectref;
!
! $sect = $manpage_sect || $app_sect;
! $sect = $default_sect if ($sect =~ m#^\w*$#);
!
! # The 'package name' part of the section should
! # not be used when citing it.
! $sectref = $1 if ($sect =~ /([0-9]*)/);
! $sectref = $sect unless ($sectref);
!
! return ($sect, $sectref);
! }
!
! # Generate a good file name.
! # Cleanup whitespace and convert to lower case if allowed.
! sub FileInfo
{
! my ($title, $sect) = @_;
! my $section, $sectnum;
!
! my $str = StripString($title);
$str = lc $str if ($lowercase_names);
$str =~ tr/ /_/;
! ($section, $sectnum) = ManPageSect($sect);
! $sect = $section unless ($sect);
!
! my $name = "$str.$sect";
! my $citation = "$str($sectnum)";
!
! return ($name, $citation);
}
# Our own version of sgml() and output() to allow simple string output
***************
*** 195,202 ****
s/\\/\\\\/g;
s/"/\\\&"/g;
! # Change tabs to spaces
! tr/\t\n/ /;
# Trim whitespace from beginning and end.
s/^ +//;
--- 256,264 ----
s/\\/\\\\/g;
s/"/\\\&"/g;
! # Change tabs and newlines to spaces
! # The newlines will be swallowed later while trimming
! tr/[\t\n]/ /;
# Trim whitespace from beginning and end.
s/^ +//;
***************
*** 253,259 ****
}
-
########################################################################
#
# Manpage management
--- 315,320 ----
***************
*** 310,320 ****
});
sgml('</REFMETA>', sub {
! $manpage_title = FileName($manpage_title);
!
! my $sect = $manpage_sect || $_[0]->ext->{'app_sect'} || $default_sect;
! push_output('file', "$manpage_title.$sect");
output <<_END_BANNER;
.\\" This manpage has been automatically generated by docbook2man
--- 371,380 ----
});
sgml('</REFMETA>', sub {
! my ($sect, $sectref) = ManPageSect($_[0]->ext->{'app_sect'});
! my ($name, $citation) = FileInfo($manpage_title, $sect);
! push_output('file', "$name");
output <<_END_BANNER;
.\\" This manpage has been automatically generated by docbook2man
***************
*** 322,343 ****
.\\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
.\\" Please send any bug reports, improvements, comments, patches,
.\\" etc. to Steve Cheng <steve\@ggi-project.org>.
_END_BANNER
my $manpage_date = $_[0]->parent->ext->{'date'} || $default_date;
output '.TH "';
! # If the title is not mixed-case, convention says to
! # uppercase the whole title. (The canonical title is
! # lowercase.)
! if($manpage_title =~ /[A-Z]/) {
! output fold_string($manpage_title);
! } else {
! output uc(fold_string($manpage_title));
! }
!
! output '" "', fold_string($sect),
'" "', fold_string($manpage_date),
'" "', $manpage_misc,
'" "', $manpage_manual,
--- 382,399 ----
.\\" <http://shell.ipoline.com/~elmert/hacks/docbook2X/>
.\\" Please send any bug reports, improvements, comments, patches,
.\\" etc. to Steve Cheng <steve\@ggi-project.org>.
+ .\\" Patched 1999-08-03 by Thomas Lockhart <lockhart\@alumni.caltech.edu>
+ .\\" for the PostgreSQL RDBMS project (http://postgresql.org).
_END_BANNER
my $manpage_date = $_[0]->parent->ext->{'date'} || $default_date;
output '.TH "';
+ my $sectnum;
+ ($citation, $sectnum) = ($1, $2) if ($citation =~ m#(.*)\((.*)\)#);
+ output fold_string(uc "$citation");
! output '" "', fold_string($sectnum),
'" "', fold_string($manpage_date),
'" "', $manpage_misc,
'" "', $manpage_manual,
***************
*** 346,368 ****
$newline_last = 1;
# References to this RefEntry.
! my $id = $_[0]->parent->attribute('ID')->value;
! if($id ne '') {
! # The 'package name' part of the section should
! # not be used when citing it.
! my ($sectnum) = ($manpage_sect =~ /([0-9]*)/);
!
! if (defined($_[0]->parent->attribute('XREFLABEL'))) {
! local $label;
! $label = $_[0]->parent->attribute('XREFLABEL');
! if(! defined($label->value)) {
! $Refs->put("refentry:$id", "$manpage_title($sectnum)");
! } else {
! $Refs->put("refentry:$id",
! $label->value . "($sectnum)");
! }
! }
}
});
--- 402,422 ----
$newline_last = 1;
# References to this RefEntry.
! if (defined($_[0]->parent->attribute('ID'))
! && defined($_[0]->parent->attribute('ID')->value)) {
! my $id = $_[0]->parent->attribute('ID')->value;
! my ($name, $citation) = FileInfo($manpage_title, $sectref);
!
! $Refs->put(lc "refentry:$id", "$citation");
! }
!
! if (defined($_[0]->parent->attribute('XREFLABEL'))
! && defined($_[0]->parent->attribute('XREFLABEL')->value)) {
! my $label = $_[0]->parent->attribute('XREFLABEL')->value;
! ($name, $citation) = FileInfo($label, $sectref);
!
! $Refs->put(lc "refentry:$label", "$citation");
}
});
***************
*** 380,385 ****
--- 434,449 ----
$manpage_title = pop_output();
}
else { font_off(); }
+
+ if (defined($_[0]->attribute('ID'))
+ && defined($_[0]->attribute('ID')->value)) {
+ local $id = $_[0]->attribute('ID')->value;
+
+ my ($sect, $sectref) = ManPageSect($_[0]->ext->{'app_sect'});
+ my ($name, $citation) = FileInfo($manpage_title, $sectref);
+
+ $Refs->put(lc "refentry:$id", $citation);
+ }
});
sgml('<MANVOLNUM>', sub {
***************
*** 447,455 ****
#RefDescriptor
-
-
-
########################################################################
#
# SYNOPSIS section and synopses
--- 511,516 ----
***************
*** 485,491 ****
man_sgml('<VOID>', "(void);\n");
-
sub arg_start
{
# my $choice = $_[0]->attribute('CHOICE')->value;
--- 546,551 ----
***************
*** 570,575 ****
--- 630,644 ----
# We assume they want uppercase and a newline.
man_output '"', uc($title), "\"\n";
}
+
+ if (defined($_[0]->attribute('ID'))
+ && defined($_[0]->attribute('ID')->value)) {
+ local $id = $_[0]->attribute('ID')->value;
+ my ($sect, $sectref) = ManPageSect($_[0]->ext->{'app_sect'});
+ my ($name, $citation) = FileInfo($manpage_title, $sectref);
+
+ $Refs->put(lc "refentry:$id", $citation);
+ }
});
sgml('<ATTRIBUTION>', sub {
***************
*** 688,696 ****
sgml('</SYSTEMITEM>', \&font_off);
-
-
-
########################################################################
#
# Set italic on enclosed content
--- 757,762 ----
***************
*** 723,732 ****
sgml('<LINEANNOTATION>', \&italic_on); sgml('</LINEANNOTATION>', \&font_off);
-
-
-
-
########################################################################
#
# Other 'inline' elements
--- 789,794 ----
***************
*** 799,807 ****
# MEDIALABEL
-
-
-
########################################################################
#
# Paragraph and paragraph-like elements
--- 861,866 ----
***************
*** 835,843 ****
sgml('</INFORMALEXAMPLE>', \¶_end);
-
-
-
########################################################################
#
# Blocks using SS sections
--- 894,899 ----
***************
*** 887,893 ****
sgml('</HIGHLIGHTS>', \¶_end);
-
########################################################################
#
# Indented 'Block' elements
--- 943,948 ----
***************
*** 1005,1020 ****
sgml('</IMPORTANT>', \&admonition_end);
-
-
-
-
-
-
-
-
-
-
########################################################################
#
# Verbatim displays.
--- 1060,1065 ----
***************
*** 1043,1050 ****
sgml('</LITERALLAYOUT>', \&verbatim_end);
sgml('<SYNOPSIS>', sub {
! if($_[0]->attribute('FORMAT')->type eq 'NOTATION'
! and $_[0]->attribute('FORMAT')->value->name eq 'LINESPECIFIC') {
&verbatim_start;
} else {
$separator = '';
--- 1088,1103 ----
sgml('</LITERALLAYOUT>', \&verbatim_end);
sgml('<SYNOPSIS>', sub {
! if (defined($_[0]->attribute('FORMAT'))) {
! my $format = $_[0]->attribute('FORMAT');
! if($format->type eq 'NOTATION'
! and $format->value->name eq 'LINESPECIFIC') {
! &verbatim_start;
! } else {
! $separator = '';
! man_output "\n.sp\n";
! }
! } elsif ($blockformat) {
&verbatim_start;
} else {
$separator = '';
***************
*** 1053,1060 ****
});
sgml('</SYNOPSIS>', sub {
! if($_[0]->attribute('FORMAT')->type eq 'NOTATION'
! and $_[0]->attribute('FORMAT')->value->name eq 'LINESPECIFIC') {
&verbatim_end;
} else {
man_output "\n";
--- 1106,1122 ----
});
sgml('</SYNOPSIS>', sub {
! if (defined($_[0]->attribute('FORMAT'))) {
! my $format = $_[0]->attribute('FORMAT');
! if($format->type eq 'NOTATION'
! and $format->value->name eq 'LINESPECIFIC') {
! &verbatim_end;
! } else {
! man_output "\n";
! $_[0]->parent->ext->{'separator'} = 'full';
! $separator = 'full';
! }
! } elsif ($blockformat) {
&verbatim_end;
} else {
man_output "\n";
***************
*** 1064,1077 ****
});
-
-
-
-
-
-
-
-
########################################################################
#
# Lists
--- 1126,1131 ----
***************
*** 1174,1180 ****
});
-
########################################################################
#
# Linkage, cross references
--- 1228,1233 ----
***************
*** 1189,1196 ****
# If cross reference target is a RefEntry,
# output CiteRefEntry-style references.
sgml('<XREF>', sub {
! my $id = $_[0]->attribute('LINKEND')->value;
! my $manref = $Refs->get("refentry:$id");
if($manref) {
my ($title, $sect) = ($manref =~ /(.*)(\(.*\))/);
--- 1242,1253 ----
# If cross reference target is a RefEntry,
# output CiteRefEntry-style references.
sgml('<XREF>', sub {
! my $id;
!
! $id = $_[0]->attribute('LINKEND')->value;
! $id = $_[0]->attribute('ENDTERM')->value
! unless (!defined($_[0]->attribute('ENDTERM')));
! my $manref = $Refs->get(lc "refentry:$id");
if($manref) {
my ($title, $sect) = ($manref =~ /(.*)(\(.*\))/);
***************
*** 1205,1212 ****
});
# Anchor
-
-
########################################################################
--- 1262,1267 ----