diff -ruN groff-1.18.1/NEWS groff-1.18.1.1/NEWS --- groff-1.18.1/NEWS Tue Oct 8 09:12:30 2002 +++ groff-1.18.1.1/NEWS Sat Jun 19 13:05:46 2004 @@ -1,6 +1,16 @@ This file describes recent user-visible changes in groff. Bug fixes are not described. There are more details in the man and info pages. +VERSION 1.18.1.1 +================ + +This is the same as 1.18.1 but with an updated version of the `groffer' +script (which was broken in 1.18.1). Reason for providing 1.18.1.1 is that +many distributions don't include newer versions of groff due to changes in +the glyph name handling which conflicts with some extensions to support +Japanese. + + VERSION 1.18.1 ============== diff -ruN groff-1.18.1/contrib/groffer/ChangeLog groff-1.18.1.1/contrib/groffer/ChangeLog --- groff-1.18.1/contrib/groffer/ChangeLog Mon Sep 30 12:41:21 2002 +++ groff-1.18.1.1/contrib/groffer/ChangeLog Tue Jun 15 03:45:11 2004 @@ -1,4 +1,389 @@ -2002-09-30 Bernd Warken +2004-06-15 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.11 + + * groffer.sh: + - To the search of the `--apropos-*' options, add man pages with a + subsection in their apropos output. + +2004-06-02 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.10 + + * groffer.sh: + - Remove automatic call of `ash' due to inconsistencies of + different ash versions. + - In the first run, add recognition of `--shell' lines in the + groffer configuration files. To configure an external shell in + a configuration file, a line starting with `--shell' is + necessary. + - list_from_cmdline(): Simplify the arguments. + - As $POSIXLY_CORRECT is internally set to `y' by some GNU + `/bin/sh' shells the following 2 fixes are necessary: + -- `sed': Empty patterns are not allowed with $POSIXLY_CORRECT + set; so move the address information before the `s' command to the + pattern after the command, and write `.*' to the address field. + -- list_from_cmdline(): Remove the strange $POSIXLY_CORRECT style + to finish the option processing after the first non-option + argument; use the flexible GNU mixing of options and file names + instead. + + * groffer.man: + - Remove any hints on `ash'. + - Add minus line behavior of `--shell' for configuration and add a + corresponding example. + - Update the information on $POSIXLY_CORRECT. + +2004-05-29 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.9 + + * groffer.sh: + Fix first run section to allow the starting shell to go on if + `ash' is not available. + + * groffer.man: + Remove unnecessary information on groffer version. + +2004-05-12 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.8 + + * groffer.sh: + Fix problems of `test' by adding subs to arguments. + + * groffer.man: + Write the file license as macros that are called in sections + AUTHOR and COPYING. + + * .cvsignore: + Restore this file. + +2004-04-30 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.7 + + * groffer.sh: + - obj(), obj_data(), obj_from_output(), obj_set(): New object + oriented functions to minimize complicated `eval' commands. + - list_*(): Corrections. + - usage(): Streamlining. + + * groffer.man, README_SH: + Corrections. + +2004-04-27 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.6 + + This version replaces the license of all files except ChangeLog of + the groffer source to the GNU General Public License (GPL) of the + version described in files COPYING and LICENSE in the groff top + source directory. + + * groffer.man: + Changement from the GNU Free Documentation License (FDL) to + the GNU General Public License (GPL). + + * README, README_SH, TODO: + Add license GNU General Public License (GPL). + + * Makefile.sub, groffer.sh: + Keep the GNU General Public License (GPL), but refer to the + COPYING and LICENSE files. + + * ChangeLog: Add a license in the style of Emacs ChangeLog file, + which is weaker than the GPL, but has its flavor. + +2004-04-24 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.5 + + This version is a rewrite of groffer in many parts, but it is kept + in the old single script style. + + Overview of new options: + --text, --mode text, --tty-viewer, + --X, --mode X, --X-viewer, --html, --mode html, --html-view, + --apropos-data, --apropos-devel, --apropos-progs + + New file: + /README_SH + + + ******* Extension of the `apropos' handling + + The output of man's `apropos' has grown immensely meanwhile, so it + has become inefficient. Now `groffer' provides new options to get + the a selected information from this output. + + * groffer.sh: + `--apropos-progs': new option for displaying only information + on programs (man page sections 1, 6, and 8) + `--apropos-data': new option for displaying only information + on documented data (man page sections 4, 5 and 7) + `--apropos-devel': new option for displaying only information + on development documentation (man page sections 2, 3 and 9) + `--apropos': still displays just the output of man's `apropos' + program. + - Specify all of these options as a single argument option; that + makes groffer's `--apropos' option slightly different because + the corresponding `man' option does not have arguments, but takes + all file arguments as apropos targets. So just ignore the `man' + options `-k' and `--apropos' in the parsing of $MANOPT. + - Exit after processing one `apropos' call. + + + ******* Quasi object oriented function arguments + + An object is the name of an environment variable. The value of + this variable contains the object's content. This allows to + specify function arguments and the calling syntax in a simpler way + by letting the first argument be a variable name, usable for input + or output. + + Such an object type is `list', the string value of a shell + variable arranged in space-separated single-quoted elements, such + as $GROFFER_OPT internally. + + * groffer.sh: + - Remove list_from_args(), list_element_from_arg() + list_from_lists(), list_length(), and list_prepend(). + They can be replaced by list_append(). + - All list*() functions are rearranged such that the first + argument is a list object, the name of a variable. + + + ******* Simplification of configuration files + + The new syntax of the groffer configuration files is + - all lines starting with a `-' character are interpreted as + command line options for all calls of groffer; they are collected + and prepended to the actual value of $GROFFER_OPT; optional + spaces at the beginning.of the line are omitted. + - all other lines are interpreted as a shell command and executed + in the current shell of the groffer call. + + Precedence: + - The command line and the external environment variables such as + $GROFFER_OPT of the groffer call have the highest precedence. + - This is overwritten by the configuration file in the user's home + directory. + - The system configuration file in /etc has the lowest + precedence. + + * groffer.sh: + The configuration files are now called after the determination of + the temporary files in main_init(). + + + ******* Script file name + + The file name of the script is needed for the several calls during + the search for the optimal shell. + + * groffer.sh: + - $_GROFFER_SH: replace $_this by $_GROFFER_SH and use $0 for + determining the file name of the script for the following calls, + instead of the cumbersome @BINDIR@ construction. + - Force the script to be called as an executable file, so $0 must + contain the program name. + + + ******* Improved temporary file names + + Just like groff, groffer mixes all file parameters into a single + output file. Its name is now constructed as a comma-separated + list built from the file name arguments without a leading comma. + So a leading comma can be used for the internal temporary file + names. + + * groffer.sh: + - $_OUTPUT_FILE_NAME: new global variable as basis for the output + file name; it is set in main_set_resources(). + - tmp_create(): use `,name' for temporary files different from + output file because the output file name does not start with a + comma. `$$' is not needed anymore. + - main_display(): simplification of $_modefile in _do_display() + and single display modes. + - Add extension `.html' to output file name in html mode. + - base_name(): correction for strange positions of `/'. + + + ******* Mode fixes + + * groffer.sh: + - Set the main default mode to `x' with groff's X Window viewer + `gxditview'. + - Allow 'x' and 'X' in `--mode' for the X Window mode; the same + for `--x' and `X', `--x-viewer' and `--X-viewer'. + - Make groff's `-X' equivalent to `mode X'. + - Fix `--auto', `--mode auto', and `--default-modes'. + - `html' mode: new mode equivalent to `www', add `konqueror' and + `lynx' as viewers. + - `pdf' mode: fix zoom options for pdf-viewer `xpdf' in + main_set_resources(); in main_display() fix the display structure. + - Set default X Window resolution to 75dpi. This is not optimal, + but with a higher value the options and resources for some viewers + must be optimized. + `--text' and `--mode text': new option for text output without a + pager. + - `--tty-viewer': new option equivalent to `--pager'. + - Correct the pagers for `tty' mode. + - Fix `groff' mode in main_set_resources() and main_display(). + - Harmonize `--mode arg' with the equivalent options `--arg'. + + + ******* Fixes for command line options + + * groffer.sh: + - list_from_cmdline(): fix the parsing of options with arguments. + - Rename $_OPT_TTY_DEVICE to $_OPT_TEXT_DEVICE. + - $_OPTS_X_*: new variables for the inhereted X Window variables. + - Improve the distribution of the command line options into + $_OPTS_GROFFER_*, $_OPTS_GROFF_*, $_OPTS_X_*, and $_OPTS_MAN_*. + - $_OPTS_MANOPT_*: new variables for the parsing of $MANOPT. + - Correct $_OPTS_CMDLINE_*. + - Remove some unused $_OPTS_*. + - `--iconic': new option from `-iconic' of the X Window toolkit. + - Correct `--rv' to an option without argument. + - Minor fixes of other X Window toolkit options. + + + ******* Other fixes + + * groffer.sh: + - is_prog(): allow 0 arguments. + - is_not_writable(): new function. + - is_*(): fix trailing return codes. + - Replace most `test' calls by is_*() functions. + - man_setup(): due to bugs in `manpath', prefer + manpath_set_from_path() for the determination of the man page path. + - man_search_section(): correction of some `for' loops. + - Remove export of external non-groffer variables. + + + ******* Documentation + + * groffer.man: + - Reorder the option details according to the option origin as + groffer, groff, X, and man options. + - Add the programming changes information mentioned above. + - Support man pages with a dot in their name + + * README_SH: new file + Move large parts of the documentation in `groffer.sh' into this + file. + + * groffer.sh: usage(): + - Change the output for `--help' to standard output. + - Restructure the information for this help output. + + + ******* Removement of the author's email address + + Because of the extreme spam attacks, the author removed all + occurencies of his email address in every file of the groffer + source. + +2003-01-22 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.4 + + * groffer.sh: corrections for some restrictive shells + - Possible exit codes in actual `ash' are between 0 and 63. To + handle even deeper restrictions, use 7 as maximal code instead + of 255 as replacement for error -1. + - Remove variables $_BAD2 and $_BAD3. + - Replace `trap' argument `EXIT' by 0 and write new fuctions + `trap_clean' and `trap_set' to handle the restrictions of `trap' + for some shells. + - Correct wrong $MANPATH to $_MAN_PATH in function + `man_do_filespec'. + - Test existence of directory before deleting it in the + `clean_up' definitions. + - Correct help output in `usage' (called by `--help'). + + * TODO: + Remove mention of `shoop' and `apropos'. + +2002-10-21 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.3 + + * groffer.sh: new temporary subdirectory + - Generate temporary subdirectory for storing temporary files + with better names in future groffer versions (name: + "groffer$$" in usual temporary directory). + - Use `umask 000' for temporary files to allow cleaning up + for everyone after a system break. + - Change both clean_up() functions (for normal shell and + for main_display() subshell) to handle the new subdirectory. + - clean_up_secondary() and $_TMP_PREFIX are unnecessary now, so + they were removed. + + * Makefile.sub: `sed' commands for "groffer:" + - Remove "@g@" entry (not used in "groffer.sh"). + - Add global replace for "@BINDIR@" and "@VERSION@" for future + usage. + + * TODO: think about... + - writing part of groffer in C/C++. + - handling several files with different macro packages. + +2002-10-17 Bernd Warken + ________________________________________________________________ + * fixes of groffer 0.9.2 + + * groffer.sh: + Terminate main_parse_MANOPT() if $MANOPT is empty or consists + of space characters only. + + * groffer.man: some fixes in "GROFFER OPTIONS" + - New macro ".Header_CB" for CB font in .TP headers; used for + definition of variables in option --mode. + - Fix some option references to refer to long options. + + * README: + New file for general information on the groffer source; it is + not installed. + +2002-10-14 Bernd Warken + + * Makefile.sub: + add replacement "@BINDIR@" to "$(bindir)" for "groffer:" + + * groffer.sh: + Define $_this as "@BINDIR@/${_PROGRAM_NAME}" to save the right + installation position of groffer for the special shell calling. + + * groffer.man: + Remove double definition of filespec parameters. + +2002-10-13 Bernd Warken + ________________________________________________________________ + * release of groffer 0.9.2 + + * groffer.sh: fixes + - Fix some 'sed' functions: two in func_stack_dump(), one in + base_name(), add 'sed' command in list_from_cmdline(). + - Finish main_parse_MANOPT() if $MANOPT is empty. + - Sort $_OPTS_GROFF_SHORT_NA like groff short options (but + unchanged). + - Fix some comments. + + * groffer.man: make it more readable (but no additions) + - A shortened section "SYNOPSIS" is followed by a simplified + section "DESCRIPTION". + - The options from "SYNOPSIS" go to new section "OPTION + OVERVIEW" with all groffer options in a single subsection. + - The details of all groffer options are described in section + "GROFFER OPTIONS". + - New macro for file names ".File_name". + - "Option Parsing" is moved to section "COMPATIBILITY". + - Fix some "EXAMPLES". + +2002-09-30 Bernd Warken ________________________________________________________________ * release of groffer 0.9.1 @@ -6,7 +391,7 @@ - Remove request for different shells. - Remove the 'sed' complaints. -2002-07-15 Bernd Warken +2002-07-15 Bernd Warken * groffer.sh: replace `sed' interface by direct `sed' - This improves the performance of the shell programming parts @@ -30,7 +415,7 @@ groffer was called from the command line, or with the shell name in the first line of the script, actually `/bin/sh'. -2002-07-12 Bernd Warken +2002-07-12 Bernd Warken ________________________________________________________________ * fixes for groffer 0.9.0 @@ -50,7 +435,7 @@ * TODO: fix entry `shoop' (not 'shopt'). -2002-06-28 Bernd Warken +2002-06-28 Bernd Warken ________________________________________________________________ * release of groffer 0.9.0 @@ -81,7 +466,7 @@ - Internally, map mode `auto' to '' to facilitate tests. - Fix auto mode sequence to: `ps,x,tty' as was intended. -2002-06-25 Bernd Warken +2002-06-25 Bernd Warken * groffer.sh: Fix `source' mode. @@ -89,7 +474,7 @@ * groffer.man: Fix some indentations. -2002-06-23 Bernd Warken +2002-06-23 Bernd Warken ________________________________________________________________ * release of groffer 0.8 @@ -208,7 +593,7 @@ Increase to 4m (we use `sh#' as the prompt). -2002-05-31 Bernd Warken +2002-05-31 Bernd Warken ________________________________________________________________ * release of groffer 0.7 @@ -244,7 +629,7 @@ - fix TP_header. -2002-05-28 Bernd Warken +2002-05-28 Bernd Warken ________________________________________________________________ * release of groffer 0.6 @@ -338,7 +723,7 @@ - The filespec parsers gets a function of its own do_manpage(). -2002-01-08 Bernd Warken +2002-01-08 Bernd Warken * groffer 0.5 (beta) released @@ -365,7 +750,7 @@ - Implement option `--dpi' for setting the resolution for the X viewer, which had already been documented in earlier versions. -2002-01-07 Bernd Warken +2002-01-07 Bernd Warken * groffer 0.4 (beta) released (as groff `contrib') @@ -404,7 +789,7 @@ * groffer.man (OptDef): Add missing backslashes. Update copyright. -2001-12-15 Bernd Warken +2001-12-15 Bernd Warken * groffer 0.3 (alpha) released (still stand-alone package). @@ -423,12 +808,12 @@ * Recognize the following filespecs as man-page parameters: man:name(section), man:name, name.section, name. -2001-12-03 Bernd Warken +2001-12-03 Bernd Warken * Stand-alone package for groffer 0.2 (alpha) created Files: groffer, groffer.man, Makefile, TODO, ChangeLog -2001-12-02 Bernd Warken +2001-12-02 Bernd Warken * groffer 0.2 (alpha) program released. @@ -448,7 +833,7 @@ * Code restructured and comments added. -2001-11-28 Bernd Warken +2001-11-28 Bernd Warken ***** groffview 0.1 (experimental) and groffview.man released (predecessor of groffer, shell script) @@ -458,3 +843,15 @@ * Search for man-pages based on $MANPATH * development of `groffview' shell script started + +2001-11-28 Bernd Warken + ________________________________________________________________ + License + + Copyright (C) 2001,2002,2003,2004 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. + + This file is part of groffer, which is part of the groff project. diff -ruN groff-1.18.1/contrib/groffer/Makefile.sub groff-1.18.1.1/contrib/groffer/Makefile.sub --- groff-1.18.1/contrib/groffer/Makefile.sub Mon Jun 24 20:08:06 2002 +++ groff-1.18.1.1/contrib/groffer/Makefile.sub Wed Apr 28 01:40:39 2004 @@ -2,7 +2,7 @@ # File position: /contrib/groffer/Makefile.sub -# Last update: 23 June 2002 +# Last update: 21 October 2002 # Copyright (C) 2001,2002 Free Software Foundation, Inc. # Written by Werner Lemberg @@ -20,9 +20,9 @@ # License for more details. # You should have received a copy of the GNU General Public License -# along with groff; see the file COPYING. If not, write to the -# Free Software Foundation, 59 Temple Place - Suite 330, Boston, -# MA 02111-1307, USA. +# along with groff; see the files COPYING and LICENSE in the top +# directory of the groff source. If not, write to the Free Software +# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ######################################################################## @@ -33,8 +33,8 @@ groffer: groffer.sh rm -f $@; \ - sed -e "s|@g@|$(g)|g" \ - -e "s|@VERSION@|$(version)$(revision)|" \ + sed -e "s|@BINDIR@|$(bindir)|g" \ + -e "s|@VERSION@|$(version)$(revision)|g" \ -e $(SH_SCRIPT_SED_CMD) $(srcdir)/groffer.sh >$@; \ chmod +x $@ diff -ruN groff-1.18.1/contrib/groffer/README groff-1.18.1.1/contrib/groffer/README --- groff-1.18.1/contrib/groffer/README Thu Jan 1 01:00:00 1970 +++ groff-1.18.1.1/contrib/groffer/README Wed Jun 2 20:55:04 2004 @@ -0,0 +1,44 @@ +The `groffer' program is the easiest way to read documents written in +some `roff' language, such as the `man pages', the manual pages in +many operating systems. + +All input is sent to `grog' and then to `groff' such that no special +`groff' arguments must be determined, but all `groff' options can be +specified. + +`groffer' also has many built-in `man' functionalities to find and +read the manual pages on UNIX and similar operating systems. It +accepts the information from an installed `man' program, but tries to +find a man path by itself. + +So far, `groffer' is a shell script. It should run on any POSIX or +Bourne style shell. + +For reporting bugs of `groffer', groff's free mailing list + can be used. For a general discussion, the +mailing list is more useful; see the `README' file in +the top directory of the `groff' source package for more details on +these mailing lists. + + +####### License + +Copyright (C) 2003,2004 Free Software Foundation, Inc. +Written by Bernd Warken + +This file is part of groffer, which is part of groff. + +groff is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +groff is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +License for more details. + +You should have received a copy of the GNU General Public License +along with groff; see the files COPYING and LICENSE in the top +directory of the groff source. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. diff -ruN groff-1.18.1/contrib/groffer/README_SH groff-1.18.1.1/contrib/groffer/README_SH --- groff-1.18.1/contrib/groffer/README_SH Thu Jan 1 01:00:00 1970 +++ groff-1.18.1.1/contrib/groffer/README_SH Wed Jun 2 20:41:43 2004 @@ -0,0 +1,221 @@ +Description of groffer.sh, the shell version of groffer + +Display groff files and man pages on X or tty, even when compressed. + + +Usage + +Input comes from either standard input or command line parameters that +represent names of exisiting roff files or standardized specifications +for searching man pages. All of these can be compressed in a format +that is decompressible by `gzip', including `.gz', `bz2', and `.Z'. + +The following displaying modes are available: +- Display formatted input with the X roff viewer `gxditview', +- with a Prostcript viewer, +- with a dvi viewer, +- with a web browser. +- Display formatted input in plain text mode. +- Run a pager on the formatted input in a text terminal (tty). +- Generate output for some groff device on stdout without a viewer. +- Output only the source code without any groff processing. +- Generate the troff intermediate output on standard output + without groff postprocessing. +By default, the program tries to display with `gxditview' as graphical +device, `tty' mode with a pager is tried as text display. + + +Several File Arguments + +So far, `groffer' bundles all filespec parameters into a single output +file in the same way as `groff'. The disadvantage of this is that all +file name arguments must have the same groff language. + +To change this, the option parsing must be revised for large parts. +It seems that this would create incompatibilities, so the actual +option strategy is kept. + + +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(). + + +Shell Compatibility + +This shell script is compatible to the both the GNU and the POSIX +shell and utilities. Care was taken to restrict the programming +technics used here in order to achieve POSIX compatibility as far back +as POSIX P1003.2 Draft 11.2 of September 1991. + +The only non-builtin used here is POSIX `sed'. This script was tested +under `bash', `ash', and `ksh'. The speed under `ash' is more than +double when compared to the larger shells. The new version of `ash' +taken from `dash' produces strange errors, so the automatic call of +`ash' was removed. + +This script provides its own option parser. It is compatible to the +usual GNU style command line (option clusters, long options, mixing of +options and non-option file names), except that it is not possible to +abbreviate 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. + + +Survey of Functions defined in groffer.sh + +The elements specified within paranthesis `(<>)' give hints to what +the arguments are meant to be; the argument names are irrelevant. +<>? 0 or 1 +<>* arbitrarily many such arguments, incl. none +<>+ one or more such arguments +<> exactly 1 + +A function that starts with an underscore `_' is an internal function +for some function. The internal functions are defined just after +their corresponding function; they are not mentioned in the following. + +abort (text>*) +base_name (path) +catz () +clean_up () +diag (text>*) +dirname_append ( []) +dirname_chop () +do_filearg () +do_nothing () +echo2 (*) +echo2n (*) +error (*) +get_first_essential (*) +is_dir () +is_empty () +is_equal ( ) +is_file () +is_non_empty_file () +is_not_dir () +is_not_empty () +is_not_equal ( ) +is_not_file () +is_not_prog () +is_not_writable () +is_not_yes () +is_prog () +is_yes () +leave () +landmark () +list_append ( ...) +list_from_cmdline ( [...]) +list_from_split ( ) +list_get () +list_has ( ) +list_has_not ( ) +main_*(), see after the functions +man_do_filespec () +man_setup () +man_register_file ( [ [
]]) +man_search_section (
) +man_set() +manpath_add_lang( ) +manpath_add_system() +manpath_from_path () +normalize_args ( *) +path_chop () +path_clean () +path_contains ( ) +path_not_contains ( ) +path_split () +register_file () +register_title () +res ( ...) +reset () +save_stdin () +string_contains ( ) +string_not_contains ( ) +tmp_cat () +tmp_create (?) +to_tmp () +trap_clean () +trap_set () +usage () +version () +warning () +whatis () +where () + + +External non-groffer Environment Variables + +If these variables are exported in the script the `ash' shell coughs +when calling `groff' in `main_display()'. + +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 (: 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_*(). + + +####### License + +Copyright (C) 2003,2004 Free Software Foundation, Inc. +Written by Bernd Warken + +This file is part of groffer, which is part of groff. + +groff is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +groff is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +License for more details. + +You should have received a copy of the GNU General Public License +along with groff; see the files COPYING and LICENSE in the top +directory of the groff source. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. diff -ruN groff-1.18.1/contrib/groffer/TODO groff-1.18.1.1/contrib/groffer/TODO --- groff-1.18.1/contrib/groffer/TODO Mon Sep 30 11:53:15 2002 +++ groff-1.18.1.1/contrib/groffer/TODO Wed Jun 2 20:48:42 2004 @@ -1,53 +1,59 @@ -# TODO file for `groffer' +TODO file for `groffer' -# File position: /contrib/groffer/TODO +File position: /contrib/groffer/TODO -# Last update: 30 Sep 2002 -# Copyright (C) 2001,2002 Free Software Foundation, Inc. -# Written by Bernd Warken +####### TODO -# This file is part of groff. - -# groff is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# groff is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -# License for more details. - -# You should have received a copy of the GNU General Public License -# along with groff; see the file COPYING. If not, write to the -# Free Software Foundation, 59 Temple Place - Suite 330, Boston, -# MA 02111-1307, USA. - -######################################################################## - -TODO +Revision: +- Revise the `--all' feature to better reflect GNU man. +- The debug function stack is buggy (no effect on normal operation). +- Check main_parse_MANOPT(), not too important. +- Add long option shortcuts. +- The actual replacement `dash' of the POSIX `ash' shell produces + strange errors with the groffer script, while the former `ash' + worked successfully. Are these errors just bugs of `dash'? 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 (not trivial). +- To increase the running speed write part of the groffer shell script + in C/C++. +- Split the groffer.sh shell script into several files for better tests + of the shell compatibility. -Features: -- Consider using the `shoop' package (OOP for `sh'). +Features of external programs: - Revise option handling of `grog'. - `gxditview' needs a complete shower. -Revision: -- Should there be a native implementation for `--apropos'? -- Revise the `--all' feature to better reflect GNU man. -- The debug function stack is buggy (no effect on normal operation). - Documentation: -- Write a README file. - Improve the documentation of the search algorithm for man pages in both the groffer script and the man page `groffer.man'. - In `groff.man', add more documentation for parts that were taken over from GNU `man'. - The documentation in the headers for some function definitions in `groffer.sh' needs to be updated. + + +####### License + +Copyright (C) 2003,2004 Free Software Foundation, Inc. +Written by Bernd Warken + +This file is part of groffer, which is part of groff. + +groff is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +groff is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +License for more details. + +You should have received a copy of the GNU General Public License +along with groff; see the files COPYING and LICENSE in the top +directory of the groff source. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. diff -ruN groff-1.18.1/contrib/groffer/groffer.man groff-1.18.1.1/contrib/groffer/groffer.man --- groff-1.18.1/contrib/groffer/groffer.man Mon Sep 30 12:15:05 2002 +++ groff-1.18.1.1/contrib/groffer/groffer.man Wed Jun 2 17:11:09 2004 @@ -15,22 +15,32 @@ Source file position: /contrib/groffer/groffer.man Installed position: $prefix/share/man/man1/groffer.1 -Version : groffer 0.9.1 -Last update : 30 Sep 2002 +Last update : 12 May 2004 -This file is part of groff, the GNU roff type-setting system. - -Copyright (C) 2001, 2002 Free Software Foundation, Inc. -Written by Bernd Warken - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.1 or -any later version published by the Free Software Foundation; with the -Invariant Sections being this .ig-section and AUTHORS, with no -Front-Cover Texts, and with no Back-Cover Texts. - -A copy of the Free Documentation License is included as a file called -FDL in the main directory of the groff source package. +Source file position: /contrib/groffer/groffer.man +.. +.de author +This file was written by Bernd Warken. +.. +.de copyleft +Copyright (C) 2001,2002,2004 Free Software Foundation, Inc. +. +.P +This file is part of groff, a free software project. +. +You can redistribute it and/or modify it under the terms of the GNU +General Public License as published by the Free Software Foundation; +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 groff, see the files COPYING and LICENSE in the top +directory of the groff source package. +. +Or read the man page +.BR gpl (1). +You can also write to the Free Software Foundation, 59 Temple Place - +Suite 330, Boston, MA 02111-1307, USA. .. . .\" -------------------------------------------------------------------- @@ -59,7 +69,7 @@ .ds @i- "\f[CI]-\f[]\"" .ds @i-- "\f[CI]--\f[]\"" . -.ds Ellipsis .\|.\|.\" +.ds Ellipsis ".\|.\|.\"" . .\" -------------------------------------------------------------------- .\" setup for the macro definitions below @@ -160,6 +170,24 @@ . hy .. .c -------------------------------------------------------------------- +.c .File_name () +.c +.c Display a file or directory name in CB font. +.c +.de File_name +. Header_CB \\$@ +.. +.c -------------------------------------------------------------------- +.c .Header_CB () +.c +.c Display a line in CB font, for example after .TP +.c +.de Header_CB +. nh +. Text \f[CB]\\$1\f[]\\$2 +. hy +.. +.c -------------------------------------------------------------------- .c .Opt_- ([]) .c .c Print `-' (minus sign); optional punctuation. @@ -259,7 +287,7 @@ .c .c Arguments: .c
: prefix, resulted is preceded by this.
-.c   : separator between minux/opt pairs.
+.c   : separator between minus/opt pairs.
 .c   : postfix, is appended to the result.
 .c   : either `-' or `--' (font CB).
 .c   : a name for an option, empty allowed (font CB).
@@ -290,22 +318,23 @@
 .    if (\\n[@count] > 0) \
 .      as @res \f[CR]\\*[@sep]\"
 .    nr @count +1
-.    as @res \f[CB]\\$1\\$2\:\"           combine minus with option name
+.    as @res \f[CB]\\$1\\$2\:\"         combine minus with option name
 .    shift 2
 .  \}
 .  if (\\n[.$] >= 3) \
 .    Error .\\0: wrong arguments: \\$@
