File: woman.el.html

WoMan implements a subset of the formatting performed by the Emacs man (or manual-entry) command to format a UN*X manual page for display, but without calling any external programs. It is intended to emulate the whole of the -man macro package, plus those
?roff requests that are most commonly used in man pages. However,
the emulation is modified to include the reformatting done by the Emacs man command. No hyphenation is performed.

Note that M-x woman doesn’t yet support the latest features of modern man pages, so we recommend using M-x man if that is available on your system.

Advantages

  Much more direct, does not require any external programs.
  Supports completion on man page names.

Disadvantages

  Not a complete emulation. Currently no support for eqn or tbl.
  Slightly slower for large man pages (but usually faster for
  small- and medium-size pages).

This browser works quite well on simple well-written man files. It works less well on idiosyncratic files that break the rules or use the more obscure ?roff requests directly. Current test results are available in the file woman.status.

WoMan supports the use of compressed man files via auto-compression-mode(var)/auto-compression-mode(fun) by turning it on if necessary. But you may need to adjust the user option woman-file-compression-regexp.

Read on for (currently) the only documentation for WoMan!

See also the documentation for the WoMan interactive commands and user option variables, all of which begin with the prefix woman-. This can be done most easily by loading WoMan and then running the command woman-mini-help, or selecting the WoMan menu option Mini Help when WoMan is running.

WoMan is still under development! Please let me know what doesn't
work -- I am adding and improving functionality as testing shows that it is necessary. See below for guidance on reporting bugs.

Recommended use
===============

Either (1 -- *RECOMMENDED*): If the MANPATH environment variable is set then WoMan will use it; otherwise you may need to reset the Lisp variable woman-manpath, and you may also want to set the Lisp variable woman-path. Please see the online documentation for these variables. Now you can execute the extended command woman, enter or select a manual entry topic, using completion, and if necessary select a filename, using completion. By default, WoMan suggests the word nearest to the cursor in the current buffer as the topic.

Or (2): Execute the extended command woman-find-file and enter a filename, using completion. This mode of execution may be useful for temporary files outside the standard UN*X manual directory structure.

