diff options
| author | Joseph Arceneaux | 1990-04-27 01:21:24 +0000 |
|---|---|---|
| committer | Joseph Arceneaux | 1990-04-27 01:21:24 +0000 |
| commit | 1a20f48da0f0435c39c7f2eccbe57724886578ce (patch) | |
| tree | 4cc87d0ade458781afbe43a70336d8571573a09e | |
| parent | 4bf7f5d12814680dfd43b518004d8bdb7b29349a (diff) | |
| download | emacs-1a20f48da0f0435c39c7f2eccbe57724886578ce.tar.gz emacs-1a20f48da0f0435c39c7f2eccbe57724886578ce.zip | |
Initial revision
| -rw-r--r-- | lisp/man.el | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/lisp/man.el b/lisp/man.el new file mode 100644 index 00000000000..077559206f4 --- /dev/null +++ b/lisp/man.el | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | ;; Read in and display parts of Unix manual. | ||
| 2 | ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | (defun manual-entry (topic &optional section) | ||
| 21 | "Display the Unix manual entry for TOPIC. | ||
| 22 | TOPIC is either the title of the entry, or has the form TITLE(SECTION) | ||
| 23 | where SECTION is the desired section of the manual, as in `tty(4)'." | ||
| 24 | (interactive "sManual entry (topic): ") | ||
| 25 | (if (= (length topic) 0) | ||
| 26 | (error "Must specify topic")) | ||
| 27 | (if (and (null section) | ||
| 28 | (string-match "\\`[ \t]*\\([^( \t]+\\)[ \t]*(\\(.+\\))[ \t]*\\'" topic)) | ||
| 29 | (setq section (substring topic (match-beginning 2) | ||
| 30 | (match-end 2)) | ||
| 31 | topic (substring topic (match-beginning 1) | ||
| 32 | (match-end 1)))) | ||
| 33 | (with-output-to-temp-buffer (concat "*" topic " Manual Entry*") | ||
| 34 | (buffer-disable-undo standard-output) | ||
| 35 | (save-excursion | ||
| 36 | (set-buffer standard-output) | ||
| 37 | (message "Looking for formatted entry for %s%s..." | ||
| 38 | topic (if section (concat "(" section ")") "")) | ||
| 39 | (let ((dirlist manual-formatted-dirlist) | ||
| 40 | (case-fold-search nil) | ||
| 41 | name) | ||
| 42 | (if (and section (or (file-exists-p | ||
| 43 | (setq name (concat manual-formatted-dir-prefix | ||
| 44 | (substring section 0 1) | ||
| 45 | "/" | ||
| 46 | topic "." section))) | ||
| 47 | (file-exists-p | ||
| 48 | (setq name (concat manual-formatted-dir-prefix | ||
| 49 | section | ||
| 50 | "/" | ||
| 51 | topic "." section))))) | ||
| 52 | (insert-man-file name) | ||
| 53 | (while dirlist | ||
| 54 | (let* ((dir (car dirlist)) | ||
| 55 | (name1 (concat dir "/" topic "." | ||
| 56 | (or section | ||
| 57 | (substring | ||
| 58 | dir | ||
| 59 | (1+ (or (string-match "\\.[^./]*$" dir) | ||
| 60 | -2)))))) | ||
| 61 | completions) | ||
| 62 | (if (file-exists-p name1) | ||
| 63 | (insert-man-file name1) | ||
| 64 | (condition-case () | ||
| 65 | (progn | ||
| 66 | (setq completions (file-name-all-completions | ||
| 67 | (concat topic "." (or section "")) | ||
| 68 | dir)) | ||
| 69 | (while completions | ||
| 70 | (insert-man-file (concat dir "/" (car completions))) | ||
| 71 | (setq completions (cdr completions)))) | ||
| 72 | (file-error nil))) | ||
| 73 | (goto-char (point-max))) | ||
| 74 | (setq dirlist (cdr dirlist))))) | ||
| 75 | |||
| 76 | (if (= (buffer-size) 0) | ||
| 77 | (progn | ||
| 78 | (message "No formatted entry, invoking man %s%s..." | ||
| 79 | (if section (concat section " ") "") topic) | ||
| 80 | (if section | ||
| 81 | (call-process manual-program nil t nil section topic) | ||
| 82 | (call-process manual-program nil t nil topic)) | ||
| 83 | (if (< (buffer-size) 80) | ||
| 84 | (progn | ||
| 85 | (goto-char (point-min)) | ||
| 86 | (end-of-line) | ||
| 87 | (error (buffer-substring 1 (point))))))) | ||
| 88 | |||
| 89 | (message "Cleaning manual entry for %s..." topic) | ||
| 90 | (nuke-nroff-bs) | ||
| 91 | (set-buffer-modified-p nil) | ||
| 92 | (setq buffer-read-only t) | ||
| 93 | (message "")))) | ||
| 94 | |||
| 95 | ;; Hint: BS stands form more things than "back space" | ||
| 96 | (defun nuke-nroff-bs () | ||
| 97 | (interactive "*") | ||
| 98 | ;; Nuke headers: "MORE(1) UNIX Programmer's Manual MORE(1)" | ||
| 99 | ;; We expext to find a footer just before the header except at the beginning. | ||
| 100 | (goto-char (point-min)) | ||
| 101 | (while (re-search-forward "^ *\\([A-Za-z][-_.A-Za-z0-9]*([0-9A-Z]+)\\).*\\1$" nil t) | ||
| 102 | (let (start end) | ||
| 103 | ;; Put START and END around footer and header and garbage blank lines. | ||
| 104 | ;; Fixed line counts are risky, but allow us to preserve | ||
| 105 | ;; significant blank lines. | ||
| 106 | (setq start (save-excursion (forward-line -10) (point))) | ||
| 107 | (setq end (save-excursion (forward-line 4) (point))) | ||
| 108 | (delete-region start end))) | ||
| 109 | ;; Catch the final footer. | ||
| 110 | (goto-char (point-max)) | ||
| 111 | (delete-region (point) (save-excursion (forward-line -7) (point))) | ||
| 112 | |||
| 113 | ;; Nuke underlining and overstriking (only by the same letter) | ||
| 114 | (goto-char (point-min)) | ||
| 115 | (while (search-forward "\b" nil t) | ||
| 116 | (let* ((preceding (char-after (- (point) 2))) | ||
| 117 | (following (following-char))) | ||
| 118 | (cond ((= preceding following) | ||
| 119 | ;; x\bx | ||
| 120 | (delete-char -2)) | ||
| 121 | ((= preceding ?\_) | ||
| 122 | ;; _\b | ||
| 123 | (delete-char -2)) | ||
| 124 | ((= following ?\_) | ||
| 125 | ;; \b_ | ||
| 126 | (delete-region (1- (point)) (1+ (point))))))) | ||
| 127 | |||
| 128 | ;; Zap ESC7, ESC8, and ESC9. | ||
| 129 | ;; This is for Sun man pages like "man 1 csh" | ||
| 130 | (goto-char (point-min)) | ||
| 131 | (while (re-search-forward "\e[789]" nil t) | ||
| 132 | (replace-match "")) | ||
| 133 | |||
| 134 | ;; Crunch blank lines | ||
| 135 | (goto-char (point-min)) | ||
| 136 | (while (re-search-forward "\n\n\n\n*" nil t) | ||
| 137 | (replace-match "\n\n")) | ||
| 138 | |||
| 139 | ;; Nuke blanks lines at start. | ||
| 140 | (goto-char (point-min)) | ||
| 141 | (skip-chars-forward "\n") | ||
| 142 | (delete-region (point-min) (point))) | ||
| 143 | |||
| 144 | |||
| 145 | (defun insert-man-file (name) | ||
| 146 | ;; Insert manual file (unpacked as necessary) into buffer | ||
| 147 | (if (or (equal (substring name -2) ".Z") | ||
| 148 | (string-match "/cat[0-9][a-z]?\\.Z/" name)) | ||
| 149 | (call-process "zcat" name t nil) | ||
| 150 | (if (equal (substring name -2) ".z") | ||
| 151 | (call-process "pcat" nil t nil name) | ||
| 152 | (insert-file-contents name)))) | ||