-.  c                                     all pairs are done
+.  c                                    all pairs are done
 .  ie (\\n[.$] == 0) \
 .    as @res \f[CR]\\*[@post]\"
 .  el \{\
-.    c                                   optional option argument
+.    c                                  optional option argument
 .    if !'\\$1'' \
 .      as @res \f[CR] \,\f[I]\\$1\"
 .    shift
-.    as @res \\f[CR]\\*[@post]\"         postfix
+.    c                                  postfix
+.    as @res \\f[CR]\\*[@post]\"
 .    if (\\n[.$] >= 1) \{\
-.      c                                 add punctuation
+.      c                                add punctuation
 .      as @res \f[\\n[@font]]\\$1\"
 .    \}
 .  \}
@@ -381,6 +410,14 @@
 .  Opt_alt -- "\\$1" "" "\\$2"
 ..
 .c --------------------------------------------------------------------
+.c .Opt_long_arg  ([  []])
+.c
+.c Print `--name=arg' somewhere in the text; optional punctuation.
+.c
+.de Opt_long_arg
+.  Opt_alt -- "\\$1=\\$2" "" "\\$3"
+..
+.c --------------------------------------------------------------------
 .c .Opt_[long]  ([ []])
 .c
 .c Print `--name' somewhere in the text; optional punctuation.
@@ -611,14 +648,16 @@
 .
 .ad l
 .Synopsis groffer