Or (3): Put this in your init file:
(add-hook 'dired-mode-hook
         (lambda ()
           (define-key dired-mode-map "W" 'woman-dired-find-file)))
and open the directory containing the man page file using dired, put the cursor on the file, and press W.

In each case, the result should (!) be a buffer in Man mode showing a formatted manual entry. When called from WoMan, Man mode should work as advertised, but modified where necessary in the context of WoMan. (However, Man will still invoke the standard Emacs manual-browsing facility rather than WoMan -- this is intentional!)

(By default, WoMan will automatically define the dired keys "W" and
"w" when it loads, but only if they are not already defined. This
behavior is controlled by the user option woman-dired-keys. Note that the dired-x (dired extra) package binds dired-copy-filename-as-kill to the key "w" (as pointed out by Jim Davidson), although "W" appears to be really unused. The dired-x package will over-write the WoMan binding to "w", whereas (by default) WoMan will not overwrite the dired-x binding.)

Using the word at point as the default topic
============================================

The woman command uses the word nearest to point in the current buffer as the default topic to look up if it matches the name of a manual page installed on the system. The default topic can also be used without confirmation by setting the user-option woman-use-topic-at-point to t; thanks to Benjamin Riefenstahl for suggesting this functionality.

The variable woman-use-topic-at-point can be rebound locally, which may be useful to provide special private key bindings, e.g.

 (global-set-key "\\C-cw"
                  (lambda ()
                    (interactive)
                    (let ((woman-use-topic-at-point t))
                      (woman)))))


Customization, Hooks and Imenu
==============================

WoMan supports the GNU Emacs customization facility, and puts a customization group called woman in the help group under the top-level emacs group.

WoMan currently runs two hooks: woman-pre-format-hook immediately before formatting a buffer and woman-post-format-hook immediately after formatting a buffer. These hooks can be used for special customizations that require code to be executed, etc., although most customization should be possible by setting WoMan user option variables, e.g. in .emacs and should NOT require the use of the hooks. woman-pre-format-hook might be appropriate for face customization, whereas woman-post-format-hook might be appropriate for installing a dynamic menu using imenu (although it is better to use the built-in WoMan imenu support).

The WoMan menu provides an option to make a contents menu for the current man page (using imenu). Alternatively, if you set the variable woman-imenu(var)/woman-imenu(fun) to t then WoMan will do it automatically for every man page. The menu title is the value of the variable woman-imenu-title, which is "CONTENTS" by default. By default, the menu shows manual sections and subsections, but you can change this by changing the value of woman-imenu-generic-expression. This facility is not yet widely tested and may be fooled by obscure man pages that break the rules.

WoMan is configured not to replace spaces in an imenu *Completion* buffer. For further documentation of the use of imenu, such as menu sorting, see the source file imenu.el, which is distributed with GNU Emacs.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Howard Melman made (essentially) the following suggestions, which are slightly different from the expression that I currently use. You may prefer one of Howard's suggestions, which I think assume that case-fold-search is t (which it is by default):

(setq woman-imenu-generic-expression
      '((nil "^\\\\( \\\\)?\\\\([A-Z][A-Z ]+[A-Z]\\\\)[ \\t]*$" 2)))

will give support for .SH and .SS, though it won't show the heading name hierarchy. If you just want .SH in the imenu then use:

(setq woman-imenu-generic-expression
      '((nil "^\\\\([A-Z][A-Z ]+[A-Z]\\\\)[ \\t]*$" 1)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Vertical spacing and blank lines
================================

The number of consecutive blank lines in the formatted buffer should be either 0 or 1. A blank line should leave a space like
.sp 1 (p. 14). Current policy is to output vertical space only
immediately before text is output.

Horizontal and vertical spacing and resolution
==============================================

WoMan currently assumes 10 characters per inch horizontally, hence a horizontal resolution of 24 basic units, and 5 lines per inch vertically, hence a vertical resolution of 48 basic units. (nroff uses 240 per inch).

The *WoMan-Log* buffer
======================

This is modeled on the byte-compiler. It logs all files formatted by WoMan, and if WoMan finds anything that it cannot handle then it writes a warning to this buffer. If the variable woman-show-log is non-nil (by default it is nil) then WoMan automatically displays this buffer. Many WoMan warnings can be completely ignored, because they are reporting the fact that WoMan has ignored requests that it is correct to ignore. In some future version this level of paranoia will be reduced, but not until WoMan is more reliable. At present, all warnings should be treated with some suspicion. Uninterpreted escape sequences are also logged (in some cases).

Uninterpreted ?roff requests can optionally be left in the formatted buffer to indicate precisely where they occur by resetting the variable woman-ignore to nil (by default it is t).

Automatic initiation of woman decoding

(Probably not a good idea. If you use it, be careful!)

Put something like this in your .emacs. The call to set-visited-file-name is to avoid font-locking triggered by automatic major mode selection.

(autoload 'woman-decode-region "woman")

(setq format-alist
      (cons
       '(man "UN*X man-page source format" "\\\\.\\\\(TH\\\\|ig\\\\) "
woman-decode-region nil nil
(lambda (arg)
set-visited-file-name
(file-name-sans-extension buffer-file-name)))))
      format-alist))


Reporting Bugs
==============

If WoMan fails completely, or formats a file incorrectly
(i.e. obviously wrongly or significantly differently from man) or
inelegantly, then please

(a) check that you are running the latest version of woman.el
    available from my web site (see above),

(b) check that the problem is not already described in the file
    woman.status, also available from my web site.

If both of the above are true then please email me the entry from the *WoMan-Log* buffer relating to the problem file, together with a brief description of the problem. Please indicate where you got the source file from, but do not send it to me unless I ask you to! Thanks. (There is at present no automated bug-reporting facility for WoMan.)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

NOTE:

CASE-DEPENDENCE OF FILENAMES. By default, WoMan ignores case in file pathnames only when it seems appropriate. MS-Windows users who want complete case independence should set the NTEmacs variable w32-downcase-file-names to t and use all lower case when setting WoMan file paths.

(1) INCOMPATIBLE CHANGE! WoMan no longer uses a persistent topic
cache by default. (It caused too much confusion!) Explicitly set
the variable woman-cache-filename to save the cache between Emacs sessions. This is recommended only if the command woman is too slow the first time that it is run in an Emacs session, while it builds its cache in main memory, which MAY be VERY slow.

(2) The user option woman-cache-level controls the amount of
information cached (in main memory and, optionally, saved to disc).

(3) UPDATING THE CACHE. A prefix argument always causes the
woman command (only) to rebuild its topic cache, and to re-save it to woman-cache-filename if this variable has a non-nil value. This is necessary if the NAMES (not contents) of any of the directories or files in the paths specified by woman-manpath or woman-path change. If WoMan user options that affect the cache are changed then WoMan will automatically update its cache file on disc (if one is in use) the next time it is run in a new Emacs session.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


TO DO
=====

Reconsider case sensitivity of file names. MUST PROCESS .if, .nr IN ORDER ENCOUNTERED IN FILE! (rcsfile, mf). Allow general delimiter in \v, cf. \h. Improve major-mode documentation. Pre-process conditionals in macro bodies if possible for speed? Emulate more complete preprocessor support for tbl (.TS/.TE) Emulate some preprocessor support for eqn (.EQ/.EN) Re-write filling and adjusting code! Allow word wrap at comma (for long option lists)? Buffer list handling not quite right. Make 10 or 12 pitch (cpi) optional -- 12 => ll = 78 Use unpaddable space for tabbing? Tidy up handling of fonts when filling and adjusting
  -- see text/text properties?
Improve speed Add font-lock support (for quoted strings, etc.)? Optionally save large files in enriched format? Add apropos facility by searching NAME (?) entry in man files? Documentation -- optional auto-display of formatted WoMan man page? Implement a bug reporter? Support diversion and traps (to some extent) - for Tcl/tk pages? Add a menu of WoMan buffers? Fix .fc properly?

Implementation strategy [this description is now well out of date!]
-- three main passes, each to process respectively:

  1) non-breaking . requests including font macros
  2) \ escape sequences, mainly special characters and font changes
  3) breaking . requests, mainly filling and justification

