Mercurial > emacs
comparison lisp/woman.el @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | 99be3a1e2589 |
children |
comparison
equal
deleted
inserted
replaced
88154:8ce476d3ba36 | 88155:d7ddb3e565de |
---|---|
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, 2002 Free Software Foundation, Inc. | 3 ;; Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Author: Francis J. Wright <F.J.Wright@qmul.ac.uk> | 5 ;; Author: Francis J. Wright <F.J.Wright@qmul.ac.uk> |
6 ;; Maintainer: Francis J. Wright <F.J.Wright@qmul.ac.uk> | 6 ;; Maintainer: FSF |
7 ;; Keywords: help, unix | 7 ;; Keywords: help, unix |
8 ;; Adapted-By: Eli Zaretskii <eliz@is.elta.co.il> | 8 ;; Adapted-By: Eli Zaretskii <eliz@gnu.org> |
9 ;; Version: see `woman-version' | 9 ;; Version: see `woman-version' |
10 ;; URL: http://centaur.maths.qmul.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 |
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 ;; GNU General Public License for more details. | 22 ;; GNU General Public License for more details. |
23 | 23 |
24 ;; You should have received a copy of the GNU General Public License | 24 ;; You should have received a copy of the GNU General Public License |
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the | 25 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
27 ;; Boston, MA 02111-1307, USA. | 27 ;; Boston, MA 02110-1301, USA. |
28 | 28 |
29 ;;; Commentary: | 29 ;;; Commentary: |
30 | 30 |
31 ;; WoMan implements a subset of the formatting performed by the Emacs | 31 ;; WoMan implements a subset of the formatting performed by the Emacs |
32 ;; `man' (or `manual-entry') command to format a UN*X manual `page' | 32 ;; `man' (or `manual-entry') command to format a UN*X manual `page' |
134 ;; Start menu) just execute | 134 ;; Start menu) just execute |
135 | 135 |
136 ;; man man_page_name | 136 ;; man man_page_name |
137 | 137 |
138 | 138 |
139 ;; Using the `word at point' as a topic suggestion | 139 ;; Using the word at point as the default topic |
140 ;; =============================================== | 140 ;; ============================================ |
141 | 141 |
142 ;; By default, the `woman' command uses the word nearest to point in | 142 ;; The `woman' command uses the word nearest to point in the current |
143 ;; the current buffer as a suggestion for the topic to look up. The | 143 ;; buffer as the default topic to look up if it matches the name of a |
144 ;; topic must be confirmed or edited in the minibuffer. This | 144 ;; manual page installed on the system. The default topic can also be |
145 ;; suggestion can be turned off, or `woman' can use the suggested | 145 ;; used without confirmation by setting the user-option |
146 ;; topic without confirmation* if possible, by setting the user-option | 146 ;; `woman-use-topic-at-point' to t; thanks to Benjamin Riefenstahl for |
147 ;; `woman-topic-at-point' to nil or t respectively. (Its default | 147 ;; suggesting this functionality. |
148 ;; value is neither nil nor t, meaning ask for confirmation.) | 148 |
149 | 149 ;; The variable `woman-use-topic-at-point' can be rebound locally, |
150 ;; [* Thanks to Benjamin Riefenstahl for suggesting this | 150 ;; which may be useful to provide special private key bindings, e.g. |
151 ;; functionality.] | |
152 | |
153 ;; The variable `woman-topic-at-point' can be rebound locally, which | |
154 ;; may be useful to provide special private key bindings, e.g. | |
155 | 151 |
156 ;; (global-set-key "\C-cw" | 152 ;; (global-set-key "\C-cw" |
157 ;; (lambda () | 153 ;; (lambda () |
158 ;; (interactive) | 154 ;; (interactive) |
159 ;; (let ((woman-topic-at-point t)) | 155 ;; (let ((woman-use-topic-at-point t)) |
160 ;; (woman))))) | 156 ;; (woman))))) |
161 | 157 |
162 | 158 |
163 ;; Customization, Hooks and Imenu | 159 ;; Customization, Hooks and Imenu |
164 ;; ============================== | 160 ;; ============================== |
400 ;; Nicolai Henriksen <nhe@lyngso-industri.dk> | 396 ;; Nicolai Henriksen <nhe@lyngso-industri.dk> |
401 ;; Thomas Herchenroeder <the@software-ag.de> | 397 ;; Thomas Herchenroeder <the@software-ag.de> |
402 ;; Alexander Hinds <ahinds@thegrid.net> | 398 ;; Alexander Hinds <ahinds@thegrid.net> |
403 ;; Stefan Hornburg <sth@hacon.de> | 399 ;; Stefan Hornburg <sth@hacon.de> |
404 ;; Theodore Jump <tjump@cais.com> | 400 ;; Theodore Jump <tjump@cais.com> |
401 ;; David Kastrup <dak@gnu.org> | |
405 ;; Paul Kinnucan <paulk@mathworks.com> | 402 ;; Paul Kinnucan <paulk@mathworks.com> |
406 ;; Jonas Linde <jonas@init.se> | 403 ;; Jonas Linde <jonas@init.se> |
407 ;; Andrew McRae <andrewm@optimation.co.nz> | 404 ;; Andrew McRae <andrewm@optimation.co.nz> |
408 ;; Howard Melman <howard@silverstream.com> | 405 ;; Howard Melman <howard@silverstream.com> |
409 ;; Dennis Pixton <dennis@math.binghamton.edu> | 406 ;; Dennis Pixton <dennis@math.binghamton.edu> |
417 ;; Karel Sprenger <ks@ic.uva.nl> | 414 ;; Karel Sprenger <ks@ic.uva.nl> |
418 ;; Chris Szurgot <szurgot@itribe.net> | 415 ;; Chris Szurgot <szurgot@itribe.net> |
419 ;; Paul A. Thompson <pat@po.cwru.edu> | 416 ;; Paul A. Thompson <pat@po.cwru.edu> |
420 ;; Arrigo Triulzi <arrigo@maths.qmw.ac.uk> | 417 ;; Arrigo Triulzi <arrigo@maths.qmw.ac.uk> |
421 ;; Geoff Voelker <voelker@cs.washington.edu> | 418 ;; Geoff Voelker <voelker@cs.washington.edu> |
422 ;; Eli Zaretskii <eliz@is.elta.co.il> | 419 ;; Eli Zaretskii <eliz@gnu.org> |
423 | |
424 ;;; History: | |
425 ;; For recent change log see end of file. | |
426 | 420 |
427 | 421 |
428 ;;; Code: | 422 ;;; Code: |
429 | 423 |
430 (defvar woman-version "0.551 (beta)" "WoMan version information.") | 424 (defvar woman-version "0.551 (beta)" "WoMan version information.") |
431 | 425 |
432 (require 'man) | 426 (require 'man) |
427 (require 'button) | |
428 (define-button-type 'WoMan-xref-man-page | |
429 :supertype 'Man-abstract-xref-man-page | |
430 'func 'woman) | |
431 | |
433 (eval-when-compile ; to avoid compiler warnings | 432 (eval-when-compile ; to avoid compiler warnings |
434 (require 'dired) | 433 (require 'dired) |
435 (require 'apropos)) | 434 (require 'apropos)) |
436 | 435 |
437 (defun woman-mapcan (fn x) | 436 (defun woman-mapcan (fn x) |
438 "Return concatenated list of FN applied to successive `car' elements of X. | 437 "Return concatenated list of FN applied to successive `car' elements of X. |
439 FN must return a list, cons or nil. Useful for splicing into a list." | 438 FN must return a list, cons or nil. Useful for splicing into a list." |
440 ;; Based on the Standard Lisp function MAPCAN but with args swapped! | 439 ;; Based on the Standard Lisp function MAPCAN but with args swapped! |
441 (and x (nconc (funcall fn (car x)) (woman-mapcan fn (cdr x))))) | 440 ;; More concise implementation than the recursive one. -- dak |
441 (apply #'nconc (mapcar fn x))) | |
442 | 442 |
443 (defun woman-parse-colon-path (paths) | 443 (defun woman-parse-colon-path (paths) |
444 "Explode search path string PATHS 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. | 445 Allow Cygwin colon-separated search paths on Microsoft platforms. |
446 Replace null components by calling `woman-parse-man.conf'. | 446 Replace null components by calling `woman-parse-man.conf'. |
537 (let ((path '("/usr/lib" "/etc"))) | 537 (let ((path '("/usr/lib" "/etc"))) |
538 (if (eq system-type 'windows-nt) | 538 (if (eq system-type 'windows-nt) |
539 (mapcar 'woman-Cyg-to-Win path) | 539 (mapcar 'woman-Cyg-to-Win path) |
540 path)) | 540 path)) |
541 "*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. |
542 A trailing separator (`/' for UNIX etc.) on directories is optional | 542 A trailing separator (`/' for UNIX etc.) on directories is optional, |
543 and the filename used if a directory is specified is the first to | 543 and the filename is used if a directory specified is the first to |
544 match the regexp \"man.*\\.conf\". | 544 contain the strings \"man\" and \".conf\" (in that order). |
545 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 |
546 instead to provide a default value for `woman-manpath'." | 546 instead to provide a default value for `woman-manpath'." |
547 :type '(repeat string) | 547 :type '(repeat string) |
548 :group 'woman-interface) | 548 :group 'woman-interface) |
549 | 549 |
552 Used only if MANPATH is not set or contains null components. | 552 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'. | 553 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 | 554 Concatenate data from all lines in the config file of the form |
555 MANPATH /usr/man | 555 MANPATH /usr/man |
556 or | 556 or |
557 MANDATORY_MANPATH /usr/man" | 557 MANDATORY_MANPATH /usr/man |
558 or | |
559 OPTIONAL_MANPATH /usr/man" | |
558 ;; Functionality suggested by Charles Curley. | 560 ;; Functionality suggested by Charles Curley. |
559 (let ((path woman-man.conf-path) | 561 (let ((path woman-man.conf-path) |
560 file manpath) | 562 file manpath) |
561 (while (and | 563 (while (and |
562 path | 564 path |
572 (with-temp-buffer | 574 (with-temp-buffer |
573 (insert-file-contents file) | 575 (insert-file-contents file) |
574 (while (re-search-forward | 576 (while (re-search-forward |
575 ;; `\(?: ... \)' is a "shy group" | 577 ;; `\(?: ... \)' is a "shy group" |
576 "\ | 578 "\ |
577 ^[ \t]*\\(?:MANDATORY_\\)?MANPATH[ \t]+\\(\\S-+\\)" nil t) | 579 ^[ \t]*\\(?:MANDATORY_\\|OPTIONAL_\\)?MANPATH[ \t]+\\(\\S-+\\)" nil t) |
578 (setq manpath (cons (match-string 1) manpath))) | 580 (setq manpath (cons (match-string 1) manpath))) |
579 manpath)) | 581 manpath)) |
580 )) | 582 )) |
581 (setq path (cdr path))) | 583 (setq path (cdr path))) |
582 (nreverse manpath))) | 584 (nreverse manpath))) |
708 "*The title to use if WoMan adds a Contents menu to the menubar. | 710 "*The title to use if WoMan adds a Contents menu to the menubar. |
709 Default is \"CONTENTS\"." | 711 Default is \"CONTENTS\"." |
710 :type 'string | 712 :type 'string |
711 :group 'woman-interface) | 713 :group 'woman-interface) |
712 | 714 |
713 (defcustom woman-topic-at-point-default 'confirm | 715 (defcustom woman-use-topic-at-point-default nil |
714 ;; `woman-topic-at-point' may be let-bound when woman is loaded, in | 716 ;; `woman-use-topic-at-point' may be let-bound when woman is loaded, |
715 ;; which case its global value does not get defined. | 717 ;; in which case its global value does not get defined. |
716 ;; `woman-file-name' sets it to this value if it is unbound. | 718 ;; `woman-file-name' sets it to this value if it is unbound. |
717 "*Default value for `woman-topic-at-point'." | 719 "*Default value for `woman-use-topic-at-point'." |
718 :type '(choice (const :tag "Yes" t) | 720 :type '(choice (const :tag "Yes" t) |
719 (const :tag "No" nil) | 721 (const :tag "No" nil)) |
720 (other :tag "Confirm" confirm)) | |
721 :group 'woman-interface) | 722 :group 'woman-interface) |
722 | 723 |
723 (defcustom woman-topic-at-point woman-topic-at-point-default | 724 (defcustom woman-use-topic-at-point woman-use-topic-at-point-default |
724 "*Controls use by `woman' of `word at point' as a topic suggestion. | 725 "*Control use of the word at point as the default topic. |
725 If non-nil then the `woman' command uses the word at point as an | 726 If non-nil the `woman' command uses the word at point automatically, |
726 initial topic suggestion when it reads a topic from the minibuffer; if | 727 without interactive confirmation, if it exists as a topic." |
727 t then the `woman' command uses the word at point WITHOUT | |
728 INTERACTIVE CONFIRMATION if it exists as a topic. The default value | |
729 is `confirm', meaning suggest a topic and ask for confirmation." | |
730 :type '(choice (const :tag "Yes" t) | 728 :type '(choice (const :tag "Yes" t) |
731 (const :tag "No" nil) | 729 (const :tag "No" nil)) |
732 (other :tag "Confirm" confirm)) | |
733 :group 'woman-interface) | 730 :group 'woman-interface) |
734 | 731 |
735 (defvar woman-file-regexp nil | 732 (defvar woman-file-regexp nil |
736 "Regexp used to select (possibly compressed) man source files, e.g. | 733 "Regexp used to select (possibly compressed) man source files, e.g. |
737 \"\\.\\([0-9lmnt]\\w*\\)\\(\\.\\(g?z\\|bz2\\)\\)?\\'\". | 734 \"\\.\\([0-9lmnt]\\w*\\)\\(\\.\\(g?z\\|bz2\\)\\)?\\'\". |
805 :type 'integer | 802 :type 'integer |
806 :group 'woman-formatting) | 803 :group 'woman-formatting) |
807 | 804 |
808 (defcustom woman-fill-frame nil | 805 (defcustom woman-fill-frame nil |
809 ;; Based loosely on a suggestion by Theodore Jump: | 806 ;; Based loosely on a suggestion by Theodore Jump: |
810 "*If non-nil then most of the frame width is used." | 807 "*If non-nil then most of the window width is used." |
811 :type 'boolean | 808 :type 'boolean |
812 :group 'woman-formatting) | 809 :group 'woman-formatting) |
813 | 810 |
814 (defcustom woman-default-indent 5 | 811 (defcustom woman-default-indent 5 |
815 "*Default prevailing indent set by -man macros -- default is 5. | 812 "*Default prevailing indent set by -man macros -- default is 5. |
817 :type 'integer | 814 :type 'integer |
818 :group 'woman-formatting) | 815 :group 'woman-formatting) |
819 | 816 |
820 (defcustom woman-bold-headings t | 817 (defcustom woman-bold-headings t |
821 "*If non-nil then embolden section and subsection headings. Default is t. | 818 "*If non-nil then embolden section and subsection headings. Default is t. |
822 Heading emboldening is NOT standard `man' behaviour." | 819 Heading emboldening is NOT standard `man' behavior." |
823 :type 'boolean | 820 :type 'boolean |
824 :group 'woman-formatting) | 821 :group 'woman-formatting) |
825 | 822 |
826 (defcustom woman-ignore t | 823 (defcustom woman-ignore t |
827 "*If non-nil then unrecognised requests etc. are ignored. Default is t. | 824 "*If non-nil then unrecognized requests etc. are ignored. Default is t. |
828 This gives the standard ?roff behaviour. If nil then they are left in | 825 This gives the standard ?roff behavior. If nil then they are left in |
829 the buffer, which may aid debugging." | 826 the buffer, which may aid debugging." |
830 :type 'boolean | 827 :type 'boolean |
831 :group 'woman-formatting) | 828 :group 'woman-formatting) |
832 | 829 |
833 (defcustom woman-preserve-ascii nil | 830 (defcustom woman-preserve-ascii t |
834 "*If non-nil then preserve ASCII characters in the WoMan buffer. | 831 "*If non-nil, preserve ASCII characters in the WoMan buffer. |
835 Otherwise, non-ASCII characters (that display as ASCII) may remain. | 832 Otherwise, to save time, some backslashes and spaces may be |
836 This is irrelevant unless the buffer is to be saved to a file." | 833 represented differently (as the values of the variables |
834 `woman-escaped-escape-char' and `woman-unpadded-space-char' | |
835 respectively) so that the buffer content is strictly wrong even though | |
836 it should display correctly. This should be irrelevant unless the | |
837 buffer text is searched, copied or saved to a file." | |
838 ;; This option should probably be removed! | |
837 :type 'boolean | 839 :type 'boolean |
838 :group 'woman-formatting) | 840 :group 'woman-formatting) |
839 | 841 |
840 (defcustom woman-emulation 'nroff | 842 (defcustom woman-emulation 'nroff |
841 "*WoMan emulation, currently either nroff or troff. Default is nroff. | 843 "*WoMan emulation, currently either nroff or troff. Default is nroff. |
864 :group 'woman-faces) | 866 :group 'woman-faces) |
865 | 867 |
866 ;; This is overkill! Troff uses just italic; Nroff uses just underline. | 868 ;; This is overkill! Troff uses just italic; Nroff uses just underline. |
867 ;; You should probably select either italic or underline as you prefer, but | 869 ;; You should probably select either italic or underline as you prefer, but |
868 ;; not both, although italic and underline work together perfectly well! | 870 ;; not both, although italic and underline work together perfectly well! |
869 (defface woman-italic-face | 871 (defface woman-italic |
870 `((((background light)) (:slant italic :underline t :foreground "red")) | 872 `((((min-colors 88) (background light)) |
873 (:slant italic :underline t :foreground "red1")) | |
874 (((background light)) (:slant italic :underline t :foreground "red")) | |
871 (((background dark)) (:slant italic :underline t))) | 875 (((background dark)) (:slant italic :underline t))) |
872 "Face for italic font in man pages." | 876 "Face for italic font in man pages." |
873 :group 'woman-faces) | 877 :group 'woman-faces) |
874 | 878 ;; backward-compatibility alias |
875 (defface woman-bold-face | 879 (put 'woman-italic-face 'face-alias 'woman-italic) |
876 '((((background light)) (:weight bold :foreground "blue")) | 880 |
881 (defface woman-bold | |
882 '((((min-colors 88) (background light)) (:weight bold :foreground "blue1")) | |
883 (((background light)) (:weight bold :foreground "blue")) | |
877 (((background dark)) (:weight bold :foreground "green2"))) | 884 (((background dark)) (:weight bold :foreground "green2"))) |
878 "Face for bold font in man pages." | 885 "Face for bold font in man pages." |
879 :group 'woman-faces) | 886 :group 'woman-faces) |
887 ;; backward-compatibility alias | |
888 (put 'woman-bold-face 'face-alias 'woman-bold) | |
880 | 889 |
881 ;; Brown is a good compromise: it is distinguishable from the default | 890 ;; Brown is a good compromise: it is distinguishable from the default |
882 ;; but not enough so to make font errors look terrible. (Files that use | 891 ;; but not enough so to make font errors look terrible. (Files that use |
883 ;; non-standard fonts seem to do so badly or in idiosyncratic ways!) | 892 ;; non-standard fonts seem to do so badly or in idiosyncratic ways!) |
884 (defface woman-unknown-face | 893 (defface woman-unknown |
885 '((((background light)) (:foreground "brown")) | 894 '((((background light)) (:foreground "brown")) |
895 (((min-colors 88) (background dark)) (:foreground "cyan1")) | |
886 (((background dark)) (:foreground "cyan"))) | 896 (((background dark)) (:foreground "cyan"))) |
887 "Face for all unknown fonts in man pages." | 897 "Face for all unknown fonts in man pages." |
888 :group 'woman-faces) | 898 :group 'woman-faces) |
889 | 899 ;; backward-compatibility alias |
890 (defface woman-addition-face | 900 (put 'woman-unknown-face 'face-alias 'woman-unknown) |
901 | |
902 (defface woman-addition | |
891 '((t (:foreground "orange"))) | 903 '((t (:foreground "orange"))) |
892 "Face for all WoMan additions to man pages." | 904 "Face for all WoMan additions to man pages." |
893 :group 'woman-faces) | 905 :group 'woman-faces) |
906 ;; backward-compatibility alias | |
907 (put 'woman-addition-face 'face-alias 'woman-addition) | |
894 | 908 |
895 (defun woman-default-faces () | 909 (defun woman-default-faces () |
896 "Set foreground colours of italic and bold faces to their default values." | 910 "Set foreground colors of italic and bold faces to their default values." |
897 (interactive) | 911 (interactive) |
898 (face-spec-set 'woman-italic-face | 912 (face-spec-set 'woman-italic (face-user-default-spec 'woman-italic)) |
899 (face-user-default-spec 'woman-italic-face)) | 913 (face-spec-set 'woman-bold (face-user-default-spec 'woman-bold))) |
900 (face-spec-set 'woman-bold-face (face-user-default-spec 'woman-bold-face))) | |
901 | 914 |
902 (defun woman-monochrome-faces () | 915 (defun woman-monochrome-faces () |
903 "Set foreground colours of italic and bold faces to that of the default face. | 916 "Set foreground colors of italic and bold faces to that of the default face. |
904 This is usually either black or white." | 917 This is usually either black or white." |
905 (interactive) | 918 (interactive) |
906 (set-face-foreground 'woman-italic-face 'unspecified) | 919 (set-face-foreground 'woman-italic 'unspecified) |
907 (set-face-foreground 'woman-bold-face 'unspecified)) | 920 (set-face-foreground 'woman-bold 'unspecified)) |
908 | 921 |
909 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 922 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
910 ;; Experimental font support, initially only for MS-Windows. | 923 ;; Experimental font support, initially only for MS-Windows. |
911 (defconst woman-font-support | 924 (defconst woman-font-support |
912 (eq window-system 'w32) ; Support X later! | 925 (eq window-system 'w32) ; Support X later! |
923 (setq symbol-fonts (cons (car fonts) symbol-fonts))) | 936 (setq symbol-fonts (cons (car fonts) symbol-fonts))) |
924 (setq fonts (cdr fonts))) | 937 (setq fonts (cdr fonts))) |
925 symbol-fonts)) | 938 symbol-fonts)) |
926 | 939 |
927 (when woman-font-support | 940 (when woman-font-support |
928 (make-face 'woman-symbol-face) | 941 (make-face 'woman-symbol) |
929 | 942 |
930 ;; Set the symbol font only if `woman-use-symbol-font' is true, to | 943 ;; Set the symbol font only if `woman-use-symbol-font' is true, to |
931 ;; avoid unnecessarily upsetting the line spacing in NTEmacs 20.5! | 944 ;; avoid unnecessarily upsetting the line spacing in NTEmacs 20.5! |
932 | 945 |
933 (defcustom woman-use-extended-font t | 946 (defcustom woman-use-extended-font t |
934 "*If non-nil then may use non-ASCII characters from the default font." | 947 "*If non-nil then may use non-ASCII characters from the default font." |
935 :type 'boolean | 948 :type 'boolean |
936 :group 'woman-faces) | 949 :group 'woman-faces) |
937 | 950 |
938 (defcustom woman-use-symbol-font nil | 951 (defcustom woman-use-symbol-font nil |
939 "*If non-nil then may use the symbol font. It is off by default, | 952 "*If non-nil then may use the symbol font. |
940 mainly because it may change the line spacing (in NTEmacs 20.5)." | 953 It is off by default, mainly because it may change the line spacing |
954 \(in NTEmacs 20.5)." | |
941 :type 'boolean | 955 :type 'boolean |
942 :group 'woman-faces) | 956 :group 'woman-faces) |
943 | 957 |
944 (defconst woman-symbol-font-list | 958 (defconst woman-symbol-font-list |
945 (or (woman-select-symbol-fonts (x-list-fonts "*" 'default)) | 959 (or (woman-select-symbol-fonts (x-list-fonts "*" 'default)) |
1013 | 1027 |
1014 (defsubst woman-reset-nospace () | 1028 (defsubst woman-reset-nospace () |
1015 "Set `woman-nospace' to nil." | 1029 "Set `woman-nospace' to nil." |
1016 (setq woman-nospace nil)) | 1030 (setq woman-nospace nil)) |
1017 | 1031 |
1018 (defconst woman-mode-line-format | |
1019 ;; This is essentially the Man-mode format with page numbers removed | |
1020 ;; and line numbers added. (Online documents do not have pages, but | |
1021 ;; they do have lines!) | |
1022 '("-" mode-line-mule-info mode-line-modified | |
1023 mode-line-frame-identification mode-line-buffer-identification | |
1024 " " global-mode-string | |
1025 " %[(WoMan" mode-line-process minor-mode-alist ")%]--" | |
1026 (line-number-mode "L%l--") | |
1027 (-3 . "%p") "-%-") | |
1028 "Mode line format for WoMan buffer.") | |
1029 | |
1030 (defconst woman-request-regexp "^[.'][ \t]*\\(\\S +\\) *" | 1032 (defconst woman-request-regexp "^[.'][ \t]*\\(\\S +\\) *" |
1031 ;; Was "^\\.[ \t]*\\([a-z0-9]+\\) *" but cvs.1 uses a macro named | 1033 ;; Was "^\\.[ \t]*\\([a-z0-9]+\\) *" but cvs.1 uses a macro named |
1032 ;; "`" and CGI.man uses a macro named "''"! | 1034 ;; "`" and CGI.man uses a macro named "''"! |
1033 ;; CGI.man uses ' as control character in places -- it *should* | 1035 ;; CGI.man uses ' as control character in places -- it *should* |
1034 ;; suppress breaks! | 1036 ;; suppress breaks! |
1055 | 1057 |
1056 (defvar woman-if-conditions-true '(?n ?e ?o) | 1058 (defvar woman-if-conditions-true '(?n ?e ?o) |
1057 "List of one-character built-in condition names that are true. | 1059 "List of one-character built-in condition names that are true. |
1058 Should include ?e, ?o (page even/odd) and either ?n (nroff) or ?t (troff). | 1060 Should include ?e, ?o (page even/odd) and either ?n (nroff) or ?t (troff). |
1059 Default is '(?n ?e ?o). Set via `woman-emulation'.") | 1061 Default is '(?n ?e ?o). Set via `woman-emulation'.") |
1060 | |
1061 | |
1062 ;;; Button types: | |
1063 | |
1064 (define-button-type 'woman-xref | |
1065 'action (lambda (button) (woman (button-label button))) | |
1066 'help-echo "RET, mouse-2: display this man page") | |
1067 | 1062 |
1068 | 1063 |
1069 ;;; Specialized utility functions: | 1064 ;;; Specialized utility functions: |
1070 | 1065 |
1071 ;;; Fast deletion without saving on the kill ring (cf. simple.el): | 1066 ;;; Fast deletion without saving on the kill ring (cf. simple.el): |
1128 | 1123 |
1129 Used non-interactively, arguments are optional: if given then TOPIC | 1124 Used non-interactively, arguments are optional: if given then TOPIC |
1130 should be a topic string and non-nil RE-CACHE forces re-caching." | 1125 should be a topic string and non-nil RE-CACHE forces re-caching." |
1131 (interactive (list nil current-prefix-arg)) | 1126 (interactive (list nil current-prefix-arg)) |
1132 ;; The following test is for non-interactive calls via gnudoit etc. | 1127 ;; The following test is for non-interactive calls via gnudoit etc. |
1133 (if (or (interactive-p) (not (stringp topic)) (string-match "\\S " topic)) | 1128 (if (or (not (stringp topic)) (string-match "\\S " topic)) |
1134 (let ((file-name (woman-file-name topic re-cache))) | 1129 (let ((file-name (woman-file-name topic re-cache))) |
1135 (if file-name | 1130 (if file-name |
1136 (woman-find-file file-name) | 1131 (woman-find-file file-name) |
1137 (message | 1132 (message |
1138 "WoMan Error: No matching manual files found in search path") | 1133 "WoMan Error: No matching manual files found in search path") |
1197 (defvar woman-topic-history nil "Topic read history.") | 1192 (defvar woman-topic-history nil "Topic read history.") |
1198 (defvar woman-file-history nil "File-name read history.") | 1193 (defvar woman-file-history nil "File-name read history.") |
1199 | 1194 |
1200 (defun woman-file-name (topic &optional re-cache) | 1195 (defun woman-file-name (topic &optional re-cache) |
1201 "Get the name of the UN*X man-page file describing a chosen TOPIC. | 1196 "Get the name of the UN*X man-page file describing a chosen TOPIC. |
1202 When `woman' is called interactively, the word at point may be used as | 1197 When `woman' is called interactively, the word at point may be |
1203 the topic or initial topic suggestion, subject to the value of the | 1198 automatically used as the topic, if the value of the user option |
1204 user option `woman-topic-at-point'. Return nil if no file can be found. | 1199 `woman-use-topic-at-point' is non-nil. Return nil if no file can |
1205 Optional argument RE-CACHE, if non-nil, forces the cache to be re-read." | 1200 be found. Optional argument RE-CACHE, if non-nil, forces the |
1201 cache to be re-read." | |
1206 ;; Handle the caching of the directory and topic lists: | 1202 ;; Handle the caching of the directory and topic lists: |
1207 (if (and (not re-cache) | 1203 (if (and (not re-cache) |
1208 (or | 1204 (or |
1209 (and woman-expanded-directory-path woman-topic-all-completions) | 1205 (and woman-expanded-directory-path woman-topic-all-completions) |
1210 (woman-read-directory-cache))) | 1206 (woman-read-directory-cache))) |
1218 (woman-write-directory-cache)) | 1214 (woman-write-directory-cache)) |
1219 ;; There is a problem in that I want to offer case-insensitive | 1215 ;; There is a problem in that I want to offer case-insensitive |
1220 ;; completions, but to return only a case-sensitive match. This | 1216 ;; completions, but to return only a case-sensitive match. This |
1221 ;; does not seem to work properly by default, so I re-do the | 1217 ;; does not seem to work properly by default, so I re-do the |
1222 ;; completion if necessary. | 1218 ;; completion if necessary. |
1223 (let (files) | 1219 (let (files |
1220 (default (current-word))) | |
1224 (or (stringp topic) | 1221 (or (stringp topic) |
1225 (and (eq t | 1222 (and (if (boundp 'woman-use-topic-at-point) |
1226 (if (boundp 'woman-topic-at-point) | 1223 woman-use-topic-at-point |
1227 woman-topic-at-point | 1224 ;; Was let-bound when file loaded, so ... |
1228 ;; Was let-bound when file loaded, so ... | 1225 (setq woman-use-topic-at-point woman-use-topic-at-point-default)) |
1229 (setq woman-topic-at-point woman-topic-at-point-default))) | 1226 (setq topic (or (current-word t) "")) ; only within or adjacent to word |
1230 (setq topic | 1227 (test-completion topic woman-topic-all-completions)) |
1231 (current-word t)) ; only within or adjacent to word | |
1232 (assoc topic woman-topic-all-completions)) | |
1233 (setq topic | 1228 (setq topic |
1234 (completing-read | 1229 (let* ((word-at-point (current-word)) |
1235 "Manual entry: " | 1230 (default |
1236 woman-topic-all-completions nil 1 | 1231 (when (and word-at-point |
1237 ;; Initial input suggestion (was nil), with | 1232 (test-completion |
1238 ;; cursor at left ready to kill suggestion!: | 1233 word-at-point woman-topic-all-completions)) |
1239 (and woman-topic-at-point | 1234 word-at-point))) |
1240 (cons (current-word) 0)) ; nearest word | 1235 (completing-read |
1241 'woman-topic-history))) | 1236 (if default |
1237 (format "Manual entry (default %s): " default) | |
1238 "Manual entry: ") | |
1239 woman-topic-all-completions nil 1 | |
1240 nil | |
1241 'woman-topic-history | |
1242 default)))) | |
1242 ;; Note that completing-read always returns a string. | 1243 ;; Note that completing-read always returns a string. |
1243 (if (= (length topic) 0) | 1244 (if (= (length topic) 0) |
1244 nil ; no topic, so no file! | 1245 nil ; no topic, so no file! |
1245 (cond | 1246 (cond |
1246 ((setq files (woman-file-name-all-completions topic))) | 1247 ((setq files (woman-file-name-all-completions topic))) |
1256 (t | 1257 (t |
1257 ;; Multiple files for topic, so must select 1. | 1258 ;; Multiple files for topic, so must select 1. |
1258 ;; Unread the command event (TAB = ?\t = 9) that runs the command | 1259 ;; Unread the command event (TAB = ?\t = 9) that runs the command |
1259 ;; `minibuffer-complete' in order to automatically complete the | 1260 ;; `minibuffer-complete' in order to automatically complete the |
1260 ;; minibuffer contents as far as possible. | 1261 ;; minibuffer contents as far as possible. |
1261 (setq unread-command-events '(9)) ; and delete any type-ahead! | 1262 (setq unread-command-events '(9)) ; and delete any type-ahead! |
1262 (completing-read "Manual file: " files nil 1 | 1263 (completing-read "Manual file: " files nil 1 |
1263 (try-completion "" files) 'woman-file-history))) | 1264 (try-completion "" files) 'woman-file-history)))))) |
1264 ))) | |
1265 | 1265 |
1266 (defun woman-select (predicate list) | 1266 (defun woman-select (predicate list) |
1267 "Select unique elements for which PREDICATE is true in LIST. | 1267 "Select unique elements for which PREDICATE is true in LIST. |
1268 \(Note that this function changes the value of LIST.)" | 1268 \(Note that this function changes the value of LIST.)" |
1269 ;; Intended to be fast by avoiding recursion and list copying. | 1269 ;; Intended to be fast by avoiding recursion and list copying. |
1365 ;; will be a list of the first `woman-cache-level' elements of the | 1365 ;; will be a list of the first `woman-cache-level' elements of the |
1366 ;; following list: (topic path-index filename). This alist `files' | 1366 ;; following list: (topic path-index filename). This alist `files' |
1367 ;; is re-processed by `woman-topic-all-completions-merge'. | 1367 ;; is re-processed by `woman-topic-all-completions-merge'. |
1368 (let (dir files (path-index 0)) ; indexing starts at zero | 1368 (let (dir files (path-index 0)) ; indexing starts at zero |
1369 (while path | 1369 (while path |
1370 (setq dir (car path) | 1370 (setq dir (pop path)) |
1371 path (cdr path)) | |
1372 (if (woman-not-member dir path) ; use each directory only once! | 1371 (if (woman-not-member dir path) ; use each directory only once! |
1373 (setq files | 1372 (push (woman-topic-all-completions-1 dir path-index) |
1374 (nconc files | 1373 files)) |
1375 (woman-topic-all-completions-1 dir path-index)))) | |
1376 (setq path-index (1+ path-index))) | 1374 (setq path-index (1+ path-index))) |
1377 ;; Uniquefy topics: | 1375 ;; Uniquefy topics: |
1378 (woman-topic-all-completions-merge files))) | 1376 ;; Concate all lists with a single nconc call to |
1377 ;; avoid retraversing the first lists repeatedly -- dak | |
1378 (woman-topic-all-completions-merge | |
1379 (apply #'nconc files)))) | |
1379 | 1380 |
1380 (defun woman-topic-all-completions-1 (dir path-index) | 1381 (defun woman-topic-all-completions-1 (dir path-index) |
1381 "Return an alist of the man topics in directory DIR with index PATH-INDEX. | 1382 "Return an alist of the man topics in directory DIR with index PATH-INDEX. |
1382 A topic is a filename sans type-related extensions. | 1383 A topic is a filename sans type-related extensions. |
1383 Support 3 levels of caching: each element of the alist will be a list | 1384 Support 3 levels of caching: each element of the alist will be a list |
1386 ;; This function used to check that each file in the directory was | 1387 ;; This function used to check that each file in the directory was |
1387 ;; not itself a directory, but this is very slow and should be | 1388 ;; not itself a directory, but this is very slow and should be |
1388 ;; unnecessary. So let us assume that `woman-file-regexp' will | 1389 ;; unnecessary. So let us assume that `woman-file-regexp' will |
1389 ;; filter out any directories, which probably should not be there | 1390 ;; filter out any directories, which probably should not be there |
1390 ;; anyway, i.e. it is a user error! | 1391 ;; anyway, i.e. it is a user error! |
1391 (mapcar | 1392 ;; |
1392 (lambda (file) | 1393 ;; Don't sort files: we do that when merging, anyway. -- dak |
1393 (cons | 1394 (let (newlst (lst (directory-files dir nil woman-file-regexp t)) |
1394 (file-name-sans-extension | 1395 ;; Make an explicit regexp for stripping extension and |
1395 (if (string-match woman-file-compression-regexp file) | 1396 ;; compression extension: file-name-sans-extension is a |
1396 (file-name-sans-extension file) | 1397 ;; far too costly function. -- dak |
1397 file)) | 1398 (ext (format "\\(\\.[^.\\/]*\\)?\\(%s\\)?\\'" |
1398 (if (> woman-cache-level 1) | 1399 woman-file-compression-regexp))) |
1399 (cons | 1400 ;; Use a loop instead of mapcar in order to avoid the speed |
1400 path-index | 1401 ;; penalty of binding function arguments. -- dak |
1401 (if (> woman-cache-level 2) | 1402 (dolist (file lst newlst) |
1402 (cons file nil)))))) | 1403 (push |
1403 (directory-files dir nil woman-file-regexp))) | 1404 (cons |
1405 (if (string-match ext file) | |
1406 (substring file 0 (match-beginning 0)) | |
1407 file) | |
1408 (and (> woman-cache-level 1) | |
1409 (cons | |
1410 path-index | |
1411 (and (> woman-cache-level 2) | |
1412 (list file))))) | |
1413 newlst)))) | |
1404 | 1414 |
1405 (defun woman-topic-all-completions-merge (alist) | 1415 (defun woman-topic-all-completions-merge (alist) |
1406 "Merge the alist ALIST so that the keys are unique. | 1416 "Merge the alist ALIST so that the keys are unique. |
1407 Also make each path-info component into a list. | 1417 Also make each path-info component into a list. |
1408 \(Note that this function changes the value of ALIST.)" | 1418 \(Note that this function changes the value of ALIST.)" |
1409 ;; Intended to be fast by avoiding recursion and list copying. | 1419 ;; Replaces unreadably "optimized" O(n^2) implementation. |
1410 (if (> woman-cache-level 1) | 1420 ;; Instead we use sorting to merge stuff efficiently. -- dak |
1411 (let ((newalist alist)) | 1421 (let (elt newalist) |
1412 (while newalist | 1422 ;; Sort list into reverse order |
1413 (let ((tail newalist) (topic (car (car newalist)))) | 1423 (setq alist (sort alist (lambda(x y) (string< (car y) (car x))))) |
1414 ;; Make the path-info into a list: | 1424 ;; merge duplicate keys. |
1415 (setcdr (car newalist) (list (cdr (car newalist)))) | 1425 (if (> woman-cache-level 1) |
1416 (while tail | 1426 (while alist |
1417 (while (and tail (not (string= topic (car (car (cdr tail)))))) | 1427 (setq elt (pop alist)) |
1418 (setq tail (cdr tail))) | 1428 (if (equal (car elt) (caar newalist)) |
1419 (if tail ; merge path-info into (car newalist) | 1429 (unless (member (cdr elt) (cdar newalist)) |
1420 (let ((path-info (cdr (car (cdr tail))))) | 1430 (setcdr (car newalist) (cons (cdr elt) |
1421 (if (member path-info (cdr (car newalist))) | 1431 (cdar newalist)))) |
1422 () | 1432 (setcdr elt (list (cdr elt))) |
1423 ;; Make the path-info into a list: | 1433 (push elt newalist))) |
1424 (nconc (car newalist) (list path-info))) | |
1425 (setcdr tail (cdr (cdr tail)))) | |
1426 )) | |
1427 (setq newalist (cdr newalist)))) | |
1428 alist) | |
1429 ;; woman-cache-level = 1 => elements are single-element lists ... | 1434 ;; woman-cache-level = 1 => elements are single-element lists ... |
1430 (while (and alist (member (car alist) (cdr alist))) | 1435 (while alist |
1431 (setq alist (cdr alist))) | 1436 (setq elt (pop alist)) |
1432 (if alist | 1437 (unless (equal (car elt) (caar newalist)) |
1433 (let ((newalist alist) cdr_alist) | 1438 (push elt newalist)))) |
1434 (while (setq cdr_alist (cdr alist)) | 1439 newalist)) |
1435 (if (not (member (car cdr_alist) (cdr cdr_alist))) | |
1436 (setq alist cdr_alist) | |
1437 (setcdr alist (cdr cdr_alist))) | |
1438 ) | |
1439 newalist)))) | |
1440 | 1440 |
1441 (defun woman-file-name-all-completions (topic) | 1441 (defun woman-file-name-all-completions (topic) |
1442 "Return an alist of the files in all man directories that match TOPIC." | 1442 "Return an alist of the files in all man directories that match TOPIC." |
1443 ;; Support 3 levels of caching: each element of | 1443 ;; Support 3 levels of caching: each element of |
1444 ;; woman-topic-all-completions is a list of one of the forms: | 1444 ;; woman-topic-all-completions is a list of one of the forms: |
1487 "Bind the argument KEY to the command `woman-dired-find-file'." | 1487 "Bind the argument KEY to the command `woman-dired-find-file'." |
1488 (define-key dired-mode-map key 'woman-dired-find-file)) | 1488 (define-key dired-mode-map key 'woman-dired-find-file)) |
1489 | 1489 |
1490 (defsubst woman-dired-define-key-maybe (key) | 1490 (defsubst woman-dired-define-key-maybe (key) |
1491 "If KEY is undefined in Dired, bind it to command `woman-dired-find-file'." | 1491 "If KEY is undefined in Dired, bind it to command `woman-dired-find-file'." |
1492 (if (eq (lookup-key dired-mode-map key) 'undefined) | 1492 (if (or (eq (lookup-key dired-mode-map key) 'undefined) |
1493 (null (lookup-key dired-mode-map key))) | |
1493 (woman-dired-define-key key))) | 1494 (woman-dired-define-key key))) |
1494 | 1495 |
1495 (defun woman-dired-define-keys () | 1496 (defun woman-dired-define-keys () |
1496 "Define dired keys to run WoMan according to `woman-dired-keys'." | 1497 "Define dired keys to run WoMan according to `woman-dired-keys'." |
1497 (if woman-dired-keys | 1498 (if woman-dired-keys |
1664 ;; Multibyte characters exist. | 1665 ;; Multibyte characters exist. |
1665 (progn | 1666 (progn |
1666 (goto-char (point-min)) | 1667 (goto-char (point-min)) |
1667 (while (search-forward "__\b\b" nil t) | 1668 (while (search-forward "__\b\b" nil t) |
1668 (backward-delete-char 4) | 1669 (backward-delete-char 4) |
1669 (woman-set-face (point) (1+ (point)) 'woman-italic-face)) | 1670 (woman-set-face (point) (1+ (point)) 'woman-italic)) |
1670 (goto-char (point-min)) | 1671 (goto-char (point-min)) |
1671 (while (search-forward "\b\b__" nil t) | 1672 (while (search-forward "\b\b__" nil t) |
1672 (backward-delete-char 4) | 1673 (backward-delete-char 4) |
1673 (woman-set-face (1- (point)) (point) 'woman-italic-face)))) | 1674 (woman-set-face (1- (point)) (point) 'woman-italic)))) |
1674 | 1675 |
1675 ;; Interpret overprinting to indicate bold face: | 1676 ;; Interpret overprinting to indicate bold face: |
1676 (goto-char (point-min)) | 1677 (goto-char (point-min)) |
1677 (while (re-search-forward "\\(.\\)\\(\\(+\\1\\)+\\)" nil t) | 1678 (while (re-search-forward "\\(.\\)\\(\\(+\\1\\)+\\)" nil t) |
1678 (woman-delete-match 2) | 1679 (woman-delete-match 2) |
1679 (woman-set-face (1- (point)) (point) 'woman-bold-face)) | 1680 (woman-set-face (1- (point)) (point) 'woman-bold)) |
1680 | 1681 |
1681 ;; Interpret underlining to indicate italic face: | 1682 ;; Interpret underlining to indicate italic face: |
1682 ;; (Must be AFTER emboldening to interpret bold _ correctly!) | 1683 ;; (Must be AFTER emboldening to interpret bold _ correctly!) |
1683 (goto-char (point-min)) | 1684 (goto-char (point-min)) |
1684 (while (search-forward "_" nil t) | 1685 (while (search-forward "_" nil t) |
1685 (delete-char -2) | 1686 (delete-char -2) |
1686 (woman-set-face (point) (1+ (point)) 'woman-italic-face)) | 1687 (woman-set-face (point) (1+ (point)) 'woman-italic)) |
1687 | 1688 |
1688 ;; Leave any other uninterpreted ^H's in the buffer for now! (They | 1689 ;; Leave any other uninterpreted ^H's in the buffer for now! (They |
1689 ;; might indicate composite special characters, which could be | 1690 ;; might indicate composite special characters, which could be |
1690 ;; interpreted if I knew what to expect.) | 1691 ;; interpreted if I knew what to expect.) |
1691 | 1692 |
1694 (cond | 1695 (cond |
1695 (woman-bold-headings | 1696 (woman-bold-headings |
1696 (goto-char (point-min)) | 1697 (goto-char (point-min)) |
1697 (forward-line) | 1698 (forward-line) |
1698 (while (re-search-forward "^\\( \\)?\\([A-Z].*\\)" nil t) | 1699 (while (re-search-forward "^\\( \\)?\\([A-Z].*\\)" nil t) |
1699 (woman-set-face (match-beginning 2) (match-end 2) 'woman-bold-face)))) | 1700 (woman-set-face (match-beginning 2) (match-end 2) 'woman-bold)))) |
1700 ) | 1701 ) |
1701 | 1702 |
1702 (defun woman-insert-file-contents (filename compressed) | 1703 (defun woman-insert-file-contents (filename compressed) |
1703 "Insert file FILENAME into the current buffer. | 1704 "Insert file FILENAME into the current buffer. |
1704 If COMPRESSED is t, or is non-nil and the filename implies compression, | 1705 If COMPRESSED is t, or is non-nil and the filename implies compression, |
1729 | 1730 |
1730 ;;; Major mode (Man) interface: | 1731 ;;; Major mode (Man) interface: |
1731 | 1732 |
1732 (defvar woman-mode-map nil "Keymap for woman mode.") | 1733 (defvar woman-mode-map nil "Keymap for woman mode.") |
1733 | 1734 |
1734 (if woman-mode-map | 1735 (unless woman-mode-map |
1735 () | 1736 (setq woman-mode-map (make-sparse-keymap)) |
1736 ;; Set up the keymap, mostly inherited from Man-mode-map. Normally | |
1737 ;; button-buffer-map is used as a parent keymap, but we can't have two | |
1738 ;; parents, so we just copy it. | |
1739 (setq woman-mode-map (copy-keymap button-buffer-map)) | |
1740 (set-keymap-parent woman-mode-map Man-mode-map) | 1737 (set-keymap-parent woman-mode-map Man-mode-map) |
1741 ;; Above two lines were | 1738 |
1742 ;; (setq woman-mode-map (cons 'keymap Man-mode-map)) | |
1743 (define-key woman-mode-map "R" 'woman-reformat-last-file) | 1739 (define-key woman-mode-map "R" 'woman-reformat-last-file) |
1744 (define-key woman-mode-map "w" 'woman) | 1740 (define-key woman-mode-map "w" 'woman) |
1745 (define-key woman-mode-map "\en" 'WoMan-next-manpage) | 1741 (define-key woman-mode-map "\en" 'WoMan-next-manpage) |
1746 (define-key woman-mode-map "\ep" 'WoMan-previous-manpage) | 1742 (define-key woman-mode-map "\ep" 'WoMan-previous-manpage) |
1747 (define-key woman-mode-map [M-mouse-2] 'woman-follow-word)) | 1743 (define-key woman-mode-map [M-mouse-2] 'woman-follow-word) |
1744 | |
1745 ;; We don't need to call `man' when we are in `woman-mode'. | |
1746 (define-key woman-mode-map [remap man] 'woman)) | |
1748 | 1747 |
1749 (defun woman-follow-word (event) | 1748 (defun woman-follow-word (event) |
1750 "Run WoMan with word under mouse as topic. | 1749 "Run WoMan with word under mouse as topic. |
1751 Argument EVENT is the invoking mouse event." | 1750 Argument EVENT is the invoking mouse event." |
1752 (interactive "e") ; mouse event | 1751 (interactive "e") ; mouse event |
1753 (goto-char (posn-point (event-start event))) | 1752 (goto-char (posn-point (event-start event))) |
1754 (woman (current-word t))) | 1753 (woman (or (current-word t) ""))) |
1755 | 1754 |
1756 ;; WoMan menu bar and pop-up menu: | 1755 ;; WoMan menu bar and pop-up menu: |
1757 (easy-menu-define | 1756 (easy-menu-define |
1758 woman-menu ; (SYMBOL MAPS DOC MENU) | 1757 woman-menu ; (SYMBOL MAPS DOC MENU) |
1759 ;; That comment was moved after the symbol `woman-menu' to make | 1758 ;; That comment was moved after the symbol `woman-menu' to make |
1825 "Reset `woman-emulation' to VALUE and reformat, for menu use." | 1824 "Reset `woman-emulation' to VALUE and reformat, for menu use." |
1826 (interactive) | 1825 (interactive) |
1827 (setq woman-emulation value) | 1826 (setq woman-emulation value) |
1828 (woman-reformat-last-file)) | 1827 (woman-reformat-last-file)) |
1829 | 1828 |
1829 (put 'woman-mode 'mode-class 'special) | |
1830 | |
1830 (defun woman-mode () | 1831 (defun woman-mode () |
1831 "Turn on (most of) Man mode to browse a buffer formatted by WoMan. | 1832 "Turn on (most of) Man mode to browse a buffer formatted by WoMan. |
1832 WoMan is an ELisp emulation of much of the functionality of the Emacs | 1833 WoMan is an ELisp emulation of much of the functionality of the Emacs |
1833 `man' command running the standard UN*X man and ?roff programs. | 1834 `man' command running the standard UN*X man and ?roff programs. |
1834 WoMan author: F.J.Wright@Maths.QMW.ac.uk | 1835 WoMan author: F.J.Wright@Maths.QMW.ac.uk |
1842 (fset 'Man-build-page-list 'ignore) | 1843 (fset 'Man-build-page-list 'ignore) |
1843 (fset 'Man-strip-page-headers 'ignore) | 1844 (fset 'Man-strip-page-headers 'ignore) |
1844 (fset 'Man-unindent 'ignore) | 1845 (fset 'Man-unindent 'ignore) |
1845 (fset 'Man-goto-page 'ignore) | 1846 (fset 'Man-goto-page 'ignore) |
1846 (unwind-protect | 1847 (unwind-protect |
1847 (progn | 1848 (delay-mode-hooks (Man-mode)) |
1848 (set (make-local-variable 'Man-mode-map) woman-mode-map) | |
1849 ;; Install Man mode: | |
1850 (Man-mode) | |
1851 ;; Reset inappropriate definitions: | |
1852 (setq mode-line-format woman-mode-line-format) | |
1853 (put 'Man-mode 'mode-class 'special)) | |
1854 ;; Restore the status quo: | 1849 ;; Restore the status quo: |
1855 (fset 'Man-build-page-list Man-build-page-list) | 1850 (fset 'Man-build-page-list Man-build-page-list) |
1856 (fset 'Man-strip-page-headers Man-strip-page-headers) | 1851 (fset 'Man-strip-page-headers Man-strip-page-headers) |
1857 (fset 'Man-unindent Man-unindent) | 1852 (fset 'Man-unindent Man-unindent) |
1858 (fset 'Man-goto-page Man-goto-page) | 1853 (fset 'Man-goto-page Man-goto-page))) |
1859 ) | 1854 (setq major-mode 'woman-mode |
1860 ;; Imenu support: | 1855 mode-name "WoMan") |
1861 (set (make-local-variable 'imenu-generic-expression) | 1856 ;; Don't show page numbers like Man-mode does. (Online documents do |
1862 ;; `make-local-variable' in case imenu not yet loaded! | 1857 ;; not have pages) |
1863 woman-imenu-generic-expression) | 1858 (kill-local-variable 'mode-line-buffer-identification) |
1864 (set (make-local-variable 'imenu-space-replacement) " ") | 1859 (use-local-map woman-mode-map) |
1865 ;; For reformat ... | 1860 ;; Imenu support: |
1866 ;; necessary when reformatting a file in its old buffer: | 1861 (set (make-local-variable 'imenu-generic-expression) |
1867 (setq imenu--last-menubar-index-alist nil) | 1862 ;; `make-local-variable' in case imenu not yet loaded! |
1868 ;; necessary to avoid re-installing the same imenu: | 1863 woman-imenu-generic-expression) |
1869 (setq woman-imenu-done nil) | 1864 (set (make-local-variable 'imenu-space-replacement) " ") |
1870 (if woman-imenu (woman-imenu)) | 1865 ;; For reformat ... |
1871 (setq buffer-read-only nil) | 1866 ;; necessary when reformatting a file in its old buffer: |
1872 (WoMan-highlight-references) | 1867 (setq imenu--last-menubar-index-alist nil) |
1873 (setq buffer-read-only t) | 1868 ;; necessary to avoid re-installing the same imenu: |
1874 (set-buffer-modified-p nil))) | 1869 (setq woman-imenu-done nil) |
1870 (if woman-imenu (woman-imenu)) | |
1871 (let (buffer-read-only) | |
1872 (Man-highlight-references 'WoMan-xref-man-page)) | |
1873 (set-buffer-modified-p nil) | |
1874 (run-mode-hooks 'woman-mode-hook)) | |
1875 | 1875 |
1876 (defun woman-imenu (&optional redraw) | 1876 (defun woman-imenu (&optional redraw) |
1877 "Add a \"Contents\" menu to the menubar. | 1877 "Add a \"Contents\" menu to the menubar. |
1878 Optional argument REDRAW, if non-nil, forces mode line to be updated." | 1878 Optional argument REDRAW, if non-nil, forces mode line to be updated." |
1879 (interactive) | 1879 (interactive) |
1929 (substring doc 0 (string-match "\n" doc)))))) | 1929 (substring doc 0 (string-match "\n" doc)))))) |
1930 (setq p (cdr p)))) | 1930 (setq p (cdr p)))) |
1931 ;; Output the result: | 1931 ;; Output the result: |
1932 (and (apropos-print t nil) | 1932 (and (apropos-print t nil) |
1933 message | 1933 message |
1934 (message message)))) | 1934 (message "%s" message)))) |
1935 | 1935 |
1936 | 1936 |
1937 (defun WoMan-getpage-in-background (topic) | 1937 (defun WoMan-getpage-in-background (topic) |
1938 "Use TOPIC to start WoMan from `Man-follow-manual-reference'." | 1938 "Use TOPIC to start WoMan from `Man-follow-manual-reference'." |
1939 ;; topic is a string, generally of the form "section topic" | 1939 ;; topic is a string, generally of the form "section topic" |
1942 (woman topic))) | 1942 (woman topic))) |
1943 | 1943 |
1944 (defvar WoMan-Man-start-time nil | 1944 (defvar WoMan-Man-start-time nil |
1945 "Used to record formatting time used by the `man' command.") | 1945 "Used to record formatting time used by the `man' command.") |
1946 | 1946 |
1947 (defadvice Man-getpage-in-background | 1947 ;; Both advices are disabled because "a file in Emacs should not put |
1948 (around Man-getpage-in-background-advice (topic) activate) | 1948 ;; advice on a function in Emacs" (see Info node "(elisp)Advising |
1949 "Use WoMan unless invoked outside a WoMan buffer or invoked explicitly. | 1949 ;; Functions"). Counting the formatting time is useful for |
1950 Otherwise use Man and record start of formatting time." | 1950 ;; developping, but less applicable for daily use. The advice for |
1951 (if (and (eq mode-line-format woman-mode-line-format) | 1951 ;; `Man-getpage-in-background' can be discarded, because the |
1952 (not (eq (caar command-history) 'man))) | 1952 ;; key-binding in `woman-mode-map' has been remapped to call `woman' |
1953 (WoMan-getpage-in-background topic) | 1953 ;; but `man'. Michael Albinus <michael.albinus@gmx.de> |
1954 ;; Initiates man processing | 1954 |
1955 (setq WoMan-Man-start-time (current-time)) | 1955 ;; (defadvice Man-getpage-in-background |
1956 ad-do-it)) | 1956 ;; (around Man-getpage-in-background-advice (topic) activate) |
1957 | 1957 ;; "Use WoMan unless invoked outside a WoMan buffer or invoked explicitly. |
1958 (defadvice Man-bgproc-sentinel | 1958 ;; Otherwise use Man and record start of formatting time." |
1959 (after Man-bgproc-sentinel-advice activate) | 1959 ;; (if (and (eq major-mode 'woman-mode) |
1960 ;; Terminates man processing | 1960 ;; (not (eq (caar command-history) 'man))) |
1961 "Report formatting time." | 1961 ;; (WoMan-getpage-in-background topic) |
1962 (let* ((time (current-time)) | 1962 ;; ;; Initiates man processing |
1963 (time (+ (* (- (car time) (car WoMan-Man-start-time)) 65536) | 1963 ;; (setq WoMan-Man-start-time (current-time)) |
1964 (- (cadr time) (cadr WoMan-Man-start-time))))) | 1964 ;; ad-do-it)) |
1965 (message "Man formatting done in %d seconds" time))) | 1965 |
1966 | 1966 ;; (defadvice Man-bgproc-sentinel |
1967 (defun WoMan-highlight-references () | 1967 ;; (after Man-bgproc-sentinel-advice activate) |
1968 "Highlight the references (in the SEE ALSO section) on mouse-over." | 1968 ;; ;; Terminates man processing |
1969 ;; Based on `Man-build-references-alist' in `man'. | 1969 ;; "Report formatting time." |
1970 (when (Man-find-section Man-see-also-regexp) | 1970 ;; (let* ((time (current-time)) |
1971 (forward-line 1) | 1971 ;; (time (+ (* (- (car time) (car WoMan-Man-start-time)) 65536) |
1972 (let ((end (save-excursion | 1972 ;; (- (cadr time) (cadr WoMan-Man-start-time))))) |
1973 (Man-next-section 1) | 1973 ;; (message "Man formatting done in %d seconds" time))) |
1974 (point)))) | |
1975 (back-to-indentation) | |
1976 (while (re-search-forward Man-reference-regexp end t) | |
1977 ;; Highlight reference when mouse is over it. | |
1978 ;; (NB: WoMan does not hyphenate!) | |
1979 (make-text-button (match-beginning 1) (match-end 1) | |
1980 'type 'woman-xref))))) | |
1981 | 1974 |
1982 | 1975 |
1983 ;;; Buffer handling: | 1976 ;;; Buffer handling: |
1984 | 1977 |
1985 (defun WoMan-previous-manpage () | 1978 (defun WoMan-previous-manpage () |
2210 (setq woman-if-conditions-true | 2203 (setq woman-if-conditions-true |
2211 (cons (string-to-char (symbol-name woman-emulation)) '(?e ?o))) | 2204 (cons (string-to-char (symbol-name woman-emulation)) '(?e ?o))) |
2212 | 2205 |
2213 ;; Prepare non-underlined versions of underlined faces: | 2206 ;; Prepare non-underlined versions of underlined faces: |
2214 (woman-non-underline-faces) | 2207 (woman-non-underline-faces) |
2215 ;; Set font of `woman-symbol-face' to `woman-symbol-font' if | 2208 ;; Set font of `woman-symbol' face to `woman-symbol-font' if |
2216 ;; `woman-symbol-font' is well defined. | 2209 ;; `woman-symbol-font' is well defined. |
2217 (and woman-use-symbol-font | 2210 (and woman-use-symbol-font |
2218 (stringp woman-symbol-font) | 2211 (stringp woman-symbol-font) |
2219 (set-face-font 'woman-symbol-face woman-symbol-font | 2212 (set-face-font 'woman-symbol woman-symbol-font |
2220 (and (frame-live-p woman-frame) woman-frame))) | 2213 (and (frame-live-p woman-frame) woman-frame))) |
2221 | 2214 |
2222 ;; Set syntax and display tables: | 2215 ;; Set syntax and display tables: |
2223 (set-syntax-table woman-syntax-table) | 2216 (set-syntax-table woman-syntax-table) |
2224 (woman-set-buffer-display-table) | 2217 (woman-set-buffer-display-table) |
2225 | 2218 |
2226 ;; Based loosely on a suggestion by Theodore Jump: | 2219 ;; Based loosely on a suggestion by Theodore Jump: |
2227 (if (or woman-fill-frame | 2220 (if (or woman-fill-frame |
2228 (not (and (integerp woman-fill-column) (> woman-fill-column 0)))) | 2221 (not (and (integerp woman-fill-column) (> woman-fill-column 0)))) |
2229 (setq woman-fill-column (- (frame-width) woman-default-indent))) | 2222 (setq woman-fill-column (- (window-width) woman-default-indent))) |
2230 | 2223 |
2231 ;; Check for preprocessor requests: | 2224 ;; Check for preprocessor requests: |
2232 (goto-char from) | 2225 (goto-char from) |
2233 (if (looking-at "'\\\\\"[ \t]*\\([a-z]+\\)") | 2226 (if (looking-at "'\\\\\"[ \t]*\\([a-z]+\\)") |
2234 (let ((letters (append (match-string 1) nil))) | 2227 (let ((letters (append (match-string 1) nil))) |
2299 (repl (if (or (= (aref esc 0) ?u) | 2292 (repl (if (or (= (aref esc 0) ?u) |
2300 (and (>= (length esc) 2) (= (aref esc 2) ?-))) | 2293 (and (>= (length esc) 2) (= (aref esc 2) ?-))) |
2301 "^" "_"))) | 2294 "^" "_"))) |
2302 (cond (first | 2295 (cond (first |
2303 (replace-match repl nil t) | 2296 (replace-match repl nil t) |
2304 (put-text-property (1- (point)) (point) | 2297 (put-text-property (1- (point)) (point) 'face 'woman-addition) |
2305 'face 'woman-addition-face) | |
2306 (WoMan-warn | 2298 (WoMan-warn |
2307 "Initial vertical motion escape \\%s simulated" esc) | 2299 "Initial vertical motion escape \\%s simulated" esc) |
2308 (WoMan-log | 2300 (WoMan-log |
2309 " by TeX `%s' in woman-addition-face!" repl)) | 2301 " by TeX `%s' in woman-addition-face!" repl)) |
2310 (t | 2302 (t |
2520 ;; ((looking-at "[te]") (setq c nil)) ; reject t(roff) and e(ven page) | 2512 ;; ((looking-at "[te]") (setq c nil)) ; reject t(roff) and e(ven page) |
2521 ((looking-at "[ntoe]") | 2513 ((looking-at "[ntoe]") |
2522 (setq c (memq (following-char) woman-if-conditions-true))) | 2514 (setq c (memq (following-char) woman-if-conditions-true))) |
2523 ;; Unrecognised letter so reject: | 2515 ;; Unrecognised letter so reject: |
2524 ((looking-at "[A-Za-z]") (setq c nil) | 2516 ((looking-at "[A-Za-z]") (setq c nil) |
2525 (WoMan-warn "%s %s -- unrecognised condition name rejected!" | 2517 (WoMan-warn "%s %s -- unrecognized condition name rejected!" |
2526 request (match-string 0))) | 2518 request (match-string 0))) |
2527 ;; Accept strings if identical: | 2519 ;; Accept strings if identical: |
2528 ((save-restriction | 2520 ((save-restriction |
2529 (narrow-to-region from woman0-if-to) | 2521 (narrow-to-region from woman0-if-to) |
2530 ;; String delimiter can be any non-numeric character, | 2522 ;; String delimiter can be any non-numeric character, |
2925 (defsubst woman-replace-match (newtext &optional face) | 2917 (defsubst woman-replace-match (newtext &optional face) |
2926 "Replace text matched by last search with NEWTEXT and return t. | 2918 "Replace text matched by last search with NEWTEXT and return t. |
2927 Set NEWTEXT in face FACE if specified." | 2919 Set NEWTEXT in face FACE if specified." |
2928 (woman-delete-match 0) | 2920 (woman-delete-match 0) |
2929 (insert-before-markers newtext) | 2921 (insert-before-markers newtext) |
2930 (if face (put-text-property (1- (point)) (point) | 2922 (if face (put-text-property (1- (point)) (point) 'face 'woman-symbol)) |
2931 'face 'woman-symbol-face)) | |
2932 t) | 2923 t) |
2933 | 2924 |
2934 (defun woman-special-characters (to) | 2925 (defun woman-special-characters (to) |
2935 "Process special character escapes \\(xx, \\[xxx] up to buffer position TO. | 2926 "Process special character escapes \\(xx, \\[xxx] up to buffer position TO. |
2936 \(This must be done AFTER translation, which may use special characters.)" | 2927 \(This must be done AFTER translation, which may use special characters.)" |
2944 (cond ((and (cddr replacement) | 2935 (cond ((and (cddr replacement) |
2945 (if (nthcdr 3 replacement) | 2936 (if (nthcdr 3 replacement) |
2946 ;; Need symbol font: | 2937 ;; Need symbol font: |
2947 (if woman-use-symbol-font | 2938 (if woman-use-symbol-font |
2948 (woman-replace-match (nth 2 replacement) | 2939 (woman-replace-match (nth 2 replacement) |
2949 'woman-symbol-face)) | 2940 'woman-symbol)) |
2950 ;; Need extended font: | 2941 ;; Need extended font: |
2951 (if woman-use-extended-font | 2942 (if woman-use-extended-font |
2952 (woman-replace-match (nth 2 replacement)))))) | 2943 (woman-replace-match (nth 2 replacement)))))) |
2953 ((cadr replacement) ; Use ASCII simulation | 2944 ((cadr replacement) ; Use ASCII simulation |
2954 (woman-replace-match (cadr replacement))))) | 2945 (woman-replace-match (cadr replacement))))) |
2969 (set-buffer standard-output) | 2960 (set-buffer standard-output) |
2970 (let ((i 32)) | 2961 (let ((i 32)) |
2971 (while (< i 256) | 2962 (while (< i 256) |
2972 (insert (format "\\%03o " i) (string i) " " (string i)) | 2963 (insert (format "\\%03o " i) (string i) " " (string i)) |
2973 (put-text-property (1- (point)) (point) | 2964 (put-text-property (1- (point)) (point) |
2974 'face 'woman-symbol-face) | 2965 'face 'woman-symbol) |
2975 (insert " ") | 2966 (insert " ") |
2976 (setq i (1+ i)) | 2967 (setq i (1+ i)) |
2977 (when (= i 128) (setq i 160) (insert "\n")) | 2968 (when (= i 128) (setq i 160) (insert "\n")) |
2978 (if (zerop (% i 8)) (insert "\n"))) | 2969 (if (zerop (% i 8)) (insert "\n"))) |
2979 )) | 2970 )) |
3237 | 3228 |
3238 ;;; Direct font selection: | 3229 ;;; Direct font selection: |
3239 | 3230 |
3240 (defconst woman-font-alist | 3231 (defconst woman-font-alist |
3241 '(("R" . default) | 3232 '(("R" . default) |
3242 ("I" . woman-italic-face) | 3233 ("I" . woman-italic) |
3243 ("B" . woman-bold-face) | 3234 ("B" . woman-bold) |
3244 ("P" . previous) | 3235 ("P" . previous) |
3245 ("1" . default) | 3236 ("1" . default) |
3246 ("2" . woman-italic-face) | 3237 ("2" . woman-italic) |
3247 ("3" . woman-bold-face) ; used in bash.1 | 3238 ("3" . woman-bold) ; used in bash.1 |
3248 ) | 3239 ) |
3249 "Alist of ?roff font indicators and woman font variables and names.") | 3240 "Alist of ?roff font indicators and woman font variables and names.") |
3250 | 3241 |
3251 (defun woman-change-fonts () | 3242 (defun woman-change-fonts () |
3252 "Process font changes." | 3243 "Process font changes." |
3253 ;; ***** NEEDS REVISING IF IT WORKS OK ***** | 3244 ;; ***** NEEDS REVISING IF IT WORKS OK ***** |
3254 ;; Paragraph .LP/PP/HP/IP/TP and font .B/.BI etc. macros reset font. | 3245 ;; Paragraph .LP/PP/HP/IP/TP and font .B/.BI etc. macros reset font. |
3255 ;; Should .SH/.SS reset font? | 3246 ;; Should .SH/.SS reset font? |
3256 ;; Font size setting macros (?) should reset font. | 3247 ;; Font size setting macros (?) should reset font. |
3257 (let ((woman-font-alist woman-font-alist) ; for local updating | 3248 (let ((font-alist woman-font-alist) ; for local updating |
3258 (previous-pos (point)) | 3249 (previous-pos (point)) |
3259 (previous-font 'default) | 3250 (previous-font 'default) |
3260 (current-font 'default)) | 3251 (current-font 'default)) |
3261 (while | 3252 (while |
3262 ;; Find font requests, paragraph macros and font escapes: | 3253 ;; Find font requests, paragraph macros and font escapes: |
3283 (if notfont | 3274 (if notfont |
3284 () | 3275 () |
3285 ;; Get font name: | 3276 ;; Get font name: |
3286 (or font | 3277 (or font |
3287 (let ((fontstring (match-string 0))) | 3278 (let ((fontstring (match-string 0))) |
3288 (setq font (assoc fontstring woman-font-alist) | 3279 (setq font (assoc fontstring font-alist) |
3289 ;; NB: woman-font-alist contains VARIABLE NAMES. | 3280 ;; NB: font-alist contains VARIABLE NAMES. |
3290 font (if font | 3281 font (if font |
3291 (cdr font) | 3282 (cdr font) |
3292 (WoMan-warn "Unknown font %s." fontstring) | 3283 (WoMan-warn "Unknown font %s." fontstring) |
3293 ;; Output this message once only per call ... | 3284 ;; Output this message once only per call ... |
3294 (setq woman-font-alist | 3285 (setq font-alist |
3295 (cons (cons fontstring 'woman-unknown-face) | 3286 (cons (cons fontstring 'woman-unknown) |
3296 woman-font-alist)) | 3287 font-alist)) |
3297 'woman-unknown-face) | 3288 'woman-unknown) |
3298 ))) | 3289 ))) |
3299 ;; Delete font control line or escape sequence: | 3290 ;; Delete font control line or escape sequence: |
3300 (cond (beg (delete-region beg (point)) | 3291 (cond (beg (delete-region beg (point)) |
3301 (if (eq font 'previous) (setq font previous-font)))) | 3292 (if (eq font 'previous) (setq font previous-font)))) |
3302 (woman-set-face previous-pos (point) current-font) | 3293 (woman-set-face previous-pos (point) current-font) |
3753 (buffer-substring start here)) | 3744 (buffer-substring start here)) |
3754 (delete-region here (point))) | 3745 (delete-region here (point))) |
3755 )) | 3746 )) |
3756 ;; Embolden heading (point is at end of heading): | 3747 ;; Embolden heading (point is at end of heading): |
3757 (woman-set-face | 3748 (woman-set-face |
3758 (save-excursion (beginning-of-line) (point)) (point) 'woman-bold-face) | 3749 (save-excursion (beginning-of-line) (point)) (point) 'woman-bold) |
3759 (forward-line) | 3750 (forward-line) |
3760 (delete-blank-lines) | 3751 (delete-blank-lines) |
3761 (setq woman-left-margin woman-default-indent) | 3752 (setq woman-left-margin woman-default-indent) |
3762 (setq woman-prevailing-indent woman-default-indent) | 3753 (setq woman-prevailing-indent woman-default-indent) |
3763 (woman2-format-paragraphs to woman-left-margin)) | 3754 (woman2-format-paragraphs to woman-left-margin)) |
3773 (woman-leave-blank-lines woman-interparagraph-distance) | 3764 (woman-leave-blank-lines woman-interparagraph-distance) |
3774 (setq woman-leave-blank-lines nil) | 3765 (setq woman-leave-blank-lines nil) |
3775 ;; Optionally embolden heading (point is at beginning of heading): | 3766 ;; Optionally embolden heading (point is at beginning of heading): |
3776 (if woman-bold-headings | 3767 (if woman-bold-headings |
3777 (woman-set-face | 3768 (woman-set-face |
3778 (point) (save-excursion (end-of-line) (point)) 'woman-bold-face)) | 3769 (point) (save-excursion (end-of-line) (point)) 'woman-bold)) |
3779 (forward-line) | 3770 (forward-line) |
3780 (setq woman-left-margin woman-default-indent | 3771 (setq woman-left-margin woman-default-indent |
3781 woman-nofill nil) ; fill output lines | 3772 woman-nofill nil) ; fill output lines |
3782 (setq woman-prevailing-indent woman-default-indent) | 3773 (setq woman-prevailing-indent woman-default-indent) |
3783 (woman2-format-paragraphs to woman-left-margin)) | 3774 (woman2-format-paragraphs to woman-left-margin)) |
4546 ))))) | 4537 ))))) |
4547 nil) ; for woman-file-readable-p etc. | 4538 nil) ; for woman-file-readable-p etc. |
4548 | 4539 |
4549 (provide 'woman) | 4540 (provide 'woman) |
4550 | 4541 |
4542 ;;; arch-tag: eea35e90-552f-4712-a94b-d9ffd3db7651 | |
4551 ;;; woman.el ends here | 4543 ;;; woman.el ends here |