-.RI [ viewing_options ]
-.RI [ man_options ]
-.RI [ groff_options ]
+.RI [ option... ]
 .Opt_[--]
 .RI [ "filespec" "\*[Ellipsis]]"
 ./Synopsis
 .
 .Synopsis groffer
+.Opt_alt -- apropos -- apropos-data -- apropos-devel -- apropos-progs name
+./Synopsis
+.
+.Synopsis groffer
 .Opt_alt - h -- help
 ./Synopsis
 .
@@ -627,1138 +666,1408 @@
 ./Synopsis
 .
 .
-.TP
-.I viewing_options
-These options determine and configure the display mode.
+.\" --------------------------------------------------------------------
+.SH DESCRIPTION
+.\" --------------------------------------------------------------------
 .
-They were synchronized with the options of both
-.BR groff (@MAN1EXT@)
-and GNU
-.BR man (1).
-As groff uses almost any letter in its option set, only long option
-names are available for most features.
+The
+.I groffer
+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 troff language.
+.
+The
+.I groffer
+program also includes many of the features for finding and displaying
+the UNIX manual pages
+.RI ( man\~pages ),
+such that it can be used as a replacement for a
+.BR man (1)
+program.
+.
+Moreover, compressed files that can be handled by
+.BR gzip (1)
+or
+.BR bzip2 (1)
+are decompressed on-the-fly.
+.
+.
+.P
+The normal usage is quite simple by supplying a file name or name of a
+man\~page without further options.
+.
+But the option handling has many possibilities for creating special
+behaviors.
+.
+This can be done in configuration files, with the shell environment
+variable
+.BR $GROFFER_OPT ,
+or on the command line.
+.
+.
+.P
+The output can be generated and viewed in several different ways
+available for
+.IR groff .
+.
+This includes the groff native X viewer
+.BR gxditview (@MAN1EXT@),
+each Postcript or dvi display program, a web browser by generating
+html in www-mode, or several text modes in text terminals.
+.
+.
+.P
+Most of the options that must be named when running
+.I groff
+directly are determined automatically for
+.IR groffer ,
+due to the internal usage of the
+.BR grog (@MAN1EXT@)
+program.
+.
+But all parts can also be controlled manually by arguments.
+.
+.
+.P
+Several file names can be specified on the command line arguments.
+.
+They are transformed into a single document in the normal way of
+.IR groff .
 .
-If none of these options is used groffer tries to find a suitable
-display mode automatically.
 .
+.\" --------------------------------------------------------------------
+.SH "OPTION OVERVIEW"
+.\" --------------------------------------------------------------------
 .
+.TP
+.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
+.
 .
+.TP
+.I groffer mode options
+.RS
 .P
-.Opt_[alt] - Q -- source
-.Opt_[alt] - T -- device device
-.Opt_[alt] -- auto-modes mode1,mode2,\*[Ellipsis]
-.Opt_[alt] -- debug
+.Opt_[alt] -- auto
 .Opt_[alt] -- default
+.Opt_[alt] -- default-modes mode1,mode2,\*[Ellipsis]
 .Opt_[alt] -- dvi
 .Opt_[alt] -- dvi-viewer prog
 .Opt_[alt] -- groff
-.Opt_[alt] -- location
+.Opt_[alt] -- html
+.Opt_[alt] -- html-viewer prog
+.Opt_[alt] -- man
 .Opt_[alt] -- mode display_mode
-.Opt_[alt] -- pager program
+.Opt_[alt] -- no-man
 .Opt_[alt] -- pdf
 .Opt_[alt] -- pdf-viewer prog
 .Opt_[alt] -- ps
 .Opt_[alt] -- ps-viewer prog
-.Opt_[alt] -- shell
+.Opt_[alt] -- text
 .Opt_[alt] -- tty
+.Opt_[alt] -- tty-viewer prog
 .Opt_[alt] -- www
 .Opt_[alt] -- www-viewer prog
-.Opt_[alt] -- x
-.Opt_[alt] -- x-viewer prog
-.
-.
-.P
-The following long options were adapted from the corresponding X
-Toolkit options with a single leading minus; see
-.BR X (1).
+.Opt_[alt] -- x -- X
+.Opt_[alt] -- x-viewer -- X-viewer prog
+.RE
 .
 .
+.TP
+.I development options
+.RS
 .P
-.Opt_[alt] -- bd
-.Opt_[alt] -- bg -- background
-.Opt_[alt] -- bw
-.Opt_[alt] -- display
-.Opt_[alt] -- fg -- foreground
-.Opt_[alt] -- ft -- font
-.Opt_[alt] -- geometry size_pos
-.Opt_[alt] -- resolution value
-.Opt_[alt] -- rv
-.Opt_[alt] -- title string
-.Opt_[alt] -- xrm X_resource
-.
+.Opt_[alt] -- debug
+.Opt_[alt] -- shell
 .RE
 .
 .
 .TP
-.I groff_options
-Any combination of (short) options from the
-.BR groff (@MAN1EXT@)
-program is accepted; the options that are not explicitly handled by
-groffer are transparently passed to groff.
-.
-Due to the automatism in groffer, none of these groff options should
-be necessary, except for advanced usage.
-.
-.
+.I options related to groff
 .RS
-.
 .P
-Because of the special outputting behavior of the groff options
-.Opt_short V,
-.Opt_short X,
-and
-.Opt_short Z,
-groffer was designed to be switched into
-.I groff
-mode by each of these options; in this mode, the groffer viewing
-features are disabled.
-.
+.Opt_[alt] - P -- postproc-arg opt_or_arg
+.Opt_[alt] - Q -- source
+.Opt_[alt] - T -- device device
+.Opt_[alt] - Z -- intermediate-output -- ditroff
 .P
-The other groff options do not switch the mode, but allow to customize
-the formatting process.
-.
-Useful groff formatting options include
-.Opt_short m
-(to add macro files that cannot be recognized by grog), and
-.Opt_short T
-(to specify an alternative device for the modes
-.I tty
-and
-.IR x ).
-.
+All further
+.I groff
+short options are accepted.
 .RE
 .
 .
 .TP
-.I man_options
-These options regulate whether and how man pages are searched.
-.
-They are compatible with the long options of the
-.I GNU man
-program.
+.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 options from man
 .RS
-.
 .P
 .Opt_[alt] -- all
 .Opt_[alt] -- ascii
-.Opt_[alt] -- apropos
 .Opt_[alt] -- ditroff
 .Opt_[alt] -- extension suffix
 .Opt_[alt] -- locale language
 .Opt_[alt] -- local-file
-.Opt_[alt] -- man
 .Opt_[alt] -- manpath dir1:dir2:\*[Ellipsis]
-.Opt_[alt] -- no-location
-.Opt_[alt] -- no-man
+.Opt_[alt] -- pager program
 .Opt_[alt] -- sections sec1:sec2:\*[Ellipsis]
 .Opt_[alt] -- systems sys1,sys2,\*[Ellipsis]
 .Opt_[alt] -- troff-device device
 .Opt_[alt] -- whatis
-.
-.
 .P
-The GNU
+Further long options of GNU
 .I man
-long options that are not mentioned are recognized, but they are just
-ignored because of alternative implementations.
-.
-The full set of long and short options of the GNU man program can be
-passed via the environment variable
-.Env_var $MANOPT ;
-see
-.BR man (1)
-if your system has GNU man installed.
-.
+are accepted as well.
 .RE
 .
 .
 .TP
+.I filespec argument
+.RS
+.P
+No
 .I filespec
-is a sequence of file names or templates for searching
-man\~pages, see
-.BR man (1).
-A
-.I filespec
-can have one of the following forms.
-.
+parameters means standard input.
 .
-.RS
 .
 .TP 10m
-.I filename
-the path name of an existing file.
+.Opt_short ""
+stands for standard input (can occur several times).
 .
 .
 .TP
-.Opt_short
-stands for standard input (can occur several times).
+.I filename
+the path name of an existing file.
 .
 .
 .TP
 .BI man: name ( section )
+.TP+
+.IB name ( section )
 search the man\~page
 .I name
-in section\~\c
+in man\~section\~\c
 .IR section .
 .
 .
 .TP
-.BI man: name . section
-search the man\~page
+.BI man: name . s
+.TP+
+.IB name . s
+if
+.I s
+is a character in
+.BR [1-9on] ,
+search for a man\~page
 .I name
-in section\~\c
-.IR section .
+in man\~section
+.IR s .
 .
 .
 .TP
 .BI man: name
-search the man\~page
-.I name
-in the lowest available section.
+man\~page in the lowest man\~section that has
+.IR name .
 .
 .
 .TP
-.IB name ( section )
-search the man\~page
+.I "s name"
+if
+.I s
+is a character in
+.BR [1-9on] ,
+search for a man\~page
 .I name
-in section\~\c
-.IR section .
+in man\~section
+.IR s .
 .
 .
 .TP
-.IB name . section
-search the man\~page
 .I name
-in section\~\c
-.IR section .
-.
-.
-.TP
-.I standard_section
-if this is `1', \*[Ellipsis], `9', `o', or `n' try to retrieve the
-next argument as a man\~page in this section.
-.
-.
-.TP
+if 
 .I name
-search for the man\~page
+is not an existing file search for the man\~page
 .I name
-in the lowest available section.
-.
-.
-.P
-No
-.I filespec
-parameters means standard input.
+in the lowest man\~section.
 .
 .RE
 .
 .
-.P
-For details on the options, see section
-.BR OPTIONS .
-.
-.
 .\" --------------------------------------------------------------------
-.SH DESCRIPTION
+.SH "OPTION DETAILS"
 .\" --------------------------------------------------------------------
 .
 The
 .I groffer
-program is part of
-.BR groff (@MAN7EXT@).
-It can be used to display arbitrary documents written in the
-.BR roff (@MAN7EXT@)
-formatting language in several different ways, in an X window viewer
-program or in a text terminal.
+program can usually be run with very few options.
 .
-The viewer programs can be chosen as the groff native viewer
-.BR gxditview (@MAN1EXT@),
-a Postcript or dvi display program, or a web browser.
+But for special purposes, it supports many options.
+.
+These can be classified in 5 option classes.
 .
 .
 .P
-A search facility for manual pages (
-.IR man\~pages )
-is provided.
+All short options of
+.I groffer
+are compatible with the short options of
+.BR groff (@MAN1EXT@).
 .
-Almost the whole functionality of the
-.I GNU man
-program was provided or suitably adapted.
+All long options of
+.I groffer
+are compatible with the long options of
+.BR man (1).
 .
-This makes the groffer program a valuable tool on systems with a poor
-.I man
-system.
 .
+.\" --------------------------------------------------------------------
+.SS "groffer breaking Options"
+.\" --------------------------------------------------------------------
 .
-.P
-The program always concatenates all input specified by the non-option
-parameters of the calling command line or standard input.
+As soon as one of these options is found on the command line it is
+executed, printed to standard output, and the running
+.I groffer
+is terminated thereafter.
 .
-Compressed standard input or files are decompressed on-the-fly.
+All other arguments are ignored.
 .
 .
-.P
-Normally, the input is run through the
-.BR groff (@MAN1EXT@)
-text processor before being displayed.
+.Opt_def -- apropos name
+Start the
+.BR apropos (1)
+command for searching within man page
+descriptions.
 .
-By using the option
-.Opt_short Q ,
-the roff source code is displayed without formatting.
+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.
 .
-.P
-The formatting process can be regulated by all options that are
-available groff.
 .
-By using the
-.Opt_short T
-option, groffer can be switched to behave exactly like groff without
-using its viewer facilities, but additionally with the search and
-decompression features.
+.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.
 .
 .
-.P
-All necessary options can be determined automatically.
+.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.
 .
-For example, the groffer program internally uses the
-.BR grog (@MAN1EXT@)
-program to determine from the unformatted document which preprocessors
-should be run and which macro files should be included.
 .
-But all parts of the program can be controlled manually by suitable
-options.
+.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.
 .
 .
-.\" --------------------------------------------------------------------
-.SH OPTIONS
-.\" --------------------------------------------------------------------
+.Opt_def - h -- help
+Print a helping information with a short explanation of option sto
+standard output.
 .
-The groffer program provides its own parser for command line options
-that is compatible to both POSIX
-.BR getopts (1)
-and GNU
-.BR getopt (1).
-The command line behaves as usually.
 .
-For completeness, the details are provided here.
+.Opt_def - v -- version
+Print version information to standard output.
 .
 .
 .\" --------------------------------------------------------------------
-.SS "Option Parsing"
+.SS "groffer Mode Options"
 .\" --------------------------------------------------------------------
 .
-The following types of options are supported, equally on all systems
-that are able to run the groffer program:
+The display mode and the viewer programs are determined by these
+options.
 .
+If none of these mode and viewer options is specified
+.I groffer
+tries to find a suitable display mode automatically.
 .
-.Topic
-single character options are always preceded by a single minus
-character, for example,
-.Opt_short c .
 .
+.Opt_def -- auto
+Equivalent to
+.Opt_long_arg mode auto .
 .
-.Topic
-the argument for a single character option is the next command line
-argument, for example,
-.Opt_alt - o\~ arg ,
-or can be appended to the option character within the same argument
-.Opt_alt - o arg .
 .
+.Opt_def -- default
+Reset all configuration from previously processed command line options
+to the default values.
 .
-.Topic
-clusters of such single character options without an argument,
-eventually terminated by a single character option with an argument;
-for example,
-.Opt_alt - abo arg
-is equivalent to
-.Opt_short a\~\c
-.Opt_short b\~\c
-.Opt_short o\~\c
-.I arg .
+This is useful to wipe out all former options of the configuration, in
+.Env_var $GROFFER_OPT ,
+and restart option processing using only the rest of the command line.
 .
 .
-.Topic
-Long options, that means option with names longer than one character
-are always prededed by a double minus; an option argument can either
-go to the next command line argument or be appended with an equal sign
-to the argument; for example,
-.Opt_alt -- long= arg
-is equivalent to
-.Opt_alt -- long\~ arg .
+.Opt_def -- default-modes mode1,mode2,\*[Ellipsis]
+Set the sequence of modes for
+.I auto mode
+to the comma separated list given in the argument.
 .
+See
+.Opt_long mode
+for details on modes.  Display in the default manner; actually, this
+means to try the modes
+.IR x ,
+.IR ps ,
+and
+.I tty
+in this sequence.
 .
-.Topic
-An argument of
-.Opt_--
-ends option parsing; all further command line arguments are
-interpreted as filespec arguments.
 .
 .
-.Topic
-By default, all command line arguments that are neither options nor
-option arguments are interpreted as filespec parameters and stored
-until option parsing has finished.
+.Opt_def -- dvi
+Equivalent to
+.Opt_long_arg mode dvi .
 .
-For example, the command line
-.Shell_cmd "groffer file1 -a -o arg file 2"
-is, by default, equivalent to
-.Shell_cmd "groffer -a -o arg -- file1 file 2"
 .
+.Opt_def -- dvi-viewer prog
+Set the viewer program for dvi mode.
 .
-.Topic
-This behavior can be changed by setting the environment variable
-.Env_var $POSIXLY_CORRECT
-to a non-empty value; in this case, option processing is stopped as
-soon as the first non-option argument is found.
+This can be a file name or a program to be searched in
+.Env_var $PATH .
 .
-For example, in posixly correct mode, the command line
-.Shell_cmd "groffer file1 -a -o arg file 2"
-is equivalent to
-.Shell_cmd "groffer -- file1 -a -o arg file 2"
-As this leads to unwanted behavior in most cases, most people do not
-want to set
-.Env_var $POSIXLY_CORRECT .
+Known dvi viewers inlude
+.BR xdvi (1)
+and
+.BR dvilx (1)
 .
+In each case, arguments can be provided additionally.
 .
-.\" --------------------------------------------------------------------
-.SS "Compatibility with Options from other Programs"
-.\" --------------------------------------------------------------------
 .
-All short options of
+.Opt_def -- groff
+Equivalent to
+.Opt_long_arg mode groff .
+.
+.
+.Opt_def -- html
+Equivalent to
+.Opt_long_arg mode html .
+.
+.
+.Opt_def -- html-viewer
+Equivalent to
+.Opt_long www-viewer .
+.
+.
+.Opt_def -- mode value
+.
+Set the display mode.
+.
+The following mode values are recognized:
+.
+.RS
+.
+.TP
+.Header_CB auto
+Select the automatic determination of the display mode.
+.
+The sequence of modes that are tried can be set with the
+.Opt_long default-modes
+option.
+.
+Useful for restoring the default mode when a different mode was
+specified before.
+.
+.
+.TP
+.Header_CB dvi
+Display formatted input in a
+.I dvi
+viewer program.
+.
+By default, the formatted input is displayed with the
+.BR xdvi (1)
+program.
+.Opt_long dvi .
+.
+.
+.TP
+.Header_CB groff
+After the file determination, switch
 .I groffer
-are compatible with the short options of
-.BR groff (@MAN1EXT@).
+to process the input like
+.BR groff (@MAN1EXT@)
+would do .
 .
-Some of the
-.I groff
-options were given a special meaning within
-.IR groffer .
+This disables the
+.I groffer
+viewing features.
 .
-All other
+.
+.TP
+.Header_CB html
+Translate the input into html format and display the result in a web
+browser program.
+.
+By default, the existence of a sequence of standard web browsers is
+tested, starting with
+.BR konqueror (1)
+and
+.BR mozilla (1).
+The text html viewer is
+.BR lynx (1).
+.
+.
+.TP
+.Header_CB pdf
+Display formatted input in a
+.I PDF
+(Portable Document Format) viewer
+program.
+.
+By default, the input is formatted by groff using the Postscript
+device, then it is transformed into the PDF file format using
+.BR gs (1),
+and finally displayed either with the
+.BR xpdf (1)
+or the
+.BR acroread (1)
+program.
+.
+PDF has a big advantage because the text is displayed graphically and
+is searchable as well.
+.
+But as the transformation takes a considerable amount of time, this
+mode is not suitable as a default device for the auto mode.
+.
+.
+.TP
+.Header_CB ps
+Display formatted input in a Postscript viewer program.
+.
+By default, the formatted input is displayed with the
+.BR ghostview (@MAN1EXT@)
+program.
+.
+.
+.TP
+.Header_CB text
+Format in a
 .I groff
-options are supported by
-.IR groffer ,
-but they are just transparently transferred to
+text mode and write the result to standard output without a pager or
+viewer program.
+.
+The text device,
+.I latin1
+by default, can be chosen with option
+.Opt_short T .
+.
+.
+.TP
+.Header_CB tty
+Format in a
 .I groff
-without any intervention.
+text mode and write the result to standard output using a text pager
+program, even when in X Window.
 .
-Therefore these transparent options are not documented here, but in
-.BR groff (@MAN1EXT@).
+.
+.TP
+.Header_CB www
+Equivalent to
+.Opt_long www .
+.
+.
+.TP
+.Header_CB X
+Display formatted input in a native roff viewer.
+.
+By default, the formatted input is displayed with the
+.BR gxditview (@MAN1EXT@)
+program, being distributed together with groff, or with
+.BR xditview (1),
+which is distributed as a standard X tool.
+.
+.
+.TP
+.Header_CB x
+Equivalent to
+.Opt_long_arg mode X .
 .
 .
 .P
-All long options of
+The following modes do not use the
 .I groffer
-are compatible with the long options of
-.BR man (1).
+viewing features.
 .
-Most of the
-.I man
-long options were implemented as native options into
+They are only interesting for advanced applications.
+.
+.
+.TP
+.Header_CB groff
+Generate device output with plain
+.I groff
+without using the special viewing features of
 .IR groffer .
+If no device was specified by option
+.Opt_short T
+the
+.I groff
+default
+.B ps
+is assumed.
 .
-These options are documented in the following; the other
-.I man
-options are recognized, but ignored.
 .
+.TP
+.Header_CB source
+Display the source code of the input without formatting; equivalent to
+.Opt_short Q .
 .
-.\" --------------------------------------------------------------------
-.SS "Native groffer Options"
-.\" --------------------------------------------------------------------
 .
-.Opt_def - h
-Print usage message to standard error and exit.
+.RE
 .
 .
-.Opt_def - Q
-Output the roff source code of the input files unprocessed.
+.Opt_def -- pdf
+Equivalent to
+.Opt_long_arg mode pdf .
 .
-This is the equivalent
-.Opt_long mode\~source .
 .
+.Opt_def -- pdf-viewer prog
+Set the viewer program for
+.I pdf
+mode.
 .
-.Opt_def - T devname
-Switch to
-.Opt_long mode\~device ,
+This can be a file name or a program to be searched in
+.Env_var $PATH .
 .
-thus disabling the
-.I groffer
-viewing.
+In each case, arguments can be provided additionally.
 .
-Instead, the input is formatted and postprocessed using plain
-.I groff
-with
-.I devname
-as the output device.
 .
-The allowed device names are listed in
-.BR groff (@MAN1EXT@).
+.Opt_def -- ps
+Equivalent to
+.Opt_long_arg mode ps .
 .
-Note that this forces all device names that begin with the letter
-.I X
-to be displayed with
-.BR gxditview (@MAN1EXT@);
-all other device names generate output for the specified device; this
-is printed onto standard output without a pager.
 .
+.Opt_def -- ps-viewer prog
+Set the viewer program for
+.I ps
+mode.
 .
-.Opt_def - v
-Print version information onto standard error.
+This can be a file name or a program to be searched in
+.Env_var $PATH .
 .
+Common Postscript viewers inlude
+.BR gv (1),
+.BR ghostview (1),
+and
+.BR gs (1),
 .
-.Opt_def - V
-Switch into
-.I groff
-mode and format the input with groff option
-.Opt_short V ;
-this produces the groff calling pipe without formatting the input.
+In each case, arguments can be provided additionally.
 .
-This an advanced option from
-.BR groff (@MAN1EXT@) ,
-only useful for debugging.
 .
+.Opt_def -- text
+Equivalent to
+.Opt_long_arg mode text .
 .
-.Opt_def - X
-Switch into
-.I groff
-mode and format the input with groff option
-.Opt_short X ;
-actually, this formats the input and displays it with
-.BR gxditview (@MAN1EXT@) .
 .
-This differs from groffer's mode
-.I x
-because groffer's viewer options are not used, but the viewer is
-configured like in groff with the groff option
-.Opt_short P .
-This option is inhereted from
-.BR groff (@MAN1EXT@) .
+.Opt_def -- tty
+Equivalent to
+.Opt_long_arg mode tty .
 .
 .
-.Opt_def - Z
-Switch into
-.I groff
-mode and format the input with groff option
-.Opt_short Z ;
-this produces the groff intermediate output without postprocessing; see
-.BR groff_out (@MAN1EXT@) .
-This an advanced option from
-.BR groff (@MAN1EXT@) ,
-useful for debugging.
+.Opt_def -- tty-viewer
+Choose tty display mode, that means displaying in a text pager even
+when in X; eqivalent to
+.Opt_long_arg mode tty .
 .
 .
-.Opt_def -- all
-In searching man pages, retrieve all suitable ones instead of only one.
+.Opt_def -- www
+Equivalent to
+.Opt_long_arg mode www .
 .
 .
-.Opt_def -- apropos
-Instead of displaying, start the `apropos' command for searching
-within man page descriptions; only kept for compatibility with `man'.
+.Opt_def -- www-viewer prog
+Set the web browser program for viewing in
+.I www
+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
+.Env_var $PATH .
 .
-.Opt_def -- auto-modes mode1,mode2,\*[Ellipsis]
-Set the sequence of modes for default mode to the comma separated list
-given in the argument.
+In each case, arguments can be provided additionally.
 .
 .
-.Opt_def -- background color
-This is equivalent to
-.Opt_long bg .
+.Opt_def - X -- X -- x
+Equivalent to
+.Opt_long_arg mode X .
 .
 .
-.Opt_def -- bd pixels
-Specifies the color of the border surrounding the viewer
-window.
+.Opt_def -- X-viewer -- x-viewer prog
+Set the viewer program for
+.I x
+mode.
 .
-This is an adaption of the X Toolkit option
-.Opt_short bd .
+Suitable viewer programs are
+.BR gxditview (@MAN1EXT@)
+and
+.BR xditview (1).
 .
-The argument is an X color name, see
-.BR (1)
-for details.
+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 -- bg color
-Set the background color of the viewer window.
 .
-This is an adaption of the X Toolkit option
-.Opt_short bg .
+.TP
+.Opt_--
+Signals the end of option processing; all remaining arguments are
+interpreted as
+.I filespec
+parameters.
 .
-The argument is an X color name, see
-.BR (1)
-for details.
 .
+.P
+Besides these,
+.I groffer
+accepts all arguments that are valid for the
+.BR groff (@MAN1EXT@)
+program.
 .
-.Opt_def -- bw pixels
-Specifies the width in pixels of the border surrounding the viewer
-window (not available for all viewers).
+All non-groffer options are sent unmodified via
+.I grog
+to
+.IR groff .
 .
-This is an adaption of the X Toolkit option
-.Opt_short bw .
+Postprocessors, macro packages, compatibility with classical
+.IR troff ,
+and much more can be manually specified.
 .
 .
+.\" --------------------------------------------------------------------
+.SH "Options for Development"
+.\" --------------------------------------------------------------------
+.
 .Opt_def -- debug
-Print debugging information.
+Print debugging information for development only.
 .
 Actually, a function call stack is printed if an error occurs.
 .
 .
-.Opt_def -- default
-Reset all configuration from previously processed command line options
-to the default values.
-.
-This is useful to wipe out all effects of former options and restart
-option processing using only the rest of the command line.
+.Opt_def -- shell "shell_program"
+Specify the shell under which the groffer script should be run.
 .
+The script first tests whether this option is set (either by
+configuration, within
+.Env_var $GROFF_OPT
+or as a command line option); if so, the script is rerun under the
+shell program specified with the option argument.
 .
-.Opt_def -- device
-Eqivalent to
-.Opt_short T .
 .
+.Opt_def - Q -- source
+Output the roff source code of the input files without further
+processing.
 .
-.Opt_def -- display X-display
-Set the X display on which the viewer program shall be started, see
-.BR X (1)
-for the syntax of the argument.
+This is the equivalent
+.Opt_long_arg mode source .
 .
 .
-.Opt_def -- ditroff
-Eqivalent to
-.Opt_short Z .
-This is kept for compatibiliy with GNU
-.BR man (1).
+.P
+Other useful debugging options are the
+.I groff
+options
+.Opt_short V
+and
+.Opt_short Z
+and option
+.Opt_long_arg mode groff .
 .
 .
-.Opt_def -- dvi
-Choose dvi mode; the formatted input is displayed with the  
-by default, the formatted input is displayed with the
-.BR xdvi (1)
-program.
+.\" --------------------------------------------------------------------
+.SH "Options related to groff"
+.\" --------------------------------------------------------------------
 .
+All short options of
+.I groffer
+are compatible with the short options of
+.BR groff (@MAN1EXT@).
 .
-.Opt_def -- dvi-viewer prog
-Set the viewer program for dvi mode.
+The following of
+.I groff
+options have either an additional special meaning within
+.I groffer
+or make sense for normal usage.
 .
-This can be a file name or a program to be searched in
-.Env_var $PATH .
 .
-Known dvi viewers inlude
-.BR xdvi (1)
+.P
+Because of the special outputting behavior of the
+.I groff
+options
+.Opt_short V
 and
-.BR dvilx (1)
+.Opt_short Z
+.I groffer
+was designed to be switched into
+.I groff
+mode by these; the
+.I groffer
+viewing features are disabled there.
 .
-In each case, arguments can be provided additionally.
+The other
+.I groff
+options do not switch the mode, but allow to customize the formatting
+process.
 .
 .
-.Opt_def -- extension suffix
-Restrict man\~page search to file names that have
-.I suffix
-appended to their section element.
+.Opt_def - a
+This generates an ascii approximation of output in text modes.
 .
-For example, in the file name
-.I /usr/share/man/man3/terminfo.3ncurses.gz
-the man\~page extension is
-.IR ncurses .
+That could be important when the text pager has problems with control
+sequences.
 .
-Originates from GNU
-.IR man .
 .
+.Opt_def - m file
+Add
+.I file
+as a
+.I groff
+macro file.
 .
-.Opt_def -- foreground color
-This is equivalent to
-.Opt_short fg .
+This is useful in case it cannot be recognized automatically.
 .
 .
-.Opt_def -- fg color
-Set the foreground color of the viewer window.
+.Opt_def - P opt_or_arg
+Send the argument
+.I opt_or_arg
+as an option or option argument to the actual
+.I groff
+postprocessor.
 .
-This is an adaption of the X Toolkit option
-.Opt_short bg .
 .
-The argument is an X color name, see
-.BR (1)
-for details.
+.Opt_def - T -- device devname
 .
+This option determines
+.IR groff 's
+output device.
 .
-.Opt_def -- font font_name
-This is equivalent to
-.Opt_short ft .
+The most important devices are the text output devices for referring
+to the different character sets, such as
+.BR ascii ,
+.BR utf8 ,
+.BR latin1 ,
+and others.
 .
+Each of these arguments switches
+.I groffer
+into a text mode using this device, to
+.I mode tty
+if the actual mode is not a text mode.
 .
-.Opt_def -- ft font_name
-Set the font used by the viewer window.
+The following
+.I devname
+arguments are mapped to the corresponding
+.I groffer
+.Opt_long_arg mode \fIdevname\fR
+option:
+.BR dvi ,
+.BR html ,
+and
+.BR ps .
+All
+.B X*
+arguments are mapped to mode
+.BR X .
+Each other
+.I devname
+argument switches to
+.I mode groff
+using this device.
 .
-This is an adaption of the X Toolkit option
-.Opt_short ft .
 .
-The argument is an X font name, see
-.BR (1)
-for details.
+.Opt_def - V
+Switch into
+.I groff
+mode and show only the
+.I groff
+calling pipe without formatting the input.
 .
+This an advanced option from
+.BR groff (@MAN1EXT@) ,
+only useful for debugging.
 .
-.Opt_def -- geometry size_pos
-Set the geometry of the display window, that means its size and its
-starting position.
 .
-See
-.BR X (1)
-for details on the syntax of the argument.
+.Opt_def - X
+was made equivalent to
+.Opt_long_arg mode x ;
+this slightly enhances the facility of
+.IR groff 's
+option.
 .
-If the actual display mode is not X then this option is ignored.
 .
+.Opt_def - Z -- intermediate-output -- ditroff
+Switch into
+.I groff
+mode and format the input with
+.I groff
+intermediate output without postprocessing; see
+.BR groff_out (@MAN1EXT@).
+This is equivalent to option
+.Opt_long ditroff
+of
+.IR man ,
+which can be used as well.
 .
-.Opt_def -- groff
-Set
+.
+.P
+All other
 .I groff
-mode.
+options are supported by
+.IR groffer ,
+but they are just transparently transferred to
+.I groff
+without any intervention.
+.
+The options that are not explicitly handled by
+.I groffer
+are transparently passed to
+.IR groff .
 .
-Switch groffer to process the input like
+Therefore these transparent options are not documented here, but in
 .BR groff (@MAN1EXT@).
+Due to the automatism in
+.IR groffer ,
+none of these
+.I groff
+options should be needed, except for advanced usage.
 .
-This disables the groffer viewing features, all groffer viewing
-options are ignored.
 .
+.\" --------------------------------------------------------------------
+.SS "X Window toolkit Options"
+.\" --------------------------------------------------------------------
 .
-.Opt_def -- help
-Eqivalent to
-.Opt_short h .
+The following long options were adapted from the corresponding X
+Toolkit options.
 .
+.I groffer
+will pass them to the actual viewer program if it is an X Window
+program.
 .
-.Opt_def -- location
-Print the location of the retrieved files to standard error.
+Otherwise these options are ignored.
 .
 .
-.Opt_def -- locale language
+.P
+Unfortunately these options use the old style of a single minus for
+long options.
 .
-Set the language for man pages.
+For
+.I groffer
+that was changed to the standard with using a double minus for long
+options, for example,
+.I groffer
+uses the option
+.Opt_long font
+for the
+.I X
+option
+.Opt_short font .
 .
-This option originates from GNU
-.BR man (1).
 .
+.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 -- man
-Check the non-option command line arguments (filespecs) first on being
-man\~pages, then whether they represent an existing file.
 .
-By default, a filespec is first tested if it is an existing file.
+.Opt_def -- background color
+Set the background color of the viewer window.
 .
 .
-.Opt_def -- manpath "'dir1:dir2:\*[Ellipsis]'"
-Use the specified search path for retrieving man\~pages instead of the
-program defaults.
+.Opt_def -- bd pixels
+Specifies the color of the border surrounding the viewer window.
 .
-If the argument is set to the empty string "" the search for man\~page
-is disabled.
 .
+.Opt_def -- bg color
+This is equivalent to
+.Opt_long background .
 .
-.Opt_def -- mode value
 .
-Set the display mode.
+.Opt_def -- bw pixels
+Specifies the width in pixels of the border surrounding the viewer
+window.
 .
-The following mode values are recognized:
 .
+.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.
 .
-.RS
 .
+.Opt_def -- foreground color
+Set the foreground color of the viewer window.
 .
-.TP
-.B auto
-Display in the default manner; this actually means to try the modes
-.IR ps ,
-.IR x ,
-and
-.I tty
-in this sequence.
 .
-Useful for restoring default mode when a different mode was specified
-with
-.Env_var $GROFFER_OPT .
+.Opt_def -- fg color
+This is equivalent to
+.Opt_short foreground .
 .
 .
-.TP
-.B dvi
-Display formatted input in a dvi viewer program; equivalent to
-.Opt_long dvi .
+.Opt_def -- font font_name
+Set the font used by the viewer window.
 .
+The argument is an X font name.
 .
-.TP
-.B pdf
-Display formatted input in a PDF (Portable Document Format) viewer
-program; equivalent to
-.Opt_long pdf .
 .
+.Opt_def -- ft font_name
+This is equivalent to
+.Opt_long ft .
 .
-.TP
-.B ps
-Display formatted input in a Postscript viewer program; equivalent to
-.Opt_long ps .
 .
+.Opt_def -- geometry size_pos
+Set the geometry of the display window, that means its size and its
+starting position.
 .
-.TP
-.B tty
-Display formatted input in a text terminal; equivalent to
-.Opt_long tty .
+See
+.BR X (7)
+for the syntax of the argument.
 .
 .
-.TP
-.B www
-Display formatted input in a internet browser program; equivalent to
-.Opt_long www .
+.Opt_def -- resolution value
+Set X resolution in dpi (dots per inch) in some viewer programs.
 .
+The only supported dpi values are
+.B 75
+and
+.BR 100 .
 .
-.TP
-.B x
-Display formatted input in a native roff viewer such as
-.BR gxditview (@MAN1EXT@); equivalent to
-.Opt_long x .
+Actually, the default resolution for
+.I groffer
+is set to
+.BR 75 .
 .
 .
-.P
-The following modes do not use the
-.I groffer
-viewing features.
+.Opt_def -- rv
+Reverse foreground and background color of the viewer window.
 .
-They are only interesting for advanced applications.
 .
+.Opt_def -- title "'some text'"
+Set the title for the viewer window.
 .
-.TP
-.B groff
-Generate device output with plain
-.I groff
-without using the special viewing features of
-.IR groffer .
-If no device was specified by option
-.Opt_short T
-the
-.I groff
-default
-.B ps
-is assumed.
 .
+.Opt_def -- xrm "'resource'"
+Set X resource.
 .
-.TP
-.B source
-Display source code; same as
-.Opt_short Q .
 .
+.\" --------------------------------------------------------------------
+.SS "Options from man"
+.\" --------------------------------------------------------------------
+.
+The long options of
+.I groffer
+were synchronized with the long options of
+.IR GNU man .
 .
-.RE
+All long options of
+.I GNU man
+are recognized, but not all of these options are important to
+.IR groffer ,
+so most of them are just ignored.
 .
 .
-.Opt_def -- no-location
-Do not display the location of retireved files; this resets a former
-call to
-.Opt_long location .
+.P
+The following two options were added by
+.I groffer
+for choosing whether the file name arguments are interpreted as names
+for local files or as a search pattern for man pages.
 .
+The default is looking up for local files.
 .
-.Opt_def -- no-man
+.
+.Opt_def -- man
+Check the non-option command line arguments
+.RI ( filespecs )
+first on being man\~pages, then whether they represent an existing
+file.
+.
+By default, a
+.I filespec
+is first tested whether it is an existing file.
+.
+.
+.Opt_def -- no-man -- local-file
 Do not check for man\~pages.
 .
+.Opt_long local-file
+is the corresponding
+.I man
+option.
 .
-.Opt_def -- pager
-Set the pager program in tty mode; default is
-.IR less .
 .
+.P
+In the following, the
+.I man
+options that have a special meaning for
+.I groffer
+are documented.
 .
-.Opt_def -- pdf
-Choose pdf mode (Portable Document Format).
 .
-By default, the input is formatted by groff using the Postscript
-device, then it is transformed into the PDF file format using
-.BR gs (1)
-(this is quite slow), and finally displayed either with the
-.BR xpdf (1)
-or the
-.BR acroread (1)
-program; this can be configured with option
-.Opt_long viewer-pdf .
+.P
+The full set of long and short options of the
+.I GNU man
+program can be passed via the environment variable
+.Env_var $MANOPT ;
+see
+.BR man (1)
+if your system has
+.I GNU man
+installed.
 .
-PDF has a big advantage because the text is displayed graphically and
-is searchable nevertheless; but as thtransformation into pdf takes a
-considerable amount of time, the pdf mode is not suitable as a default
-device for the auto mode.
 .
-The only device that is compatible to this mode is
-.IR ps ,
-which is also the default when no device is specified.
+.Opt_def -- all
+In searching man\~pages, retrieve all suitable documents instead of
+only one.
 .
 .
-.Opt_def -- pdf-viewer prog
-Set the viewer program for
-.I pdf
-mode.
+.Opt_def - 7 -- ascii
+In text modes, display ASCII translation of special characters.
 .
-This can be a file name or a program to be searched in
-.Env_var $PATH .
 .
-In each case, arguments can be provided additionally.
+.Opt_def -- ditroff
+Eqivalent to
+.I groffer
+.Opt_short Z .
+.
+.
+.Opt_def -- extension suffix
+Restrict man\~page search to file names that have
+.I suffix
+appended to their section element.
 .
+For example, in the file name
+.I /usr/share/man/man3/terminfo.3ncurses.gz
+the man\~page extension is
+.IR ncurses .
 .
-.Opt_def -- ps
-Choose ps mode (Postscript).
 .
-By default, the formatted input is displayed with the
-.BR ghostview (@MAN1EXT@)
-program; this can be configured with option
-.Opt_long viewer-ps .
+.Opt_def -- locale language
 .
-The only device that is compatible to this mode is
-.IR ps ,
-which is also the default when no device is specified.
+Set the language for man pages.
 .
+This has the same effect, but overwrites
+.Env_var $LANG
 .
-.Opt_def -- ps-viewer prog
-Set the viewer program for
-.I ps
-mode.
 .
-This can be a file name or a program to be searched in
-.Env_var $PATH .
+.Opt_def -- location
+Print the location of the retrieved files to standard error.
 .
-Common Postscript viewers inlude
-.BR gv (1),
-.BR ghostview (1),
-and
-.BR gs (1),
 .
-In each case, arguments can be provided additionally.
+.Opt_def -- no-location
+Do not display the location of retrieved files; this resets a former
+call to
+.Opt_long location .
 .
+This was added by
+.IR groffer .
 .
-.Opt_def -- resolution value
-Set X resolution in dpi (dots per inch) in some viewer programs.
 .
-The only supported dpi values are
-.B 75
-and
-.BR 100 .
-This is an adaption of the X Toolkit option
-.Opt_short resolution .
+.Opt_def -- manpath "'dir1:dir2:\*[Ellipsis]'"
+Use the specified search path for retrieving man\~pages instead of the
+program defaults.
 .
+If the argument is set to the empty string "" the search for man\~page
+is disabled.
 .
-.Opt_def -- rv
-Reverse foreground and background color of the viewer window.
 .
-This is an adaption of the X Toolkit option
-.Opt_short rv .
-This feature is not available in all viewer programs.
+.Opt_def -- pager
+Set the pager program in tty mode; default is
+.IR less .
+This is equivalent to
+.Opt_long tty-viewer .
 .
 .
-.Opt_def -- sections
-Restrict searching for man pages to the given
+.Opt_def -- sections "'sec1:sec2:\*[Ellipsis]'"
+Restrict searching for man\~pages to the given
 .IR sections ,
 a colon-separated list.
 .
 .
-.Opt_def -- shell "shell_program"
-Specify the shell under which the groffer script should be run.
+.Opt_def -- systems "'sys1,sys2,\*[Ellipsis]'"
+Search for man pages for the given operating systems; the argument
+.I systems
+is a comma-separated list.
 .
-The script first tests whether this option is set (either within
-.Env_var $GROFF_OPT
-or as a command line option); if so, the script is rerun under the
-shell program specified with the option argument.
 .
+.Opt_def -- whatis
+Instead of displaying the content, get the one-liner description from
+the retrieved man\~page files \[em] or say that it is not a man\~page.
 .
-.Opt_def -- source
-Equivalent to
-.Opt_short Q .
 .
+.Opt_def -- where
+Eqivalent to
+.Opt_long location .
 .
-.Opt_def -- systems
-Search for man pages for the given operating systems; the argument
-.I systems
-is a comma-separated list.
 .
+.P
+Additionally, the following short option of
+.I man
+is supported as well.
 .
-.Opt_def -- title "'some text'"
-Set the title for the viewer window.
 .
-This feature is not available in all viewer programs.
+.\" --------------------------------------------------------------------
+.SS "Filespec Arguments"
+.\" --------------------------------------------------------------------
 .
+A
+.I filespec
+parameter is an argument meaning an input source, such as a file name
+or template for searching man\~pages.
 .
-.Opt_def -- to-postproc opt_or_arg
-Eqivalent to
-.Opt_short P .
+These input sources are collected and composed into a single output
+file such as
+.I groff
+does.
 .
 .
-.Opt_def -- troff-device
-Eqivalent to
-.Opt_short T .
-This option is only kept for compatibility with GNU
-.BR man (1).
+.P
+The strange POSIX behavior that maps all arguments behind the first
+non-option argument into
+.I filespec
+arguments is ignored.
 .
+The GNU behavior to recognize options even when mixed with
+.I filespec
+arguments is used througout.
 .
-.Opt_def -- tty
-Choose tty display mode, that means displaying in a text pager even
-when in X; eqivalent to
-.Opt_long mode\~tty .
+But, as usual, the double minus argument
+.Opt_long
+still takes all following arguments as
+.IR filespecs .
 .
 .
-.Opt_def -- version
-Eqivalent to
-.Opt_short v .
+.P
+Each
+.I filespec
+parameters can have one of the following forms.
 .
 .
-.Opt_def -- whatis
-Instead of displaying the content, get the one-liner description from
-the retrieved man page files \[em] or say that it is not a man page.
+.P
+No
+.I filespec
+parameters means that
+.I groffer
+waits for standard input.
 .
+The minus option
+.Opt_short ""
+stands for standard input, too, but can occur several times.
 .
-.Opt_def -- where
-Eqivalent to
-.Opt_long location .
+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 man\~page.
 .
-.Opt_def -- www
-Choose www mode (html), display in a web browser program, which can be
-specified with option
-.Opt_long www-viewer .
-By default, the existence of a sequence of standard web browsers is
-tested, starting with
-.BR mozilla (1)
-and
-.BR netscape (1)
 .
+.P
+On each system, the man pages are sorted according to their content
+into several sections.
 .
-.Opt_def -- www-viewer prog
-Set the web browser program for viewing in
-.I www
-mode.
+The
+.I classical man sections
+have a single-character name, either are a digit from
+.B 1
+to
+.B 9
+or one of the characters
+.B n
+or
+.BR o .
 .
-Each program that accepts html input and allows the
-.BI file://localhost/ dir / file
-syntax on the command line is suitable; it can be the path name of an
-executable file or a program in
-.Env_var $PATH .
+In the following, a stand-alone character
+.I s
+means this scheme.
 .
-In each case, arguments can be provided additionally.
 .
+.P
+The internal precedence of
+.I man
+for searching man pages with the same name within several sections
+goes according to the classical single-character sequence.
 .
-.Opt_def -- x
-Choose
-.I x
-mode (view in X roff viewer).
+On some systems, this single character can be extended by a following
+string.
 .
-By default, the formatted input is displayed with the
-.BR gxditview (@MAN1EXT@)
-program, being distributed together with groff, or with
-.BR xditview (1),
-which is distributed as a standard X tool.
+But the special
+.I groffer
+man page facility is based on the classical single character sections.
 .
-This can be configured with option
-.Opt_long x-viewer .
 .
-The only devices (option
-.Opt_short T )
-that are compatible with this mode are
-.IR X75 ,
-.IR X100 ,
-.IR X75-12 ,
-.IR X100-12 ,
+.P
+.BI man: name ( section )
 and
-.I ps
-(the default device).
+.IB name ( section )
+search the man\~page
+.I name
+in man\~section\~\c
+.IR section ,
+where
+.I section
+can be any string, but it must exist in the
+.I man
+system.
 .
 .
-.Opt_def -- x-viewer prog
-Set the viewer program for
-.I x
-mode.
+.P
+Next some patterns based on the
+.I classical man sections
+were constructed.
 .
-Suitable viewer programs are
-.BR gxditview (@MAN1EXT@)
+.BI man: name . s
 and
-.BR xditview (1).
+.IB name . s
+search for a man\~page
+.I name
+in man\~section
+.I s
+if
+.I s
+is a
+.I classical man section
+mentioned above.
+.
+Otherwise search for a man\~page named
+.IR name.s
+in the lowest
+.I man
+section.
 .
-But the argument can be any executable file or a program in
-.Env_var $PATH .
 .
-In each case, arguments can be provided additionally.
+.P
+Now
+.BI man: name
+searches for a man\~page in the lowest man\~section that has a
+document called
+.IR name .
 .
 .
-.TP
-.Opt_--
-Signals the end of option processing; all remaining arguments are
-interpreted as
+.P
+The pattern
+.I "s name"
+originates from a strange argument parsing of the
+.I man
+program.
+.
+If
+.I s
+is a
+.I classical man section
+interpret it as a search for a man\~page called
+.I name
+in man\~section
+.IR s ,
+otherwise interpret
+.I s
+as a file argument and
+.I name
+as another
 .I filespec
-parameters.
+argument.
 .
 .
 .P
-Besides these, groffer accepts all arguments that are valid for the
-.BR groff (@MAN1EXT@)
-program.
+We are left with the argument
+.I name
+which is not an existing file.
 .
-All non-groffer options are sent unmodified via grog to groff.
+So this searches for the man\~page called
+.I name
+in the lowest man\~section that has a document for this name.
 .
-Postprocessors, macro packages, compatibility with classical troff,
-and much more can be manually specified.
 .
+.P
+Several file name arguments can be supplied.
 .
-.\" --------------------------------------------------------------------
-.SH "OUTPUT MODES"
-.\" --------------------------------------------------------------------
+They are mixed by
+.I groff
+into a single document.
 .
-By default, the groffer program formats the input and then
-automatically chooses a suitable display mode, but the user can also
-choose between the following modes:
+Note that the set of option arguments must fit to all of these file
+arguments.
 .
-.Topic
-graphically display the formatted input with an X window program,
-including
+So they should have at least the same style of the
+.I groff
+language.
 .
-.RS
-.Topic
-with X window roff viewers such as
-.BR gxditview (@MAN1EXT@)
-.RI ( x
-mode),
 .
-.Topic
-in a dvi viewer program
-.RI ( dvi
-mode),
+.\" --------------------------------------------------------------------
+.SH "OUTPUT MODES"
+.\" --------------------------------------------------------------------
 .
-.Topic
-in a Postscript viewer
-.RI ( ps
-mode),
+By default, the
+.I groffer
+program collects all input into a single file, formats it with the
+.I groff
+program for a certain device, and then chooses a suitable viewer
+program.
 .
-.Topic
-in a PDF viewer
-.RI ( pdf
-mode),
+The device and viewer process in
+.I groffer
+is called a
+.IR mode .
 .
-.Topic
-in a web browser
-.RI ( www
-mode),
-.RE
+The mode and viewer of a running
+.I groffer
+program is selected automatically, but the user can also choose it
+with options.
 .
-.Topic
-display formatted input in a pager on the text terminal
-.RI ( tty
-mode),
 .
-.Topic
-run groffer like groff, but with decompression and man\~page searching
-.RI ( groff
-mode); this includes things like generating the groff intermediate
-output.
+The modes are selected by option the arguments of
+.Opt_long_arg mode \fIanymode .
+Additionally, each of this argument can be specified as an option of
+its own, such as
+.Opt_long \fIanymode .
+Most of these modes have a viewer program, which can be chosen by an
+option that is constructed like
+.Opt_long \fIanymode\fR-viewer .
 .
-.Topic
-stream the unformatted source code of the input onto standard output
-.RI ( source
-mode),
+.
+.P
+Several different modes are offered, graphical X modes, text modes,
+and some direct
+.I groff
+modes for debugging and development.
 .
 .
 .P
-By
-.IR default ,
+By default,
 .I groffer
 first tries whether
 .B x
@@ -1769,10 +2078,10 @@
 mode.
 .
 This mode testing sequence for
-.B default
+.B auto
 mode can be changed by specifying a comma separated list of modes
 with the option
-.Opt_long default-modes.
+.Opt_long default\-modes.
 .
 .
 .P
@@ -1784,47 +2093,60 @@
 .SS "Graphical Display Modes"
 .\" --------------------------------------------------------------------
 .
-The graphical display modes work only in the X window environment (or
+The graphical display modes work only in the X Window environment (or
 similar implementations within other windowing environments).
 .
 The environment variable
 .Env_var $DISPLAY
-or the option
+and the option
 .Opt_long display
-are used for specifying the X display to be used; if neither is
-specified, groffer assumes that no X is running.
+are used for specifying the X display to be used.
+.
+If neither is given,
+.I groffer
+assumes that no X and changes to one text mode.
+.
+You can change this automatic behavior by the option
+.Opt_long default\-modes .
 .
 .
 .P
-A certain graphical display mode can be selected by one of the options
-.Opt_long dvi ,
-.Opt_long pdf ,
-.Opt_long ps ,
-.Opt_short X ,
-and
-.Opt_long www .
+Known viewers for the graphical display modes and their standard X
+Window viewer progams are
 .
-By default, some graphical modes are tried first.  If none succeeds
-groffer switches to
-.B tty
-mode.
+.Topic
+X Window roff viewers such as
+.BR gxditview (@MAN1EXT@)
+or
+.BR xditview (1)
+(in
+.I x
+or
+.I X
+mode),
+.
+.Topic
+in a Postscript viewer
+.RI ( ps
+mode),
 .
+.Topic
+in a dvi viewer program
+.RI ( dvi
+mode),
 .
-.P
-The graphical modes can be customized by options that were named
-according to the resource options in the
-.BR X (1)
-Toolkit but using a leading double minus instead of the single minus
-used by X.
-.
-These include
-.Opt_long background ,
-.Opt_long foreground ,
-.Opt_long geometry ,
-.Opt_long resolution ,
-.Opt_long title ,
-.Opt_long xrm ,
-etc.
+.Topic
+in a PDF viewer
+.RI ( pdf
+mode),
+.
+.Topic
+in a web browser
+.RI ( html
+or
+.I www
+mode),
+.RE
 .
 .
 .P
@@ -1834,112 +2156,129 @@
 that allows to search for text within the viewer; this can be a really
 important feature.
 .
-Unfortunately, it takes a long time to transform the input into the
-PDF format, so it was not chosen as the major mode.
+Unfortunately, it takes some time to transform the input into the PDF
+format, so it was not chosen as the major mode.
 .
-You can change this by the options
-.Opt_long pdf
-and
-.Opt_long auto-modes .
+.
+.P
+These graphical viewers can be customized by options of the X Window
+Toolkit.
+.
+But the
+.I groffer
+options use a leading double minus instead of the single minus used by
+the X Window Toolkit.
 .
 .
 .\" --------------------------------------------------------------------
-.SS "Displaying on a tty"
+.SS "Text mode"
 .\" --------------------------------------------------------------------
 .
+There are to modes for text output, mode
+.I text
+for plain output without a pager and mode
+.I tty
+for a text output on a text terminal using some pager program.
+.
+.
+.P
 If the variable
 .Env_var $DISPLAY
-is not set or empty, groffer assumes that it should produce output on
-a text terminal.
-.
-This mode can also be forced by option
-.Opt_long tty .
+is not set or empty, groffer assumes that it should use
+.I tty
+mode.
 .
 .
 .P
 In the actual implementation, the groff output device
 .I latin1
-is chosen and the processed output is piped into a pager program.
+is chosen for text modes.
 .
 This can be changed by specifying option
-.Opt_long tty-device .
+.Opt_short T
+or
+.Opt_long device .
 .
 .
 .P
-The pager to be used can be specified by option
+The pager to be used can be specified by one of the options
 .Opt_long pager
-by the environment variable
+and
+.Opt_long tty-viewer ,
+or by the environment variable
 .Env_var $PAGER .
-If this is not set or empty the
+If all of this is not used the
 .BR less (1)
-program is used as the default pager.
+program with the option
+.Opt_short r
+for correctly displaying control sequences is used as the default
+pager.
 .
 .
 .\" --------------------------------------------------------------------
-.SS "Non-displaying Modes"
+.SS "Special Modes for Debugging and Development"
 .\" --------------------------------------------------------------------
 .
-There are some special modes that do not display the formatted output
-in a viewer program.
-.
-These modes are regarded as advanced, they are useful for debugging
-purposes.
-.
+These modes use the
+.I groffer
+file determination and decompression.
 .
-.TP
-.I source mode
-Instead of displaying the formatted output, it is also possible to
-have the roff source code streamed onto the standard output.
+This is combined into a single input file that is fed directly into
+.I groff
+with different strategy without the
+.I groffer
+viewing facilities.
 .
-This mode must be requested by one of the options
-.Opt_short Q
-or
-.Opt_long source .
+These modes are regarded as advanced, they are useful for debugging
+and development purposes.
 .
 .
-.TP
-.I groff mode
-This mode disables the groffer viewing facilities.
+.P
+The
+.I source
+mode with just displays the generated input.
 .
-The input is handled as usual with decompression and man\~page
-searching, but then it is passed to groff using only the options
-provided by groff.
+The
+.I groff
+mode passes the input to
+.I groff
+using only some suitable options provided to
+.IR groffer .
 .
 This enables the user to save the generated output into a file or pipe
 it into another program.
 .
-In this mode, the input is formatted, but not postprocessed; see
-.BR groff_out (@MAN5EXT@)
-for details.
 .
-This mode is activated automatically by the three groff options
-.Opt_short V
-(print roff pipe, no formatting),
-.Opt_short X
-(display with gxditview in groff's native way, using
-.Opt_short P
-for customization), and
+.P
+In
+.I groff
+mode, the option
 .Opt_short Z
-(disable post-processing, thus producing the groff intermediate output).
+disables post-processing, thus producing the
+.I groff intermediate
+.IR output .
 .
+In this mode, the input is formatted, but not postprocessed; see
+.BR groff_out (@MAN5EXT@)
+for details.
 .
-.\" --------------------------------------------------------------------
-.SH "FILE PARAMETERS"
-.\" --------------------------------------------------------------------
 .
-The non-option command line parameters determine which files should be
-displayed.
+.P
+All
+.I groff
+short options are supported by
+.IR groffer .
 .
 .
 .\" --------------------------------------------------------------------
-.SS "Filespecs"
+.SH "MAN\~PAGE\~SEARCHING"
 .\" --------------------------------------------------------------------
 .
-The default behavior of groffer is to first test whether the file
-parameter is represents a local file; if not, it is assumed to
-represent a filespec for searching one or more man\~page.
+The default behavior of groffer is to first test whether a file
+parameter represents a local file; if it is not an existing file name,
+it is assumed to represent a name of a man\~page.
 .
-This behavior can be modified by options.
+This behavior can be modified by the following options.
 .
 .
 .TP
@@ -1948,111 +2287,51 @@
 man\~pages.
 .
 .TP
-.Opt_long no-man
+.Opt_long no\-man
 .TP+
-.Opt_long local-file
+.Opt_long local\-file
 disable the man searching; so only local files are displayed.
 .
 .
 .P
-The following parameter formats are recognized to represent a wanted
-man\~page.
-.
-.
-.TP
-.BI man: name ( section )
-the quasi-URL notation used in many Desktop systems to 
-represent the man\~page
-.I name
-in
-.IR section .
-.
-.
-.TP
-.BI man: name
-search the man\~page
-.I name
-in the lowest section.
-The corresponding command with the man program would be
-.Shell_cmd man\~ name
-.
-.
-.TP
-.IB name . section
-the man\~page
-.I name
-in
-.IR section .
-The corresponding command with the man program would be
-.Shell_cmd man\~ section\~name
-.
-.
-.TP
-.I name
-if
-.I name
-is not an existing file search for the man\~page
-.I name
-in the lowest section just like
-.Shell_cmd man\~ name
-.
-.
-.TP
-.I section name
-Even this curious construct known from the various
-.I man
-programs is handled.
-.
-For example,
-.Shell_cmd "groffer 7 groff"
-was modelled according to
-.Shell_cmd "man 7 groff"
-retrieves the man\~page named
-.I groff
-in section 7.
-.
-Only a few standard section names are accepted, being actually the
-number sections
-.I 1, 2, 3, 4, 5, 6, 7, 8,
-and
-.IR 9,
-and the lower case letters
-.I `o'
-and
-.IR `n' .
-.
-.
-.P
 If neither a local file nor a man\~page was retrieved for some file
 parameter a warning is issued on standard error, but processing is
 continued.
 .
 .
-.\" --------------------------------------------------------------------
-.SS "Man\~Page Searching"
-.\" --------------------------------------------------------------------
-.
-The groffer program provides a search facility for system manual pages
-(man\~pages).
+.P
+The groffer program provides a search facility for man\~pages.
 .
 All long options, all environment variables, and most of the
 functionality of the GNU
 .BR man (1)
 program were implemented.
 .
+This inludes the extended file names of man\~pages, for example,
+the man\~page of
+.I groff
+in man\~section 7 may be stored under
+.File_name /usr/share/man/man7/groff.7.gz ,
+where
+.File_name /usr/share/man/
+is part of the man\~path, the subdirectory
+.I man7
+and the file extension
+.I .7
+refer to the man\~section 7;
+.I .gz
+shows the compression of the file.
+.
 .
 .P
-Preformatted man\~pages (cat\~pages) are intentionally excluded from
-the search because groffer is a roff program that wants to format by
-its own, not spit out stuff that was digested previously by someone
-else.
+The
+.I cat\~pages
+(preformatted man\~pages) are intentionally excluded from the search
+because groffer is a roff program that wants to format by its own.
 .
 With the excellent performance of the actual computers, the
 preformatted man\~pages aren't necessary any longer.
 .
-Due to their inflexible nature, they tend to provoke some trouble with
-changing line lengths and different environments in networks.
-.
 .
 .P
 The algorithm for retrieving man\~pages uses five search methods.
@@ -2079,15 +2358,17 @@
 variable
 .Env_var $MANOPT .
 .
+.
 .Topic
-If this does not work, the
-.BR manpath (1)
-program for determining a path of man directories is tried.
+If this does not work a reasonable default path from
+.Env_var $PATH
+is searched for man\~pages.
 .
 .
 .Topic
-If this does not work a reasonable default path is searched for
-man\~pages.
+If this does not work, the
+.BR manpath (1)
+program for determining a path of man directories is tried.
 .
 .
 .P
@@ -2189,8 +2470,8 @@
 The search can further be restricted by limiting it to certain
 sections.
 .
-A single section can be specified within a filespec, several sections
-as a colon-separated list in command line option
+A single section can be specified within each filespec argument,
+several sections as a colon-separated list in command line option
 .Opt_long sections
 or environment variable
 .Env_var $MANSECT .
@@ -2216,7 +2497,7 @@
 .
 .
 .\" --------------------------------------------------------------------
-.SS Decompression
+.SH DECOMPRESSION
 .\" --------------------------------------------------------------------
 .
 The program has a decompression facility.
@@ -2264,7 +2545,7 @@
 The options specified in this variable are overridden by the options
 given on the command line.
 .
-The content of this variable is run through the shell builitin `eval';
+The content of this variable is run through the shell builtin `eval';
 so arguments containing white-space or special shell characters should
 be quoted.
 .
@@ -2284,7 +2565,7 @@
 .
 .TP
 .Env_var $DISPLAY
-If this variable is set this indicates that the X window system is
+If this variable is set this indicates that the X Window system is
 running.
 .
 Testing this variable decides on whether graphical or text output is
@@ -2358,11 +2639,20 @@
 .
 .TP
 .Env_var $POSIXLY_CORRECT
-If set to a non-empty value this chooses the POSIX mode for option
-processing, that means that option processing will be finished as soon
-as a non-option argument is found.
+If set to a non-empty value this chooses the POSIX mode.
+.
+This is done internally by some shells.
+.
+.I groffer
+ignores the bad POSIX behavior for option processing, that means that
+option processing will be finished as soon as a non-option argument is
+found.
+.
+Instead the GNU behavior of freely mixing options and
+.I filespec
+arguments is used in any case.
 .
-Usually, you do not want to set this environment variable.
+Usually, you do not want to set this environment variable externally.
 .
 .
 .\" --------------------------------------------------------------------
@@ -2372,7 +2662,7 @@
 The groffer program internally calls groff, so all environment
 variables documented in
 .BR groff (@MAN1EXT@)
-are internally used within groffer as well; see there for details.
+are internally used within groffer as well.
 .
 The following variables have a direct meaning for the groffer program.
 .
@@ -2386,7 +2676,7 @@
 .SS "Man Variables"
 .\" --------------------------------------------------------------------
 .
-Parts of the functionality of the man program were implemented in
+Parts of the functionality of the man\~program were implemented in
 groffer; support for all environment variables documented in
 .BR man (1)
 was added to groffer, but the meaning was slightly modified due to the
@@ -2457,25 +2747,25 @@
 .
 .
 .\" --------------------------------------------------------------------
-.SH "FILES"
+.SH "CONFIGURATION FILES"
 .\" --------------------------------------------------------------------
 .
-The groffer program can be preconfigured by two configuration files.
+The
+.I groffer
+program can be preconfigured by two configuration files.
 .
-Both of them are shell scripts that are called at the beginning of
-groffer using the `\c
-.CB .\~\c
-.IR filename '
-syntax.
+This configuration can be overridden at each program start by command
+line options or by the environment variable
+.Env_var $GROFFER_OPT .
 .
 .
 .TP
-.CB /etc/groff/groffer.conf
+.File_name /etc/groff/groffer.conf
 System-wide configuration file for groffer.
 .
 .
 .TP
-.CB $HOME/.groff/groffer.conf
+.File_name $HOME/.groff/groffer.conf
 User-specific configuration file for groffer, where
 .Env_var $HOME
 denotes the user's home directory.
@@ -2485,25 +2775,53 @@
 .
 .
 .P
+Their lines either start with a minus character or are shell commands.
+.
+Arbitrary spaces are allowed at the beginning, they are just ignored.
+.
+The lines with the beginning minus are appended to the existing value
+of $GROFFER_OPT.
+.
+This easily allows to set general
+.I groffer
+options that are used with any call of
+.IR groffer .
+.
+.
+.P
+After the transformation of the minus lines the emerging shell scripts
+that are called by
+.I groffer
+using the `\c
+.CB .\~\c
+.IR filename '
+syntax.
+.
+.
+.P
+The only option that needs a minus line in the configuration files is
+.Opt_long shell .
+The reason is that its argument must be called at a very early stage
+before the whole syntax of the configuration can be transformed.
+.
+.
+.P
 It makes sense to use these configuration files for the following
 tasks:
 .
 .Topic
-Preset environment variables recognized by groffer; preferably a
-variable should only be set when it is unset in order not to override
-a user-provided value.
+Preset command line options by writing them into lines starting with a
+minus sign.
 .
 .Topic
-Preset command line options by prepending them to
-.Env_var $GROFFER_OPT ;
-prepending should be preferred to appending and setting in order not
-to delete the environment variable provided by the 
+Preset environment variables recognized by groffer.
 .
 .Topic
-Write functions for calling viewer programs in a special way and feed
-them into the
-.Opt_long \f[I]*\f[]-viewer
-options.
+Write a function for calling a viewer program for a special
+.I mode
+and feed this name into its corresponding
+.Opt_long \f[I]mode\f[]\-viewer
+option.
 .
 Note that the name of such a function must coincide with some existing
 program in the system path
@@ -2512,44 +2830,90 @@
 .
 .
 .P
-As an example, consider the following configuration file.
+As an example, consider the following configuration file in
+~/.groff/groffer.conf, say.
 .
 .P
 .ft CR
 .nh
 .nf
-#! /bin/sh
-# ~/.groff/groffer.conf
+# groffer configuration file
+#
+# groffer options that are used in each call of groffer
+--shell=/bin/bash
+--resolution=100
+--foreground=DarkBlue
+--x-viewer='gxditview -geometry 850x800'
+#
+# some shell commands
 if test "$DISPLAY" = ""; then
-  DISPLAY='localhost:0.0';
-fi;
-GROFF_OPT="--resolution=100 $GROFF_OPT";
-gxditview()
-{
-  /usr/local/bin/gxditview --fg DarkBlue "$@";
-}
+  DISPLAY='localhost:0.0'
+fi
+date >>~/mygroffer.log
 .fi
 .hy
 .ft
 .
 .
 .P
+This configuration sets four
+.I groffer
+options and runs two shell commands.
+.
 This has the following effects:
+.
+.
 .Topic
-allows to start groffer in a graphical mode even from a text
-terminal;
+Lines starting with a 
+.B #
+character
+are 
+.
+.
 .Topic
-all graphical modes use a resolution of 100 dpi where applicable;
+Use
+.B /bin/bash
+as the shell to run the
+.I groffer
+script.
+.
+.
 .Topic
-the
+Take a resolution of
+.B 100 dpi
+and a text color of
+.B DarkBlue
+in all viewers that support this.
+.
+.
+.Topic
+Force
 .BR gxditview (@MAN1EXT@)
-program is told to use
-.I DarkBlue
-as the text color.
+as the X-mode viewer using the geometry option for setting the width
+to
+.B 850 dpi
+and the height to
+.B 800
+.BR dpi .
+.
+.
+.Topic
+The variable
+.Env_var $DISPLAY
+is set to
+.IR localhost:0.0
+which allows to start
+.I groffer
+in the standard X display, even when the program is called from a text
+console.
 .
-These configurations can be overridden by command line options and by
-environment variable
-.Env_var $GROFFER_OPT .
+.
+.Topic
+Just for fun, the date of each
+.I groffer
+start is written to the file
+.B mygroffer.log
+in the home directory.
 .
 .
 .\" --------------------------------------------------------------------
@@ -2570,20 +2934,65 @@
 .I meintro.ms.gz
 in the directory
 .IR /usr/local/share/doc/groff ,
-using a default graphical viewer when in X window, or the
+using
+.I gxditview
+as graphical viewer when in X Window, or the
 .BR less (1)
 pager program when not in X.
 .
 .
 .TP
-.Shell_cmd "groffer\~groff.7\~groff\~\[cq]troff(1)\[cq]\~man:roff"
+.Shell_cmd "groffer\~groff"
+If the file
+.I ./groff
+exists use it as input.
+.
+Otherwise interpret the argument as a search for the man\~page named
+.I groff
+in the smallest possible man\~section, being secion 1 in this case.
+.
+.
+.TP
+.Shell_cmd "groffer\~man:groff"
+search for the man\~page of
+.I groff
+even when the file
+.I ./groff
+exists.
+.
+.
+.TP
+.Shell_cmd "groffer\~groff.7"
+.TP+
+.Shell_cmd "groffer\~7\~groff"
+search the man\~page of
+.I groff
+in man\~section
+.BR 7 .
+This section search works only for a digit or a single character from
+a small set.
+.
+.
+.TP
+.Shell_cmd "groffer\~fb.modes"
+If the file
+.I ./fb.modes
+does not exist interpret this as a search for the man\~page of
+.IR fb.modes .
+As the extension
+.I modes
+is not a single character in classical section style the argument is
+not split to a search for
+.IR fb .
+.
+.
+.TP
+.Shell_cmd "groffer\~groff\~\[cq]troff(1)\[cq]\~man:roff"
 .
 The arguments that are not existing files are looked-up as the
 following man\~pages:
 .I groff
-(in section\~7),
-.I groff
-(automatic search, should be found in section\~1),
+(automatic search, should be found in man\~section\~1),
 .I troff
 (in section\~1),
 and
@@ -2603,14 +3012,18 @@
 .
 .
 .TP
-.Shell_cmd "LANG=de\~groffer\~--man\~--www\~--www-viever=netscape\~ls"
+.Shell_cmd "LANG=de\~groffer\~--man\~--www\~--www-viever=mozilla\~ls"
 .
-Retrieve the German man\~page for the
+Retrieve the German man\~page (language
+.IR de )
+for the
 .B ls
-program (or the English one if there is a German version), decompress
-it, format it into the html format and view the result in the default
-web browser
-.I netscape .
+program, decompress it, format it to
+.I html
+format
+.RI ( www
+mode) and view the result in the web browser
+.I galeon .
 The option
 .Opt_long man
 guarantees that the man\~page is retrieved, even when a local file
@@ -2619,29 +3032,34 @@
 .
 .
 .TP
-.Shell_cmd "groffer\~-Q\~'man:roff(7)'"
+.Shell_cmd "groffer\~--source\~'man:roff(7)'"
 .
-Print the unformatted content of the man\~page called
+Get the man\~page called
 .I roff
-in section 7 on standard output.
+in man\~section 7, decompress it, and print its unformatted content,
+its source code.
 .
 .
 .TP
-.Shell_cmd "groffer\~-Z\~-mfoo"
+.Shell_cmd "cat\~file.gz\~|\~groffer\~-Z\~-mfoo"
 .
-Decompress the standard input, switch to
+Decompress the standard input, send this to
 .I groff
-mode, format the input with groff using the macro package foo, but do
-not postprocess the result, thus producing the intermediate output.
+intermediate mode without post-processing (groff option
+.Opt_short Z ),
+using macro package by
+.I foo
+(groff option
+.Opt_short m ) .
 .
 .
 .TP
 .Shell_cmd "echo\~'\[rs]f[CB]WOW!'\~|"
 .TP+
-.Shell_cmd+ "groffer --x --bg red --fg yellow --geometry 200x100"
+.Shell_cmd+ "groffer --x --bg red --fg yellow --geometry 200x100 -"
 .
-Display \f[CB]WOW!\f[] in a small window in constant-width bold font,
-using color yellow on red background.
+Display the word \f[CB]WOW!\f[] in a small window in constant-width
+bold font, using color yellow on red background.
 .
 .
 .\" --------------------------------------------------------------------
@@ -2650,16 +3068,26 @@
 .
 The
 .B groffer
-shell script is compatible to both POSIX and GNU.
+shell script is compatible with both GNU and POSIX.
 .
 POSIX compatibility refers to
 .B IEEE P1003.2/D11.2
-of September 1991, a very early version of this standard.
+of September 1991, a very early version of the POSIX standard that is
+still freely available in the internet.
+.
+Unfortunately, this version of the standard has `local' for shell
+function variables removed.
+.
+As `local' is needed for serious programming this temporary POSIX
+deprecation was ignored.
 .
-The script uses only a quite restricted set of shell language elements
-and shell builtins, common to all POSIX versions; the only external
-program used is `sed', again only the most basic POSIX features of
-`sed' are used.
+.
+.P
+Most GNU shells are compatible with this interpretation of POSIX, but
+provide much more facilities.
+.
+Nevertheless this script uses only a restricted set of shell language
+elements and shell builtins.
 .
 The groffer script should work on most actual free and commercial
 operating systems.
@@ -2673,12 +3101,10 @@
 .
 .P
 The groffer shell script was tested with the following common
-implementations of the POSIX shell:
-.BR ash (1),
-.BR bash (1),
-.BR ksh (1),
-and POSIX
+implementations of the GNU shells:
+POSIX
 .BR sh (1),
+.BR bash (1),
 and others.
 .
 Free POSIX compatible shells and shell utilities for most operating
@@ -2687,36 +3113,83 @@
 .
 .
 .P
-The best performance was obtained with the
-.I ash
-shell; so groffer tries to run under
-.I ash
-whenever possible.
+The shell can be chosen by the option
+.Opt_long shell .
+This option can also be given to the environment variable
+.Env_var $GROFF_OPT .
+If you want to write it to one of the
+.I groffer
+configuration files you must use the single option style, a line
+starting with
+.Opt_long shell .
+.
+.
+.P
+The groffer program provides its own parser for command line arguments
+that is compatible to both POSIX
+.BR getopts (1)
+and GNU
+.BR getopt (1)
+except for shortcuts of long options.
 .
-The procedure to determine the shell to run groffer was programmed to
-be as follows:
+The following standard types of options are supported.
 .
 .
 .Topic
-the argument of the command line option
-.Opt_long shell ;
-if not set
+A single minus always refers to single character option or a
+combination thereof, for example, the
+.I groffer
+short option combination
+.Opt_short Qmfoo
+is equivalent to
+.Opt_short Q\~\-m\~foo .
+.
 .
 .Topic
-the argument of the option
-.Opt_long shell
-in the environment variable
-.Env_var $GROFF_OPT ;
-if not set
+Long options are options with names longer than one character; they
+are always prededed by a double minus.
+.
+An option argument can either go to the next command line argument or
+be appended with an equal sign to the argument; for example,
+.Opt_alt -- long=arg
+is equivalent to
+.Opt_alt -- long\~arg .
+.
 .
 .Topic
-try
-.IR ash ;
-if not available
+An argument of
+.Opt_--
+ends option parsing; all further command line arguments are
+interpreted as file name arguments.
+.
 .
 .Topic
-continue with the shell under which the script was started in the
-first place.
+By default, all command line arguments that are neither options nor
+option arguments are interpreted as filespec parameters and stored
+until option parsing has finished.
+.
+For example, the command line
+.Shell_cmd "groffer file1 -a -o arg file2"
+is, by default, equivalent to
+.Shell_cmd "groffer -a -o arg -- file1 file2"
+.
+.
+.P
+This behavior can be changed by setting the environment variable
+.Env_var $POSIXLY_CORRECT
+to a non-empty value.
+.
+Then the strange POSIX non-option behavior is adopted, i. e. option
+processing is stopped as soon as the first non-option argument is
+found and each following argument is taken as a file name.
+.
+For example, in posixly correct mode, the command line
+.Shell_cmd "groffer file1 -a -o arg file 2"
+is equivalent to
+.Shell_cmd "groffer -- file1 -a -o arg file 2"
+As this leads to unwanted behavior in most cases, most people do not
+want to set
+.Env_var $POSIXLY_CORRECT .
 .
 .
 .\" --------------------------------------------------------------------
@@ -2727,27 +3200,27 @@
 .BR groff (@MAN1EXT@)
 .TP+
 .BR troff (@MAN1EXT@)
-Details on the options and environment variables available in groff;
+Details on the options and environment variables available in
+.IR groff ;
 all of them can be used with groffer.
 .
 .
 .TP
-.BR grog (@MAN1EXT@)
-Internally, groffer tries to guess the groff command line options from
-the input using this program.
-.
+.BR man (1)
+The standard program to diplay man\~pages.
 .
-.TP
-.BR groff_out (@MAN5EXT@)
-Documentation on the groff intermediate output (ditroff output).
+The information there is only useful if it is the man\~page for
+.IR "GNU\~man" .
+Then it documents the options and environment variables that are
+supported by groffer.
 .
 .
 .TP
-.BR xdvi (1)
+.BR gxditview (@MAN1EXT@)
 .TP+
-.BR dvilx (1)
+.BR xditview (1x)
 Viewers for groffer's
-.I dvi
+.I x
 mode.
 .
 .
@@ -2779,15 +3252,22 @@
 .
 .
 .TP
-.BR gxditview (@MAN1EXT@)
+.BR xdvi (1)
 .TP+
-.BR xditview (1x)
+.BR dvilx (1)
 Viewers for groffer's
-.I x
+.I dvi
 mode.
 .
 .
 .TP
+.BR less (1)
+Standard pager program for the
+.I tty
+.IR mode .
+.
+.
+.TP
 .BR gzip (1)
 .TP+
 .BR bzip2 (1)
@@ -2795,36 +3275,33 @@
 .
 .
 .TP
-.BR man (1)
-The standard program to diplay man\~pages.
+.BR groff (@MAN7EXT@)
+Documentation of the
+.I groff
+language.
 .
-The information there is only useful if it is the man\~page for
-.IR "GNU\~man" .
-Then it documents the options and environment variables that are
-supported by groffer.
+.
+.TP
+.BR grog (@MAN1EXT@)
+Internally, groffer tries to guess the groff command line options from
+the input using this program.
+.
+.
+.TP
+.BR groff_out (@MAN5EXT@)
+Documentation on the groff intermediate output (ditroff output).
 .
 .
 .\" --------------------------------------------------------------------
 .SH "AUTHOR"
 .\" --------------------------------------------------------------------
+.author
 .
-Copyright (C) 2001, 2002 Free Software Foundation, Inc.
-.
-.P
-This document is distributed under the terms of the FDL (GNU Free
-Documentation License) version 1.1 or later.
-.
-You should have received a copy of the FDL on your system, it is also
-available on-line at the
-.URL http://\:www.gnu.org/\:copyleft/\:fdl.html "GNU copyleft site" .
 .
-.P
-This document is part of
-.IR groff ,
-the GNU roff distribution.
-.
-It was written by
-.MTO bwarken@mayn.de "Bernd Warken" .
+.\" --------------------------------------------------------------------
+.SH "COPYING"
+.\" --------------------------------------------------------------------
+.copyleft
 .
 .
 \" --------------------------------------------------------------------
diff -ruN groff-1.18.1/contrib/groffer/groffer.sh groff-1.18.1.1/contrib/groffer/groffer.sh
--- groff-1.18.1/contrib/groffer/groffer.sh	Mon Sep 30 12:18:07 2002
+++ groff-1.18.1.1/contrib/groffer/groffer.sh	Tue Jun 15 03:44:50 2004
@@ -2,12 +2,12 @@
 
 # groffer - display groff files
 
-# File position: /contrib/groffer/groffer
+# Source file position: /contrib/groffer/groffer.sh
 
-# Copyright (C) 2001,2002 Free Software Foundation, Inc.
-# Written by Bernd Warken 
+# Copyright (C) 2001,2002,2003,2004 Free Software Foundation, Inc.
+# Written by Bernd Warken
 
-# This file is part of groff.
+# This file is part of groff version @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
@@ -20,33 +20,47 @@
 # License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with groff; see the file COPYING.  If not, write to the
-# Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-# MA 02111-1307, USA.
-
-export _PROGRAM_NAME;
-export _PROGRAM_VERSION;
-export _LAST_UPDATE;
+# along with groff; see the files COPYING and LICENSE in the top
+# directory of the groff source.  If not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 _PROGRAM_NAME='groffer';
-_PROGRAM_VERSION='0.9.1';
-_LAST_UPDATE='30 Sep 2002';
+_PROGRAM_VERSION='0.9.11';
+_LAST_UPDATE='15 June 2004';
+
 
 ########################################################################
-# Determine the shell under which to run this script;
-# if `ash' is available restart the script using `ash';
-# otherwise just go on.
+# Determine the shell under which to run this script from the command
+# line arguments or $GROFF_OPT; if none is specified, just go on with
+# the starting shell.
 
-if test "${_groffer_run}" != 'second'; then
+if test _"${_groffer_run}"_ = __; then
   # only reached during the first run of the script
 
-  export GROFFER_OPT;
-  export _groffer_run;
-  export _this;
-
+  export _groffer_run;		# counter for the runs of groffer
+  _groffer_run='first';
 
-  #_this="@BINDIR@/${_PROGRAM_NAME}";
-  _this='groffer.sh';
+  export _PROGRAM_NAME;
+  export _PROGRAM_VERSION;
+  export _LAST_UPDATE;
+
+  export GROFFER_OPT;		# option environment for groffer
+  export _GROFFER_SH;		# file name of this shell script
+  export _OUTPUT_FILE_NAME;	# output generated, see main_set_res..()
+
+  export _CONFFILES;		# configuration files
+  _CONFFILES="/etc/groff/groffer.conf ${HOME}/.groff/groffer.conf";
+
+  case "$0" in
+  *${_PROGRAM_NAME}*)
+    _GROFFER_SH="$0";
+    # was: _GROFFER_SH="@BINDIR@/${_PROGRAM_NAME}";
+    ;;
+  *)
+    echo "The ${_PROGRAM_NAME} script should be started directly." >&2
+    exit 1;
+    ;;
+  esac;
 
   ###########################
   # _get_opt_shell ("$@")