For each pass, a control function finds and pre-processes the escape or request and then calls the appropriate function to perform the required formatting. Based originally on enriched.el and format.el.

The background information that made this project possible is freely available courtesy of Bell Labs from http://cm.bell-labs.com/7thEdMan/

Acknowledgments
===============

For Heather, Kathryn and Madelyn, the women in my life
(although they will probably never use it)!

I also thank the following for helpful suggestions, bug reports, code fragments, general interest, etc.:
  Jari Aalto <jari.aalto@cs.tpu.fi>
  Dean Andrews <dean@dra.com>
  Juanma Barranquero <lekktu@gmail.com>
  Karl Berry <kb@cs.umb.edu>
  Jim Chapman <jchapman@netcomuk.co.uk>
  Kin Cho <kin@neoscale.com>
  Frederic Corne <frederic.corne@erli.fr>
  Peter Craft <craft@alacritech.com>
  Charles Curley <ccurley@trib.com>
  Jim Davidson <jdavidso@teknowledge.com>
  Kevin D'Elia <Kevin.DElia@mci.com>
  John Fitch <jpff@maths.bath.ac.uk>
  Hans Frosch <jwfrosch@rish.b17c.ingr.com>
  Guy Gascoigne-Piggford <ggp@informix.com>
  Brian Gorka <gorkab@sanchez.com>
  Nicolai Henriksen <nhe@lyngso-industri.dk>
  Thomas Herchenroeder <the@software-ag.de>
  Alexander Hinds <ahinds@thegrid.net>
  Stefan Hornburg <sth@hacon.de>
  Theodore Jump <tjump@cais.com>
  David Kastrup <dak@gnu.org>
  Paul Kinnucan <paulk@mathworks.com>
  Jonas Linde <jonas@init.se>
  Andrew McRae <andrewm@optimation.co.nz>
  Howard Melman <howard@silverstream.com>
  Dennis Pixton <dennis@math.binghamton.edu>
  T. V. Raman <raman@Adobe.COM>
  Bruce Ravel <bruce.ravel@nist.gov>
  Benjamin Riefenstahl <benny@crocodial.de>
  Kevin Ruland <kruland@seistl.com>
  Tom Schutter <tom@platte.com>
  Wei-Xue Shi <wxshi@ma.neweb.ne.jp>
  Fabio Somenzi <fabio@joplin.colorado.edu>
  Karel Sprenger <ks@ic.uva.nl>
  Chris Szurgot <szurgot@itribe.net>
  Paul A. Thompson <pat@po.cwru.edu>
  Arrigo Triulzi <arrigo@maths.qmw.ac.uk>
  Geoff Voelker <voelker@cs.washington.edu>
  Eli Zaretskii <eliz@gnu.org>

