On Sat Jan 18, 2025 at 6:32 PM CET, Walter Alejandro Iglesias wrote:
> [...] (Don't get me wrong, I cut off the rest of your
> explanation so the post doesn't get too long, as I plan to add another
> example below.)

That's a completely normal part of mailing list etiquette, no worries.

> > When using \Z in centered lines, the text
> >        actually becomes right justified.
> [...]
> > 
> > I doubt the behavior of \Z shown above is intended.
>
> This is what I still don't understand, "right justified" against what?

Well, it should be right justified against the right margin, which is
equivalent to line length + page offset + indent, i.e.
  (u; \n[.l] + \n[.o] + \n[.in])
  
> Run the next adaptation of your example, please, first with ".ad c" and
> then with ".ad n", and you'll see the last line is placed both times in
> the right margin, what I understand as right justifing.

Huh? Maybe I am just misunderstanding what you're trying to say...
  $ groff -Tutf8 << EOF | sed "s/ /'/g"
  .pl 1
  .ll 20
  .ad c
  One\h'4n'Two
  EOF
  '''''One''''Two

  $ groff -Tutf8 << EOF | sed "s/ /'/g"
  .pl 1
  .ll 20
  .ad n
  One\h'4n'Two
  EOF
  One''''Two

  $ groff -Tutf8 << EOF | sed "s/ /'/g"
  .pl 1
  .ll 20
  .ad b
  One\h'4n'Two
  EOF
  One''''Two

But if you meant the example with \Z, please re-read what I wrote
before, i.e. \Z somehow causes the text to be right justified when
centering is enabled. In other words, this is not a problem with
centering; you should use it without the \Z.

> .pl 40
> .ll 40
> .ad c
> v
> .br

  $ groff -Tutf8 | sed "s/ /'/g"
  '''''''''''''''''''v

  $ groff -Tutf8 | sed -E "s/ /'/g; s/v\$//" | tr -d '\n' | wc -m
  19

The v is centered as expected, padded from the left margin by
19 blanks (what should've been 19.5n). 19 * 2 + len(v) = 39.

> 123\h'3n'789
> .br

  $ groff -Tutf8 | sed "s/ /'/g"
  '''''''''''''''123'''789

  $ groff -Tutf8 << EOF | sed -E "s/ /'/g;s/123'''789\$//" |
          tr -d '\n'| wc -m
  15

15 * 2 + len(123\h'3n'789) = 39, also centered as expected.

> \h'3n'456789
> .br

  $ groff -Tutf8 | sed "s/ /'/g"
  ''''''''''''''''''456789

  $ groff -Tutf8 << EOF | sed -E "s/ /'/g;s/'''456789\$//" |
          tr -d '\n'| wc -m
  15

As above.

> \Z'\h'3n'456789'
> .br

  $ groff -Tutf8 | sed "s/ /'/g"
  '''''''''''''''''''''''456789

  $ groff -Tutf8 << EOF | sed -E "s/ /'/g;s/'''456789\$//" |
          tr -d '\n'| wc -m
  20

Okay, this is weird. It should be left-padded by 31n, not 20.

> \Z'123456789'
> .rj
> 123456789

  $ groff -Tutf8 | sed "s/ /'/g"
  ''''''''''''''''''''123456789
  '''''''''''''''''''''''''''''''123456789

Huh. I get what you meant by "right-justified against what?" now.
It might just be that my conclusion of \Z causing right justification
when centering is enabled was wrong. I don't actually know what groff
does; its source code is too complicated for me to read.

By the way, I tried this with neatroff and it works as expected:
  $ neatroff/roff -F. << EOF | neatpost/pdf -F. -pa4 > t.pdf
  .pl 29.7c
  .ll 21c
  .po 0
  .ad c
  \Z'123456789'
  .br
  .ad r
  123456789
  EOF

The first 123456789 is indented by half the line length, whereas the
second one is set flush against the right margin.

> [...] I was trying to center vertical
> text on the spine of the cover of my novels.  First I tried the well
> known pic hack to rotate text:
>
>   https://troff.org/faq.html

For the sake of others' context:
  How can I generate rotated text?
   There's no way to specify rotated text in pure troff. However, if
   the output is PostScript then groff's pic can be used to align text
   with an invisible line. The table is not required, it's just part
   of the example.
  .TS
  tab(:) allbox;
  cw(1i) cw(1i) cw(1i).
  A quick:T{
  .PS
  line invis up "and" aligned
  move right
  line invis down then right "dirty" aligned
  .PE
  T}:hack
  .TE

>
> But, depending on the font you use, it doesn't always center the text
> perfectly.  Searching a bit more I found this hack from Tadziu Hoffmann:
>
>   https://lists.gnu.org/archive/html/groff/2017-09/msg00051.html

By the way, the way gpic does it is by emitting PostScript instructions
to the grops postprocessor. See gropdf(1):
  gropdf understands some of the device control commands supported by
  grops(1).

  \X'ps: exec gsave currentpoint 2 copy translate n rotate neg exch
  neg exch translate'
    where n is the angle of rotation.  This is to support the align
    command in pic(1).

  \X'ps: exec grestore'
    Used by pic(1) to restore state after rotation.

Tadziu Hoffman's approach is using these exact commands as well.

> More late, this useful explanaition from Werner Lemberg (thank you
> both!)
>
>   https://lists.nongnu.org/archive/html/bug-groff/2010-01/msg00004.html
> [...]
> So, adapting Werner Lemberg's reasoning to my case:
> [...]
> Then I applied that reasoning to my adaptation of Tadziu's hack:
>
>   .ds 90 \R'w \w'\\$*''\
>   \v'\\nwu-\\n[.v]u'\
>   \h'(\\n[rst]u+\\n[rsb]u)/2u'\
>   \X'ps: exec gsave currentpoint 2 copy translate \
>   -90 rotate neg exch neg exch translate'\
>   \Z'\\$*'\
>   \X'ps: exec grestore'
>
> But that works as expected only if you use \Z:
> [...]
> Or, if instead of using '.ad c' or '.ce' you center your text manually
> in the page:
> [...]
> You can also center perfectly your text with .ce and without \Z by
> removing the division by two from the \h move (third line).
>
>   [...]
>   \h'\\n[rst]u+\\n[rsb]u'\
>   [...]
>
> All that solutions work but I'm still not able to decide which is the
> consistent one. :-)

I would expect the last one to be the one, but note that I know very
little PostScript and I don't have the time to study the outlined
solutions. When I tried using these PostScript commands before, they
didn't seem very intuitive, so personally in your use case I would
probably generate the text to be rotated as a separate PDF and then
rotating it and either overlaying it over or adding it to the main
PDF with some PDF manipulation software instead of trying to solve
it entirely in troff.

> Thank you again onf!

I'm glad it helped.

~ onf


Reply via email to