@@ -92,40 +106,53 @@
   #
   _test_on_shell()
   {
-    if test "$#" -le 0 || test "$1" = ''; then
+    if test "$#" -le 0 || test _"$1"_ = __; then
       return 1;
     fi;
     # do not quote $1 to allow arguments
-    test "$($1 -c 's=ok; echo -n "$s"' 2>/dev/null)" = 'ok';
+    test _"$($1 -c 's=ok; echo -n "$s"' 2>/dev/null)"_ = _ok_;
   }
 
-  # do the shell determination
+  # do the shell determination from command line and $GROFFER_OPT
   _shell="$(_get_opt_shell "$@")";
-  if test "${_shell}" = ''; then
-    _shell='ash';
+
+  if test _"${_shell}"_ = __; then
+    # none found, so look at the `--shell' lines in configuration files
+    export f;
+    for f in ${_CONFFILES}; do
+      if test -f $f; then
+        _all="$(cat $f | sed -n -e '/^--shell[= ] *\([^ ]*\)$/s//\1/p')"
+        for s in ${_all}; do
+          _shell=$s;
+        done;
+      fi;
+    done;
+    unset f;
+    unset s;
+    unset _all;
   fi;
+
+  # restart the script with the last found $_shell, if it is a shell
   if _test_on_shell "${_shell}"; then
     _groffer_run='second';
     # do not quote $_shell to allow arguments
