Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

roffitall's TOC generation broken #11739

Closed
p5pRT opened this issue Nov 8, 2011 · 10 comments
Closed

roffitall's TOC generation broken #11739

p5pRT opened this issue Nov 8, 2011 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 8, 2011

Migrated from rt.perl.org#103202 (status was 'resolved')

Searchable as RT103202$

@p5pRT
Copy link
Author

p5pRT commented Nov 8, 2011

From @nwc10

Created by @nwc10

In the words of perlutil.pod,

  The C<roffitall> utility is not installed on your system but lives in
  the F<pod/> directory of your Perl source kit; it converts all the
  documentation from the distribution to F<*roff> format, and produces a
  typeset PostScript or text file of the whole lot.

Its table of contents generation has been broken for almost 4 years, and
no-one has noticed. Specifically, since commit 40dcca8,
"Upgrade to podlators 2.0.6", only the headings of the first Pod document
(perl.pod) appear in the generated table of contents. And for over a year,
since commit ff906f8, "Global executable bit cleanup", TOC
generation has been completely stuffed, as pod/roffitall expects to run
./rofftoc, but rofftoc is now -x

Reversing part of the change restores the TOC generation​:

Inline Patch
diff --git a/cpan/podlators/lib/Pod/Man.pm b/cpan/podlators/lib/Pod/Man.pm
index 96f3fcc..5b86776 100644
--- a/cpan/podlators/lib/Pod/Man.pm
+++ b/cpan/podlators/lib/Pod/Man.pm
@@ -1391,19 +1391,15 @@ sub preamble_template {
 .\" If the F register is turned on, we'll generate index entries on stderr for
 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
 .\" entries marked with X<> in POD.  Of course, you'll have to process the
 .\" output yourself in some meaningful fashion.
-.ie \nF \{\
+.if \nF \{\
 .    de IX
 .    tm Index:\\$1\t\\n%\t"\\$2"
 ..
 .    nr % 0
 .    rr F
 .\}
-.el \{\
-.    de IX
-..
-.\}
 ----END OF PREAMBLE----
 
     if ($accents) {
         $preamble .= <<'----END OF PREAMBLE----'
diff --git a/pod/rofftoc b/pod/rofftoc
old mode 100644 new mode 100755

However, this will introduce a regression. The change is described as​:

2007-11-28 Russ Allbery <rra@​stanford.edu>

  * VERSION​: podlators 2.0.6 released.

  * lib/Pod/Man.pm (preamble_template)​: Define the IX macro to empty
  rather than leaving it undefined when indexing is not requested to
  eliminate warnings when groff warnings are enabled.

[snip].

As best I can work out from TFM, the above code written to the start of each
Perl manpage's source does the following​:

* If register F is set, then the if block (re)defines the macro IX to output
  index information, and clears register F.
* podlators 2.0.6 added an else block that (re)defines the macro IX to do
  nothing.

roffitall runs roff with a command line flag to set the F register, then
collects and processes this information to generate the TOC, to get the
page correct numbers for heading (etc) as formatted by roff.

The problem comes when one attempts to render 2 or more man pages in one go,
with the F register. The first man page defines IX correctly, but clears F.
Without the else block, subsequent pages don't change IX, and continue to
output page numbers to stderr. With the else block, subsequent pages run the
same code, but now as F is not defined, they redefine IX to do nothing.

I'm not sure what the right solution is. From scanning TFM, there doesn't
look to be a roff equivalent of C's #ifdef, so it doesn't look like it's
possible to write a preamble that never *re*defines IX.

I don't know why the preamble clears the F register. That roff code to set
IX seems to date back commit cb1a09d, back in December 1995,
("This is patch.2b1g to perl5.002beta1."), which added the first version of
pod/roffitall, and changed pod2man.PL to add the roff code to the preamble
of each perl man page it generated.

It would be nice to fix this, as roff generates very pleasant typeset output.
[I guess I'm not a fan of Computer Modern.]

Nicholas Clark

Perl Info

Flags:
    category=utilities
    severity=low

Site configuration information for perl 5.15.4:

Configured by nick at Tue Nov  8 12:30:34 GMT 2011.

Summary of my perl5 (revision 5 version 15 subversion 4) configuration:
  Commit id: 387df3811e7dc9ad3b27895d08c771375f20fb9a
  Platform:
    osname=darwin, osvers=10.8.0, archname=darwin-2level
    uname='darwin mouse-mill.local 10.8.0 darwin kernel version 10.8.0: tue jun 7 16:33:36 pdt 2011; root:xnu-1504.15.3~1release_i386 i386 '
    config_args='-Dusedevel=y -Dcc=ccache gcc -Dld=gcc -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@ccl4.org -Dperladmin=nick@ccl4.org -Dinc_version_list=  -Dinc_version_list_init=0 -Dstatic_ext=Fcntl -DDEBUGGING -Doptimize=-g -Uusethreads -Uuse64bitall -Uuselongdouble -Uusemymalloc -Duseperlio -Dprefix=~/Sandpit/snap5.9.x-v5.15.4-185-g387df38-i -Dinstallman1dir=none -Dinstallman3dir=none -Dusevendorprefix -Dvendorprefix=~/Sandpit/vendor -Uuserelocatableinc -Ud_dosuid -Uuseshrplib -de -Accccflags=-fcatch-undefined-behavior -Accflags=-DNO_MATHOMS -Umad'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='ccache gcc', ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp -DNO_MATHOMS -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/opt/local/include',
    optimize='-g',
    cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-precomp -DNO_MATHOMS -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/opt/local/include'
    ccversion='', gccversion='4.2.1 (Apple Inc. build 5666) (dot 3)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector -L/usr/local/lib -L/opt/local/lib'
    libpth=/usr/local/lib /opt/local/lib /usr/lib
    libs=-lgdbm -ldbm -ldl -lm -lutil -lc
    perllibs=-ldl -lm -lutil -lc
    libc=, so=dylib, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib -L/opt/local/lib -fstack-protector'

Locally applied patches:
    


@INC for perl 5.15.4:
    /Users/nick/Sandpit/snap5.9.x-v5.15.4-185-g387df38-i/lib/perl5/site_perl/5.15.4/darwin-2level
    /Users/nick/Sandpit/snap5.9.x-v5.15.4-185-g387df38-i/lib/perl5/site_perl/5.15.4
    /Users/nick/Sandpit/vendor/lib/perl5/vendor_perl/5.15.4/darwin-2level
    /Users/nick/Sandpit/vendor/lib/perl5/vendor_perl/5.15.4
    /Users/nick/Sandpit/snap5.9.x-v5.15.4-185-g387df38-i/lib/perl5/5.15.4/darwin-2level
    /Users/nick/Sandpit/snap5.9.x-v5.15.4-185-g387df38-i/lib/perl5/5.15.4
    .


Environment for perl 5.15.4:
    DYLD_LIBRARY_PATH (unset)
    HOME=/Users/nick
    LANG=en_GB.ISO8859-1
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/opt/local/bin:/opt/local/sbin:/Users/nick/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/local/sbin:/sbin:/usr/sbin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 9, 2011

From tchrist@perl.com

# New Ticket Created by Nicholas Clark

I'm going to quote most of this to keep the context. It's really esoteric.

Congratulations on your archaeological expedition, Nick; I'm sorry to have
caused you so much trouble. I should have done a better job explaining
what I was doing, because even I no longer recall most of it after 16 years.

I've cc'd Russ and Larry, because they're the only other ones I can think
of who might know something about all this business. Rafael's name is on
the 5.004 version of roffitall, but I think Russ last looked at it all.

In the words of perlutil.pod,

The C\<roffitall> utility is not installed on your system but lives in
the F\<pod/> directory of your Perl source kit; it converts all the
documentation from the distribution to F\<\*roff> format\, and produces a
typeset PostScript or text file of the whole lot\.

Its table of contents generation has been broken for almost 4 years, and
no-one has noticed. Specifically, since commit 40dcca8,
"Upgrade to podlators 2.0.6", only the headings of the first Pod document
(perl.pod) appear in the generated table of contents. And for over a year,
since commit ff906f8, "Global executable bit cleanup", TOC
generation has been completely stuffed, as pod/roffitall expects to run
./rofftoc, but rofftoc is now -x

Reversing part of the change restores the TOC generation​:

diff --git a/cpan/podlators/lib/Pod/Man.pm b/cpan/podlators/lib/Pod/Man.pm
index 96f3fcc..5b86776 100644
--- a/cpan/podlators/lib/Pod/Man.pm
+++ b/cpan/podlators/lib/Pod/Man.pm
@​@​ -1391,19 +1391,15 @​@​ sub preamble_template {
.\" If the F register is turned on, we'll generate index entries on std<SNIP>
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
-.ie \nF \{\
+.if \nF \{\
. de IX
. tm Index​:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
-.el \{\
-. de IX
-..
-.\}
----END OF PREAMBLE----

 if \($accents\) \{
     $preamble \.= \<\<'\-\-\-\-END OF PREAMBLE\-\-\-\-'

diff --git a/pod/rofftoc b/pod/rofftoc
old mode 100644
new mode 100755

However, this will introduce a regression. The change is described as​:

2007-11-28 Russ Allbery <rra@​stanford.edu>

\* VERSION&#8203;: podlators 2\.0\.6 released\.
\* lib/Pod/Man\.pm \(preamble\_template\)&#8203;: Define the IX macro to empty
rather than leaving it undefined when indexing is not requested to
eliminate warnings when groff warnings are enabled\.

[snip].

As best I can work out from TFM, the above code written to the start of each
Perl manpage's source does the following​:

* If register F is set, then the if block (re)defines the macro IX to output

Actually, if it has been accessed. See below.

index information, and clears register F.

Actually, it removes the register. See below.

* podlators 2.0.6 added an else block that (re)defines the macro IX to do
nothing.

roffitall runs roff with a command line flag to set the F register, then
collects and processes this information to generate the TOC, to get the
page correct numbers for heading (etc) as formatted by roff.

The problem comes when one attempts to render 2 or more man pages in one go,
with the F register. The first man page defines IX correctly, but clears F.
Without the else block, subsequent pages don't change IX, and continue to
output page numbers to stderr. With the else block, subsequent pages run the
same code, but now as F is not defined, they redefine IX to do nothing.

I'm not sure what the right solution is. From scanning TFM, there doesn't
look to be a roff equivalent of C's #ifdef, so it doesn't look like it's
possible to write a preamble that never *re*defines IX.

What you can do is ask whether a certain number register has ever been accessed.
I *believe* that these set registers C and D to 0 not if they are "false" as it
would appear, but rather if they have *never been accessed* before​:

  .if !rD .nr D 0
  .if !rC .nr C 0

That's because apart from a bit of numeric handling in certain kinds of
expressions (and this isn't one of those), troff is really a string macro-
processing language, so more like cpp than like C proper. So those aren't
numeric expressions, even though they look like it.

I don't know why the preamble clears the F register.

Actually, it doesn't "clear" it, per se. That would be

  .nr F 0

if you think like a C programmer with an integer variable. Instead it's
more like cpp's #undef F, because it really removes the register altogether​:

  .rr F

That makes a subsequent nF test come up false for never having
been accessed.

I'm not convinced I understand why the else block became necessary.
Did groff start getting mouthy at us after all these years?

That roff code to set
IX seems to date back commit cb1a09d, back in December 1995,
("This is patch.2b1g to perl5.002beta1."), which added the first version of
pod/roffitall, and changed pod2man.PL to add the roff code to the preamble
of each perl man page it generated.

Oops. From perlhist​:

  Tom 5.002b1g 1995-Dec-21 Doc release.

So I'm pretty sure you have me to blame for almost all of this. I wish I
had less brain rot, because I really remember almost none of it, and it was
only 16 years ago. We've always known how to put comments in troff, but we
seem almost never to have done so. I'm kicking myself for that now.

What was going on is that I created a way to troff the entire docset as
one contiguous stream, including a table of contents and index, so that
it could be printed and bound into one book. You've uncovered most of
the pieces of the puzzle, but as you note, there is still stuff that
isn't clearly understood.

As to why the F register gets cleared, the only thing that now comes to
mind is some strange impulse toward good housekeeping. I'm not sure
that I believe that though, because I'm not usually so tidy. But I can't
find anything else that's using it. By removing the register altogether,
it should count as never having been accessed in conditionals, so I don't
understand the new else block. Is it that groff now causes warnings in
a situation when before it did not?

Notice roffitall also sets the C and D registers, but nothing in the
generated roff *seems* to use them. That's because those are used in the
tmac.an macros themselves​:

  .\" -rC1 => number pages continuously, rather than start each at 1
  .\" -rD1 => double-sided printing, ie different odd and even page footers
  .\" -rPnnn => number first page nnn
  .\" -rXnnn => number pages after nnn as nnna, nnnb, nnnc, ...

The D register's use for *D*ouble-sided printing makes sense when you understand
this is supposed to be made into a book. The C register for making troff's %
pagenum register (whence Perl's $%) operate in *C*ontinuous mode, which was
needed for roffing them together to make sure the page numbers don't reset an
the next TH. This really should be documented in roffitall, and it isn't.

I cannot swear that this is why, but I *think* I grabbed the F register because
it was for processing everything the *F*irst time around, when you're just
generating the index and the toc. But it's also possible that I was just
using (almost) the next one in the series, not that it had some particular
F* mnemonic -- or at least not a particularly memorable one, which rather
defeats the purpose, now doesn't it? :(

But F for First-time-through sounds good enough to use from now on, even if it
wasn't why I chose it before. It might have been, but this much later I'm just
making it up. This often works to reproduce the original since it's the same
mind at work, but it's more like finding things only because they're where it
makes sense for you to have put them, not because you actually remember having
done so.

It would be nice to fix this, as roff generates very pleasant typeset output.
[I guess I'm not a fan of Computer Modern.]

Indeed so. The other translators have never managed to do as attractive a
job at typesetting as the original did, Russ kept all of that magic stuff
when he did his rewrite. Some of the magic was there from Larry's version,
but I put a bunch of special smarts in because of my experience with Camel2,
which thought written in pod was set in troff. So troff was fresh in my
mind at the time. It certainly isn't any more, though.

These days with Camel4 the pod turns into DocBook XML, clearly a deficient
format since it has no mysterious one-letter registers for us to to ponder
the purpose of decades later. :-|

--tom

@p5pRT
Copy link
Author

p5pRT commented Nov 9, 2011

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 9, 2011

From rra@stanford.edu

Tom Christiansen <tchrist@​perl.com> writes​:

I'm going to quote most of this to keep the context. It's really esoteric.

Congratulations on your archaeological expedition, Nick; I'm sorry to
have caused you so much trouble. I should have done a better job
explaining what I was doing, because even I no longer recall most of it
after 16 years.

Thank you *very* much for your thorough investigation of this bug, Nick.
It's exceptionally helpful.

I'm not convinced I understand why the else block became necessary.
Did groff start getting mouthy at us after all these years?

Sort of. I believe what happened is that Debian asked groff to get mouthy
and then this showed up. And because I didn't understand the original
code, I didn't realize that maintaining the lack of an else block was
important for processing multiple documents at once.

Debian, in an effort to clean up problems with man pages and proactively
detect errors, started scanning all man pages included in Debian packages
with man --warnings, which enables warnings in groff. One of those
warnings is using a macro that was never defined. That's caught some real
problems (typos in macro names, for instance), but also was triggering on
.IX, which resulted in Debian Lintian complaints for lots of Perl modules
packaged for Debian, which was making life miserable for the Perl
packaging group.

As to why the F register gets cleared, the only thing that now comes to
mind is some strange impulse toward good housekeeping.

If we just remove the line that removes the register, will that work?
Nick, since you're already set up with the tools to attempt this, could
you give that a try and see if that works? There was a mention in the
original message about that causing a duplicate definition of .IX; does
that cause problems, or another warning, or is that quietly allowed?
That's a corner of *roff that I don't know off the top of my head.

Failing that, we could undefine .IX before defining it, or we could set or
use some other register as a marker to not trigger the else block on
subsequent times through the preamble.

--
Russ Allbery (rra@​stanford.edu) <http​://www.eyrie.org/~eagle/>

@p5pRT
Copy link
Author

p5pRT commented Nov 9, 2011

From @nwc10

On Tue, Nov 08, 2011 at 04​:53​:09PM -0800, Russ Allbery wrote​:

Tom Christiansen <tchrist@​perl.com> writes​:

I'm going to quote most of this to keep the context. It's really esoteric.

Congratulations on your archaeological expedition, Nick; I'm sorry to
have caused you so much trouble. I should have done a better job
explaining what I was doing, because even I no longer recall most of it
after 16 years.

Thank you *very* much for your thorough investigation of this bug, Nick.
It's exceptionally helpful.

Um, I'm feeling somewhat lost for words. I just kept digging into behaviour
and skimming man pages (etc) until I couldn't get any further.

At least, not any further without attempting "teach yourself *roff", because
the next question to answer seemed to be "so, why is the F register cleared?"
[or as I now learn from Tom's reply, more like "unset"] "Does it matter if
it isn't?"

I'm not convinced I understand why the else block became necessary.
Did groff start getting mouthy at us after all these years?

Sort of. I believe what happened is that Debian asked groff to get mouthy
and then this showed up. And because I didn't understand the original
code, I didn't realize that maintaining the lack of an else block was
important for processing multiple documents at once.

It's really obscure. I wouldn't have noticed it except that I've been
tidying up pod/buildtoc, and found a comment from me-of-8-years-ago about
roffitall, so started to look at roffitall. And another digression started...

As to why the F register gets cleared, the only thing that now comes to
mind is some strange impulse toward good housekeeping.

If we just remove the line that removes the register, will that work?

I did this​:

$ git diff

Inline Patch
diff --git a/cpan/podlators/lib/Pod/Man.pm b/cpan/podlators/lib/Pod/Man.pm
index 96f3fcc..4b19cb2 100644
--- a/cpan/podlators/lib/Pod/Man.pm
+++ b/cpan/podlators/lib/Pod/Man.pm
@@ -1397,7 +1397,6 @@ sub preamble_template {
 .    tm Index:\\$1\t\\n%\t"\\$2"
 ..
 .    nr % 0
-.    rr F
 .\}
 .el \{\
 .    de IX
diff --git a/pod/rofftoc b/pod/rofftoc
old mode 100644 new mode 100755

and everything seems to work.

(didn't spot any warnings while running make install, cursory test of 1
man page still looks good, and *now* PerlTOC.ps has the right contents)

Nick, since you're already set up with the tools to attempt this, could
you give that a try and see if that works? There was a mention in the

It doesn't seem to need much "set up." Both a Mac laptop and an Ubuntu
desktop already had sufficient developer toolchain installed to view it,
it seems simply as a side effect of historical things I've installed when
building stuff on them.

original message about that causing a duplicate definition of .IX; does
that cause problems, or another warning, or is that quietly allowed?
That's a corner of *roff that I don't know off the top of my head.

I don't know *roff at all.

(Other than roughly "what it's used for". It's about the same as my knowledge
of Sparc assembler)

The manual suggests that there's no distinction between defining a macro and
redefining it. I've no idea about whether it's allowed to warn.

The irony is that my understanding of C is that

* a compiler is allowed to issue as many diagnostics as it feels like for
  conformant code. There's no rule about compilers "should be seen and not
  heard" *
* the C pre-processor is allowed to ignore the redefinition of a macro
  [and at least one AIX compiler does just this, which can really confuse
  open source projects which aren't defensively portable, to the point of
  them assuming that the bug is not their own, when actually it is.]

It was very fortunate that my bisect run turned up a commit with a small
change, and that that had an obvious looking culprit.
Everything in the bug report was gleaned from trying to apply the contents
of man pages and manuals to things I was running.

Failing that, we could undefine .IX before defining it, or we could set or
use some other register as a marker to not trigger the else block on
subsequent times through the preamble.

Not clearing F seems to have no issues. But I don't know *roff, so I don't
know how to search the *roff (or more tellingly, the Perl code that
generates it) it to be sure that there are no hidden references or
uses of it, in particular in *roff that Pod​::Man could generate, but didn't
here.

Nicholas Clark

* and garrulous compilers make me think of jokes such as
  http​://linuxgazette.net/173/misc/grebler/your-mouse-has-moved.png
  (not actually appropriate, as the styling predates USB support), and
  the love Windows has of telling me every time the *same* USB mouse is
  plugged or unplugged.

@p5pRT
Copy link
Author

p5pRT commented Nov 26, 2011

From @nwc10

On Wed, Nov 09, 2011 at 09​:59​:13PM +0000, Nicholas Clark wrote​:

On Tue, Nov 08, 2011 at 04​:53​:09PM -0800, Russ Allbery wrote​:

If we just remove the line that removes the register, will that work?

No.

I did this​:

$ git diff
diff --git a/cpan/podlators/lib/Pod/Man.pm b/cpan/podlators/lib/Pod/Man.pm
index 96f3fcc..4b19cb2 100644
--- a/cpan/podlators/lib/Pod/Man.pm
+++ b/cpan/podlators/lib/Pod/Man.pm
@​@​ -1397,7 +1397,6 @​@​ sub preamble_template {
. tm Index​:\\$1\t\\n%\t"\\$2"
..
. nr % 0
-. rr F
.\}
.el \{\
. de IX
diff --git a/pod/rofftoc b/pod/rofftoc
old mode 100644
new mode 100755

and everything seems to work.

(didn't spot any warnings while running make install, cursory test of 1
man page still looks good, and *now* PerlTOC.ps has the right contents)

But the page numbers in the TOC reset for every man page.
Which I didn't notice first time.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Nov 28, 2011

From rra@stanford.edu

Nicholas Clark <nick@​ccl4.org> writes​:

On Wed, Nov 09, 2011 at 09​:59​:13PM +0000, Nicholas Clark wrote​:

--- a/cpan/podlators/lib/Pod/Man.pm
+++ b/cpan/podlators/lib/Pod/Man.pm
@​@​ -1397,7 +1397,6 @​@​ sub preamble_template {
. tm Index​:\\$1\t\\n%\t"\\$2"
..
. nr % 0
-. rr F
.\}
.el \{\
. de IX

But the page numbers in the TOC reset for every man page.
Which I didn't notice first time.

Ah, because we reset the % register on the start of each man page using
that code.

I wonder if something like​:

.ie \nF \{\
. de IX
. tm Index​:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. nr I 1
.\}
.if !\nI \{\
. de IX
..
.\}

would work. I'm not sure which number registers are already in use and
which we can safely use.

--
Russ Allbery (rra@​stanford.edu) <http​://www.eyrie.org/~eagle/>

@p5pRT
Copy link
Author

p5pRT commented May 26, 2012

From rra@stanford.edu

Nicholas Clark <nick@​ccl4.org> writes​:

I did this​:

$ git diff
diff --git a/cpan/podlators/lib/Pod/Man.pm b/cpan/podlators/lib/Pod/Man.pm
index 96f3fcc..4b19cb2 100644
--- a/cpan/podlators/lib/Pod/Man.pm
+++ b/cpan/podlators/lib/Pod/Man.pm
@​@​ -1397,7 +1397,6 @​@​ sub preamble_template {
. tm Index​:\\$1\t\\n%\t"\\$2"
..
. nr % 0
-. rr F
.\}
.el \{\
. de IX
diff --git a/pod/rofftoc b/pod/rofftoc
old mode 100644
new mode 100755

and everything seems to work.

(didn't spot any warnings while running make install, cursory test of 1
man page still looks good, and *now* PerlTOC.ps has the right contents)

But the page numbers in the TOC reset for every man page.
Which I didn't notice first time.

I finally got a chance to look at this in more detail, in combination with
another bug report about suppressing warnings from groff about undefined
registers. I decided to (somewhat arbitrarily) decide on a value of "2"
for the F register to mean to do indexing and to not reset the page
number. The resulting preamble section below appears to now work
properly​:

.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF​:(\n(.g==0)) \{
. if \nF \{
. de IX
. tm Index​:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF

(The rF logic is to suppress groff warnings.)

This will be in the next podlators release.

--
Russ Allbery (rra@​stanford.edu) <http​://www.eyrie.org/~eagle/>

@p5pRT
Copy link
Author

p5pRT commented May 26, 2012

From @cpansprout

On Sat May 26 13​:41​:11 2012, rra@​stanford.edu wrote​:

This will be in the next podlators release.

I’m marking this as resolved, seeing it is now a podlators problem, not
a perl problem.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented May 26, 2012

@cpansprout - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant