groff-commit
[Top][All Lists]
Advanced

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

[Groff-commit] groff/contrib/groffer ChangeLog Makefile.sub RE...


From: Werner LEMBERG
Subject: [Groff-commit] groff/contrib/groffer ChangeLog Makefile.sub RE...
Date: Tue, 23 Aug 2005 05:57:10 -0400

CVSROOT:        /cvsroot/groff
Module name:    groff
Branch:         
Changes by:     Werner LEMBERG <address@hidden> 05/08/23 09:57:10

Modified files:
        contrib/groffer: ChangeLog Makefile.sub README_SH TODO 
                         groffer.man groffer.sh groffer2.sh 

Log message:
        * release of groffer 0.9.22
        
        ### `--whatis'
        
        Produce a `groff' output and allow wild cards on filespec
        parameters for `--whatis'.
        
        * groffer2.sh:
        - $_FILESPEC_ARG: New variable for storing the actual filespec
        parameter.
        - main_do_fileargs(): Set $_FILESPEC_ARG and add
        what_is_filespec().
        - main_parse_args(): Add --all to --whatis.
        - to_tmp_line(): New function to write the arguments to the
        temorary cat file.
        - whatis_filename(): Rename of what_is().  Construct a better
        printout using $_FILESPEC_ARG.  Repair the sed sequneces.
        - whatis_filespec(): New function to print the filespec once
        during the `whatis' process.
        - whatis_header(): New funtion for printing the header of the
        `whatis' output.
        
        * groffer.man: Revise the documentation of --whatis.
        
        ### `--apropos*'
        
        Produce `groff' for `--apropos*'.  Allow `--sections' for
        `--apropos', ignore it  with `--apropos-*'.
        
        * groffer2.sh:
        - --apropos*: Make these options without argument.
        - $_APROPOS_PROG: New variable for the program that is is used for
        `apropos'.
        - $_APROPOS_SECTIONS: New variable to determine the sections that
        are filtered out of `apropos' output depending on `--apropos-*'.
        - apropos_filespec(): Handling of apropos at the filespec level.
        - apropos_run(): Remove it.
        - apropos_setup(): New function.
        - main_set_mode(): Remove handling of $_OPT_APROPOS*.
        
        * groffer.man:
        - Revise the documentation of `--apropos*'.
        - Split section 'options for GNU man' into two sections `options
        for man pages' and `long options taken over from GNU man'.
        - Move `--apropos*', `--whatis', `--man', and `--no-man' to
        section `options for man pages'.
        
        ### special display (apropos and whatis)
        
        * groffer2.sh:
        - special_setup(): New function that chooses the setup between
        apropos and whatis.
        - special_filespec(): New function that does the output at the
        filespec level for apropos or whatis.
        
        ### handle `--sections' for man page searching
        
        * groffer2.sh:
        - man_do_filespec(): Use $_OPT_SECTIONS of --sections instead of
        $_MAN_AUTO_SEC if non-empty.  If a section was given on the
        filespec parameter $_OPT_SECTIONS is ignored.  This differs from
        `man' which always uses the restricted sections of --sections.
        This function works for both normal man page search and whatis.
        - apropos_filespec(): Use --sections for --apropos, but not for
        --apropos-* because these provide already their own sections.
        
        ### wildcards in filespec arguments
        
        * groffer2.sh: Wildcards are now accepted.  In `--apropos*' and
        `--whatis' they are interpreted as wildcard search elements; but
        in normal display they are only handled as their own character.
        
        ### development; new option
        
        * groffer2.sh:
        - --print: New option that prints just its argument for parameter
        check.
        - usage(): Add new option.
        - $_OPT_DO_NOTHING: New variable for do_nothing().  Handle it at
        the end of main_parse_Args().
        
        * groffer.man: Add information on --print.
        
        ### safe exit
        
        * groffer2.sh:
        - error(): Always exit with $_ERROR.
        - exit_test(): New function to exit when first exit was hidden by
        ().  Call it after each $().
        
        ### automatic shell determination
        
        * groffer.sh:
        - If no option --shell is given perform a test of several shells
        to automatically start some shell for groffer2.sh.  `ksh' is used
        first because it can be safely terminated by Ctrl-C.
        - This can be cancelled by providing --shell=''.
        - Add test on `sed' program.
        
        * groffer.man: Revise information on --shell.
        
        ### trap
        
        * groffer2.sh:
        - trap_set(): Remove argument.  Instead of $_ALL_EXIT use only
        signal 0.
        - trap_unset(): Rename trap_clean().  Instead of $_ALL_EXIT use
        only signal 0.
        - $_ALL_EXIT: Remove this variable.
        - Replace all direct `trap' calls by trap_set().
        
        * README_SH: New section `Bugs' on `trap'..
        
        ### user errors, error output without function stack
        
        * groffer2.sh:
        - error_user(): New function for user errors.
        - error(): Remove call of clean_up() because the trap will do it
        with the exit.  Remove the `kill' commands.  Create a temporary
        file `.error' that can be tested by exit_test() for a better exit
        test (especially for shell `ksh').
        - $_DEBUG_USER_WITH_STACK: New variable to enable function stack
        output in error_user().
        - list_from_cmdline(), list_single_from_abbrev(), main_set_mode():
        Use error_user().
        
        ### test modes on X and tty
        
        * groffer2,sh:
        - is_X(), is_not_X(): New functions for checking on X Window.
        - $_VIEWER_HTML_TTY, $_VIEWER_HTML_X: New variables that split
        $_VIEWER_HTML.  Add `galeon'.
        - main_parse_args(): Allow mode change for graphical modes only
        when in X Window.
        - _do_display() of main_display(): Create a special run for
        viewers that run on the terminal; `lynx' is the only one so far.
        
        ### add $GROFFER_MODE to command line
        
        * groffer.sh:
        - After the handling of the configuration files integrate
        $GROFFER_OPT to the command line.
        - This makes a `set' in the shell determination unnecessary.
        
        * groffer2.sh:
        - The debug test gets simpler because quotes are vanished without
        $GROFFER_OPT.
        - main_parse_MANOPT(): Prepend $mpm_list to the command line.
        - main_parse_args(): `set' is unnecessary.
        
        ### debug; new options
        
        * groffer2.sh:
        - --debug-all, --debug-lm, --debug-params, --debug-shell,
        --debug-stacks, --debug-tmpdir, --debug-user: New options.
        - --debug: Enable all debug variables except $_DEBUG_STACKS and
        $_DEBUG_LM.  By the new options the smallest abbreviation is now
        `--debug'.
        - $_DEBUG_STACKS: Rename $_DEBUG.
        - $_DEBUG_PRINT_TMPDIR: New debug variable for printing the name
        of the temporary directory in main_init().
        - $_OPT_DEBUG: Remove this variable because debug is handled at
        the early part of the script.
        - clean_up(): Enlarge $_DEBUG_KEEP_FILES to not deleting the
        temporary directory.
        - usage(): Move all development options on a section of its own.
        - Move the test of rudimentary shell functionality at the
        beginning of the script.  Add test on `sed'.
        - Follow this by the debug section.  The determination of all
        --debug* options can be done without a function.
        
        * groffer.man: Revise information on --debug and add new options.
        
        ### variables
        
        * groffer.sh:
        - $_ERROR: Move the definition of this variable here.
        - $_GROFF_VERSION: New variable, is set over @...@ construct.
        - $_OUTPUT_FILE_NAME: Move this variable to groffer2.sh.
        
        * groffer2.sh:
        - $_MAN_AUTO_SEC_LIST: Rename $_MAN_AUTO_SEC because it represents
        a list.
        - $_MAN_AUTO_SEC_CHARS: New read-only variable for storing
        $_MAN_AUTO_SEC_LIST in [] construct.  Use it in man_do_filespec()
        and whatis_filename().
        - $_SPACE_CASE: New read-only variable with [] on space characters
        with \ for `case' patterns.  Use it in several functions.
        - $_SPACE_SED: New read-only variable with [] on space characters
        for `sed'.  Use it in several functions.
        
        ### options and display
        
        * groffer2.sh:
        - list_from_cmdline(): Add test whether the same abbreviation is
        part of long options with and without arguments.  Give handling of
        `=' a `case' pattern of its own.
        - main_display(): Remove unnecessary calls of `clean_up' in order
        to use `mozilla' without problems.  In _do_display(): Fix -X by
        providing a different process when $_DISPLAY_PROG is empty.
        - main_set_mode(): Accept options for viewers as is, without check
        for program.  Add test whether no program is given for a mode.
        This avoids unnecessary empty $_DISPLAY_PROG in main_display().
        
        ### viewer programs that run on the terminal (tty); new options
        
        * groffer2.sh:
        - $_VIEWER_TERMINAL: New variable that stores whether a viewer was
        supposed to run on tty.
        - --dvi-viewer-tty, --html-viewer-tty, --pdf-viewer-tty,
        --ps-viewer-tty, --tty-viewer-tty, --X-viewer-tty, --x-viewer-tty,
        --www-viewer-tty: New options for viewers that run on a terminal.
        - main_parse_args(), _do_display() of main_display(): Use the new
        options and the new variable.
        - usage(): Add the new options.
        
        * groffer.man: Add information on options --*-viewer-tty.
        
        ### other fixes
        
        * groffer2.sh:
        - _do_display() of main_display(): Bear errors of `groff' run.
        - is_not_file: Fix to have exactly one argument.
        - is_not_prog(): Handle no arguments.
        - list_has_not(): Fix.
        - main_do_fileargs(): Remove $mdfa_exitcode.
        - register_title(): Limit title to 4 elements.
        - version(): Print the version information to standard output just
        like `groff' does.
        - --no-special: New option to disable former calls of `--all',
        `--apropos*', and `whatis.
        - --title: Make it an option with argument.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/ChangeLog.diff?tr1=1.33&tr2=1.34&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/Makefile.sub.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/README_SH.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/TODO.diff?tr1=1.14&tr2=1.15&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/groffer.man.diff?tr1=1.27&tr2=1.28&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/groffer.sh.diff?tr1=1.32&tr2=1.33&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/groffer2.sh.diff?tr1=1.2&tr2=1.3&r1=text&r2=text

Patches:
Index: groff/contrib/groffer/ChangeLog
diff -u groff/contrib/groffer/ChangeLog:1.33 
groff/contrib/groffer/ChangeLog:1.34
--- groff/contrib/groffer/ChangeLog:1.33        Sun Aug  7 12:56:45 2005
+++ groff/contrib/groffer/ChangeLog     Tue Aug 23 09:57:09 2005
@@ -1,3 +1,239 @@
+       ________________________________________________________________
+       * release of groffer 0.9.22
+
+2005-22-04  Bernd Warken
+
+       ### `--whatis'
+
+       Produce a `groff' output and allow wild cards on filespec
+       parameters for `--whatis'.
+
+       * groffer2.sh:
+       - $_FILESPEC_ARG: New variable for storing the actual filespec
+       parameter.
+       - main_do_fileargs(): Set $_FILESPEC_ARG and add
+       what_is_filespec().
+        - main_parse_args(): Add --all to --whatis.
+       - to_tmp_line(): New function to write the arguments to the
+       temorary cat file.
+       - whatis_filename(): Rename of what_is().  Construct a better
+       printout using $_FILESPEC_ARG.  Repair the sed sequneces.
+       - whatis_filespec(): New function to print the filespec once
+       during the `whatis' process.
+       - whatis_header(): New funtion for printing the header of the
+       `whatis' output.
+
+       * groffer.man: Revise the documentation of --whatis.
+
+       ### `--apropos*'
+
+       Produce `groff' for `--apropos*'.  Allow `--sections' for
+       `--apropos', ignore it  with `--apropos-*'.
+
+       * groffer2.sh:
+       - --apropos*: Make these options without argument.
+       - $_APROPOS_PROG: New variable for the program that is is used for
+       `apropos'.
+       - $_APROPOS_SECTIONS: New variable to determine the sections that
+       are filtered out of `apropos' output depending on `--apropos-*'.
+       - apropos_filespec(): Handling of apropos at the filespec level.
+       - apropos_run(): Remove it.
+       - apropos_setup(): New function.
+       - main_set_mode(): Remove handling of $_OPT_APROPOS*.
+
+       * groffer.man:
+       - Revise the documentation of `--apropos*'.
+       - Split section 'options for GNU man' into two sections `options
+       for man pages' and `long options taken over from GNU man'.
+       - Move `--apropos*', `--whatis', `--man', and `--no-man' to
+       section `options for man pages'.
+
+       ### special display (apropos and whatis)
+
+       * groffer2.sh:
+       - special_setup(): New function that chooses the setup between
+       apropos and whatis.
+       - special_filespec(): New function that does the output at the
+       filespec level for apropos or whatis.
+
+       ### handle `--sections' for man page searching
+
+       * groffer2.sh:
+       - man_do_filespec(): Use $_OPT_SECTIONS of --sections instead of
+       $_MAN_AUTO_SEC if non-empty.  If a section was given on the
+       filespec parameter $_OPT_SECTIONS is ignored.  This differs from
+       `man' which always uses the restricted sections of --sections.
+       This function works for both normal man page search and whatis.
+       - apropos_filespec(): Use --sections for --apropos, but not for
+       --apropos-* because these provide already their own sections.
+
+       ### wildcards in filespec arguments
+
+       * groffer2.sh: Wildcards are now accepted.  In `--apropos*' and
+       `--whatis' they are interpreted as wildcard search elements; but
+       in normal display they are only handled as their own character.
+
+       ### development; new option
+
+       * groffer2.sh:
+       - --print: New option that prints just its argument for parameter
+       check.
+       - usage(): Add new option.
+       - $_OPT_DO_NOTHING: New variable for do_nothing().  Handle it at
+       the end of main_parse_Args().
+
+       * groffer.man: Add information on --print.
+
+       ### safe exit
+
+       * groffer2.sh:
+       - error(): Always exit with $_ERROR.
+       - exit_test(): New function to exit when first exit was hidden by
+       ().  Call it after each $().
+
+       ### automatic shell determination
+
+       * groffer.sh:
+       - If no option --shell is given perform a test of several shells
+       to automatically start some shell for groffer2.sh.  `ksh' is used
+       first because it can be safely terminated by Ctrl-C.
+       - This can be cancelled by providing --shell=''.
+       - Add test on `sed' program.
+
+       * groffer.man: Revise information on --shell.
+
+       ### trap
+
+       * groffer2.sh:
+       - trap_set(): Remove argument.  Instead of $_ALL_EXIT use only
+       signal 0.
+       - trap_unset(): Rename trap_clean().  Instead of $_ALL_EXIT use
+       only signal 0.
+       - $_ALL_EXIT: Remove this variable.
+       - Replace all direct `trap' calls by trap_set().
+       
+       * README_SH: New section `Bugs' on `trap'..
+
+       ### user errors, error output without function stack
+
+       * groffer2.sh:
+       - error_user(): New function for user errors.
+       - error(): Remove call of clean_up() because the trap will do it
+       with the exit.  Remove the `kill' commands.  Create a temporary
+       file `.error' that can be tested by exit_test() for a better exit
+       test (especially for shell `ksh').
+       - $_DEBUG_USER_WITH_STACK: New variable to enable function stack
+       output in error_user().
+       - list_from_cmdline(), list_single_from_abbrev(), main_set_mode():
+       Use error_user().
+
+       ### test modes on X and tty
+
+       * groffer2,sh:
+       - is_X(), is_not_X(): New functions for checking on X Window.
+       - $_VIEWER_HTML_TTY, $_VIEWER_HTML_X: New variables that split
+       $_VIEWER_HTML.  Add `galeon'.
+       - main_parse_args(): Allow mode change for graphical modes only
+       when in X Window.
+       - _do_display() of main_display(): Create a special run for
+       viewers that run on the terminal; `lynx' is the only one so far.
+
+       ### add $GROFFER_MODE to command line
+
+       * groffer.sh:
+       - After the handling of the configuration files integrate
+       $GROFFER_OPT to the command line.
+       - This makes a `set' in the shell determination unnecessary.
+
+       * groffer2.sh:
+       - The debug test gets simpler because quotes are vanished without
+       $GROFFER_OPT.
+       - main_parse_MANOPT(): Prepend $mpm_list to the command line.
+       - main_parse_args(): `set' is unnecessary.
+
+       ### debug; new options
+
+       * groffer2.sh:
+       - --debug-all, --debug-lm, --debug-params, --debug-shell,
+       --debug-stacks, --debug-tmpdir, --debug-user: New options.
+       - --debug: Enable all debug variables except $_DEBUG_STACKS and
+       $_DEBUG_LM.  By the new options the smallest abbreviation is now
+       `--debug'.
+       - $_DEBUG_STACKS: Rename $_DEBUG.
+       - $_DEBUG_PRINT_TMPDIR: New debug variable for printing the name
+       of the temporary directory in main_init().
+       - $_OPT_DEBUG: Remove this variable because debug is handled at
+       the early part of the script.
+       - clean_up(): Enlarge $_DEBUG_KEEP_FILES to not deleting the
+       temporary directory.
+       - usage(): Move all development options on a section of its own.
+       - Move the test of rudimentary shell functionality at the
+       beginning of the script.  Add test on `sed'.
+       - Follow this by the debug section.  The determination of all
+       --debug* options can be done without a function.
+
+       * groffer.man: Revise information on --debug and add new options.
+
+       ### variables
+
+       * groffer.sh:
+       - $_ERROR: Move the definition of this variable here.
+       - $_GROFF_VERSION: New variable, is set over @...@ construct.
+       - $_OUTPUT_FILE_NAME: Move this variable to groffer2.sh.
+
+       * groffer2.sh:
+       - $_MAN_AUTO_SEC_LIST: Rename $_MAN_AUTO_SEC because it represents
+       a list.
+       - $_MAN_AUTO_SEC_CHARS: New read-only variable for storing
+       $_MAN_AUTO_SEC_LIST in [] construct.  Use it in man_do_filespec()
+       and whatis_filename().
+       - $_SPACE_CASE: New read-only variable with [] on space characters
+       with \ for `case' patterns.  Use it in several functions.
+       - $_SPACE_SED: New read-only variable with [] on space characters
+       for `sed'.  Use it in several functions.
+
+       ### options and display
+
+       * groffer2.sh:
+       - list_from_cmdline(): Add test whether the same abbreviation is
+       part of long options with and without arguments.  Give handling of
+       `=' a `case' pattern of its own.
+       - main_display(): Remove unnecessary calls of `clean_up' in order
+       to use `mozilla' without problems.  In _do_display(): Fix -X by
+       providing a different process when $_DISPLAY_PROG is empty.
+       - main_set_mode(): Accept options for viewers as is, without check
+       for program.  Add test whether no program is given for a mode.
+       This avoids unnecessary empty $_DISPLAY_PROG in main_display().
+
+       ### viewer programs that run on the terminal (tty); new options
+
+       * groffer2.sh:
+       - $_VIEWER_TERMINAL: New variable that stores whether a viewer was
+       supposed to run on tty.
+       - --dvi-viewer-tty, --html-viewer-tty, --pdf-viewer-tty,
+       --ps-viewer-tty, --tty-viewer-tty, --X-viewer-tty, --x-viewer-tty,
+       --www-viewer-tty: New options for viewers that run on a terminal.
+       - main_parse_args(), _do_display() of main_display(): Use the new
+       options and the new variable.
+       - usage(): Add the new options.
+
+       * groffer.man: Add information on options --*-viewer-tty.
+
+       ### other fixes
+
+       * groffer2.sh:
+       - _do_display() of main_display(): Bear errors of `groff' run.
+       - is_not_file: Fix to have exactly one argument.
+       - is_not_prog(): Handle no arguments.
+       - list_has_not(): Fix.
+       - main_do_fileargs(): Remove $mdfa_exitcode.
+       - register_title(): Limit title to 4 elements.
+       - version(): Print the version information to standard output just
+       like `groff' does.
+       - --no-special: New option to disable former calls of `--all',
+       `--apropos*', and `whatis.
+       - --title: Make it an option with argument.
+
 2005-08-07  Keith Marshall  <address@hidden>
 
        * contrib/groffer/Makefile.sub (install): Reference groffer2.sh
@@ -5,7 +241,6 @@
        different directory from the source.
 
        ________________________________________________________________
-
        * release of groffer 0.9.21
 
 2005-08-02  Bernd Warken
@@ -1302,7 +1537,7 @@
        Copyright (C) 2001,2002,2003,2004,2005
        Free Software Foundation, Inc.
        Written by Bernd Warken
-       
+
        Copying and distribution of this file, with or without
        modification, are permitted provided the copyright notice and this
        notice are preserved.
Index: groff/contrib/groffer/Makefile.sub
diff -u groff/contrib/groffer/Makefile.sub:1.13 
groff/contrib/groffer/Makefile.sub:1.14
--- groff/contrib/groffer/Makefile.sub:1.13     Sun Aug  7 12:56:45 2005
+++ groff/contrib/groffer/Makefile.sub  Tue Aug 23 09:57:09 2005
@@ -5,7 +5,7 @@
 # Copyright (C) 2001,2002,2005 Free Software Foundation, Inc.
 # Written by Werner Lemberg <address@hidden> and Bernd Warken.
 
-# Last update: 2 August 2005
+# Last update: 15 August 2005
 
 # This file is part of `groffer' which is part of `groff'.
 
@@ -35,22 +35,22 @@
 all: groffer
 
 groffer: groffer.sh groffer2.sh $(SH_DEPS_SED_SCRIPT)
-       $(RM) $@; \
+       $(RM) $@;
        sed -f $(SH_DEPS_SED_SCRIPT) \
             -e "s|@g@|$(g)|g" \
            -e "s|@BINDIR@|$(bindir)|g" \
            -e "s|@libdir@|$(libdir)|g" \
            -e "s|@VERSION@|$(version)$(revision)|g" \
-           -e $(SH_SCRIPT_SED_CMD) $(srcdir)/groffer.sh >$@; \
+           -e $(SH_SCRIPT_SED_CMD) $(srcdir)/groffer.sh >$@;
        chmod +x $@
 
 install_data: groffer
        -test -d $(bindir) || $(mkinstalldirs) $(bindir)
+       -$(RM) $(bindir)/groffer
+       $(INSTALL_SCRIPT) groffer $(bindir)/groffer
        -test -d $(libdir)/groff/groffer || \
           $(mkinstalldirs) $(libdir)/groff/groffer
-       -$(RM) $(bindir)/groffer
        -$(RM) $(libdir)/groff/groffer/groffer2.sh
-       $(INSTALL_SCRIPT) groffer $(bindir)/groffer
        $(INSTALL_SCRIPT) $(srcdir)/groffer2.sh \
          $(libdir)/groff/groffer/groffer2.sh
 
Index: groff/contrib/groffer/README_SH
diff -u groff/contrib/groffer/README_SH:1.11 
groff/contrib/groffer/README_SH:1.12
--- groff/contrib/groffer/README_SH:1.11        Wed Aug  3 06:32:11 2005
+++ groff/contrib/groffer/README_SH     Tue Aug 23 09:57:09 2005
@@ -20,6 +20,99 @@
 different shell, using the `groffer' option `--shell'.
 
 
+Options
+
+The `groffer' script provides its own option parser.  It is compatible
+to the usual GNU style command line This includes long option names
+with two signs such as `--option', clusters of short options, the
+mixing of options and non-option file names, the option `--' to close
+the option handling, and it is possible to abbreviate the long option
+names.
+
+The flexible mixing of options and file names in GNU style is always
+possible, even if the environment variable `$POSIXLY_CORRECT' is set
+to a non-empty value.  This disables the rather wicked POSIX behavior
+to terminate option parsing when the first non-option command line
+argument is found.
+
+
+Error Handling
+
+Error handling and exit behavior is complicated by the fact that
+`exit' can only escape from the current shell; trouble occurs in
+subshells.  This was solved by sending kill signals, see $_PROCESS_ID
+and error().
+
+
+Function Definitions in `groffer2.sh'
+
+Each funtion in groffer2.sh has a description that starts with the
+function name and symbols for its arguments in paranthesis `()'.  Each
+`<>' construction gives an argument name that just gives a hint on
+what the argument is meant to be; these argument names are otherwise
+irrelevant.  The `>' sign can be followed by another character that
+shows how many of these arguments are possible.
+
+<arg>      exactly 1 of this argument
+<arg>?     0 or 1 of these arguments
+<arg>*     arbitrarily many such arguments, incl. none
+<arg>+     one or more such arguments
+<arg>...   one or more such arguments
+[...]      optional arguments
+
+A function that starts with an underscore `_' is an internal function
+for some other function.  The internal functions are defined just
+after their corresponding function.
+
+
+External Environment Variables
+
+The groffer.sh script uses the following external system variables.
+It is supposed that these variables are already exported outside of
+groffer.sh; otherwise they do not have a value within the script.
+
+external system environment variables that are explicitly used
+$DISPLAY:              Presets the X display.
+$LANG:                 For language specific man pages.
+$LC_ALL:               For language specific man pages.
+$LC_MESSAGES:          For language specific man pages.
+$PAGER:                        Paging program for tty mode.
+$PATH:                 Path for the programs called (`:' separated list).
+
+groffer native environment variables
+$GROFFER_OPT           preset options for groffer.
+
+all groff environment variables are used, see groff(1)
+$GROFF_BIN_PATH:       Path for all groff programs.
+$GROFF_COMMAND_PREFIX: '' (normally) or 'g' (several troffs).
+$GROFF_FONT_PATH:      Path to non-default groff fonts.
+$GROFF_TMAC_PATH:      Path to non-default groff macro files.
+$GROFF_TMPDIR:         Directory for groff temporary files.
+$GROFF_TYPESETTER:     Preset default device.
+
+all GNU man environment variables are used, see man(1).
+$MANOPT:               Preset options for man pages.
+$MANPATH:              Search path for man pages (: list).
+$MANROFFSEQ:           Ignored because of grog guessing.
+$MANSECT:              Search man pages only in sections (:).
+$SYSTEM:               Man pages for different OS's (, list).
+
+
+Object-oriented Functions
+
+The groffer script provides an object-oriented construction (OOP).  In
+object-oriented terminology, a type of object is called a `class'; a
+function that handles objects from a class is named `method'.
+
+In the groffer script, the object is a variable name whose content is
+the object's data.  Methods are functions that have an object as first
+argument.
+
+The basic functions for object handling are obj_*().
+
+The class `list' represents an array structure, see list_*().
+
+
 Shell Compatibility
 
 The `groffer' shell scripts are compatible to both the GNU and the
@@ -36,11 +129,11 @@
 function.
 
 The `groffer' scripts were tested under the shells `ash', `bash',
-`dash', 'ksh', `mksh', `pdksh', 'posh', and `zsh' without problems in
-Linux Debian.  A shell can be tested by the `groffer' option
-`--shell', but that will run only with groffer2.sh.  To start it
-directly from the beginning under this shell the following command can
-be used.
+`bash-minimal', `dash', 'ksh', `mksh', `pdksh', 'posh', and `zsh'
+without problems in Linux Debian.  A shell can be tested by the
+`groffer' option `--shell', but that will run only with groffer2.sh.
+To start it directly from the beginning under this shell the following
+command can be used.
 
   <shell-name> groffer.sh --shell=<shell-name> <argument>...
 
@@ -135,102 +228,17 @@
 unset
 
 
-Options
-
-The `groffer' script provides its own option parser.  It is compatible
-to the usual GNU style command line This includes long option names
-with two signs such as `--option', clusters of short options, the
-mixing of options and non-option file names, the option `--' to close
-the option handling, and it is possible to abbreviate the long option
-names.
-
-The flexible mixing of options and file names in GNU style is always
-possible, even if the environment variable `$POSIXLY_CORRECT' is set
-to a non-empty value.  This disables the rather wicked POSIX behavior
-to terminate option parsing when the first non-option command line
-argument is found.
-
-
-Error Handling
-
-Error handling and exit behavior is complicated by the fact that
-`exit' can only escape from the current shell; trouble occurs in
-subshells.  This was solved by sending kill signals, see $_PROCESS_ID
-and error().
-
-
-Function Definitions in `groffer2.sh'
-
-Each funtion in groffer2.sh has a description that starts with the
-function name and symbols for its arguments in paranthesis `()'.  Each
-`<>' construction gives an argument name that just gives a hint on
-what the argument is meant to be; these argument names are otherwise
-irrelevant.  The `>' sign can be followed by another character that
-shows how many of these arguments are possible.
+Bugs
 
-<arg>      exactly 1 of this argument
-<arg>?     0 or 1 of these arguments
-<arg>*     arbitrarily many such arguments, incl. none
-<arg>+     one or more such arguments
-<arg>...   one or more such arguments
-[...]      optional arguments
-
-A function that starts with an underscore `_' is an internal function
-for some other function.  The internal functions are defined just
-after their corresponding function.
-
-
-External Environment Variables
-
-The groffer.sh script uses the following external system variables.
-It is supposed that these variables are already exported outside of
-groffer.sh; otherwise they do not have a value within the script.
-
-external system environment variables that are explicitly used
-$DISPLAY:              Presets the X display.
-$LANG:                 For language specific man pages.
-$LC_ALL:               For language specific man pages.
-$LC_MESSAGES:          For language specific man pages.
-$PAGER:                        Paging program for tty mode.
-$PATH:                 Path for the programs called (`:' separated list).
-
-groffer native environment variables
-$GROFFER_OPT           preset options for groffer.
-
-all groff environment variables are used, see groff(1)
-$GROFF_BIN_PATH:       Path for all groff programs.
-$GROFF_COMMAND_PREFIX: '' (normally) or 'g' (several troffs).
-$GROFF_FONT_PATH:      Path to non-default groff fonts.
-$GROFF_TMAC_PATH:      Path to non-default groff macro files.
-$GROFF_TMPDIR:         Directory for groff temporary files.
-$GROFF_TYPESETTER:     Preset default device.
-
-all GNU man environment variables are used, see man(1).
-$MANOPT:               Preset options for man pages.
-$MANPATH:              Search path for man pages (: list).
-$MANROFFSEQ:           Ignored because of grog guessing.
-$MANSECT:              Search man pages only in sections (:).
-$SYSTEM:               Man pages for different OS's (, list).
-
-
-Object-oriented Functions
-
-The groffer script provides an object-oriented construction (OOP).  In
-object-oriented terminology, a type of object is called a `class'; a
-function that handles objects from a class is named `method'.
-
-In the groffer script, the object is a variable name whose content is
-the object's data.  Methods are functions that have an object as first
-argument.
-
-The basic functions for object handling are obj_*().
-
-The class `list' represents an array structure, see list_*().
+If the `groffer' run is interrupted by Crtl-C the clean up is not done
+by all shells.  The `trap' commands work for the shells `bash',
+`bash-minimal', and 'ksh'; they do not work for `ash', `dash',
+`pdksh', `posh', and `zsh'.
 
 
 ####### License
 
-Last update: 2 August 2005
+Last update: 19 August 2005
 
 Copyright (C) 2003,2004,2005 Free Software Foundation, Inc.
 Written by Bernd Warken
Index: groff/contrib/groffer/TODO
diff -u groff/contrib/groffer/TODO:1.14 groff/contrib/groffer/TODO:1.15
--- groff/contrib/groffer/TODO:1.14     Wed Aug  3 06:32:11 2005
+++ groff/contrib/groffer/TODO  Tue Aug 23 09:57:09 2005
@@ -7,11 +7,6 @@
 
 Revision:
 
-- Make --apropos-* options without arguments, based on all filespecs.
-  Transform the output into a `groff' file and have it viewed; maybe
-  also for --version and -V.
-- Make --whatis a breaking option and its output a good man-page.
-
 Optimization:
 - Optimize `man' path determination in manpath_add_lang_sys() for speed
   by building-up the `man' path only by and by as far as necessary
@@ -33,7 +28,7 @@
 
 ####### License
 
-Last update: 2 August 2005
+Last update: 16 August 2005
 
 Copyright (C) 2003,2004,2005 Free Software Foundation, Inc.
 Written by Bernd Warken
Index: groff/contrib/groffer/groffer.man
diff -u groff/contrib/groffer/groffer.man:1.27 
groff/contrib/groffer/groffer.man:1.28
--- groff/contrib/groffer/groffer.man:1.27      Wed Aug  3 06:32:11 2005
+++ groff/contrib/groffer/groffer.man   Tue Aug 23 09:57:09 2005
@@ -15,12 +15,13 @@
 Source file position:  <groff_source_top>/contrib/groffer/groffer.man
 Installed position:    $prefix/share/man/man1/groffer.1
 
-Last update : 2 August 2005
+Last update: 22 August 2005
 
 Source file position: <groff-source>/contrib/groffer/groffer.man
 ..
 .de author
-This file was written by \m[blue]Bernd Warken\m[].
+This file was written by
+.MTO "" "Bernd Warken" .
 ..
 .de copyleft
 Copyright (C) 2001,2002,2004,2005 Free Software Foundation, Inc.
@@ -43,8 +44,8 @@
 either version 2, or (at your option) any later version.
 .
 .P
-You should have received a copy of the GNU General Public License
-along with
+You should have received a copy of the \f[CR]GNU General Public
+License\f[] along with
 .IR groff ,
 see the files \%\f[CB]COPYING\f[] and \%\f[CB]LICENSE\f[] in the top
 directory of the
@@ -199,7 +200,7 @@
 .c --------------------------------------------------------------------
 .c .Opt_-  ([<punct>])
 .c
-.c Print `-' (minus sign); optional punctuation. 
+.c Print `-' (minus sign); optional punctuation.
 .c
 .de Opt_-
 .  ie (\\n[.$] == 0) \
@@ -210,7 +211,7 @@
 .c --------------------------------------------------------------------
 .c .Opt_[-]  ([<punct>])
 .c
-.c Print `Opt_[-]' (minus sign in brackets); optional punctuation. 
+.c Print `Opt_[-]' (minus sign in brackets); optional punctuation.
 .c
 .de Opt_[-]
 .  ie (\\n[.$] == 0) \
@@ -221,7 +222,7 @@
 .c --------------------------------------------------------------------
 .c .Opt_--  ([<punct>])
 .c
-.c Print `--' (double minus); optional punctuation. 
+.c Print `--' (double minus); optional punctuation.
 .c
 .de Opt_--
 .  ie (\\n[.$] == 0) \
@@ -232,7 +233,7 @@
 .c --------------------------------------------------------------------
 .c .Opt_[--]  ([<punct>])
 .c
-.c Print `Opt_[--]' (double minus in brackets); optional punctuation. 
+.c Print `Opt_[--]' (double minus in brackets); optional punctuation.
 .c
 .de Opt_[--]
 .  ie (\\n[.$] == 0) \
@@ -666,11 +667,7 @@
 .Synopsis groffer
 .RI [ option... ]
 .Opt_[--]
-.RI [ "filespec" "\*[Ellipsis]]"
-./Synopsis
-.
-.Synopsis groffer
-.Opt_alt -- apropos -- apropos-data -- apropos-devel -- apropos-progs name
+.RI [ "\%filespec" "\*[Ellipsis]]"
 ./Synopsis
 .
 .Synopsis groffer
@@ -691,17 +688,21 @@
 program is the easiest way to use
 .BR \%groff (@MAN1EXT@).
 It can display arbitrary documents written in the
-.BR \%groff (@MAN7EXT@)
-language or other
-.BR \%roff (@MAN7EXT@)
-languages that are compatible to the original
+.I \%groff
+language, see
+.BR \%groff (@MAN7EXT@),
+or other
+.I \%roff
+languages, see
+.BR \%roff (@MAN7EXT@),
+that are compatible to the original
 .I \%troff
 language.
 .
 The
 .B \%groffer
 program also includes many of the features for finding and displaying
-the \%UNIX manual pages
+the \%\f[CR]Unix\f[] manual pages
 .nh
 .RI ( man\~pages ),
 .hy
@@ -729,9 +730,6 @@
 .BR \%$GROFFER_OPT ,
 or on the command line.
 .
-For example, it makes sense to specify a faster shell in a
-configuration file.
-.
 .
 .P
 The output can be generated and viewed in several different ways
@@ -740,9 +738,12 @@
 .
 This includes the
 .I \%groff
-native X\~\%viewer
+native \%\f[CR]X\~Window\f[] viewer
 .BR \%gxditview (@MAN1EXT@),
-each Postcript or
+each
+.IR \%Postcript ,
+.IR \%pdf ,
+or
 .I \%dvi
 display program, a web browser by generating
 .I \%html
@@ -773,7 +774,7 @@
 .
 .
 .P
-Option handling is done in GNU style.
+Option handling is done in \f[CR]GNU\f[] style.
 .
 Options and file names can be mixed freely.
 .
@@ -793,10 +794,6 @@
 .I breaking options
 .RS
 .P
-.Opt_[alt] -- apropos name
-.Opt_[alt] -- apropos\-data name
-.Opt_[alt] -- apropos\-devel name
-.Opt_[alt] -- apropos\-progs name
 .Opt_[alt] - h -- help
 .Opt_[alt] - v -- version
 .RE
@@ -811,23 +808,28 @@
 .Opt_[alt] -- default\-modes mode1,mode2,\*[Ellipsis]
 .Opt_[alt] -- dvi
 .Opt_[alt] -- dvi\-viewer prog
+.Opt_[alt] -- dvi\-viewer\-tty prog
 .Opt_[alt] -- groff
 .Opt_[alt] -- html
 .Opt_[alt] -- html\-viewer prog
-.Opt_[alt] -- man
+.Opt_[alt] -- html\-viewer\-tty prog
 .Opt_[alt] -- mode display_mode
-.Opt_[alt] -- no-man
 .Opt_[alt] -- pdf
 .Opt_[alt] -- pdf\-viewer prog
+.Opt_[alt] -- pdf\-viewer\-tty prog
 .Opt_[alt] -- ps
 .Opt_[alt] -- ps\-viewer prog
+.Opt_[alt] -- ps\-viewer\-tty prog
 .Opt_[alt] -- text
 .Opt_[alt] -- tty
 .Opt_[alt] -- tty\-viewer prog
+.Opt_[alt] -- tty\-viewer\-tty prog
 .Opt_[alt] -- www
 .Opt_[alt] -- www\-viewer prog
+.Opt_[alt] -- www\-viewer\- prog
 .Opt_[alt] -- x -- X
 .Opt_[alt] -- x\-viewer -- X\-viewer prog
+.Opt_[alt] -- x\-viewer\-tty -- X\-viewer\-tty prog
 .RE
 .
 .
@@ -857,25 +859,19 @@
 .
 .
 .TP
-.I X\~\%Window\~\%Toolkit options
-.RS
-.P
-.Opt_[alt] -- bd pixels
-.Opt_[alt] -- bg -- background color
-.Opt_[alt] -- bw pixels
-.Opt_[alt] -- display X-display
-.Opt_[alt] -- fg -- foreground color
-.Opt_[alt] -- ft -- font font_name
-.Opt_[alt] -- geometry size_pos
-.Opt_[alt] -- resolution value
-.Opt_[alt] -- rv
-.Opt_[alt] -- title string
-.Opt_[alt] -- xrm X-resource
-.RE
+.I options for man\~pages
+.Opt_[alt] -- apropos
+.Opt_[alt] -- apropos\-data
+.Opt_[alt] -- apropos\-devel
+.Opt_[alt] -- apropos\-progs
+.Opt_[alt] -- whatis
+.Opt_[alt] -- man
+.Opt_[alt] -- no-man
+.Opt_[alt] -- no-special
 .
 .
 .TP
-.I options from GNU man
+.I long options taken over from GNU man
 .RS
 .P
 .Opt_[alt] -- all
@@ -889,20 +885,37 @@
 .Opt_[alt] -- sections sec1:sec2:\*[Ellipsis]
 .Opt_[alt] -- systems sys1,sys2,\*[Ellipsis]
 .Opt_[alt] -- troff-device device
-.Opt_[alt] -- whatis
 .P
-Further long options of GNU
+Further long options of \f[CR]GNU\f[]
 .B man
 are accepted as well.
 .RE
 .
 .
 .TP
-.I filespec argument
+.I X Window Toolkit options
+.RS
+.P
+.Opt_[alt] -- bd pixels
+.Opt_[alt] -- bg -- background color
+.Opt_[alt] -- bw pixels
+.Opt_[alt] -- display X-display
+.Opt_[alt] -- fg -- foreground color
+.Opt_[alt] -- ft -- font font_name
+.Opt_[alt] -- geometry size_pos
+.Opt_[alt] -- resolution value
+.Opt_[alt] -- rv
+.Opt_[alt] -- title string
+.Opt_[alt] -- xrm X-resource
+.RE
+.
+.
+.TP
+.I \%filespec arguments
 .RS
 .P
 No
-.I filespec
+.I \%filespec
 parameters means standard input.
 .
 .
@@ -960,7 +973,7 @@
 .
 .TP
 .I name
-if 
+if
 .I \%name
 is not an existing file search for the man\~page
 .I \%name
@@ -1006,47 +1019,6 @@
 All other arguments are ignored.
 .
 .
-.Opt_def -- apropos name
-Start the
-.BR \%apropos (1)
-command for searching within
-.I \%man\~page
-descriptions.
-.
-That slightly differs from the strange behavior of the
-.Opt_long apropos
-program of
-.BR \%man (1),
-which has no argument of its own, but takes the file arguments
-instead.
-.
-Practically both concepts are compatible.
-.
-.
-.Opt_def -- apropos\-data name
-Show only the
-.BR \%apropos (1)
-descriptions for data documents, in the
-.BR \%man (7)
-sections 4, 5, and 7.
-.
-.
-.Opt_def -- apropos\-devel name
-Show only the
-.BR apropos (1)
-descriptions for development documents, in the
-.BR man (7)
-sections 2, 3, and 9.
-.
-.
-.Opt_def -- apropos\-progs name
-Show only the
-.BR \%apropos (1)
-descriptions for documents on programs, in the
-.BR \%man (7)
-sections 1, 6, and 8.
-.
-.
 .Opt_def - h -- help
 Print a helping information with a short explanation of option sto
 standard output.
@@ -1067,6 +1039,57 @@
 .B \%groffer
 tries to find a suitable display mode automatically.
 .
+The default modes are
+.I mode x
+with
+.B gxditview
+in \%\f[CR]X\~Window\f[] and
+.I mode tty
+with device
+.I latin1
+under
+.B less
+on a terminal.
+.
+.
+.P
+There are two kinds of options for viewers.
+.Opt_long \fImode\fP-viewer
+chooses the normal viewer programs that run on their own in
+\%\f[CR]X\~Window\f[], while
+.Opt_long \fImode\fP-viewer-tty
+chooses programs that run on the terminal (on tty).
+.
+Most graphical viewers are programs running in \%\f[CR]X\~Window\f[],
+so there aren't many opportunities to call the tty viewers.
+.
+But they give the chance to view the output source; for example,
+.Opt_long ps\-viewer\-tty=less
+shows the content of the
+.I Postscript
+output with the pager
+.BR less .
+.
+.
+.P
+The \%\f[CR]X\~Window\f[] viewers are not critical, you can use both
+.Opt_long *\-viewer
+and
+.Opt_long *\-viewer\-tty
+for them; with
+.Opt_long *\-viewer\-tty
+the viewer program will not become independently, it just stays
+coupled with
+.BR groffer .
+But the program will not run if you specify a terminal program with
+.Opt_long *\-viewer
+because this viewer will stay in background without a chance to reach
+it.
+.
+So you really need
+.Opt_long *\-viewer\-tty
+for viewers that run on tty.
+.
 .
 .Opt_def -- auto
 Equivalent to
@@ -1105,15 +1128,15 @@
 .
 .
 .Opt_def -- dvi\-viewer prog
-Set the viewer program for
+Choose an \%\f[CR]X\~Window\f[] viewer program for
 .IR \%dvi\~mode .
 .
 This can be a file name or a program to be searched in
 .Env_var $PATH .
 .
-Known
+Known \%\f[CR]X\~Window\f[]
 .I \%dvi
-viewers inlude
+viewers include
 .BR \%xdvi (1)
 and
 .BR \%dvilx (1)
@@ -1121,6 +1144,15 @@
 In each case, arguments can be provided additionally.
 .
 .
+.Opt_def -- dvi\-viewer\-tty prog
+Choose a program running on the terminal for viewing the output of
+.IR \%dvi\~mode .
+.
+This can be a file name or a program to be searched in
+.Env_var $PATH ;
+arguments can be provided additionally.
+.
+.
 .Opt_def -- groff
 Equivalent to
 .Opt_long_arg mode groff .
@@ -1132,18 +1164,24 @@
 .
 .
 .Opt_def -- html\-viewer
-Set the web browser program for viewing in
+Choose an \%\f[CR]X\~Window\f[] web browser program for viewing in
 .I \%html\~mode .
 .
-Each program that accepts html input and allows the
-.BI \%file://localhost/ dir / file
-syntax on the command line is suitable as viewer program; it can be
-the path name of an executable file or a program in
+It can be the path name of an executable file or a program in
 .Env_var $PATH .
 .
 In each case, arguments can be provided additionally.
 .
 .
+.Opt_def -- html\-viewer\-tty
+Choose a terminal program for viewing the output of
+.I \%html\~mode .
+.
+It can be the path name of an executable file or a program in
+.Env_var $PATH ;
+arguments can be provided additionally.
+.
+.
 .Opt_def -- mode value
 .
 Set the display mode.
@@ -1257,7 +1295,7 @@
 Format in a
 .I \%groff\~text\~mode
 and write the result to standard output using a text pager program,
-even when in X\~\%Window.
+even when in \%\f[CR]X\~Window\f[].
 .
 .
 .TP
@@ -1276,7 +1314,7 @@
 .BR \%gxditview (@MAN1EXT@)
 program being distributed together with
 .BR \%groff .
-But the standard X\~tool
+But the standard \%\f[CR]X\~Window\f[] tool
 .BR \%xditview (1)
 can also be chosen with the option
 .Opt_long x\-viewer .
@@ -1352,13 +1390,21 @@
 .
 .
 .Opt_def -- pdf\-viewer prog
-Set the viewer program for
+Choose an \%\f[CR]X\~Window\f[] viewer program for
 .IR \%pdf\~mode .
 .
 This can be a file name or a program to be searched in
-.Env_var $PATH .
+.Env_var $PATH ;
+arguments can be provided additionally.
 .
-In each case, arguments can be provided additionally.
+.
+.Opt_def -- pdf\-viewer\-tty prog
+Choose a terminal viewer program for
+.IR \%pdf\~mode .
+.
+This can be a file name or a program to be searched in
+.Env_var $PATH ;
+arguments can be provided additionally.
 .
 .
 .Opt_def -- ps
@@ -1367,7 +1413,7 @@
 .
 .
 .Opt_def -- ps\-viewer prog
-Set the viewer program for
+Choose an \%\f[CR]X\~Window\f[] viewer program for
 .IR \%ps\~mode .
 .
 This can be a file name or a program to be searched in
@@ -1382,6 +1428,15 @@
 In each case, arguments can be provided additionally.
 .
 .
+.Opt_def -- ps\-viewer\-tty prog
+Choose a terminal viewer program for
+.IR \%ps\~mode .
+.
+This can be a file name or a program to be searched in
+.Env_var $PATH ;
+arguments can be provided additionally.
+.
+.
 .Opt_def -- text
 Equivalent to
 .Opt_long_arg mode text .
@@ -1401,6 +1456,17 @@
 .I man
 option
 .Opt_long_arg pager prog .
+The option argument can be a file name or a program to be searched in
+.Env_var $PATH ;
+arguments can be provided additionally.
+.
+.
+.Opt_def -- tty\-viewer\-tty prog
+This is equivalent to
+.Opt_long tty\-viewer
+because the programs for
+.I tty
+mode run on a terminal anyway.
 .
 .
 .Opt_def -- www
@@ -1413,24 +1479,34 @@
 .Opt_long html\-viewer .
 .
 .
+.Opt_def -- www\-viewer\-tty prog
+Equivalent to
+.Opt_long html\-viewer\-tty .
+.
+.
 .Opt_def -- X -- x
 Equivalent to
 .Opt_long_arg mode x .
 .
 .
 .Opt_def -- X\-viewer -- x\-viewer prog
-Set the viewer program for
+Choose an \%\f[CR]X\~Window\f[] viewer program for
 .IR \%x\~mode .
-.
 Suitable viewer programs are
 .BR \%gxditview (@MAN1EXT@)
 which is the default and
 .BR \%xditview (1).
+The argument can be any executable file or a program in
+.Env_var $PATH ;
+arguments can be provided additionally.
 .
-But the argument can be any executable file or a program in
-.Env_var $PATH .
 .
-In each case, arguments can be provided additionally.
+.Opt_def -- X\-viewer\-tty -- x\-viewer\-tty prog
+Choose a terminal viewer program for
+.IR \%x\~mode .
+The argument can be any executable file or a program in
+.Env_var $PATH ;
+arguments can be provided additionally.
 .
 .
 .TP
@@ -1444,7 +1520,7 @@
 .P
 Besides these,
 .B \%groffer
-accepts all arguments that are valid for the
+accepts all short options that are valid for the
 .BR \%groff (@MAN1EXT@)
 program.
 .
@@ -1455,7 +1531,7 @@
 to
 .BR \%groff .
 .
-Postprocessors, macro packages, compatibility with
+So postprocessors, macro packages, compatibility with
 .I classical
 .IR \%troff ,
 and much more can be manually specified.
@@ -1466,12 +1542,56 @@
 .\" --------------------------------------------------------------------
 .
 .Opt_def -- debug
-Enable three debugging informations.
+Enable five debugging informations.
+.
+The temporary files are kept and not deleted, the name of the
+temporary directory and the shell name for
+.File_name groffer2.sh
+are printed, the parameters are printed at several steps of
+development, and a function stack is output with function
+\f[CR]error_user()\f[] as well.
+.
+Neither the function call stack that is printed at each opening and
+closing of a function call nor the landmark information that is
+printed to determine how far the program is running are used.
+.
+This seems to be the most useful among all debugging options.
+.
+.
+.Opt_def -- debug\-all
+Enable all seven debugging informations including the function call
+stack and the landmark information.
 .
-A function call stack is printed at each opening and closing of a
-function call; a landmark information is printed to determine how far
-the program is running, and the early deletion of the temporary
-formatting files is prohibited.
+.
+.Opt_def -- debug\-keep
+Enable two debugging information, the printing of the name of the
+temporary directory and the keeping of the temporary files.
+.
+.
+.Opt_def -- debug\-lm
+Enable one debugging information, the landmark information.
+.
+.
+.Opt_def -- debug\-params
+Enable one debugging information, the parameters at several steps.
+.
+.
+.Opt_def -- debug\-shell
+Enable one debugging information, the shell name for
+.File_name groffer2.sh .
+.
+.
+.Opt_def -- debug\-stacks
+Enable one debugging information, the function call stack.
+.
+.
+.Opt_def -- debug\-tmpdir
+Enable one debugging information, the name of the temporary directory.
+.
+.
+.Opt_def -- debug\-user
+Enable one debugging information, the function stack with
+\f[CR]error_user()\f[].
 .
 .
 .Opt_def -- do-nothing
@@ -1482,20 +1602,27 @@
 This makes only sense in development.
 .
 .
+.Opt_def -- print=text
+Just print the argument to standard error.
+.
+This is good for parameter check.
+.
+.
 .Opt_def -- shell "shell_program"
 Specify the shell under which the
 .File_name \%groffer2.sh
 script should be run.
 .
+This option overwrites the automatic shell determination of the
+program.
+.
 If the argument
 .I shell_program
-is empty a former shell option is cancelled and the default shell is
-restored.
+is empty a former shell option and the automatic shell determination
+is cancelled and the default shell is restored.
 .
 Some shells run considerably faster than the standard shell.
 .
-It makes sense to set this option in a configuration file.
-.
 .
 .Opt_def - Q -- source
 Output the roff source code of the input files without further
@@ -1703,137 +1830,109 @@
 .
 .
 .\" --------------------------------------------------------------------
-.SS "X\~\%Window\~\%Toolkit Options"
+.SS "Options for man\~pages"
 .\" --------------------------------------------------------------------
 .
-The following long options were adapted from the corresponding
-X\~\%Toolkit options.
-.
-.B \%groffer
-will pass them to the actual viewer program if it is an X\~\%Window
-program.
-.
-Otherwise these options are ignored.
-.
-.
-.P
-Unfortunately these options use the old style of a single minus for
-long options.
-.
-For
-.B \%groffer
-that was changed to the standard with using a double minus for long
-options, for example,
-.B \%groffer
-uses the option
-.Opt_long font
-for the X\~\%option
-.Opt_short font .
-.
-.
-.P
-See
-.BR \%X (1),
-.BR \%X (7),
-and the documentation on the X\~\%Toolkit\~\%options for more details on
-these options and their arguments.
-.
-.
-.Opt_def -- background color
-Set the background color of the viewer window.
-.
-.
-.Opt_def -- bd pixels
-Specifies the color of the border surrounding the viewer window.
-.
-.
-.Opt_def -- bg color
-This is equivalent to
-.Opt_long background .
-.
-.
-.Opt_def -- bw pixels
-Specifies the width in pixels of the border surrounding the viewer
-window.
-.
-.
-.Opt_def -- display X-display
-Set the X\~\%display on which the viewer program shall be started, see the
-.I X\~\%Window
-documentation for the syntax of the argument.
-.
-.
-.Opt_def -- foreground color
-Set the foreground color of the viewer window.
-.
-.
-.Opt_def -- fg color
-This is equivalent to
-.Opt_short foreground .
-.
-.
-.Opt_def -- font font_name
-Set the font used by the viewer window.
-.
-The argument is an X\~\%font\~\%name.
-.
-.
-.Opt_def -- ft font_name
-This is equivalent to
-.Opt_long ft .
-.
-.
-.Opt_def -- geometry size_pos
-Set the geometry of the display window, that means its size and its
-starting position.
-.
-See
-.BR \%X (7)
-for the syntax of the argument.
-.
-.
-.Opt_def -- resolution value
-Set X\~\%resolution in dpi (dots per inch) in some viewer programs.
+.Opt_def -- apropos
+Start the
+.BR \%apropos (1)
+command or facility of
+.BR \%man (1)
+for searching the
+.I \%filespec
+arguments within all
+.I \%man\~page
+descriptions.
 .
-The only supported dpi values are
-.B 75
+Each
+.I \%filespec
+argument is taken for search as it is; section specific parts are not
+handled, such that
+.B 7 groff
+searches for the two arguments
+.B 7
 and
-.BR 100 .
+.B groff
+with a large result; for the
+.I \%filespec
+.B groff.7
+nothing will be found.
 .
-Actually, the default resolution for
-.B \%groffer
-is set to
-.BR 75\~dpi .
-The resolution also sets the default device in
-.IR "mode x" .
+The display differs from the
+.B \%apropos
+program by the following concepts:
+.RS
+.Topic
+construct a
+.I \%groff
+frame to the output of
+.BR \%apropos ,
+.Topic
+each
+.I \%filespec
+argument is searched on its own.
+.Topic
+the restriction by
+.Opt_long sections
+is handled as well,
+.Topic
+wildcard characters are allowed and handled without a further option.
+.RE
 .
 .
-.Opt_def -- rv
-Reverse foreground and background color of the viewer window.
+.Opt_def -- apropos\-data
+Show only the
+.B \%apropos
+descriptions for data documents, these are the
+.BR \%man (7)
+sections 4, 5, and 7.
 .
+Direct section declarations are ignored, wildcards are accepted.
 .
-.Opt_def -- title "'some text'"
-Set the title for the viewer window.
 .
+.Opt_def -- apropos\-devel
+Show only the
+.B \%apropos
+descriptions for development documents, these are the
+.BR man (7)
+sections 2, 3, and 9.
 .
-.Opt_def -- xrm "'resource'"
-Set X\~\%resource.
+Direct section declarations are ignored, wildcards are accepted.
 .
 .
-.\" --------------------------------------------------------------------
-.SS "Options for man"
-.\" --------------------------------------------------------------------
+.Opt_def -- apropos\-progs
+Show only the
+.B \%apropos
+descriptions for documents on programs, these are the
+.BR \%man (7)
+sections 1, 6, and 8.
 .
-The long options of
-.B \%groffer
-were synchronized with the long options of GNU
-.BR man .
+Direct section declarations are ignored, wildcards are accepted.
 .
-All long options of GNU
-.B man
-are recognized, but not all of these options are important to
-.BR \%groffer ,
-so most of them are just ignored.
+.
+.Opt_def -- whatis
+For each
+.I \%filespec
+argument search all
+.I \%man\~pages
+and display their description \[em] or say that it is not a
+.IR \%man\~page .
+This differs from
+.IR man 's
+.B whatis
+output by the following concepts
+.RS
+.Topic
+each retrieved file name is added,
+.Topic
+local files are handled as well,
+.Topic
+the display is framed by a
+.I groff
+output format,
+.Topic
+wildcard characters are allowed without a further option.
+.RE
 .
 .
 .P
@@ -1870,6 +1969,30 @@
 option.
 .
 .
+.Opt_def -- no-special
+Disable former calls of
+.Opt_long all ,
+.Opt_long apropos* ,
+and
+.Opt_long whatis .
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Long options taken over from GNU man"
+.\" --------------------------------------------------------------------
+.
+The long options of
+.B \%groffer
+were synchronized with the long options of \f[CR]GNU\f[]
+.BR man .
+.
+All long options of \f[CR]GNU\f[]
+.B man
+are recognized, but not all of these options are important to
+.BR \%groffer ,
+so most of them are just ignored.
+.
+.
 .P
 In the following, the
 .B man
@@ -1879,13 +2002,13 @@
 .
 .
 .P
-The full set of long and short options of the GNU
+The full set of long and short options of the \f[CR]GNU\f[]
 .B man
 program can be passed via the environment variable
 .Env_var $MANOPT ;
 see
 .BR \%man (1)
-if your system has GNU
+if your system has \f[CR]GNU\f[]
 .B man
 installed.
 .
@@ -1985,27 +2108,144 @@
 is a comma-separated list.
 .
 .
-.Opt_def -- whatis
-Instead of displaying the content, get the one-liner description from
-the retrieved
-.I \%man\~page
-files \[em] or say that it is not a
-.IR \%man\~page .
-.
-.
 .Opt_def -- where
 Eqivalent to
 .Opt_long location .
 .
 .
 .\" --------------------------------------------------------------------
+.SS "X\~\%Window\~\%Toolkit Options"
+.\" --------------------------------------------------------------------
+.
+The following long options were adapted from the corresponding
+\%\f[CR]X\~\Window\~Toolkit\f[] options.
+.
+.B \%groffer
+will pass them to the actual viewer program if it is an
+\%\f[CR]X\~Window\f[] program.
+.
+Otherwise these options are ignored.
+.
+.
+.P
+Unfortunately these options use the old style of a single minus for
+long options.
+.
+For
+.B \%groffer
+that was changed to the standard with using a double minus for long
+options, for example,
+.B \%groffer
+uses the option
+.Opt_long font
+for the \%\f[CR]X\~Window\f[] option
+.Opt_short font .
+.
+.
+.P
+See
+.BR \%X (1),
+.BR \%X (7),
+and the documentation on the \%\f[CR]X\~Window\~Toolkit\f[] options
+for more details on these options and their arguments.
+.
+.
+.Opt_def -- background color
+Set the background color of the viewer window.
+.
+.
+.Opt_def -- bd pixels
+Specifies the color of the border surrounding the viewer window.
+.
+.
+.Opt_def -- bg color
+This is equivalent to
+.Opt_long background .
+.
+.
+.Opt_def -- bw pixels
+Specifies the width in pixels of the border surrounding the viewer
+window.
+.
+.
+.Opt_def -- display X-display
+Set the \%\f[CR]X\~Window\f[] display on which the viewer program
+shall be started, see the \%\f[CR]X\~Window\f[] documentation for the
+syntax of the argument.
+.
+.
+.Opt_def -- foreground color
+Set the foreground color of the viewer window.
+.
+.
+.Opt_def -- fg color
+This is equivalent to
+.Opt_short foreground .
+.
+.
+.Opt_def -- font font_name
+Set the font used by the viewer window.
+.
+The argument is an \%\f[CR]X\~Window\f[] font name.
+.
+.
+.Opt_def -- ft font_name
+This is equivalent to
+.Opt_long ft .
+.
+.
+.Opt_def -- geometry size_pos
+Set the geometry of the display window, that means its size and its
+starting position.
+.
+See
+.BR \%X (7)
+for the syntax of the argument.
+.
+.
+.Opt_def -- resolution value
+Set \%\f[CR]X\~Window\f[] resolution in dpi (dots per inch) in some
+viewer programs.
+.
+The only supported dpi values are
+.B 75
+and
+.BR 100 .
+.
+Actually, the default resolution for
+.B \%groffer
+is set to
+.BR 75\~dpi .
+The resolution also sets the default device in
+.IR "mode x" .
+.
+.
+.Opt_def -- rv
+Reverse foreground and background color of the viewer window.
+.
+.
+.Opt_def -- title "'some text'"
+Set the title for the viewer window.
+.
+.
+.Opt_def -- xrm "'resource'"
+Set \f[CR]\%X\~Window\f[] resource.
+.
+.
+.\" --------------------------------------------------------------------
 .SS "Filespec Arguments"
 .\" --------------------------------------------------------------------
 .
 A
 .I \%filespec
-parameter is an argument meaning an input source, such as a file name
-or template for searching
+parameter is an argument that is not an option or option argument.
+.
+It means an input source.
+.
+In
+.BR \%groffer ,
+.I \%filespec
+parameters are a file name or a template for searching
 .IR \%man\~pages .
 .
 These input sources are collected and composed into a single output
@@ -2015,55 +2255,30 @@
 .
 .
 .P
-The strange \%POSIX behavior that maps all arguments behind the first
-non-option argument into
+The strange \%\f[CR]POSIX\f[] behavior to regard all arguments behind
+the first non-option argument as
 .I \%filespec
 arguments is ignored.
 .
-The GNU behavior to recognize options even when mixed with
+The \f[CR]GNU\f[] behavior to recognize options even when mixed with
 .I \%filespec
 arguments is used througout.
 .
 But, as usual, the double minus argument
 .Opt_long
-still takes all following arguments as
+ends the option handling and interprets all following arguments as
 .I \%filespec
-arguments.
-.
-.
-.P
-Each
-.I \%filespec
-parameters can have one of the following forms.
+arguments; so the \%\f[CR]POSIX\f[] behavior can be easily adopted.
 .
 .
 .P
-No
-.I \%filespec
-parameters means that
-.B \%groffer
-waits for standard input.
-.
-The minus option
-.Opt_short ""
-stands for standard input, too, but can occur several times.
-.
-Next
-.I \%filespec
-is tested whether it is the path name of an existing file.
-.
-Otherwise it is assumed as a searching pattern for a
-.IR \%man\~page .
-.
-.
-.P
-On each system, the
+For the following, it is necessary to know that on each system the
 .I \%man\~pages
 are sorted according to their content into several sections.
 .
 The
 .I classical man sections
-have a single-character name, either are a digit from
+have a single-character name, either a digit from
 .B 1
 to
 .B 9
@@ -2074,10 +2289,8 @@
 .
 In the following, a stand-alone character
 .I s
-means this scheme.
-.
-.
-.P
+stands for a
+.IR "classical man section" .
 The internal precedence of
 .B \%man
 for searching
@@ -2095,6 +2308,33 @@
 .
 .
 .P
+Each
+.I \%filespec
+parameter can have one of the following forms in decreasing sequence.
+.
+.
+.Topic
+No
+.I \%filespec
+parameters means that
+.B \%groffer
+waits for standard input.
+.
+The minus option
+.Opt_short ""
+stands for standard input, too; it can occur several times.
+.
+.
+.Topic
+Next a
+.I \%filespec
+is tested whether it is the path name of an existing file.
+.
+Otherwise it is assumed to be a searching pattern for a
+.IR \%man\~page .
+.
+.
+.Topic
 .BI \%man: name ( section )
 and
 .IB \%name ( section )
@@ -2109,10 +2349,10 @@
 system.
 .
 .
-.P
+.Topic
 Next some patterns based on the
 .I classical man sections
-were constructed.
+are checked.
 .
 .BI \%man: name . s
 and
@@ -2127,15 +2367,15 @@
 .I classical man section
 mentioned above.
 .
-Otherwise search for a
+Otherwise a
 .I \%man\~page
 named
 .IR \%name.s
-in the lowest
+is searched in the lowest
 .B man\~section .
 .
 .
-.P
+.Topic
 Now
 .BI \%man: name
 searches for a
@@ -2146,7 +2386,7 @@
 .IR \%name .
 .
 .
-.P
+.Topic
 The pattern
 .I \%s\~name
 originates from a strange argument parsing of the
@@ -2163,16 +2403,16 @@
 .I \%name
 in man\~section
 .IR s ,
-otherwise interpret
+otherwise interpret both
 .I s
-as a file argument and
+and
 .I \%name
-as another
+as two independent
 .I \%filespec
-argument.
+arguments.
 .
 .
-.P
+.Topic
 We are left with the argument
 .I \%name
 which is not an existing file.
@@ -2187,6 +2427,16 @@
 .
 .
 .P
+Wildcards in
+.I \%filespec
+arguments are only accepted for
+.Opt_long apropos*
+and
+.Opt_long whatis ;
+for normal display, they are interpreted as characters.
+.
+.
+.P
 Several file name arguments can be supplied.
 .
 They are mixed by
@@ -2235,7 +2485,7 @@
 .
 .P
 Several different modes are offered, graphical modes for
-.IR \%X\~Window ,
+\f[CR]\%X\~Window\f[],
 .IR \%text\~modes ,
 and some direct
 .I \%groff\~modes
@@ -2269,19 +2519,19 @@
 .SS "Graphical Display Modes"
 .\" --------------------------------------------------------------------
 .
-The graphical display modes work only in the
-.I X\~\%Window environment
-(or similar implementations within other windowing environments).
+The graphical display modes work mostly in the \%\f[CR]X\~Window\f[]
+environment (or similar implementations within other windowing
+environments).
 .
 The environment variable
 .Env_var $DISPLAY
 and the option
 .Opt_long display
-are used for specifying the X\~\%display to be used.
+are used for specifying the \%\f[CR]X\~Window\f[] display to be used.
 .
-If neither is given,
+If this environment variable is empty
 .B \%groffer
-assumes that no X and changes to one
+assumes that no \%\f[CR]X\~Window\f[] is running and changes to a
 .IR \%text\~mode .
 .
 You can change this automatic behavior by the option
@@ -2290,10 +2540,10 @@
 .
 .P
 Known viewers for the graphical display modes and their standard
-X\~\%Window viewer progams are
+\%\f[CR]X\~Window\f[] viewer progams are
 .
 .Topic
-X\~\%Window
+\%\f[CR]X\~Window\f[]
 .I roff
 viewers such as
 .BR \%gxditview (@MAN1EXT@)
@@ -2325,7 +2575,7 @@
 .nh
 .RI ( html
 or
-.IR \%www\~mode ),
+.IR \%www\~mode ).
 .hy
 .RE
 .
@@ -2343,13 +2593,12 @@
 .
 .P
 These graphical viewers can be customized by options of the
-X\~\%Window\~\%Toolkit.
+\%\f[CR]X\~Window\~Toolkit\f[].
 .
 But the
 .B \%groffer
 options use a leading double minus instead of the single minus used by
-the
-.I X\~\%Window\~\%Toolkit .
+the \%\f[CR]X\~Window\~Toolkit\f[].
 .
 .
 .\" --------------------------------------------------------------------
@@ -2480,7 +2729,9 @@
 .
 .TP
 .Opt_long man
-forces to interpret all file parameters as filespecs for searching
+forces to interpret all file parameters as
+.I \%filespecs
+for searching
 .IR \%man\~pages .
 .
 .TP
@@ -2506,7 +2757,7 @@
 .IR \%man\~pages .
 .
 All long options, all environment variables, and most of the
-functionality of the GNU
+functionality of the \f[CR]GNU\f[]
 .BR \%man (1)
 program were implemented.
 .
@@ -2612,7 +2863,7 @@
 .
 .
 .P
-The locale (language) is determined like in GNU
+The locale (language) is determined like in \f[CR]GNU\f[]
 .BR man ,
 that is from highest to lowest precedence:
 .Topic
@@ -2635,8 +2886,8 @@
 .
 .
 .P
-The language locale is usually specified in the \%POSIX 1003.1 based
-format:
+The language locale is usually specified in the
+\%\f[CR]POSIX\~1003.1\f[] based format:
 .P
 .nh
 \f[I]<language>\f[][\f[CB]_\f[]\f[I]<territory>\f[][\f[CB].\f[]\
@@ -2707,8 +2958,10 @@
 The search can further be restricted by limiting it to certain
 sections.
 .
-A single section can be specified within each filespec argument,
-several sections as a colon-separated list in command line option
+A single section can be specified within each
+.I \%filespec
+argument, several sections as a colon-separated list in command line
+option
 .Opt_long sections
 or environment variable
 .Env_var $MANSECT .
@@ -2750,7 +3003,7 @@
 .BR \%bzip2 (1)
 it is decompressed on-the-fly.
 .
-This includes the GNU
+This includes the \f[CR]GNU\f[]
 .BR \%.gz ,
 .BR \%.bz2 ,
 and the traditional
@@ -2772,7 +3025,7 @@
 .
 All environment variables of
 .BR \%groff (@MAN1EXT@)
-and GNU
+and \f[CR]GNU\f[]
 .BR \%man (1)
 and some standard system variables are honored.
 .
@@ -2793,6 +3046,10 @@
 so arguments containing white-space or special shell characters should
 be quoted.
 .
+Do not forget to export this variable, otherwise it does not exist
+during the run of
+.BR groffer .
+.
 .
 .\" --------------------------------------------------------------------
 .SS "System Variables"
@@ -2812,8 +3069,8 @@
 .
 .TP
 .Env_var $DISPLAY
-If this variable is set this indicates that the X\~\%Window system is
-running.
+If this variable is set this indicates that the \%\f[CR]X\~Window\f[]
+system is running.
 .
 Testing this variable decides on whether graphical or text output is
 generated.
@@ -2821,7 +3078,7 @@
 This variable should not be changed by the user carelessly, but it can
 be used to start the graphical
 .B \%groffer
-on a remote X\~\%terminal.
+on a remote \%\f[CR]X\~Window\f[] terminal.
 .
 For example, depending on your system,
 .B \%groffer
@@ -2860,10 +3117,7 @@
 see
 .BR \%setlocale (3).
 .
-The locale values\~\c
-.B C
-and
-.B \%POSIX
+The locale values \f[CR]C\f[] and \%\f[CR]POSIX\f[]
 stand for the default, i.e. the
 .I \%man\~page
 directories without a language prefix.
@@ -2907,7 +3161,7 @@
 .B \%groffer
 as well.
 .
-The following variables have a direct meaning for the
+The following variable has a direct meaning for the
 .B \%groffer
 program.
 .
@@ -2915,7 +3169,9 @@
 .Env_var $GROFF_TMPDIR
 If the value of this variable is an existing, writable directory,
 .B \%groffer
-uses it for storing its temporary files, just as groff does.
+uses it for storing its temporary files, just as
+.B groff
+does.
 .
 .
 .\" --------------------------------------------------------------------
@@ -3095,8 +3351,12 @@
 tasks:
 .
 .Topic
-Preset command line options by writing them into lines starting with a
-minus sign.
+Preset command line options, such as choosing a
+.I \%mode
+or a viewer.
+.
+These are written into lines starting with a single or double minus
+sign, followed by the option name.
 .
 .Topic
 Preset environment variables recognized by
@@ -3104,30 +3364,19 @@
 but do not forget to export them.
 .
 .Topic
-Write a function for calling a viewer program for a special
-.I \%mode
-and feed this name into its corresponding
+You can also write a shell function for calling, for example a viewer
+program for some
+.IR \%mode .
+Such a function can be fed into a corresponding
 .Opt_long \f[I]mode\f[]\-viewer
 option.
 .
-Note that the name of such a function must either be given as the full
-file name or coincide with some existing program in the system path
-.Env_var $PATH
-in order to be recognized by
-.BR groffer .
-.
 .Topic
 Enter
 .Opt_long shell
 to specify a shell for the run of
 .File_name groffer2.sh .
-Some shells run much faster than the standard shell; the fastest
-Bourne shell that I know is
-.BR ash (1).
-It makes really sense to add a line like
-.Opt_long shell=ash
-to your configuration file as long as the given shell is installed on
-your system.
+Some shells run much faster than the standard shell.
 .
 .
 .P
@@ -3142,7 +3391,7 @@
 # groffer configuration file
 #
 # groffer options that are used in each call of groffer
-\-\-shell=ash
+\-\-shell=ksh
 \-\-foreground=DarkBlue
 \-\-resolution=100
 \-\-x\-viewer='gxditview \-geometry 900x1200'
@@ -3172,7 +3421,7 @@
 .
 .Topic
 Use
-.B ash
+.B ksh
 as the shell to run the
 .B \%groffer
 script; if it works it should be faster than the usual
@@ -3219,8 +3468,8 @@
 .
 That allows to start
 .B \%groffer
-in the standard X\~\%display, even when the program is called from a
-text console.
+in the standard \%\f[CR]X\~Window\f[] display, even when the program
+is called from a text console.
 .
 .
 .Topic
@@ -3253,11 +3502,11 @@
 .File_name meintro.ms.gz
 in the directory
 .File_name /usr/local/share/doc/groff ,
-using
+using the standard viewer
 .B \%gxditview
-as graphical viewer when in X\~\%Window, or the
+as graphical viewer when in \%\f[CR]X\~Window\f[], or the
 .BR \%less (1)
-pager program when not in X.
+pager program when not in \%\f[CR]X\~Window\f[].
 .
 .
 .TP
@@ -3345,7 +3594,7 @@
 .
 .
 .TP
-.Shell_cmd "LANG=de\~groffer\~--man\~--www\~--www-viever=mozilla\~ls"
+.Shell_cmd "LANG=de\~groffer\~--man\~--www\~--www-viever=galeon\~ls"
 .
 Retrieve the German
 .I \%man\~page
@@ -3446,20 +3695,20 @@
 .
 .P
 Both scripts are compatible with both
-GNU and \%POSIX.
+\f[CR]GNU\f[] and \%\f[CR]POSIX\f[].
 .
-\%POSIX compatibility refers to
-.B IEEE P1003.2/D11.2
-of September 1991, a very early version of the \%POSIX standard that
-is still freely available in the internet at
+\%\f[CR]POSIX\f[] compatibility refers to
+\%\f[CR]IEEE\~P1003.2/D11.2\f[] of September 1991, a very early
+version of the \%\f[CR]POSIX\f[] standard that is still freely
+available in the internet at
 .URL http://\:www.funet.fi/\:pub/\:doc/\:posix/\:p1003.2/\:d11.2/\:all \
-"\%POSIX P1003.2 draft 11.2" .
+"\%POSIX\~P1003.2\~draft\~11.2" .
 .
 .
 .P
 Only a restricted set of shell language elements and shell builtins is
 used to achieve even compatibility with some Bourne shells that are
-not fully \%POSIX compatible.
+not fully \%\f[CR]POSIX\f[] compatible.
 .
 The
 .B \%groffer
@@ -3494,11 +3743,9 @@
 The
 .B \%groffer
 program provides its own parser for command line arguments that is
-compatible to both
-.I \%POSIX
+compatible to both \%\f[CR]POSIX\f[]
 .BR \%getopts (1)
-and
-.I \%GNU
+and \%\f[CR]GNU\f[]
 .BR \%getopt (1).
 It can handle option arguments and file names containing white space
 and a large set of special characters.
@@ -3537,15 +3784,17 @@
 An argument of
 .Opt_--
 ends option parsing; all further command line arguments are
-interpreted as filespec parameters, i.e. file names or constructs for
-searching
+interpreted as
+.I \%filespec
+parameters, i.e. file names or constructs for searching
 .IR \%man\~pages ).
 .
 .
 .Topic
 All command line arguments that are neither options nor option
-arguments are interpreted as filespec parameters and stored until
-option parsing has finished.
+arguments are interpreted as
+.I \%filespec
+parameters and stored until option parsing has finished.
 .
 For example, the command line
 .Shell_cmd "groffer file1 -a -o arg file2"
@@ -3554,12 +3803,13 @@
 .
 .
 .P
-The free mixing of options and filespec parameters follows the GNU
-principle.
+The free mixing of options and
+.I \%filespec
+parameters follows the GNU principle.
 .
-That does not fulfill the strange option behavior of \%POSIX that ends
-option processing as soon as the first non-option argument has been
-reached.
+That does not fulfill the strange option behavior of \%\f[CR]POSIX\f[]
+that ends option processing as soon as the first non-option argument
+has been reached.
 .
 The end of option processing can be forced by the option
 .RB ` \-\- '
Index: groff/contrib/groffer/groffer.sh
diff -u groff/contrib/groffer/groffer.sh:1.32 
groff/contrib/groffer/groffer.sh:1.33
--- groff/contrib/groffer/groffer.sh:1.32       Wed Aug  3 06:32:11 2005
+++ groff/contrib/groffer/groffer.sh    Tue Aug 23 09:57:09 2005
@@ -9,7 +9,7 @@
 # Written by Bernd Warken
 
 # This file is part of `groffer', which is part of `groff' version
-# 1.19.2.
+# @address@hidden  See $_GROFF_VERSION.
 
 # `groff' is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -27,14 +27,15 @@
 # Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301,
 # USA.
 
-_PROGRAM_VERSION='0.9.21';
-_LAST_UPDATE='2 August 2005';
+########################################################################
+
+_PROGRAM_VERSION='0.9.22';
+_LAST_UPDATE='22 August 2005';
 
 export _PROGRAM_VERSION;
 export _LAST_UPDATE;
 
 export GROFFER_OPT;            # option environment for groffer
-export _OUTPUT_FILE_NAME;      # output generated, see main_set_res..()
 
 export _CONF_FILE_ETC;         # configuration file in /etc
 export _CONF_FILE_HOME;                # configuration file in $HOME
@@ -55,8 +56,18 @@
 _SQ="'";
 _TAB=' ';
 
+export _ERROR;
+_ERROR='7';                    # for syntax errors; no `-1' in `ash'
+
 # @...@ constructs
 
+export _GROFF_VERSION
+_GROFF_VERSION='@VERSION@';
+if test address@hidden@_ = _${_AT}VERSION${_AT}_
+then
+  _GROFF_VERSION='1.19.2';
+fi;
+
 export _AT_BINDIR_AT;
 export _AT_G_AT;
 export _AT_LIBDIR_AT;
@@ -103,11 +114,20 @@
 if test _"$(echo "$(echo 'test')")"_ \
      != _test_
 then
-  echo 'The "$()" construct did not work' >&2;
+  echo 'The "$()" construct did not work.' >&2;
+  exit "${_ERROR}";
+fi;
+
+# Test of sed program
+if test _"$(echo red | sed -e 's/r/s/')"_ != _sed_
+then
+  echo 'The sed program did not work.' >&2;
   exit "${_ERROR}";
 fi;
 
 
+########################### configuration
+
 # read and transform the configuration files, execute the arising commands
 for f in "${_CONF_FILE_HOME}" "${_CONF_FILE_ETC}"
 do
@@ -148,6 +168,14 @@
   fi;
 done;
 
+# integrate $GROFFER_OPT into the command line; it isn't needed any more
+if test _"${GROFFER_OPT}"_ != __
+then
+  eval set x "${GROFFER_OPT}" '"$@"';
+  shift;
+  GROFFER_OPT='';
+fi;
+
 
 ########################### Determine the shell
 
@@ -156,15 +184,15 @@
 # use "``" instead of "$()" for using the case ")" construct
 # do not use "" quotes because of ksh
 _SHELL=`
-  # $x means list
-  # $s means shell
+  # $x means list.
+  # $s means shell.
+  # The command line arguments are taken over.
+  # Shifting herein does not have an effect outside.
   export x;  
-  case " ${GROFFER_OPT} $*" in
+  case " $*" in
   *\ --sh*)                    # abbreviation for --shell
     x='';
     s='';
-    eval set x "${GROFFER_OPT}" '"$@"';
-    shift;
     # determine all --shell arguments, store them in $x in reverse order
     while test $# != 0
     do
@@ -206,6 +234,7 @@
           if test _"$i"_ = __
           then
             # use the empty argument as the default shell
+            echo empty;
             break;
           else
             # test $i on being a shell program;
@@ -235,7 +264,27 @@
   esac;
 `
 
+########################### test fast shells for automatic run
+
+if test _"${_SHELL}"_ = __
+then
+  for s in ksh ash dash pdksh zsh posh
+  do
+    if test _"$(eval "$s -c 'echo ok'" 2>${_NULL_DEV})"_ = _ok_ >&2
+    then
+      _SHELL="$s";
+      break;
+    fi;
+  done;
+fi;
+
+
 ########################### start groffer2.sh
+
+if test _"${_SHELL}"_ = _empty_
+then
+  _SHELL='';
+fi;
 
 if test _"${_SHELL}"_ = __
 then
Index: groff/contrib/groffer/groffer2.sh
diff -u groff/contrib/groffer/groffer2.sh:1.2 
groff/contrib/groffer/groffer2.sh:1.3
--- groff/contrib/groffer/groffer2.sh:1.2       Wed Aug  3 06:32:11 2005
+++ groff/contrib/groffer/groffer2.sh   Tue Aug 23 09:57:09 2005
@@ -12,7 +12,7 @@
 # Free Software Foundation, Inc.
 # Written by Bernd Warken
 
-# Last update: 2 August 2005
+# Last update: 22 August 2005
 
 # This file is part of `groffer', which is part of `groff'.
 
@@ -34,11 +34,95 @@
 
 
 ########################################################################
-# diagnostic messages for debugging
+#             Test of rudimentary shell functionality
+########################################################################
+
+
+########################################################################
+# Test of `unset'
+#
+export _UNSET;
+export _foo;
+_foo=bar;
+_res="$(unset _foo 2>&1)";
+if unset _foo >${_NULL_DEV} 2>&1 && \
+   test _"${_res}"_ = __ && test _"${_foo}"_ = __
+then
+  _UNSET='unset';
+  eval "${_UNSET}" _foo;
+  eval "${_UNSET}" _res;
+else
+  _UNSET=':';
+fi;
+
+
+########################################################################
+# Test of `test'.
+#
+if test a = a && test a != b && test -f "${_GROFFER_SH}"
+then
+  :;
+else
+  echo '"test" did not work.' >&2;
+  exit "${_ERROR}";
+fi;
+
+
+########################################################################
+# Test of `echo' and the `$()' construct.
+#
+if echo '' >${_NULL_DEV}
+then
+  :;
+else
+  echo '"echo" did not work.' >&2;
+  exit "${_ERROR}";
+fi;
+if test _"$(t1="$(echo te)" &&
+            t2="$(echo '')" &&
+            t3="$(echo 'st')" &&
+            echo "${t1}${t2}${t3}")"_ \
+     != _test_
+then
+  echo 'The "$()" construct did not work' >&2;
+  exit "${_ERROR}";
+fi;
+
+
+########################################################################
+# Test of sed program; test in groffer.sh is not valid here.
+#
+if test _"$(echo red | sed -e 's/r/s/')"_ != _sed_
+then
+  echo 'The sed program did not work.' >&2;
+  exit "${_ERROR}";
+fi;
+
+
+########################################################################
+# Test of function definitions.
 #
-export _DEBUG;
-_DEBUG='no';                   # disable debugging information
-#_DEBUG='yes';                 # enable debugging information
+_t_e_s_t_f_u_n_c_()
+{
+  return 0;
+}
+
+if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV}
+then
+  :;
+else
+  echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
+  exit "${_ERROR}";
+fi;
+
+
+########################################################################
+#                    debug - diagnostic messages
+########################################################################
+
+export _DEBUG_STACKS;
+_DEBUG_STACKS='no';            # disable stack output in each function
+#_DEBUG_STACKS='yes';          # enable stack output in each function
 
 export _DEBUG_LM;
 _DEBUG_LM='no';                        # disable landmark messages
@@ -56,21 +140,89 @@
 _DEBUG_PRINT_SHELL='no';       # disable printing of the shell name
 #_DEBUG_PRINT_SHELL='yes';     # enable printing of the shell name
 
-
-# test of $GROFFER_OPT and $* on `--debug' with shortest abbreviation `--deb'
-case " ${GROFFER_OPT} $* " in
-*' --deb '*|*' --debu '*|*' --debug '*)
-  _DEBUG='yes';
-  _DEBUG_LM='yes';
-  _DEBUG_KEEP_FILES='yes';
-  _DEBUG_PRINT_PARAMS='yes';
-  _DEBUG_PRINT_SHELL='yes';
+export _DEBUG_PRINT_TMPDIR;
+_DEBUG_PRINT_TMPDIR='no';      # disable printing of the temporary dir
+#_DEBUG_PRINT_TMPDIR='yes';    # enable printing of the temporary dir
+
+export _DEBUG_USER_WITH_STACK;
+_DEBUG_USER_WITH_STACK='no';   # disable stack dump in error_user()
+#_DEBUG_USER_WITH_STACK='yes'; # enable stack dump in error_user()
+
+# determine all --debug* options
+case " $*" in
+*\ --debug*)
+  case " $* " in
+  *' --debug '*)
+    # _DEBUG_STACKS='yes';
+    # _DEBUG_LM='yes';
+    _DEBUG_KEEP_FILES='yes';
+    _DEBUG_PRINT_PARAMS='yes';
+    _DEBUG_PRINT_SHELL='yes';
+    _DEBUG_PRINT_TMPDIR='yes';
+    _DEBUG_USER_WITH_STACK='yes';
+    ;;
+  esac;
+  d=' --debug-all --debug-keep --debug-lm --debug-params --debug-shell '\
+'--debug-stacks --debug-tmpdir --debug-user ';
+  for i
+  do
+    case "$i" in
+    --debug-s)
+      echo 'The abbreviation --debug-s has multiple options: '\
+'--debug-shell and --debug-stacks.' >&2
+      exit "${_ERROR}";
+      ;;
+    esac;
+    case "$d" in
+    *\ ${i}*)
+      # extract whole word of abbreviation $i
+      s="$(cat <<EOF | sed -n -e 's/^.* \('"$i"'[^ ]*\) .*/\1/p'
+$d
+EOF
+)"
+      case "$s" in
+      '') continue; ;;
+      --debug-all)
+        _DEBUG_STACKS='yes';
+        _DEBUG_LM='yes';
+        _DEBUG_KEEP_FILES='yes';
+        _DEBUG_PRINT_PARAMS='yes';
+        _DEBUG_PRINT_SHELL='yes';
+        _DEBUG_PRINT_TMPDIR='yes';
+        _DEBUG_USER_WITH_STACK='yes';
+        ;;
+      --debug-keep)
+        _DEBUG_PRINT_TMPDIR='yes';
+        _DEBUG_KEEP_FILES='yes';
+        ;;
+      --debug-lm)
+        _DEBUG_LM='yes';
+        ;;
+      --debug-params)
+        _DEBUG_PRINT_PARAMS='yes';
+        ;;
+      --debug-shell)
+        _DEBUG_PRINT_SHELL='yes';
+        ;;
+      --debug-stacks)
+        _DEBUG_STACKS='yes';
+        ;;
+      --debug-tmpdir)
+        _DEBUG_PRINT_TMPDIR='yes';
+        ;;
+      --debug-user)
+        _DEBUG_USER_WITH_STACK='yes';
+        ;;
+      esac;
+      ;;
+    esac;
+  done
   ;;
 esac;
 
 if test _"${_DEBUG_PRINT_PARAMS}"_ = _yes_
 then
-  echo "parameters: ${GROFFER_OPT} $@" >&2;
+  echo "parameters: $@" >&2;
 fi;
 
 if test _"${_DEBUG_PRINT_SHELL}"_ = _yes_
@@ -115,7 +267,6 @@
 # function return values; `0' means ok; other values are error codes
 export _ALL_EXIT;
 export _BAD;
-export _ERROR;
 export _GOOD;
 export _NO;
 export _OK;
@@ -123,10 +274,7 @@
 
 _GOOD='0';                     # return ok
 _BAD='1';                      # return negatively, error code `1'
-_ERROR='7';                    # for syntax errors; no `-1' in `ash'
-
- # all exit codes (for `trap_set()')
-_ALL_EXIT="${_GOOD} ${_BAD} ${_ERROR}";
+# $_ERROR was already defined as `7' in groffer.sh.
 
 _NO="${_BAD}";
 _YES="${_GOOD}";
@@ -160,13 +308,16 @@
 # _VIEWER_* viewer programs for different modes (only X is necessary)
 # _VIEWER_* a comma-separated list of viewer programs (with options)
 export _VIEWER_DVI;            # viewer program for dvi mode
-export _VIEWER_PS;             # viewer program for ps mode
-export _VIEWER_HTML_X;         # viewer program for html mode in X
 export _VIEWER_HTML_TTY;       # viewer program for html mode in tty
+export _VIEWER_HTML_X;         # viewer program for html mode in X
+export _VIEWER_PDF;            # viewer program for pdf mode
+export _VIEWER_PS;             # viewer program for ps mode
+export _VIEWER_X;              # viewer program for X mode
 _VIEWER_DVI='kdvi,xdvi,dvilx';
+_VIEWER_HTML_TTY='lynx';
+_VIEWER_HTML_X='konqueror,mozilla,netscape,galeon,opera,amaya,arena';
 _VIEWER_PDF='kghostview --scale 1.45,ggv,xpdf,acroread,kpdf';
 _VIEWER_PS='kghostview --scale 1.45,ggv,gv,ghostview,gs_x11,gs';
-_VIEWER_HTML='konqueror,mozilla,netscape,opera,amaya,arena,lynx';
 _VIEWER_X='gxditview,xditview';
 
 # Search automatically in standard sections `1' to `8', and in the
@@ -174,8 +325,16 @@
 # exist even more sections, mostly containing a set of man pages
 # special to a specific program package.  These aren't searched for
 # automatically, but must be specified on the command line.
-export _MAN_AUTO_SEC;
-_MAN_AUTO_SEC="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'"
+export _MAN_AUTO_SEC_LIST;
+_MAN_AUTO_SEC_LIST="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'";
+export _MAN_AUTO_SEC_CHARS;
+_MAN_AUTO_SEC_CHARS='[123456789no]';
+
+export _SPACE_SED;
+_SPACE_SED='['"${_SP}${_TAB}"']';
+
+export _SPACE_CASE;
+_SPACE_CASE='[\'"${_SP}"'\'"${_TAB}"']';
 
 export _PROCESS_ID;            # for shutting down the program
 _PROCESS_ID="$$";
@@ -226,16 +385,21 @@
 _OPTS_GROFFER_SHORT_NA="'h' 'Q' 'v' 'V' 'X' 'Z'";
 _OPTS_GROFFER_SHORT_ARG="'T'";
 
-_OPTS_GROFFER_LONG_NA="'auto' 'debug' 'default' 'do-nothing' 'dvi' \
+_OPTS_GROFFER_LONG_NA="'auto' \
+'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \
+'debug' 'debug-all' 'debug-keep' 'debug-lm' 'debug-params' 'debug-shell' \
+'debug-stacks' 'debug-tmpdir' 'debug-user' 'default' 'do-nothing' 'dvi' \
 'groff' 'help' 'intermediate-output' 'html' 'man' \
-'no-location' 'no-man' 'pdf' 'ps' 'rv' 'source' 'text' 'text-device' \
-'title' 'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
+'no-location' 'no-man' 'no-special' 'pdf' 'ps' 'rv' 'source' \
+'text' 'text-device' \
+'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
 
 _OPTS_GROFFER_LONG_ARG="\
-'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \
-'default-modes' 'device' 'dvi-viewer' 'extension' 'fg' 'fn' 'font' \
-'foreground' 'html-viewer' 'mode' 'pdf-viewer' 'ps-viewer' 'shell' \
-'tty-viewer' 'www-viewer' 'x-viewer' 'X-viewer'";
+'default-modes' 'device' 'dvi-viewer' 'dvi-viewer-tty' 'extension' 'fg' \
+'fn' 'font' 'foreground' 'html-viewer' 'html-viewer-tty' 'mode' \
+'pdf-viewer' 'pdf-viewer-tty' 'print' 'ps-viewer' 'ps-viewer-tty' 'shell' \
+'title' 'tty-viewer' 'tty-viewer-tty' 'www-viewer' 'www-viewer-tty' \
+'x-viewer' 'x-viewer-tty' 'X-viewer' 'X-viewer-tty'";
 
 ##### groffer options inhereted from groff
 
@@ -302,11 +466,14 @@
 export _ADDOPTS_GROFF;         # Transp. options for groff (`eval').
 export _ADDOPTS_POST;          # Transp. options postproc (`eval').
 export _ADDOPTS_X;             # Transp. options X postproc (`eval').
+export _APROPOS_PROG;          # Program to run apropos.
+export _APROPOS_SECTIONS;      # Sections for different --apropos-*.
 export _DEFAULT_MODES;         # Set default modes.
 export _DISPLAY_MODE;          # Display mode.
 export _DISPLAY_PROG;          # Viewer program to be used for display.
 export _DISPLAY_ARGS;          # X resources for the viewer program.
 export _FILEARGS;              # Stores filespec parameters.
+export _FILESPEC_ARG;          # Stores the actual filespec parameter.
 export _FUNC_STACK;            # Store debugging information.
 export _REGISTERED_TITLE;      # Processed file names.
 # _HAS_* from availability tests
@@ -337,15 +504,12 @@
 # _OPT_* as parsed from groffer command line
 export _OPT_ALL;               # display all suitable man pages.
 export _OPT_APROPOS;           # call `apropos' program.
-export _OPT_APROPOS_DATA;      # `apropos' for man sections 4, 5, 7
-export _OPT_APROPOS_DEVEL;     # `apropos' for man sections 2, 3, 9
-export _OPT_APROPOS_PROGS;     # `apropos' for man sections 1, 6, 8
 export _OPT_BD;                        # set border color in some modes.
 export _OPT_BG;                        # set background color in some modes.
 export _OPT_BW;                        # set border width in some modes.
-export _OPT_DEBUG;             # print debugging information on stderr.
 export _OPT_DEFAULT_MODES;     # `,'-list of modes when no mode given.
 export _OPT_DEVICE;            # device option.
+export _OPT_DO_NOTHING;                # do nothing in main_display().
 export _OPT_DISPLAY;           # set X display.
 export _OPT_FG;                        # set foreground color in some modes.
 export _OPT_FN;                        # set font in some modes.
@@ -368,9 +532,11 @@
 export _OPT_VIEWER_PS;         # viewer program for ps mode
 export _OPT_VIEWER_HTML;       # viewer program for html mode
 export _OPT_VIEWER_X;          # viewer program for x mode
-export _OPT_WHATIS;            # print the one-liner man info
+export _OPT_WHATIS;            # print the man description
 export _OPT_XRM;               # specify X resource.
 export _OPT_Z;                 # groff option -Z.
+export _OUTPUT_FILE_NAME;      # output generated, see main_set_res..()
+export _VIEWER_TERMINAL;       # viewer options for terminal (--*-viewer-tty)
 # _TMP_* temporary directory and files
 export _TMP_DIR;               # groffer directory for temporary files
 export _TMP_CAT;               # stores concatenation of everything
@@ -380,78 +546,6 @@
 
 
 ########################################################################
-#             Test of rudimentary shell functionality
-########################################################################
-
-
-########################################################################
-# Test of `unset'
-#
-export _UNSET;
-export _foo;
-_foo=bar;
-_res="$(unset _foo 2>&1)";
-if unset _foo >${_NULL_DEV} 2>&1 && \
-   test _"${_res}"_ = __ && test _"${_foo}"_ = __
-then
-  _UNSET='unset';
-  eval "${_UNSET}" _res;
-else
-  _UNSET=':';
-fi;
-
-
-########################################################################
-# Test of `test'.
-#
-if test a = a && test a != b && test -f "${_GROFFER_SH}"
-then
-  :;
-else
-  echo '"test" did not work.' >&2;
-  exit "${_ERROR}";
-fi;
-
-
-########################################################################
-# Test of `echo' and the `$()' construct.
-#
-if echo '' >${_NULL_DEV}
-then
-  :;
-else
-  echo '"echo" did not work.' >&2;
-  exit "${_ERROR}";
-fi;
-if test _"$(t1="$(echo te)" &&
-            t2="$(echo '')" &&
-            t3="$(echo 'st')" &&
-            echo "${t1}${t2}${t3}")"_ \
-     != _test_
-then
-  echo 'The "$()" construct did not work' >&2;
-  exit "${_ERROR}";
-fi;
-
-
-########################################################################
-# Test of function definitions.
-#
-_t_e_s_t_f_u_n_c_()
-{
-  return "${_OK}";
-}
-
-if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV}
-then
-  :;
-else
-  echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
-  exit "${_ERROR}";
-fi;
-
-
-########################################################################
 # Preset and reset of read-write global variables
 ########################################################################
 
@@ -489,6 +583,8 @@
   _ADDOPTS_GROFF='';
   _ADDOPTS_POST='';
   _ADDOPTS_X='';
+  _APROPOS_PROG='';
+  _APROPOS_SECTIONS='';
   _DISPLAY_ARGS='';
   _DISPLAY_MODE='';
   _DISPLAY_PROG='';
@@ -519,17 +615,14 @@
 
   # _OPT_* as parsed from groffer command line
   _OPT_ALL='no';
-  _OPT_APROPOS='';
-  _OPT_APROPOS_DATA='';
-  _OPT_APROPOS_DEVEL='';
-  _OPT_APROPOS_PROGS='';
+  _OPT_APROPOS='no';
   _OPT_BD='';
   _OPT_BG='';
   _OPT_BW='';
-  _OPT_DEBUG='no';
   _OPT_DEFAULT_MODES='';
   _OPT_DEVICE='';
   _OPT_DISPLAY='';
+  _OPT_DO_NOTHING='no';
   _OPT_FG='';
   _OPT_FN='';
   _OPT_GEOMETRY='';
@@ -554,7 +647,7 @@
   _OPT_WHATIS='no';
   _OPT_XRM='';
   _OPT_Z='no';
-
+  _VIEWER_TERMINAL='no';
 }
 
 reset;
@@ -575,7 +668,7 @@
 echo1()
 {
   cat <<EOF
-$*
+$@
 EOF
 }
 
@@ -590,7 +683,7 @@
 echo2()
 {
   cat >&2 <<EOF
-$*
+$@
 EOF
 }
 
@@ -621,12 +714,17 @@
 clean_up()
 {
   cd "${_START_DIR}" >"${_NULL_DEV}" 2>&1;
-  if test _"${_TMP_DIR}"_ != __
+  if test _${_DEBUG_KEEP_FILES}_ = _yes_
   then
-    if test -d "${_TMP_DIR}" || test -f "${_TMP_DIR}"
+    echo2 "Kept temporary directory ${_TMP_DIR}."
+  else
+    if test _"${_TMP_DIR}"_ != __
     then
-      rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
-    fi; 
+      if test -d "${_TMP_DIR}" || test -f "${_TMP_DIR}"
+      then
+        rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
+      fi; 
+    fi;
   fi;
 }
 
@@ -645,41 +743,71 @@
 #############
 # error (<text>*)
 #
-# Print an error message to standard error; exit with an error condition
-#
-# Variable prefix: err
+# Print an error message to standard error, print the function stack,
+# exit with an error condition.  The argument should contain the name
+# of the function from which it was called.  This is for system errors.
 #
 error()
 {
-  err_code="${_ERROR}";
   case "$#" in
-    0) :; ;;
     1) echo2 'groffer error: '"$1"; ;;
-    2)
-      echo2 'groffer error: '"$1";
-      err_code="$2";
-      ;;
     *) echo2 'groffer error: wrong number of arguments in error().'; ;;
   esac;
   func_stack_dump;
-  clean_up;
-  kill "${_PROCESS_ID}" >${_NULL_DEV} 2>&1;
-  kill -9 "${_PROCESS_ID}" >${_NULL_DEV} 2>&1;
-  n="${err_code}";
-  eval ${_UNSET} err_code;
-  exit "$n";
+  if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
+  then
+    : >"${_TMP_DIR}"/,error;
+  fi;
+  exit "${_ERROR}";
+}
+
+
+#############
+# error_user (<text>*)
+#
+# Print an error message to standard error; exit with an error condition.
+# The error is supposed to be produce by the user.  So the funtion stack
+# is omitted.
+#
+error_user()
+{
+  case "$#" in
+    1)
+      echo2 'groffer error: '"$1";
+       ;;
+    *)
+      echo2 'groffer error: wrong number of arguments in error_user().';
+      ;;
+  esac;
+  if test _"${_DEBUG_USER_WITH_STACK}"_ = _yes_
+  then
+    func_stack_dump;
+  fi;
+  if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
+  then
+    : >"${_TMP_DIR}"/,error;
+  fi;
+  exit "${_ERROR}";
 }
 
 
 #############
-# abort (<text>*)
+# exit_test ()
 #
-# Terminate program with error condition
+# Test whether the former command ended with error().  Exit again.
 #
-abort()
+# Globals: $_ERROR
+#
+exit_test()
 {
-  error "abort(): Program aborted.";
-  exit 1;
+  if test "$?" = "${_ERROR}"
+  then
+    exit ${_ERROR};
+  fi;
+  if test _"${_TMP_DIR}"_ != __ && test -f "${_TMP_DIR}"/,error
+  then
+    exit ${_ERROR};
+  fi;
 }
 
 
@@ -757,7 +885,7 @@
 ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.';
   fi;
   func_push "${fc_fname}";
-  if test _"${_DEBUG}"_ = _yes_
+  if test _"${_DEBUG_STACKS}"_ = _yes_
   then
     echo2 '+++ '"${fc_fname} $@";
     echo2 '>>> '"${_FUNC_STACK}";
@@ -789,20 +917,21 @@
   fi;
   case "${_FUNC_STACK}" in
   '')
-    if test _"${_DEBUG}"_ = _yes_
+    if test _"${_DEBUG_STACKS}"_ = _yes_
     then
       error 'func_pop(): stack is empty.';
     fi;
     ;;
   *!*)
     # split at first bang `!'.
-   _FUNC_STACK="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')";
+    _FUNC_STACK="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')";
+    exit_test;
     ;;
   *)
     _FUNC_STACK='';
     ;;
   esac;
-  if test _"${_DEBUG}"_ = _yes_
+  if test _"${_DEBUG_STACKS}"_ = _yes_
   then
     echo2 '<<< '"${_FUNC_STACK}";
   fi;
@@ -831,6 +960,7 @@
   *'!'*)
     # remove all bangs `!'.
     fp_element="$(echo1 "$1" | sed -e 's/!//g')";
+    exit_test;
     ;;
   *)
     fp_element="$1";
@@ -893,7 +1023,7 @@
 if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_
 then
   _HAS_COMPRESSION='yes';
-  if echo 'test' | bzip2 -c 2>${_NULL_DEV} | bzip2 -t 2>${_NULL_DEV} \
+  if echo1 'test' | bzip2 -c 2>${_NULL_DEV} | bzip2 -t 2>${_NULL_DEV} \
      && test _"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \
                              | bzip2 -d -c 2>${_NULL_DEV})"_ \
              = _test_
@@ -914,29 +1044,76 @@
 landmark "3: functions";
 
 ########################################################################
-# abort (<text>*)
+# apropos_filespec ()
 #
-# Unconditionally terminate the program with error code;
-# useful for debugging.
+# Setup for the --apropos* options
 #
-# defined above
+apropos_filespec()
+{
+
+  func_check apropos_filespec '=' 0 "$@";
+  if obj _OPT_APROPOS is_yes
+  then
+    eval to_tmp_line \
+      "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
+    exit_test;
+    if obj _APROPOS_PROG is_empty
+    then
+      error 'apropos_filespec: apropos_setup() must be run first.';
+    fi;
+    if obj _APROPOS_SECTIONS is_empty
+    then
+      if obj _OPT_SECTIONS is_empty
+      then
+        s='^.*(.*).*$';
+      else
+        s='^.*(['"$(echo1 "${_OPT_SECTIONS}" | sed -e 's/://g')"']';
+      fi;
+    else
+      s='^.*(['"${_APROPOS_SECTIONS}"']';
+    fi;
+    eval "${_APROPOS_PROG}" "'${_FILESPEC_ARG}'" | \
+      sed -n -e '
+/^'"${_FILESPEC_ARG}"': /p
+/'"$s"'/p
+' | \
+      sort |\
+      sed -e '
+s/^\(.* (..*)\)  *-  *\(.*\)$/\.br\n\.TP 15\n\.BR \1\n\2/
+' >>"${_TMP_CAT}";
+  fi;
+  eval "${return_ok}";
+}
 
 
 ########################################################################
-# apropos_run (<name>)
+# apropos_setup ()
 #
+# Setup for the --apropos* options
 #
-apropos_run() {
-  func_check apropos_run = 1 "$@";
-  if apropos apropos >${_NULL_DEV} 2>${_NULL_DEV}
-  then
-    apropos "$1";
-  elif man --apropos man >${_NULL_DEV} 2>${_NULL_DEV}
-  then
-    man --apropos "$1";
-  elif man -k man >${_NULL_DEV} 2>${_NULL_DEV}
+apropos_setup()
+{
+  func_check apropos_setup '=' 0 "$@";
+  if obj _OPT_APROPOS is_yes
   then
-    man -k "$1";
+    if is_prog apropos
+    then
+      _APROPOS_PROG='apropos';
+    elif is_prog man
+    then
+      if man --apropos man >${_NULL_DEV} 2>${_NULL_DEV}
+      then
+        _APROPOS_PROG='man --apropos';
+      elif man -k man >${_NULL_DEV} 2>${_NULL_DEV}
+      then
+        _APROPOS_PROG='man -k';
+      fi;
+    fi;
+    if obj _APROPOS_PROG is_empty
+    then
+      error 'apropos_setup: no apropos program available.';
+    fi;
+    to_tmp_line '.TH GROFFER APROPOS';
   fi;
   eval "${return_ok}";
 }
@@ -962,6 +1139,7 @@
     */)
       # delete all final slashes
       bn_name="$(echo1 "${bn_name}" | sed -e 's|//*$||')";
+      exit_test;
       ;;
   esac;
   case "${bn_name}" in
@@ -1086,6 +1264,7 @@
   func_check dirname_chop = 1 "$@";
   # replace all multiple slashes by a single slash `/'.
   dc_res="$(echo1 "$1" | sed -e 's|///*|/|g')";
+  exit_test;
   case "${dc_res}" in
   ?*/)
     # remove trailing slash '/';
@@ -1108,7 +1287,7 @@
 # or Z format it is decompressed.  A title element is generated.
 #
 # Argument either:
-#   - name of an existing files.
+#   - name of an existing file.
 #   - `-' to represent standard input (several times allowed).
 #   - `man:name.(section)' the man-page for `name' in `section'.
 #   - `man:name.section' the man-page for `name' in `section'.
@@ -1129,78 +1308,88 @@
   df_filespec="$1";
   # store sequence into positional parameters
   case "${df_filespec}" in
-    '')
-       eval ${_UNSET} df_filespec;
-       eval "${return_good}";
-       ;;
-    '-')
-      register_file '-';
-      eval ${_UNSET} df_filespec;
-      eval "${return_good}";
-      ;;
-    */*)                       # with directory part; so no man search
-      set 'File';
-      ;;
-    *)
-      if obj _MAN_ENABLE is_yes
+  '')
+    eval ${_UNSET} df_filespec;
+    eval "${return_good}";
+    ;;
+  '-')
+    register_file '-';
+    eval ${_UNSET} df_filespec;
+    eval "${return_good}";
+    ;;
+  */*)                        # with directory part; so no man search
+    set 'File';
+    ;;
+  *)
+    if obj _MAN_ENABLE is_yes
+    then
+      if obj _MAN_FORCE is_yes
       then
-        if obj _MAN_FORCE is_yes
-        then
-          set 'Manpage' 'File';
-        else
-          set 'File' 'Manpage';
-        fi;
+        set 'Manpage' 'File';
       else
-        set 'File';
+        set 'File' 'Manpage';
       fi;
-      ;;
+      else
+      set 'File';
+    fi;
+    ;;
   esac;
   for i
   do
     case "$i" in
-      File)
-        if test -f "${df_filespec}"
+    File)
+      if test -f "${df_filespec}"
+      then
+        if test -r "${df_filespec}"
         then
-          if test -r "${df_filespec}"
-          then
-            register_file "${df_filespec}";
-            eval ${_UNSET} df_filespec;
-            eval ${_UNSET} df_no_man;
-            eval "${return_good}";
-          else
-           echo2 "could not read \`${df_filespec}'";
-            eval ${_UNSET} df_filespec;
-            eval ${_UNSET} df_no_man;
-            eval "${return_bad}";
-          fi;
+          register_file "${df_filespec}";
+          eval ${_UNSET} df_filespec;
+          eval ${_UNSET} df_no_man;
+          eval "${return_good}";
         else
-          if obj df_no_man is_not_empty
+          echo2 "could not read \`${df_filespec}'";
+          eval ${_UNSET} df_filespec;
+          eval ${_UNSET} df_no_man;
+          eval "${return_bad}";
+        fi;
+      else
+        if obj df_no_man is_not_empty
+        then
+          if obj _OPT_WHATIS is_yes
           then
+            to_tmp_line "This is neither a file nor a man page."
+          else
             echo2 "\`${df_filespec}' is neither a file nor a man page."
           fi;
-          df_no_file=yes;
-          continue;
-        fi;
-        ;;
-      Manpage)                 # parse filespec as man page
-        if obj _MAN_IS_SETUP is_not_yes
-        then
-          man_setup;
         fi;
-        if man_do_filespec "${df_filespec}"
+        df_no_file=yes;
+        continue;
+      fi;
+      ;;
+    Manpage)                   # parse filespec as man page
+      if obj _MAN_IS_SETUP is_not_yes
+      then
+        man_setup;
+      fi;
+      if man_do_filespec "${df_filespec}"
+      then
+        eval ${_UNSET} df_filespec;
+        eval ${_UNSET} df_no_file;
+        eval "${return_good}";
+      else
+        if obj df_no_file is_not_empty
         then
-          eval ${_UNSET} df_filespec;
-          eval ${_UNSET} df_no_file;
-          eval "${return_good}";
-        else
-          if obj df_no_file is_not_empty
+          if obj _OPT_WHATIS is_yes
           then
+            to_tmp_line "This is neither a file nor a man page."
+          else
             echo2 "\`${df_filespec}' is neither a file nor a man page."
           fi;
-          df_no_man=yes;
-          continue;
-       fi;
-        ;;
+        fi;
+        df_no_man=yes;
+        continue;
+      fi;
+      ;;
     esac;
   done;
   eval ${_UNSET} df_filespec;
@@ -1238,6 +1427,14 @@
 
 
 ########################################################################
+# exit_test ()
+#
+# Test whether the former command ended with error().  Exit again.
+#
+# defined above
+
+
+########################################################################
 # func_check (<func_name> <rel_op> <nr_args> "$@")
 #
 # Check number of arguments and register to _FUNC_STACK.
@@ -1320,7 +1517,7 @@
 #
 is_dir()
 {
-  func_check is_dir = 1 "$@";
+  func_check is_dir '=' 1 "$@";
   if test _"$1"_ != __ && test -d "$1" && test -r "$1"
   then
     eval "${return_yes}";
@@ -1339,7 +1536,7 @@
 #
 is_empty()
 {
-  func_check is_empty = 1 "$@";
+  func_check is_empty '=' 1 "$@";
   if test _"$1"_ = __
   then
     eval "${return_yes}";
@@ -1358,7 +1555,7 @@
 #
 is_equal()
 {
-  func_check is_equal = 2 "$@";
+  func_check is_equal '=' 2 "$@";
   if test _"$1"_ = _"$2"_
   then
     eval "${return_yes}";
@@ -1378,7 +1575,7 @@
 #
 is_existing()
 {
-  func_check is_existing = 1 "$@";
+  func_check is_existing '=' 1 "$@";
   if test _"$1"_ = __
   then
     eval "${return_no}";
@@ -1401,8 +1598,8 @@
 #
 is_file()
 {
-  func_check is_file = 1 "$@";
-  if test _"$1"_ != __ && test -f "$1" && test -r "$1"
+  func_check is_file '=' 1 "$@";
+  if is_not_empty "$1" && test -f "$1" && test -r "$1"
   then
     eval "${return_yes}";
   fi;
@@ -1422,7 +1619,7 @@
 #
 is_non_empty_file()
 {
-  func_check is_non_empty_file = 1 "$@";
+  func_check is_non_empty_file '=' 1 "$@";
   if is_file "$1" && test -s "$1"
   then
     eval "${return_yes}";
@@ -1441,7 +1638,7 @@
 #
 is_not_dir()
 {
-  func_check is_not_dir = 1 "$@";
+  func_check is_not_dir '=' 1 "$@";
   if is_dir "$1"
   then
     eval "${return_no}";
@@ -1460,7 +1657,7 @@
 #
 is_not_empty()
 {
-  func_check is_not_empty = 1 "$@";
+  func_check is_not_empty '=' 1 "$@";
   if is_empty "$1"
   then
     eval "${return_no}";
@@ -1478,7 +1675,7 @@
 #
 is_not_equal()
 {
-  func_check is_not_equal = 2 "$@";
+  func_check is_not_equal '=' 2 "$@";
   if is_equal "$1" "$2"
   then
     eval "${return_no}";
@@ -1492,11 +1689,11 @@
 #
 # Test whether `name' is a not readable file.
 #
-# Arguments : >=1 (empty allowed), more args are ignored
+# Arguments : 1 (empty allowed)
 #
 is_not_file()
 {
-  func_check is_not_file '>=' 1 "$@";
+  func_check is_not_file '=' 1 "$@";
   if is_file "$1"
   then
     eval "${return_no}";
@@ -1506,20 +1703,27 @@
 
 
 ########################################################################
-# is_not_prog (<name>)
+# is_not_prog ([<name> [<arg>*]])
 #
 # Verify that arg is a not program in $PATH.
 #
-# Arguments : >=1 (empty allowed)
+# Arguments : >=0 (empty allowed)
 #   more args are ignored, this allows to specify progs with arguments
 #
 is_not_prog()
 {
-  func_check is_not_prog '>=' 1 "$@";
-  if where_is "$1" >${_NULL_DEV}
-  then
-    eval "${return_no}";
-  fi;
+  func_check is_not_prog '>=' 0 "$@";
+  case "$#" in
+  0)
+    eval "${return_yes}";
+    ;;
+  *)
+    if where_is "$1" >${_NULL_DEV}
+    then
+      eval "${return_no}";
+    fi;
+    ;;
+  esac
   eval "${return_yes}";
 }
 
@@ -1543,6 +1747,22 @@
 
 
 ########################################################################
+# is_not_X ()
+#
+# Test whether not running in X Window by checking $DISPLAY
+#
+is_not_X()
+{
+  func_check is_X '=' 0 "$@";
+  if obj DISPLAY is_empty
+  then
+    eval "${return_yes}";
+  fi;
+  eval "${return_no}";
+}
+
+
+########################################################################
 # is_not_yes (<string>)
 #
 # Test whether `string' is not "yes".
@@ -1561,7 +1781,7 @@
 
 
 ########################################################################
-# is_prog (<name> [<arg>*])
+# is_prog ([<name> [<arg>*]])
 #
 # Determine whether <name> is a program in $PATH
 #
@@ -1612,16 +1832,31 @@
 
 
 ########################################################################
+# is_X ()
+#
+# Test whether running in X Window by checking $DISPLAY
+#
+is_X()
+{
+  func_check is_X '=' 0 "$@";
+  if obj DISPLAY is_not_empty
+  then
+    eval "${return_yes}";
+  fi;
+  eval "${return_no}";
+}
+
+
+########################################################################
 # is_yes (<string>)
 #
 # Test whether `string' has value "yes".
 #
-# Arguments : <=1
 # Return    : `0' if arg1 is `yes', `1' otherwise.
 #
 is_yes()
 {
-  func_check is_yes = 1 "$@";
+  func_check is_yes '=' 1 "$@";
   if is_equal "$1" 'yes'
   then
     eval "${return_yes}";
@@ -1695,6 +1930,7 @@
       # "'" (squote) by "'\''" (squote bslash squote squote);
       # note that the backslash must be doubled in the following `sed'
       la_element="$(echo1 "${la_s}" | sed -e 's/'"${_SQ}"'/&\\&&/g')";
+      exit_test;
       ;;
     '')
       la_element="";
@@ -1766,6 +2002,7 @@
   lfc_short_a="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument
   lfc_long_n="$(obj_data "$1"_LONG_NA)";    # long options, no argument
   lfc_long_a="$(obj_data "$1"_LONG_ARG)";   # long options, with argument
+  exit_test;
   if obj lfc_short_n is_empty
   then
     error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.';
@@ -1782,6 +2019,7 @@
   then
     error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
   fi;
+
   shift;
   if is_equal "$#" 0
   then
@@ -1794,6 +2032,7 @@
     eval ${_UNSET} lfc_result;
     eval "${return_ok}";
   fi;
+
   lfc_fparams='';
   lfc_result='';
   while test "$#" -ge 1
@@ -1802,55 +2041,79 @@
     shift;
     case "${lfc_arg}" in
     --) break; ;;
-    --?*)
+    --*=*)
       # delete leading '--';
       lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
-      lfc_opt="$(list_single_from_abbrev lfc_long_n "${lfc_abbrev}")";
-      if obj lfc_opt is_not_empty
+      lfc_with_equal="${lfc_abbrev}";
+      # extract option by deleting from the first '=' to the end
+      lfc_abbrev="$(echo1 "${lfc_with_equal}" | \
+                    sed -e 's/^\([^=]*\)=.*$/\1/')";
+      lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
+      exit_test;
+      if obj lfc_opt is_empty
       then
-        # long option, no argument
-        list_append lfc_result "--${lfc_opt}";
+        error_user "--${lfc_abbrev} is not an option.";
+      else
+        # get the option argument by deleting up to first `='
+        lfc_optarg="$(echo1 "${lfc_with_equal}" | sed -e 's/^[^=]*=//')";
+        exit_test;
+        list_append lfc_result "--${lfc_opt}" "${lfc_optarg}";
         continue;
       fi;
-      # test on `--opt=arg'
-      if string_contains "${lfc_abbrev}" '='
+      ;;
+    --*)
+      # delete leading '--';
+      lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
+      if list_has lfc_long_n "${lfc_abbrev}"
       then
-        lfc_with_equal="${lfc_abbrev}";
-        # extract option by deleting from the first '=' to the end
-        lfc_abbrev="$(echo1 "${lfc_with_equal}" | \
-                      sed -e 's/^\([^=]*\)=.*$/\1/')";
-        lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
-        if obj lfc_opt is_not_empty
+        lfc_opt="${lfc_abbrev}";
+      else
+        exit_test;
+        lfc_opt="$(list_single_from_abbrev lfc_long_n "${lfc_abbrev}")";
+        exit_test;
+        if obj lfc_opt is_not_empty && is_not_equal "$#" 0
         then
-          # get the option argument by deleting up to first `='
-          lfc_optarg="$(echo1 "${lfc_with_equal}" | sed -e 's/^[^=]*=//')";
-          list_append lfc_result "--${lfc_opt}" "${lfc_optarg}";
-          continue;
+          a="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
+          exit_test;
+          if obj a is_not_empty
+          then
+            error_user "The abbreviation ${lfc_arg} \
+has multiple options: --${lfc_opt} and --${a}.";
+          fi;
         fi;
       fi;
+      if obj lfc_opt is_not_empty
+      then
+        # long option, no argument
+        list_append lfc_result "--${lfc_opt}";
+        continue;
+      fi;
       lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
+      exit_test;
       if obj lfc_opt is_not_empty
       then
         # long option with argument
         if test "$#" -le 0
         then
-          error "list_from_cmdline(): no argument for option --${lfc_opt}."
+          error_user "no argument for option --${lfc_opt}."
         fi;
         list_append lfc_result "--${lfc_opt}" "$1";
         shift;
         continue;
       fi;
-      error "list_from_cmdline(): --${lfc_opt} is not an option."
+      error_user "${lfc_arg} is not an option.";
       ;;
     -?*)                       # short option (cluster)
       # delete leading `-';
       lfc_rest="$(echo1 "${lfc_arg}" | sed -e 's/^-//')";
+      exit_test;
       while obj lfc_rest is_not_empty
       do
         # get next short option from cluster (first char of $lfc_rest)
         lfc_optchar="$(echo1 "${lfc_rest}" | sed -e 's/^\(.\).*$/\1/')";
         # remove first character from ${lfc_rest};
         lfc_rest="$(echo1 "${lfc_rest}" | sed -e 's/^.//')";
+        exit_test;
         if list_has lfc_short_n "${lfc_optchar}"
         then
           list_append lfc_result "-${lfc_optchar}";
@@ -1865,8 +2128,7 @@
               shift;
               continue;
             else
-              error 'list_from_cmdline(): no argument for option -'\
-"${lfc_optchar}."
+              error_user "no argument for option -${lfc_optchar}.";
             fi;
           else                 # rest is the argument
             list_append lfc_result "-${lfc_optchar}" "${lfc_rest}";
@@ -1874,7 +2136,7 @@
             continue;
           fi;
         else
-          error "list_from_cmdline(): unknown option -${lfc_optchar}."
+          error_user "unknown option -${lfc_optchar}.";
         fi;
       done;
       ;;
@@ -1934,7 +2196,8 @@
   func_check list_from_split = 2 "$@";
 
   # precede each space or tab by a backslash `\' (doubled for `sed')
-  lfs_s="$(echo1 "$1" | sed -e 's/\(['"${_SP}${_TAB}"']\)/\\\1/g')";
+  lfs_s="$(echo1 "$1" | sed -e 's/\('"${_SPACE_SED}"'\)/\\\1/g')";
+  exit_test;
 
   # replace split character of string by the list separator ` ' (space).
   case "$2" in
@@ -1979,9 +2242,10 @@
   eval lg_list='"${'$1'}"';
   # remove leading and final space characters
   lg_list="$(echo1 "${lg_list}" | sed -e '
-s/^['"${_SP}${_TAB}"']*//
-s/['"${_SP}${_TAB}"']*$//
+s/^'"${_SPACE_SED}"'*//
+s/'"${_SPACE_SED}"'*$//
 ')";
+  exit_test;
   case "${lg_list}" in
   '')
     eval ${_UNSET} lg_list;
@@ -2059,10 +2323,13 @@
     eval "${return_no}";
   fi;
   case "$2" in
-    \'*) lha_element=" $(echo1 "$2" | sed -e 's/'"${_SQ}"'$//')"; ;;
-    *)   lha_element=" '$2"; ;;
+    \'*)
+      lha_element="$(echo1 "$2" | sed -e 's/'"${_SQ}"'$//')";
+      exit_test;
+      ;;
+    *) lha_element="'$2"; ;;
   esac;
-  if string_contains " ${lha_list}" "${lha_element}"
+  if string_contains " ${lha_list}" " ${lha_element}"
   then
     eval "${_UNSET}" lha_list;
     eval "${_UNSET}" lha_element;
@@ -2098,7 +2365,7 @@
   fi;
   case "$2" in
     \'*\') lhn_element=" $2 "; ;;
-    *)     lhn_element="' $2 '"; ;;
+    *)     lhn_element=" '$2' "; ;;
   esac;
   if string_contains " ${lhn_list} " "${lhn_element}"
   then
@@ -2155,8 +2422,8 @@
       ${lsfa_abbrev}*)
         if obj lsfa_element is_not_empty
         then
-          error "list_single_from_abbrev: the abbreviation ${lsfa_abbrev} \
-has multiple options: ${lsfa_element} and ${i}.";
+          error_user "The abbreviation --${lsfa_abbrev} \
+has multiple options: --${lsfa_element} and --${i}.";
         fi;
         lsfa_element="$i";
         ;;
@@ -2214,43 +2481,48 @@
   mdf_name='';
   mdf_section='';
   case "${mdf_spec}" in
-    */*)                       # not a man spec when it contains '/'
-      eval ${_UNSET} mdf_got_one;
-      eval ${_UNSET} mdf_name;
-      eval ${_UNSET} mdf_section;
-      eval ${_UNSET} mdf_spec;
-      eval "${return_bad}";
-      ;;
-    man:?*\(?*\))              # man:name(section)
-      mdf_name="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^man:\(..*\)(\(..*\))$/\1/')";
-      mdf_section="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')";
-      ;;
-    man:?*.[0-9on])                    # man:name.section
-      mdf_name="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^man:\(..*\)\..$/\1/')";
-      mdf_section="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^.*\(.\)$/\1/')";
-      ;;
-    man:?*)                    # man:name
-      mdf_name="$(echo1 "${mdf_spec}" | sed -e 's/^man://')";
-      ;;
-    ?*\(?*\))                  # name(section)
-      mdf_name="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^\(..*\)(\(..*\))$/\1/')";
-      mdf_section="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^\(..*\)(\(..*\))$/\2/')";
-      ;;
-    ?*.[0-9on])                        # name.section
-      mdf_name="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^\(..*\)\..$/\1/')";
-      mdf_section="$(echo1 "${mdf_spec}" \
-               | sed -e 's/^.*\(.\)$/\1/')";
-      ;;
-    ?*)
-      mdf_name="${mdf_spec}";
-      ;;
+  */*)                         # not a man spec with containing '/'
+    eval ${_UNSET} mdf_got_one;
+    eval ${_UNSET} mdf_name;
+    eval ${_UNSET} mdf_section;
+    eval ${_UNSET} mdf_spec;
+    eval "${return_bad}";
+    ;;
+  man:?*\(?*\))                        # man:name(section)
+    mdf_name="$(echo1 "${mdf_spec}" \
+                | sed -e 's/^man:\(..*\)(\(..*\))$/\1/')";
+    mdf_section="$(echo1 "${mdf_spec}" \
+                   | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')";
+    exit_test;
+    ;;
+  man:?*.${_MAN_AUTO_SEC_CHARS}) # man:name.section
+    mdf_name="$(echo1 "${mdf_spec}" \
+                | sed -e 's/^man:\(..*\)\..$/\1/')";
+    mdf_section="$(echo1 "${mdf_spec}" \
+                   | sed -e 's/^.*\(.\)$/\1/')";
+    exit_test;
+    ;;
+  man:?*)                      # man:name
+    mdf_name="$(echo1 "${mdf_spec}" | sed -e 's/^man://')";
+    exit_test;
+    ;;
+  ?*\(?*\))                    # name(section)
+    mdf_name="$(echo1 "${mdf_spec}" \
+                | sed -e 's/^\(..*\)(\(..*\))$/\1/')";
+    mdf_section="$(echo1 "${mdf_spec}" \
+                   | sed -e 's/^\(..*\)(\(..*\))$/\2/')";
+    exit_test;
+    ;;
+  ?*.${_MAN_AUTO_SEC_CHARS})   # name.section
+    mdf_name="$(echo1 "${mdf_spec}" \
+                | sed -e 's/^\(..*\)\..$/\1/')";
+    mdf_section="$(echo1 "${mdf_spec}" \
+                   | sed -e 's/^.*\(.\)$/\1/')";
+    exit_test;
+    ;;
+  ?*)
+    mdf_name="${mdf_spec}";
+    ;;
   esac;
   if obj mdf_name is_empty
   then
@@ -2263,7 +2535,13 @@
   mdf_got_one='no';
   if obj mdf_section is_empty
   then
-    eval set x "${_MAN_AUTO_SEC}";
+    if obj _OPT_SECTIONS is_empty
+    then
+      eval set x "${_MAN_AUTO_SEC_LIST}";
+    else
+      # use --sections when no section is given to filespec
+      eval set x "$(echo1 "${_OPT_SECTIONS}" | sed -e 's/:/ /g')";
+    fi;
     shift;
     for s
     do
@@ -2300,7 +2578,7 @@
       eval "${return_bad}";
     fi;
   fi;
-  if obj _MAN_ALL is_yes && is_yes "${mdf_got_one}"
+  if obj _MAN_ALL is_yes && obj mdf_got_one is_yes
   then
     eval ${_UNSET} mdf_got_one;
     eval ${_UNSET} mdf_name;
@@ -2383,6 +2661,7 @@
   mss_name="$1";
   mss_section="$2";
   eval set x "$(path_split "${_MAN_PATH}")";
+  exit_test;
   shift;
   mss_got_one='no';
   if obj _MAN_EXT is_empty
@@ -2390,18 +2669,28 @@
     for d
     do
       mss_dir="$(dirname_append "$d" "man${mss_section}")";
+      exit_test;
       if obj mss_dir is_dir
       then
         mss_prefix="$(\
           dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
-        mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
-                     sed -e '\| found|s|.*||'
-                     )";
+        if obj _OPT_WHATIS is_yes
+        then
+          mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
+                       sed -e '\| found|s|.*||'
+                       )";
+        else
+          mss_files="$(eval ls "'${mss_prefix}'"'*' 2>${_NULL_DEV} |
+                       sed -e '\| found|s|.*||'
+                       )";
+        fi;
+        exit_test;
         if obj mss_files is_not_empty
         then
           # for f in $mss_files
-          for f in $(eval set x ${mss_files}; shift; echo "$@")
+          for f in $(eval set x ${mss_files}; shift; echo1 "$@")
           do
+            exit_test;
             mss_f="$f";
             if obj mss_f is_file
             then
@@ -2435,6 +2724,7 @@
     for d
     do
       mss_dir="$(dirname_append $d man${mss_section}${mss_ext})";
+      exit_test;
       if obj mss_dir is_dir
       then
         mss_prefix=\
@@ -2442,10 +2732,11 @@
         mss_files="$( eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
                      sed -e '\|not found|s|.*||'
                      )";
+        exit_test;
         if obj mss_files is_not_empty
         then
           # for f in $mss_files
-          for f in $(eval set x ${mss_files}; shift; echo "$@")
+          for f in $(eval set x ${mss_files}; shift; echo1 "$@")
           do
             mss_f="$f";
             if obj mss_f is_file
@@ -2478,6 +2769,7 @@
     for d
     do
       mss_dir="$(dirname_append "$d" "man${mss_section}")";
+      exit_test;
       if obj mss_dir is_dir
       then
         mss_prefix="$(dirname_append "${mss_dir}" \
@@ -2485,10 +2777,11 @@
         mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
                      sed -e '\|not found|s|.*||'
                      )";
+        exit_test;
         if obj mss_files is_not_empty
         then
           # for f in $mss_files
-          for f in $(eval set x ${mss_files}; shift; echo "$@")
+          for f in $(eval set x ${mss_files}; shift; echo1 "$@")
           do
             mss_f="$f";
             if obj mss_f is_file
@@ -2584,17 +2877,20 @@
   # determine basic path for man pages
   _MAN_PATH="$(get_first_essential \
                "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")";
+  exit_test;
   if obj _MAN_PATH is_empty
   then
     manpath_set_from_path;
   else
     _MAN_PATH="$(path_clean "${_MAN_PATH}")";
+    exit_test;
   fi;
   if obj _MAN_PATH is_empty
   then
     if is_prog 'manpath'
     then
       _MAN_PATH="$(manpath 2>${_NULL_DEV})"; # not always available
+      exit_test;
     fi;
   fi;
   if obj _MAN_PATH is_empty
@@ -2604,6 +2900,7 @@
   fi;
 
   _MAN_ALL="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")";
+  exit_test;
   if obj _MAN_ALL is_empty
   then
     _MAN_ALL='no';
@@ -2613,6 +2910,7 @@
               "${_OPT_SYSTEMS}" "${_MANOPT_SYS}" "${SYSTEM}")";
   ms_lang="$(get_first_essential \
            "${_OPT_LANG}" "${LC_ALL}" "${LC_MESSAGES}" "${LANG}")";
+  exit_test;
   case "${ms_lang}" in
     C|POSIX)
       _MAN_LANG="";
@@ -2626,6 +2924,7 @@
       _MAN_LANG="${ms_lang}";
       # get first two characters of $ms_lang
       _MAN_LANG2="$(echo1 "${ms_lang}" | sed -e 's/^\(..\).*$/\1/')";
+      exit_test;
       ;;
   esac;
   # from now on, use only $_LANG, forget about $_OPT_LANG, $LC_*.
@@ -2634,6 +2933,7 @@
 
   _MAN_SEC="$(get_first_essential \
               "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")";
+  exit_test;
   if obj _MAN_PATH is_empty
   then
     _MAN_ENABLE="no";
@@ -2643,6 +2943,7 @@
 
   _MAN_EXT="$(get_first_essential \
               "${_OPT_EXTENSION}" "${_MANOPT_EXTENSION}")";
+  exit_test;
   eval ${_UNSET} ms_lang;
   eval "${return_ok}";
 } # man_setup()
@@ -2678,18 +2979,23 @@
   # twice test both sys and lang
   eval set x "$(path_split "${_MAN_PATH}")";
   shift;
+  exit_test;
   mals_mp='';
   for p
   do                           # loop on man path directories
     mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
+    exit_test;
   done;
   eval set x "$(path_split "${mals_mp}")";
   shift;
+  exit_test;
   for p
   do                           # loop on man path directories
     mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
+    exit_test;
   done;
   _MAN_PATH="$(path_chop "${mals_mp}")";
+  exit_test;
   eval ${_UNSET} mals_mp;
   eval "${return_ok}";
 }
@@ -2711,9 +3017,11 @@
   _mals_parent="$2";
   eval set x "$(list_from_split "${_MAN_SYS}" ',')";
   shift;
+  exit_test;
   for d in "$@" "${_MAN_LANG}" "${_MAN_LANG2}"
   do
     _mals_dir="$(dirname_append "${_mals_parent}" "$d")";
+    exit_test;
     if obj _mals_res path_not_contains "${_mals_dir}" && \
        obj _mals_dir is_dir
     then
@@ -2758,10 +3066,12 @@
   then
     eval set x "$(path_split "${PATH}")";
     shift;
+    exit_test;
     for d
     do
       # delete the final `/bin' part
       msfp_base="$(echo1 "$d" | sed -e 's|//*bin/*$||')";
+      exit_test;
       for e in /share/man /man
       do
         msfp_mandir="${msfp_base}$e";
@@ -2818,13 +3128,13 @@
 obj()
 {
   func_check obj '>=' 2 "$@";
+  eval o_arg1='"${'$1'}"';
   if is_empty "$2"
   then
     error "obj(): function name is empty."
   else
     o_func="$2";
   fi;
-  eval o_arg1='"${'$1'}"';
   shift;
   shift;
   eval "${o_func}"' "${o_arg1}" "$@"';
@@ -2889,6 +3199,7 @@
   fi;
   shift;
   eval "${ofo_result_name}"'="$('"$@"')"';
+  exit_test;
   eval "${return_ok}";
 }
 
@@ -2957,6 +3268,7 @@
   fi;
   pc_arg="$1";
   eval set x "$(path_split "${pc_arg}")";
+  exit_test;
   shift;
   pc_res="";
   for i
@@ -2967,8 +3279,14 @@
        && obj pc_i is_dir
     then
       case "${pc_i}" in
-        ?*/) pc_res="${pc_res}$(dirname_chop "${pc_i}")"; ;;
-        *)  pc_res="${pc_res}:${pc_i}";
+      ?*/)
+        pc_res="${pc_res}$(dirname_chop "${pc_i}")";
+        exit_test;
+        ;;
+      *)
+        pc_res="${pc_res}:${pc_i}";
+        exit_test;
+        ;;
       esac;
     fi;
   done;
@@ -3069,9 +3387,10 @@
   else
     to_tmp "$1";
     register_title "$(base_name "$1")";
+    exit_test;
   fi;
   eval "${return_ok}";
-}
+} # register_file()
 
 
 ########################################################################
@@ -3090,23 +3409,39 @@
   then
     eval "${return_ok}";
   fi;
-  rt_title="$(base_name "$1")";        # remove directory part
 
+  case "${_REGISTERED_TITLE}" in
+  *\ *\ *\ *)
+    eval "${return_ok}";
+    ;;
+  esac;
+
+  # remove directory part
+  rt_title="$(base_name "$1")";
   # replace space characters by `_'
   rt_title="$(echo1 "${rt_title}" | sed -e 's/[        ]/_/g')";
+  # remove extension `.bz2'
+  rt_title="$(echo1 "${rt_title}" | sed -e 's/\.bz2$//')";
   # remove extension `.gz'
   rt_title="$(echo1 "${rt_title}" | sed -e 's/\.gz$//')";
   # remove extension `.Z'
   rt_title="$(echo1 "${rt_title}" | sed -e 's/\.Z$//')";
+  exit_test;
 
   if obj rt_title is_empty
   then
+    eval ${_UNSET} rt_title;
     eval "${return_ok}";
   fi;
-  _REGISTERED_TITLE="${_REGISTERED_TITLE} ${rt_title}";
+  if obj _REGISTERED_TITLE is_empty
+  then
+    _REGISTERED_TITLE="${rt_title}";
+  else
+    _REGISTERED_TITLE="${_REGISTERED_TITLE} ${rt_title}";
+  fi;
   eval ${_UNSET} rt_title;
   eval "${return_ok}";
-}
+} # register_title()
 
 
 ########################################################################
@@ -3220,6 +3555,58 @@
 
 
 ########################################################################
+# special_filespec ()
+#
+# Handle special modes like whatis and apropos.
+#
+special_filespec()
+{
+  func_check special_setup '=' 0 "$@";
+  if obj _OPT_APROPOS is_yes
+  then
+    if obj _OPT_WHATIS is_yes
+    then
+      error \
+        'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
+    fi;
+    apropos_filespec;
+    eval "${return_ok}";
+  fi;
+  if obj _OPT_WHATIS is_yes
+  then
+    whatis_filespec;
+  fi;
+  eval "${return_ok}";
+}
+
+
+########################################################################
+# special_setup ()
+#
+# Handle special modes like whatis and apropos.
+#
+special_setup()
+{
+  func_check special_setup '=' 0 "$@";
+  if obj _OPT_APROPOS is_yes
+  then
+    if obj _OPT_WHATIS is_yes
+    then
+      error \
+        'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
+    fi;
+    apropos_setup;
+    eval "${return_ok}";
+  fi;
+  if obj _OPT_WHATIS is_yes
+  then
+    whatis_header;
+  fi;  
+  eval "${return_ok}";
+}
+
+
+########################################################################
 landmark '11: stack_*()';
 ########################################################################
 
@@ -3318,7 +3705,11 @@
 #
 to_tmp()
 {
-  func_check to_tmp = 1 "$@";
+  func_check to_tmp '=' 1 "$@";
+  if obj _TMP_CAT is_empty
+  then
+    error 'to_tmp_line: $_TMP_CAT is not yet set';
+  fi;
   if is_file "$1"
   then
     if obj _OPT_LOCATION is_yes
@@ -3327,7 +3718,7 @@
     fi;
     if obj _OPT_WHATIS is_yes
     then
-      what_is "$1" >>"${_TMP_CAT}";
+      whatis_filename "$1" >>"${_TMP_CAT}";
     else
       cat_z "$1" >>"${_TMP_CAT}";
     fi;
@@ -3339,41 +3730,44 @@
 
 
 ########################################################################
-# trap_clean ()
-#
-# disable trap on all exit codes ($_ALL_EXIT)
+# to_tmp_line ([<text>])
 #
-# Arguments: 0
-# Globals:   $_ALL_EXIT
+# print line to the temporary cat file
 #
-trap_clean()
+to_tmp_line()
 {
-  func_check trap_clean = 0 "$@";
-  # for i in $_ALL_EXIT
-  for i in $(eval set x "${_ALL_EXIT}"; shift; echo "$@")
-  do
-    trap "" "$i" 2>${_NULL_DEV} || :;
-  done;
+  func_check to_tmp '>=' 0 "$@";
+  if obj _TMP_CAT is_empty
+  then
+    error 'to_tmp_line: $_TMP_CAT is not yet set';
+  fi;
+  echo1 "$*" >>"${_TMP_CAT}";
   eval "${return_ok}";
 }
 
 
 ########################################################################
-# trap_set (<functionname>)
+# trap_set
 #
-# call function on all exit codes ($_ALL_EXIT)
-#
-# Arguments: 1 (name of a shell function)
-# Globals:   $_ALL_EXIT
+# call function on signal 0
 #
 trap_set()
 {
-  func_check trap_set = 1 "$@";
-  # for i in $_ALL_EXIT
-  for i in $(eval set x "${_ALL_EXIT}"; shift; echo "$@")
-  do
-    trap "$1" "$i" 2>${_NULL_DEV} || :;
-  done;
+  func_check trap_set '=' 0 "$@";
+  trap 'clean_up' 0 2>${_NULL_DEV} || :;
+  eval "${return_ok}";
+}
+
+
+########################################################################
+# trap_unset ()
+#
+# disable trap on signal 0.
+#
+trap_unset()
+{
+  func_check trap_unset '=' 0 "$@";
+  trap '' 0 2>${_NULL_DEV} || :;
   eval "${return_ok}";
 }
 
@@ -3388,7 +3782,7 @@
   func_check usage = 0 "$@";
   echo;
   version;
-  echo 'Usage: groffer [option]... [filespec]...';
+  echo1 'Usage: groffer [option]... [filespec]...';
   cat <<EOF
 
 Display roff files, standard input, and/or Unix manual pages with a X
@@ -3439,31 +3833,43 @@
 --mode=auto|dvi|groff|html|pdf|ps|source|text|tty|www|x|X
                   choose display mode.
 --no-man          disable man-page facility.
+--no-special      disable --all, --apropos*, and --whatis
 --pager=program   preset the paging program for tty mode.
 --pdf             display in a PDF viewer.
 --pdf-viewer=prog choose the viewer program for pdf mode.
 --ps              display in a Postscript viewer.
 --ps-viewer=prog  choose the viewer program for ps mode.
---shell=program   specify shell under which to run groffer2.sh.
+--shell=program   specify a shell under which to run groffer2.sh.
 --text            output in a text device without a pager.
 --tty             display with a pager on text terminal even when in X.
 --tty-viewer=prog select a pager for tty mode; same as --pager.
+--whatis          display the file name and description of man pages
 --www             same as --html.
 --www-viewer=prog same as --html-viewer
 --x --X           display with "gxditview" using an X* device.
 --x-viewer=prog   choose viewer program for x mode (X mode).
 --X-viewer=prog   same as "--xviewer".
 
-The usual X Windows toolkit options transformed into GNU long options
+Development options that are not useful for normal usage:
+--debug, --debug-all, --debug-keep, --debug-lm, --debug-params,
+--debug-shell, --debug-stacks, --debug-tmpdir, --debug-user,
+--do-nothing, --print=text
+
+Viewer programs for the different modes that run on the terminal:
+--dvi-viewer-tty=prog, --html-viewer-tty=prog, --pdf-viewer-tty=prog,
+--ps-viewer-tty=prog, --tty-viewer-tty, --X-viewer-tty=prog,
+--x-viewer-tty=prog, --www-viewer-tty=prog
+
+The usual X Windows toolkit options transformed into GNU long options:
 --background=color, --bd=size, --bg=color, --bordercolor=color,
 --borderwidth=size, --bw=size, --display=Xdisplay, --fg=color,
 --fn=font, --font=font, --foreground=color, --geometry=geom, --iconic,
 --resolution=dpi, --rv, --title=text, --xrm=resource
 
-Long options of GNU "man"
- --all, --ascii, --ditroff, --extension=suffix, --locale=language,
+Long options of GNU "man":
+--all, --ascii, --ditroff, --extension=suffix, --locale=language,
 --local-file=name, --location, --manpath=dir1:dir2:...,
---sections=s1:s2:..., --systems=s1,s2,..., --whatis, --where, ...
+--sections=s1:s2:..., --systems=s1,s2,..., --where, ...
 
 EOF
   eval "${return_ok}";
@@ -3478,9 +3884,9 @@
 version()
 {
   func_check version = 0 "$@";
-  echo2 "groffer ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
+  echo1 "groffer ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
   # also display groff's version, but not the called subprograms
-  groff -v 2>&1 | sed -e '/^ *$/q' | sed -e '1s/^/is part of /' >&2;
+  groff -v 2>&1 | sed -e '/^ *$/q' | sed -e '1s/^/is part of /';
   eval "${return_ok}";
 }
 
@@ -3497,68 +3903,166 @@
 
 
 ########################################################################
-# what_is (<filename>)
+# whatis_filename (<filename>)
 #
 # Interpret <filename> as a man page and display its `whatis'
 # information as a fragment written in the groff language.
 #
-# Variable prefix: wi
+# Variable prefix: wf
 #
-what_is()
+whatis_filename()
 {
-  func_check what_is = 1 "$@";
-  if is_not_file "$1"
+  func_check whatis_filename = 1 "$@";
+  wf_arg="$1";
+  if obj wf_arg is_not_file
+  then
+    error "whatis_filename(): argument is not a readable file."
+  fi;
+  wf_dot='^\.'"${_SPACE_SED}"'*';
+  if obj _FILESPEC_ARG is_equal '-'
   then
-    error "what_is(): argument is not a readable file."
+    wf_arg='stdin';
   fi;
-  wi_dot='^\.['"${_SP}${_TAB}"']*';
   cat <<EOF
-.br
-  $1:
+\f[CR]${wf_arg}\f[]:
 .br
 EOF
-  # grep the line containing `.TH' macro, if any
-  wi_res="$(cat_z "$1" | sed -e '/'"${wi_dot}"'TH /p
-d')";
-  if obj wi_res is_not_empty
+
+  # get the parts of the file name
+  wf_name="$(base_name $1)";
+  wf_section="$(echo1 $1 | sed -n -e '
+s|^.*/man\('"${_MAN_AUTO_SEC_CHARS}"'\).*$|\1|p
+')";
+  if obj wf_section is_not_empty
+  then
+    case "${wf_name}" in
+    *.${wf_section}*)
+      s='yes';
+      ;;
+    *)
+      s='';
+      wf_section='';
+      ;;
+    esac
+    if obj s is_yes
+    then
+      wf_name="$(echo1 ${wf_name} | sed -e '
+s/^\(.*\)\.'${wf_section}'.*$/\1/
+')";
+    fi;
+  fi;
+
+  # traditional man style; grep the line containing `.TH' macro, if any
+  wf_res="$(cat_z "$1" | sed -e '
+/'"${wf_dot}"'TH /p
+d
+')";
+  exit_test;
+  if obj wf_res is_not_empty
   then                         # traditional man style
-    # get the text between the first and the second `.SH' macro, by
+    # get the first line after the first `.SH' macro, by
     # - delete up to first .SH;
-    # - of this, print everything up to next .SH, and delete the rest;
-    # - of this, delete the final .SH line;
-    cat_z "$1" | sed -e '1,/'"${wi_dot}"'SH/d' \
-              | sed -e '1,/'"${wi_dot}"'SH/p
-d' \
-              | sed -e '/'"${wi_dot}"'SH/d';
-    eval ${_UNSET} wi_dot;
-    eval ${_UNSET} wi_res;
+    # - print all lines before the next .SH;
+    # - quit.
+    wf_res="$(cat_z "$1" | sed -n -e '
+1,/'"${wf_dot}"'SH/d
+/'"${wf_dot}"'SH/q
+p
+')";
+
+    if obj wf_section is_not_empty
+    then
+      case "${wf_res}" in
+      ${wf_name}${_SPACE_CASE}*-${_SPACE_CASE}*)
+        s='yes';
+        ;;
+      *)
+        s='';
+        ;;
+      esac;
+      if obj s is_yes
+      then
+        wf_res="$(obj wf_res echo1 | sed -e '
+s/^'"${wf_name}${_SPACE_SED}"'[^-]*-'"${_SPACE_SED}"'*\(.*\)$/'"${wf_name}"' 
('"${wf_section}"') \\[em] \1/
+')";
+      fi;
+    fi;
+    obj wf_res echo1;
+    echo;
+    eval ${_UNSET} wf_arg;
+    eval ${_UNSET} wf_dot;
+    eval ${_UNSET} wf_name;
+    eval ${_UNSET} wf_res;
+    eval ${_UNSET} wf_section;
     eval "${return_ok}";
   fi;
-  # grep the line containing `.Dd' macro, if any
-  wi_res="$(cat_z "$1" | sed -e '/'"${wi_dot}"'Dd /p
-d')";
-  if obj wi_res is_not_empty
+
+  # mdoc style (BSD doc); grep the line containing `.Nd' macro, if any
+  wf_res="$(cat_z "$1" | sed -n -e '/'"${wf_dot}"'Nd /s///p')";
+  exit_test;
+  if obj wf_res is_not_empty
   then                         # BSD doc style
-    # get the text between the first and the second `.Nd' macro, by
-    # - delete up to first .Nd;
-    # - of this, print everything up to next .Nd, and delete the rest;
-    # - of this, delete the final .Nd line;
-    cat_z "$1" | sed -e '1,/'"${wi_dot}"'Nd/d' \
-              | sed -e '1,/'"${wi_dot}"'Nd/p
-d' \
-              | sed -e '/'"${wi_dot}"'Nd/d';
-    eval ${_UNSET} wi_dot;
-    eval ${_UNSET} wi_res;
+    if obj wf_section is_not_empty
+    then
+      wf_res="$(obj wf_res echo1 | sed -n -e '
+s/^\(.*\)$/'"${wf_name}"' ('"${wf_section}"') \\[em] \1/p
+')";
+    fi;
+    obj wf_res echo1;
+    echo;
+    eval ${_UNSET} wf_arg;
+    eval ${_UNSET} wf_dot;
+    eval ${_UNSET} wf_name;
+    eval ${_UNSET} wf_res;
+    eval ${_UNSET} wf_section;
     eval "${return_ok}";
   fi;
-  echo 'is not a man page.';
-  eval ${_UNSET} wi_dot;
-  eval ${_UNSET} wi_res;
+  echo1 'is not a man page';
+  echo;
+  eval ${_UNSET} wf_arg;
+  eval ${_UNSET} wf_dot;
+  eval ${_UNSET} wf_name;
+  eval ${_UNSET} wf_res;
+  eval ${_UNSET} wf_section;
   eval "${return_bad}";
 }
 
 
 ########################################################################
+# whatis_filespec ()
+#
+# Print the filespec name as .SH to the temporary cat file.
+#
+whatis_filespec()
+{
+  func_check whatis_filespec '=' 0 "$@";
+  if obj _OPT_WHATIS is_yes
+  then
+    eval to_tmp_line \
+      "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
+    exit_test;
+  fi;
+  eval "${return_ok}";
+}
+
+
+########################################################################
+# whatis_header ()
+#
+# Print the whatis header to the temporary cat file.
+#
+whatis_header()
+{
+  func_check whatis_header '=' 0 "$@";
+  if obj _OPT_WHATIS is_yes
+  then
+     to_tmp_line '.TH GROFFER WHATIS';
+  fi;
+  eval "${return_ok}";
+}
+
+
+########################################################################
 # where_is (<program>)
 #
 # Output path of a program if in $PATH.
@@ -3591,6 +4095,7 @@
       ;;
   esac;
   eval set x "$(path_split "${PATH}")";
+  exit_test;
   shift;
   for p
   do
@@ -3626,9 +4131,6 @@
 # - main_display(): do the displaying
 # - main(): the main function that calls all main_*()
 
-# These parts are implemented as functions, being defined below in the
-# sequence they are called in the main() function.
-
 
 #######################################################################
 # main_init ()
@@ -3642,8 +4144,8 @@
 main_init()
 {
   func_check main_init = 0 "$@";
-  # call clean_up() on any signal
-  trap_set clean_up;
+  # call clean_up() on shell termination.
+  trap_set;
 
   # create temporary directory
   umask 0022;
@@ -3707,9 +4209,14 @@
     error "main_init: \
 Couldn't create a directory for storing temporary files.";
   fi;
+  if obj _DEBUG_PRINT_TMPDIR is_yes
+  then
+    echo2 "temporary directory: ${_TMP_DIR}";
+  fi;
 
   _TMP_CAT="$(tmp_create groffer_cat)";
   _TMP_STDIN="$(tmp_create groffer_input)";
+  exit_test;
 
   eval ${_UNSET} mi_dir;
   eval ${_UNSET} mi_n;
@@ -3728,7 +4235,6 @@
 # Globals:
 #   in: $MANOPT, $_OPTS_MANOPT_*
 #   out: $_MANOPT_*
-#   in/out: $GROFFER_OPT
 #
 # Variable prefix: mpm
 #
@@ -3740,9 +4246,10 @@
   then
     # Delete leading and final spaces
     MANOPT="$(echo1 "${MANOPT}" | sed -e '
-s/^['"${_SP}${_TAB}"']*//
-s/['"${_SP}${_TAB}"']*$//
+s/^'"${_SPACE_SED}"'*//
+s/'"${_SPACE_SED}"'*$//
 ')";
+  exit_test;
   fi;
   if obj MANOPT is_empty
   then
@@ -3752,108 +4259,107 @@
   mpm_list='';
   # add arguments in $MANOPT by mapping them to groffer options
   eval set x "$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")";
+  exit_test;
   shift;
   until test "$#" -le 0 || is_equal "$1" '--'
   do
     mpm_opt="$1";
     shift;
     case "${mpm_opt}" in
-      -7|--ascii)
-        list_append mpm_list '--ascii';
-        ;;
-      -a|--all)
-        list_append mpm_list '--all';
-        ;;
-      -c|--catman)
-        do_nothing;
-        shift;
-        ;;
-      -d|--debug)
-       do_nothing;
-        ;;
-      -D|--default)
-        # undo all man options so far
-        mpm_list='';
-        ;;
-      -e|--extension)
-        list_append mpm_list '--extension';
-        shift;
-        ;;
-      -f|--whatis)
-        list_append mpm_list '--whatis';
-        shift;
-        ;;
-      -h|--help)
-        do_nothing;
-        shift;
-        ;;
-      -k|--apropos)
-       # groffer's --apropos takes an argument, but man's does not, so
-        do_nothing;
-        ;;
-      -l|--local-file)
-        do_nothing;
-        ;;
-      -L|--locale)
-        list_append mpm_list '--locale' "$1";
-        shift;
-        ;;
-      -m|--systems)
-        list_append mpm_list '--systems' "$1";
-        shift;
-        ;;
-      -M|--manpath)
-        list_append mpm_list '--manpath' "$1";
-        shift;
-        ;;
-      -p|--preprocessor)
-        do_nothing;
-        shift;
-        ;;
-      -P|--pager)
-        list_append mpm_list '--pager' "$1";
-        shift;
-        ;;
-      -r|--prompt)
-        do_nothing;
-        shift;
-        ;;
-      -S|--sections)
-        list_append mpm_list '--sections' "$1";
-        shift;
-        ;;
-      -t|--troff)
-        do_nothing;
-        shift;
-        ;;
-      -T|--device)
-        list_append mpm_list '-T' "$1";
-        shift;
-        ;;
-      -u|--update)
-        do_nothing;
-        shift;
-        ;;
-      -V|--version)
-        do_nothing;
-        ;;
-      -w|--where|--location)
-        list_append mpm_list '--location';
-        ;;
-      -Z|--ditroff)
-        do_nothing;
-        ;;
-      # ignore all other options
+    -7|--ascii)
+      list_append mpm_list '--ascii';
+      ;;
+    -a|--all)
+      list_append mpm_list '--all';
+      ;;
+    -c|--catman)
+      do_nothing;
+      shift;
+      ;;
+    -d|--debug)
+      do_nothing;
+      ;;
+    -D|--default)
+      # undo all man options so far
+      mpm_list='';
+      ;;
+    -e|--extension)
+      list_append mpm_list '--extension';
+      shift;
+      ;;
+    -f|--whatis)
+      list_append mpm_list '--whatis';
+      shift;
+      ;;
+    -h|--help)
+      do_nothing;
+      shift;
+      ;;
+    -k|--apropos)
+      # groffer's --apropos takes an argument, but man's does not, so
+      do_nothing;
+      ;;
+    -l|--local-file)
+      do_nothing;
+      ;;
+    -L|--locale)
+      list_append mpm_list '--locale' "$1";
+      shift;
+      ;;
+    -m|--systems)
+      list_append mpm_list '--systems' "$1";
+      shift;
+      ;;
+    -M|--manpath)
+      list_append mpm_list '--manpath' "$1";
+      shift;
+      ;;
+    -p|--preprocessor)
+      do_nothing;
+      shift;
+      ;;
+    -P|--pager)
+      list_append mpm_list '--pager' "$1";
+      shift;
+      ;;
+    -r|--prompt)
+      do_nothing;
+      shift;
+      ;;
+    -S|--sections)
+      list_append mpm_list '--sections' "$1";
+      shift;
+      ;;
+    -t|--troff)
+      do_nothing;
+      shift;
+      ;;
+    -T|--device)
+      list_append mpm_list '-T' "$1";
+      shift;
+      ;;
+    -u|--update)
+      do_nothing;
+      shift;
+      ;;
+    -V|--version)
+      do_nothing;
+      ;;
+    -w|--where|--location)
+      list_append mpm_list '--location';
+      ;;
+    -Z|--ditroff)
+      do_nothing;
+      ;;
+    # ignore all other options
     esac;
   done;
 
-  # prepend $mpm_list to $GROFFER_OPT
-  if obj GROFFER_OPT is_empty
-  then
-    GROFFER_OPT="${mpm_list}";
-  elif obj mpm_list is_not_empty
+  # prepend $mpm_list to the command line
+  if obj mpm_list is_not_empty
   then
-    GROFFER_OPT="${mpm_list} ${GROFFER_OPT}";
+    eval set x "${mpm_list}" '"$@"';
+    shift;
   fi;
 
   eval ${_UNSET} mpm_list;
@@ -3877,10 +4383,8 @@
 main_parse_args()
 {
   func_check main_parse_args '>=' 0 "$@";
-  eval set x "${GROFFER_OPT}" '"$@"';
-  shift;
-
   _ALL_PARAMS="$(list_from_cmdline _OPTS_CMDLINE "$@")";
+  exit_test;
   if obj _DEBUG_PRINT_PARAMS is_yes
   then
     echo2 "parameters: ${_ALL_PARAMS}";
@@ -3902,303 +4406,374 @@
     mpa_opt="$1";              # $mpa_opt is fed into the option handler
     shift;
     case "${mpa_opt}" in
-      -h|--help)
-        usage;
-        leave;
-        ;;
-      -Q|--source)             # output source code (`Quellcode').
-        _OPT_MODE='source';
-        ;;
-      -T|--device|--troff-device) # device; arg
-        _OPT_DEVICE="$1";
-        _check_device_with_mode;
+    -h|--help)
+      usage;
+      leave;
+      ;;
+    -Q|--source)               # output source code (`Quellcode').
+      _OPT_MODE='source';
+      ;;
+    -T|--device|--troff-device) # device; arg
+      _OPT_DEVICE="$1";
+      _check_device_with_mode;
+      shift;
+      ;;
+    -v|--version)
+      version;
+      leave;
+      ;;
+    -V)
+      _OPT_V='yes';
+      ;;
+    -Z|--ditroff|--intermediate-output) # groff intermediate output
+      _OPT_Z='yes';
+      ;;
+    -X)
+      if is_X
+      then
+        _OPT_MODE=X;
+      fi;
+      ;;
+    -?)
+      # delete leading `-'
+      mpa_optchar="$(echo1 "${mpa_opt}" | sed -e 's/^-//')";
+      exit_test;
+      if list_has _OPTS_GROFF_SHORT_NA "${mpa_optchar}"
+      then
+        list_append _ADDOPTS_GROFF "${mpa_opt}";
+      elif list_has _OPTS_GROFF_SHORT_ARG "${mpa_optchar}"
+      then
+        list_append _ADDOPTS_GROFF "${mpa_opt}" "$1";
         shift;
+      else
+        error "main_parse_args(): Unknown option : \`$1'";
+      fi;
+      ;;
+    --all)
+        _OPT_ALL='yes';
         ;;
-      -v|--version)
-        version;
-        leave;
-        ;;
-      -V)
-        _OPT_V='yes';
+    --apropos)                 # run `apropos'
+      _OPT_APROPOS='yes';
+      _APROPOS_SECTIONS='';
+      _OPT_WHATIS='no';
+      ;;
+    --apropos-data)            # run `apropos' for data sections
+      _OPT_APROPOS='yes';
+      _APROPOS_SECTIONS='457';
+      _OPT_WHATIS='no';
+      ;;
+    --apropos-devel)           # run `apropos' for development sections
+      _OPT_APROPOS='yes';
+      _APROPOS_SECTIONS='239';
+      _OPT_WHATIS='no';
+      ;;
+    --apropos-progs)           # run `apropos' for program sections
+      _OPT_APROPOS='yes';
+      _APROPOS_SECTIONS='168';
+      _OPT_WHATIS='no';
+      ;;
+    --ascii)
+      list_append _ADDOPTS_GROFF '-mtty-char';
+      if obj _OPT_MODE is_empty
+      then
+        _OPT_MODE='text';
+      fi;
+      ;;
+    --auto)                    # the default automatic mode
+      _OPT_MODE='';
+      ;;
+    --bd)                      # border color for viewers, arg;
+      _OPT_BD="$1";
+      shift;
+      ;;
+    --bg|--backgroud)          # background color for viewers, arg;
+      _OPT_BG="$1";
+      shift;
+      ;;
+    --bw)                      # border width for viewers, arg;
+      _OPT_BW="$1";
+      shift;
+      ;;
+    --debug|--debug-all|--debug-keep|--debug-lm|--debug-params|\
+--debug-shell|--debug-stacks|--debug-tmpdir|--debug-user)
+      # debug is handled at the beginning
+      :;
+      ;;
+    --default)                 # reset variables to default
+      reset;
+      ;;
+    --default-modes)           # sequence of modes in auto mode; arg
+      _OPT_DEFAULT_MODES="$1";
+      shift;
+      ;;
+    --display)                 # set X display, arg
+      _OPT_DISPLAY="$1";
+      shift;
+      ;;
+    --do-nothing)
+      _OPT_DO_NOTHING='yes';
+      ;;
+    --dvi)
+      if is_X
+      then
+        _OPT_MODE='dvi';
+      fi;
+      ;;
+    --dvi-viewer)              # viewer program for dvi mode; arg
+      _VIEWER_TERMINAL='no';
+      _OPT_VIEWER_DVI="$1";
+      shift;
+      ;;
+    --dvi-viewer-tty)          # viewer program for dvi mode in tty; arg
+      _VIEWER_TERMINAL='yes';
+      _OPT_VIEWER_DVI="$1";
+      shift;
+      ;;
+    --extension)               # the extension for man pages, arg
+      _OPT_EXTENSION="$1";
+      shift;
+      ;;
+    --fg|--foreground)         # foreground color for viewers, arg;
+      _OPT_FG="$1";
+      shift;
+      ;;
+    --fn|--font)               # set font for viewers, arg;
+      _OPT_FN="$1";
+      shift;
+      ;;
+    --geometry)                        # window geometry for viewers, arg;
+      _OPT_GEOMETRY="$1";
+      shift;
+      ;;
+    --groff)
+      _OPT_MODE='groff';
+      ;;
+    --html|--www)              # display with web browser
+      _OPT_MODE=html;
+      ;;
+    --html-viewer|--www-viewer) # viewer program for html mode; arg
+      _VIEWER_TERMINAL='no';
+      _OPT_VIEWER_HTML="$1";
+      shift;
+      ;;
+    --html-viewer-tty|--www-viewer-tty) # viewer for html mode in tty; arg
+      _VIEWER_TERMINAL='yes';
+      _OPT_VIEWER_HTML="$1";
+      shift;
+      ;;
+    --iconic)                  # start viewers as icons
+      _OPT_ICONIC='yes';
+      ;;
+    --locale)                  # set language for man pages, arg
+      # argument is address@hidden (ISO 639,...)
+      _OPT_LANG="$1";
+      shift;
+      ;;
+    --local-file)              # force local files; same as `--no-man'
+      _MAN_FORCE='no';
+      _MAN_ENABLE='no';
+      ;;
+    --location|--where)                # print file locations to stderr
+      _OPT_LOCATION='yes';
+      ;;
+    --man)                    # force all file params to be man pages
+      _MAN_ENABLE='yes';
+      _MAN_FORCE='yes';
+      ;;
+    --manpath)               # specify search path for man pages, arg
+      # arg is colon-separated list of directories
+      _OPT_MANPATH="$1";
+      shift;
+      ;;
+    --mode)                    # display mode
+      mpa_arg="$1";
+      shift;
+      case "${mpa_arg}" in
+      auto|'')              # search mode automatically among default
+        _OPT_MODE='';
         ;;
-      -Z|--ditroff|--intermediate-output) # groff intermediate output
-        _OPT_Z='yes';
+      groff)                   # pass input to plain groff
+        _OPT_MODE='groff';
         ;;
-      -X)
-        _OPT_MODE=X;
+      html|www)                        # display with a web browser
+        _OPT_MODE='html';
         ;;
-      -?)
-        # delete leading `-'
-        mpa_optchar="$(echo1 "${mpa_opt}" | sed -e 's/^-//')";
-        if list_has _OPTS_GROFF_SHORT_NA "${mpa_optchar}"
+      dvi)                     # display with xdvi viewer
+        if is_X
         then
-          list_append _ADDOPTS_GROFF "${mpa_opt}";
-        elif list_has _OPTS_GROFF_SHORT_ARG "${mpa_optchar}"
-        then
-          list_append _ADDOPTS_GROFF "${mpa_opt}" "$1";
-          shift;
-        else
-          error "main_parse_args(): Unknown option : \`$1'";
+          _OPT_MODE='dvi';
         fi;
         ;;
-      --all)
-          _OPT_ALL="yes";
-          ;;
-      --apropos)               # run `apropos'
-       apropos_run "$1";
-        leave "$?";
-        ;;
-      --apropos-data)          # run `apropos' for data sections
-       apropos_run "$1" | grep '^[^(]*([457][^)]*)';
-        leave "$?";
-        ;;
-      --apropos-devel)         # run `apropos' for development sections
-       apropos_run "$1" | grep '^[^(]*([239][^)]*)';
-        leave "$?";
-        ;;
-      --apropos-progs)         # run `apropos' for program sections
-       apropos_run "$1" | grep '^[^(]*([168][^)]*)';
-        leave "$?";
-        ;;
-      --ascii)
-        list_append _ADDOPTS_GROFF '-mtty-char';
-        if obj _OPT_MODE is_empty
+      pdf)                     # display with PDF viewer
+        if is_X
         then
-         _OPT_MODE='text';
+          _OPT_MODE='pdf';
         fi;
         ;;
-      --auto)                  # the default automatic mode
-        _OPT_MODE='';
-        ;;
-      --bd)                    # border color for viewers, arg;
-        _OPT_BD="$1";
-        shift;
-        ;;
-      --bg|--backgroud)                # background color for viewers, arg;
-        _OPT_BG="$1";
-        shift;
-        ;;
-      --bw)                    # border width for viewers, arg;
-        _OPT_BW="$1";
-        shift;
-        ;;
-      --default)               # reset variables to default
-        reset;
-        ;;
-      --default-modes)         # sequence of modes in auto mode; arg
-        _OPT_DEFAULT_MODES="$1";
-        shift;
-        ;;
-      --debug)                 # only for development
-        _OPT_DEBUG='yes';
-        ;;
-      --display)               # set X display, arg
-        _OPT_DISPLAY="$1";
-        shift;
-        ;;
-      --do-nothing)
-        leave;
-        ;;
-      --dvi)
-        _OPT_MODE='dvi';
-        ;;
-      --dvi-viewer)            # viewer program for dvi mode; arg
-        _OPT_VIEWER_DVI="$1";
-        shift;
-        ;;
-      --extension)             # the extension for man pages, arg
-        _OPT_EXTENSION="$1";
-        shift;
-        ;;
-      --fg|--foreground)       # foreground color for viewers, arg;
-        _OPT_FG="$1";
-        shift;
-        ;;
-      --fn|--font)             # set font for viewers, arg;
-        _OPT_FN="$1";
-        shift;
-        ;;
-      --geometry)              # window geometry for viewers, arg;
-        _OPT_GEOMETRY="$1";
-        shift;
-        ;;
-      --groff)
-        _OPT_MODE='groff';
-        ;;
-      --html|--www)            # display with web browser
-        _OPT_MODE=html;
-        ;;
-      --html-viewer|--www-viewer) # viewer program for html mode; arg
-        _OPT_VIEWER_HTML="$1";
-        shift;
-        ;;
-      --iconic)                        # start viewers as icons
-        _OPT_ICONIC='yes';
-        ;;
-      --locale)                        # set language for man pages, arg
-        # argument is address@hidden (ISO 639,...)
-        _OPT_LANG="$1";
-        shift;
-        ;;
-      --local-file)            # force local files; same as `--no-man'
-        _MAN_FORCE='no';
-        _MAN_ENABLE='no';
-        ;;
-      --location|--where)      # print file locations to stderr
-        _OPT_LOCATION='yes';
+      ps)                      # display with Postscript viewer
+        if is_X
+        then
+          _OPT_MODE='ps';
+        fi;
         ;;
-      --man)                   # force all file params to be man pages
-        _MAN_ENABLE='yes';
-        _MAN_FORCE='yes';
+      text)                    # output on terminal
+        _OPT_MODE='text';
         ;;
-      --manpath)               # specify search path for man pages, arg
-        # arg is colon-separated list of directories
-        _OPT_MANPATH="$1";
-        shift;
+      tty)                     # output on terminal
+        _OPT_MODE='tty';
         ;;
-      --mode)                  # display mode
-        mpa_arg="$1";
-        shift;
-        case "${mpa_arg}" in
-          auto|'')             # search mode automatically among default
-           _OPT_MODE='';
-            ;;
-          groff)               # pass input to plain groff
-            _OPT_MODE='groff';
-            ;;
-          html|www)            # display with a web browser
-            _OPT_MODE='html';
-            ;;
-          dvi)                 # display with xdvi viewer
-            _OPT_MODE='dvi';
-            ;;
-          pdf)                 # display with PDF viewer
-            _OPT_MODE='pdf';
-            ;;
-          ps)                  # display with Postscript viewer
-            _OPT_MODE='ps';
-            ;;
-          text)                        # output on terminal
-            _OPT_MODE='text';
-            ;;
-          tty)                 # output on terminal
-            _OPT_MODE='tty';
-            ;;
-          X|x)                 # output on X roff viewer
-            _OPT_MODE='x';
-            ;;
-          Q|source)            # display source code
-            _OPT_MODE="source";
-            ;;
-         *)
-            error "main_parse_args(): unknown mode ${mpa_arg}";
-            ;;
-        esac;
-        ;;
-      --no-location)           # disable former call to `--location'
-        _OPT_LOCATION='yes';
+      X|x)                     # output on X roff viewer
+        if is_X
+        then
+          _OPT_MODE='x';
+        fi;
         ;;
-      --no-man)                        # disable search for man pages
-        # the same as --local-file
-        _MAN_FORCE="no";
-        _MAN_ENABLE="no";
+      Q|source)                        # display source code
+        _OPT_MODE="source";
         ;;
-      --pager|--tty-viewer)    # set paging program for tty mode, arg
-        _OPT_PAGER="$1";
-        shift;
+      *)
+        error "main_parse_args(): unknown mode ${mpa_arg}";
         ;;
-      --pdf)
+      esac;
+      ;;
+    --no-location)             # disable former call to `--location'
+      _OPT_LOCATION='yes';
+      ;;
+    --no-man)                  # disable search for man pages
+      # the same as --local-file
+      _MAN_FORCE='no';
+      _MAN_ENABLE='no';
+      ;;
+    --no-special)              # disable some special former calls
+      _OPT_ALL='no'
+      _OPT_APROPOS='no'
+      _OPT_WHATIS='no'
+      ;;
+    --pager|--tty-viewer|--tty-viewer-tty)
+      # set paging program for tty mode, arg
+      _VIEWER_TERMINAL='yes';
+      _OPT_PAGER="$1";
+      shift;
+      ;;
+    --pdf)
+      if is_X
+      then
         _OPT_MODE='pdf';
-        ;;
-      --pdf-viewer)            # viewer program for ps mode; arg
-        _OPT_VIEWER_PDF="$1";
-        shift;
-        ;;
-      --ps)
+      fi;
+      ;;
+    --pdf-viewer)              # viewer program for ps mode; arg
+      _VIEWER_TERMINAL='no';
+      _OPT_VIEWER_PDF="$1";
+      shift;
+      ;;
+    --pdf-viewer-tty)          # viewer program for ps mode in tty; arg
+      _VIEWER_TERMINAL='yes';
+      _OPT_VIEWER_PDF="$1";
+      shift;
+      ;;
+    --print)                   # for argument test
+      echo2 "$1";
+      shift;
+      ;;
+    --ps)
+      if is_X
+      then
         _OPT_MODE='ps';
+      fi;
+      ;;
+    --ps-viewer)               # viewer program for ps mode; arg
+      _VIEWER_TERMINAL='no';
+      _OPT_VIEWER_PS="$1";
+      shift;
+      ;;
+    --ps-viewer-tty)           # viewer program for ps mode in tty; arg
+      _VIEWER_TERMINAL='yes';
+      _OPT_VIEWER_PS="$1";
+      shift;
+      ;;
+    --resolution)              # set resolution for X devices, arg
+      mpa_arg="$1";
+      shift;
+      case "${mpa_arg}" in
+      75|75dpi)
+        mpa_dpi=75;
         ;;
-      --ps-viewer)             # viewer program for ps mode; arg
-        _OPT_VIEWER_PS="$1";
-        shift;
+      100|100dpi)
+        mpa_dpi=100;
         ;;
-      --resolution)            # set resolution for X devices, arg
-        mpa_arg="$1";
-        shift;
-        case "${mpa_arg}" in
-          75|75dpi)
-            mpa_dpi=75;
-            ;;
-          100|100dpi)
-            mpa_dpi=100;
-            ;;
-          *)
-            error "main_parse_args(): \
+      *)
+        error "main_parse_args(): \
 only resoutions of 75 or 100 dpi are supported";
-            ;;
-        esac;
-        _OPT_RESOLUTION="${mpa_dpi}";
-        ;;
-      --rv)
-        _OPT_RV='yes';
-        ;;
-      --sections)              # specify sections for man pages, arg
-        # arg is colon-separated list of section names
-        _OPT_SECTIONS="$1";
-        shift;
-        ;;
-      --shell)
-        # already done during the first run; so ignore the argument
-        shift;
-        ;;
-      --systems)               # man pages for different OS's, arg
-        # argument is a comma-separated list
-        _OPT_SYSTEMS="$1";
-        shift;
-        ;;
-      --text)                  # text mode without pager
-        _OPT_MODE=text;
-        ;;
-      --title)                 # title for X viewers; arg
-        _OPT_TITLE="$1";
-        shift;
-        ;;
-      --tty)                   # tty mode, text with pager
-        _OPT_MODE=tty;
-        ;;
-      --text-device|--tty-device) # device for tty mode; arg
-        _OPT_TEXT_DEVICE="$1";
-        shift;
         ;;
-      --whatis)
-        _OPT_WHATIS='yes';
-        ;;
-      --X|--x)
+      esac;
+      _OPT_RESOLUTION="${mpa_dpi}";
+      ;;
+    --rv)
+      _OPT_RV='yes';
+      ;;
+    --sections)                        # specify sections for man pages, arg
+      # arg is colon-separated list of section names
+      _OPT_SECTIONS="$1";
+      shift;
+      ;;
+    --shell)
+      # already done during the first run; so ignore the argument
+      shift;
+      ;;
+    --systems)                 # man pages for different OS's, arg
+      # argument is a comma-separated list
+      _OPT_SYSTEMS="$1";
+      shift;
+      ;;
+    --text)                    # text mode without pager
+      _OPT_MODE=text;
+      ;;
+    --title)                   # title for X viewers; arg
+      _OPT_TITLE="$1";
+      shift;
+      ;;
+    --tty)                     # tty mode, text with pager
+      _OPT_MODE=tty;
+      ;;
+    --text-device|--tty-device) # device for tty mode; arg
+      _OPT_TEXT_DEVICE="$1";
+      shift;
+      ;;
+    --whatis)
+      _OPT_WHATIS='yes';
+      _OPT_ALL='yes';
+      _OPT_APROPOS='no';
+      ;;
+    --X|--x)
+      if is_X
+      then
         _OPT_MODE=x;
-        ;;
-      --xrm)                   # pass X resource string, arg;
-        list_append _OPT_XRM "$1";
-        shift;
-        ;;
-      --x-viewer|--X-viewer)   # viewer program for x mode; arg
-        _OPT_VIEWER_X="$1";
-        shift;
-        ;;
-      *)
-        error 'main_parse_args(): error on argument parsing : '"\`$*'";
-        ;;
+      fi;
+      ;;
+    --xrm)                     # pass X resource string, arg;
+      list_append _OPT_XRM "$1";
+      shift;
+      ;;
+    --x-viewer|--X-viewer)     # viewer program for x mode; arg
+      _VIEWER_TERMINAL='no';
+      _OPT_VIEWER_X="$1";
+      shift;
+      ;;
+    --x-viewer-tty|--X-viewer-tty) # viewer program for x mode in tty; arg
+      _VIEWER_TERMINAL='yes';
+      _OPT_VIEWER_X="$1";
+      shift;
+      ;;
+    *)
+      error 'main_parse_args(): error on argument parsing : '"\`$*'";
+      ;;
     esac;
   done;
   shift;                       # remove `--' argument
-  if obj _DEBUG is_not_yes
+
+  if obj _OPT_DO_NOTHING is_yes
   then
-    if obj _OPT_DEBUG is_yes
-    then
-      _DEBUG='yes';
-      _DEBUG_LM='yes';
-      _DEBUG_KEEP_FILES='yes';
-      _DEBUG_PRINT_PARAMS='yes';
-      _DEBUG_PRINT_SHELL='yes';
-    fi;
+    leave;
   fi;
 
   # Remaining arguments are file names (filespecs).
@@ -4229,37 +4804,37 @@
 {
   func_check _check_device_with_mode = 0 "$@";
   case "${_OPT_DEVICE}" in
-    dvi)
-      _OPT_MODE=dvi;
-      eval "${return_ok}";
-      ;;
-    html)
-      _OPT_MODE=html;
-      eval "${return_ok}";
-      ;;
-    lbp|lj4)
-      _OPT_MODE=groff;
-      eval "${return_ok}";
-      ;;
-    ps)
-      _OPT_MODE=ps;
-      eval "${return_ok}";
-      ;;
-    ascii|cp1047|latin1|utf8)
-      if obj _OPT_MODE is_not_equal text
-      then
-        _OPT_MODE=tty;         # default text mode
-      fi;
-      eval "${return_ok}";
-      ;;
-    X*)
-      _OPT_MODE=x;
-      eval "${return_ok}";
-      ;;
-    *)                         # unknown device, go to groff mode
-      _OPT_MODE=groff;
-      eval "${return_ok}";
-      ;;
+  dvi)
+    _OPT_MODE=dvi;
+    eval "${return_ok}";
+    ;;
+  html)
+    _OPT_MODE=html;
+    eval "${return_ok}";
+    ;;
+  lbp|lj4)
+    _OPT_MODE=groff;
+    eval "${return_ok}";
+    ;;
+  ps)
+    _OPT_MODE=ps;
+    eval "${return_ok}";
+    ;;
+  ascii|cp1047|latin1|utf8)
+    if obj _OPT_MODE is_not_equal text
+    then
+      _OPT_MODE=tty;           # default text mode
+    fi;
+    eval "${return_ok}";
+    ;;
+  X*)
+    _OPT_MODE=x;
+    eval "${return_ok}";
+    ;;
+  *)                           # unknown device, go to groff mode
+    _OPT_MODE=groff;
+    eval "${return_ok}";
+    ;;
   esac;
   eval "${return_error}";
 } # _check_device_with_mode() of main_parse_args()
