/[emacs]/emacs/lisp/woman.el
ViewVC logotype

Diff of /emacs/lisp/woman.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.13 by rost, Mon May 13 15:40:28 2002 UTC revision 1.13.2.1 by miles, Fri Apr 4 06:20:12 2003 UTC
# Line 1  Line 1 
1  ;;; woman.el --- browse UN*X manual pages `wo (without) man'  ;;; woman.el --- browse UN*X manual pages `wo (without) man'
2    
3  ;; Copyright (C) 2000 Free Software Foundation, Inc.  ;; Copyright (C) 2000, 2002 Free Software Foundation, Inc.
4    
5  ;; Author: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk>  ;; Author: Francis J. Wright <F.J.Wright@qmul.ac.uk>
6  ;; Maintainer: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk>  ;; Maintainer: Francis J. Wright <F.J.Wright@qmul.ac.uk>
7  ;; Keywords: help, man, UN*X, manual  ;; Keywords: help, unix
8  ;; Adapted-By: Eli Zaretskii <eliz@is.elta.co.il>  ;; Adapted-By: Eli Zaretskii <eliz@is.elta.co.il>
9  ;; Version: see `woman-version'  ;; Version: see `woman-version'
10  ;; URL: http://centaur.maths.qmw.ac.uk/Emacs/WoMan/  ;; URL: http://centaur.maths.qmul.ac.uk/Emacs/WoMan/
11    
12  ;; This file is part of GNU Emacs.  ;; This file is part of GNU Emacs.
13    
# Line 337  Line 337 
337  ;; Allow general delimiter in `\v', cf. `\h'.  ;; Allow general delimiter in `\v', cf. `\h'.
338  ;; Improve major-mode documentation.  ;; Improve major-mode documentation.
339  ;; Pre-process conditionals in macro bodies if possible for speed?  ;; Pre-process conditionals in macro bodies if possible for speed?
340  ;; Emulate some preprocessor support for tbl (.TS/.TE) and eqn (.EQ/.EN)  ;; Emulate more complete preprocessor support for tbl (.TS/.TE)
341    ;; Emulate some preprocessor support for eqn (.EQ/.EN)
342  ;; Re-write filling and adjusting code!  ;; Re-write filling and adjusting code!
343  ;; Allow word wrap at comma (for long option lists)?  ;; Allow word wrap at comma (for long option lists)?
344  ;; Buffer list handling not quite right.  ;; Buffer list handling not quite right.
# Line 386  Line 387 
387  ;;   Juanma Barranquero <barranquero@laley-actualidad.es>  ;;   Juanma Barranquero <barranquero@laley-actualidad.es>
388  ;;   Karl Berry <kb@cs.umb.edu>  ;;   Karl Berry <kb@cs.umb.edu>
389  ;;   Jim Chapman <jchapman@netcomuk.co.uk>  ;;   Jim Chapman <jchapman@netcomuk.co.uk>
390    ;;   Kin Cho <kin@neoscale.com>
391  ;;   Frederic Corne <frederic.corne@erli.fr>  ;;   Frederic Corne <frederic.corne@erli.fr>
392  ;;   Peter Craft <craft@alacritech.com>  ;;   Peter Craft <craft@alacritech.com>
393  ;;   Charles Curley <ccurley@trib.com>  ;;   Charles Curley <ccurley@trib.com>
# Line 419  Line 421 
421  ;;   Geoff Voelker <voelker@cs.washington.edu>  ;;   Geoff Voelker <voelker@cs.washington.edu>
422  ;;   Eli Zaretskii <eliz@is.elta.co.il>  ;;   Eli Zaretskii <eliz@is.elta.co.il>
423    
 (defvar woman-version "0.54 (beta)" "WoMan version information.")  
   
424  ;;; History:  ;;; History:
425  ;;  For recent change log see end of file.  ;;  For recent change log see end of file.
426    
427    
428  ;;; Code:  ;;; Code:
429    
430    (defvar woman-version "0.551 (beta)" "WoMan version information.")
431    
432  (require 'man)  (require 'man)
433  (eval-when-compile                      ; to avoid compiler warnings  (eval-when-compile                      ; to avoid compiler warnings
434    (require 'dired)    (require 'dired)
# Line 438  FN must return a list, cons or nil.  Use Line 440  FN must return a list, cons or nil.  Use
440    ;; Based on the Standard Lisp function MAPCAN but with args swapped!    ;; Based on the Standard Lisp function MAPCAN but with args swapped!
441    (and x (nconc (funcall fn (car x)) (woman-mapcan fn (cdr x)))))    (and x (nconc (funcall fn (car x)) (woman-mapcan fn (cdr x)))))
442    
443  (defun woman-parse-colon-path (cd-path)  (defun woman-parse-colon-path (paths)
444    "Explode a search path CD-PATH into a list of directory names.    "Explode search path string PATHS into a list of directory names.
445    Allow Cygwin colon-separated search paths on Microsoft platforms.
446  Replace null components by calling `woman-parse-man.conf'.  Replace null components by calling `woman-parse-man.conf'.
447  Allow UN*X-style search paths on Microsoft platforms, i.e. allow path  As a special case, if PATHS is nil then replace it by calling
448  elements to be separated by colons and convert Cygwin-style drive  `woman-parse-man.conf'."
 specifiers `//x/' to `x:'."  