Defined variables (77)

WoMan-Man-start-timeUsed to record formatting time used by the ‘man’ command.
woman-RS-left-marginLeft margin stack for nested use of ‘.RS/.RE’.
woman-RS-prevailing-indentPrevailing indent stack for nested use of ‘.RS/.RE’.
woman-adjustCurrent adjustment number-register value.
woman-adjust-bothAdjustment indicator ‘b’ or ‘n’ -- adjust both margins.
woman-adjust-centerAdjustment indicator ‘c’ -- center.
woman-adjust-leftAdjustment indicator ‘l’ -- adjust left margin only.
woman-adjust-previousPrevious adjustment number-register value.
woman-adjust-rightAdjustment indicator ‘r’ -- adjust right margin only.
woman-bold-headingsIf non-nil then embolden section and subsection headings. Default is t.
woman-buffer-alistAn alist representing WoMan buffers that are already decoded.
woman-buffer-numberOrdinal number of current buffer entry in ‘woman-buffer-alist’.
woman-cache-filenameThe full pathname of the WoMan directory and topic cache file.
woman-cache-levelThe level of topic caching.
woman-cached-dataA list of cached data used to determine cache validity.
woman-default-indentDefault prevailing indent set by -man macros -- default is 5.
woman-dired-keysList of ‘dired’ mode keys to define to run WoMan on current file.
woman-emulate-tblNon-nil if WoMan should emulate the tbl preprocessor.
woman-emulationWoMan emulation, currently either nroff or troff. Default is nroff.
woman-escaped-escape-charInternal character representation of escaped escape characters.
woman-escaped-escape-stringInternal string representation of escaped escape characters.
woman-expanded-directory-pathExpanded directory list cache. Resetting to nil forces update.
woman-file-compression-regexpDo not change this unless you are sure you know what you are doing!
woman-file-historyFile-name read history.
woman-file-regexpRegexp used to select (possibly compressed) man source files, e.g.
woman-fill-columnRight margin for formatted text -- default is 70.
woman-fill-frameIf non-nil then most of the window width is used.
woman-font-alistAlist of ?roff font indicators and woman font variables and names.
woman-font-supportIf non-nil then non-ASCII characters and symbol font supported.
woman-fontifyIf non-nil then WoMan assumes that face support is available.
woman-frameDedicated frame used for displaying WoMan windows.
woman-if-conditions-trueList of one-character built-in condition names that are true.
woman-ignoreIf non-nil then unrecognized requests etc. are ignored. Default is t.
woman-imenuIf non-nil then WoMan adds a Contents menu to the menubar.
woman-imenu-doneBuffer-local: set to true if function ‘woman-imenu’ has been called.
woman-imenu-generic-expressionImenu support for Sections and Subsections.
woman-imenu-titleThe title to use if WoMan adds a Contents menu to the menubar.
woman-interparagraph-distanceInterparagraph distance in lines.
woman-justifyCurrent justification style for ‘fill-region-as-paragraph’.
woman-justify-previousPrevious justification style for ‘fill-region-as-paragraph’.
woman-justify-stylesJustify styles for ‘fill-region-as-paragraph’.
woman-last-file-nameThe full pathname of the last file formatted by WoMan.
woman-leave-blank-linesBlank lines to leave as vertical space.
woman-left-marginCurrent left margin.
woman-localeString specifying a manual page locale, or nil.
woman-man.conf-pathList of dirs to search and/or files to try for man config file.
woman-manpathList of DIRECTORY TREES to search for UN*X manual files.
woman-manpath-man-regexpRegexp to match man directories UNDER ‘woman-manpath’ directories.
woman-menuWoMan Menu.
woman-mode-abbrev-tableAbbrev table for ‘woman-mode’.
woman-mode-hookHook run after entering WoMan mode.
woman-mode-mapKeymap for ‘woman-mode’.
woman-mode-syntax-tableSyntax table for ‘woman-mode’.
woman-negative-vertical-spaceSet to t if .sp N with N < 0 encountered.
woman-nofillCurrent fill mode: nil for filling.
woman-nospaceCurrent no-space mode: nil for normal spacing.
woman-pathList of SPECIFIC DIRECTORIES to search for UN*X manual files.
woman-post-format-hookHook run by WoMan immediately after formatting a buffer.
woman-pre-format-hookHook run by WoMan immediately before formatting a buffer.
woman-preserve-asciiIf non-nil, preserve ASCII characters in the WoMan buffer.
woman-prevailing-indentCurrent prevailing indent.
woman-registersRegister alist: the key is the register name as a string.
woman-request-regexpRegexp to match a ?roff request plus trailing white space.
woman-show-logIf non-nil then show the *WoMan-Log* buffer if appropriate.
woman-special-charactersAlist of special character codes with ASCII and extended-font equivalents.
woman-string-alistAlist of strings predefined in the -man macro package ‘tmac.an’.
woman-syntax-tableSyntax table to support special characters used internally by WoMan.
woman-tab-widthDefault tab width set by -man macros.
woman-topic-all-completionsExpanded topic alist cache. Resetting to nil forces update.
woman-topic-historyTopic read history.
woman-uncompressed-file-regexpDo not change this unless you are sure you know what you are doing!
woman-unpadded-space-charInternal character representation of unpadded space characters.
woman-unpadded-space-stringInternal string representation of unpadded space characters.
woman-use-own-frameIf non-nil then use a dedicated frame for displaying WoMan windows.
woman-use-topic-at-pointControl use of the word at point as the default topic.
woman-use-topic-at-point-defaultDefault value for ‘woman-use-topic-at-point’.
woman-versionWoMan version information.

