[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #44784] groff-git_2015-04-04: Compatibility Mode rendering of groff

From: anonymous
Subject: [bug #44784] groff-git_2015-04-04: Compatibility Mode rendering of groff manual pages
Date: Thu, 09 Apr 2015 04:41:58 +0000
User-agent: Mozilla/5.0 (X11; SunOS i86pc; rv:29.0) Gecko/20100101 Firefox/29.0


                 Summary: groff-git_2015-04-04: Compatibility Mode rendering
of groff manual pages
                 Project: GNU troff
            Submitted by: None
            Submitted on: Thu 09 Apr 2015 04:41:57 AM UTC
                Severity: 3 - Normal
              Item Group: Incorrect behaviour
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
         Planned Release: None




It seems that https://savannah.gnu.org/bugs/?44708, has exposed a
portability issue in the provided groff manual pages, which has
exposed a larger issue about compatibility mode.

I needed to read the grog(1) manual page for a piece of code I'm
working on, so I typed "groff -Tascii -man .../grog.1 | less -R",
and got:

     grog -- guess options for a following groff command

     grog -h | --help
     grog -v | --version

Which is the same as the output of Solaris' man(1) command.

Looking at grog --help, than the raw manual page source, I realised
that I was missing out on some of the desired formatted output.

After BUG-44708 mentioned compatibility mode, I search the
documentation and code and discovered that groff -man on Solaris uses
.../lib/groff/site-tmac/an.tmac (which enables compatibility mode and
loads the Operating System provided macros), and that the groff
version of the 'an' macros were installed as
.../share/groff/1.22.3/tmac/gan.tmac.  So then I tried "groff -Tascii
-mgan .../grog.1 | less -R", and got what the manual page author

       grog -- guess options for a following groff command

       grog [-C] [--run] [--warnings] [--ligatures] [ groff-option ...] [--]
            [ filespec ...]
       grog -h | --help
       grog -v | --version

Looking at the raw source again, I discovered that the .SY/.OP/.YS
macros used by the first synopsis line where not being rendered. In
the groff manual pages, there are 34 files that use (*1) .OP (for
example), while only 9 files that define (*2) the OP macro. I then
looked at the two renderings (-man and -mgan) in a postscript viewer
for "missing content" on the grog(1) manual page and also noticed that
email addresses in the author section were missing, which the source
suggested was the rendering of the .MT macro. The stats for .MT are 33
files that use and 0 files that define. The command (*3) shows
inconsistencies in the arguments provided to the .MT macro, including
occasional quoting of '-' as in '\-' and occasional use of '\:' after
an '@' as in '@\:', I wondered if the later were from texinfo source
documentation where '@' is special. Finally I noticed that examples in
'-mgan' used a typewriter style font (Courier?), but that is was
absent from the '-man' output, seems to be related to .EX or maybe .IP
or .RS (not investigated further).

My next thought was, "That's fine, I'll disable compatibility mode",
as my particular use is predominantly for rendering Free, Libre and
Open Source Software documentation. After a little research I found
what I believe is the source of the logic in m4/groff.m4 in the
AC_DEFUN([GROFF_TMAC]) definition. Unfortunately, neither the code or
the output of 'configure --help', has enlightened me as to, how to
disable compatibility mode; short of hacking the generated configure
script and changing the paths search for system macros to something
non-existent, and even than I am not sure that would change the value
in AC_SUBST([tmac_wrap]) or AC_SUBST([g]) (from AC_DEFUN([GROFF_G])),
which all seem related to compatibility mode.

Summarizing findings to-date:

  1. groff manual pages use macros defined in the groff's 'an' or
     'an-ext' macro sets. Which IMHO is a perfectly reasonable
     approach, but which will break(*4) man(1) and groff(1) renderings
     on systems that have installed compatibility mode macro files,
     that do not contain the same macros as groff's 'an' provides.

  2. Some manual pages may have been fixed in the past to ensure they
     render correctly in compatibility mode, and now define macros
     that are present in 'an' or 'an-ext'. In-line with the DRY
     Principle (Do not Repeat Yourself), repeating the definition of
     macros can lead to a maintenance issue and unexpected results
     when these macros get out of sync.
  3. Macro arguments, in particular .MT, have lost consistency over time.
     This will of course happen in any project, consistency is hard in
     any project of reasonable size - even with only one author ;-)

  4. There is no way to disable compatibility mode from configure (that
     I am aware of).

As groff is the portable and de facto standard full-featured *roff
implementation these days, and most FLOSS development is done on
systems that use groff as the only *roff implementation, it seems that
compatibility mode files would likely break(*4) more project's manual
pages than having the groff macros as the default. Though systems that
don't use groff(1) for manual page rendering will still suffer when
rendering groff and other FLOSS manual pages - such systems may wish
to consider alternative FLOSS man(1) implementations (which is what
I'm going at the moment), these include man-db-2.7.1, mdocml-1.13.3
(aka mandoc) or man-1.6g, as at the time of writing. But they will
still need NO compatibility macros installed by groff as the default
macro sets.

As effectively an end user of groff, I lack the insight, history and
wisdom to offer actual solutions to the issues mentioned, but I offer
the following for the developers/maintainers consideration, note that,
some topics make multiple competing suggestions, and or pro/con
arguments to any suggested approach.

  a. Decide if groff manual pages will render with any 'an' macros, or
     only the groff 'an' macros.  Devolving to use only the lowest
     common denominator 'an' macros across the supported platform set,
     and thus allowing the reading of groff manual pages on all
     supported platform's man(1) implementations.

     Associated Thoughts:

     i)    this is portable, but very hard to maintain without some tool
           to warn developers that a macro is not portable, as the
           page will render correctly on most systems. And as seen
           earlier in the write-up, a macro that is not defined will
           render to nothing, giving the end-user no clue they are
           missing author provided content.

     ii)   this then leads to the likely inclusion of convenience macros
           in multiple manual pages, breaking the DRY principle. This
           could be avoided by generating the final manual pages to be
           installed with these convenience macros included in-line,
           from a common include file. I'm guessing soelim(1) as part
           of the build process could be a solution to this problem.

      iii) making the decision to render groff manual pages with the
           lowest common denominator 'an' macros, does not solve the
           problem for the rest of the FLOSS projects who developers
           use system's where groff is the default *roff implementation.

           It also means that groff can not use its own manual pages
           to highlight it own features or promote 'an' macro-set best
           practice. Bug Report 44708's resolution, involved reverting
           readable macro names to two letter abbreviations, this does
           not promote maintainability, let alone the semantic goals
           of projects like mdocml (mandoc).

           The conversion of groff 'an' / 'an-ext' documents to lowest
           common denominator 'an' macros would likely be non-trivial
           and is likely a poor use of developer / maintainer time.
           The developers of mdocml had a reason to write an -mdoc to
           -man converter, to promote the use of -mdoc to projects
           that need to support platforms without -mdoc macros.

  b. Make compatibility mode a configurable feature at configure time.
     Once configurable, the groff "builder" has a decision point, what
     do they wish to preference, operating system vendor macro
     compatibility or modern FLOSS projects compatibility.

     It actually does not have to be an either or choice.  Rather then
     placing the OS vendor macros in site-tmac as their original name
     (example: an.tmac), they could be installed as <macro>-os.tmac or
     <macro>-vendor.tmac, thus making their use with groff possible
     but manual via -m<macro>-os instead of -m<macro>. Making the
     possible configuration options of --compatibility-mode, one of
     'auto' (existing behavior), 'yes', 'no' or 'manual'. All options
     (except no) still need the filesystem check but groff builder, now
     has control of the decision regarding compatibility mode.

     This solves many problems in the issues raised above, and allows
     groff to be the *roff render of choice for those using FLOSS
     software, to get repeatable results on all systems (assuming that
     compatibility mode is changed to 'no' or 'manual' by most groff
     "builders"). Thus man(1) implementation that allow the choice of
     *roff implementation allow the "builder" to choose maximum FLOSS
     compatibility. This is possibly at the expense of vendor macro
     sets that exceed the groff implementation; the groff developers
     and maintainers may like to make notes in the documentation about
     known issues on given platforms.