449    ;; Based on suggestions by Jari Aalto and Eli Zaretskii.    ;; Based on suggestions by Jari Aalto and Eli Zaretskii.
450    (mapcar    ;; parse-colon-path returns nil for a null path component and
451     (lambda (path)                       ; //a/b -> a:/b    ;; an empty substring of MANPATH denotes the default list.
452       (when (and path (string-match "\\`//./" path))    (if (memq system-type '(windows-nt ms-dos))
453         (setq path (substring path 1))   ; //a/b -> /a/b        (cond ((null paths)
454         (aset path 0 (aref path 1))      ; /a/b -> aa/b               (mapcar 'woman-Cyg-to-Win (woman-parse-man.conf)))
455         (aset path 1 ?:))                ; aa/b -> a:/b              ((string-match ";" paths)
456       path)               ;; Assume DOS-style path-list...
457     (woman-mapcan                        ; splice into list...               (woman-mapcan              ; splice list into list
458      (lambda (path)                (lambda (x)
459        ;; parse-colon-path returns nil for a null path component and                  (if x
460        ;; an empty substring of MANPATH denotes the default list...                      (list x)
461        (if path (list path) (woman-parse-man.conf)))                    (mapcar 'woman-Cyg-to-Win (woman-parse-man.conf))))
462      (if (and (memq system-type '(windows-nt ms-dos))                (parse-colon-path paths)))
463               (not (string-match ";" cd-path)))              ((string-match "\\`[a-zA-Z]:" paths)
464          (let ((path-separator ":"))               ;; Assume single DOS-style path...
465            (parse-colon-path cd-path))               paths)
466        (parse-colon-path cd-path)))))              (t
467                 ;; Assume UNIX/Cygwin-style path-list...
468                 (woman-mapcan              ; splice list into list
469                  (lambda (x)
470                    (mapcar 'woman-Cyg-to-Win
471                            (if x (list x) (woman-parse-man.conf))))
472                  (let ((path-separator ":"))
473                    (parse-colon-path paths)))))
474        ;; Assume host-default-style path-list...
475        (woman-mapcan                       ; splice list into list
476         (lambda (x) (if x (list x) (woman-parse-man.conf)))
477         (parse-colon-path (or paths "")))))
478    
479    (defun woman-Cyg-to-Win (file)
480      "Convert an absolute filename FILE from Cygwin to Windows form."
481      ;; Code taken from w32-symlinks.el
482      (if (eq (aref file 0) ?/)
483          ;; Try to use Cygwin mount table via `cygpath.exe'.
484          (condition-case nil
485              (with-temp-buffer
486                ;; cygpath -m file
487                (call-process "cygpath" nil t nil "-m" file)
488                (buffer-substring 1 (buffer-size)))
489            (error
490             ;; Assume no `cygpath' program available.
491             ;; Hack /cygdrive/x/ or /x/ or (obsolete) //x/ to x:/
492             (when (string-match "\\`\\(/cygdrive\\|/\\)?/./" file)
493               (if (match-string 1)         ; /cygdrive/x/ or //x/ -> /x/
494                   (setq file (substring file (match-end 1))))
495               (aset file 0 (aref file 1))  ; /x/ -> xx/
496               (aset file 1 ?:))            ; xx/ -> x:/
497             file))
498        file))
499    
500    
501  ;;; User options:  ;;; User options:
# Line 500  Change only via `Customization' or the f Line 534  Change only via `Customization' or the f
534    :group 'woman)    :group 'woman)
535    
536  (defcustom woman-man.conf-path  (defcustom woman-man.conf-path
537    '("/etc" "/etc/manpath.config" "/usr/local/lib")    (let ((path '("/usr/lib" "/etc")))
538        (if (eq system-type 'windows-nt)
539            (mapcar 'woman-Cyg-to-Win path)
540          path))
541    "*List of dirs to search and/or files to try for man config file.    "*List of dirs to search and/or files to try for man config file.
 Default is '(\"/etc\" \"/usr/local/lib\") [for GNU/Linux, Cygwin resp.]  
542  A trailing separator (`/' for UNIX etc.) on directories is optional  A trailing separator (`/' for UNIX etc.) on directories is optional
543  and the filename matched if a directory is specified is the first to  and the filename used if a directory is specified is the first to
544  contain the string \"man.conf\".  match the regexp \"man.*\\.conf\".
545  If MANPATH is not set but a config file is found then it is parsed  If MANPATH is not set but a config file is found then it is parsed
546  instead to provide a default value for `woman-manpath'."  instead to provide a default value for `woman-manpath'."
547    :type '(repeat string)    :type '(repeat string)
548    :group 'woman-interface)    :group 'woman-interface)
549    
550  (defun woman-parse-man.conf ()  (defun woman-parse-man.conf ()
551    "Parse if possible Linux-style configuration file for man command.    "Parse if possible configuration file for man command.
552  Used only if MANPATH is not set or contains null components.  Used only if MANPATH is not set or contains null components.
553  Look in `woman-man.conf-path' and return a value for `woman-manpath'.  Look in `woman-man.conf-path' and return a value for `woman-manpath'.
554  Concatenate data from all lines in the config file of the form  Concatenate data from all lines in the config file of the form
555      MANPATH  /usr/man
   MANPATH       /usr/man  
   
556  or  or
557      MANDATORY_MANPATH  /usr/man"
   MANDATORY_MANPATH     /usr/man"  
558    ;; Functionality suggested by Charles Curley.    ;; Functionality suggested by Charles Curley.
559    (let ((path woman-man.conf-path)    (let ((path woman-man.conf-path)
560          file manpath)          file manpath)
# Line 533  or Line 566  or
566                    (or (not (file-directory-p file))                    (or (not (file-directory-p file))
567                        (and                        (and
568                         (setq file                         (setq file
569                               (directory-files file t "man\\.conf" t))                               (directory-files file t "man.*\\.conf" t))
570                         (file-readable-p (setq file (car file)))))                         (file-readable-p (setq file (car file)))))
571                    ;; Parse the file -- if no MANPATH data ignore it:                    ;; Parse the file -- if no MANPATH data ignore it:
572                    (with-temp-buffer                    (with-temp-buffer
573                      (insert-file-contents file)                      (insert-file-contents file)
574                      (while (re-search-forward                      (while (re-search-forward
575                              "^[ \t]*\\(MANDATORY_\\)?MANPATH[ \t]+\\(\\S-+\\)" nil t)                              ;; `\(?: ... \)' is a "shy group"
576                        (setq manpath (cons (match-string 2) manpath)))                              "\
577    ^[ \t]*\\(?:MANDATORY_\\)?MANPATH[ \t]+\\(\\S-+\\)" nil t)
578                          (setq manpath (cons (match-string 1) manpath)))
579                      manpath))                      manpath))
580                   ))                   ))
581        (setq path (cdr path)))        (setq path (cdr path)))
582      (nreverse manpath)))      (nreverse manpath)))
583    
584  (defcustom woman-manpath  (defcustom woman-manpath
585    (let ((manpath (getenv "MANPATH")))    (or (woman-parse-colon-path (getenv "MANPATH"))
586      (or        '("/usr/man" "/usr/share/man" "/usr/local/man"))
      (and manpath (woman-parse-colon-path manpath))  
      (woman-parse-man.conf)  
      '("/usr/man" "/usr/share/man" "/usr/local/man")  
      ))  
587    "*List of DIRECTORY TREES to search for UN*X manual files.    "*List of DIRECTORY TREES to search for UN*X manual files.
588  Each element should be the name of a directory that contains  Each element should be the name of a directory that contains
589  subdirectories of the form `man?', or more precisely subdirectories  subdirectories of the form `man?', or more precisely subdirectories
# Line 561  and unreadable files are ignored. Line 592  and unreadable files are ignored.
592    
593  If not set then the environment variable MANPATH is used.  If no such  If not set then the environment variable MANPATH is used.  If no such
594  environment variable is found, the default list is determined by  environment variable is found, the default list is determined by
595  consulting the man configuration file if found.  By default this is  consulting the man configuration file if found, which is determined by
596  either `/etc/man.config' or `/usr/local/lib/man.conf', which is  the user option `woman-man.conf-path'.  An empty substring of MANPATH
597  determined by the user option `woman-man.conf-path'.  An empty  denotes the default list.
 substring of MANPATH denotes the default list.  Otherwise, the default  
 value of this variable is  
   
   (\"/usr/man\" \"/usr/local/man\").  
598    
599  Any environment variables (names must have the UN*X-style form $NAME,  Any environment variables (names must have the UN*X-style form $NAME,
600  e.g. $HOME, $EMACSDATA, $EMACS_DIR) are evaluated first but each  e.g. $HOME, $EMACSDATA, $emacs_dir) are evaluated first but each
601  element must evaluate to a SINGLE directory name.  Trailing `/'s are  element must evaluate to a SINGLE directory name.  Trailing `/'s are
602  ignored.  (Specific directories in `woman-path' are also searched.)  ignored.  (Specific directories in `woman-path' are also searched.)
603    
604  Microsoft platforms:  Microsoft platforms:
605  I recommend including drive letters explicitly, e.g.  I recommend including drive letters explicitly, e.g.
606    
607    (\"C:/Cygnus/cygwin-b20/man\" \"C:/usr/man\" \"C:/usr/local/man\").    (\"C:/Cygwin/usr/man/\" \"C:/Cygwin/usr/local/man\").
608    
609  The MANPATH environment variable may be set using DOS semi-colon-  The MANPATH environment variable may be set using DOS semi-colon-
610  separated or UN*X / Cygwin colon-separated syntax (but not mixed)."  separated or UN*X/Cygwin colon-separated syntax (but not mixed)."
611    :type '(repeat string)    :type '(repeat string)
612    :group 'woman-interface)    :group 'woman-interface)
613    
# Line 609  string is expanded into a list of matchi Line 636  string is expanded into a list of matchi
636  and unreadable files are ignored.  The default value is nil.  and unreadable files are ignored.  The default value is nil.
637    
638  Any environment variables (which must have the UN*X-style form $NAME,  Any environment variables (which must have the UN*X-style form $NAME,
639  e.g. $HOME, $EMACSDATA, $EMACS_DIR) are evaluated first but each  e.g. $HOME, $EMACSDATA, $emacs_dir) are evaluated first but each
640  element must evaluate to a SINGLE directory name (regexp, see above).  element must evaluate to a SINGLE directory name (regexp, see above).
641  For example  For example
642    
643    (\"$EMACSDATA\") [or equivalently (\"$EMACS_DIR/etc\")].    (\"$EMACSDATA\") [or equivalently (\"$emacs_dir/etc\")].
644    
645  Trailing `/'s are discarded.  (The directory trees in `woman-manpath'  Trailing `/'s are discarded.  (The directory trees in `woman-manpath'
646  are also searched.)  On Microsoft platforms I recommend including  are also searched.)  On Microsoft platforms I recommend including
# Line 786  Only useful when run on a graphic displa Line 813  Only useful when run on a graphic displa
813    
814  (defcustom woman-default-indent 5  (defcustom woman-default-indent 5
815    "*Default prevailing indent set by -man macros -- default is 5.    "*Default prevailing indent set by -man macros -- default is 5.
816  Set this variable to 7 to emulate Linux man formatting."  Set this variable to 7 to emulate GNU man formatting."
817    :type 'integer    :type 'integer
818    :group 'woman-formatting)    :group 'woman-formatting)
819    
# Line 862  or different fonts." Line 889  or different fonts."
889    
890  (defface woman-addition-face  (defface woman-addition-face
891    '((t (:foreground "orange")))    '((t (:foreground "orange")))
892    "Face for all additions made by WoMan to man pages.    "Face for all WoMan additions to man pages."
 Default: foreground orange."  
893    :group 'woman-faces)    :group 'woman-faces)
894    
895  (defun woman-default-faces ()  (defun woman-default-faces ()
# Line 1033  Should include ?e, ?o (page even/odd) an Line 1059  Should include ?e, ?o (page even/odd) an
1059  Default is '(?n ?e ?o).  Set via `woman-emulation'.")  Default is '(?n ?e ?o).  Set via `woman-emulation'.")
1060    
1061    
 ;;; Button types:  
   
 (define-button-type 'woman-xref  
   'action (lambda (button) (woman (button-label button)))  
   'help-echo "RET, mouse-2: display this man page")  
   
   
1062  ;;; Specialized utility functions:  ;;; Specialized utility functions:
1063    
1064  ;;; Fast deletion without saving on the kill ring (cf. simple.el):  ;;; Fast deletion without saving on the kill ring (cf. simple.el):
# Line 1321  Any UN*X-style environment variables are Line 1340  Any UN*X-style environment variables are
1340    ;; including `.' and `..', so remove any trailing / !!!    ;; including `.' and `..', so remove any trailing / !!!
1341    (if (string= (substring dir -1) "/")    (if (string= (substring dir -1) "/")
1342        (setq dir (substring dir 0 -1)))        (setq dir (substring dir 0 -1)))
1343    (if (memq system-type '(windows-nt ms-dos)) ; what else?    (if (memq system-type '(windows-nt ms-dos cygwin)) ; what else?
1344        ;; Match capitalization used by `file-name-directory':        ;; Match capitalization used by `file-name-directory':
1345        (setq dir (concat (file-name-directory dir)        (setq dir (concat (file-name-directory dir)
1346                          (file-name-nondirectory dir))))                          (file-name-nondirectory dir))))
# Line 1843  See `Man-mode' for additional details." Line 1862  See `Man-mode' for additional details."
1862      (setq woman-imenu-done nil)      (setq woman-imenu-done nil)
1863      (if woman-imenu (woman-imenu))      (if woman-imenu (woman-imenu))
1864      (setq buffer-read-only nil)      (setq buffer-read-only nil)
1865      (WoMan-highlight-references)      (Man-highlight-references)
1866      (setq buffer-read-only t)      (setq buffer-read-only t)
1867      (set-buffer-modified-p nil)))      (set-buffer-modified-p nil)))
1868    
# Line 1938  Otherwise use Man and record start of fo Line 1957  Otherwise use Man and record start of fo
1957                    (- (cadr time) (cadr WoMan-Man-start-time)))))                    (- (cadr time) (cadr WoMan-Man-start-time)))))
1958      (message "Man formatting done in %d seconds" time)))      (message "Man formatting done in %d seconds" time)))
1959    
 (defun WoMan-highlight-references ()  
   "Highlight the references (in the SEE ALSO section) on mouse-over."  
   ;; Based on `Man-build-references-alist' in `man'.  
   (when (Man-find-section Man-see-also-regexp)  
     (forward-line 1)  
     (let ((end (save-excursion  
                  (Man-next-section 1)  
                  (point))))  
       (back-to-indentation)  
       (while (re-search-forward Man-reference-regexp end t)  
         ;; Highlight reference when mouse is over it.  
         ;; (NB: WoMan does not hyphenate!)  
         (make-text-button (match-beginning 1) (match-end 1)  
                           'type 'woman-xref)))))  
   
