diff options
| author | Juanma Barranquero | 2002-10-23 09:08:20 +0000 |
|---|---|---|
| committer | Juanma Barranquero | 2002-10-23 09:08:20 +0000 |
| commit | 2d4c3c85e0c03909ae37957abf61fc75398bf2f6 (patch) | |
| tree | eb9e0919d1de0c4b6992037b1669d5b45369c7c4 | |
| parent | 08bfde76b7d27d6c3d753e18ac1e82f57ccba0ac (diff) | |
| download | emacs-2d4c3c85e0c03909ae37957abf61fc75398bf2f6.tar.gz emacs-2d4c3c85e0c03909ae37957abf61fc75398bf2f6.zip | |
Updated user interface generally, especially Cygwin
compatibility. Added some support for long groff names of the
form [xxx]. Added preprocessor detection and preliminary support
for tables using tbl/.TS/.TE.
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/woman.el | 373 |
2 files changed, 218 insertions, 162 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1f60758a695..6668f15b4f5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2002-10-23 Francis J. Wright <F.J.Wright@qmul.ac.uk> | ||
| 2 | |||
| 3 | * woman.el: Updated user interface generally, especially Cygwin | ||
| 4 | compatibility. Added some support for long groff names of the | ||
| 5 | form [xxx]. Added preprocessor detection and preliminary support | ||
| 6 | for tables using tbl/.TS/.TE. | ||
| 7 | |||
| 1 | 2002-10-23 Kim F. Storm <storm@cua.dk> | 8 | 2002-10-23 Kim F. Storm <storm@cua.dk> |
| 2 | 9 | ||
| 3 | * ido.el (ido-restrict-to-matches): New command. | 10 | * ido.el (ido-restrict-to-matches): New command. |
diff --git a/lisp/woman.el b/lisp/woman.el index f9929794343..115e70546bb 100644 --- a/lisp/woman.el +++ b/lisp/woman.el | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | ;;; woman.el --- browse UN*X manual pages `wo (without) man' | 1 | ;;; woman.el --- browse UN*X manual pages `wo (without) man' |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2000 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2000, 2002 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk> | 5 | ;; Author: Francis J. Wright <F.J.Wright@qmul.ac.uk> |
| 6 | ;; Maintainer: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk> | 6 | ;; Maintainer: Francis J. Wright <F.J.Wright@qmul.ac.uk> |
| 7 | ;; Keywords: help, man, UN*X, manual | 7 | ;; Keywords: help, unix |
| 8 | ;; Adapted-By: Eli Zaretskii <eliz@is.elta.co.il> | 8 | ;; Adapted-By: Eli Zaretskii <eliz@is.elta.co.il> |
| 9 | ;; Version: see `woman-version' | 9 | ;; Version: see `woman-version' |
| 10 | ;; URL: http://centaur.maths.qmw.ac.uk/Emacs/WoMan/ | 10 | ;; URL: http://centaur.maths.qmul.ac.uk/Emacs/WoMan/ |
| 11 | 11 | ||
| 12 | ;; This file is part of GNU Emacs. | 12 | ;; This file is part of GNU Emacs. |
| 13 | 13 | ||
| @@ -337,7 +337,8 @@ | |||
| 337 | ;; Allow general delimiter in `\v', cf. `\h'. | 337 | ;; Allow general delimiter in `\v', cf. `\h'. |
| 338 | ;; Improve major-mode documentation. | 338 | ;; Improve major-mode documentation. |
| 339 | ;; Pre-process conditionals in macro bodies if possible for speed? | 339 | ;; Pre-process conditionals in macro bodies if possible for speed? |
| 340 | ;; Emulate some preprocessor support for tbl (.TS/.TE) and eqn (.EQ/.EN) | 340 | ;; Emulate more complete preprocessor support for tbl (.TS/.TE) |
| 341 | ;; Emulate some preprocessor support for eqn (.EQ/.EN) | ||
| 341 | ;; Re-write filling and adjusting code! | 342 | ;; Re-write filling and adjusting code! |
| 342 | ;; Allow word wrap at comma (for long option lists)? | 343 | ;; Allow word wrap at comma (for long option lists)? |
| 343 | ;; Buffer list handling not quite right. | 344 | ;; Buffer list handling not quite right. |
| @@ -386,6 +387,7 @@ | |||
| 386 | ;; Juanma Barranquero <barranquero@laley-actualidad.es> | 387 | ;; Juanma Barranquero <barranquero@laley-actualidad.es> |
| 387 | ;; Karl Berry <kb@cs.umb.edu> | 388 | ;; Karl Berry <kb@cs.umb.edu> |
| 388 | ;; Jim Chapman <jchapman@netcomuk.co.uk> | 389 | ;; Jim Chapman <jchapman@netcomuk.co.uk> |
| 390 | ;; Kin Cho <kin@neoscale.com> | ||
| 389 | ;; Frederic Corne <frederic.corne@erli.fr> | 391 | ;; Frederic Corne <frederic.corne@erli.fr> |
| 390 | ;; Peter Craft <craft@alacritech.com> | 392 | ;; Peter Craft <craft@alacritech.com> |
| 391 | ;; Charles Curley <ccurley@trib.com> | 393 | ;; Charles Curley <ccurley@trib.com> |
| @@ -419,14 +421,14 @@ | |||
| 419 | ;; Geoff Voelker <voelker@cs.washington.edu> | 421 | ;; Geoff Voelker <voelker@cs.washington.edu> |
| 420 | ;; Eli Zaretskii <eliz@is.elta.co.il> | 422 | ;; Eli Zaretskii <eliz@is.elta.co.il> |
| 421 | 423 | ||
| 422 | (defvar woman-version "0.54 (beta)" "WoMan version information.") | ||
| 423 | |||
| 424 | ;;; History: | 424 | ;;; History: |
| 425 | ;; For recent change log see end of file. | 425 | ;; For recent change log see end of file. |
| 426 | 426 | ||
| 427 | 427 | ||
| 428 | ;;; Code: | 428 | ;;; Code: |
| 429 | 429 | ||
| 430 | (defvar woman-version "0.551 (beta)" "WoMan version information.") | ||
| 431 | |||
| 430 | (require 'man) | 432 | (require 'man) |
| 431 | (eval-when-compile ; to avoid compiler warnings | 433 | (eval-when-compile ; to avoid compiler warnings |
| 432 | (require 'dired) | 434 | (require 'dired) |
| @@ -438,30 +440,62 @@ FN must return a list, cons or nil. Useful for splicing into a list." | |||
| 438 | ;; Based on the Standard Lisp function MAPCAN but with args swapped! | 440 | ;; Based on the Standard Lisp function MAPCAN but with args swapped! |
| 439 | (and x (nconc (funcall fn (car x)) (woman-mapcan fn (cdr x))))) | 441 | (and x (nconc (funcall fn (car x)) (woman-mapcan fn (cdr x))))) |
| 440 | 442 | ||
| 441 | (defun woman-parse-colon-path (cd-path) | 443 | (defun woman-parse-colon-path (paths) |
| 442 | "Explode a search path CD-PATH into a list of directory names. | 444 | "Explode search path string PATHS into a list of directory names. |
| 445 | Allow Cygwin colon-separated search paths on Microsoft platforms. | ||
| 443 | Replace null components by calling `woman-parse-man.conf'. | 446 | Replace null components by calling `woman-parse-man.conf'. |
| 444 | Allow UN*X-style search paths on Microsoft platforms, i.e. allow path | 447 | As a special case, if PATHS is nil then replace it by calling |
| 445 | elements to be separated by colons and convert Cygwin-style drive | 448 | `woman-parse-man.conf'." |
| 446 | specifiers `//x/' to `x:'." | ||
| 447 | ;; Based on suggestions by Jari Aalto and Eli Zaretskii. | 449 | ;; Based on suggestions by Jari Aalto and Eli Zaretskii. |
| 448 | (mapcar | 450 | ;; parse-colon-path returns nil for a null path component and |
| 449 | (lambda (path) ; //a/b -> a:/b | 451 | ;; an empty substring of MANPATH denotes the default list. |
| 450 | (when (and path (string-match "\\`//./" path)) | 452 | (if (memq system-type '(windows-nt ms-dos)) |
| 451 | (setq path (substring path 1)) ; //a/b -> /a/b | 453 | (cond ((null paths) |
| 452 | (aset path 0 (aref path 1)) ; /a/b -> aa/b | 454 | (mapcar 'woman-Cyg-to-Win (woman-parse-man.conf))) |
| 453 | (aset path 1 ?:)) ; aa/b -> a:/b | 455 | ((string-match ";" paths) |
| 454 | path) | 456 | ;; Assume DOS-style path-list... |
| 455 | (woman-mapcan ; splice into list... | 457 | (woman-mapcan ; splice list into list |
| 456 | (lambda (path) | 458 | (lambda (x) |
| 457 | ;; parse-colon-path returns nil for a null path component and | 459 | (if x |
| 458 | ;; an empty substring of MANPATH denotes the default list... | 460 | (list x) |
| 459 | (if path (list path) (woman-parse-man.conf))) | 461 | (mapcar 'woman-Cyg-to-Win (woman-parse-man.conf)))) |
| 460 | (if (and (memq system-type '(windows-nt ms-dos)) | 462 | (parse-colon-path paths))) |
| 461 | (not (string-match ";" cd-path))) | 463 | ((string-match "\\`[a-zA-Z]:" paths) |
| 462 | (let ((path-separator ":")) | 464 | ;; Assume single DOS-style path... |
| 463 | (parse-colon-path cd-path)) | 465 | paths) |
| 464 | (parse-colon-path cd-path))))) | 466 | (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)) | ||
| 465 | 499 | ||
| 466 | 500 | ||
| 467 | ;;; User options: | 501 | ;;; User options: |
| @@ -500,28 +534,27 @@ Change only via `Customization' or the function `add-hook'." | |||
| 500 | :group 'woman) | 534 | :group 'woman) |
| 501 | 535 | ||
| 502 | (defcustom woman-man.conf-path | 536 | (defcustom woman-man.conf-path |
| 503 | '("/etc" "/etc/manpath.config" "/usr/local/lib") | 537 | (let ((path '("/usr/lib" "/etc"))) |
| 538 | (if (eq system-type 'windows-nt) | ||
| 539 | (mapcar 'woman-Cyg-to-Win path) | ||
| 540 | path)) | ||
| 504 | "*List of dirs to search and/or files to try for man config file. | 541 | "*List of dirs to search and/or files to try for man config file. |
| 505 | Default is '(\"/etc\" \"/usr/local/lib\") [for GNU/Linux, Cygwin resp.] | ||
| 506 | A trailing separator (`/' for UNIX etc.) on directories is optional | 542 | A trailing separator (`/' for UNIX etc.) on directories is optional |
| 507 | and the filename matched if a directory is specified is the first to | 543 | and the filename used if a directory is specified is the first to |
| 508 | contain the string \"man.conf\". | 544 | match the regexp \"man.*\\.conf\". |
| 509 | If MANPATH is not set but a config file is found then it is parsed | 545 | If MANPATH is not set but a config file is found then it is parsed |
| 510 | instead to provide a default value for `woman-manpath'." | 546 | instead to provide a default value for `woman-manpath'." |
| 511 | :type '(repeat string) | 547 | :type '(repeat string) |
| 512 | :group 'woman-interface) | 548 | :group 'woman-interface) |
| 513 | 549 | ||
| 514 | (defun woman-parse-man.conf () | 550 | (defun woman-parse-man.conf () |
| 515 | "Parse if possible Linux-style configuration file for man command. | 551 | "Parse if possible configuration file for man command. |
| 516 | Used only if MANPATH is not set or contains null components. | 552 | Used only if MANPATH is not set or contains null components. |
| 517 | Look in `woman-man.conf-path' and return a value for `woman-manpath'. | 553 | Look in `woman-man.conf-path' and return a value for `woman-manpath'. |
| 518 | Concatenate data from all lines in the config file of the form | 554 | Concatenate data from all lines in the config file of the form |
| 519 | 555 | MANPATH /usr/man | |
| 520 | MANPATH /usr/man | ||
| 521 | |||
| 522 | or | 556 | or |
| 523 | 557 | MANDATORY_MANPATH /usr/man" | |
| 524 | MANDATORY_MANPATH /usr/man" | ||
| 525 | ;; Functionality suggested by Charles Curley. | 558 | ;; Functionality suggested by Charles Curley. |
| 526 | (let ((path woman-man.conf-path) | 559 | (let ((path woman-man.conf-path) |
| 527 | file manpath) | 560 | file manpath) |
| @@ -533,26 +566,24 @@ or | |||
| 533 | (or (not (file-directory-p file)) | 566 | (or (not (file-directory-p file)) |
| 534 | (and | 567 | (and |
| 535 | (setq file | 568 | (setq file |
| 536 | (directory-files file t "man\\.conf" t)) | 569 | (directory-files file t "man.*\\.conf" t)) |
| 537 | (file-readable-p (setq file (car file))))) | 570 | (file-readable-p (setq file (car file))))) |
| 538 | ;; Parse the file -- if no MANPATH data ignore it: | 571 | ;; Parse the file -- if no MANPATH data ignore it: |
| 539 | (with-temp-buffer | 572 | (with-temp-buffer |
| 540 | (insert-file-contents file) | 573 | (insert-file-contents file) |
| 541 | (while (re-search-forward | 574 | (while (re-search-forward |
| 542 | "^[ \t]*\\(MANDATORY_\\)?MANPATH[ \t]+\\(\\S-+\\)" nil t) | 575 | ;; `\(?: ... \)' is a "shy group" |
| 543 | (setq manpath (cons (match-string 2) manpath))) | 576 | "\ |
| 577 | ^[ \t]*\\(?:MANDATORY_\\)?MANPATH[ \t]+\\(\\S-+\\)" nil t) | ||
| 578 | (setq manpath (cons (match-string 1) manpath))) | ||
| 544 | manpath)) | 579 | manpath)) |
| 545 | )) | 580 | )) |
| 546 | (setq path (cdr path))) | 581 | (setq path (cdr path))) |
| 547 | (nreverse manpath))) | 582 | (nreverse manpath))) |
| 548 | 583 | ||
| 549 | (defcustom woman-manpath | 584 | (defcustom woman-manpath |
| 550 | (let ((manpath (getenv "MANPATH"))) | 585 | (or (woman-parse-colon-path (getenv "MANPATH")) |
| 551 | (or | 586 | '("/usr/man" "/usr/share/man" "/usr/local/man")) |
| 552 | (and manpath (woman-parse-colon-path manpath)) | ||
| 553 | (woman-parse-man.conf) | ||
| 554 | '("/usr/man" "/usr/share/man" "/usr/local/man") | ||
| 555 | )) | ||
| 556 | "*List of DIRECTORY TREES to search for UN*X manual files. | 587 | "*List of DIRECTORY TREES to search for UN*X manual files. |
| 557 | Each element should be the name of a directory that contains | 588 | Each element should be the name of a directory that contains |
| 558 | subdirectories of the form `man?', or more precisely subdirectories | 589 | subdirectories of the form `man?', or more precisely subdirectories |
| @@ -561,26 +592,22 @@ and unreadable files are ignored. | |||
| 561 | 592 | ||
| 562 | If not set then the environment variable MANPATH is used. If no such | 593 | If not set then the environment variable MANPATH is used. If no such |
| 563 | environment variable is found, the default list is determined by | 594 | environment variable is found, the default list is determined by |
| 564 | consulting the man configuration file if found. By default this is | 595 | consulting the man configuration file if found, which is determined by |
| 565 | either `/etc/man.config' or `/usr/local/lib/man.conf', which is | 596 | the user option `woman-man.conf-path'. An empty substring of MANPATH |
| 566 | determined by the user option `woman-man.conf-path'. An empty | 597 | denotes the default list. |
| 567 | substring of MANPATH denotes the default list. Otherwise, the default | ||
| 568 | value of this variable is | ||
| 569 | |||
| 570 | (\"/usr/man\" \"/usr/local/man\"). | ||
| 571 | 598 | ||
| 572 | Any environment variables (names must have the UN*X-style form $NAME, | 599 | Any environment variables (names must have the UN*X-style form $NAME, |
| 573 | e.g. $HOME, $EMACSDATA, $EMACS_DIR) are evaluated first but each | 600 | e.g. $HOME, $EMACSDATA, $emacs_dir) are evaluated first but each |
| 574 | element must evaluate to a SINGLE directory name. Trailing `/'s are | 601 | element must evaluate to a SINGLE directory name. Trailing `/'s are |
| 575 | ignored. (Specific directories in `woman-path' are also searched.) | 602 | ignored. (Specific directories in `woman-path' are also searched.) |
| 576 | 603 | ||
| 577 | Microsoft platforms: | 604 | Microsoft platforms: |
| 578 | I recommend including drive letters explicitly, e.g. | 605 | I recommend including drive letters explicitly, e.g. |
| 579 | 606 | ||
| 580 | (\"C:/Cygnus/cygwin-b20/man\" \"C:/usr/man\" \"C:/usr/local/man\"). | 607 | (\"C:/Cygwin/usr/man/\" \"C:/Cygwin/usr/local/man\"). |
| 581 | 608 | ||
| 582 | The MANPATH environment variable may be set using DOS semi-colon- | 609 | The MANPATH environment variable may be set using DOS semi-colon- |
| 583 | separated or UN*X / Cygwin colon-separated syntax (but not mixed)." | 610 | separated or UN*X/Cygwin colon-separated syntax (but not mixed)." |
| 584 | :type '(repeat string) | 611 | :type '(repeat string) |
| 585 | :group 'woman-interface) | 612 | :group 'woman-interface) |
| 586 | 613 | ||
| @@ -609,11 +636,11 @@ string is expanded into a list of matching directories. Non-directory | |||
| 609 | and unreadable files are ignored. The default value is nil. | 636 | and unreadable files are ignored. The default value is nil. |
| 610 | 637 | ||
| 611 | Any environment variables (which must have the UN*X-style form $NAME, | 638 | Any environment variables (which must have the UN*X-style form $NAME, |
| 612 | e.g. $HOME, $EMACSDATA, $EMACS_DIR) are evaluated first but each | 639 | e.g. $HOME, $EMACSDATA, $emacs_dir) are evaluated first but each |
| 613 | element must evaluate to a SINGLE directory name (regexp, see above). | 640 | element must evaluate to a SINGLE directory name (regexp, see above). |
| 614 | For example | 641 | For example |
| 615 | 642 | ||
| 616 | (\"$EMACSDATA\") [or equivalently (\"$EMACS_DIR/etc\")]. | 643 | (\"$EMACSDATA\") [or equivalently (\"$emacs_dir/etc\")]. |
| 617 | 644 | ||
| 618 | Trailing `/'s are discarded. (The directory trees in `woman-manpath' | 645 | Trailing `/'s are discarded. (The directory trees in `woman-manpath' |
| 619 | are also searched.) On Microsoft platforms I recommend including | 646 | are also searched.) On Microsoft platforms I recommend including |
| @@ -786,7 +813,7 @@ Only useful when run on a graphic display such as X or MS-Windows." | |||
| 786 | 813 | ||
| 787 | (defcustom woman-default-indent 5 | 814 | (defcustom woman-default-indent 5 |
| 788 | "*Default prevailing indent set by -man macros -- default is 5. | 815 | "*Default prevailing indent set by -man macros -- default is 5. |
| 789 | Set this variable to 7 to emulate Linux man formatting." | 816 | Set this variable to 7 to emulate GNU man formatting." |
| 790 | :type 'integer | 817 | :type 'integer |
| 791 | :group 'woman-formatting) | 818 | :group 'woman-formatting) |
| 792 | 819 | ||
| @@ -862,8 +889,7 @@ or different fonts." | |||
| 862 | 889 | ||
| 863 | (defface woman-addition-face | 890 | (defface woman-addition-face |
| 864 | '((t (:foreground "orange"))) | 891 | '((t (:foreground "orange"))) |
| 865 | "Face for all additions made by WoMan to man pages. | 892 | "Face for all WoMan additions to man pages." |
| 866 | Default: foreground orange." | ||
| 867 | :group 'woman-faces) | 893 | :group 'woman-faces) |
| 868 | 894 | ||
| 869 | (defun woman-default-faces () | 895 | (defun woman-default-faces () |
| @@ -2114,13 +2140,11 @@ To be called on original buffer and any .so insertions." | |||
| 2114 | ;; ***** Need test for .ec arg and warning here! ***** | 2140 | ;; ***** Need test for .ec arg and warning here! ***** |
| 2115 | (woman-delete-whole-line))) | 2141 | (woman-delete-whole-line))) |
| 2116 | 2142 | ||
| 2117 | ;; Delete comments .\"<anything>, \"<anything>, pre-processor | 2143 | ;; Delete comments .\"<anything>, \"<anything> and null requests. |
| 2118 | ;; directives '\"<anything> (should give warning?) and null | 2144 | ;; (However, should null . requests cause a break?) |
| 2119 | ;; requests. (However, should null . requests cause a break?) | ||
| 2120 | (goto-char from) | 2145 | (goto-char from) |
| 2121 | (while (re-search-forward "^[.'][ \t]*\\(\\\\\".*\\)?\n\\|\\\\\".*" to t) | 2146 | (while (re-search-forward "^[.'][ \t]*\\(\\\\\".*\\)?\n\\|\\\\\".*" to t) |
| 2122 | (woman-delete-match 0)) | 2147 | (woman-delete-match 0))) |
| 2123 | ) | ||
| 2124 | 2148 | ||
| 2125 | (defun woman-non-underline-faces () | 2149 | (defun woman-non-underline-faces () |
| 2126 | "Prepare non-underlined versions of underlined faces." | 2150 | "Prepare non-underlined versions of underlined faces." |
| @@ -2135,6 +2159,32 @@ To be called on original buffer and any .so insertions." | |||
| 2135 | (set-face-underline-p face-no-ul nil)))) | 2159 | (set-face-underline-p face-no-ul nil)))) |
| 2136 | (setq face-list (cdr face-list))))) | 2160 | (setq face-list (cdr face-list))))) |
| 2137 | 2161 | ||
| 2162 | ;; Preprocessors | ||
| 2163 | ;; ============= | ||
| 2164 | |||
| 2165 | ;; This information is based on documentation for the man command by | ||
| 2166 | ;; Graeme W. Wilford <G.Wilford@ee.surrey.ac.uk> | ||
| 2167 | |||
| 2168 | ;; First, the environment variable $MANROFFSEQ is interrogated, and if | ||
| 2169 | ;; not set then the initial line of the nroff file is parsed for a | ||
| 2170 | ;; preprocessor string. To contain a valid preprocessor string, the | ||
| 2171 | ;; first line must resemble | ||
| 2172 | ;; | ||
| 2173 | ;; '\" <string> | ||
| 2174 | ;; | ||
| 2175 | ;; where string can be any combination of the following letters that | ||
| 2176 | ;; specify the sequence of preprocessors to run before nroff or | ||
| 2177 | ;; troff/groff. Not all installations will have a full set of | ||
| 2178 | ;; preprocessors. Some of the preprocessors and the letters used to | ||
| 2179 | ;; designate them are: eqn (e), grap (g), pic (p), tbl (t), vgrind | ||
| 2180 | ;; (v), refer (r). This option overrides the $MANROFFSEQ environment | ||
| 2181 | ;; variable. zsoelim is always run as the very first preprocessor. | ||
| 2182 | |||
| 2183 | (defvar woman-emulate-tbl nil | ||
| 2184 | "True if WoMan should emulate the tbl preprocessor. | ||
| 2185 | This applies to text between .TE and .TS directives. | ||
| 2186 | Currently set only from '\" t in the first line of the source file.") | ||
| 2187 | |||
| 2138 | (defun woman-decode-region (from to) | 2188 | (defun woman-decode-region (from to) |
| 2139 | "Decode the region between FROM and TO in UN*X man-page source format." | 2189 | "Decode the region between FROM and TO in UN*X man-page source format." |
| 2140 | ;; Suitable for use in format-alist. | 2190 | ;; Suitable for use in format-alist. |
| @@ -2178,6 +2228,18 @@ To be called on original buffer and any .so insertions." | |||
| 2178 | (not (and (integerp woman-fill-column) (> woman-fill-column 0)))) | 2228 | (not (and (integerp woman-fill-column) (> woman-fill-column 0)))) |
| 2179 | (setq woman-fill-column (- (frame-width) woman-default-indent))) | 2229 | (setq woman-fill-column (- (frame-width) woman-default-indent))) |
| 2180 | 2230 | ||
| 2231 | ;; Check for preprocessor requests: | ||
| 2232 | (goto-char from) | ||
| 2233 | (if (looking-at "'\\\\\"[ \t]*\\([a-z]+\\)") | ||
| 2234 | (let ((letters (append (match-string 1) nil))) | ||
| 2235 | (if (memq ?t letters) | ||
| 2236 | (setq woman-emulate-tbl t | ||
| 2237 | letters (delete ?t letters))) | ||
| 2238 | (if letters | ||
| 2239 | (WoMan-warn "Unhandled preprocessor request letters %s" | ||
| 2240 | (concat letters))) | ||
| 2241 | (woman-delete-line 1))) | ||
| 2242 | |||
| 2181 | (woman-pre-process-region from nil) | 2243 | (woman-pre-process-region from nil) |
| 2182 | ;; Process ignore requests, macro definitions, | 2244 | ;; Process ignore requests, macro definitions, |
| 2183 | ;; conditionals and switch source requests: | 2245 | ;; conditionals and switch source requests: |
| @@ -2432,7 +2494,7 @@ Start at FROM and re-scan new text as appropriate." | |||
| 2432 | (woman-strings to) | 2494 | (woman-strings to) |
| 2433 | (goto-char from) ; necessary! | 2495 | (goto-char from) ; necessary! |
| 2434 | ;; Strip font-change escapes: | 2496 | ;; Strip font-change escapes: |
| 2435 | (while (re-search-forward "\\\\f\\((..\\|.\\)" to t) | 2497 | (while (re-search-forward "\\\\f\\(\\[[^]]+\\]\\|(..\\|.\\)" to t) |
| 2436 | (woman-delete-match 0)) | 2498 | (woman-delete-match 0)) |
| 2437 | (goto-char from) ; necessary! | 2499 | (goto-char from) ; necessary! |
| 2438 | (woman2-process-escapes to 'numeric)) | 2500 | (woman2-process-escapes to 'numeric)) |
| @@ -2740,6 +2802,19 @@ Optional argument APPEND, if non-nil, means append macro." | |||
| 2740 | 2802 | ||
| 2741 | ;;; Process strings: | 2803 | ;;; Process strings: |
| 2742 | 2804 | ||
| 2805 | (defun woman-match-name () | ||
| 2806 | "Match and move over name of form: x, (xx or [xxx...]. | ||
| 2807 | Applies to number registers, fonts, strings/macros/diversions, and | ||
| 2808 | special characters." | ||
| 2809 | (cond ((= (following-char) ?\[ ) | ||
| 2810 | (forward-char) | ||
| 2811 | (re-search-forward "[^]]+") | ||
| 2812 | (forward-char)) ; skip closing ] | ||
| 2813 | ((= (following-char) ?\( ) | ||
| 2814 | (forward-char) | ||
| 2815 | (re-search-forward "..")) | ||
| 2816 | (t (re-search-forward ".")))) | ||
| 2817 | |||
| 2743 | (defun woman-strings (&optional to) | 2818 | (defun woman-strings (&optional to) |
| 2744 | "Process ?roff string requests and escape sequences up to buffer position TO. | 2819 | "Process ?roff string requests and escape sequences up to buffer position TO. |
| 2745 | Strings are defined/updated by `.ds xx string' requests and | 2820 | Strings are defined/updated by `.ds xx string' requests and |
| @@ -2772,10 +2847,7 @@ interpolated by `\*x' and `\*(xx' escapes." | |||
| 2772 | (woman-delete-line 1)) | 2847 | (woman-delete-line 1)) |
| 2773 | (t ; \* | 2848 | (t ; \* |
| 2774 | (let ((beg (match-beginning 0))) | 2849 | (let ((beg (match-beginning 0))) |
| 2775 | (cond ((= (following-char) ?\( ) | 2850 | (woman-match-name) |
| 2776 | (forward-char) | ||
| 2777 | (re-search-forward "..")) | ||
| 2778 | (t (re-search-forward "."))) | ||
| 2779 | (let* ((stringname (match-string 0)) | 2851 | (let* ((stringname (match-string 0)) |
| 2780 | (string (assoc stringname woman-string-alist))) | 2852 | (string (assoc stringname woman-string-alist))) |
| 2781 | (cond (string | 2853 | (cond (string |
| @@ -2860,12 +2932,14 @@ Set NEWTEXT in face FACE if specified." | |||
| 2860 | t) | 2932 | t) |
| 2861 | 2933 | ||
| 2862 | (defun woman-special-characters (to) | 2934 | (defun woman-special-characters (to) |
| 2863 | "Process special character escapes \(xx up to buffer position TO. | 2935 | "Process special character escapes \\(xx, \\[xxx] up to buffer position TO. |
| 2864 | \(This must be done AFTER translation, which may use special characters.)" | 2936 | \(This must be done AFTER translation, which may use special characters.)" |
| 2865 | (while (re-search-forward "\\\\(\\(..\\)" to t) | 2937 | (while (re-search-forward "\\\\\\(?:(\\(..\\)\\|\\[\\([[^]]+\\)\\]\\)" to t) |
| 2866 | (let ((replacement | 2938 | (let* ((name (or (match-string-no-properties 1) |
| 2867 | (assoc (match-string-no-properties 1) woman-special-characters))) | 2939 | (match-string-no-properties 2))) |
| 2868 | (if (and | 2940 | (replacement (assoc name woman-special-characters))) |
| 2941 | (unless | ||
| 2942 | (and | ||
| 2869 | replacement | 2943 | replacement |
| 2870 | (cond ((and (cddr replacement) | 2944 | (cond ((and (cddr replacement) |
| 2871 | (if (nthcdr 3 replacement) | 2945 | (if (nthcdr 3 replacement) |
| @@ -2878,9 +2952,9 @@ Set NEWTEXT in face FACE if specified." | |||
| 2878 | (woman-replace-match (nth 2 replacement)))))) | 2952 | (woman-replace-match (nth 2 replacement)))))) |
| 2879 | ((cadr replacement) ; Use ASCII simulation | 2953 | ((cadr replacement) ; Use ASCII simulation |
| 2880 | (woman-replace-match (cadr replacement))))) | 2954 | (woman-replace-match (cadr replacement))))) |
| 2881 | () | 2955 | (WoMan-warn (concat "Special character " |
| 2882 | (WoMan-warn "Special character \\(%s not interpolated!" | 2956 | (if (match-string 1) "\\(%s" "\\[%s]") |
| 2883 | (match-string-no-properties 1)) | 2957 | " not interpolated!") name) |
| 2884 | (if woman-ignore (woman-delete-match 0)))) | 2958 | (if woman-ignore (woman-delete-match 0)))) |
| 2885 | )) | 2959 | )) |
| 2886 | 2960 | ||
| @@ -3204,11 +3278,7 @@ If optional arg CONCAT is non-nil then join arguments." | |||
| 3204 | ((match-string 4) | 3278 | ((match-string 4) |
| 3205 | ;; \f escape found | 3279 | ;; \f escape found |
| 3206 | (setq beg (match-beginning 0)) | 3280 | (setq beg (match-beginning 0)) |
| 3207 | (cond ((= (following-char) ?\( ) | 3281 | (woman-match-name)) |
| 3208 | (forward-char) | ||
| 3209 | (re-search-forward "..")) | ||
| 3210 | (t (re-search-forward "."))) | ||
| 3211 | ) | ||
| 3212 | (t (setq notfont t))) | 3282 | (t (setq notfont t))) |
| 3213 | (if notfont | 3283 | (if notfont |
| 3214 | () | 3284 | () |
| @@ -3274,8 +3344,8 @@ Ignore the default face and underline only word characters." | |||
| 3274 | (defun woman-get-next-char () | 3344 | (defun woman-get-next-char () |
| 3275 | "Return and delete next char in buffer, including special chars." | 3345 | "Return and delete next char in buffer, including special chars." |
| 3276 | (if ;;(looking-at "\\\\(\\(..\\)") | 3346 | (if ;;(looking-at "\\\\(\\(..\\)") |
| 3277 | ;; Match special \(xx and strings \*x, \*(xx: | 3347 | ;; Match special \(xx and strings \*[xxx], \*(xx, \*x: |
| 3278 | (looking-at "\\\\\\((..\\|\\*\\((..\\|.\\)\\)") | 3348 | (looking-at "\\\\\\((..\\|\\*\\(\\[[^]]+\\]\\|(..\\|.\\)\\)") |
| 3279 | (prog1 (match-string 0) | 3349 | (prog1 (match-string 0) |
| 3280 | (woman-delete-match 0)) | 3350 | (woman-delete-match 0)) |
| 3281 | (prog1 (char-to-string (following-char)) | 3351 | (prog1 (char-to-string (following-char)) |
| @@ -3485,10 +3555,12 @@ expression in parentheses. Leaves point after the value." | |||
| 3485 | ;; currently needed to set match-end, even though | 3555 | ;; currently needed to set match-end, even though |
| 3486 | ;; string-to-number returns 0 if number not parsed. | 3556 | ;; string-to-number returns 0 if number not parsed. |
| 3487 | (string-to-number (match-string 0))) | 3557 | (string-to-number (match-string 0))) |
| 3488 | ((looking-at "\\\\n\\([-+]\\)?\\(\(\\(..\\)\\|\\(.\\)\\)") | 3558 | ((looking-at "\\\\n\\([-+]\\)?\\(?:\ |
| 3559 | \\[\\([^]]+\\)\\]\\|\(\\(..\\)\\|\\(.\\)\\)") | ||
| 3489 | ;; interpolate number register, maybe auto-incremented | 3560 | ;; interpolate number register, maybe auto-incremented |
| 3490 | (let* ((pm (match-string-no-properties 1)) | 3561 | (let* ((pm (match-string-no-properties 1)) |
| 3491 | (name (or (match-string-no-properties 3) | 3562 | (name (or (match-string-no-properties 2) |
| 3563 | (match-string-no-properties 3) | ||
| 3492 | (match-string-no-properties 4))) | 3564 | (match-string-no-properties 4))) |
| 3493 | (value (assoc name woman-registers))) | 3565 | (value (assoc name woman-registers))) |
| 3494 | (if value | 3566 | (if value |
| @@ -3510,9 +3582,9 @@ expression in parentheses. Leaves point after the value." | |||
| 3510 | 0) ; default to zero | 3582 | 0) ; default to zero |
| 3511 | )) | 3583 | )) |
| 3512 | ((re-search-forward | 3584 | ((re-search-forward |
| 3513 | ;; Delimiter can be special char escape \(.. or | 3585 | ;; Delimiter can be special char escape \[xxx], |
| 3514 | ;; single normal char (usually '): | 3586 | ;; \(xx or single normal char (usually '): |
| 3515 | "\\=\\\\w\\(\\\\(..\\|.\\)" nil t) | 3587 | "\\=\\\\w\\(\\\\\\[[^]]+\\]\\|\\\\(..\\|.\\)" nil t) |
| 3516 | (let ((from (match-end 0)) | 3588 | (let ((from (match-end 0)) |
| 3517 | (delim (regexp-quote (match-string 1)))) | 3589 | (delim (regexp-quote (match-string 1)))) |
| 3518 | (if (re-search-forward delim nil t) | 3590 | (if (re-search-forward delim nil t) |
| @@ -3636,7 +3708,7 @@ expression in parentheses. Leaves point after the value." | |||
| 3636 | (defun woman2-PD (to) | 3708 | (defun woman2-PD (to) |
| 3637 | ".PD d -- Set the interparagraph distance to d. | 3709 | ".PD d -- Set the interparagraph distance to d. |
| 3638 | Round to whole lines, default 1 line. Format paragraphs upto TO. | 3710 | Round to whole lines, default 1 line. Format paragraphs upto TO. |
| 3639 | (Breaks, but should not.)" | 3711 | \(Breaks, but should not.)" |
| 3640 | ;; .ie \\n[.$] .nr PD (v;\\$1) | 3712 | ;; .ie \\n[.$] .nr PD (v;\\$1) |
| 3641 | ;; .el .nr PD .4v>?\n[.V] | 3713 | ;; .el .nr PD .4v>?\n[.V] |
| 3642 | (woman-set-interparagraph-distance) | 3714 | (woman-set-interparagraph-distance) |
| @@ -3945,7 +4017,7 @@ Format paragraphs upto TO. (Breaks, but should not.)" | |||
| 3945 | 4017 | ||
| 3946 | (defun woman2-na (to) | 4018 | (defun woman2-na (to) |
| 3947 | ".na -- No adjusting. Format paragraphs upto TO. | 4019 | ".na -- No adjusting. Format paragraphs upto TO. |
| 3948 | (Breaks, but should not.)" | 4020 | \(Breaks, but should not.)" |
| 3949 | (setq woman-adjust-previous woman-adjust | 4021 | (setq woman-adjust-previous woman-adjust |
| 3950 | woman-justify-previous woman-justify | 4022 | woman-justify-previous woman-justify |
| 3951 | woman-adjust woman-adjust-left ; fill but do not adjust | 4023 | woman-adjust woman-adjust-left ; fill but do not adjust |
| @@ -4358,6 +4430,49 @@ Needs doing properly!" | |||
| 4358 | (woman2-format-paragraphs to)) | 4430 | (woman2-format-paragraphs to)) |
| 4359 | 4431 | ||
| 4360 | 4432 | ||
| 4433 | ;;; Preliminary table support (.TS/.TE) | ||
| 4434 | |||
| 4435 | (defun woman2-TS (to) | ||
| 4436 | ".TS -- Start of table code for the tbl processor. | ||
| 4437 | Format paragraphs upto TO." | ||
| 4438 | ;; This is a preliminary hack that seems to suffice for lilo.8. | ||
| 4439 | (woman-delete-line 1) ; ignore any arguments | ||
| 4440 | (when woman-emulate-tbl | ||
| 4441 | ;; Assumes column separator is \t and intercolumn spacing is 3. | ||
| 4442 | ;; The first line may optionally be a list of options terminated by | ||
| 4443 | ;; a semicolon. Currently, just delete it: | ||
| 4444 | (if (looking-at ".*;[ \t]*$") (woman-delete-line 1)) ; | ||
| 4445 | ;; The following lines must specify the format of each line of the | ||
| 4446 | ;; table and end with a period. Currently, just delete them: | ||
| 4447 | (while (not (looking-at ".*\\.[ \t]*$")) (woman-delete-line 1)) | ||
| 4448 | (woman-delete-line 1) | ||
| 4449 | ;; For each column, find its width and align it: | ||
| 4450 | (let ((start (point)) (col 1)) | ||
| 4451 | (while (prog1 (search-forward "\t" to t) (goto-char start)) | ||
| 4452 | ;; Find current column width: | ||
| 4453 | (while (< (point) to) | ||
| 4454 | (when (search-forward "\t" to t) | ||
| 4455 | (backward-char) | ||
| 4456 | (if (> (current-column) col) (setq col (current-column)))) | ||
| 4457 | (forward-line)) | ||
| 4458 | ;; Align current column: | ||
| 4459 | (goto-char start) | ||
| 4460 | (setq col (+ col 3)) ; intercolumn space | ||
| 4461 | (while (< (point) to) | ||
| 4462 | (when (search-forward "\t" to t) | ||
| 4463 | (delete-char -1) | ||
| 4464 | (insert-char ?\ (- col (current-column)))) | ||
| 4465 | (forward-line)) | ||
| 4466 | (goto-char start)))) | ||
| 4467 | ;; Format table with no filling or adjusting (cf. woman2-nf): | ||
| 4468 | (setq woman-nofill t) | ||
| 4469 | (woman2-format-paragraphs to)) | ||
| 4470 | |||
| 4471 | (defalias 'woman2-TE 'woman2-fi) | ||
| 4472 | ;; ".TE -- End of table code for the tbl processor." | ||
| 4473 | ;; Turn filling and adjusting back on. | ||
| 4474 | |||
| 4475 | |||
| 4361 | ;;; WoMan message logging: | 4476 | ;;; WoMan message logging: |
| 4362 | 4477 | ||
| 4363 | ;; The basis for this logging code was shamelessly pirated from bytecomp.el | 4478 | ;; The basis for this logging code was shamelessly pirated from bytecomp.el |
| @@ -4433,70 +4548,4 @@ logging the message." | |||
| 4433 | 4548 | ||
| 4434 | (provide 'woman) | 4549 | (provide 'woman) |
| 4435 | 4550 | ||
| 4436 | ;; RECENT CHANGE LOG | ||
| 4437 | ;; ================= | ||
| 4438 | |||
| 4439 | ;; Changes in version 0.50 ([*] => user interface change) | ||
| 4440 | ;; [*] Requires GNU Emacs 20.3+. | ||
| 4441 | ;; [*] `defface' used to define faces. | ||
| 4442 | ;; [*] Follow `see also' references with mouse-2 click. | ||
| 4443 | ;; Number register increment support added (woman-registers). | ||
| 4444 | ;; .j must be a NUMBER acceptable by .ad request. | ||
| 4445 | ;; Very crude field support added. | ||
| 4446 | ;; Vertical unit specifier `v' added to register handling. | ||
| 4447 | ;; Improvement to local horizontal motion processing. | ||
| 4448 | ;; Minor fix to handle negative numeric arguments. | ||
| 4449 | ;; Handle horizontal motion escapes `\h' better. | ||
| 4450 | ;; Allow arbitrary delimiters in `.if', inc. special character escapes. | ||
| 4451 | ;; Allow `\n' within `.if' string comparisons. | ||
| 4452 | ;; Allow arbitrary delimiters in `\w', inc. special character escapes. | ||
| 4453 | ;; Processing of `\h' moved much later -- after indenting etc! | ||
| 4454 | |||
| 4455 | ;; Changes in version 0.51 ([*] => user interface change) | ||
| 4456 | ;; [*] Improved handling of underlined faces (mainly for "italics"). | ||
| 4457 | ;; [*] Allow environment variables in directory path elements. | ||
| 4458 | ;; Display of pre-formatted files improved. | ||
| 4459 | ;; [*] Unintentional interaction with standard Man mode reduced. | ||
| 4460 | ;; [*] bzip2 decompression support added. All decompression now | ||
| 4461 | ;; works by turning on `auto-compression-mode' to decompress the | ||
| 4462 | ;; file if necessary, rather than decompressing explicitly. | ||
| 4463 | ;; Filename and compression regexps are now customizable user | ||
| 4464 | ;; options. | ||
| 4465 | |||
| 4466 | ;; Changes in version 0.52 ([*] => user interface change) | ||
| 4467 | ;; Speeded up handling of underlined faces (mainly for "italics"). | ||
| 4468 | ;; [*] WoMan formatting time display and log added. Emacs `man' | ||
| 4469 | ;; formatting time display advice added. (This suggests that | ||
| 4470 | ;; WoMan formatting is faster than Emacs `man' *formatting*, | ||
| 4471 | ;; i.e. when man is not using `catman' caching. E.g. `woman | ||
| 4472 | ;; bash' takes 27s whereas `man bash' takes 35s and for smaller | ||
| 4473 | ;; files `woman' can be relatively much faster than `man'.) | ||
| 4474 | ;; [*] Experimental support for non-ASCII characters from the | ||
| 4475 | ;; default and symbol fonts added, initially only for MS-Windows. | ||
| 4476 | ;; NOTE: It is off by default, mainly because it may increase the | ||
| 4477 | ;; line spacing; customize `woman-use-symbols' to `on' to use it. | ||
| 4478 | ;; Pad character handling for .fc fixed. | ||
| 4479 | ;; Tested: see `woman.status'. | ||
| 4480 | |||
| 4481 | ;; Changes in version 0.53 ([*] => user interface change) | ||
| 4482 | ;; [*] Customization option to use a separate frame for WoMan windows. | ||
| 4483 | ;; [*] Experimental option to emulate nroff (default) or troff (not tested). | ||
| 4484 | ;; [*] Separation of extended and symbol font options. | ||
| 4485 | ;; Only symbol font size 16 seems to work, and only with Win 95, not NT! | ||
| 4486 | ;; [*] `Advanced' sub-menu containing: | ||
| 4487 | ;; `View Source' option; | ||
| 4488 | ;; `Show Log' option; | ||
| 4489 | ;; `Extended Font' toggle and reformat; | ||
| 4490 | ;; `Symbol Font' toggle and reformat; | ||
| 4491 | ;; `Font Map' option; | ||
| 4492 | ;; `Emulation' radio buttons. | ||
| 4493 | ;; [*] Support for man config file added for default manpath. | ||
| 4494 | |||
| 4495 | ;; Changes in version 0.54 | ||
| 4496 | ;; Revised for distribution with Emacs 21. | ||
| 4497 | ;; Comment order and doc strings changed substantially. | ||
| 4498 | ;; MS-DOS support added (by Eli Zaretskii). | ||
| 4499 | ;; checkdoc run: no real errors. | ||
| 4500 | ;; woman topic interface speeded up. | ||
| 4501 | |||
| 4502 | ;;; woman.el ends here | 4551 | ;;; woman.el ends here |