The 'configure --compatibility-mode' option with a new manual option,
at this stage seems like a reasonable approach and should only require
autoconf / makefile changes, and could default to existing behavior
(auto), or whatever the maintainers think is the best for most users,
which IMHO might be manual. My GNU make(1) skills are reasonable to
good, but my autoconf(1) skills are negligible, so I may not be the
best candidate for implementation duties, but I think it is a
worthwhile change, so I'm willing to help.

Peter Bray
Sydney Australia

PS: Attached is the -Tascii rendering of the groff manual pages with
-man (on a Solaris 10 system), and -mgan on the same system.

*1: find .../share/man/man* -type f | xargs grep -l '^.OP' | wc -l
*2: find .../share/man/man* -type f | xargs grep -l '^.de.*OP' | wc -l 
*3: find .../share/man/man* -type f | xargs grep -h '^\.MT' | sort | uniq -c
*4: break in the sense that the manual page will not be rendered as the
    manual page author intended.


File Attachments:

Date: Thu 09 Apr 2015 04:41:57 AM UTC  Name:
groff-git_2015_04_04-manual_page_issue.txt  Size: 10kB   By: None

Date: Thu 09 Apr 2015 04:41:57 AM UTC  Name:
groff-git_2015_04_04-manual_pages.tar.gz  Size: 677kB   By: None



Reply to this item at:


  Message sent via/by Savannah

reply via email to

[Prev in Thread] Current Thread [Next in Thread]