1960    
1961  ;;; Buffer handling:  ;;; Buffer handling:
1962    
# Line 2114  To be called on original buffer and any Line 2118  To be called on original buffer and any
2118        ;; ***** Need test for .ec arg and warning here! *****        ;; ***** Need test for .ec arg and warning here! *****
2119        (woman-delete-whole-line)))        (woman-delete-whole-line)))
2120    
2121    ;; Delete comments .\"<anything>, \"<anything>, pre-processor    ;; Delete comments .\"<anything>, \"<anything> and null requests.
2122    ;; directives '\"<anything> (should give warning?) and null    ;; (However, should null . requests cause a break?)
   ;; requests.  (However, should null . requests cause a break?)  
2123    (goto-char from)    (goto-char from)
2124    (while (re-search-forward "^[.'][ \t]*\\(\\\\\".*\\)?\n\\|\\\\\".*" to t)    (while (re-search-forward "^[.'][ \t]*\\(\\\\\".*\\)?\n\\|\\\\\".*" to t)
2125      (woman-delete-match 0))      (woman-delete-match 0)))
   )  
2126    
2127  (defun woman-non-underline-faces ()  (defun woman-non-underline-faces ()
2128    "Prepare non-underlined versions of underlined faces."    "Prepare non-underlined versions of underlined faces."
# Line 2135  To be called on original buffer and any Line 2137  To be called on original buffer and any
2137                (set-face-underline-p face-no-ul nil))))                (set-face-underline-p face-no-ul nil))))
2138        (setq face-list (cdr face-list)))))        (setq face-list (cdr face-list)))))
2139    
2140    ;; Preprocessors
2141    ;; =============
2142    
2143    ;; This information is based on documentation for the man command by
2144    ;; Graeme W. Wilford <G.Wilford@ee.surrey.ac.uk>
2145    
2146    ;; First, the environment variable $MANROFFSEQ is interrogated, and if
2147    ;; not set then the initial line of the nroff file is parsed for a
2148    ;; preprocessor string. To contain a valid preprocessor string, the
2149    ;; first line must resemble
2150    ;;
2151    ;; '\" <string>
2152    ;;
2153    ;; where string can be any combination of the following letters that
2154    ;; specify the sequence of preprocessors to run before nroff or
2155    ;; troff/groff.  Not all installations will have a full set of
2156    ;; preprocessors.  Some of the preprocessors and the letters used to
2157    ;; designate them are: eqn (e), grap (g), pic (p), tbl (t), vgrind
2158    ;; (v), refer (r).  This option overrides the $MANROFFSEQ environment
2159    ;; variable.  zsoelim is always run as the very first preprocessor.
2160    
2161    (defvar woman-emulate-tbl nil
2162      "True if WoMan should emulate the tbl preprocessor.
2163    This applies to text between .TE and .TS directives.
2164    Currently set only from '\" t in the first line of the source file.")
2165    
2166  (defun woman-decode-region (from to)  (defun woman-decode-region (from to)
2167    "Decode the region between FROM and TO in UN*X man-page source format."    "Decode the region between FROM and TO in UN*X man-page source format."
2168    ;; Suitable for use in format-alist.    ;; Suitable for use in format-alist.
# Line 2178  To be called on original buffer and any Line 2206  To be called on original buffer and any
2206              (not (and (integerp woman-fill-column) (> woman-fill-column 0))))              (not (and (integerp woman-fill-column) (> woman-fill-column 0))))
2207          (setq woman-fill-column (- (frame-width) woman-default-indent)))          (setq woman-fill-column (- (frame-width) woman-default-indent)))
2208    
2209        ;; Check for preprocessor requests:
2210        (goto-char from)
2211        (if (looking-at "'\\\\\"[ \t]*\\([a-z]+\\)")
2212            (let ((letters (append (match-string 1) nil)))
2213              (if (memq ?t letters)
2214                  (setq woman-emulate-tbl t
2215                        letters (delete ?t letters)))
2216              (if letters
2217                  (WoMan-warn "Unhandled preprocessor request letters %s"
2218                              (concat letters)))
2219              (woman-delete-line 1)))
2220    
2221      (woman-pre-process-region from nil)      (woman-pre-process-region from nil)
2222      ;; Process ignore requests, macro definitions,      ;; Process ignore requests, macro definitions,
2223      ;; conditionals and switch source requests:      ;; conditionals and switch source requests:
# Line 2432  Start at FROM and re-scan new text as ap Line 2472  Start at FROM and re-scan new text as ap
2472    (woman-strings to)    (woman-strings to)
2473    (goto-char from)                      ; necessary!    (goto-char from)                      ; necessary!
2474    ;; Strip font-change escapes:    ;; Strip font-change escapes:
2475    (while (re-search-forward "\\\\f\\((..\\|.\\)" to t)    (while (re-search-forward "\\\\f\\(\\[[^]]+\\]\\|(..\\|.\\)" to t)
2476      (woman-delete-match 0))      (woman-delete-match 0))
2477    (goto-char from)                      ; necessary!    (goto-char from)                      ; necessary!
2478    (woman2-process-escapes to 'numeric))    (woman2-process-escapes to 'numeric))
# Line 2740  Optional argument APPEND, if non-nil, me Line 2780  Optional argument APPEND, if non-nil, me
2780    
2781  ;;; Process strings:  ;;; Process strings:
2782    
2783    (defun woman-match-name ()
2784      "Match and move over name of form: x, (xx or [xxx...].
2785    Applies to number registers, fonts, strings/macros/diversions, and
2786    special characters."
2787      (cond ((= (following-char) ?\[ )
2788             (forward-char)
2789             (re-search-forward "[^]]+")
2790             (forward-char))                ; skip closing ]
2791            ((= (following-char) ?\( )
2792             (forward-char)
2793             (re-search-forward ".."))
2794            (t (re-search-forward "."))))
2795    
2796  (defun woman-strings (&optional to)  (defun woman-strings (&optional to)
2797    "Process ?roff string requests and escape sequences up to buffer position TO.    "Process ?roff string requests and escape sequences up to buffer position TO.
2798  Strings are defined/updated by `.ds xx string' requests and  Strings are defined/updated by `.ds xx string' requests and
# Line 2772  interpolated by `\*x' and `\*(xx' escape Line 2825  interpolated by `\*x' and `\*(xx' escape
2825             (woman-delete-line 1))             (woman-delete-line 1))
2826            (t                            ; \*            (t                            ; \*
2827             (let ((beg (match-beginning 0)))             (let ((beg (match-beginning 0)))
2828               (cond ((= (following-char) ?\( )               (woman-match-name)
                     (forward-char)  
                     (re-search-forward ".."))  
                    (t (re-search-forward ".")))  
2829               (let* ((stringname (match-string 0))               (let* ((stringname (match-string 0))
2830                     (string (assoc stringname woman-string-alist)))                     (string (assoc stringname woman-string-alist)))
2831                 (cond (string                 (cond (string
# Line 2860  Set NEWTEXT in face FACE if specified." Line 2910  Set NEWTEXT in face FACE if specified."
2910    t)    t)
2911    
2912  (defun woman-special-characters (to)  (defun woman-special-characters (to)
2913    "Process special character escapes \(xx up to buffer position TO.    "Process special character escapes \\(xx, \\[xxx] up to buffer position TO.
2914  \(This must be done AFTER translation, which may use special characters.)"  \(This must be done AFTER translation, which may use special characters.)"
2915    (while (re-search-forward "\\\\(\\(..\\)" to t)    (while (re-search-forward "\\\\\\(?:(\\(..\\)\\|\\[\\([[^]]+\\)\\]\\)" to t)
2916      (let ((replacement      (let* ((name (or (match-string-no-properties 1)
2917             (assoc (match-string-no-properties 1) woman-special-characters)))                       (match-string-no-properties 2)))
2918        (if (and             (replacement (assoc name woman-special-characters)))
2919          (unless
2920              (and
2921             replacement             replacement
2922             (cond ((and (cddr replacement)             (cond ((and (cddr replacement)
2923                         (if (nthcdr 3 replacement)                         (if (nthcdr 3 replacement)
# Line 2878  Set NEWTEXT in face FACE if specified." Line 2930  Set NEWTEXT in face FACE if specified."
2930                               (woman-replace-match (nth 2 replacement))))))                               (woman-replace-match (nth 2 replacement))))))
2931                   ((cadr replacement)    ; Use ASCII simulation                   ((cadr replacement)    ; Use ASCII simulation
2932                    (woman-replace-match (cadr replacement)))))                    (woman-replace-match (cadr replacement)))))
2933            ()          (WoMan-warn (concat "Special character "
2934          (WoMan-warn "Special character \\(%s not interpolated!"                              (if (match-string 1) "\\(%s" "\\[%s]")
2935                      (match-string-no-properties 1))                              " not interpolated!") name)
2936          (if woman-ignore (woman-delete-match 0))))          (if woman-ignore (woman-delete-match 0))))
2937      ))      ))
2938    
# Line 3204  If optional arg CONCAT is non-nil then j Line 3256  If optional arg CONCAT is non-nil then j
3256                ((match-string 4)                ((match-string 4)
3257                 ;; \f escape found                 ;; \f escape found
3258                 (setq beg (match-beginning 0))                 (setq beg (match-beginning 0))
3259                 (cond ((= (following-char) ?\( )                 (woman-match-name))
                       (forward-char)  
                       (re-search-forward ".."))  
                      (t (re-search-forward ".")))  
                )  
3260                (t (setq notfont t)))                (t (setq notfont t)))
3261          (if notfont          (if notfont
3262              ()              ()
# Line 3274  Ignore the default face and underline on Line 3322  Ignore the default face and underline on
3322  (defun woman-get-next-char ()  (defun woman-get-next-char ()
3323    "Return and delete next char in buffer, including special chars."    "Return and delete next char in buffer, including special chars."
3324    (if ;;(looking-at "\\\\(\\(..\\)")    (if ;;(looking-at "\\\\(\\(..\\)")
3325        ;; Match special \(xx and strings \*x, \*(xx:        ;; Match special \(xx and strings \*[xxx], \*(xx, \*x:
3326        (looking-at "\\\\\\((..\\|\\*\\((..\\|.\\)\\)")        (looking-at "\\\\\\((..\\|\\*\\(\\[[^]]+\\]\\|(..\\|.\\)\\)")
3327        (prog1 (match-string 0)        (prog1 (match-string 0)
3328          (woman-delete-match 0))          (woman-delete-match 0))
3329      (prog1 (char-to-string (following-char))      (prog1 (char-to-string (following-char))
# Line 3485  expression in parentheses.  Leaves point Line 3533  expression in parentheses.  Leaves point
3533                      ;; currently needed to set match-end, even though                      ;; currently needed to set match-end, even though
3534                      ;; string-to-number returns 0 if number not parsed.                      ;; string-to-number returns 0 if number not parsed.
3535                      (string-to-number (match-string 0)))                      (string-to-number (match-string 0)))
3536                     ((looking-at "\\\\n\\([-+]\\)?\\(\(\\(..\\)\\|\\(.\\)\\)")                     ((looking-at "\\\\n\\([-+]\\)?\\(?:\
3537    \\[\\([^]]+\\)\\]\\|\(\\(..\\)\\|\\(.\\)\\)")
3538                      ;; interpolate number register, maybe auto-incremented                      ;; interpolate number register, maybe auto-incremented
3539                      (let* ((pm (match-string-no-properties 1))                      (let* ((pm (match-string-no-properties 1))
3540                             (name (or (match-string-no-properties 3)                             (name (or (match-string-no-properties 2)
3541                                         (match-string-no-properties 3)
3542                                       (match-string-no-properties 4)))                                       (match-string-no-properties 4)))
3543                             (value (assoc name woman-registers)))                             (value (assoc name woman-registers)))
3544                        (if value                        (if value
# Line 3510  expression in parentheses.  Leaves point Line 3560  expression in parentheses.  Leaves point
3560                          0)              ; default to zero                          0)              ; default to zero
3561                        ))                        ))
3562                     ((re-search-forward                     ((re-search-forward
3563                       ;; Delimiter can be special char escape \(.. or                       ;; Delimiter can be special char escape \[xxx],
3564                       ;; single normal char (usually '):                       ;; \(xx or single normal char (usually '):
3565                       "\\=\\\\w\\(\\\\(..\\|.\\)" nil t)                       "\\=\\\\w\\(\\\\\\[[^]]+\\]\\|\\\\(..\\|.\\)" nil t)
3566                      (let ((from (match-end 0))                      (let ((from (match-end 0))
3567                            (delim (regexp-quote (match-string 1))))                            (delim (regexp-quote (match-string 1))))
3568                        (if (re-search-forward delim nil t)                        (if (re-search-forward delim nil t)
# Line 3636  expression in parentheses.  Leaves point Line 3686  expression in parentheses.  Leaves point
3686  (defun woman2-PD (to)  (defun woman2-PD (to)
3687    ".PD d -- Set the interparagraph distance to d.    ".PD d -- Set the interparagraph distance to d.
3688  Round to whole lines, default 1 line.  Format paragraphs upto TO.  Round to whole lines, default 1 line.  Format paragraphs upto TO.
3689  (Breaks, but should not.)"  \(Breaks, but should not.)"
3690    ;; .ie \\n[.$] .nr PD (v;\\$1)    ;; .ie \\n[.$] .nr PD (v;\\$1)
3691    ;; .el .nr PD .4v>?\n[.V]    ;; .el .nr PD .4v>?\n[.V]
3692    (woman-set-interparagraph-distance)    (woman-set-interparagraph-distance)
# Line 3945  Format paragraphs upto TO.  (Breaks, but Line 3995  Format paragraphs upto TO.  (Breaks, but
3995    
3996  (defun woman2-na (to)  (defun woman2-na (to)
3997    ".na -- No adjusting.  Format paragraphs upto TO.    ".na -- No adjusting.  Format paragraphs upto TO.
3998  (Breaks, but should not.)"  \(Breaks, but should not.)"
3999    (setq woman-adjust-previous woman-adjust    (setq woman-adjust-previous woman-adjust
4000          woman-justify-previous woman-justify          woman-justify-previous woman-justify
4001          woman-adjust woman-adjust-left  ; fill but do not adjust          woman-adjust woman-adjust-left  ; fill but do not adjust
# Line 4358  Needs doing properly!" Line 4408  Needs doing properly!"
4408    (woman2-format-paragraphs to))    (woman2-format-paragraphs to))
4409    
4410    
4411    ;;; Preliminary table support (.TS/.TE)
4412    
4413    (defun woman2-TS (to)
4414      ".TS -- Start of table code for the tbl processor.
4415    Format paragraphs upto TO."
4416      ;; This is a preliminary hack that seems to suffice for lilo.8.
4417      (woman-delete-line 1)                 ; ignore any arguments
4418      (when woman-emulate-tbl
4419        ;; Assumes column separator is \t and intercolumn spacing is 3.
4420        ;; The first line may optionally be a list of options terminated by
4421        ;; a semicolon.  Currently, just delete it:
4422        (if (looking-at ".*;[ \t]*$") (woman-delete-line 1)) ;
4423        ;; The following lines must specify the format of each line of the
4424        ;; table and end with a period.  Currently, just delete them:
4425        (while (not (looking-at ".*\\.[ \t]*$")) (woman-delete-line 1))
4426        (woman-delete-line 1)
4427        ;; For each column, find its width and align it:
4428        (let ((start (point)) (col 1))
4429          (while (prog1 (search-forward "\t" to t) (goto-char start))
4430            ;; Find current column width:
4431            (while (< (point) to)
4432              (when (search-forward "\t" to t)
4433                (backward-char)
4434                (if (> (current-column) col) (setq col (current-column))))
4435              (forward-line))
4436            ;; Align current column:
4437            (goto-char start)
4438            (setq col (+ col 3))            ; intercolumn space
4439            (while (< (point) to)
4440              (when (search-forward "\t" to t)
4441                (delete-char -1)
4442                (insert-char ?\  (- col (current-column))))
4443              (forward-line))
4444            (goto-char start))))
4445      ;; Format table with no filling or adjusting (cf. woman2-nf):
4446      (setq woman-nofill t)
4447      (woman2-format-paragraphs to))
4448    
4449    (defalias 'woman2-TE 'woman2-fi)
4450      ;; ".TE -- End of table code for the tbl processor."
4451      ;; Turn filling and adjusting back on.
4452    
4453    
4454  ;;; WoMan message logging:  ;;; WoMan message logging:
4455    
4456  ;; The basis for this logging code was shamelessly pirated from bytecomp.el  ;; The basis for this logging code was shamelessly pirated from bytecomp.el
# Line 4433  logging the message." Line 4526  logging the message."
4526    
4527  (provide 'woman)  (provide 'woman)
4528    
 ;; RECENT CHANGE LOG  
 ;; =================  
   
 ;; Changes in version 0.50 ([*] => user interface change)  
 ;;   [*] Requires GNU Emacs 20.3+.  
 ;;   [*] `defface' used to define faces.  
 ;;   [*] Follow `see also' references with mouse-2 click.  
 ;;   Number register increment support added (woman-registers).  
 ;;   .j must be a NUMBER acceptable by .ad request.  
 ;;   Very crude field support added.  
 ;;   Vertical unit specifier `v' added to register handling.  
 ;;   Improvement to local horizontal motion processing.  
 ;;   Minor fix to handle negative numeric arguments.  
 ;;   Handle horizontal motion escapes `\h' better.  
 ;;   Allow arbitrary delimiters in `.if', inc. special character escapes.  
 ;;   Allow `\n' within `.if' string comparisons.  
 ;;   Allow arbitrary delimiters in `\w', inc. special character escapes.  
 ;;   Processing of `\h' moved much later -- after indenting etc!  
   
 ;; Changes in version 0.51 ([*] => user interface change)  
 ;;   [*] Improved handling of underlined faces (mainly for "italics").  
 ;;   [*] Allow environment variables in directory path elements.  
 ;;   Display of pre-formatted files improved.  
 ;;   [*] Unintentional interaction with standard Man mode reduced.  
 ;;   [*] bzip2 decompression support added.  All decompression now  
 ;;      works by turning on `auto-compression-mode' to decompress the  
 ;;      file if necessary, rather than decompressing explicitly.  
 ;;      Filename and compression regexps are now customizable user  
 ;;      options.  
   
 ;; Changes in version 0.52 ([*] => user interface change)  
 ;;   Speeded up handling of underlined faces (mainly for "italics").  
 ;;   [*] WoMan formatting time display and log added.  Emacs `man'  
 ;;      formatting time display advice added.  (This suggests that  
 ;;      WoMan formatting is faster than Emacs `man' *formatting*,  
 ;;      i.e. when man is not using `catman' caching.  E.g. `woman  
 ;;      bash' takes 27s whereas `man bash' takes 35s and for smaller  
 ;;      files `woman' can be relatively much faster than `man'.)  
 ;;   [*] Experimental support for non-ASCII characters from the  
 ;;      default and symbol fonts added, initially only for MS-Windows.  
 ;;      NOTE: It is off by default, mainly because it may increase the  
 ;;      line spacing; customize `woman-use-symbols' to `on' to use it.  
 ;;   Pad character handling for .fc fixed.  
 ;;   Tested: see `woman.status'.  
   
 ;; Changes in version 0.53 ([*] => user interface change)  
 ;;   [*] Customization option to use a separate frame for WoMan windows.  
 ;;   [*] Experimental option to emulate nroff (default) or troff (not tested).  
 ;;   [*] Separation of extended and symbol font options.  
 ;;   Only symbol font size 16 seems to work, and only with Win 95, not NT!  
 ;;   [*] `Advanced' sub-menu containing:  
 ;;      `View Source' option;  
 ;;      `Show Log' option;  
 ;;      `Extended Font' toggle and reformat;  
 ;;      `Symbol Font' toggle and reformat;  
 ;;      `Font Map' option;  
 ;;      `Emulation' radio buttons.  
 ;;   [*] Support for man config file added for default manpath.  
   
 ;; Changes in version 0.54  
 ;;   Revised for distribution with Emacs 21.  
 ;;   Comment order and doc strings changed substantially.  
 ;;   MS-DOS support added (by Eli Zaretskii).  
 ;;   checkdoc run: no real errors.  
 ;;   woman topic interface speeded up.  
   
4529  ;;; woman.el ends here  ;;; woman.el ends here

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.13.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26