comparison lisp/woman.el @ 90796:4ef881a120fe

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 675-697) - Update from CVS - Merge from gnus--rel--5.10 - Release ERC 5.2. * gnus--rel--5.10 (patch 211-215) - Update from CVS - Merge from emacs--devo--0 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-189
author Miles Bader <miles@gnu.org>
date Wed, 11 Apr 2007 00:17:47 +0000
parents c0409ee15cee 5ca8f461a8b1
children f55f9811f5d7
comparison
equal deleted inserted replaced
90795:b9182b6a90c9 90796:4ef881a120fe
484 (lambda (x) (if x (list x) (woman-parse-man.conf))) 484 (lambda (x) (if x (list x) (woman-parse-man.conf)))
485 (parse-colon-path (or paths ""))))) 485 (parse-colon-path (or paths "")))))
486 486
487 (defun woman-Cyg-to-Win (file) 487 (defun woman-Cyg-to-Win (file)
488 "Convert an absolute filename FILE from Cygwin to Windows form." 488 "Convert an absolute filename FILE from Cygwin to Windows form."
489 ;; Code taken from w32-symlinks.el 489 ;; MANPATH_MAP conses are not converted since they presumably map
490 (if (eq (aref file 0) ?/) 490 ;; Cygwin to Cygwin form.
491 ;; Try to use Cygwin mount table via `cygpath.exe'. 491 (if (consp file)
492 (condition-case nil 492 file
493 (with-temp-buffer 493 ;; Code taken from w32-symlinks.el
494 ;; cygpath -m file 494 (if (eq (aref file 0) ?/)
495 (call-process "cygpath" nil t nil "-m" file) 495 ;; Try to use Cygwin mount table via `cygpath.exe'.
496 (buffer-substring 1 (buffer-size))) 496 (condition-case nil
497 (error 497 (with-temp-buffer
498 ;; Assume no `cygpath' program available. 498 ;; cygpath -m file
499 ;; Hack /cygdrive/x/ or /x/ or (obsolete) //x/ to x:/ 499 (call-process "cygpath" nil t nil "-m" file)
500 (when (string-match "\\`\\(/cygdrive\\|/\\)?/./" file) 500 (buffer-substring 1 (buffer-size)))
501 (if (match-string 1) ; /cygdrive/x/ or //x/ -> /x/ 501 (error
502 (setq file (substring file (match-end 1)))) 502 ;; Assume no `cygpath' program available.
503 (aset file 0 (aref file 1)) ; /x/ -> xx/ 503 ;; Hack /cygdrive/x/ or /x/ or (obsolete) //x/ to x:/
504 (aset file 1 ?:)) ; xx/ -> x:/ 504 (when (string-match "\\`\\(/cygdrive\\|/\\)?/./" file)
505 file)) 505 (if (match-string 1) ; /cygdrive/x/ or //x/ -> /x/
506 file)) 506 (setq file (substring file (match-end 1))))
507 (aset file 0 (aref file 1)) ; /x/ -> xx/
508 (aset file 1 ?:)) ; xx/ -> x:/
509 file))
510 file)))
507 511
508 512
509 ;;; User options: 513 ;;; User options:
510 514
511 ;; NB: Group identifiers must be lowercase! 515 ;; NB: Group identifiers must be lowercase!
545 (let ((path '("/usr/lib" "/etc"))) 549 (let ((path '("/usr/lib" "/etc")))
546 (if (eq system-type 'windows-nt) 550 (if (eq system-type 'windows-nt)
547 (mapcar 'woman-Cyg-to-Win path) 551 (mapcar 'woman-Cyg-to-Win path)
548 path)) 552 path))
549 "*List of dirs to search and/or files to try for man config file. 553 "*List of dirs to search and/or files to try for man config file.
550 A trailing separator (`/' for UNIX etc.) on directories is optional, 554 A trailing separator (`/' for UNIX etc.) on directories is
551 and the filename is used if a directory specified is the first to 555 optional, and the filename is used if a directory specified is
552 contain the strings \"man\" and \".conf\" (in that order). 556 the first to start with \"man\" and has an extension starting
553 If MANPATH is not set but a config file is found then it is parsed 557 with \".conf\". If MANPATH is not set but a config file is found
554 instead to provide a default value for `woman-manpath'." 558 then it is parsed instead to provide a default value for
559 `woman-manpath'."
555 :type '(repeat string) 560 :type '(repeat string)
556 :group 'woman-interface) 561 :group 'woman-interface)
557 562
558 (defun woman-parse-man.conf () 563 (defun woman-parse-man.conf ()
559 "Parse if possible configuration file for man command. 564 "Parse if possible configuration file for man command.
562 Concatenate data from all lines in the config file of the form 567 Concatenate data from all lines in the config file of the form
563 MANPATH /usr/man 568 MANPATH /usr/man
564 or 569 or
565 MANDATORY_MANPATH /usr/man 570 MANDATORY_MANPATH /usr/man
566 or 571 or
567 OPTIONAL_MANPATH /usr/man" 572 OPTIONAL_MANPATH /usr/man
573 or
574 MANPATH_MAP /opt/bin /opt/man"
568 ;; Functionality suggested by Charles Curley. 575 ;; Functionality suggested by Charles Curley.
569 (let ((path woman-man.conf-path) 576 (let ((path woman-man.conf-path)
570 file manpath) 577 file manpath)
571 (while (and 578 (while (and
572 path 579 path
574 (file-readable-p (setq file (car path))) 581 (file-readable-p (setq file (car path)))
575 ;; If not a file then find the file: 582 ;; If not a file then find the file:
576 (or (not (file-directory-p file)) 583 (or (not (file-directory-p file))
577 (and 584 (and
578 (setq file 585 (setq file
579 (directory-files file t "man.*\\.conf" t)) 586 (directory-files file t "\\`man.*\\.conf[a-z]*\\'" t))
580 (file-readable-p (setq file (car file))))) 587 (file-readable-p (setq file (car file)))))
581 ;; Parse the file -- if no MANPATH data ignore it: 588 ;; Parse the file -- if no MANPATH data ignore it:
582 (with-temp-buffer 589 (with-temp-buffer
583 (insert-file-contents file) 590 (insert-file-contents file)
584 (while (re-search-forward 591 (while (re-search-forward
585 ;; `\(?: ... \)' is a "shy group" 592 ;; `\(?: ... \)' is a "shy group"
586 "\ 593 "\
587 ^[ \t]*\\(?:MANDATORY_\\|OPTIONAL_\\)?MANPATH[ \t]+\\(\\S-+\\)" nil t) 594 ^[ \t]*\\(?:\\(?:MANDATORY_\\|OPTIONAL_\\)?MANPATH[ \t]+\\(\\S-+\\)\\|\
588 (setq manpath (cons (match-string 1) manpath))) 595 MANPATH_MAP[ \t]+\\(\\S-+\\)[ \t]+\\(\\S-+\\)\\)" nil t)
596 (add-to-list 'manpath
597 (if (match-beginning 1)
598 (match-string 1)
599 (cons (match-string 2)
600 (match-string 3)))))
589 manpath)) 601 manpath))
590 )) 602 ))
591 (setq path (cdr path))) 603 (setq path (cdr path)))
592 (nreverse manpath))) 604 (nreverse manpath)))
593 605
598 Each element should be the name of a directory that contains 610 Each element should be the name of a directory that contains
599 subdirectories of the form `man?', or more precisely subdirectories 611 subdirectories of the form `man?', or more precisely subdirectories
600 selected by the value of `woman-manpath-man-regexp'. Non-directory 612 selected by the value of `woman-manpath-man-regexp'. Non-directory
601 and unreadable files are ignored. 613 and unreadable files are ignored.
602 614
615 Elements can also be a cons cell indicating a mapping from PATH
616 to manual trees: if such an element's car is equal to a path
617 element of the environment variable PATH, the cdr of the cons
618 cell is included in the directory tree search.
619
603 If not set then the environment variable MANPATH is used. If no such 620 If not set then the environment variable MANPATH is used. If no such
604 environment variable is found, the default list is determined by 621 environment variable is found, the default list is determined by
605 consulting the man configuration file if found, which is determined by 622 consulting the man configuration file if found, which is determined by
606 the user option `woman-man.conf-path'. An empty substring of MANPATH 623 the user option `woman-man.conf-path'. An empty substring of MANPATH
607 denotes the default list. 624 denotes the default list.
616 633
617 (\"C:/Cygwin/usr/man/\" \"C:/Cygwin/usr/local/man\"). 634 (\"C:/Cygwin/usr/man/\" \"C:/Cygwin/usr/local/man\").
618 635
619 The MANPATH environment variable may be set using DOS semi-colon- 636 The MANPATH environment variable may be set using DOS semi-colon-
620 separated or UN*X/Cygwin colon-separated syntax (but not mixed)." 637 separated or UN*X/Cygwin colon-separated syntax (but not mixed)."
621 :type '(repeat string) 638 :type '(repeat (choice string (cons string string)))
622 :group 'woman-interface) 639 :group 'woman-interface)
623 640
624 (defcustom woman-manpath-man-regexp "[Mm][Aa][Nn]" 641 (defcustom woman-manpath-man-regexp "[Mm][Aa][Nn]"
625 "Regexp to match man directories UNDER `woman-manpath' directories. 642 "Regexp to match man directories UNDER `woman-manpath' directories.
626 These normally have names of the form `man?'. Its default value is 643 These normally have names of the form `man?'. Its default value is
1157 (defun woman-cached-data () 1174 (defun woman-cached-data ()
1158 "Generate a list of data used to determine cache validity. 1175 "Generate a list of data used to determine cache validity.
1159 Called both to generate and to check the cache!" 1176 Called both to generate and to check the cache!"
1160 ;; Must use substituted paths because values of env vars may change! 1177 ;; Must use substituted paths because values of env vars may change!
1161 (list woman-cache-level 1178 (list woman-cache-level
1162 (mapcar 'substitute-in-file-name woman-manpath) 1179 (let (lst path)
1180 (dolist (dir woman-manpath (nreverse lst))
1181 (when (consp dir)
1182 (unless path
1183 (setq path
1184 (split-string (getenv "PATH") path-separator t)))
1185 (setq dir (and (member (car dir) path) (cdr dir))))
1186 (when dir (add-to-list 'lst (substitute-in-file-name dir)))))
1163 (mapcar 'substitute-in-file-name woman-path))) 1187 (mapcar 'substitute-in-file-name woman-path)))
1164 1188
1165 (defun woman-read-directory-cache () 1189 (defun woman-read-directory-cache ()
1166 "Load the directory and topic cache. 1190 "Load the directory and topic cache.
1167 It is loaded from the file named by the variable `woman-cache-filename'. 1191 It is loaded from the file named by the variable `woman-cache-filename'.
1318 WOMAN-PATH should be a list of specific manual directory regexps. 1342 WOMAN-PATH should be a list of specific manual directory regexps.
1319 Ignore any paths that are unreadable or not directories." 1343 Ignore any paths that are unreadable or not directories."
1320 ;; Allow each path to be a single string or a list of strings: 1344 ;; Allow each path to be a single string or a list of strings:
1321 (if (not (listp woman-manpath)) (setq woman-manpath (list woman-manpath))) 1345 (if (not (listp woman-manpath)) (setq woman-manpath (list woman-manpath)))
1322 (if (not (listp woman-path)) (setq woman-path (list woman-path))) 1346 (if (not (listp woman-path)) (setq woman-path (list woman-path)))
1323 (let (dir head dirs) 1347 (let (dir head dirs path)
1324 (while woman-manpath 1348 (while woman-manpath
1325 (setq dir (car woman-manpath) 1349 (setq dir (car woman-manpath)
1326 woman-manpath (cdr woman-manpath)) 1350 woman-manpath (cdr woman-manpath))
1351 (when (consp dir)
1352 (unless path
1353 (setq path (split-string (getenv "PATH") path-separator t)))
1354 (setq dir (and (member (car dir) path)
1355 (cdr dir))))
1327 (if (and dir (woman-file-readable-p dir)) 1356 (if (and dir (woman-file-readable-p dir))
1328 ;; NB: `parse-colon-path' creates null elements for 1357 ;; NB: `parse-colon-path' creates null elements for
1329 ;; redundant (semi-)colons and trailing `/'s! 1358 ;; redundant (semi-)colons and trailing `/'s!
1330 ;; If does not actually matter here if dir ends with `/'. 1359 ;; If does not actually matter here if dir ends with `/'.
1331 ;; Need regexp "man" here to avoid "cat?", `.', `..', etc. 1360 ;; Need regexp "man" here to avoid "cat?", `.', `..', etc.
2100 "Decode a buffer in UN*X man-page source format. 2129 "Decode a buffer in UN*X man-page source format.
2101 No external programs are used." 2130 No external programs are used."
2102 (interactive) ; mainly for testing 2131 (interactive) ; mainly for testing
2103 (WoMan-log-begin) 2132 (WoMan-log-begin)
2104 (run-hooks 'woman-pre-format-hook) 2133 (run-hooks 'woman-pre-format-hook)
2105
2106 ;; look for macro sets that woman cannot handle:
2107 (goto-char (point-min))
2108 (let ((case-fold-search nil))
2109 (unless (and (re-search-forward "^\\.SH[ \n]" (point-max) t)
2110 (progn (goto-char (point-min))
2111 (re-search-forward "^\\.TH[ \n]" (point-max) t))
2112 (progn (goto-char (point-min))
2113 (not (re-search-forward "^\\.\\([pnil]p\\|sh\\)[ \n]"
2114 (point-max) t))))
2115 (error "WoMan can only format man pages written with the usual `-man' macros")))
2116
2117 (and (boundp 'font-lock-mode) font-lock-mode (font-lock-mode -1)) 2134 (and (boundp 'font-lock-mode) font-lock-mode (font-lock-mode -1))
2118 ;; (fundamental-mode) 2135 ;; (fundamental-mode)
2119 (let ((start-time (current-time)) ; (HIGH LOW MICROSEC) 2136 (let ((start-time (current-time)) ; (HIGH LOW MICROSEC)
2120 time) ; HIGH * 2**16 + LOW seconds 2137 time) ; HIGH * 2**16 + LOW seconds
2121 (message "WoMan formatting buffer...") 2138 (message "WoMan formatting buffer...")
2266 2283
2267 (woman-pre-process-region from nil) 2284 (woman-pre-process-region from nil)
2268 ;; Process ignore requests, macro definitions, 2285 ;; Process ignore requests, macro definitions,
2269 ;; conditionals and switch source requests: 2286 ;; conditionals and switch source requests:
2270 (woman0-roff-buffer from) 2287 (woman0-roff-buffer from)
2288
2289 ;; Check for macro sets that woman cannot handle. We can only
2290 ;; because do this after processing source-switch directives.
2291 (goto-char (point-min))
2292 (let ((case-fold-search nil))
2293 (unless (and (re-search-forward "^\\.SH[ \n]" (point-max) t)
2294 (progn (goto-char (point-min))
2295 (re-search-forward "^\\.TH[ \n]" (point-max) t))
2296 (progn (goto-char (point-min))
2297 (not (re-search-forward "^\\.\\([pnil]p\\|sh\\)[ \n]"
2298 (point-max) t))))
2299 (error "WoMan can only format man pages written with the usual `-man' macros")))
2271 2300
2272 ;; Process \k escapes BEFORE changing tab width (?): 2301 ;; Process \k escapes BEFORE changing tab width (?):
2273 (goto-char from) 2302 (goto-char from)
2274 (woman-mark-horizonal-position) 2303 (woman-mark-horizonal-position)
2275 2304