Hi Oliver,

On Wed Nov 13, 2024 at 8:44 PM CET, Oliver Corff wrote:
> [...]
> In me, adding a footer with .fo 'arg left'arg center'arg right' works as
> expected, with the blatantly obvious limitation that the elements of the
> footer should not contain line breaks.
>
> However, I'd like to have information in two lines --- perhaps best to
> be imagined like a tbl with two rows and three columns:
>
> .TS
> center expand nospaces tab(|);
> l c r.
> Contact | Tax ID|Bank Account / IBAN
> me@org|12334|DE12123123450100
> .TE
>
> Since the letters I want to create never have more than one page, I
> could bypass the .fo mechanism. Should I indeed use a table which I
> somehow push to the bottom of the page, or should I construct three pic
> boxes with text in them? Or is there a much better way? What is your
> best practice?

The way headers and footers are constructed in plain troff -- and how
I would expect me to work internally -- is by using vertical traps.

A vertical trap is a macro which is executed each time the text reaches
a particular vertical position. It is set using the .wh ("where")
request. Quoting groff(7):
  .wh VPOS NAME
      Plant macro NAME as page location trap at VPOS (default
      scaling unit v), removing any visible trap already there.

VPOS is relative to the top if positive and to the bottom of the page
if negative. Thus, writing:
  .wh -2c FOOTER

will set a vertical trap located 2 cm above the bottom of the page,
executing the macro FOOTER each time the text baseline would reach
such a position.

Note that this works correctly even when you break the page manually
with .bp; you can imagine a manual page break as 'scrolling through'
the remaining vertical space, triggering any traps it runs into.

A complete example might look like this:
  .ev FOOTER  \" configure new environment FOOTER:
  . evc 0     \" copy default environment's properties
  .ev
  .de FOOTER  \" define footer
  . ev FOOTER \" switch to environment FOOTER
  . sp
  . tl 'Contact'Tax ID'Bank account / IBAN'
  . tl 'me@org'12334'DE12123123450100'
  . bp
  . ev        \" switch back to default environment
  ..
  .wh -2c FOOTER \" set footer trap

Notice the .ev request, which switches to a different troff
environment (named `FOOTER`) for the footer's duration. This saves
any partially filled text line so that the main text can continue
on the next page (after the .bp request) without any line breaks or
interruptions.

Because each environment maintains its text properties separately,
which includes having its own page dimensions settings, we switch to
it at the beginning to copy the default environment's (named `0`)
properties.

Note that a vertical trap might be sprung a bit later than at the
exact position specified depending on how the text grid looks, which
may cause the footer to move slightly from page to page. This can be
remedied by replacing the .sp line with something like this:
  .sp |(\n[.p]u - 2c + 1v)

which does the same thing, except relative to the page length.
(Someone more knowledgable might prove me to be wrong about some of
this, though. Looking at you, Branden ;)

Hope this helps. You can find more information here:
  https://www.gnu.org/software/groff/manual/groff.html#Traps
  https://www.gnu.org/software/groff/manual/groff.html#Environments
... and elsewhere in the linked texinfo manual.

~ onf

Reply via email to