Defined functions (175)

WoMan-find-buffer()
WoMan-getpage-in-background(TOPIC)
WoMan-log(FORMAT &rest ARGS)
WoMan-log-1(STRING &optional END)
WoMan-log-begin()
WoMan-log-end(TIME)
WoMan-next-manpage()
WoMan-previous-manpage()
WoMan-warn(FORMAT &rest ARGS)
WoMan-warn-ignored(REQUEST IGNORED)
set-woman-file-regexp(SYMBOL VALUE)
woman(&optional TOPIC RE-CACHE)
woman-Cyg-to-Win(FILE)
woman-bookmark-jump(BOOKMARK)
woman-bookmark-make-record()
woman-break-table(START-COLUMN TO START)
woman-cached-data()
woman-canonicalize-dir(DIR)
woman-change-fonts()
woman-decode-buffer()
woman-decode-region(FROM TO)
woman-default-faces()
woman-delete-following-space()
woman-delete-line(&optional ARG)
woman-delete-match(SUBEXP)
woman-delete-whole-line()
woman-directory-files(HEAD DIR)
woman-dired-define-key(KEY)
woman-dired-define-key-maybe(KEY)
woman-dired-define-keys()
woman-dired-find-file()
woman-display-extended-fonts()
woman-expand-directory-path(PATH-DIRS PATH-REGEXPS)
woman-expand-locale(LOCALE)
woman-file-accessible-directory-p(DIR)
woman-file-name(TOPIC &optional RE-CACHE)
woman-file-name-all-completions(TOPIC)
woman-file-readable-p(DIR)
woman-find-file(FILE-NAME &optional REFORMAT)
woman-find-next-control-line(&optional PAT)
woman-find-next-control-line-carefully()
woman-follow(TOPIC)
woman-follow-word(EVENT)
woman-forward-arg(&optional UNQUOTE CONCAT)
woman-get-next-char()
woman-get-numeric-arg()
woman-get-tab-stop(TAB-STOPS)
woman-horizontal-escapes(TO)
woman-horizontal-line()
woman-if-body(REQUEST TO DELETE)
woman-if-ignore(TO REQUEST)
woman-imenu(&optional REDRAW)
woman-insert-file-contents(FILENAME COMPRESSED)
woman-interparagraph-space()
woman-interpolate-macro(MACRO)
woman-leave-blank-lines(&optional LEAVE)
woman-make-bufname(BUFNAME)
woman-man-buffer()
woman-manpath-add-locales(MANPATH)
woman-mark-horizontal-position()
woman-match-name()
woman-menu(ARG1)
woman-mini-help()
woman-mode()
woman-monochrome-faces()
woman-negative-vertical-space(FROM)
woman-non-underline-faces()
woman-not-member(DIR PATH)
woman-parse-colon-path(PATHS)
woman-parse-man.conf()
woman-parse-numeric-arg()
woman-parse-numeric-value()
woman-pre-process-region(FROM TO)
woman-process-buffer()
woman-read-directory-cache()
woman-really-find-file(FILENAME COMPRESSED BUFNAME)
woman-reformat-last-file()
woman-replace-match(NEWTEXT &optional FACE)
woman-reset-emulation(VALUE)
woman-reset-nospace()
woman-select(PREDICATE LIST)
woman-select-symbol-fonts(FONTS)
woman-set-arg(ARG &optional PREVIOUS)
woman-set-buffer-display-table()
woman-set-face(FROM TO FACE)
woman-set-file-regexp(SYMBOL VALUE)
woman-set-interparagraph-distance()
woman-special-characters(TO)
woman-strings(&optional TO)
woman-tab-to-tab-stop()
woman-tar-extract-file()
woman-toggle-fill-frame()
woman-toggle-use-extended-font()
woman-toggle-use-symbol-font()
woman-topic-all-completions(PATH)
woman-topic-all-completions-1(DIR PATH-INDEX)
woman-topic-all-completions-merge(ALIST)
woman-translate(TO)
woman-unescape(MACRO)
woman-unquote(TO)
woman-unquote-args()
woman-write-directory-cache()
woman0-de(&optional APPEND)
woman0-el()
woman0-if(REQUEST)
woman0-ig()
woman0-macro(REQUEST)
woman0-process-escapes(FROM TO)
woman0-rename()
woman0-rn()
woman0-roff-buffer(FROM)
woman0-so()
woman1-B()
woman1-B-or-I(B-OR-I)
woman1-BI()
woman1-BR()
woman1-I()
woman1-IB()
woman1-IR()
woman1-IX()
woman1-RB()
woman1-RI()
woman1-SB()
woman1-SM()
woman1-TP()
woman1-TX()
woman1-alt-fonts(FONTS)
woman1-bd()
woman1-cs()
woman1-hc()
woman1-hw()
woman1-hy()
woman1-ne()
woman1-nh()
woman1-ps()
woman1-roff-buffer()
woman1-ss()
woman1-ul()
woman1-vs()
woman2-DT(TO)
woman2-HP(TO)
woman2-IP(TO)
woman2-LP(TO)
woman2-P(TO)
woman2-PD(TO)
woman2-PP(TO)
woman2-RE(TO)
woman2-RS(TO)
woman2-SH(TO)
woman2-SS(TO)
woman2-TE(TO)
woman2-TH(TO)
woman2-TP(TO)
woman2-TS(TO)
woman2-ad(TO)
woman2-br(TO)
woman2-fc(TO)
woman2-fi(TO)
woman2-format-paragraphs(TO &optional NEW-LEFT)
woman2-get-prevailing-indent(&optional LEAVE-EOL)
woman2-in(TO)
woman2-ll(TO)
woman2-na(TO)
woman2-nf(TO)
woman2-nr(TO)
woman2-ns(TO)
woman2-process-escapes(TO &optional NUMERIC)
woman2-process-escapes-to-eol(&optional NUMERIC)
woman2-roff-buffer()
woman2-rs(TO)
woman2-sp(TO)
woman2-ta(TO)
woman2-tagged-paragraph(TO I)
woman2-ti(TO)
woman2-tr(TO)

Defined faces (4)

woman-additionFace for all WoMan additions to man pages.
woman-boldFace for bold font in man pages.
woman-italicFace for italic font in man pages.
woman-unknownFace for all unknown fonts in man pages.