-    exec ${_shell} "${_this}" "$@";
+    exec ${_shell} "${_GROFFER_SH}" "$@";
     exit;
   fi;
 
-  # clean-up of shell determination
+  _groffer_run='second';
   unset _shell;
-  unset _this;
-  unset _groffer_run;
-  _get_opt_shell()
-  {
-    return 0;
-  }
-  _test_on_shell()
-  {
-    return 0;
-  }
 
+fi; # end of first run
+
+if test _"${_groffer_run}"_ != _second_;
+then
+  echo "$_groffer_run should be 'second' here." >&2
+  exit 1
 fi;
 
+unset _groffer_run
+
 
 ########################################################################
 # diagnostic messages
@@ -140,145 +167,6 @@
 
 
 ########################################################################
-#                          Description
-########################################################################
-
-# Display groff files and man pages on X or tty, even when compressed.
-
-
-### Usage
-
-# Input comes from either standard input or command line parameters
-# that represent either names of exisiting roff files or standardized
-# specifications for man pages.  All of these can be compressed in a
-# format that is decompressible by `gzip'.
-
-# The following displaying modes are available:
-# - Display formatted input with the X roff viewer `gxditview',
-# - with a Prostcript viewer,
-# - with a dvi viewer,
-# - with a web browser.
-# - Display formatted input in a text terminal using a text device.
-# - Generate output for some groff device on stdout without a viewer.
-# - Output only the source code without any groff processing.
-# - Generate the troff intermediate output on standard output
-#   without groff postprocessing.
-# By default, the program tries to display with `gxditview' (1); if
-# this does not work, text display (2) is used.
-
-
-### 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().
-
-
-### Compatibility
-
-# This shell script is compatible to the both the GNU and the POSIX
-# shell and utilities.  Care was taken to restrict the programming
-# technics used here in order to achieve POSIX compatibility as far
-# back as POSIX P1003.2 Draft 11.2 of September 1991.
-
-# The only non-builtin used here is POSIX `sed'.  This script was
-# tested under `bash', `ash', and `ksh'.  The speed under `ash' is
-# more than double when compared to the larger shells.
-
-# This script provides its own option parser.  It is compatible to the
-# usual GNU style command line (option clusters, long options, mixing
-# of options and non-option file names), except that it is not
-# possible to abbreviate long option names.
-
-# The mixing of options and file names can be prohibited by setting
-# the environment variable `$POSIXLY_CORRECT' to a non-empty value.
-# This enables the rather wicked POSIX behavior to terminate option
-# parsing when the first non-option command line argument is found.
-
-
-########################################################################
-#            Survey of functions defined in this document
-########################################################################
-
-# The elements specified within paranthesis `(<>)' give hints to what
-# the arguments are meant to be; the argument names are irrelevant.
-# <>?     0 or 1
-# <>*     arbitrarily many such arguments, incl. none
-# <>+     one or more such arguments
-# <>      exactly 1
-
-# A function that starts with an underscore `_' is an internal
-# function for some function.  The internal functions are defined just
-# after their corresponding function; they are not mentioned in the
-# following.
-
-# abort (text>*)
-# base_name (path)
-# catz ()
-# clean_up ()
-# clean_up_secondary ()
-# diag (text>*)
-# dirname_append ( [])
-# dirname_chop ()
-# do_filearg ()
-# do_nothing ()
-# echo2 (*)
-# echo2n (*)
-# error (*)
-# get_first_essential (*)
-# is_dir ()
-# is_empty ()
-# is_equal ( )
-# is_file ()
-# is_not_empty ()
-# is_not_equal ( )
-# is_not_file ()
-# is_not_prog ()
-# is_prog ()
-# is_yes ()
-# leave ()
-# landmark ()
-# list_append ( ...)
-# list_check ()
-# list_from_args (...)
-# list_from_cmdline (    [...])
-# list_from_split ( )
-# list_has ( )
-# list_has_not ( )
-# list_length ()
-#   main_*(), see after the functions
-# man_do_filespec ()
-# man_setup ()
-# man_register_file ( [ [
]]) -# man_search_section (
) -# man_set() -# manpath_add_lang( ) -# manpath_add_system() -# manpath_from_path () -# normalize_args ( *) -# path_chop () -# path_clean () -# path_contains ( ) -# path_not_contains ( ) -# path_split () -# register_file () -# register_title () -# reset () -# save_stdin () -# string_contains ( ) -# string_not_contains ( ) -# tmp_cat () -# tmp_create (?) -# to_tmp () -# usage () -# version () -# warning () -# whatis () -# where () - - -######################################################################## # Environment Variables ######################################################################## @@ -298,43 +186,6 @@ ######################################################################## -# External environment variables - -# If these variables are exported here then the `ash' shell coughs -# when calling `groff' in `main_display()'. - -if test "${GROFFER_EXPORT_EXTERNALS}" = 'yes'; then - - # external system environment variables that are explicitly used - export DISPLAY; # Presets the X display. - export LANG; # For language specific man pages. - export LC_ALL; # For language specific man pages. - export LC_MESSAGES; # For language specific man pages. - export PAGER; # Paging program for tty mode. - export PATH; # Path for the programs called (: list). - - # groffer native environment variables - export GROFFER_OPT # preset options for groffer. - - # all groff environment variables are used, see groff(1) - export GROFF_BIN_PATH; # Path for all groff programs. - export GROFF_COMMAND_PREFIX; # '' (normally) or 'g' (several troffs). - export GROFF_FONT_PATH; # Path to non-default groff fonts. - export GROFF_TMAC_PATH; # Path to non-default groff macro files. - export GROFF_TMPDIR; # Directory for groff temporary files. - export GROFF_TYPESETTER; # Preset default device. - - # all GNU man environment variables are used, see man(1). - export MANOPT; # Preset options for man pages. - export MANPATH; # Search path for man pages (: list). - export MANROFFSEQ; # Ignored because of grog guessing. - export MANSECT; # Search man pages only in sections (:). - export SYSTEM; # Man pages for different OS's (, list). - -fi; - - -######################################################################## # read-only variables (global to this file) ######################################################################## @@ -366,9 +217,8 @@ _TAB=' '; # function return values; `0' means ok; other values are error codes +export _ALL_EXIT; export _BAD; -export _BAD2; -export _BAD3; export _ERROR; export _GOOD; export _NO; @@ -377,9 +227,9 @@ _GOOD='0'; # return ok _BAD='1'; # return negatively, error code `1' -_BAD2='2'; # return negatively, error code `2' -_BAD3='3'; # return negatively, error code `3' -_ERROR='255'; # for syntax errors; no `-1' in `ash' +_ERROR='7'; # for syntax errors; no `-1' in `ash' + +_ALL_EXIT="${_GOOD} ${_BAD} ${_ERROR}"; # all exit codes (for `trap_set') _NO="${_BAD}"; _YES="${_GOOD}"; @@ -400,13 +250,10 @@ return_error="func_pop; return ${_ERROR}"; -export _CONFFILES; -_CONFFILES="/etc/groff/groffer.conf ${HOME}/.groff/groffer.conf"; - export _DEFAULT_MODES; -_DEFAULT_MODES='ps,x,tty'; +_DEFAULT_MODES='x,ps,tty'; export _DEFAULT_RESOLUTION; -_DEFAULT_RESOLUTION='100'; +_DEFAULT_RESOLUTION='75'; export _DEFAULT_TTY_DEVICE; _DEFAULT_TTY_DEVICE='latin1'; @@ -415,12 +262,12 @@ # _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_WWW_X; # viewer program for www mode in X -export _VIEWER_WWW_TTY; # viewer program for www mode in tty +export _VIEWER_HTML_X; # viewer program for html mode in X +export _VIEWER_HTML_TTY; # viewer program for html mode in tty _VIEWER_DVI='xdvi,dvilx'; _VIEWER_PDF='xpdf,acroread'; _VIEWER_PS='gv,ghostview,gs_x11,gs'; -_VIEWER_WWW='mozilla,netscape,opera,amaya,arena'; +_VIEWER_HTML='konqueror,mozilla,netscape,opera,amaya,arena,lynx'; _VIEWER_X='gxditview,xditview'; # Search automatically in standard sections `1' to `8', and in the @@ -458,86 +305,95 @@ export _OPTS_GROFF_SHORT_ARG; export _OPTS_GROFF_LONG_NA; export _OPTS_GROFF_LONG_ARG; +export _OPTS_X_SHORT_ARG; +export _OPTS_X_SHORT_NA; +export _OPTS_X_LONG_ARG; +export _OPTS_X_LONG_NA; export _OPTS_MAN_SHORT_ARG; export _OPTS_MAN_SHORT_NA; export _OPTS_MAN_LONG_ARG; export _OPTS_MAN_LONG_NA; -export _OPTS_GROFFER_LONG; -export _OPTS_GROFFER_SHORT; -export _OPTS_GROFF_LONG; -export _OPTS_GROFF_SHORT; +export _OPTS_MANOPT_SHORT_ARG; +export _OPTS_MANOPT_SHORT_NA; +export _OPTS_MANOPT_LONG_ARG; +export _OPTS_MANOPT_LONG_NA; export _OPTS_CMDLINE_SHORT_NA; export _OPTS_CMDLINE_SHORT_ARG; -export _OPTS_CMDLINE_SHORT; export _OPTS_CMDLINE_LONG_NA; export _OPTS_CMDLINE_LONG_ARG; -export _OPTS_CMDLINE_LONG; - -###### native groffer options +###### groffer native options _OPTS_GROFFER_SHORT_NA="'h' 'Q' 'v' 'V' 'X' 'Z'"; _OPTS_GROFFER_SHORT_ARG="'T'"; -_OPTS_GROFFER_LONG_NA="'all' 'apropos' 'ascii' 'auto' 'default' 'dvi' \ -'groff' 'help' 'intermediate-output' 'local-file' 'location' 'man' \ -'no-location' 'no-man' 'pdf' 'ps' 'rv' 'source' 'tty' 'tty-device' \ -'version' 'whatis' 'where' 'www' 'x'"; - -_OPTS_GROFFER_LONG_ARG="'background' 'bd' 'bg' 'bw' 'default-modes' \ -'device' 'display' 'dvi-viewer' 'extension' 'fg' 'fn' 'font' \ -'foreground' 'geometry' 'locale' 'manpath' 'mode' 'pager' \ -'pdf-viewer' 'ps-viewer' 'resolution' 'sections' 'shell' \ -'systems' 'title' 'troff-device' 'www-viewer' 'xrm' 'x-viewer'"; +_OPTS_GROFFER_LONG_NA="'auto' 'debug' 'default' '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'"; + +_OPTS_GROFFER_LONG_ARG="\ +'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \ +'default-modes' 'dvi-viewer' 'extension' 'fg' 'fn' 'font' \ +'foreground' 'html-viewer' 'mode' 'pdf-viewer' 'ps-viewer' 'shell' \ +'tty-viewer' 'www-viewer' 'x-viewer' 'X-viewer'"; -##### options inhereted from groff +##### groffer options inhereted from groff -_OPTS_GROFF_SHORT_NA="'a' 'b' 'c' 'e' 'g' 'i' 'l' 'p' 's' 't' 'z' \ -'C' 'E' 'G' 'N' 'R' 'S' 'U' 'V'"; +_OPTS_GROFF_SHORT_NA="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \ +'R' 's' 'S' 't' 'U' 'V' 'z'"; _OPTS_GROFF_SHORT_ARG="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \ 'w' 'W'"; -_OPTS_GROFF_LONG_NA=""; -_OPTS_GROFF_LONG_ARG=""; +_OPTS_GROFF_LONG_NA="'source'"; +_OPTS_GROFF_LONG_ARG="'device' 'macro-file'"; -###### man options (for parsing $MANOPT only) +##### groffer options inhereted from the X Window toolkit -_OPTS_MAN_SHORT_NA="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \ -'V' 'w' 'Z'"; -_OPTS_MAN_SHORT_ARG="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'"; +_OPTS_X_SHORT_NA=""; +_OPTS_X_SHORT_ARG=""; + +_OPTS_X_LONG_NA="'iconic' 'rv'"; + +_OPTS_X_LONG_ARG="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \ +'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft', 'geometry' +'resolution' 'title' 'xrm'"; + +###### groffer options inherited from man + +_OPTS_MAN_SHORT_NA=""; +_OPTS_MAN_SHORT_ARG=""; -_OPTS_MAN_LONG_NA="'all' 'ascii' 'apropos' 'catman' 'debug' 'default' \ -'ditroff' 'help' 'local-file' 'location' 'troff' 'update' 'version' \ +_OPTS_MAN_LONG_NA="'all' 'ascii' 'catman' 'debug' 'ditroff' 'help' \ +'local-file' 'location' 'pager' 'troff' 'update' 'version' \ 'whatis' 'where'"; _OPTS_MAN_LONG_ARG="'extension' 'locale' 'manpath' \ 'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'"; -###### collections of options +###### additional options for parsing $MANOPT only -# groffer - -_OPTS_GROFFER_LONG="${_OPTS_GROFFER_LONG_ARG} ${_OPTS_GROFFER_LONG_NA}"; -_OPTS_GROFFER_SHORT=\ -"${_OPTS_GROFFER_SHORT_ARG} ${_OPTS_GROFFER_SHORT_NA}"; +_OPTS_MANOPT_SHORT_NA="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \ +'V' 'w' 'Z'"; +_OPTS_MANOPT_SHORT_ARG="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'"; -# groff +_OPTS_MANOPT_LONG_NA="${_OPTS_MAN_LONG_NA} \ +'apropos' 'debug' 'default' 'html' 'ignore-case' 'location-cat' \ +'match-case' 'troff' 'update' 'version' 'where-cat'"; -_OPTS_GROFF_LONG="${_OPTS_GROFF_LONG_ARG} ${_OPTS_GROFF_LONG_NA}"; -_OPTS_GROFF_SHORT="${_OPTS_GROFF_SHORT_ARG} ${_OPTS_GROFF_SHORT_NA}"; +_OPTS_MANOPT_LONG_ARG="${_OPTS_MAN_LONG_NA} \ +'config_file' 'encoding' 'locale'"; -# all command line options +###### collections of command line options -_OPTS_CMDLINE_SHORT_NA="\ -${_OPTS_GROFFER_SHORT_NA} ${_OPTS_GROFF_SHORT_NA}"; -_OPTS_CMDLINE_SHORT_ARG="\ -${_OPTS_GROFFER_SHORT_ARG} ${_OPTS_GROFF_SHORT_ARG}"; -_OPTS_CMDLINE_SHORT="${_OPTS_GROFFER_SHORT} ${_OPTS_GROFF_SHORT}"; +_OPTS_CMDLINE_SHORT_NA="${_OPTS_GROFFER_SHORT_NA}\ +${_OPTS_GROFF_SHORT_NA} ${_OPTS_X_SHORT_NA} ${_OPTS_MAN_SHORT_NA}"; +_OPTS_CMDLINE_SHORT_ARG="${_OPTS_GROFFER_SHORT_ARG} \ +${_OPTS_GROFF_SHORT_ARG} ${_OPTS_X_SHORT_ARG} ${_OPTS_MAN_SHORT_ARG}"; _OPTS_CMDLINE_LONG_NA="${_OPTS_GROFFER_LONG_NA} \ -${_OPTS_GROFF_LONG_NA} ${_OPTS_MAN_LONG_NA}"; +${_OPTS_GROFF_LONG_NA} ${_OPTS_X_LONG_NA} ${_OPTS_MAN_LONG_NA}"; _OPTS_CMDLINE_LONG_ARG="${_OPTS_GROFFER_LONG_ARG} \ -${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG}"; -_OPTS_CMDLINE_LONG="${_OPTS_GROFFER_LONG} ${_OPTS_GROFF_LONG}"; +${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG} ${_OPTS_X_LONG_ARG}"; ######################################################################## @@ -581,7 +437,10 @@ export _MANOPT_SYS; # $MANOPT --systems # _OPT_* as parsed from groffer command line export _OPT_ALL; # display all suitable man pages. -export _OPT_APROPOS; # branch to `apropos' program. +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. @@ -592,6 +451,7 @@ export _OPT_FG; # set foreground color in some modes. export _OPT_FN; # set font in some modes. export _OPT_GEOMETRY; # set size and position of viewer in X. +export _OPT_ICONIC; # -iconic option for X viewers. export _OPT_LANG; # set language for man pages export _OPT_LOCATION; # print processed file names to stderr export _OPT_MODE; # values: X, tty, Q, Z, "" @@ -602,21 +462,20 @@ export _OPT_SECTIONS; # sections for man page search export _OPT_SYSTEMS; # man pages of different OS's export _OPT_TITLE; # title for gxditview window -export _OPT_TTY_DEVICE; # set device for tty mode. +export _OPT_TEXT_DEVICE; # set device for tty mode. export _OPT_V; # groff option -V. export _OPT_VIEWER_DVI; # viewer program for dvi mode export _OPT_VIEWER_PDF; # viewer program for pdf mode export _OPT_VIEWER_PS; # viewer program for ps mode -export _OPT_VIEWER_WWW; # viewer program for www 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_X; # groff option -X. export _OPT_XRM; # specify X resource. export _OPT_Z; # groff option -Z. # _TMP_* temporary files -export _TMP_DIR; # directory for temporary files +export _TMP_DIR; # groff directory for temporary files +export _TMP_DIR_SUB; # groffer directory for temporary files export _TMP_CAT; # stores concatenation of everything -export _TMP_PREFIX; # dir and base name for temporary files export _TMP_STDIN; # stores stdin, if any # these variables are preset in section `Preset' after the rudim. test @@ -637,7 +496,7 @@ # Test of `echo' and the `$()' construct. # echo -n '' >/dev/null || exit "${_ERROR}"; -if test "$(echo -n 'te' && echo -n '' && echo -n 'st')" != "test"; then +if test _"$(echo -n 'te' && echo -n '' && echo -n 'st')"_ != _test_; then exit "${_ERROR}"; fi; @@ -674,8 +533,8 @@ # _TMP_* temporary files _TMP_DIR=''; +_TMP_DIR_SUB=''; _TMP_CAT=''; -_TMP_PREFIX=''; _TMP_STDIN=''; @@ -723,7 +582,10 @@ # _OPT_* as parsed from groffer command line _OPT_ALL='no'; - _OPT_APROPOS='no'; + _OPT_APROPOS=''; + _OPT_APROPOS_DATA=''; + _OPT_APROPOS_DEVEL=''; + _OPT_APROPOS_PROGS=''; _OPT_BD=''; _OPT_BG=''; _OPT_BW=''; @@ -734,25 +596,25 @@ _OPT_FG=''; _OPT_FN=''; _OPT_GEOMETRY=''; + _OPT_ICONIC='no'; _OPT_LANG=''; _OPT_LOCATION='no'; _OPT_MODE=''; _OPT_MANPATH=''; _OPT_PAGER=''; _OPT_RESOLUTION=''; - _OPT_RV=''; + _OPT_RV='no'; _OPT_SECTIONS=''; _OPT_SYSTEMS=''; _OPT_TITLE=''; - _OPT_TTY_DEVICE=''; + _OPT_TEXT_DEVICE=''; _OPT_V='no'; _OPT_VIEWER_DVI=''; _OPT_VIEWER_PDF=''; _OPT_VIEWER_PS=''; - _OPT_VIEWER_WWW=''; + _OPT_VIEWER_HTML=''; _OPT_VIEWER_X=''; _OPT_WHATIS='no'; - _OPT_X='no'; _OPT_XRM=''; _OPT_Z='no'; @@ -775,7 +637,7 @@ # landmark() { - if test "${_DEBUG_LM}" = 'yes'; then + if test _"${_DEBUG_LM}"_ = _yes_; then echo ">>> $*" >&2; fi; } @@ -790,19 +652,10 @@ # clean_up() { - clean_up_secondary; - rm -f "${_TMP_CAT}"; -} - - -############## -# clean_up_secondary () -# -# Clean up temporary files without $_TMP_CAT. -# -clean_up_secondary() -{ - rm -f "${_TMP_STDIN}"; + if test -d "${_TMP_DIR}"; then + rm -f "${_TMP_DIR}"/*; + rmdir "${_TMP_DIR}"; + fi; } @@ -862,7 +715,7 @@ ;; *) echo2 'groffer error: wrong number of arguments in error().'; ;; esac; - if test "${_DEBUG}" = 'yes'; then + if test _"${_DEBUG}"_ = _yes_; then func_stack_dump; fi; clean_up; @@ -956,7 +809,7 @@ error \ "${_fname}"'() needs '"${_comp} ${_nargs}"' argument'"${_s}"'.'; fi; - if test "${_DEBUG}" = 'yes'; then + if test _"${_DEBUG}"_ = _yes_; then func_push "${_fname} $*"; fi; } @@ -975,7 +828,7 @@ # func_pop() { - if test "${_DEBUG}" = 'yes'; then + if test _"${_DEBUG}"_ = _yes_; then if test "$#" -ne 0; then error 'func_pop() does not have arguments.'; fi; @@ -1009,7 +862,7 @@ func_push() { local _element; - if test "${_DEBUG}" = 'yes'; then + if test _"${_DEBUG}"_ = _yes_; then if test "$#" -ne 1; then error 'func_push() needs 1 argument.'; fi; @@ -1022,7 +875,7 @@ _element="$1"; ;; esac; - if test "${_FUNC_STACK}" = ''; then + if test _"${_FUNC_STACK}"_ = __; then _FUNC_STACK="${_element}"; else _FUNC_STACK="${_element}!${_FUNC_STACK}"; @@ -1042,11 +895,11 @@ case "${_FUNC_STACK}" in *!*) _rest="${_FUNC_STACK}"; - while test "${_rest}" != ''; do + while test _"${_rest}"_ != __; do # get part before the first bang `!'. - diag "$(echo -n "${_rest}" | sed -e 's/^\([^!]*\)!.*$/\1/')"; - # delete part up to the first bang `!'. - _rest="$(echo -n "${_rest}" | sed -e 's/^!*[^!]*!*//')"; + diag "$(echo -n "${_rest}" | sed -e 's/!.*$//')"; + # delete part before and including the first bang `!'. + _rest="$(echo -n "${_rest}" | sed -e 's/^[^!]*!//')"; done; ;; *) @@ -1087,7 +940,7 @@ # Test of `unset'. # _test='test'; -if unset _test >/dev/null 2>&1 && test "${_test}" = ''; then +if unset _test >/dev/null 2>&1 && test _"${_test}"_ = __; then true; else unset() @@ -1113,7 +966,7 @@ else local() { - if test "$1" != ''; then + if test _"$1"_ != __; then error "overriding global variable \`$1' with local value."; fi; } @@ -1134,7 +987,7 @@ } _t_e_s_t_f_u_n_c_; -if test "${_global}" != 'inside' || test "${_clobber}" != 'outside'; +if test _"${_global}"_ != _inside_ || test _"${_clobber}"_ != _outside_; then error "Cannot assign to global variables from within functions."; fi; @@ -1146,9 +999,10 @@ ######################################################################## # Test of function `sed'. # -if test "$(echo xTesTx \ + +if test _"$(echo xTesTx \ | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \ - | sed -e '\|T|s||t|g')" != 'test'; + | sed -e '\|T|s|T|t|g')"_ != _test_; then error 'Test of "sed" command failed.'; fi; @@ -1157,7 +1011,7 @@ ######################################################################## # Test of function `cat'. # -if test "$(echo test | cat)" != "test"; then +if test _"$(echo test | cat)"_ != _test_; then error 'Test of "cat" command failed.'; fi; @@ -1165,12 +1019,12 @@ ######################################################################## # Test for compression. # -if test "$(echo 'test' | gzip -c -d -f - 2>/dev/null)" = 'test'; then +if test _"$(echo 'test' | gzip -c -d -f - 2>/dev/null)"_ = _test_; then _HAS_COMPRESSION='yes'; if echo 'test' | bzip2 -c 2>/dev/null | bzip2 -t 2>/dev/null \ - && test "$(echo 'test' | bzip2 -c 2>/dev/null \ - | bzip2 -d -c 2>/dev/null)" \ - = 'test'; then + && test _"$(echo 'test' | bzip2 -c 2>/dev/null \ + | bzip2 -d -c 2>/dev/null)"_ \ + = _test_; then _HAS_BZIP='yes'; else _HAS_BZIP='no'; @@ -1203,10 +1057,27 @@ ######################################################################## +# apropos_run () +# +# +apropos_run() { + func_check apropos_run = 1 "$@"; + if apropos apropos >/dev/null 2>/dev/null; then + apropos "$1"; + elif man --apropos man >/dev/null 2>/dev/null; then + man --apropos "$1"; + elif man -k man >/dev/null 2>/dev/null; then + man -k "$1"; + fi; +} + + +######################################################################## # base_name () # # Get the file name part of , i.e. delete everything up to last -# `/' from the beginning of . +# `/' from the beginning of . Remove final slashes, too, to get a +# non-empty output. # # Arguments : 1 # Output : the file name part (without slashes) @@ -1214,16 +1085,24 @@ base_name() { func_check base_name = 1 "$@"; - case "$1" in + local f; + f="$1"; + case "$f" in */) - do_nothing; + # delete all final slashes + f="$(echo -n "$f" | sed -e '\|.*|s|//*$||')"; + ;; + esac; + case "$f" in + /|'') + eval "${return_bad}"; ;; */*) - # delete everything up to last slash `/'. - echo -n "$1" | sed -e '\|^.*/*\([^/]*\)$|s||\1|'; + # delete everything before and including the last slash `/'. + echo -n "$f" | sed -e '\|.*|s|^.*//*\([^/]*\)$|\1|'; ;; *) - echo -n "$1"; + echo -n "$f"; ;; esac; eval "${return_ok}"; @@ -1240,7 +1119,7 @@ # Arguments: 1, a file name. # Output: the content of , possibly decompressed. # -if test "${_HAS_COMPRESSION}" = 'yes'; then +if test _"${_HAS_COMPRESSION}"_ = _yes_; then catz() { func_check catz = 1 "$@"; @@ -1252,7 +1131,7 @@ error 'catz(): for standard input use save_stdin()'; ;; esac; - if is_yes "${_HAS_BZIP}"; then + if obj _HAS_BZIP is_yes; then if bzip2 -t "$1" 2>/dev/null; then bzip2 -c -d "$1" 2>/dev/null; eval "${return_ok}"; @@ -1280,14 +1159,6 @@ ######################################################################## -# clean_up_secondary () -# -# Do the second but final cleaning up. -# -# defined above - - -######################################################################## # diag (*) # # Print marked message to standard error; useful for debugging. @@ -1338,11 +1209,11 @@ local _res; local _sep; # replace all multiple slashes by a single slash `/'. - _res="$(echo -n "$1" | sed -e '\|///*|s||/|g')"; + _res="$(echo -n "$1" | sed -e '\|.*|s|///*|/|g')"; case "${_res}" in ?*/) # remove trailing slash '/'; - echo -n "${_res}" | sed -e '\|/$|s|||'; + echo -n "${_res}" | sed -e '\|.*|s|/$||'; ;; *) echo -n "${_res}"; ;; esac; @@ -1390,8 +1261,8 @@ set -- 'File'; ;; *) - if is_yes "${_MAN_ENABLE}"; then - if is_yes "${_MAN_FORCE}"; then + if obj _MAN_ENABLE is_yes; then + if obj _MAN_FORCE is_yes; then set -- 'Manpage' 'File'; else set -- 'File' 'Manpage'; @@ -1417,7 +1288,7 @@ fi; ;; Manpage) # parse filespec as man page - if is_not_yes "${_MAN_IS_SETUP}"; then + if obj _MAN_IS_SETUP is_not_yes; then man_setup; fi; if man_do_filespec "${_filespec}"; then @@ -1516,11 +1387,11 @@ { func_check get_first_essential '>=' 0 "$@"; local i; - if test "$#" -eq 0; then + if is_equal "$#" 0; then eval "${return_ok}"; fi; for i in "$@"; do - if is_not_empty "$i"; then + if obj i is_not_empty; then echo -n "$i"; eval "${return_ok}"; fi; @@ -1544,12 +1415,10 @@ is_dir() { func_check is_dir = 1 "$@"; - if is_not_empty "$1" && test -d "$1" && test -r "$1"; then + if test -d "$1" && test -r "$1"; then eval "${return_yes}"; - else - eval "${return_no}"; fi; - eval "${return_ok}"; + eval "${return_no}"; } @@ -1564,12 +1433,10 @@ is_empty() { func_check is_empty = 1 "$@"; - if test -z "$1"; then + if test _"$1"_ = __; then eval "${return_yes}"; - else - eval "${return_no}"; fi; - eval "${return_ok}"; + eval "${return_no}"; } @@ -1584,12 +1451,10 @@ is_equal() { func_check is_equal = 2 "$@"; - if test "$1" = "$2"; then + if test _"$1"_ = _"$2"_; then eval "${return_yes}"; - else - eval "${return_no}"; fi; - eval "${return_ok}"; + eval "${return_no}"; } @@ -1604,12 +1469,32 @@ is_file() { func_check is_file = 1 "$@"; - if is_not_empty "$1" && test -f "$1" && test -r "$1"; then + if test -f "$1" && test -r "$1"; then eval "${return_yes}"; - else - eval "${return_no}"; fi; - eval "${return_ok}"; + eval "${return_no}"; +} + + +######################################################################## +# is_non_empty_file () +# +# Test whether `file_name' is a non-empty existing file. +# +# Arguments : <=1 +# Return : +# `0' if arg1 is a non-empty existing file +# `1' otherwise +# +is_non_empty_file() +{ + func_check is_empty = 1 "$@"; + if is_file "$1"; then + if is_not_empty "$(cat "$1" | sed -e '/./q')"; then + eval "${return_yes}"; + fi; + fi; + eval "${return_no}"; } @@ -1626,10 +1511,8 @@ func_check is_not_dir = 1 "$@"; if is_dir "$1"; then eval "${return_no}"; - else - eval "${return_yes}"; fi; - eval "${return_ok}"; + eval "${return_yes}"; } @@ -1646,17 +1529,15 @@ func_check is_not_empty = 1 "$@"; if is_empty "$1"; then eval "${return_no}"; - else - eval "${return_yes}"; fi; - eval "${return_ok}"; + eval "${return_yes}"; } ######################################################################## # is_not_equal ( ) # -# Test whether `string1' and differ. +# Test whether `string1' differs from `string2'. # # Arguments : 2 # @@ -1665,10 +1546,8 @@ func_check is_not_equal = 2 "$@"; if is_equal "$1" "$2"; then eval "${return_no}"; - else - eval "${return_yes}"; - fi; - eval "${return_ok}"; + fi + eval "${return_yes}"; } @@ -1684,10 +1563,8 @@ func_check is_not_file '>=' 1 "$@"; if is_file "$1"; then eval "${return_no}"; - else - eval "${return_yes}"; fi; - eval "${return_ok}"; + eval "${return_yes}"; } @@ -1704,10 +1581,25 @@ func_check is_not_prog '>=' 1 "$@"; if where "$1" >/dev/null; then eval "${return_no}"; - else - eval "${return_yes}"; fi; - eval "${return_ok}"; + eval "${return_yes}"; +} + + +######################################################################## +# is_not_writable () +# +# Test whether `name' is a not a writable file or directory. +# +# Arguments : >=1 (empty allowed), more args are ignored +# +is_not_writable() +{ + func_check is_not_writable '>=' 1 "$@"; + if is_writable "$1"; then + eval "${return_no}"; + fi; + eval "${return_yes}"; } @@ -1721,12 +1613,10 @@ is_not_yes() { func_check is_not_yes = 1 "$@"; - if test "$1" = 'yes'; then + if is_yes "$1"; then eval "${return_no}"; - else - eval "${return_yes}"; fi; - eval "${return_ok}"; + eval "${return_yes}"; } @@ -1735,18 +1625,42 @@ # # Determine whether arg is a program in $PATH # -# Arguments : >=1 (empty allowed) +# Arguments : >=0 (empty allowed) # more args are ignored, this allows to specify progs with arguments # is_prog() { - func_check is_prog '>=' 1 "$@"; - if where "$1" >/dev/null; then - eval "${return_yes}"; - else + func_check is_prog '>=' 0 "$@"; + case "$#" in + 0) eval "${return_no}"; + ;; + *) + if where "$1" >/dev/null; then + eval "${return_yes}"; + fi; + ;; + esac + eval "${return_no}"; +} + + +######################################################################## +# is_writable () +# +# Test whether `name' is a writable file or directory. +# +# Arguments : >=1 (empty allowed), more args are ignored +# +is_writable() +{ + func_check is_writable '>=' 1 "$@"; + if test -r "$1"; then + if test -w "$1"; then + eval "${return_yes}"; + fi; fi; - eval "${return_ok}"; + eval "${return_no}"; } @@ -1761,12 +1675,10 @@ is_yes() { func_check is_yes = 1 "$@"; - if test "$1" = 'yes'; then + if is_equal "$1" 'yes'; then eval "${return_yes}"; - else - eval "${return_no}"; fi; - eval "${return_ok}"; + eval "${return_no}"; } @@ -1795,138 +1707,61 @@ ######################################################################## landmark '6: list_*()'; ######################################################################## +# +# `list' is an object class that represents an array or list. Its +# data consists of space-separated single-quoted elements. So a list +# has the form "'first' 'second' '...' 'last'". See list_append() for +# more details on the list structure. The array elements of `list' +# can be get by `set -- $list`. + ######################################################################## # list_append ( ...) # # Arguments: >=2 -# : a space-separated list of single-quoted elements. -# : some sequence of characters. -# Output: +# : a variable name for a list of single-quoted elements +# : some sequence of characters. +# Output: none, but $ is set to # if is empty: "'' '...'" -# otherwise: " '' ..." +# otherwise: "$list '' ..." # list_append() { func_check list_append '>=' 2 "$@"; local _element; - local _res; - _res="$1"; + local _list; + local _name; + _name="$1"; + eval _list='"${'$1'}"'; shift; for s in "$@"; do case "$s" in - *\'*) - # escape each single quote by replacing each "'" (squote) - # by "'\''" (squote bslash squote squote); - # note that the backslash must be doubled for `sed'. - _element="$(echo -n "$s" | sed -e 's/'"${_SQUOTE}"'/&\\&&/g')"; - ;; - *) - _element="$s"; - ;; - esac; - _res="${_res} '${_element}'"; - done; - echo -n "${_res}"; - eval "${return_ok}"; -} - - -######################################################################## -# list_check () -# -# Check whether is a space-separated list of '-quoted elements. -# -# If the test fails an error is raised. -# If the test succeeds the argument is echoed. -# -# Testing criteria: -# A list has the form "'first' 'second' '...' 'last'". -# So it has a leading and a final quote and the elements are separated -# by "' '" constructs. If these are all removed there should not be -# any single-quotes left. Watch out for escaped single quotes; they -# have the form '\'' (sq bs sq sq). -# -# Arguments: 1 -# Output: the argument unchanged, it the check succeeded. -# -list_check() -{ - func_check list_check = 1 "$@"; - local _list; - if is_empty "$1"; then - eval "${return_ok}"; - fi; - case "$1" in - \'*\') _list="$1"; ;; - *) - error "list_check() bad list: $1" + *\'*) + # escape each single quote by replacing each + # "'" (squote) by "'\''" (squote bslash squote squote); + # note that the backslash must be doubled in the following `sed' + _element="$(echo -n "$s" | sed -e 's/'"${_SQUOTE}"'/&\\&&/g')"; ;; - esac; - # Remove leading single quote, - # remove final single quote, - # remove escaped single quotes (squote bslash squote squote) - # [note that `sed' doubles the backslash (bslash bslash)], - # remove field separators (squote space squote). - _list="$(echo -n "${_list}" \ - | sed -e 's/^'"${_SQUOTE}"'//' \ - | sed -e 's/'"${_SQUOTE}"'$//' \ - | sed -e \ - 's/'"${_SQUOTE}${_BSLASH}${_BSLASH}${_SQUOTE}${_SQUOTE}"'//g' \ - | sed -e 's/'"${_SQUOTE}${_SPACE}${_SPACE}"'*'"${_SQUOTE}"'//g')"; - case "${_list}" in - *\'*) # criterium fails if squote is left - error 'list_check() bad list: '"${_list}"; + '') + _element=""; ;; - esac; - echo -n "$1"; - eval "${return_ok}"; -} - - -######################################################################## -# list_element_from_arg () -# -# Arguments: 1 -# : some sequence of characters (also single quotes allowed). -# Output: the list element generated from . -# -list_element_from_arg() -{ - func_check list_element_from_arg = 1 "$@"; - local _res; - echo -n "'"; - # replace each single quote "'" by "'\''". - echo -n "$1" | sed -e 's/'\''/&\\&&/g'; # ' for emacs - echo -n "'"; - eval "${return_ok}"; -} - - -######################################################################## -# list_from_args (...) -# -# Generate a space-separated list of single-quoted elements from args. -# -# Arguments: -# : some sequence of characters. -# Output: "'' '...'" -# -list_from_args() -{ - func_check list_from_args '>=' 1 "$@"; - local _list; - _list=""; - for s in "$@"; do - _list="$(list_append "${_list}" "$s")"; + *) + _element="$s"; + ;; + esac; + if obj _list is_empty; then + _list="'${_element}'"; + else + _list="${_list} '${_element}'"; + fi; done; - echo -n "${_list}"; + eval "${_name}"='"${_list}"'; eval "${return_ok}"; } ######################################################################## -# list_from_cmdline ( [...]) +# list_from_cmdline ( [...]) # # Transform command line arguments into a normalized form. # @@ -1934,30 +1769,25 @@ # output each as a single-quoted argument of its own. Options and # file parameters are separated by a '--' argument. # -# Arguments: >=4 -# : space-separated list of short options without an arg. -# : space-separated list of short options that have an arg. -# : space-separated list of long options without an arg. -# : space-separated list of long options that have an arg. -# ...: the arguments from the command line (by "$@"). -# -# Globals: $POSIXLY_CORRECT (only kept for compatibility). +# Arguments: >=1 +# : common part of a set of 4 environment variable names: +# $_SHORT_NA: list of short options without an arg. +# $_SHORT_ARG: list of short options that have an arg. +# $_LONG_NA: list of long options without an arg. +# $_LONG_ARG: list of long options that have an arg. +# ...: the arguments from a command line, such as "$@", +# the content of a variable, or direct arguments. # # Output: ['-[-]opt' ['optarg']]... '--' ['filename']... # # Example: -# list_normalize 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2 -# will result in printing: +# list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2 +# If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are +# none-empty option lists, this will result in printing: # '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2' -# If $POSIXLY_CORRECT is not empty, the result will be: -# '-a' '--' 'f1' '-bcarg' '--long=larg' 'f2' # -# Rationale: -# In POSIX, the first non-option ends the option processing. -# In GNU mode (default), non-options are sorted behind the options. -# -# Use this function only in the following way: -# eval set -- "$(args_norm '...' '...' '...' '...' "$@")"; +# Use this function in the following way: +# eval set -- "$(args_norm PRE_NAME "$@")"; # while test "$1" != '--'; do # case "$1" in # ... @@ -1969,21 +1799,33 @@ # list_from_cmdline() { - func_check list_from_cmdline '>=' 4 "$@"; + func_check list_from_cmdline '>=' 1 "$@"; local _fparams; local _fn; - local _result; - local _long_a; - local _long_n; local _short_a; local _short_n; - _short_n="$(list_check "$1")"; # short options, no argument - _short_a="$(list_check "$2")"; # short options with argument - _long_n="$(list_check "$3")"; # long options, no argument - _long_a="$(list_check "$4")"; # long options with argument - shift 4; + local _long_a; + local _long_n; + local _result; + _short_n="$(obj_data "$1"_SHORT_NA)"; # short options, no argument + _short_a="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument + _long_n="$(obj_data "$1"_LONG_NA)"; # long options, no argument + _long_a="$(obj_data "$1"_LONG_ARG)"; # long options, with argument + if obj _short_n is_empty; then + error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.'; + fi; + if obj _short_a is_empty; then + error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.'; + fi; + if obj _long_n is_empty; then + error 'list_from_cmdline(): no $'"$1"'_LONG_NA options.'; + fi; + if obj _long_a is_empty; then + error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.'; + fi; + shift; _fn='list_from_cmdline():'; # for error messages - if test "$#" -eq 0; then + if is_equal "$#" 0; then echo -n "'--'"; eval "${return_ok}"; fi; @@ -1997,63 +1839,48 @@ --?*) # delete leading '--'; _opt="$(echo -n "${_arg}" | sed -e 's/^..//')"; - if list_has "${_long_n}" "${_opt}"; then + if list_has _long_n "${_opt}"; then # long option, no argument - _result="$(list_append "${_result}" "--${_opt}")"; - continue; - fi; - if list_has "${_long_a}" "${_opt}"; then - # long option with argument - _result="$(list_append "${_result}" "--${_opt}")"; - if test "$#" -le 0; then - error "${_fn} no argument for option --${_opt}." - fi; - _result="$(list_append "${_result}" "$1")"; - shift; + list_append _result "--${_opt}"; continue; fi; # test on `--opt=arg' if string_contains "${_opt}" '='; then # extract option by deleting from the first '=' to the end _lopt="$(echo -n "${_opt}" | sed -e 's/=.*$//')"; - if list_has "${_long_a}" "${_lopt}"; then + if list_has _long_a "${_lopt}"; then # get the option argument by deleting up to first `=' _optarg="$(echo -n "${_opt}" | sed -e 's/^[^=]*=//')"; - _result="$(list_append "${_result}" \ - "--${_lopt}" "${_optarg}")"; + list_append _result "--${_lopt}" "${_optarg}"; continue; fi; fi; + if list_has _long_a "${_opt}"; then + # long option with argument + if test "$#" -le 0; then + error "${_fn} no argument for option --${_opt}." + fi; + list_append _result "--${_opt}" "$1"; + shift; + continue; + fi; error "${_fn} --${_opt} is not an option." ;; -?*) # short option (cluster) # delete leading `-'; - _rest="$(echo -n "${_arg}" | sed -e 's/^.//')"; - while is_not_empty "${_rest}"; do + _rest="$(echo -n "${_arg}" | sed -e 's/^-//')"; + while obj _rest is_not_empty; do # get next short option from cluster (first char of $_rest) _optchar="$(echo -n "${_rest}" | sed -e 's/^\(.\).*$/\1/')"; # remove first character from ${_rest}; - _rest="$(echo -n "${_rest}" | 's/^.//')"; - if list_has "${_short_n}" "${_optchar}"; then - _result="$(list_append "${_result}" "-${_optchar}")"; + _rest="$(echo -n "${_rest}" | sed -e 's/^.//')"; + if list_has _short_n "${_optchar}"; then + list_append _result "-${_optchar}"; continue; - elif list_has "${_short_a}" "${_optchar}"; then - # remove leading character - case "${_optchar}" in - /) # cannot use normal `sed' separator - _rest="$(echo -n "${_rest}" | sed -e '\|^.|s|||')"; - ;; - ?) - _rest="$(echo -n "${_rest}" | sed -e 's/^.//')"; - ;; - *) - error "${_fn} several chars parsed for short option." - ;; - esac; - if is_empty "${_rest}"; then + elif list_has _short_a "${_optchar}"; then + if obj _rest is_empty; then if test "$#" -ge 1; then - _result="$(list_append "${_result}" \ - "-${_optchar}" "$1")"; + list_append _result "-${_optchar}" "$1"; shift; continue; else @@ -2061,8 +1888,7 @@ "${_fn}"' no argument for option -'"${_optchar}." fi; else # rest is the argument - _result="$(list_append "${_result}" \ - "-${_optchar}" "${_rest}")"; + list_append _result "-${_optchar}" "${_rest}"; _rest=''; continue; fi; @@ -2073,22 +1899,21 @@ ;; *) # Here, $_arg is not an option, so a file parameter. - # When $POSIXLY_CORRECT is set this ends option parsing; - # otherwise, the argument is stored as a file parameter and - # option processing is continued. - _fparams="$(list_append "${_fparams}" "${_arg}")"; - if is_not_empty "$POSIXLY_CORRECT"; then - break; - fi; + list_append _fparams "${_arg}"; + + # Ignore the strange option handling of $POSIXLY_CORRECT to + # end option parsing after the first file name argument. To + # reuse it, do a `break' here if $POSIXLY_CORRECT is + # non-empty. ;; esac; done; - _result="$(list_append "${_result}" '--')"; - if is_not_empty "${_fparams}"; then + list_append _result '--'; + if obj _fparams is_not_empty; then _result="${_result} ${_fparams}"; fi; if test "$#" -gt 0; then - _result="$(list_append "${_result}" "$@")"; + list_append _result "$@"; fi; echo -n "$_result"; eval "${return_ok}"; @@ -2096,30 +1921,14 @@ ######################################################################## -# list_from_lists ( ...) -# -# Generate a list from the concatenation of the lists in the arguments. -# -# Arguments: >=2 -# : string of space-separated single-quoted elements. -# Output: "'' ..." -# -list_from_lists() -{ - func_check list_from_lists '>=' 2 "$@"; - _list=''; - echo -n "$*"; - eval "${return_ok}"; -} - -######################################################################## # list_from_split ( ) # -# In escape white space and replace each by space. +# In , escape all white space characters and replace each +# by space. # # Arguments: 2: a that is to be split into parts divided by # -# Output: the resulting string +# Output: the resulting list string # list_from_split() { @@ -2132,7 +1941,7 @@ # replace split character of string by the list separator ` ' (space). case "$2" in /) # cannot use normal `sed' separator - echo -n "${_s}" | sed -e '\|'"$2"'|s|| |g'; + echo -n "${_s}" | sed -e '\|.*|s|'"$2"'| |g'; ;; ?) # use normal `sed' separator echo -n "${_s}" | sed -e 's/'"$2"'/ /g'; @@ -2146,22 +1955,65 @@ ######################################################################## -# list_has ( ) +# list_get () +# +# Check whether is a space-separated list of '-quoted elements. +# +# If the test fails an error is raised. +# If the test succeeds the argument is echoed. +# +# Testing criteria: +# A list has the form "'first' 'second' '...' 'last'". So it has a +# leading and a final quote and the elements are separated by "' '" +# constructs. If these are all removed there should not be any +# unescaped single-quotes left. Watch out for escaped single +# quotes; they have the form '\'' (sq bs sq sq). + +# Arguments: 1 +# Output: the argument unchanged, if the check succeeded. +# +list_get() +{ + func_check list_get = 1 "$@"; + local _list; + eval _list='"${'$1'}"'; + # remove leading and final space characters + _list="$(echo -n "${_list}" | \ + sed -e 's/^['"${_SPACE}${_TAB}"']*//' | \ + sed -e 's/['"${_SPACE}${_TAB}"']*$//')"; + case "${_list}" in + '') + eval "${return_ok}"; + ;; + \'*\') + echo -n "${_list}"; + eval "${return_ok}"; + ;; + *) + error "list_get(): bad list: $1" + ;; + esac; + eval "${return_ok}"; +} + + +######################################################################## +# list_has ( ) # # Arguments: 2 -# : a space-separated list of single-quoted elements. -# : some sequence of characters. +# : a variable name for a list of single-quoted elements +# : some sequence of characters. # Output: # if is empty: "'' '...'" -# otherwise: " '' ..." +# otherwise: "list '' ..." # list_has() { func_check list_has = 2 "$@"; - if is_empty "$1"; then + eval _list='"${'$1'}"'; + if obj _list is_empty; then eval "${return_no}"; fi; - _list="$1"; _element="$2"; case "$2" in \'*\') _element="$2"; ;; @@ -2189,64 +2041,20 @@ list_has_not() { func_check list_has_not = 2 "$@"; - if is_empty "$1"; then - eval "${return_yes}"; - fi; - _list="$1"; - _element="$2"; - case "$2" in - \'*\') _element="$2"; ;; - *) _element="'$2'"; ;; - esac; - if string_contains "${_list}" "${_element}"; then - eval "${return_no}"; - else - eval "${return_yes}"; - fi; - eval "${return_ok}"; -} - - -######################################################################## -# list_length () -# -# Arguments: 1 -# : a space-separated list of single-quoted elements. -# Output: the number of elements in -# -list_length() -{ - func_check list_length = 1 "$@"; - eval set -- "$1"; - echo -n "$#"; - eval "${return_ok}"; -} - - -######################################################################## -# list_prepend ( ...) -# -# Insert new at the beginning of -# -# Arguments: >=2 -# : a space-separated list of single-quoted elements. -# : some sequence of characters. -# Output: -# if is empty: "'' ..." -# otherwise: "'' ... " -# -list_prepend() -{ - func_check list_prepend '>=' 2 "$@"; - local _res; - _res="$1"; - shift; - for s in "$@"; do - # escape single quotes in list style (squote bslash squote squote). - _element="$(echo -n "$s" | sed -e 's/'\''/&\\&&/g')"; - _res="'${_element}' ${_res}"; - done; - echo -n "${_res}"; + eval _list='"${'$1'}"'; + if obj _list is_empty; then + eval "${return_yes}"; + fi; + _element="$2"; + case "$2" in + \'*\') _element="$2"; ;; + *) _element="'$2'"; ;; + esac; + if string_contains "${_list}" "${_element}"; then + eval "${return_no}"; + else + eval "${return_yes}"; + fi; eval "${return_ok}"; } @@ -2283,7 +2091,7 @@ local _spec; local _string; local s; - if is_empty "${MANPATH}"; then + if obj _MAN_PATH is_empty; then eval "${return_bad}"; fi; if is_empty "$1"; then @@ -2302,11 +2110,11 @@ _section="$(echo -n "${_spec}" \ | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')"; ;; - man:?*.?*) # man:name.section + man:?*.[0-9on]) # man:name.section _name="$(echo -n "${_spec}" \ - | sed -e 's/^man:\(..*\)\.\(..*\)$/\1/')"; + | sed -e 's/^man:\(..*\)\..$/\1/')"; _section="$(echo -n "${_spec}" \ - | sed -e 's/^man:\(..*\)\.\(..*\)$/\2/')"; + | sed -e 's/^.*\(.\)$/\1/')"; ;; man:?*) # man:name _name="$(echo -n "${_spec}" | sed -e 's/^man://')"; @@ -2317,25 +2125,25 @@ _section="$(echo -n "${_spec}" \ | sed -e 's/^\(..*\)(\(..*\))$/\2/')"; ;; - ?*.?*) # name.section + ?*.[0-9on]) # name.section _name="$(echo -n "${_spec}" \ - | sed -e 's/^\(..*\)\.\(..*\)$/\1/')"; + | sed -e 's/^\(..*\)\..$/\1/')"; _section="$(echo -n "${_spec}" \ - | sed -e 's/^\(..*\)\.\(..*\)$/\2/')"; + | sed -e 's/^.*\(.\)$/\1/')"; ;; ?*) _name="${_filespec}"; ;; esac; - if is_empty "${_name}"; then + if obj _name is_empty; then eval "${return_bad}"; fi; _got_one='no'; - if is_empty "${_section}"; then + if obj _section is_empty; then eval set -- "${_MAN_AUTO_SEC}"; for s in "$@"; do if man_search_section "${_name}" "$s"; then # found - if is_yes "${_MAN_ALL}"; then + if obj _MAN_ALL is_yes; then _got_one='yes'; else eval "${return_good}"; @@ -2349,7 +2157,7 @@ eval "${return_bad}"; fi; fi; - if is_yes "${_MAN_ALL}" && is_yes "${_got_one}"; then + if obj _MAN_ALL is_yes && is_yes "${_got_one}"; then eval "${return_good}"; fi; eval "${return_bad}"; @@ -2383,7 +2191,7 @@ eval "${return_ok}"; ;; 3) - register_title "$2($3)"; + register_title "$2.$3"; eval "${return_ok}"; ;; esac; @@ -2411,7 +2219,7 @@ local _section; local d; local f; - if is_empty "${_MAN_PATH}"; then + if obj _MAN_PATH is_empty; then eval "${return_bad}"; fi; if is_empty "$1"; then @@ -2424,16 +2232,16 @@ _section="$2"; eval set -- "$(path_split "${_MAN_PATH}")"; _got_one='no'; - if is_empty "${_MAN_EXT}"; then + if obj _MAN_EXT is_empty; then for d in "$@"; do _dir="$(dirname_append "$d" "man${_section}")"; - if is_dir "${_dir}"; then + if obj _dir is_dir; then _prefix="$(dirname_append "${_dir}" "${_name}.${_section}")"; for f in $(echo -n ${_prefix}*); do - if is_file "$f"; then + if obj f is_file; then if is_yes "${_got_one}"; then register_file "$f"; - elif is_yes "${_MAN_ALL}"; then + elif obj _MAN_ALL is_yes; then man_register_file "$f" "${_name}"; else man_register_file "$f" "${_name}" "${_section}"; @@ -2449,13 +2257,13 @@ # check for directory name having trailing extension for d in "$@"; do _dir="$(dirname_append $d man${_section}${_ext})"; - if is_dir "${_dir}"; then + if obj _dir is_dir; then _prefix="$(dirname_append "${_dir}" "${_name}.${_section}")"; for f in ${_prefix}*; do - if is_file "$f"; then + if obj f is_file; then if is_yes "${_got_one}"; then register_file "$f"; - elif is_yes "${_MAN_ALL}"; then + elif obj _MAN_ALL is_yes; then man_register_file "$f" "${_name}"; else man_register_file "$f" "${_name}" "${_section}"; @@ -2469,14 +2277,14 @@ # check for files with extension in directories without extension for d in "$@"; do _dir="$(dirname_append "$d" "man${_section}")"; - if is_dir "${_dir}"; then + if obj _dir is_dir; then _prefix="$(dirname_append "${_dir}" \ "${_name}.${_section}${_ext}")"; for f in ${_prefix}*; do - if is_file "$f"; then + if obj f is_file; then if is_yes "${_got_one}"; then register_file "$f"; - elif is_yes "${_MAN_ALL}"; then + elif obj _MAN_ALL is_yes; then man_register_file "$f" "${_name}"; else man_register_file "$f" "${_name}" "${_section}"; @@ -2488,7 +2296,7 @@ fi; done; fi; - if is_yes "${_MAN_ALL}" && is_yes "${_got_one}"; then + if obj _MAN_ALL is_yes && is_yes "${_got_one}"; then eval "${return_good}"; fi; eval "${return_bad}"; @@ -2522,35 +2330,35 @@ func_check main_man_setup = 0 "$@"; local _lang; - if is_yes "${_MAN_IS_SETUP}"; then + if obj _MAN_IS_SETUP is_yes; then eval "${return_ok}"; fi; _MAN_IS_SETUP='yes'; - if is_not_yes "${_MAN_ENABLE}"; then + if obj _MAN_ENABLE is_not_yes; then eval "${return_ok}"; fi; # determine basic path for man pages _MAN_PATH="$(get_first_essential \ "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")"; - if is_empty "${_MAN_PATH}"; then - if is_prog 'manpath'; then - _MAN_PATH="$(manpath 2>/dev/null)"; # not always available - fi; - fi; - if is_empty "${_MAN_PATH}"; then + if obj _MAN_PATH is_empty; then manpath_set_from_path; else _MAN_PATH="$(path_clean "${_MAN_PATH}")"; fi; - if is_empty "${_MAN_PATH}"; then + if obj _MAN_PATH is_empty; then + if is_prog 'manpath'; then + _MAN_PATH="$(manpath 2>/dev/null)"; # not always available + fi; + fi; + if obj _MAN_PATH is_empty; then _MAN_ENABLE="no"; eval "${return_ok}"; fi; _MAN_ALL="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")"; - if is_empty "${_MAN_ALL}"; then + if obj _MAN_ALL is_empty; then _MAN_ALL='no'; fi; @@ -2579,7 +2387,7 @@ _MAN_SEC="$(get_first_essential \ "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")"; - if is_empty "${_MAN_PATH}"; then + if obj _MAN_PATH is_empty; then _MAN_ENABLE="no"; eval "${return_ok}"; fi; @@ -2613,7 +2421,7 @@ func_check manpath_add_lang_sys = 0 "$@"; local p; local _mp; - if is_empty "${_MAN_PATH}"; then + if obj _MAN_PATH is_empty; then eval "${return_ok}"; fi; # twice test both sys and lang @@ -2640,16 +2448,14 @@ # argument: 2: `man_path' and `dir' # output: colon-separated path of the retrieved subdirectories # + func_check _manpath_add_lang_sys_single = 2 "$@"; local d; -# if test "$#" -ne 2; then -# error "manpath_add_system_single() needs 2 arguments."; -# fi; _res="$1"; _parent="$2"; eval set -- "$(list_from_split "${_MAN_SYS}" ',')"; for d in "$@" "${_MAN_LANG}" "${_MAN_LANG2}"; do _dir="$(dirname_append "${_parent}" "$d")"; - if path_not_contains "${_res}" "${_dir}" && is_dir "${_dir}"; then + if obj _res path_not_contains "${_dir}" && obj _dir is_dir; then _res="${_res}:${_dir}"; fi; done; @@ -2684,11 +2490,11 @@ _manpath=''; # get a basic man path from $PATH - if is_not_empty "${PATH}"; then + if obj PATH is_not_empty; then eval set -- "$(path_split "${PATH}")"; for d in "$@"; do # delete the final `/bin' part - _base="$(echo -n "$d" | sed -e '\|//*bin/*$|s|||')"; + _base="$(echo -n "$d" | sed -e '\|.*|s|//*bin/*$||')"; for e in /share/man /man; do _mandir="${_base}$e"; if test -d "${_mandir}" && test -r "${_mandir}"; then @@ -2704,7 +2510,7 @@ /usr/X11R6/man /usr/openwin/man \ /opt/share/man /opt/man \ /opt/gnome/man /opt/kde/man; do - if path_not_contains "${_manpath}" "$d" && is_dir "$d"; then + if obj _manpath path_not_contains "$d" && obj d is_dir; then _manpath="${_manpath}:$d"; fi; done; @@ -2715,8 +2521,106 @@ ######################################################################## -landmark '9: path_*()'; +landmark '9: obj_*()'; +######################################################################## + +######################################################################## +# obj ( ...) +# +# This works like a method (object function) call for an object. +# Run " $ ...". +# +# The first argument represents an object whose data is given as first +# argument to (). +# +# Argument: >=2 +# : variable name +# : a program or function name +# +obj() +{ + func_check obj '>=' 2 "$@"; + local func; + local var; + if is_empty "$2"; then + error "obj(): function name is empty." + else + func="$2"; + fi; + eval arg1='"${'$1'}"'; + shift; + shift; + eval "${func}"' "${arg1}" "$@"'; +} + + +######################################################################## +# obj_data () +# +# Print the data of , i.e. the content of $. +# For possible later extensions. +# +# Arguments: 1 +# : a variable name +# Output: the data of +# +obj_data() +{ + func_check obj '=' 1 "$@"; + if is_empty "$1"; then + error "obj_data(): object name is empty." + fi; + eval echo -n '"${'$1'}"'; +} + + +######################################################################## +# obj_from_output ( ...) +# +# Run '$="$( ...)"' to set the result of a +# function call to a global variable. +# +# Arguments: >=2 +# : a variable name +# : the name of a function or program +# : optional argument to +# Output: none +# +obj_from_output() +{ + func_check obj_from_output '>=' 2 "$@"; + local result_name; + if is_empty "$1"; then + error "res(): variable name is empty."; + elif is_empty "$2"; then + error "res(): function name is empty." + else + result_name="$1"; + fi; + shift; + eval "${result_name}"'="$('"$@"')"'; +} + + ######################################################################## +# obj_set ( ) +# +# Set the data of , i.e. call "$=". +# +# Arguments: 2 +# : a variable name +# : a string +# Output:: none +# +obj_set() +{ + func_check obj_set '=' 2 "$@"; + if is_empty "$1"; then + error "obj_set(): object name is empty." + fi; + eval "$1"='"$2"'; +} + ######################################################################## # path_chop () @@ -2755,16 +2659,16 @@ local _dir; local _res; local i; - if test "$#" -ne 1; then + if is_not_equal "$#" 1; then error 'path_clean() needs 1 argument.'; fi; _arg="$1"; eval set -- "$(path_split "${_arg}")"; _res=""; for i in "$@"; do - if is_not_empty "$i" \ - && path_not_contains "${_res}" "$i" \ - && is_dir "$i"; + if obj i is_not_empty \ + && obj _res path_not_contains "$i" \ + && obj i is_dir; then case "$i" in ?*/) _res="${_res}$(dirname_chop "$i")"; ;; @@ -2839,15 +2743,6 @@ ######################################################################## -# reset () -# -# Reset the variables that can be affected by options to their default. -# -# -# Defined in section `Preset' after the rudimentary shell tests. - - -######################################################################## landmark '10: register_*()'; ######################################################################## @@ -2897,7 +2792,7 @@ # remove extension `.Z' _title="$(echo -n "${_title}" | sed -e 's/\.Z$//')"; - if is_empty "${_title}"; then + if obj _title is_empty; then eval "${return_ok}"; fi; _REGISTERED_TITLE="${_REGISTERED_TITLE} ${_title}"; @@ -2906,16 +2801,25 @@ ######################################################################## +# reset () +# +# Reset the variables that can be affected by options to their default. +# +# +# Defined in section `Preset' after the rudimentary shell tests. + + +######################################################################## # save_stdin () # # Store standard input to temporary file (with decompression). # -if test "${_HAS_COMPRESSION}" = 'yes'; then +if obj _HAS_COMPRESSION is_yes; then save_stdin() { local _f; func_check save_stdin = 0 "$@"; - _f="$(tmp_create)"; + _f="${_TMP_DIR}"/INPUT; cat >"${_f}"; catz "${_f}" >"${_TMP_STDIN}"; rm -f "${_f}"; @@ -3007,9 +2911,10 @@ { func_check tmp_create '<=' 1 "$@"; local _tmp; - _tmp="${_TMP_PREFIX}${_PROCESS_ID}$1"; + # the output file does not have `,' as first character + _tmp="${_TMP_DIR}/,$1"; echo -n >"${_tmp}"; - echo -n "${_tmp}"; + echo -n "${_tmp}"; # output file name eval "${return_ok}"; } @@ -3023,10 +2928,10 @@ { func_check to_tmp = 1 "$@"; if is_file "$1"; then - if is_yes "${_OPT_LOCATION}"; then + if obj _OPT_LOCATION is_yes; then echo2 "$1"; fi; - if is_yes "${_OPT_WHATIS}"; then + if obj _OPT_WHATIS is_yes; then what_is "$1" >>"${_TMP_CAT}"; else catz "$1" >>"${_TMP_CAT}"; @@ -3039,76 +2944,102 @@ ######################################################################## +# trap_clean () +# +# disable trap on all exit codes ($_ALL_EXIT) +# +# Arguments: 0 +# Globals: $_ALL_EXIT +# +trap_clean() +{ + func_check trap_clean = 0 "$@"; + local i; + for i in ${_ALL_EXIT}; do + trap "" "$i" 2>/dev/null || true; + done; + eval "${return_ok}"; +} + + +######################################################################## +# trap_set () +# +# call function on all exit codes ($_ALL_EXIT) +# +# Arguments: 1 (name of a shell function) +# Globals: $_ALL_EXIT +# +trap_set() +{ + func_check trap_set = 1 "$@"; + local i; + for i in ${_ALL_EXIT}; do + trap "$1" "$i" 2>/dev/null || true; + done; + eval "${return_ok}"; +} + + +######################################################################## # usage () # -# print usage information to stderr +# print usage information to stderr; for groffer option --help. # usage() { func_check usage = 0 "$@"; - echo2; + echo; version; - cat >&2 <&2 <&1 | sed -e '/^ *$/q' | sed -e '1s/^/is part of /' >&2; @@ -3177,7 +3116,7 @@ # grep the line containing `.TH' macro, if any _res="$(catz "$1" | sed -e '/'"${_dot}"'TH /p d')"; - if is_not_empty "${_res}"; then # traditional man style + if obj _res is_not_empty; then # traditional man style # get the text between the first and the second `.SH' macro, by # - delete up to first .SH; # - of this, print everything up to next .SH, and delete the rest; @@ -3191,7 +3130,7 @@ # grep the line containing `.Dd' macro, if any _res="$(catz "$1" | sed -e '/'"${_dot}"'Dd /p d')"; - if is_not_empty "${_res}"; then # BSD doc style + if obj _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; @@ -3223,7 +3162,7 @@ local _arg; local p; _arg="$1"; - if is_empty "${_arg}"; then + if obj _arg is_empty; then eval "${return_bad}"; fi; case "${_arg}" in @@ -3238,8 +3177,8 @@ eval set -- "$(path_split "${PATH}")"; for p in "$@"; do case "$p" in - */) _file=$p${_arg}; ;; - *) _file=$p/${_arg}; ;; + */) _file=${p}${_arg}; ;; + *) _file=${p}/${_arg}; ;; esac; if test -f "${_file}" && test -x "${_file}"; then echo -n "${_file}"; @@ -3279,33 +3218,58 @@ { func_check main_init = 0 "$@"; # call clean_up() on any signal - trap clean_up 2>/dev/null || true; - - for f in ${_CONFFILES}; do - if is_file "$f"; then - . "$f"; - fi; - done; + trap_set clean_up; # determine temporary directory + umask 000; + _TMP_DIR=''; for d in "${GROFF_TMPDIR}" "${TMPDIR}" "${TMP}" "${TEMP}" \ "${TEMPDIR}" "${HOME}"'/tmp' '/tmp' "${HOME}" '.'; do - if test "$d" != ""; then - if test -d "$d" && test -r "$d" && test -w "$d"; then - _TMP_DIR="$d"; - break; + if is_not_empty "$d"; then + if obj d is_dir && obj d is_writable; then + _TMP_DIR="${d}/${_PROGRAM_NAME}${_PROCESS_ID}"; + if obj _TMP_DIR is_dir; then + rm -f "${_TMP_DIR}"/*; + break; + else + mkdir "${_TMP_DIR}"; + if obj _TMP_DIR is_not_dir; then + _TMP_DIR=''; + continue; + fi; + break; + fi; + fi; + if obj _TMP_DIR is_not_writable; then + _TMP_DIR=''; + continue; fi; fi; done; unset d; - if test "${_TMP_DIR}" = ""; then - error "Couldn't find a directory for storing temorary files."; + if obj _TMP_DIR is_empty; then + error "Couldn't create a directory for storing temporary files."; fi; - _TMP_PREFIX="${_TMP_DIR}/${_PROGRAM_NAME}"; - _TMP_CAT="$(tmp_create)"; - _TMP_STDIN="$(tmp_create i)"; + _TMP_CAT="$(tmp_create groffer_cat)"; + _TMP_STDIN="$(tmp_create groffer_input)"; + + # groffer configuration files + for f in ${_CONFFILES}; do + if obj f is_file; then + echo '_groffer_opt=""' >>${_TMP_CAT}; + # collect the lines starting with a minus + cat "$f" | sed -e \ + 's/^[ ]*\(-.*\)$/_groffer_opt="${_groffer_opt} \1"'/ \ + >>${_TMP_CAT}; + # prepend the collected information to $GROFFER_OPT + echo 'GROFFER_OPT="${_groffer_opt} ${GROFFER_OPT}"' >>${_TMP_CAT}; + fi; + done; + . "${_TMP_CAT}"; + _TMP_CAT="$(tmp_create groffer_cat)"; + eval "${return_ok}"; } # main_init() @@ -3313,10 +3277,11 @@ ######################################################################## # main_parse_MANOPT () # -# Parse $MANOPT; this clobbered by the command line. +# Parse $MANOPT to retrieve man options, but only if it is a non-empty +# string; found man arguments can be overwritten by the command line. # # Globals: -# in: $MANOPT, $_OPTS_MAN_* +# in: $MANOPT, $_OPTS_MANOPT_* # out: $_MANOPT_* # in/out: $GROFFER_OPT # @@ -3327,38 +3292,42 @@ local _opt; local _list; _list=''; - # feed in $MANOPT - eval set -- "$(list_from_cmdline \ - "${_OPTS_MAN_SHORT_NA}" "${_OPTS_MAN_SHORT_ARG}" \ - "${_OPTS_MAN_LONG_NA}" "${_OPTS_MAN_LONG_ARG}" \ - "${MANOPT}")"; + if obj MANOPT is_not_empty; then + MANOPT="$(echo -n "${MANOPT}" | \ + sed -e 's/^'"${_SPACE}${_SPACE}"'*//')"; + fi; + if obj MANOPT is_empty; then + eval "${return_ok}"; + fi; + # add arguments in $MANOPT by mapping them to groffer options + eval set -- "$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")"; until test "$#" -le 0 || is_equal "$1" '--'; do _opt="$1"; shift; case "${_opt}" in -7|--ascii) - _list="$(list_append "${_list}" '--ascii')"; + list_append _list '--ascii'; ;; -a|--all) - _list="$(list_append "${_list}" '--all')"; + list_append _list '--all'; ;; -c|--catman) do_nothing; shift; ;; -d|--debug) - _list="$(list_append "${_list}" '--debug')"; + list_append _list '--debug'; ;; -D|--default) # undo all man options so far _list=''; ;; -e|--extension) - _list="$(list_append "${_list}" '--extension')"; + list_append _list '--extension'; shift; ;; -f|--whatis) - _list="$(list_append "${_list}" '--whatis')"; + list_append _list '--whatis'; shift; ;; -h|--help) @@ -3366,30 +3335,31 @@ shift; ;; -k|--apropos) - _list="$(list_append "${_list}" '--apropos')"; + # groffer's --apropos takes an argument, but man's does not, so + do_nothing; shift; ;; -l|--local-file) - _list="$(list_append "${_list}" '--local-file')"; + list_append _list '--local-file'; ;; -L|--locale) - _list="$(list_append "${_list}" '--locale' "$1")"; + list_append _list '--locale' "$1"; shift; ;; -m|--systems) - _list="$(list_append "${_list}" '--systems' "$1")"; + list_append _list '--systems' "$1"; shift; ;; -M|--manpath) - _list="$(list_append "${_list}" '--manpath' "$1")"; + list_append _list '--manpath' "$1"; shift; ;; -p|--preprocessor) do_nothing; shift; ;; - -P|--pager) - _list="$(list_append "${_list}" '--pager' "$1")"; + -P|--pager|--tty-viewer) + list_append _list '--pager' "$1"; shift; ;; -r|--prompt) @@ -3397,7 +3367,7 @@ shift; ;; -S|--sections) - _list="$(list_append "${_list}" '--sections' "$1")"; + list_append _list '--sections' "$1"; shift; ;; -t|--troff) @@ -3405,7 +3375,7 @@ shift; ;; -T|--device) - _list="$(list_append "${_list}" '-T' "$1")"; + list_append _list '-T' "$1"; shift; ;; -u|--update) @@ -3416,16 +3386,21 @@ do_nothing; ;; -w|--where|--location) - _list="$(list_append "${_list}" '--location')"; + list_append _list '--location'; ;; -Z|--ditroff) - _list="$(list_append "${_list}" '-Z' "$1")"; + list_append _list '-Z' "$1"; shift; ;; # ignore all other options esac; done; - GROFFER_OPT="$(list_from_lists "${_list}" "${GROFFER_OPT}")"; + # append the 2 lists in $_list and $GROFFER_OPT to $GROFFER_OPT + if obj GROFFER_OPT is_empty; then + GROFFER_OPT="${_list}"; + elif obj _list is_not_empty; then + GROFFER_OPT="${_list} ${GROFFER_OPT}"; + fi; eval "${return_ok}"; } # main_parse_MANOPT() @@ -3457,10 +3432,7 @@ eval set -- "${GROFFER_OPT}" '"$@"'; - eval set -- "$(list_from_cmdline \ - "$_OPTS_CMDLINE_SHORT_NA" "$_OPTS_CMDLINE_SHORT_ARG" \ - "$_OPTS_CMDLINE_LONG_NA" "$_OPTS_CMDLINE_LONG_ARG" \ - "$@")"; + eval set -- "$(list_from_cmdline _OPTS_CMDLINE "$@")"; # By the call of `eval', unnecessary quoting was removed. So the # positional shell parameters ($1, $2, ...) are now guaranteed to @@ -3482,9 +3454,9 @@ -Q|--source) # output source code (`Quellcode'). _OPT_MODE='source'; ;; - -T|--device|--troff-device) - # device; arg + -T|--device|--troff-device) # device; arg _OPT_DEVICE="$1"; + _check_device_with_mode; shift; ;; -v|--version) @@ -3494,25 +3466,22 @@ -V) _OPT_V='yes'; ;; - -X) - _OPT_X='yes'; - ;; - -Z|--ditroff|--intermediate-output) - # groff intermediate output + -Z|--ditroff|--intermediate-output) # groff intermediate output _OPT_Z='yes'; ;; + -X|--X|--x) + _OPT_MODE=x; + ;; -?) # delete leading `-' _optchar="$(echo -n "${_opt}" | sed -e 's/^.//')"; - if list_has "${_OPTS_GROFF_SHORT_NA}" "${_optchar}"; + if list_has _OPTS_GROFF_SHORT_NA "${_optchar}"; then - _ADDOPTS_GROFF="$(list_append "${_ADDOPTS_GROFF}" \ - "${_opt}")"; - elif list_has "${_OPTS_GROFF_SHORT_ARG}" "${_optchar}"; + list_append _ADDOPTS_GROFF "${_opt}"; + elif list_has _OPTS_GROFF_SHORT_ARG "${_optchar}"; then - _ADDOPTS_GROFF="$(list_append "${_ADDOPTS_GROFF}" \ - "${_opt}" "$1")"; - shift; + list_append _ADDOPTS_GROFF "${_opt}" "$1"; + shift; else error "Unknown option : \`$1'"; fi; @@ -3520,12 +3489,35 @@ --all) _OPT_ALL="yes"; ;; - --ascii) - _ADDOPTS_GROFF="$(list_append "${_ADDOPTS_GROFF}" \ - '-mtty-char')"; + --apropos) # run `apropos' + apropos_run "$1"; + _code="$?"; + clean_up; + exit "${_code}"; + ;; + --apropos-data) # run `apropos' for data sections + apropos_run "$1" | grep '^[^(]*([457][^)]*)'; + _code="$?"; + clean_up; + exit "${_code}"; + ;; + --apropos-devel) # run `apropos' for development sections + apropos_run "$1" | grep '^[^(]*([239][^)]*)'; + _code="$?"; + clean_up; + exit "${_code}"; + ;; + --apropos-progs) # run `apropos' for program sections + apropos_run "$1" | grep '^[^(]*([168][^)]*)'; + _code="$?"; + clean_up; + exit "${_code}"; ;; - --apropos) - _OPT_APROPOS="yes"; + --ascii) + list_append _ADDOPTS_GROFF '-mtty-char'; + if obj _mode is_empty; then + _mode='text'; + fi; ;; --auto) # the default automatic mode _mode=''; @@ -3549,7 +3541,7 @@ _OPT_DEFAULT_MODES="$1"; shift; ;; - --debug) # sequence of modes in auto mode; arg + --debug) # buggy, only for development _OPT_DEBUG='yes'; ;; --display) # set X display, arg @@ -3582,6 +3574,16 @@ --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 xx[_territory[.codeset[@modifier]]] (ISO 639,...) _OPT_LANG="$1"; @@ -3607,12 +3609,15 @@ _arg="$1"; shift; case "${_arg}" in - auto|'') # the default automatic mode + auto|'') # search mode automatically among default _mode=''; ;; groff) # pass input to plain groff _mode='groff'; ;; + html|www) # display with a web browser + _mode='html'; + ;; dvi) # display with xdvi viewer _mode='dvi'; ;; @@ -3622,12 +3627,15 @@ ps) # display with Postscript viewer _mode='ps'; ;; - X|x) # output on X roff viewer - _mode='x'; + text) # output on terminal + _mode='text'; ;; tty) # output on terminal _mode='tty'; ;; + X|x) # output on X roff viewer + _mode='x'; + ;; Q|source) # display source code _mode="source"; ;; @@ -3688,6 +3696,7 @@ shift; ;; --shell) + # already done during the first run; so ignore the argument shift; ;; --systems) # man pages for different OS's, arg @@ -3695,35 +3704,28 @@ _OPT_SYSTEMS="$1"; shift; ;; + --text) # text mode without pager + _OPT_MODE=text; + ;; --title) # title for X viewers; arg _OPT_TITLE="$1"; shift; ;; - --tty) - _OPT_MODE="tty"; + --tty) # tty mode, text with pager + _OPT_MODE=tty; ;; - --tty-device) # device for tty mode; arg - _OPT_TTY_DEVICE="$1"; + --text-device|--tty-device) # device for tty mode; arg + _OPT_TEXT_DEVICE="$1"; shift; ;; --whatis) _OPT_WHATIS='yes'; ;; - --www) # display with web browser - _OPT_MODE='www'; - ;; - --www-viewer) # viewer program for www mode; arg - _OPT_VIEWER_WWW="$1"; - shift; - ;; - --x) - _OPT_MODE='x'; - ;; --xrm) # pass X resource string, arg; - _OPT_XRM="$(list_append "${_OPT_XRM}" "$1")"; + list_append _OPT_XRM "$1"; shift; ;; - --x-viewer) # viewer program for x mode; arg + --x-viewer|--X-viewer) # viewer program for x mode; arg _OPT_VIEWER_X="$1"; shift; ;; @@ -3734,25 +3736,66 @@ done; shift; # remove `--' argument - if test "${_DEBUG}" != 'yes'; then - if test "${_OPT_DEBUG}" = 'yes'; then + if obj _DEBUG is_not_yes; then + if obj _OPT_DEBUG is_yes; then _DEBUG='yes'; fi; fi; # Remaining arguments are file names (filespecs). # Save them to list $_FILEARGS - if test "$#" -eq 0; then # use "-" for standard input + if is_equal "$#" 0; then # use "-" for standard input set -- '-'; fi; - _FILEARGS="$(list_from_args "$@")"; - if list_has "$_FILEARGS" '-'; then + _FILEARGS=''; + list_append _FILEARGS "$@"; + if list_has _FILEARGS '-'; then save_stdin; fi; # $_FILEARGS must be retrieved with `eval set -- "$_FILEARGS"' eval "${return_ok}"; } # main_parse_args() +# Called from main_parse_args() because double `case' is not possible. +# Globals: $_OPT_DEVICE, $_OPT_MODE +_check_device_with_mode() +{ + 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}"; + ;; + esac; + eval "${return_error}"; +} + ######################################################################## # main_set_mode () @@ -3785,38 +3828,52 @@ local _viewers; # handle apropos - if is_yes "${_OPT_APROPOS}"; then - apropos "$@"; + if obj _OPT_APROPOS is_not_empty; then + apropos "${_OPT_APROPOS}"; + _code="$?"; + clean_up; + exit "${_code}"; + fi; + if obj _OPT_APROPOS_DATA is_not_empty; then + apropos "$@" | grep '^[^(]*([457])'; + _code="$?"; + clean_up; + exit "${_code}"; + fi; + if obj _OPT_APROPOS_DEVEL is_not_empty; then + apropos "$@" | grep '^[^(]*([239])'; + _code="$?"; + clean_up; + exit "${_code}"; + fi; + if obj _OPT_APROPOS_PROGS is_not_empty; then + apropos "$@" | grep '^[^(]*([168])'; _code="$?"; clean_up; exit "${_code}"; fi; # set display - if is_not_empty "${_OPT_DISPLAY}"; then + if obj _OPT_DISPLAY is_not_empty; then DISPLAY="${_OPT_DISPLAY}"; fi; - if is_yes "${_OPT_V}"; then - _DISPLAY_MODE='groff'; - _ADDOPTS_GROFF="$(list_append "${_ADDOPTS_GROFF}" '-V')"; - fi; - if is_yes "${_OPT_X}"; then + if obj _OPT_V is_yes; then _DISPLAY_MODE='groff'; - _ADDOPTS_GROFF="$(list_append "${_ADDOPTS_GROFF}" '-X')"; + list_append _ADDOPTS_GROFF '-V'; fi; - if is_yes "${_OPT_Z}"; then + if obj _OPT_Z is_yes; then _DISPLAY_MODE='groff'; - _ADDOPTS_GROFF="$(list_append "${_ADDOPTS_GROFF}" '-Z')"; + list_append _ADDOPTS_GROFF '-Z'; fi; - if is_equal "${_OPT_MODE}" 'groff'; then + if obj _OPT_MODE is_equal 'groff'; then _DISPLAY_MODE='groff'; fi; - if is_equal "${_DISPLAY_MODE}" 'groff'; then + if obj _DISPLAY_MODE is_equal 'groff'; then eval "${return_ok}"; fi; - if is_equal "${_OPT_MODE}" 'source'; then + if obj _OPT_MODE is_equal 'source'; then _DISPLAY_MODE='source'; eval "${return_ok}"; fi; @@ -3825,34 +3882,40 @@ '') # automatic mode case "${_OPT_DEVICE}" in X*) - if is_empty "${DISPLAY}"; then + if obj DISPLAY is_empty; then error "no X display found for device ${_OPT_DEVICE}"; fi; _DISPLAY_MODE='x'; eval "${return_ok}"; ;; ascii|cp1047|latin1|utf8) - _DISPLAY_MODE='tty'; + if obj _DISPLAY_MODE is_not_equal 'text'; then + _DISPLAY_MODE='tty'; + fi; eval "${return_ok}"; ;; esac; - if is_empty "${DISPLAY}"; then + if obj DISPLAY is_empty; then _DISPLAY_MODE='tty'; eval "${return_ok}"; fi; - if is_empty "${_OPT_DEFAULT_MODES}"; then + if obj _OPT_DEFAULT_MODES is_empty; then _modes="${_DEFAULT_MODES}"; else _modes="${_OPT_DEFAULT_MODES}"; fi; ;; + text) + _DISPLAY_MODE='text'; + eval "${return_ok}"; + ;; tty) _DISPLAY_MODE='tty'; eval "${return_ok}"; ;; *) # display mode was given - if is_empty "${DISPLAY}"; then + if obj DISPLAY is_empty; then error "you must be in X Window for ${_OPT_MODE} mode."; fi; _modes="${_OPT_MODE}"; @@ -3865,18 +3928,22 @@ m="$1"; shift; case "$m" in + text) + _DISPLAY_MODE='text'; + eval "${return_ok}"; + ;; tty) _DISPLAY_MODE='tty'; eval "${return_ok}"; ;; x) - if is_not_empty "${_OPT_VIEWER_X}"; then + if obj _OPT_VIEWER_X is_not_empty; then _viewers="${_OPT_VIEWER_X}"; else _viewers="${_VIEWER_X}"; fi; _viewer="$(_get_first_prog "${_viewers}")"; - if test "$?" -ne 0; then + if is_not_equal "$?" 0; then continue; fi; _DISPLAY_PROG="${_viewer}"; @@ -3884,13 +3951,13 @@ eval "${return_ok}"; ;; dvi) - if is_not_empty "${_OPT_VIEWER_DVI}"; then + if obj _OPT_VIEWER_DVI is_not_empty; then _viewers="${_OPT_VIEWER_DVI}"; else _viewers="${_VIEWER_DVI}"; fi; _viewer="$(_get_first_prog "${_viewers}")"; - if test "$?" -ne 0; then + if is_not_equal "$?" 0; then continue; fi; _DISPLAY_PROG="${_viewer}"; @@ -3898,13 +3965,13 @@ eval "${return_ok}"; ;; pdf) - if is_not_empty "${_OPT_VIEWER_PDF}"; then + if obj _OPT_VIEWER_PDF is_not_empty; then _viewers="${_OPT_VIEWER_PDF}"; else _viewers="${_VIEWER_PDF}"; fi; _viewer="$(_get_first_prog "${_viewers}")"; - if test "$?" -ne 0; then + if is_not_equal "$?" 0; then continue; fi; _DISPLAY_PROG="${_viewer}"; @@ -3912,31 +3979,31 @@ eval "${return_ok}"; ;; ps) - if is_not_empty "${_OPT_VIEWER_PS}"; then + if obj _OPT_VIEWER_PS is_not_empty; then _viewers="${_OPT_VIEWER_PS}"; else _viewers="${_VIEWER_PS}"; fi; _viewer="$(_get_first_prog "${_viewers}")"; - if test "$?" -ne 0; then + if is_not_equal "$?" 0; then continue; fi; _DISPLAY_PROG="${_viewer}"; _DISPLAY_MODE="ps"; eval "${return_ok}"; ;; - www) - if is_not_empty "${_OPT_VIEWER_WWW}"; then - _viewers="${_OPT_VIEWER_WWW}"; + html) + if obj _OPT_VIEWER_HTML is_not_empty; then + _viewers="${_OPT_VIEWER_HTML}"; else - _viewers="${_VIEWER_WWW}"; + _viewers="${_VIEWER_HTML}"; fi; _viewer="$(_get_first_prog "${_viewers}")"; - if test "$?" -ne 0; then + if is_not_equal "$?" 0; then continue; fi; _DISPLAY_PROG="${_viewer}"; - _DISPLAY_MODE="www"; + _DISPLAY_MODE=html; eval "${return_ok}"; ;; esac; @@ -3947,7 +4014,7 @@ _get_first_prog() { local i; - if test "$#" -eq 0; then + if is_equal "$#" 0; then error "_get_first_prog() needs 1 argument."; fi; if is_empty "$1"; then @@ -3955,7 +4022,7 @@ fi; eval set -- "$(list_from_split "$1" ',')"; for i in "$@"; do - if is_empty "$i"; then + if obj i is_empty; then continue; fi; if is_prog "$(get_first_essential $i)"; then @@ -4001,7 +4068,7 @@ continue; ;; ?) - if list_has_not "${_MAN_AUTO_SEC}" "${_filespec}"; then + if list_has_not _MAN_AUTO_SEC "${_filespec}"; then if do_filearg "${_filespec}"; then _exitcode="${_GOOD}"; fi; @@ -4042,7 +4109,7 @@ _exitcode="${_GOOD}"; fi; done; - clean_up_secondary; + rm -f "${_TMP_STDIN}"; if is_equal "${_exitcode}" "${_BAD}"; then eval "${return_bad}"; fi; @@ -4053,7 +4120,9 @@ ######################################################################## # main_set_resources () # -# Determine options for setting X resources with $_DISPLAY_PROG. +# Determine options for setting X resources with $_DISPLAY_PROG. +# +# Globals: $_DISPLAY_PROG, $_OUTPUT_FILE_NAME # landmark '18: main_set_resources()'; main_set_resources() @@ -4061,70 +4130,107 @@ func_check main_set_resources = 0 "$@"; local _prog; # viewer program local _rl; # resource list - _rl=''; - if is_empty "${_DISPLAY_PROG}"; then + local n; + _title="$(get_first_essential \ + "${_OPT_TITLE}" "${_REGISTERED_TITLE}")"; + _OUTPUT_FILE_NAME=''; + set -- ${_title}; + until is_equal "$#" 0; do + n="$1"; + case "$n" in + '') + continue; + ;; + ,*) + n="$(echo -n "$1" | sed -e 's/^,,*//')"; + ;; + esac + if obj n is_empty; then + continue; + fi; + if obj _OUTPUT_FILE_NAME is_not_empty; then + _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME},"; + fi; + _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}$n"; + shift; + done; + case "${_OUTPUT_FILE_NAME}" in + '') + _OUTPUT_FILE_NAME='-'; + ;; + ,*) + error "$_OUTPUT_FILE_NAME starts with a comma."; + ;; + esac; + _OUTPUT_FILE_NAME="${_TMP_DIR}/${_OUTPUT_FILE_NAME}"; + + if obj _DISPLAY_PROG is_empty; then # for example, for groff mode + _DISPLAY_ARGS=''; eval "${return_ok}"; fi; + set -- ${_DISPLAY_PROG}; _prog="$(base_name "$1")"; - if is_not_empty "${_OPT_BD}"; then + _rl=''; + if obj _OPT_BD is_not_empty; then case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi) - _rl="$(list_append "$_rl" '-bd' "${_OPT_BD}")"; + list_append _rl '-bd' "${_OPT_BD}"; ;; esac; fi; - if is_not_empty "${_OPT_BG}"; then + if obj _OPT_BG is_not_empty; then case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi) - _rl="$(list_append "$_rl" '-bg' "${_OPT_BG}")"; + list_append _rl '-bg' "${_OPT_BG}"; ;; xpdf) - _rl="$(list_append "$_rl" '-papercolor' "${_OPT_BG}")"; + list_append _rl '-papercolor' "${_OPT_BG}"; ;; esac; fi; - if is_not_empty "${_OPT_BW}"; then + if obj _OPT_BW is_not_empty; then case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi) - _rl="$(list_append "$_rl" '-bw' "${_OPT_BW}")"; + _list_append _rl '-bw' "${_OPT_BW}"; ;; esac; fi; - if is_not_empty "${_OPT_FG}"; then + if obj _OPT_FG is_not_empty; then case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi) - _rl="$(list_append "$_rl" '-fg' "${_OPT_FG}")"; + list_append _rl '-fg' "${_OPT_FG}"; ;; esac; fi; if is_not_empty "${_OPT_FN}"; then case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi) - _rl="$(list_append "$_rl" '-fn' "${_OPT_FN}")"; + list_append _rl '-fn' "${_OPT_FN}"; ;; esac; fi; if is_not_empty "${_OPT_GEOMETRY}"; then case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi|xpdf) - _rl="$(list_append "$_rl" '-geometry' "${_OPT_GEOMETRY}")"; + list_append _rl '-geometry' "${_OPT_GEOMETRY}"; ;; esac; fi; if is_empty "${_OPT_RESOLUTION}"; then + _OPT_RESOLUTION="${_DEFAULT_RESOLUTION}"; case "${_prog}" in gxditview|xditview) - _rl="$(list_append "$_rl" \ - '-resolution' "${_DEFAULT_RESOLUTION}")"; + list_append _rl '-resolution' "${_DEFAULT_RESOLUTION}"; ;; xpdf) case "${_DEFAULT_RESOLUTION}" in 75) - _rl="$(list_append "$_rl" '-z' '2')"; + # 72dpi is '100' + list_append _rl '-z' '104'; ;; 100) - _rl="$(list_append "$_rl" '-z' '3')"; + list_append _rl '-z' '139'; ;; esac; ;; @@ -4132,24 +4238,32 @@ else case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi) - _rl="$(list_append "$_rl" '-resolution' "${_OPT_RESOLUTION}")"; + list_append _rl '-resolution' "${_OPT_RESOLUTION}"; ;; xpdf) case "${_OPT_RESOLUTION}" in 75) - _rl="$(list_append "$_rl" '-z' '2')"; + list_append _rl '-z' '104'; + # '100' corresponds to 72dpi ;; 100) - _rl="$(list_append "$_rl" '-z' '3')"; + list_append _rl '-z' '139'; ;; esac; ;; esac; fi; - if is_not_empty "${_OPT_RV}"; then + if is_yes "${_OPT_ICONIC}"; then + case "${_prog}" in + ghostview|gv|gxditview|xditview|xdvi) + list_append _rl '-iconic'; + ;; + esac; + fi; + if is_yes "${_OPT_RV}"; then case "${_prog}" in ghostview|gv|gxditview|xditview|xdvi) - _rl="$(list_append "$_rl" '-rv')"; + list_append _rl '-rv'; ;; esac; fi; @@ -4158,21 +4272,20 @@ ghostview|gv|gxditview|xditview|xdvi|xpdf) eval set -- "{$_OPT_XRM}"; for i in "$@"; do - _rl="$(list_append "$_rl" '-xrm' "$i")"; + list_append _rl '-xrm' "$i"; done; ;; esac; fi; - _title="$(get_first_essential \ - "${_OPT_TITLE}" "${_REGISTERED_TITLE}")"; if is_not_empty "${_title}"; then case "${_prog}" in gxditview|xditview) - _rl="$(list_append "$_rl" '-title' "${_title}")"; + list_append _rl '-title' "${_title}"; ;; esac; fi; _DISPLAY_ARGS="${_rl}"; + eval "${return_ok}"; } # main_set_resources @@ -4185,7 +4298,7 @@ # Globals: # in: $_DISPLAY_MODE, $_OPT_DEVICE, # $_ADDOPTS_GROFF, $_ADDOPTS_POST, $_ADDOPTS_X, -# $_REGISTERED_TITLE, $_TMP_PREFIX, $_TMP_CAT, +# $_REGISTERED_TITLE, $_TMP_CAT, # $_OPT_PAGER $PAGER $_MANOPT_PAGER # landmark '19: main_display()'; @@ -4204,44 +4317,43 @@ export _groggy; export _modefile; - # Some display programs have trouble with empty input. - # This is avoided by feeding a space character in this case. - # Test on non-empty file by tracking a line with at least 1 character. - if is_empty "$(tmp_cat | sed -e '/./q')"; then - echo ' ' > "${_TMP_CAT}"; + if obj _TMP_CAT is_non_empty_file; then + _modefile="${_OUTPUT_FILE_NAME}"; + else + clean_up; + eval "${return_ok}"; fi; - case "${_DISPLAY_MODE}" in groff) _ADDOPTS_GROFF="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}"; - if is_not_empty "${_OPT_DEVICE}"; then + if obj _OPT_DEVICE is_not_empty; then _ADDOPTS_GROFF="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}"; fi; _groggy="$(tmp_cat | eval grog "${_options}")"; - trap "" EXIT 2>/dev/null || true; + trap_clean; # start a new shell program to get another process ID. sh -c ' set -e; - _PROCESS_ID="$$"; - _modefile="${_TMP_DIR}/${_PROGRAM_NAME}${_PROCESS_ID}"; - rm -f "${_modefile}"; + test -f "${_modefile}" && rm -f "${_modefile}"; mv "${_TMP_CAT}" "${_modefile}"; - rm -f "${_TMP_CAT}"; cat "${_modefile}" | \ ( clean_up() { - rm -f "${_modefile}"; + if test -d "${_TMP_DIR}"; then + rm -f "${_TMP_DIR}"/* || true; + rmdir "${_TMP_DIR}"; + fi; } - trap clean_up EXIT 2>/dev/null || true; + trap clean_up 0 2>/dev/null || true; eval "${_groggy}" "${_ADDOPTS_GROFF}"; ) &' ;; - tty) + text|tty) case "${_OPT_DEVICE}" in '') _device="$(get_first_essential \ - "${_OPT_TTY_DEVICE}" "${_DEFAULT_TTY_DEVICE}")"; + "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")"; ;; ascii|cp1047|latin1|utf8) _device="${_OPT_DEVICE}"; @@ -4253,19 +4365,23 @@ esac; _addopts="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}"; _groggy="$(tmp_cat | grog -T${_device})"; - _pager=''; - for p in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \ - 'less' 'more' 'cat'; do - if is_prog "$p"; then + if obj _DISPLAY_MODE is_equal 'text'; then + tmp_cat | eval "${_groggy}" "${_addopts}"; + else + _pager=''; + for p in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \ + 'less -r -R' 'more' 'pager' 'cat'; do + if is_prog $p; then # no "" for is_prog() allows args for $p _pager="$p"; break; fi; - done; - if is_empty "${_pager}"; then - error 'no pager program found for tty mode'; + done; + if obj _pager is_empty; then + error 'no pager program found for tty mode'; + fi; + tmp_cat | eval "${_groggy}" "${_addopts}" | \ + eval "${_pager}"; fi; - tmp_cat | eval "${_groggy}" "${_addopts}" | \ - eval "${_pager}"; clean_up; ;; @@ -4282,6 +4398,18 @@ _groggy="$(tmp_cat | grog -Tdvi)"; _do_display; ;; + html) + case "${_OPT_DEVICE}" in + ''|html) do_nothing; ;; + *) + warning \ + "wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"; + ;; + esac; + _modefile="${_modefile}".html + _groggy="$(tmp_cat | grog -Thtml)"; + _do_display; + ;; pdf) case "${_OPT_DEVICE}" in ''|ps) @@ -4292,28 +4420,31 @@ "wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"; ;; esac; + _modefile="${_modefile}" _groggy="$(tmp_cat | grog -Tps)"; - trap "" EXIT 2>/dev/null || true; + trap_clean; # start a new shell program to get another process ID. sh -c ' set -e; - _PROCESS_ID="$$"; - _psfile="${_TMP_DIR}/${_PROGRAM_NAME}${_PROCESS_ID}"; - _modefile="${_TMP_DIR}/${_PROGRAM_NAME}${_PROCESS_ID}.pdf"; - rm -f "${_psfile}"; - rm -f "${_modefile}"; + _psfile="${_modefile}.ps"; + _modefile="${_modefile}.pdf"; + test -f "${_psfile}" && rm -f "${_psfile}"; + test -f "${_modefile}" && rm -f "${_modefile}"; cat "${_TMP_CAT}" | \ - eval "${_groggy}" "${_ADDOPTS_GROFF}" > "${_psfile}"; + eval "${_groggy}" "${_ADDOPTS_GROFF}" > "${_psfile}"; gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \ -sOutputFile="${_modefile}" -c save pop -f "${_psfile}"; - rm -f "${_psfile}"; - rm -f "${_TMP_CAT}"; + test -f "${_psfile}" && rm -f "${_psfile}"; + test -f "${_TMP_CAT}" && rm -f "${_TMP_CAT}"; ( - clean_up() - { + clean_up() { rm -f "${_modefile}"; + if test -d "${_TMP_DIR}"; then + rm -f "${_TMP_DIR}"/* || true; + rmdir "${_TMP_DIR}"; + fi; } - trap clean_up EXIT 2>/dev/null || true; + trap clean_up 0 2>/dev/null || true; eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "${_modefile}"; ) &' ;; @@ -4334,17 +4465,6 @@ tmp_cat; clean_up; ;; - www) - case "${_OPT_DEVICE}" in - ''|html) do_nothing; ;; - *) - warning \ - "wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"; - ;; - esac; - _groggy="$(tmp_cat | grog -Thtml)"; - _do_display; - ;; x) case "${_OPT_DEVICE}" in '') @@ -4370,22 +4490,24 @@ _do_display() { - trap "" EXIT 2>/dev/null || true; - # start a new shell program to get another process ID. + func_check _do_display = 0 "$@"; + trap_clean; + # start a new shell program for another process ID and better + # cleaning-up of the temporary files. sh -c ' set -e; - _PROCESS_ID="$$"; - _modefile="${_TMP_DIR}/${_PROGRAM_NAME}${_PROCESS_ID}"; - rm -f "${_modefile}"; + test -f "${_modefile}" && rm -f "${_modefile}"; cat "${_TMP_CAT}" | \ eval "${_groggy}" "${_ADDOPTS_GROFF}" > "${_modefile}"; rm -f "${_TMP_CAT}"; ( - clean_up() - { - rm -f "${_modefile}"; + clean_up() { + if test -d "${_TMP_DIR}"; then + rm -f "${_TMP_DIR}"/* || true; + rmdir "${_TMP_DIR}"; + fi; } - trap clean_up EXIT 2>/dev/null || true; + trap clean_up 0 2>/dev/null || true; eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "${_modefile}"; ) &' }