@@ -4280,28 +4855,6 @@
 {
   func_check main_set_mode = 0 "$@";
 
-  # handle apropos
-  if obj _OPT_APROPOS is_not_empty
-  then
-    apropos "${_OPT_APROPOS}";
-    leave "$?";
-  fi;
-  if obj _OPT_APROPOS_DATA is_not_empty
-  then
-    apropos "$@" | grep '^[^(]*([457])';
-    leave "$?";
-  fi;
-  if obj _OPT_APROPOS_DEVEL is_not_empty
-  then
-    apropos "$@" | grep '^[^(]*([239])';
-    leave "$?";
-  fi;
-  if obj _OPT_APROPOS_PROGS is_not_empty
-  then
-    apropos "$@" | grep '^[^(]*([168])';
-    leave "$?";
-  fi;
-
   # set display
   if obj _OPT_DISPLAY is_not_empty
   then
@@ -4339,46 +4892,179 @@
   fi;
 
   case "${_OPT_MODE}" in
-    '')                                # automatic mode
-      case "${_OPT_DEVICE}" in
-        X*)
-          if obj DISPLAY is_empty
-          then
-            error "main_set_mode(): \
-no X display found for device ${_OPT_DEVICE}";
-          fi;
-          _DISPLAY_MODE='x';
-          eval ${_UNSET} msm_modes;
-          eval ${_UNSET} msm_viewer;
-          eval ${_UNSET} msm_viewers;
-          eval "${return_ok}";
-          ;;
-        ascii|cp1047|latin1|utf8)
-          if obj _DISPLAY_MODE is_not_equal 'text'
-          then
-            _DISPLAY_MODE='tty';
-          fi;
-          eval ${_UNSET} msm_modes;
-          eval ${_UNSET} msm_viewer;
-          eval ${_UNSET} msm_viewers;
-          eval "${return_ok}";
-          ;;
-      esac;
-      if obj DISPLAY is_empty
+  '')                          # automatic mode
+    case "${_OPT_DEVICE}" in
+    X*)
+     if is_not_X
+      then
+        error_user "no X display found for device ${_OPT_DEVICE}";
+      fi;
+      _DISPLAY_MODE='x';
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
+      ;;
+    ascii|cp1047|latin1|utf8)
+      if obj _DISPLAY_MODE is_not_equal 'text'
+      then
+        _DISPLAY_MODE='tty';
+      fi;
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
+      ;;
+    esac;
+    if is_not_X
+    then
+      _DISPLAY_MODE='tty';
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
+    fi;
+
+    if obj _OPT_DEFAULT_MODES is_empty
+    then
+      msm_modes="${_DEFAULT_MODES}";
+    else
+      msm_modes="${_OPT_DEFAULT_MODES}";
+    fi;
+    ;;
+  text)
+    _DISPLAY_MODE='text';
+    eval ${_UNSET} msm_modes;
+    eval ${_UNSET} msm_viewer;
+    eval ${_UNSET} msm_viewers;
+    eval "${return_ok}";
+    ;;
+  tty)
+    _DISPLAY_MODE='tty';
+    eval ${_UNSET} msm_modes;
+    eval ${_UNSET} msm_viewer;
+    eval ${_UNSET} msm_viewers;
+    eval "${return_ok}";
+    ;;
+  html)
+    _DISPLAY_MODE='html';
+    msm_modes="${_OPT_MODE}";
+    ;;
+  *)                           # display mode was given
+    if is_not_X
+    then
+      error_user "You must be in X Window for ${_OPT_MODE} mode.";
+    fi;
+    msm_modes="${_OPT_MODE}";
+    ;;
+  esac;
+
+  # only viewer modes are left
+  eval set x "$(list_from_split "${msm_modes}" ',')";
+  exit_test;
+  shift;
+  while test "$#" -gt 0
+  do
+    m="$1";
+    shift;
+    case "$m" in
+    dvi)
+      if obj _OPT_VIEWER_DVI is_not_empty
+      then
+        msm_viewer="${_OPT_VIEWER_DVI}";
+      else
+        msm_viewer="$(_get_first_prog "$_VIEWER_DVI}")";
+        exit_test;
+      fi;
+      if obj msm_viewer is_empty
+      then
+        error 'No viewer for dvi mode available.';
+      fi;
+      if is_not_equal "$?" 0
+      then
+        continue;
+      fi;
+      _DISPLAY_PROG="${msm_viewer}";
+      _DISPLAY_MODE="dvi";
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
+      ;;
+    html)
+      if obj _OPT_VIEWER_HTML is_not_empty
+      then
+        msm_viewer="${_OPT_VIEWER_HTML}";
+      else
+        if is_X
+        then
+          msm_viewers="${_VIEWER_HTML_X}";
+        else
+          msm_viewers="${_VIEWER_HTML_TTY}";
+        fi;
+        msm_viewer="$(_get_first_prog "${msm_viewers}")";
+        exit_test;
+      fi;
+      if obj msm_viewer is_empty
+      then
+        error 'No viewer for html mode available.';
+      fi;
+      if is_not_equal "$?" 0
+      then
+        continue;
+      fi;
+      _DISPLAY_PROG="${msm_viewer}";
+      _DISPLAY_MODE=html;
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
+      ;;
+    pdf)
+      if obj _OPT_VIEWER_PDF is_not_empty
+      then
+        msm_viewer="${_OPT_VIEWER_PDF}";
+      else
+        msm_viewer="$(_get_first_prog "${_VIEWER_PDF}")";
+        exit_test;
+      fi;
+      if obj msm_viewer is_empty
       then
-        _DISPLAY_MODE='tty';
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
+        error 'No viewer for pdf mode available.';
       fi;
-
-      if obj _OPT_DEFAULT_MODES is_empty
+      if is_not_equal "$?" 0
+      then
+        continue;
+      fi;
+      _DISPLAY_PROG="${msm_viewer}";
+      _DISPLAY_MODE="pdf";
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
+      ;;
+    ps)
+      if obj _OPT_VIEWER_PS is_not_empty
       then
-        msm_modes="${_DEFAULT_MODES}";
+        msm_viewer="${_OPT_VIEWER_PS}";
       else
-        msm_modes="${_OPT_DEFAULT_MODES}";
+        msm_viewer="$(_get_first_prog "${_VIEWER_PS}")";
+        exit_test;
+      fi;
+      if obj msm_viewer is_empty
+      then
+        error 'No viewer for ps mode available.';
       fi;
+      if is_not_equal "$?" 0
+      then
+        continue;
+      fi;
+      _DISPLAY_PROG="${msm_viewer}";
+      _DISPLAY_MODE="ps";
+     eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
       ;;
     text)
       _DISPLAY_MODE='text';
@@ -4394,146 +5080,42 @@
       eval ${_UNSET} msm_viewers;
       eval "${return_ok}";
       ;;
-    *)                         # display mode was given
-      if obj DISPLAY is_empty
+    x)
+      if obj _OPT_VIEWER_X is_not_empty
+      then
+        msm_viewer="${_OPT_VIEWER_X}";
+      else
+        msm_viewer="$(_get_first_prog "${_VIEWER_X}")";
+        exit_test;
+      fi;
+      if obj msm_viewer is_empty
+      then
+        error 'No viewer for x mode available.';
+      fi;
+      if is_not_equal "$?" 0
       then
-        error "main_set_mode(): \
-you must be in X Window for ${_OPT_MODE} mode.";
+        continue;
       fi;
-      msm_modes="${_OPT_MODE}";
+      _DISPLAY_PROG="${msm_viewer}";
+      _DISPLAY_MODE='x';
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
+      ;;
+    X)
+      _DISPLAY_MODE='X';
+      eval ${_UNSET} msm_modes;
+      eval ${_UNSET} msm_viewer;
+      eval ${_UNSET} msm_viewers;
+      eval "${return_ok}";
       ;;
-  esac;
-
-  # only viewer modes are left
-  eval set x "$(list_from_split "${msm_modes}" ',')";
-  shift;
-  while test "$#" -gt 0
-  do
-    m="$1";
-    shift;
-    case "$m" in
-      text)
-        _DISPLAY_MODE='text';
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
-      tty)
-        _DISPLAY_MODE='tty';
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
-      x)
-        if obj _OPT_VIEWER_X is_not_empty
-        then
-          msm_viewers="${_OPT_VIEWER_X}";
-        else
-          msm_viewers="${_VIEWER_X}";
-        fi;
-        msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0
-        then
-          continue;
-        fi;
-        _DISPLAY_PROG="${msm_viewer}";
-        _DISPLAY_MODE='x';
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
-      X)
-        _DISPLAY_MODE='X';
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
-      dvi)
-        if obj _OPT_VIEWER_DVI is_not_empty
-        then
-          msm_viewers="${_OPT_VIEWER_DVI}";
-        else
-          msm_viewers="${_VIEWER_DVI}";
-        fi;
-        msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0
-        then
-          continue;
-        fi;
-        _DISPLAY_PROG="${msm_viewer}";
-        _DISPLAY_MODE="dvi";
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
-      pdf)
-        if obj _OPT_VIEWER_PDF is_not_empty
-        then
-          msm_viewers="${_OPT_VIEWER_PDF}";
-        else
-          msm_viewers="${_VIEWER_PDF}";
-        fi;
-        msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0
-        then
-          continue;
-        fi;
-        _DISPLAY_PROG="${msm_viewer}";
-        _DISPLAY_MODE="pdf";
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
-      ps)
-        if obj _OPT_VIEWER_PS is_not_empty
-        then
-          msm_viewers="${_OPT_VIEWER_PS}";
-        else
-          msm_viewers="${_VIEWER_PS}";
-        fi;
-        msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0
-        then
-          continue;
-        fi;
-        _DISPLAY_PROG="${msm_viewer}";
-        _DISPLAY_MODE="ps";
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
-      html)
-        if obj _OPT_VIEWER_HTML is_not_empty
-        then
-          msm_viewers="${_OPT_VIEWER_HTML}";
-        else
-          msm_viewers="${_VIEWER_HTML}";
-        fi;
-        msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0
-        then
-          continue;
-        fi;
-        _DISPLAY_PROG="${msm_viewer}";
-        _DISPLAY_MODE=html;
-        eval ${_UNSET} msm_modes;
-        eval ${_UNSET} msm_viewer;
-        eval ${_UNSET} msm_viewers;
-        eval "${return_ok}";
-        ;;
     esac;
   done;
   eval ${_UNSET} msm_modes;
   eval ${_UNSET} msm_viewer;
   eval ${_UNSET} msm_viewers;
-  error "main_set_mode(): no suitable display mode found.";
+  error_user "No suitable display mode found.";
 } # main_set_mode()
 
 
@@ -4561,6 +5143,7 @@
     return "${_BAD}";
   fi;
   eval set x "$(list_from_split "$1" ',')";
+  exit_test;
   shift;
   for i
   do
@@ -4571,6 +5154,7 @@
     fi;
     if eval is_prog "$(get_first_essential ${_gfp_i})"
     then
+      exit_test;
       obj _gfp_i echo1;
       eval ${_UNSET} _gfp_i;
       return "${_GOOD}";
@@ -4594,7 +5178,7 @@
 main_do_fileargs()
 {
   func_check main_do_fileargs = 0 "$@";
-  mdfa_exitcode="${_BAD}";
+  special_setup;
   eval set x "${_FILEARGS}";
   shift;
   eval ${_UNSET} _FILEARGS;
@@ -4603,77 +5187,75 @@
   do
     # test for `s name' arguments, with `s' a 1-char standard section
     mdfa_filespec="$1";
+    _FILESPEC_ARG="$1";
     shift;
     case "${mdfa_filespec}" in
-      '')
+    '')
+      continue;
+      ;;
+    '-')
+      special_filespec;
+      if obj _OPT_APROPOS is_yes
+      then
         continue;
-        ;;
-      '-')
-        if register_file '-'
-        then
-          mdfa_exitcode="${_GOOD}";
-        fi;
+      fi;
+      register_file '-'
+      continue;
+      ;;
+    ?)
+      if obj _OPT_APROPOS is_yes
+      then
+        special_filespec;
         continue;
-        ;;
-      ?)
-        if list_has_not _MAN_AUTO_SEC "${mdfa_filespec}"
-        then
-          if do_filearg "${mdfa_filespec}"
-          then
-            mdfa_exitcode="${_GOOD}";
-          fi;
-          continue;
-        fi;
-        mdfa_name="$1";
-        case "${mdfa_name}" in
-          */*|man:*|*\(*\)|*."${mdfa_filespec}")
-            if do_filearg "${mdfa_filespec}"
-            then
-              mdfa_exitcode="${_GOOD}";
-            fi;
-            continue;
-            ;;
-        esac;
-        if do_filearg "man:${mdfa_name}(${mdfa_filespec})"
-        then
-          mdfa_exitcode="${_GOOD}";
-          shift;
-          continue;
-        else
-          if do_filearg "${mdfa_filespec}"
-          then
-            mdfa_exitcode="${_GOOD}";
-          fi;
-          continue;
-        fi;
-        ;;
-      *)
-        if do_filearg "${mdfa_filespec}"
-        then
-          mdfa_exitcode="${_GOOD}";
-        fi;
+      fi;
+      if list_has_not _MAN_AUTO_SEC_LIST "${mdfa_filespec}"
+      then
+        special_filespec;
+        do_filearg "${mdfa_filespec}"
+        continue;
+      fi;
+      mdfa_name="$1";
+      _FILESPEC_ARG="${_FILESPEC_ARG} $1";
+      special_filespec;
+      case "${mdfa_name}" in
+      */*|man:*|*\(*\)|*."${mdfa_filespec}")
+        do_filearg "${mdfa_filespec}"
         continue;
         ;;
+      esac;
+      shift;
+      if do_filearg "man:${mdfa_name}(${mdfa_filespec})"
+      then
+        continue;
+      else
+        do_filearg "${mdfa_filespec}"
+        continue;
+      fi;
+      ;;
+    *)
+      special_filespec;
+      if obj _OPT_APROPOS is_yes
+      then
+        continue;
+      fi;
+      do_filearg "${mdfa_filespec}"
+      continue;
+      ;;
     esac;
   done;                                # end of `s name' test
   while test "$#" -gt 0
   do
     mdfa_filespec="$1";
+    _FILESPEC_ARG="$1";
     shift;
-    if do_filearg "${mdfa_filespec}"
+    special_filespec;
+    if obj _OPT_APROPOS is_yes
     then
-      mdfa_exitcode="${_GOOD}";
+      continue;
     fi;
+    do_filearg "${mdfa_filespec}"
   done;
   obj _TMP_STDIN rm_file_with_debug;
-  if is_equal "${mdfa_exitcode}" "${_BAD}"
-  then
-    eval ${_UNSET} mdfa_exitcode;
-    eval ${_UNSET} mdfa_filespec;
-    eval ${_UNSET} mdfa_name;
-    eval "${return_bad}";
-  fi;
-  eval ${_UNSET} mdfa_exitcode;
   eval ${_UNSET} mdfa_filespec;
   eval ${_UNSET} mdfa_name;
   eval "${return_ok}";
@@ -4696,6 +5278,7 @@
   # $msr_rl     resource list
   msr_title="$(get_first_essential \
                  "${_OPT_TITLE}" "${_REGISTERED_TITLE}")";
+  exit_test;
   _OUTPUT_FILE_NAME='';
   eval set x "${msr_title}";
   shift;
@@ -4708,6 +5291,7 @@
       ;;
     ,*)
       msr_n="$(echo1 "$1" | sed -e 's/^,,*//')";
+      exit_test;
       ;;
     esac
     if obj msr_n is_empty
@@ -4744,6 +5328,7 @@
   eval set x "${_DISPLAY_PROG}";
   shift;
   msr_prog="$(base_name "$1")";
+  exit_test;
   shift;
   if test $# != 0
   then
@@ -4909,8 +5494,7 @@
 # Globals:
 #   in: $_DISPLAY_MODE, $_OPT_DEVICE,
 #       $_ADDOPTS_GROFF, $_ADDOPTS_POST, $_ADDOPTS_X,
-#       $_REGISTERED_TITLE, $_TMP_CAT,
-#       $_OPT_PAGER $PAGER, $_MANOPT_PAGER,
+#       $_TMP_CAT, $_OPT_PAGER, $PAGER, $_MANOPT_PAGER,
 #       $_OUTPUT_FILE_NAME
 #
 # Variable prefix: md
@@ -4937,172 +5521,182 @@
   cd "${_TMP_DIR}" >"${_NULL_DEV}" 2>&1;
 
   case "${_DISPLAY_MODE}" in
-    groff)
-      _ADDOPTS_GROFF="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
-      if obj _OPT_DEVICE is_not_empty
-      then
-        _ADDOPTS_GROFF="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
-      fi;
-      md_groggy="$(tmp_cat | eval grog "${md_options}")";
-      trap_clean;
-      _do_opt_V;
-
-      obj md_modefile rm_file;
-      mv "${_TMP_CAT}" "${md_modefile}";
-      cat "${md_modefile}" | \
-      {
-        trap clean_up 0 2>${_NULL_DEV} || :;
-        eval "${md_groggy}" "${_ADDOPTS_GROFF}";
-        clean_up;
-      } &
-      ;;
-    text|tty)
-      case "${_OPT_DEVICE}" in
-        '')
-          md_device="$(get_first_essential \
-                         "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")";
-          ;;
-        ascii|cp1047|latin1|utf8)
-          md_device="${_OPT_DEVICE}";
-          ;;
-        *)
-          warning "main_display(): \
+  groff)
+    _ADDOPTS_GROFF="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
+    if obj _OPT_DEVICE is_not_empty
+    then
+      _ADDOPTS_GROFF="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
+    fi;
+    md_groggy="$(tmp_cat | eval grog "${md_options}")";
+    exit_test;
+    _do_opt_V;
+
+    obj md_modefile rm_file;
+    mv "${_TMP_CAT}" "${md_modefile}";
+    trap_unset;
+    cat "${md_modefile}" | \
+    {
+      trap_set;
+      eval "${md_groggy}" "${_ADDOPTS_GROFF}";
+    } &
+    ;;
+  text|tty)
+    case "${_OPT_DEVICE}" in
+    '')
+      md_device="$(get_first_essential \
+                     "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")";
+      exit_test;
+      ;;
+    ascii|cp1047|latin1|utf8)
+      md_device="${_OPT_DEVICE}";
+      ;;
+    *)
+      warning "main_display(): \
 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
-          ;;
-      esac;
-      md_addopts="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
-      md_groggy="$(tmp_cat | grog -T${md_device})";
-      if obj _DISPLAY_MODE is_equal 'text'
-      then
-        _do_opt_V;
-        tmp_cat | eval "${md_groggy}" "${md_addopts}";
-      else
-        md_pager='';
-        for p in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \
-                 'less -r -R' 'more' 'pager' 'cat'
-        do
-          md_p="$p";
-          if eval is_prog ${md_p}
-          then               # no "" for is_prog() allows args for $p
-            md_pager="${md_p}";
-            break;
-          fi;
-        done;
-        if obj md_pager is_empty
-        then
-          error 'main_display(): no pager program found for tty mode';
+      ;;
+    esac;
+    md_addopts="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
+    md_groggy="$(tmp_cat | grog -T${md_device})";
+    exit_test;
+    if obj _DISPLAY_MODE is_equal 'text'
+    then
+      _do_opt_V;
+      tmp_cat | eval "${md_groggy}" "${md_addopts}";
+    else
+      md_pager='';
+      for p in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \
+               'less -r -R' 'more' 'pager' 'cat'
+      do
+        md_p="$p";
+        if eval is_prog ${md_p}
+        then                 # no "" for is_prog() allows args for $p
+          md_pager="${md_p}";
+          break;
         fi;
-        _do_opt_V;
-        tmp_cat | eval "${md_groggy}" "${md_addopts}" | \
-                  eval "${md_pager}";
+      done;
+      if obj md_pager is_empty
+      then
+        error 'main_display(): no pager program found for tty mode';
       fi;
-      clean_up;
-      ;;
-    source)
-      tmp_cat;
-      clean_up;
-      ;;
+      _do_opt_V;
+      tmp_cat | eval "${md_groggy}" "${md_addopts}" | \
+                eval "${md_pager}";
+    fi;
+    clean_up;
+    ;;
+  source)
+    tmp_cat;
+    clean_up;
+    ;;
 
-    #### viewer modes
+  #### viewer modes
 
-    dvi)
-      case "${_OPT_DEVICE}" in
-        ''|dvi) do_nothing; ;;
-        *)
-          warning "main_display(): \
+  dvi)
+    case "${_OPT_DEVICE}" in
+    ''|dvi) do_nothing; ;;
+    *)
+      warning "main_display(): \
 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"
-          ;;
-      esac;
-      md_modefile="${md_modefile}".dvi;
-      md_groggy="$(tmp_cat | grog -Tdvi)";
-      _do_display;
       ;;
-    html)
-      case "${_OPT_DEVICE}" in
-        ''|html) do_nothing; ;;
-        *)
-          warning "main_display(): \
+    esac;
+    md_modefile="${md_modefile}".dvi;
+    md_groggy="$(tmp_cat | grog -Tdvi)";
+    exit_test;
+    _do_display;
+    ;;
+  html)
+    case "${_OPT_DEVICE}" in
+    ''|html) do_nothing; ;;
+    *)
+      warning "main_display(): \
 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
-          ;;
-      esac;
-      md_modefile="${md_modefile}".html;
-      md_groggy="$(tmp_cat | grog -Thtml)";
-      _do_display;
       ;;
-    pdf)
-      case "${_OPT_DEVICE}" in
-        ''|ps)
-          do_nothing;
-          ;;
-        *)
-          warning "main_display(): \
+    esac;
+    md_modefile="${md_modefile}".html;
+    md_groggy="$(tmp_cat | grog -Thtml)";
+    exit_test;
+    _do_display;
+    ;;
+  pdf)
+    case "${_OPT_DEVICE}" in
+    ''|ps)
+      do_nothing;
+      ;;
+    *)
+      warning "main_display(): \
 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
-          ;;
-      esac;
-      md_groggy="$(tmp_cat | grog -Tps)";
-      _do_display _make_pdf;
       ;;
-    ps)
-      case "${_OPT_DEVICE}" in
-        ''|ps)
-          do_nothing;
-          ;;
-        *)
-          warning "main_display(): \
+    esac;
+    md_groggy="$(tmp_cat | grog -Tps)";
+    exit_test;
+    _do_display _make_pdf;
+    ;;
+  ps)
+    case "${_OPT_DEVICE}" in
+    ''|ps)
+      do_nothing;
+      ;;
+    *)
+      warning "main_display(): \
 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
-          ;;
-      esac;
-      md_modefile="${md_modefile}".ps;
-      md_groggy="$(tmp_cat | grog -Tps)";
-      _do_display;
       ;;
-    x)
-      case "${_OPT_DEVICE}" in
-      X*)
-        md_device="${_OPT_DEVICE}"
-        ;;
-      *)
-        case "${_OPT_RESOLUTION}" in
-        100)
-          md_device='X100';
-          if obj _OPT_GEOMETRY is_empty
-          then
-            case "${_DISPLAY_PROG}" in
-            gxditview|xditview)
-              # add width of 800dpi for resolution of 100dpi to the args
-              list_append _DISPLAY_ARGS '-geometry' '800';
-              ;;
-            esac;
-          fi;
-          ;;
-        *)
-          md_device='X75-12';
-          ;;
-        esac
-      esac;
-      md_groggy="$(tmp_cat | grog -T${md_device} -Z)";
-      _do_display;
+    esac;
+    md_modefile="${md_modefile}".ps;
+    md_groggy="$(tmp_cat | grog -Tps)";
+    exit_test;
+    _do_display;
+    ;;
+  x)
+    case "${_OPT_DEVICE}" in
+    X*)
+      md_device="${_OPT_DEVICE}"
       ;;
-    X)
-      case "${_OPT_DEVICE}" in
-      '')
-        md_groggy="$(tmp_cat | grog -X)";
-        ;;
-      X*|dvi|html|lbp|lj4|ps)
-        # these devices work with 
-        md_groggy="$(tmp_cat | grog -T"${_OPT_DEVICE}" -X)";
+    *)
+      case "${_OPT_RESOLUTION}" in
+      100)
+        md_device='X100';
+        if obj _OPT_GEOMETRY is_empty
+        then
+          case "${_DISPLAY_PROG}" in
+          gxditview|xditview)
+            # add width of 800dpi for resolution of 100dpi to the args
+            list_append _DISPLAY_ARGS '-geometry' '800';
+            ;;
+          esac;
+        fi;
         ;;
       *)
-        warning "main_display(): \
-wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
-        md_groggy="$(tmp_cat | grog -Z)";
+        md_device='X75-12';
         ;;
-      esac;
-      _do_display;
+      esac
+    esac;
+    md_groggy="$(tmp_cat | grog -T${md_device} -Z)";
+    exit_test;
+    _do_display;
+    ;;
+  X)
+    case "${_OPT_DEVICE}" in
+    '')
+      md_groggy="$(tmp_cat | grog -X)";
+      exit_test;
+      ;;
+    X*|dvi|html|lbp|lj4|ps)
+      # these devices work with 
+      md_groggy="$(tmp_cat | grog -T"${_OPT_DEVICE}" -X)";
+      exit_test;
       ;;
     *)
-      error "main_display(): unknown mode \`${_DISPLAY_MODE}'";
+      warning "main_display(): \
+wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
+      md_groggy="$(tmp_cat | grog -Z)";
+      exit_test;
       ;;
+    esac;
+    _do_display;
+    ;;
+  *)
+    error "main_display(): unknown mode \`${_DISPLAY_MODE}'";
+    ;;
   esac;
   eval ${_UNSET} md_addopts;
   eval ${_UNSET} md_device;
@@ -5120,33 +5714,48 @@
 #
 # Perform the generation of the output and view the result.  If an
 # argument is given interpret it as a function name that is called in
-# the midst.
+# the midst (actually only for `pdf').
 #
 # Globals: $md_modefile, $md_groggy (from main_display())
 #
 _do_display()
 {
   func_check _do_display '>=' 0 "$@";
-  trap_clean;
   _do_opt_V;
-  obj md_modefile rm_file;
-  if cat "${_TMP_CAT}" | \
-     eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}"
+  if obj _DISPLAY_PROG is_empty
   then
-    :;
+    trap_unset;
+    {
+      trap_set;
+      eval "${md_groggy}" "${_ADDOPTS_GROFF}" "${_TMP_CAT}";
+    } &
   else
-    error "_do_display: error on groff call";
-  fi;
-  if is_not_empty "$1"
-  then
-    eval "$1";
+    obj md_modefile rm_file;
+    cat "${_TMP_CAT}" | \
+      eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}";
+    if is_not_empty "$1"
+    then
+      eval "$1";
+    fi;
+    obj _TMP_CAT rm_file_with_debug;
+    if obj _VIEWER_TERMINAL is_yes # for programs that run on tty
+    then
+      eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
+    else
+      case "${_DISPLAY_PROG}" in
+#      lynx\ *|less\ *|more\ *) # programs known to run on the terminal
+#        eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
+#        ;;
+      *)
+        trap_unset;
+        {
+          trap_set;
+          eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
+        } &
+        ;;
+      esac;
+    fi;
   fi;
-  obj _TMP_CAT rm_file_with_debug;
-  {
-    trap clean_up 0 2>${_NULL_DEV} || :;
-    eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
-    clean_up;
-  } &
   eval "${return_ok}";
 } # _do_display() of main_display()
 
@@ -5167,13 +5776,16 @@
   if obj _OPT_V is_yes
   then
     _OPT_V='no';
-    echo "Output file:    ${md_modefile}";
-    echo "Display mode:   ${_DISPLAY_MODE}";
-    echo "Display prog:   ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
-    echo "Parameters:     ${_ALL_PARAMS}";
-    echo "Output of grog: ${md_groggy} $(eval echo1 "'${_ADDOPTS_GROFF}'")";
+    echo1 "Parameters:     ${_ALL_PARAMS}";
+    echo1 "Display mode:   ${_DISPLAY_MODE}";
+    echo1 "Output file:    ${md_modefile}";
+    echo1 "Display prog:   ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
+    a="$(eval echo1 "'${_ADDOPTS_GROFF}'")";
+    exit_test;
+    echo1 "Output of grog: ${md_groggy} $a";
     _doV_res="$(eval "${md_groggy}" "${_ADDOPTS_GROFF}")";
-    echo "groff -V:       ${_doV_res}"
+    exit_test;
+    echo1 "groff -V:       ${_doV_res}"
     leave;
   fi;
   eval "${return_ok}";
@@ -5236,7 +5848,6 @@
   eval "${return_ok}";
 }
 
-landmark '20: end of function definitions';
 
 ########################################################################
 




reply via email to

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