Mercurial > emacs
comparison lisp/woman.el @ 29074:3b4c3f9b9c66
(From Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk)
(woman-mapcan, woman-parse-man.conf)
(woman-toggle-use-extended-font, woman-toggle-use-symbol-font)
(woman-reset-emulation): New functions.
(woman-parse-colon-path): Call woman-mapcan. Recognize Cygwin
path syntax better.
(woman-man.conf-path, woman-use-own-frame): New defcustoms.
(woman-manpath): Call woman-parse-man.conf.
(woman-emulation): New defcustom, defaults to nroff.
(woman-font-support): New defconst.
(woman-select-symbol-fonts): New function.
(woman-use-symbol-font): New defcustom.
(woman-menu): Add new menu items: "Colored/BW", "Advanced",
"Emulation".
Many functions: Doc fix.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Mon, 22 May 2000 06:58:47 +0000 |
parents | eb06b6bb8aa8 |
children | eea914233f47 |
comparison
equal
deleted
inserted
replaced
29073:b46c4dc8c51a | 29074:3b4c3f9b9c66 |
---|---|
5 ;; Author: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk> | 5 ;; Author: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk> |
6 ;; Maintainer: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk> | 6 ;; Maintainer: Francis J. Wright <F.J.Wright@Maths.QMW.ac.uk> |
7 ;; Keywords: help, man, UN*X, manual | 7 ;; Keywords: help, man, UN*X, manual |
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/ | |
10 | 11 |
11 ;; This file is part of GNU Emacs. | 12 ;; This file is part of GNU Emacs. |
12 | 13 |
13 ;; GNU Emacs is free software; you can redistribute it and/or modify | 14 ;; GNU Emacs is free software; you can redistribute it and/or modify |
14 ;; it under the terms of the GNU General Public License as published by | 15 ;; it under the terms of the GNU General Public License as published by |
64 ;; Help' when WoMan is running. | 65 ;; Help' when WoMan is running. |
65 | 66 |
66 ;; WoMan is still under development! Please let me know what doesn't | 67 ;; WoMan is still under development! Please let me know what doesn't |
67 ;; work -- I am adding and improving functionality as testing shows | 68 ;; work -- I am adding and improving functionality as testing shows |
68 ;; that it is necessary. See below for guidance on reporting bugs. | 69 ;; that it is necessary. See below for guidance on reporting bugs. |
69 | |
70 ;; The latest versions of this (and related) files are available from | |
71 ;; the URL | |
72 | |
73 ;; http://centaur.maths.qmw.ac.uk/Emacs/ | |
74 | 70 |
75 ;; Recommended use | 71 ;; Recommended use |
76 ;; =============== | 72 ;; =============== |
77 | 73 |
78 ;; Put this in your .emacs: | 74 ;; Put this in your .emacs: |
98 | 94 |
99 ;; Or (3): Put the next two sexpr's in your .emacs: | 95 ;; Or (3): Put the next two sexpr's in your .emacs: |
100 ;; (autoload 'woman-dired-find-file "woman" | 96 ;; (autoload 'woman-dired-find-file "woman" |
101 ;; "In dired, run the WoMan man-page browser on this file." t) | 97 ;; "In dired, run the WoMan man-page browser on this file." t) |
102 ;; (add-hook 'dired-mode-hook | 98 ;; (add-hook 'dired-mode-hook |
103 ;; #'(lambda () | 99 ;; (lambda () |
104 ;; (define-key dired-mode-map "W" 'woman-dired-find-file))) | 100 ;; (define-key dired-mode-map "W" 'woman-dired-find-file))) |
105 ;; and open the directory containing the man page file using dired, | 101 ;; and open the directory containing the man page file using dired, |
106 ;; put the cursor on the file, and press `W'. | 102 ;; put the cursor on the file, and press `W'. |
107 | 103 |
108 ;; In each case, the result should (!) be a buffer in Man mode showing | 104 ;; In each case, the result should (!) be a buffer in Man mode showing |
109 ;; a formatted manual entry. When called from WoMan, Man mode should | 105 ;; a formatted manual entry. When called from WoMan, Man mode should |
156 | 152 |
157 ;; The variable `woman-topic-at-point' can be rebound locally, which | 153 ;; The variable `woman-topic-at-point' can be rebound locally, which |
158 ;; may be useful to provide special private key bindings, e.g. | 154 ;; may be useful to provide special private key bindings, e.g. |
159 | 155 |
160 ;; (global-set-key "\C-cw" | 156 ;; (global-set-key "\C-cw" |
161 ;; #'(lambda () | 157 ;; (lambda () |
162 ;; (interactive) | 158 ;; (interactive) |
163 ;; (let ((woman-topic-at-point t)) | 159 ;; (let ((woman-topic-at-point t)) |
164 ;; (woman))))) | 160 ;; (woman))))) |
165 | 161 |
166 | 162 |
272 | 268 |
273 ;; (setq format-alist | 269 ;; (setq format-alist |
274 ;; (cons | 270 ;; (cons |
275 ;; '(man "UN*X man-page source format" "\\.\\(TH\\|ig\\) " | 271 ;; '(man "UN*X man-page source format" "\\.\\(TH\\|ig\\) " |
276 ;; woman-decode-region nil nil | 272 ;; woman-decode-region nil nil |
277 ;; #'(lambda (arg) | 273 ;; (lambda (arg) |
278 ;; (set-visited-file-name | 274 ;; set-visited-file-name |
279 ;; (file-name-sans-extension buffer-file-name))))) | 275 ;; (file-name-sans-extension buffer-file-name))))) |
280 ;; format-alist)) | 276 ;; format-alist)) |
281 | 277 |
282 | 278 |
283 ;; Reporting Bugs | 279 ;; Reporting Bugs |
284 ;; ============== | 280 ;; ============== |
334 | 330 |
335 | 331 |
336 ;; TO DO | 332 ;; TO DO |
337 ;; ===== | 333 ;; ===== |
338 | 334 |
335 ;; Reconsider case sensitivity of file names. | |
339 ;; MUST PROCESS .if, .nr IN ORDER ENCOUNTERED IN FILE! (rcsfile, mf). | 336 ;; MUST PROCESS .if, .nr IN ORDER ENCOUNTERED IN FILE! (rcsfile, mf). |
340 ;; Allow general delimiter in `\v', cf. `\h'. | 337 ;; Allow general delimiter in `\v', cf. `\h'. |
341 ;; Improve major-mode documentation. | 338 ;; Improve major-mode documentation. |
342 ;; Pre-process conditionals in macro bodies if possible for speed? | 339 ;; Pre-process conditionals in macro bodies if possible for speed? |
343 ;; Emulate some preprocessor support for tbl (.TS/.TE) and eqn (.EQ/.EN) | 340 ;; Emulate some preprocessor support for tbl (.TS/.TE) and eqn (.EQ/.EN) |
354 ;; Add apropos facility by searching NAME (?) entry in man files? | 351 ;; Add apropos facility by searching NAME (?) entry in man files? |
355 ;; Documentation -- optional auto-display of formatted WoMan man page? | 352 ;; Documentation -- optional auto-display of formatted WoMan man page? |
356 ;; Implement a bug reporter? | 353 ;; Implement a bug reporter? |
357 ;; Support diversion and traps (to some extent) - for Tcl/tk pages? | 354 ;; Support diversion and traps (to some extent) - for Tcl/tk pages? |
358 ;; Add a menu of WoMan buffers? | 355 ;; Add a menu of WoMan buffers? |
356 ;; Fix .fc properly? | |
359 | 357 |
360 | 358 |
361 ;; Implementation strategy [this description is now well out of date!] | 359 ;; Implementation strategy [this description is now well out of date!] |
362 ;; -- three main passes, each to process respectively: | 360 ;; -- three main passes, each to process respectively: |
363 | 361 |
368 ;; For each pass, a control function finds and pre-processes the | 366 ;; For each pass, a control function finds and pre-processes the |
369 ;; escape or request and then calls the appropriate function to | 367 ;; escape or request and then calls the appropriate function to |
370 ;; perform the required formatting. Based originally on enriched.el | 368 ;; perform the required formatting. Based originally on enriched.el |
371 ;; and format.el. | 369 ;; and format.el. |
372 | 370 |
373 ;; See also /usr/local/share/groff/tmac/tmac.an | 371 ;; The background information that made this project possible is |
372 ;; freely available courtesy of Bell Labs from | |
373 ;; http://cm.bell-labs.com/7thEdMan/ | |
374 | 374 |
375 | 375 |
376 ;; Acknowledgements | 376 ;; Acknowledgements |
377 ;; ================ | 377 ;; ================ |
378 | 378 |
413 ;; Wei-Xue Shi <wxshi@ma.neweb.ne.jp> | 413 ;; Wei-Xue Shi <wxshi@ma.neweb.ne.jp> |
414 ;; Fabio Somenzi <fabio@joplin.colorado.edu> | 414 ;; Fabio Somenzi <fabio@joplin.colorado.edu> |
415 ;; Karel Sprenger <ks@ic.uva.nl> | 415 ;; Karel Sprenger <ks@ic.uva.nl> |
416 ;; Chris Szurgot <szurgot@itribe.net> | 416 ;; Chris Szurgot <szurgot@itribe.net> |
417 ;; Paul A. Thompson <pat@po.cwru.edu> | 417 ;; Paul A. Thompson <pat@po.cwru.edu> |
418 ;; Arrigo Triulzi <arrigo@maths.qmw.ac.uk> | |
418 ;; Geoff Voelker <voelker@cs.washington.edu> | 419 ;; Geoff Voelker <voelker@cs.washington.edu> |
419 | 420 |
420 (defconst woman-version "0.52 (beta), Time-stamp: <09 January 2000>" | 421 (defvar woman-version "0.54 (beta)" "WoMan version information.") |
421 "WoMan version information.") | 422 |
422 | 423 ;;; History: |
423 ;; $Id: woman.el,v 1.26 2000-01-09 09:44:25+00 fjw Rel $ | 424 ;; For recent change log see end of file. |
424 | |
425 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
426 ;; Changes in version 0.52 ([*] => user interface change) | |
427 ;; Speeded up handling of underlined faces (mainly for "italics"). | |
428 ;; [*] WoMan formatting time display and log added. Emacs `man' | |
429 ;; formatting time display advice added. (This suggests that | |
430 ;; WoMan formatting is faster than Emacs `man' *formatting*, | |
431 ;; i.e. when man is not using `catman' caching. E.g. `woman | |
432 ;; bash' takes 27s whereas `man bash' takes 35s and for smaller | |
433 ;; files `woman' can be relatively much faster than `man'.) | |
434 ;; [*] Experimental support for non-ASCII characters from the | |
435 ;; default and symbol fonts added, initially only for MS-Windows. | |
436 ;; NOTE: It is off by default, mainly because it may increase the | |
437 ;; line spacing; customize `woman-use-symbols' to `on' to use it. | |
438 ;; Pad character handling for .fc fixed. | |
439 ;; Tested: see `woman.status'. | |
440 | |
441 ;; Changes in version 0.51 ([*] => user interface change) | |
442 ;; [*] Improved handling of underlined faces (mainly for "italics"). | |
443 ;; [*] Allow environment variables in directory path elements. | |
444 ;; Display of pre-formatted files improved. | |
445 ;; [*] Unintentional interaction with standard Man mode reduced. | |
446 ;; [*] bzip2 decompression support added. All decompression now | |
447 ;; works by turning on `auto-compression-mode' to decompress the | |
448 ;; file if necessary, rather than decompressing explicitly. | |
449 ;; Filename and compression regexps are now customizable user | |
450 ;; options. | |
451 | |
452 ;; Changes in version 0.50 ([*] => user interface change) | |
453 ;; [*] Requires GNU Emacs 20.3+. | |
454 ;; [*] `defface' used to define faces. | |
455 ;; [*] Follow `see also' references with mouse-2 click. | |
456 ;; Number register increment support added (woman-registers). | |
457 ;; .j must be a NUMBER acceptable by .ad request. | |
458 ;; Very crude field support added. | |
459 ;; Vertical unit specifier `v' added to register handling. | |
460 ;; Improvement to local horizontal motion processing. | |
461 ;; Minor fix to handle negative numeric arguments. | |
462 ;; Handle horizontal motion escapes `\h' better. | |
463 ;; Allow arbitrary delimiters in `.if', inc. special character escapes. | |
464 ;; Allow `\n' within `.if' string comparisons. | |
465 ;; Allow arbitrary delimiters in `\w', inc. special character escapes. | |
466 ;; Processing of `\h' moved much later -- after indenting etc! | |
467 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
468 | 425 |
469 | 426 |
470 ;;; Code: | 427 ;;; Code: |
471 | 428 |
472 (require 'man) | 429 (require 'man) |
473 (eval-when-compile ; to avoid compiler warnings | 430 (eval-when-compile ; to avoid compiler warnings |
474 (require 'dired) | 431 (require 'dired) |
475 (require 'apropos)) | 432 (require 'apropos)) |
476 | 433 |
434 (defun woman-mapcan (fn x) | |
435 "Return concatenated list of FN applied to successive CAR elements of X. | |
436 FN must return a list, cons or nil. Useful for splicing into a list." | |
437 ;; Based on the Standard Lisp function MAPCAN but with args swapped! | |
438 (and x (nconc (funcall fn (car x)) (woman-mapcan fn (cdr x))))) | |
439 | |
477 (defun woman-parse-colon-path (cd-path) | 440 (defun woman-parse-colon-path (cd-path) |
478 "Explode a search path CD-PATH into a list of directory names. | 441 "Explode a search path CD-PATH into a list of directory names. |
479 If the platform is MS-DOS/MS-Windows and any path begins with `//', | 442 If the platform is Microsoft Windows and no path contains `\\' then |
480 assume a Cygwin-style colon-separated search path and convert any | 443 assume a Cygwin-style colon-separated search path and convert any |
481 leading drive specifier `//X/' to `X:', otherwise assume paths | 444 leading drive specifier `//X/' to `X:', otherwise assume paths |
482 separated by `path-separator'." | 445 separated by `path-separator'." |
483 ;; Based on a suggestion by Jari Aalto. | 446 ;; Based on a suggestion by Jari Aalto. |
484 (if (and (memq system-type '(ms-dos windows-nt)) | 447 (woman-mapcan ; splice into list... |
485 (or (string-match "://" cd-path) | 448 (lambda (path) |
486 (and (not (string-match ":" cd-path)) | 449 ;; parse-colon-path returns nil for a null path component and |
487 (string-match "\\`//" cd-path)))) | 450 ;; an empty substring of MANPATH denotes the default list... |
488 (let ((path-separator ":")) | 451 (if path (cons path nil) (woman-parse-man.conf))) |
489 (mapcar | 452 (if (and (memq system-type '(windows-nt ms-dos)) |
490 (function | 453 (not (or (string-match ";" cd-path) |
454 (string-match "\\\\" cd-path)))) | |
455 (let ((path-separator ":")) | |
456 (mapcar | |
491 (lambda (path) ; //a/b -> a:/b | 457 (lambda (path) ; //a/b -> a:/b |
492 (cond ((string-match "\\`//" path) | 458 (cond ((and path (string-match "\\`//./" path)) |
493 (setq path (substring path 1)) ; //a/b -> /a/b | 459 (setq path (substring path 1)) ; //a/b -> /a/b |
494 (aset path 0 (aref path 1)) ; /a/b -> aa/b | 460 (aset path 0 (aref path 1)) ; /a/b -> aa/b |
495 (aset path 1 ?:) ; aa/b -> a:/b | 461 (aset path 1 ?:) ; aa/b -> a:/b |
496 )) | 462 )) |
497 path)) | 463 path) |
498 (parse-colon-path cd-path))) | 464 (parse-colon-path cd-path))) |
499 (parse-colon-path cd-path))) | 465 (parse-colon-path cd-path)))) |
500 | 466 |
501 | 467 |
502 ;;; User options: | 468 ;;; User options: |
503 | 469 |
504 ;; NB: Group identifiers must be lowercase! | 470 ;; NB: Group identifiers must be lowercase! |
532 (defgroup woman-interface nil | 498 (defgroup woman-interface nil |
533 "Interface options for browsing UNIX manual pages `wo (without) man'." | 499 "Interface options for browsing UNIX manual pages `wo (without) man'." |
534 :tag "WoMan Interface" | 500 :tag "WoMan Interface" |
535 :group 'woman) | 501 :group 'woman) |
536 | 502 |
503 (defcustom woman-man.conf-path | |
504 '("/etc" "/usr/local/lib") | |
505 "*List of dirs to search and/or files to try for man config file. | |
506 Default is '(\"/etc\" \"/usr/local/lib\") [for GNU/Linux, Cygwin resp.] | |
507 A trailing separator (`/' for UNIX etc.) on directories is optional | |
508 and the filename matched if a directory is specified is the first to | |
509 contain the string \"man.conf\". | |
510 If MANPATH is not set but a config file is found then it is parsed | |
511 instead to provide a default value for `woman-manpath'." | |
512 :type '(repeat string) | |
513 :group 'woman-interface) | |
514 | |
515 (defun woman-parse-man.conf () | |
516 "Parse man config file if found. (Used only if MANPATH is not set.) | |
517 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 | |
519 MANPATH /usr/man" | |
520 ;; Functionality suggested by Charles Curley. | |
521 (let ((path woman-man.conf-path) | |
522 file manpath) | |
523 (while (and | |
524 path | |
525 (not (and | |
526 (file-readable-p (setq file (car path))) | |
527 ;; If not a file then find the file: | |
528 (or (not (file-directory-p file)) | |
529 (and | |
530 (setq file | |
531 (directory-files file t "man\\.conf" t)) | |
532 (file-readable-p (setq file (car file))))) | |
533 ;; Parse the file -- if no MANPATH data ignore it: | |
534 (with-temp-buffer | |
535 (insert-file-contents file) | |
536 (while (re-search-forward | |
537 "^[ \t]*MANPATH[ \t]+\\(\\S-+\\)" nil t) | |
538 (setq manpath (cons (match-string 1) manpath))) | |
539 manpath)) | |
540 )) | |
541 (setq path (cdr path))) | |
542 (nreverse manpath))) | |
543 | |
537 (defcustom woman-manpath | 544 (defcustom woman-manpath |
538 (let ((manpath (getenv "MANPATH"))) | 545 (let ((manpath (getenv "MANPATH"))) |
539 (if manpath | 546 (or |
540 (woman-parse-colon-path manpath) | 547 (and manpath (woman-parse-colon-path manpath)) |
541 ;; NB: `parse-colon-path' creates null elements for redundant | 548 (woman-parse-man.conf) |
542 ;; (semi-)colons and trailing `/'s! | 549 '("/usr/man" "/usr/local/man") |
543 '("/usr/man" "/usr/local/man") | 550 )) |
544 )) | |
545 "*List of DIRECTORY TREES to search for UN*X manual files. | 551 "*List of DIRECTORY TREES to search for UN*X manual files. |
546 Each element should be the name of a directory that contains | 552 Each element should be the name of a directory that contains |
547 subdirectories of the form `man?', or more precisely subdirectories | 553 subdirectories of the form `man?', or more precisely subdirectories |
548 selected by the value of `woman-manpath-man-regexp'. Non-directory | 554 selected by the value of `woman-manpath-man-regexp'. Non-directory |
549 and unreadable files are ignored. The default value of this variable | 555 and unreadable files are ignored. |
550 is based on the UN*X MANPATH environment variable if set, otherwise | 556 |
557 If not set then the environment variable MANPATH is used. If no such | |
558 environment variable is found, the default list is determined by | |
559 consulting the man configuration file if found. By default this is | |
560 either `/etc/man.config' or `/usr/local/lib/man.conf', which is | |
561 determined by the user option `woman-man.conf-path'. An empty | |
562 substring of MANPATH denotes the default list. Otherwise, the default | |
563 value of this variable is | |
551 | 564 |
552 (\"/usr/man\" \"/usr/local/man\"). | 565 (\"/usr/man\" \"/usr/local/man\"). |
553 | 566 |
554 Any environment variables (which must have the UN*X-style form $NAME, | 567 Any environment variables (names must have the UN*X-style form $NAME, |
555 e.g. $HOME, $EMACSDATA, $EMACS_DIR) are evaluated first but each | 568 e.g. $HOME, $EMACSDATA, $EMACS_DIR) are evaluated first but each |
556 element must evaluate to a SINGLE directory name. Trailing `/'s are | 569 element must evaluate to a SINGLE directory name. Trailing `/'s are |
557 ignored. (Specific directories in `woman-path' are also searched.) | 570 ignored. (Specific directories in `woman-path' are also searched.) |
558 | 571 |
559 Microsoft platforms: | 572 Microsoft platforms: |
652 see the documentation for `imenu-generic-expression'." | 665 see the documentation for `imenu-generic-expression'." |
653 :type 'sexp | 666 :type 'sexp |
654 :group 'woman-interface) | 667 :group 'woman-interface) |
655 | 668 |
656 (defcustom woman-imenu nil | 669 (defcustom woman-imenu nil |
657 "*If non-nil, WoMan adds a Contents menu to the menubar. | 670 "*If non-nil then WoMan adds a Contents menu to the menubar. |
658 WoMan adds the Contents menu by calling `imenu-add-to-menubar'. | 671 It does this by calling `imenu-add-to-menubar'. Default is nil." |
659 Default is nil." | |
660 :type 'boolean | 672 :type 'boolean |
661 :group 'woman-interface) | 673 :group 'woman-interface) |
662 | 674 |
663 (defcustom woman-imenu-title "CONTENTS" | 675 (defcustom woman-imenu-title "CONTENTS" |
664 "*The title to use if WoMan adds a Contents menu to the menubar. | 676 "*The title to use if WoMan adds a Contents menu to the menubar. |
697 (defvar woman-uncompressed-file-regexp) ; for the compiler | 709 (defvar woman-uncompressed-file-regexp) ; for the compiler |
698 (defvar woman-file-compression-regexp) ; for the compiler | 710 (defvar woman-file-compression-regexp) ; for the compiler |
699 | 711 |
700 (defun set-woman-file-regexp (symbol value) | 712 (defun set-woman-file-regexp (symbol value) |
701 "Bind SYMBOL to VALUE and set `woman-file-regexp' as per user customizations. | 713 "Bind SYMBOL to VALUE and set `woman-file-regexp' as per user customizations. |
702 Used as :set cookie by Customize when user customized the user options | 714 Used as :set cookie by Customize when customizing the user options |
703 `woman-uncompressed-file-regexp' and `woman-file-compression-regexp'." | 715 `woman-uncompressed-file-regexp' and `woman-file-compression-regexp'." |
704 (set-default symbol value) | 716 (set-default symbol value) |
705 (and (boundp 'woman-uncompressed-file-regexp) | 717 (and (boundp 'woman-uncompressed-file-regexp) |
706 (boundp 'woman-file-compression-regexp) | 718 (boundp 'woman-file-compression-regexp) |
707 (setq woman-file-regexp | 719 (setq woman-file-regexp |
727 | 739 |
728 (defcustom woman-file-compression-regexp | 740 (defcustom woman-file-compression-regexp |
729 "\\.\\(g?z\\|bz2\\)\\'" | 741 "\\.\\(g?z\\|bz2\\)\\'" |
730 "*Do not change this unless you are sure you know what you are doing! | 742 "*Do not change this unless you are sure you know what you are doing! |
731 Regexp used to match compressed man file extensions for which | 743 Regexp used to match compressed man file extensions for which |
732 decompressors are available and handled by function `auto-compression-mode', | 744 decompressors are available and handled by auto-compression mode, |
733 e.g. \"\\\\.\\\\(g?z\\\\|bz2\\\\)\\\\'\" for `gzip' or `bzip2'. | 745 e.g. \"\\\\.\\\\(g?z\\\\|bz2\\\\)\\\\'\" for `gzip' or `bzip2'. |
734 Should begin with \\. and end with \\' and MUST NOT be optional." | 746 Should begin with \\. and end with \\' and MUST NOT be optional." |
747 ;; Should be compatible with car of | |
748 ;; `jka-compr-file-name-handler-entry', but that is unduly | |
749 ;; complicated, includes an inappropriate extension (.tgz) and is | |
750 ;; not loaded by default! | |
735 :type 'regexp | 751 :type 'regexp |
736 :set 'set-woman-file-regexp | 752 :set 'set-woman-file-regexp |
753 :group 'woman-interface) | |
754 | |
755 (defcustom woman-use-own-frame | |
756 (or (and (fboundp 'display-graphic-p) (display-graphic-p)) | |
757 (memq window-system '(x w32))) | |
758 "*If non-nil then use a dedicated frame for displaying WoMan windows. | |
759 Only useful when run on a graphic display such as X or MS-Windows." | |
760 :type 'boolean | |
737 :group 'woman-interface) | 761 :group 'woman-interface) |
738 | 762 |
739 | 763 |
740 ;; Formatting options | 764 ;; Formatting options |
741 | 765 |
766 Heading emboldening is NOT standard `man' behaviour." | 790 Heading emboldening is NOT standard `man' behaviour." |
767 :type 'boolean | 791 :type 'boolean |
768 :group 'woman-formatting) | 792 :group 'woman-formatting) |
769 | 793 |
770 (defcustom woman-ignore t | 794 (defcustom woman-ignore t |
771 "*If non-nil then unrecognised requests are ignored. Default is t. | 795 "*If non-nil then unrecognised requests etc. are ignored. Default is t. |
772 This gives the standard ?roff behaviour. If nil then they are left in | 796 This gives the standard ?roff behaviour. If nil then they are left in |
773 the buffer, which may aid debugging." | 797 the buffer, which may aid debugging." |
774 :type 'boolean | 798 :type 'boolean |
775 :group 'woman-formatting) | 799 :group 'woman-formatting) |
776 | 800 |
777 (defcustom woman-preserve-ascii nil | 801 (defcustom woman-preserve-ascii nil |
778 "*If non-nil then preserve ASCII characters in the WoMan buffer. | 802 "*If non-nil then preserve ASCII characters in the WoMan buffer. |
779 Otherwise, non-ASCII characters (that display as ASCII) may remain. | 803 Otherwise, non-ASCII characters (that display as ASCII) may remain. |
780 This is irrelevant unless the buffer is to be saved to a file." | 804 This is irrelevant unless the buffer is to be saved to a file." |
781 :type 'boolean | 805 :type 'boolean |
806 :group 'woman-formatting) | |
807 | |
808 (defcustom woman-emulation 'nroff | |
809 "*WoMan emulation, currently either nroff or troff. Default is nroff. | |
810 Troff emulation is experimental and largely untested. | |
811 \(Add groff later?)" | |
812 :type '(choice (const nroff) (const troff)) | |
782 :group 'woman-formatting) | 813 :group 'woman-formatting) |
783 | 814 |
784 | 815 |
785 ;; Faces: | 816 ;; Faces: |
786 | 817 |
841 (interactive) | 872 (interactive) |
842 (set-face-foreground 'woman-italic-face "Black") | 873 (set-face-foreground 'woman-italic-face "Black") |
843 (set-face-foreground 'woman-bold-face "Black")) | 874 (set-face-foreground 'woman-bold-face "Black")) |
844 | 875 |
845 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
846 ;; Experimental symbol font support, initially only for MS-Windows. | 877 ;; Experimental font support, initially only for MS-Windows. |
847 (eval-when-compile | 878 (defconst woman-font-support |
848 (defvar woman-symbol-font) | 879 (eq window-system 'w32) ; Support X later! |
849 (defvar woman-use-symbols)) | 880 "If non-nil then non-ASCII characters and symbol font supported.") |
850 | 881 |
851 (when (and window-system (eq system-type 'windows-nt)) | 882 (defun woman-select-symbol-fonts (fonts) |
883 "Select symbol fonts from a list FONTS of font name strings." | |
884 (let (symbol-fonts) | |
885 ;; With NTEmacs 20.5, the PATTERN option to `x-list-fonts' does | |
886 ;; not seem to work and fonts may be repeated, so ... | |
887 (while fonts | |
888 (and (string-match "-Symbol-" (car fonts)) | |
889 (not (member (car fonts) symbol-fonts)) | |
890 (setq symbol-fonts (cons (car fonts) symbol-fonts))) | |
891 (setq fonts (cdr fonts))) | |
892 symbol-fonts)) | |
893 | |
894 (when woman-font-support | |
852 (make-face 'woman-symbol-face) | 895 (make-face 'woman-symbol-face) |
853 | 896 |
854 ;; Set up the symbol font only if `woman-use-symbols' is true, to | 897 ;; Set the symbol font only if `woman-use-symbol-font' is true, to |
855 ;; avoid unnecessarily upsetting the line spacing in NTEmacs 20.5! | 898 ;; avoid unnecessarily upsetting the line spacing in NTEmacs 20.5! |
856 | 899 |
857 (defcustom woman-use-symbols nil | 900 (defcustom woman-use-extended-font t |
858 "*If non-nil then may use symbol font and non-ASCII characters | 901 "*If non-nil then may use non-ASCII characters from the default font." |
859 from the default font for special characters. It is off by default, | |
860 mainly because it may increase the line spacing in NTEmacs 20.5." | |
861 :type 'boolean | 902 :type 'boolean |
862 :set #'(lambda (symbol value) | |
863 (set-default symbol value) | |
864 (if (and (boundp 'woman-symbol-font) | |
865 (stringp woman-symbol-font)) | |
866 (set-face-font 'woman-symbol-face woman-symbol-font))) | |
867 :group 'woman-faces) | 903 :group 'woman-faces) |
868 | 904 |
905 (defcustom woman-use-symbol-font nil | |
906 "*If non-nil then may use the symbol font. It is off by default, | |
907 mainly because it may change the line spacing (in NTEmacs 20.5)." | |
908 :type 'boolean | |
909 :group 'woman-faces) | |
910 | |
869 (defconst woman-symbol-font-list | 911 (defconst woman-symbol-font-list |
870 (let ((fonts (x-list-fonts "*" 'default)) | 912 (or (woman-select-symbol-fonts (x-list-fonts "*" 'default)) |
871 symbol-fonts) | 913 (woman-select-symbol-fonts (x-list-fonts "*"))) |
872 ;; With NTEmacs 20.5, the PATTERN option to `x-list-fonts' does | 914 "Symbol font(s), preferably same size as default when WoMan was loaded.") |
873 ;; not seem to work and fonts may be repeated, so ... | |
874 (while fonts | |
875 (and (string-match "-Symbol-" (car fonts)) | |
876 (not (member (car fonts) symbol-fonts)) | |
877 (setq symbol-fonts (cons (car fonts) symbol-fonts))) | |
878 (setq fonts (cdr fonts))) | |
879 symbol-fonts) | |
880 "Symbol fonts in the same size as the default font when WoMan was loaded.") | |
881 | 915 |
882 (defcustom woman-symbol-font (car woman-symbol-font-list) | 916 (defcustom woman-symbol-font (car woman-symbol-font-list) |
883 "*A string describing the symbol font to use for special characters. | 917 "*A string describing the symbol font to use for special characters. |
884 It should be compatible with, and the same size as, the default text font. | 918 It should be compatible with, and the same size as, the default text font. |
885 Under MS-Windows, the default is | 919 Under MS-Windows, the default is |
886 \"-*-Symbol-normal-r-*-*-*-*-96-96-p-*-ms-symbol\"." | 920 \"-*-Symbol-normal-r-*-*-*-*-96-96-p-*-ms-symbol\"." |
887 :type `(choice | 921 :type `(choice |
888 ,@(mapcar #'(lambda (x) (list 'const x)) | 922 ,@(mapcar (lambda (x) (list 'const x)) |
889 woman-symbol-font-list) | 923 woman-symbol-font-list) |
890 string) | 924 string) |
891 :set #'(lambda (symbol value) | |
892 (set-default symbol value) | |
893 (if woman-use-symbols | |
894 (set-face-font 'woman-symbol-face value))) | |
895 :group 'woman-faces) | 925 :group 'woman-faces) |
896 | 926 |
897 ) | 927 ) |
898 | 928 |
899 (defvar woman-use-symbols nil) ; for non windows-nt | 929 ;; For non windows-nt ... |
930 (defvar woman-use-extended-font nil) | |
931 (defvar woman-use-symbol-font nil) | |
932 (defvar woman-symbol-font nil) | |
900 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 933 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
901 | 934 |
902 | 935 |
903 ;;; Internal variables: | 936 ;;; Internal variables: |
904 | 937 |
944 (defvar woman-nospace nil | 977 (defvar woman-nospace nil |
945 "Current no-space mode: nil for normal spacing. | 978 "Current no-space mode: nil for normal spacing. |
946 Set by `.ns' request; reset by any output or `.rs' request") | 979 Set by `.ns' request; reset by any output or `.rs' request") |
947 | 980 |
948 (defsubst woman-reset-nospace () | 981 (defsubst woman-reset-nospace () |
949 "Make woman-nospace be nil." | 982 "Set `woman-nospace' to nil." |
950 (setq woman-nospace nil)) | 983 (setq woman-nospace nil)) |
951 | 984 |
952 (defconst woman-mode-line-format | 985 (defconst woman-mode-line-format |
953 ;; This is essentially the Man-mode format with page numbers removed | 986 ;; This is essentially the Man-mode format with page numbers removed |
954 ;; and line numbers added. (Online documents do not have pages, but | 987 ;; and line numbers added. (Online documents do not have pages, but |
968 ;; suppress breaks! | 1001 ;; suppress breaks! |
969 ;; Could end with "\\( +\\|$\\)" instead of " *" | 1002 ;; Could end with "\\( +\\|$\\)" instead of " *" |
970 "Regexp to match a ?roff request plus trailing white space.") | 1003 "Regexp to match a ?roff request plus trailing white space.") |
971 | 1004 |
972 (defvar woman-imenu-done nil | 1005 (defvar woman-imenu-done nil |
973 "Buffer-local: set to true if `woman-imenu' has been called.") | 1006 "Buffer-local: set to true if function `woman-imenu' has been called.") |
974 (make-variable-buffer-local 'woman-imenu-done) | 1007 (make-variable-buffer-local 'woman-imenu-done) |
975 | 1008 |
976 ;; From imenu.el -- needed when reformatting a file in its old buffer. | 1009 ;; From imenu.el -- needed when reformatting a file in its old buffer. |
977 ;; The latest buffer index used to update the menu bar menu. | 1010 ;; The latest buffer index used to update the menu bar menu. |
978 (eval-when-compile | 1011 (eval-when-compile |
979 (require 'imenu)) | 1012 (require 'imenu)) |
980 (make-variable-buffer-local 'imenu--last-menubar-index-alist) | 1013 (make-variable-buffer-local 'imenu--last-menubar-index-alist) |
981 | 1014 |
982 (defvar woman-buffer-alist nil | 1015 (defvar woman-buffer-alist nil |
983 "An alist of WoMan buffers that are already decoded. | 1016 "An alist representing WoMan buffers that are already decoded. |
984 Each element is of the form (FILE-NAME BUFFER-NAME).") | 1017 Each element is of the form (FILE-NAME . BUFFER-NAME).") |
985 | 1018 |
986 (defvar woman-buffer-number 0 | 1019 (defvar woman-buffer-number 0 |
987 "Ordinal number of current buffer entry in `woman-buffer-alist'. | 1020 "Ordinal number of current buffer entry in `woman-buffer-alist'. |
988 The ordinal numbers start from 0.") | 1021 The ordinal numbers start from 0.") |
989 | 1022 |
1023 (defvar woman-if-conditions-true '(?n ?e ?o) | |
1024 "List of one-character built-in condition names that are true. | |
1025 Should include ?e, ?o (page even/odd) and either ?n (nroff) or ?t (troff). | |
1026 Default is '(?n ?e ?o). Set via `woman-emulation'.") | |
1027 | |
990 | 1028 |
991 ;;; Specialized utility functions: | 1029 ;;; Specialized utility functions: |
992 | 1030 |
993 ;;; Fast deletion without saving on the kill ring (cf. simple.el): | 1031 ;;; Fast deletion without saving on the kill ring (cf. simple.el): |
994 | 1032 |
995 (defun woman-delete-line (&optional arg) | 1033 (defun woman-delete-line (&optional arg) |
996 "Delete the rest of the current line; if all-blank line, delete thru newline. | 1034 "Delete rest of current line; if all blank then delete thru newline. |
997 With a numeric argument ARG, delete that many lines from point. | 1035 With a numeric argument ARG, delete that many lines from point. |
998 Negative arguments delete lines backward." | 1036 Negative arguments delete lines backward." |
999 ;; This is a non-interactive version of kill-line in simple.el that | 1037 ;; This is a non-interactive version of kill-line in simple.el that |
1000 ;; deletes instead of killing and assumes kill-whole-line is nil, | 1038 ;; deletes instead of killing and assumes kill-whole-line is nil, |
1001 ;; which is essential! | 1039 ;; which is essential! |
1038 (defvar woman-topic-all-completions nil | 1076 (defvar woman-topic-all-completions nil |
1039 "Expanded topic alist cache. Resetting to nil forces update.") | 1077 "Expanded topic alist cache. Resetting to nil forces update.") |
1040 | 1078 |
1041 ;;;###autoload | 1079 ;;;###autoload |
1042 (defun woman (&optional topic re-cache) | 1080 (defun woman (&optional topic re-cache) |
1043 "Browse a UN*X man page for TOPIC WithOut using a `man' program. | 1081 "Browse UN*X man page for TOPIC (Without using external Man program). |
1044 The major browsing mode used is essentially the standard Man mode. | 1082 The major browsing mode used is essentially the standard Man mode. |
1045 Choose the filename for the man page using completion, based on the | 1083 Choose the filename for the man page using completion, based on the |
1046 topic selected from the directories specified in `woman-manpath' and | 1084 topic selected from the directories specified in `woman-manpath' and |
1047 `woman-path'. The directory expansions and topics are cached for | 1085 `woman-path'. The directory expansions and topics are cached for |
1048 speed, but a non-nil interactive argument forces the caches to be | 1086 speed, but a non-nil interactive argument forces the caches to be |
1049 updated (e.g. to re-interpret the current directory). | 1087 updated (e.g. to re-interpret the current directory). |
1050 | 1088 |
1051 Used non-interactively, arguments are optional: if they are given then | 1089 Used non-interactively, arguments are optional: if given then TOPIC |
1052 the argument TOPIC should be a topic string and the RE-CACHE may be | 1090 should be a topic string and non-nil RE-CACHE forces re-caching." |
1053 non-nil to force re-caching." | |
1054 (interactive (list nil current-prefix-arg)) | 1091 (interactive (list nil current-prefix-arg)) |
1055 ;; The following test is for non-interactive calls via gnudoit etc. | 1092 ;; The following test is for non-interactive calls via gnudoit etc. |
1056 (if (or (interactive-p) (not (stringp topic)) (string-match "\\S " topic)) | 1093 (if (or (interactive-p) (not (stringp topic)) (string-match "\\S " topic)) |
1057 (let ((file-name (woman-file-name topic re-cache))) | 1094 (let ((file-name (woman-file-name topic re-cache))) |
1058 (if file-name | 1095 (if file-name |
1063 ) | 1100 ) |
1064 (message "WoMan Error: No topic specified in non-interactive call") | 1101 (message "WoMan Error: No topic specified in non-interactive call") |
1065 (ding)) | 1102 (ding)) |
1066 ) | 1103 ) |
1067 | 1104 |
1068 ;; The following allows to call WoMan via the standard Help menu | 1105 ;; Allow WoMan to be called via the standard Help menu: |
1069 ;; without the need to call it first via the keyboard: | |
1070 | |
1071 ;; Repeated calls of `define-key-after' do not seem to matter! | |
1072 (define-key-after menu-bar-manuals-menu [woman] | 1106 (define-key-after menu-bar-manuals-menu [woman] |
1073 '(menu-item "Read Man Page (WoMan)..." woman | 1107 '(menu-item "Read Man Page (WoMan)..." woman |
1074 :help "Man-page documentation Without Man") t) | 1108 :help "Man-page documentation Without Man") t) |
1075 | 1109 |
1076 (defvar woman-cached-data nil | 1110 (defvar woman-cached-data nil |
1085 (mapcar 'substitute-in-file-name woman-manpath) | 1119 (mapcar 'substitute-in-file-name woman-manpath) |
1086 (mapcar 'substitute-in-file-name woman-path))) | 1120 (mapcar 'substitute-in-file-name woman-path))) |
1087 | 1121 |
1088 (defun woman-read-directory-cache () | 1122 (defun woman-read-directory-cache () |
1089 "Load the directory and topic cache. | 1123 "Load the directory and topic cache. |
1090 The cache is loaded from the file named precisely as specified by the | 1124 It is loaded from the file named by the variable `woman-cache-filename'. |
1091 variable `woman-cache-filename'. | 1125 Return t if the file exists, nil otherwise." |
1092 Value is t if the file exists, nil otherwise." | |
1093 (and | 1126 (and |
1094 woman-cache-filename | 1127 woman-cache-filename |
1095 (load woman-cache-filename t nil t) ; file exists | 1128 (load woman-cache-filename t nil t) ; file exists |
1096 (equal woman-cached-data (woman-cached-data)))) ; cache valid | 1129 (equal woman-cached-data (woman-cached-data)))) ; cache valid |
1097 | 1130 |
1098 (defun woman-write-directory-cache () | 1131 (defun woman-write-directory-cache () |
1099 "Save the directory and topic cache. | 1132 "Save the directory and topic cache. |
1100 The directory and topic cache is written to the file named precisely as | 1133 It is saved to the file named by the variable `woman-cache-filename'." |
1101 specified by the variable `woman-cache-filename'." | |
1102 (if woman-cache-filename | 1134 (if woman-cache-filename |
1103 (save-excursion ; to restore current buffer | 1135 (save-excursion ; to restore current buffer |
1104 ;; Make a temporary buffer; name starting with space "hides" it. | 1136 ;; Make a temporary buffer; name starting with space "hides" it. |
1105 (let ((standard-output | 1137 (let ((standard-output |
1106 (set-buffer (generate-new-buffer "WoMan tmp buffer"))) | 1138 (set-buffer (generate-new-buffer "WoMan tmp buffer"))) |
1125 (defvar woman-topic-history nil "Topic read history.") | 1157 (defvar woman-topic-history nil "Topic read history.") |
1126 (defvar woman-file-history nil "File-name read history.") | 1158 (defvar woman-file-history nil "File-name read history.") |
1127 | 1159 |
1128 (defun woman-file-name (topic &optional re-cache) | 1160 (defun woman-file-name (topic &optional re-cache) |
1129 "Get the name of the UN*X man-page file describing a chosen TOPIC. | 1161 "Get the name of the UN*X man-page file describing a chosen TOPIC. |
1130 When called interactively, the word at point may be used as the topic | 1162 When `woman' is called interactively, the word at point may be used as |
1131 or initial topic suggestion, subject to the value of the user option | 1163 the topic or initial topic suggestion, subject to the value of the |
1132 `woman-topic-at-point'. | 1164 user option `woman-topic-at-point'. Return nil if no file can be found. |
1133 Optional argument RE-CACHE, if non-nil, forces the cache to be re-read. | 1165 Optional argument RE-CACHE, if non-nil, forces the cache to be re-read." |
1134 Value is nil if no file can be found." | |
1135 ;; Handle the caching of the directory and topic lists: | 1166 ;; Handle the caching of the directory and topic lists: |
1136 (if (and (not re-cache) | 1167 (if (and (not re-cache) |
1137 (or | 1168 (or |
1138 (and woman-expanded-directory-path woman-topic-all-completions) | 1169 (and woman-expanded-directory-path woman-topic-all-completions) |
1139 (woman-read-directory-cache))) | 1170 (woman-read-directory-cache))) |
1216 "Return t if DIR is readable, otherwise log a warning." | 1247 "Return t if DIR is readable, otherwise log a warning." |
1217 (or (file-readable-p dir) | 1248 (or (file-readable-p dir) |
1218 (WoMan-warn "Ignoring unreadable `manpath' directory tree `%s'!" dir))) | 1249 (WoMan-warn "Ignoring unreadable `manpath' directory tree `%s'!" dir))) |
1219 | 1250 |
1220 (defun woman-directory-files (head dir) | 1251 (defun woman-directory-files (head dir) |
1221 "Return a sorted list of files in directory HEAD matching the regexp in DIR. | 1252 "Return a sorted list of files in directory HEAD matching regexp in DIR. |
1222 Value is a sorted list of the absolute pathnames of all the files in | 1253 Value is a sorted list of the absolute pathnames of all the files in |
1223 directory HEAD, or the current directory if HEAD is nil, that match the | 1254 directory HEAD, or the current directory if HEAD is nil, that match the |
1224 regexp that is the final component of DIR. Log a warning if list is empty." | 1255 regexp that is the final component of DIR. Log a warning if list is empty." |
1225 (or (directory-files | 1256 (or (directory-files |
1226 (or head (directory-file-name default-directory)) ; was "." | 1257 (or head (directory-file-name default-directory)) ; was "." |
1232 "Return t if DIR is accessible, otherwise log a warning." | 1263 "Return t if DIR is accessible, otherwise log a warning." |
1233 (or (file-accessible-directory-p dir) | 1264 (or (file-accessible-directory-p dir) |
1234 (WoMan-warn "Ignoring inaccessible `man-page' directory `%s'!" dir))) | 1265 (WoMan-warn "Ignoring inaccessible `man-page' directory `%s'!" dir))) |
1235 | 1266 |
1236 (defun woman-expand-directory-path (woman-manpath woman-path) | 1267 (defun woman-expand-directory-path (woman-manpath woman-path) |
1237 "Expand manual directories in WOMAN-MANPATH and WOMAN-PATH. | 1268 "Expand the manual directories in WOMAN-MANPATH and WOMAN-PATH. |
1238 WOMAN-MANPATH should be the list of the general manual directories, while | 1269 WOMAN-MANPATH should be a list of general manual directories, while |
1239 WOMAN-PATH should be the list of specific manual directory regexps. | 1270 WOMAN-PATH should be a list of specific manual directory regexps. |
1240 Ignore any paths that are unreadable or not directories." | 1271 Ignore any paths that are unreadable or not directories." |
1241 ;; Allow each path to be a single string or a list of strings: | 1272 ;; Allow each path to be a single string or a list of strings: |
1242 (if (not (listp woman-manpath)) (setq woman-manpath (list woman-manpath))) | 1273 (if (not (listp woman-manpath)) (setq woman-manpath (list woman-manpath))) |
1243 (if (not (listp woman-path)) (setq woman-path (list woman-path))) | 1274 (if (not (listp woman-path)) (setq woman-path (list woman-path))) |
1244 (let (dir head dirs) | 1275 (let (dir head dirs) |
1267 ;; was "." -- at head of list for later filtering | 1298 ;; was "." -- at head of list for later filtering |
1268 ))) | 1299 ))) |
1269 (woman-select 'woman-file-accessible-directory-p dirs))) | 1300 (woman-select 'woman-file-accessible-directory-p dirs))) |
1270 | 1301 |
1271 (defun woman-canonicalize-dir (dir) | 1302 (defun woman-canonicalize-dir (dir) |
1272 "Canonicalize a directory name DIR. | 1303 "Canonicalize the directory name DIR. |
1273 Any UN*X-style environment variables are evaluated first." | 1304 Any UN*X-style environment variables are evaluated first." |
1274 (setq dir (expand-file-name (substitute-in-file-name dir))) | 1305 (setq dir (expand-file-name (substitute-in-file-name dir))) |
1275 ;; A path that ends with / matches all directories in it, | 1306 ;; A path that ends with / matches all directories in it, |
1276 ;; including `.' and `..', so remove any trailing / !!! | 1307 ;; including `.' and `..', so remove any trailing / !!! |
1277 (if (string= (substring dir -1) "/") | 1308 (if (string= (substring dir -1) "/") |
1278 (setq dir (substring dir 0 -1))) | 1309 (setq dir (substring dir 0 -1))) |
1279 (if (memq system-type '(windows-nt ms-dos)) ; what else? | 1310 (if (memq system-type '(windows-nt ms-dos)) ; what else? |
1280 ;; Match capitalization used by `file-name-directory': | 1311 ;; Match capitalization used by `file-name-directory': |
1281 (setq dir (concat (file-name-directory dir) | 1312 (setq dir (concat (file-name-directory dir) |
1282 (file-name-nondirectory dir)))) | 1313 (file-name-nondirectory dir)))) |
1283 dir) | 1314 dir) |
1284 | 1315 |
1285 (defsubst woman-not-member (dir path) | 1316 (defsubst woman-not-member (dir path) |
1286 "Return true if DIR is not a member of the list PATH. | 1317 "Return t if DIR is not a member of the list PATH, nil otherwise. |
1287 If DIR is `.' it is first replaced by the current directory." | 1318 If DIR is `.' it is first replaced by the current directory." |
1288 (not (member dir path))) | 1319 (not (member dir path))) |
1289 | 1320 |
1290 (defun woman-topic-all-completions (path) | 1321 (defun woman-topic-all-completions (path) |
1291 "Return an alist of the man files in all man directories in the list PATH. | 1322 "Return an alist of the man files in all man directories in the list PATH. |
1313 (setcdr (nthcdr (1- n) args) nil)) | 1344 (setcdr (nthcdr (1- n) args) nil)) |
1314 args) | 1345 args) |
1315 | 1346 |
1316 (defun woman-topic-all-completions-1 (dir path-index) | 1347 (defun woman-topic-all-completions-1 (dir path-index) |
1317 "Return an alist of the man files in directory DIR with index PATH-INDEX. | 1348 "Return an alist of the man files in directory DIR with index PATH-INDEX. |
1318 The cdr of each alist element is the path-index / filename." | 1349 The `cdr' of each alist element is the path-index / filename." |
1350 ;; *** NEED case-fold-search t HERE ??? | |
1319 (let ((old (directory-files dir nil woman-file-regexp)) | 1351 (let ((old (directory-files dir nil woman-file-regexp)) |
1320 new file) | 1352 new file) |
1321 ;; Convert list to alist of non-directory files: | 1353 ;; Convert list to alist of non-directory files: |
1322 (while old | 1354 (while old |
1323 (setq file (car old) | 1355 (setq file (car old) |
1336 new)))) | 1368 new)))) |
1337 new)) | 1369 new)) |
1338 | 1370 |
1339 (defun woman-topic-all-completions-merge (alist) | 1371 (defun woman-topic-all-completions-merge (alist) |
1340 "Merge the alist ALIST so that the keys are unique. | 1372 "Merge the alist ALIST so that the keys are unique. |
1341 Also, make each path-info component into a list. | 1373 Also make each path-info component into a list. |
1342 \(Note that this function changes the value of ALIST.)" | 1374 \(Note that this function changes the value of ALIST.)" |
1343 ;; Intended to be fast by avoiding recursion and list copying. | 1375 ;; Intended to be fast by avoiding recursion and list copying. |
1344 (if (> woman-cache-level 1) | 1376 (if (> woman-cache-level 1) |
1345 (let ((newalist alist)) | 1377 (let ((newalist alist)) |
1346 (while newalist | 1378 (while newalist |
1485 ;;;###autoload | 1517 ;;;###autoload |
1486 (defun woman-find-file (file-name &optional reformat) | 1518 (defun woman-find-file (file-name &optional reformat) |
1487 "Find, decode and browse a specific UN*X man-page source file FILE-NAME. | 1519 "Find, decode and browse a specific UN*X man-page source file FILE-NAME. |
1488 Use existing buffer if possible; reformat only if prefix arg given. | 1520 Use existing buffer if possible; reformat only if prefix arg given. |
1489 When called interactively, optional argument REFORMAT forces reformatting | 1521 When called interactively, optional argument REFORMAT forces reformatting |
1490 of existing WoMan buffers formatted earlier. | 1522 of an existing WoMan buffer formatted earlier. |
1491 No external programs are used, except that `gunzip' will be used to | 1523 No external programs are used, except that `gunzip' will be used to |
1492 decompress the file if appropriate. See the documentation for the | 1524 decompress the file if appropriate. See the documentation for the |
1493 `woman' command for further details." | 1525 `woman' command for further details." |
1494 (interactive "fBrowse UN*X manual file: \nP") | 1526 (interactive "fBrowse UN*X manual file: \nP") |
1495 (setq woman-last-file-name | 1527 (setq woman-last-file-name |
1529 (substring bufname (1+ dot)) " " | 1561 (substring bufname (1+ dot)) " " |
1530 (substring bufname 0 dot)))) | 1562 (substring bufname 0 dot)))) |
1531 (generate-new-buffer-name ; ensure uniqueness | 1563 (generate-new-buffer-name ; ensure uniqueness |
1532 (concat "*WoMan " bufname "*")))) | 1564 (concat "*WoMan " bufname "*")))) |
1533 | 1565 |
1566 (defvar woman-frame nil | |
1567 "Dedicated frame used for displaying WoMan windows.") | |
1568 | |
1534 (defun woman-really-find-file (filename compressed bufname) | 1569 (defun woman-really-find-file (filename compressed bufname) |
1535 "Find, decompress, and decode a UN*X man page FILENAME. | 1570 "Find, decompress, and decode a UN*X man page FILENAME. |
1536 If COMPRESSED is non-nil, turn on `auto-compression-mode' to | 1571 If COMPRESSED is non-nil, turn on auto-compression mode to decompress |
1537 decompress the file if necessary. Set buffer name and major mode. | 1572 the file if necessary. Set buffer name BUFNAME and major mode. |
1538 Do not call directly!" | 1573 Do not call directly!" |
1539 (let ((WoMan-current-file filename)) ; used for message logging | 1574 (let ((WoMan-current-file filename)) ; used for message logging |
1575 (if woman-use-own-frame | |
1576 (select-frame | |
1577 (or (and (frame-live-p woman-frame) woman-frame) | |
1578 (setq woman-frame (make-frame))))) | |
1540 (switch-to-buffer (get-buffer-create bufname)) | 1579 (switch-to-buffer (get-buffer-create bufname)) |
1541 (buffer-disable-undo) | 1580 (buffer-disable-undo) |
1542 (setq buffer-read-only nil) | 1581 (setq buffer-read-only nil) |
1543 (erase-buffer) ; NEEDED for reformat | 1582 (erase-buffer) ; NEEDED for reformat |
1544 (woman-insert-file-contents filename compressed) | 1583 (woman-insert-file-contents filename compressed) |
1613 ) | 1652 ) |
1614 | 1653 |
1615 (defun woman-insert-file-contents (filename compressed) | 1654 (defun woman-insert-file-contents (filename compressed) |
1616 "Insert file FILENAME into the current buffer. | 1655 "Insert file FILENAME into the current buffer. |
1617 If COMPRESSED is t, or is non-nil and the filename implies compression, | 1656 If COMPRESSED is t, or is non-nil and the filename implies compression, |
1618 turn on `auto-compression-mode' to decompress the file. | 1657 then turn on auto-compression mode to decompress the file. |
1619 Leave point at end of new text. Return length of inserted text." | 1658 Leave point at end of new text. Return length of inserted text." |
1620 ;; Leaves point at end of inserted text in GNU Emacs 20.3, but at | 1659 ;; Leaves point at end of inserted text in GNU Emacs 20.3, but at |
1621 ;; start in 19.34! | 1660 ;; start in 19.34! |
1622 (save-excursion | 1661 (save-excursion |
1623 (let ((case-fold-search t)) | 1662 (let ((case-fold-search t)) |
1689 ["Kill WoMan Buffer" Man-kill t] | 1728 ["Kill WoMan Buffer" Man-kill t] |
1690 "--" | 1729 "--" |
1691 ;; ["Toggle Fill Frame Width" woman-toggle-fill-frame t] | 1730 ;; ["Toggle Fill Frame Width" woman-toggle-fill-frame t] |
1692 ["Use Full Frame Width" woman-toggle-fill-frame | 1731 ["Use Full Frame Width" woman-toggle-fill-frame |
1693 :active t :style toggle :selected woman-fill-frame] | 1732 :active t :style toggle :selected woman-fill-frame] |
1694 ["Reformat Last File" woman-reformat-last-file t] | 1733 ["Reformat Last Man Page" woman-reformat-last-file t] |
1695 ["Use Coloured Main Faces" woman-colour-faces t] | 1734 ["Use Coloured Main Faces" woman-colour-faces t] |
1696 ["Use Black Main Faces" woman-black-faces t] | 1735 ["Use Black Main Faces" woman-black-faces t] |
1697 ["Make Contents Menu" (woman-imenu t) (not woman-imenu-done)] | 1736 ["Make Contents Menu" (woman-imenu t) (not woman-imenu-done)] |
1698 "--" | 1737 "--" |
1699 ["Describe (Wo)Man Mode" describe-mode t] | 1738 ["Describe (Wo)Man Mode" describe-mode t] |
1700 ["Mini Help" woman-mini-help t] | 1739 ["Mini Help" woman-mini-help t] |
1701 ,@(if (fboundp 'customize-group) | 1740 ,@(if (fboundp 'customize-group) |
1702 '(["Customize..." (customize-group 'woman) t])) | 1741 '(["Customize..." (customize-group 'woman) t])) |
1703 ["Show Version" (message "WoMan %s" woman-version) t] | 1742 ["Show Version" (message "WoMan %s" woman-version) t] |
1743 "--" | |
1744 ("Advanced" | |
1745 ["View Source" (view-file woman-last-file-name) woman-last-file-name] | |
1746 ["Show Log" (switch-to-buffer-other-window "*WoMan-Log*" t) t] | |
1747 ["Extended Font" woman-toggle-use-extended-font | |
1748 :included woman-font-support | |
1749 :active t :style toggle :selected woman-use-extended-font] | |
1750 ["Symbol Font" woman-toggle-use-symbol-font | |
1751 :included woman-font-support | |
1752 :active t :style toggle :selected woman-use-symbol-font] | |
1753 ["Font Map" woman-display-extended-fonts | |
1754 :included woman-font-support | |
1755 :active woman-use-symbol-font] | |
1756 "--" | |
1757 "Emulation" | |
1758 ["nroff" (woman-reset-emulation 'nroff) | |
1759 :active t :style radio :selected (eq woman-emulation 'nroff)] | |
1760 ["troff" (woman-reset-emulation 'troff) | |
1761 :active t :style radio :selected (eq woman-emulation 'troff)] | |
1762 ) | |
1704 )) | 1763 )) |
1764 | |
1765 (defun woman-toggle-use-extended-font () | |
1766 "Toggle `woman-use-extended-font' and reformat, for menu use." | |
1767 (interactive) | |
1768 (setq woman-use-extended-font (not woman-use-extended-font)) | |
1769 (woman-reformat-last-file)) | |
1770 | |
1771 (defun woman-toggle-use-symbol-font () | |
1772 "Toggle `woman-use-symbol-font' and reformat, for menu use." | |
1773 (interactive) | |
1774 (setq woman-use-symbol-font (not woman-use-symbol-font)) | |
1775 (woman-reformat-last-file)) | |
1776 | |
1777 (defun woman-reset-emulation (value) | |
1778 "Reset `woman-emulation' to VALUE and reformat, for menu use." | |
1779 (interactive) | |
1780 (setq woman-emulation value) | |
1781 (woman-reformat-last-file)) | |
1705 | 1782 |
1706 (defun woman-mode () | 1783 (defun woman-mode () |
1707 "Turn on (most of) Man mode to browse a buffer formatted by WoMan. | 1784 "Turn on (most of) Man mode to browse a buffer formatted by WoMan. |
1708 WoMan is an ELisp emulation of much of the functionality of the Emacs | 1785 WoMan is an ELisp emulation of much of the functionality of the Emacs |
1709 `man' command running the standard UN*X man and ?roff programs. | 1786 `man' command running the standard UN*X man and ?roff programs. |
1778 (let ((message | 1855 (let ((message |
1779 (let ((standard-output (get-buffer-create "*Apropos*"))) | 1856 (let ((standard-output (get-buffer-create "*Apropos*"))) |
1780 (print-help-return-message 'identity)))) | 1857 (print-help-return-message 'identity)))) |
1781 (setq apropos-accumulator | 1858 (setq apropos-accumulator |
1782 (apropos-internal "woman" | 1859 (apropos-internal "woman" |
1783 #'(lambda (symbol) | 1860 (lambda (symbol) |
1784 (or (commandp symbol) | 1861 (or (commandp symbol) |
1785 (user-variable-p symbol))))) | 1862 (user-variable-p symbol))))) |
1786 ;; Filter out any inhibited symbols: | 1863 ;; Filter out any inhibited symbols: |
1787 (let ((tem apropos-accumulator)) | 1864 (let ((tem apropos-accumulator)) |
1788 (while tem | 1865 (while tem |
1789 (if (get (car tem) 'apropos-inhibit) | 1866 (if (get (car tem) 'apropos-inhibit) |
1790 (setq apropos-accumulator (delq (car tem) apropos-accumulator))) | 1867 (setq apropos-accumulator (delq (car tem) apropos-accumulator))) |
1889 () | 1966 () |
1890 (WoMan-next-manpage))) | 1967 (WoMan-next-manpage))) |
1891 | 1968 |
1892 (defun WoMan-find-buffer () | 1969 (defun WoMan-find-buffer () |
1893 "Switch to buffer corresponding to `woman-buffer-number' and return it. | 1970 "Switch to buffer corresponding to `woman-buffer-number' and return it. |
1894 If such a buffer doesn't exist, remove its association from the alist in | 1971 If such a buffer does not exist then remove its association from the |
1895 `woman-buffer-alist' and return nil." | 1972 alist in `woman-buffer-alist' and return nil." |
1896 (if (zerop woman-buffer-number) | 1973 (if (zerop woman-buffer-number) |
1897 (let ((buffer (get-buffer (cdr (car woman-buffer-alist))))) | 1974 (let ((buffer (get-buffer (cdr (car woman-buffer-alist))))) |
1898 (if buffer | 1975 (if buffer |
1899 (switch-to-buffer buffer) | 1976 (switch-to-buffer buffer) |
1900 ;; Delete alist element: | 1977 ;; Delete alist element: |
2059 woman-RS-prevailing-indent nil | 2136 woman-RS-prevailing-indent nil |
2060 woman-adjust woman-adjust-both | 2137 woman-adjust woman-adjust-both |
2061 woman-justify (nth woman-adjust woman-justify-list) | 2138 woman-justify (nth woman-adjust woman-justify-list) |
2062 woman-nofill nil) | 2139 woman-nofill nil) |
2063 | 2140 |
2141 (setq woman-if-conditions-true | |
2142 (cons (string-to-char (symbol-name woman-emulation)) '(?e ?o))) | |
2143 | |
2064 ;; Prepare non-underlined versions of underlined faces: | 2144 ;; Prepare non-underlined versions of underlined faces: |
2065 (woman-non-underline-faces) | 2145 (woman-non-underline-faces) |
2146 ;; Set font of `woman-symbol-face' to `woman-symbol-font' if | |
2147 ;; `woman-symbol-font' is well defined. | |
2148 (and woman-use-symbol-font | |
2149 (stringp woman-symbol-font) | |
2150 (set-face-font 'woman-symbol-face woman-symbol-font | |
2151 (and (frame-live-p woman-frame) woman-frame))) | |
2066 | 2152 |
2067 ;; Set syntax and display tables: | 2153 ;; Set syntax and display tables: |
2068 (set-syntax-table woman-syntax-table) | 2154 (set-syntax-table woman-syntax-table) |
2069 (woman-set-buffer-display-table) | 2155 (woman-set-buffer-display-table) |
2070 | 2156 |
2215 | 2301 |
2216 ;; Must return the new end of file if used in format-alist. | 2302 ;; Must return the new end of file if used in format-alist. |
2217 (point-max))) | 2303 (point-max))) |
2218 | 2304 |
2219 (defun woman-horizontal-escapes (to) | 2305 (defun woman-horizontal-escapes (to) |
2220 "\\h'+/-N' local horizontal motion, preserving `point'. | 2306 "Process \\h'+/-N' local horizontal motion escapes upto TO. |
2221 Argument TO is the target of the motion. | 2307 Implements arbitrary forward and non-overlapping backward motion. |
2222 Implement arbitrary forward and non-overlapping backward motion." | 2308 Preserves location of `point'." |
2223 ;; Moved from `woman-decode-region' for version 0.50. | 2309 ;; Moved from `woman-decode-region' for version 0.50. |
2224 ;; N may include width escape \w'...' (but may already be processed! | 2310 ;; N may include width escape \w'...' (but may already be processed! |
2225 (let ((from (point))) | 2311 (let ((from (point))) |
2226 (while (re-search-forward | 2312 (while (re-search-forward |
2227 ;; Delimiter can be a special char escape sequence \(.. or | 2313 ;; Delimiter can be a special char escape sequence \(.. or |
2263 )) | 2349 )) |
2264 (goto-char from))) | 2350 (goto-char from))) |
2265 | 2351 |
2266 | 2352 |
2267 | 2353 |
2268 ;;; Process ignore requests (.ig), conditionals (.if etc.), | 2354 ;; Process ignore requests (.ig), conditionals (.if etc.), |
2269 ;;; source-switch (.so), macro definitions (.de etc.) and macro | 2355 ;; source-switch (.so), macro definitions (.de etc.) and macro |
2270 ;;; expansions. | 2356 ;; expansions. |
2271 | 2357 |
2272 (defvar woman0-if-to) ; marker bound in woman0-roff-buffer | 2358 (defvar woman0-if-to) ; marker bound in woman0-roff-buffer |
2273 (defvar woman0-macro-alist) ; bound in woman0-roff-buffer | 2359 (defvar woman0-macro-alist) ; bound in woman0-roff-buffer |
2274 (defvar woman0-search-regex) ; bound in woman0-roff-buffer | 2360 (defvar woman0-search-regex) ; bound in woman0-roff-buffer |
2275 (defvar woman0-search-regex-start ; bound in woman0-roff-buffer | 2361 (defvar woman0-search-regex-start ; bound in woman0-roff-buffer |
2279 ;; Alternatively, force maximal match (Posix?) | 2365 ;; Alternatively, force maximal match (Posix?) |
2280 | 2366 |
2281 (defvar woman0-rename-alist) ; bound in woman0-roff-buffer | 2367 (defvar woman0-rename-alist) ; bound in woman0-roff-buffer |
2282 | 2368 |
2283 (defun woman0-roff-buffer (from) | 2369 (defun woman0-roff-buffer (from) |
2284 "Process conditional-type requests and user-defined macros, starting at FROM. | 2370 "Process conditional-type requests and user-defined macros. |
2285 Re-scan new text as appropriate." | 2371 Start at FROM and re-scan new text as appropriate." |
2286 (goto-char from) | 2372 (goto-char from) |
2287 (let ((woman0-if-to (make-marker)) | 2373 (let ((woman0-if-to (make-marker)) |
2288 request woman0-macro-alist | 2374 request woman0-macro-alist |
2289 (woman0-search-regex-start woman0-search-regex-start) | 2375 (woman0-search-regex-start woman0-search-regex-start) |
2290 (woman0-search-regex | 2376 (woman0-search-regex |
2347 (set-marker woman0-if-to | 2433 (set-marker woman0-if-to |
2348 (save-excursion (skip-syntax-forward "^ ") (point))) | 2434 (save-excursion (skip-syntax-forward "^ ") (point))) |
2349 ;; Process condition: | 2435 ;; Process condition: |
2350 (if (setq negated (= (following-char) ?!)) (delete-char 1)) | 2436 (if (setq negated (= (following-char) ?!)) (delete-char 1)) |
2351 (cond | 2437 (cond |
2352 ((looking-at "[no]") (setq c t)) ; accept n(roff) and o(dd page) | 2438 ;; ((looking-at "[no]") (setq c t)) ; accept n(roff) and o(dd page) |
2353 ((looking-at "[te]") (setq c nil)) ; reject t(roff) and e(ven page) | 2439 ;; ((looking-at "[te]") (setq c nil)) ; reject t(roff) and e(ven page) |
2440 ((looking-at "[ntoe]") | |
2441 (setq c (memq (following-char) woman-if-conditions-true))) | |
2354 ;; Unrecognised letter so reject: | 2442 ;; Unrecognised letter so reject: |
2355 ((looking-at "[A-Za-z]") (setq c nil) | 2443 ((looking-at "[A-Za-z]") (setq c nil) |
2356 (WoMan-warn "%s %s -- unrecognised condition name rejected!" | 2444 (WoMan-warn "%s %s -- unrecognised condition name rejected!" |
2357 request (match-string 0))) | 2445 request (match-string 0))) |
2358 ;; Accept strings if identical: | 2446 ;; Accept strings if identical: |
2382 (woman-if-ignore woman0-if-to request) ; ERROR! | 2470 (woman-if-ignore woman0-if-to request) ; ERROR! |
2383 (woman-if-body request woman0-if-to (eq c negated))) | 2471 (woman-if-body request woman0-if-to (eq c negated))) |
2384 )) | 2472 )) |
2385 | 2473 |
2386 (defun woman-if-body (request to delete) ; should be reversed as `accept'? | 2474 (defun woman-if-body (request to delete) ; should be reversed as `accept'? |
2387 "Process if-body, including \\{ ... \\}, deleting it if TO is non-nil. | 2475 "Process if-body, including \\{ ... \\}. |
2388 REQUEST is the invoking directive. | 2476 REQUEST is the invoking directive without the leading dot. |
2389 If DELETE is non-nil, delete from point." | 2477 If TO is non-nil then delete the if-body. |
2478 If DELETE is non-nil then delete from point." | |
2390 ;; Assume concealed newlines already processed. | 2479 ;; Assume concealed newlines already processed. |
2391 (let ((from (point))) | 2480 (let ((from (point))) |
2392 (if to (delete-region (point) to)) | 2481 (if to (delete-region (point) to)) |
2393 (delete-horizontal-space) | 2482 (delete-horizontal-space) |
2394 (cond (;;(looking-at "[^{\n]*\\\\{\\s *") ; multi-line | 2483 (cond (;;(looking-at "[^{\n]*\\\\{\\s *") ; multi-line |
2440 (skip-chars-forward "^ \t") | 2529 (skip-chars-forward "^ \t") |
2441 (if (looking-at "[ \t]*\\{") (search-forward "\\}")) | 2530 (if (looking-at "[ \t]*\\{") (search-forward "\\}")) |
2442 (forward-line 1)))) | 2531 (forward-line 1)))) |
2443 | 2532 |
2444 (defun woman-if-ignore (to request) | 2533 (defun woman-if-ignore (to request) |
2445 "Ignore an if request REQUEST at TO and warn about that." | 2534 "Ignore but warn about an if request ending at TO, named REQUEST." |
2446 (WoMan-warn-ignored request "ignored -- condition not handled!") | 2535 (WoMan-warn-ignored request "ignored -- condition not handled!") |
2447 (if woman-ignore | 2536 (if woman-ignore |
2448 (woman-if-body request to t) | 2537 (woman-if-body request to t) |
2449 ;; Ignore -- leave in buffer | 2538 ;; Ignore -- leave in buffer |
2450 ;; This does not work too well, but it's only for debugging! | 2539 ;; This does not work too well, but it's only for debugging! |
2523 (defconst woman-unescape-regex | 2612 (defconst woman-unescape-regex |
2524 (concat woman-escaped-escape-string | 2613 (concat woman-escaped-escape-string |
2525 "\\(" woman-escaped-escape-string "\\)?")) | 2614 "\\(" woman-escaped-escape-string "\\)?")) |
2526 | 2615 |
2527 (defsubst woman-unescape (macro) | 2616 (defsubst woman-unescape (macro) |
2528 "Replace escaped sequences in body of MACRO. | 2617 "Replace escape sequences in the body of MACRO. |
2529 Replaces || by |, but | by \, where | denotes the internal escape." | 2618 Replaces || by |, but | by \, where | denotes the internal escape." |
2530 (let (start) | 2619 (let (start) |
2531 (while (setq start (string-match woman-unescape-regex macro start)) | 2620 (while (setq start (string-match woman-unescape-regex macro start)) |
2532 (setq macro | 2621 (setq macro |
2533 (if (match-string 1 macro) | 2622 (if (match-string 1 macro) |
2577 )) | 2666 )) |
2578 (beginning-of-line) ; delete .de/am line | 2667 (beginning-of-line) ; delete .de/am line |
2579 (woman-delete-line 1)) | 2668 (woman-delete-line 1)) |
2580 | 2669 |
2581 (defun woman0-macro (request) | 2670 (defun woman0-macro (request) |
2582 "Process macro call like the named REQUEST." | 2671 "Process the macro call named REQUEST." |
2583 ;; Leaves point at start of new text. | 2672 ;; Leaves point at start of new text. |
2584 (let ((macro (assoc request woman0-macro-alist))) | 2673 (let ((macro (assoc request woman0-macro-alist))) |
2585 (if macro | 2674 (if macro |
2586 (woman-interpolate-macro (cdr macro)) | 2675 (woman-interpolate-macro (cdr macro)) |
2587 ;; SHOULD DELETE THE UNINTERPRETED REQUEST!!!!! | 2676 ;; SHOULD DELETE THE UNINTERPRETED REQUEST!!!!! |
2588 ;; Output this message once only per call (cf. strings)? | 2677 ;; Output this message once only per call (cf. strings)? |
2589 (WoMan-warn "Undefined macro %s not interpolated!" request)))) | 2678 (WoMan-warn "Undefined macro %s not interpolated!" request)))) |
2590 | 2679 |
2591 (defun woman-interpolate-macro (macro) | 2680 (defun woman-interpolate-macro (macro) |
2592 "Interpolate (.de) or append (.am) a expansion of MACRO into the buffer." | 2681 "Interpolate (.de) or append (.am) expansion of MACRO into the buffer." |
2593 ;; Could make this more efficient by checking which arguments are | 2682 ;; Could make this more efficient by checking which arguments are |
2594 ;; actually used in the expansion! | 2683 ;; actually used in the expansion! |
2595 (skip-chars-forward " \t") | 2684 (skip-chars-forward " \t") |
2596 ;; Process arguments: | 2685 ;; Process arguments: |
2597 (let ((argno 0) (append (car macro)) | 2686 (let ((argno 0) (append (car macro)) |
2631 | 2720 |
2632 | 2721 |
2633 ;;; Process strings: | 2722 ;;; Process strings: |
2634 | 2723 |
2635 (defun woman-strings (&optional to) | 2724 (defun woman-strings (&optional to) |
2636 "Process ?roff strings: defined/updated by `.ds xx string' requests. | 2725 "Process ?roff string requests and escape sequences up to buffer position TO. |
2637 Interpolate by `\*x' and `\*(xx' escapes. | 2726 Strings are defined/updated by `.ds xx string' requests and |
2638 Optional argument TO specifies where in the buffer does the request end." | 2727 interpolated by `\*x' and `\*(xx' escapes." |
2639 ;; Add support for .as and .rm? | 2728 ;; Add support for .as and .rm? |
2640 (while | 2729 (while |
2641 ;; Find .ds requests and \* escapes: | 2730 ;; Find .ds requests and \* escapes: |
2642 (re-search-forward "\\(^[.'][ \t]*ds\\)\\|\\\\\\*" to t) | 2731 (re-search-forward "\\(^[.'][ \t]*ds\\)\\|\\\\\\*" to t) |
2643 (cond ((match-string 1) ; .ds | 2732 (cond ((match-string 1) ; .ds |
2737 i.e. omitted, to indicate use of the default font. | 2826 i.e. omitted, to indicate use of the default font. |
2738 Any element may be nil. Avoid control character codes (0 to \\37, \\180 | 2827 Any element may be nil. Avoid control character codes (0 to \\37, \\180 |
2739 to \\237) in `extended-font-string' for now, since they can be | 2828 to \\237) in `extended-font-string' for now, since they can be |
2740 displayed only with a modified display table. | 2829 displayed only with a modified display table. |
2741 | 2830 |
2742 Use the Emacs command `woman-display-extended-fonts' or a character | 2831 Use the WoMan command `woman-display-extended-fonts' or a character |
2743 map accessory to help construct this alist.") | 2832 map accessory to help construct this alist.") |
2744 | 2833 |
2834 (defsubst woman-replace-match (newtext &optional face) | |
2835 "Replace text matched by last search with NEWTEXT and return t. | |
2836 Set NEWTEXT in face FACE if specified." | |
2837 (woman-delete-match 0) | |
2838 (insert-before-markers newtext) | |
2839 (if face (put-text-property (1- (point)) (point) | |
2840 'face 'woman-symbol-face)) | |
2841 t) | |
2842 | |
2745 (defun woman-special-characters (to) | 2843 (defun woman-special-characters (to) |
2746 "Process special character escapes \(xx up to buffer position TO." | 2844 "Process special character escapes \(xx up to buffer position TO. |
2747 ;; Must be done AFTER translation, which may use special chars. | 2845 \(This must be done AFTER translation, which may use special characters.)" |
2748 (while (re-search-forward "\\\\(\\(..\\)" to t) | 2846 (while (re-search-forward "\\\\(\\(..\\)" to t) |
2749 (let ((replacement | 2847 (let ((replacement |
2750 (assoc (match-string-no-properties 1) woman-special-characters))) | 2848 (assoc (match-string-no-properties 1) woman-special-characters))) |
2751 (if (and | 2849 (if (and |
2752 replacement | 2850 replacement |
2753 (cond ((and woman-use-symbols (cddr replacement)) | 2851 (cond ((and (cddr replacement) |
2754 ; use extended font | 2852 (if (nthcdr 3 replacement) |
2755 (woman-delete-match 0) | 2853 ;; Need symbol font: |
2756 (insert-before-markers (nth 2 replacement)) | 2854 (if woman-use-symbol-font |
2757 (if (nthcdr 3 replacement) ; use woman-symbol-face | 2855 (woman-replace-match (nth 2 replacement) |
2758 (put-text-property (1- (point)) (point) | 2856 'woman-symbol-face)) |
2759 'face 'woman-symbol-face)) | 2857 ;; Need extended font: |
2760 t) | 2858 (if woman-use-extended-font |
2859 (woman-replace-match (nth 2 replacement)))))) | |
2761 ((cadr replacement) ; Use ASCII simulation | 2860 ((cadr replacement) ; Use ASCII simulation |
2762 (woman-delete-match 0) | 2861 (woman-replace-match (cadr replacement))))) |
2763 (insert-before-markers (cadr replacement)) | |
2764 t))) | |
2765 () | 2862 () |
2766 (WoMan-warn "Special character \\(%s not interpolated!" | 2863 (WoMan-warn "Special character \\(%s not interpolated!" |
2767 (match-string-no-properties 1)) | 2864 (match-string-no-properties 1)) |
2768 (if woman-ignore (woman-delete-match 0)))) | 2865 (if woman-ignore (woman-delete-match 0)))) |
2769 )) | 2866 )) |
2770 | 2867 |
2771 (defun woman-display-extended-fonts () | 2868 (defun woman-display-extended-fonts () |
2772 "Display glyphs of graphic charactes and their octal codes. | 2869 "Display table of glyphs of graphic characters and their octal codes. |
2773 All the characters in the ranges [32..127] and [160..255] are displayed | 2870 All the octal codes in the ranges [32..127] and [160..255] are displayed |
2774 together with the corresponding glyphs from the default and symbol fonts. | 2871 together with the corresponding glyphs from the default and symbol fonts. |
2775 Useful for constructing the `woman-special-characters' alist." | 2872 Useful for constructing the alist variable `woman-special-characters'." |
2776 (interactive) | 2873 (interactive) |
2777 (with-output-to-temp-buffer "*WoMan Extended Font Map*" | 2874 (with-output-to-temp-buffer "*WoMan Extended Font Map*" |
2778 (save-excursion | 2875 (save-excursion |
2779 (set-buffer standard-output) | 2876 (set-buffer standard-output) |
2780 (let ((i 32)) | 2877 (let ((i 32)) |
2857 ".I -- Set words of current line in italic font." | 2954 ".I -- Set words of current line in italic font." |
2858 (woman1-B-or-I ".ft I\n")) | 2955 (woman1-B-or-I ".ft I\n")) |
2859 | 2956 |
2860 (defun woman1-B-or-I (B-or-I) | 2957 (defun woman1-B-or-I (B-or-I) |
2861 ".B/I -- Set words of current line in bold/italic font. | 2958 ".B/I -- Set words of current line in bold/italic font. |
2862 B-OR-I is the invoking directive." | 2959 B-OR-I is the appropriate complete control line." |
2863 ;; Should NOT concatenate the arguments! | 2960 ;; Should NOT concatenate the arguments! |
2864 (insert B-or-I) ; because it might be a control line | 2961 (insert B-or-I) ; because it might be a control line |
2865 ;; Return to bol to process .SM/.B, .B/.if etc. | 2962 ;; Return to bol to process .SM/.B, .B/.if etc. |
2866 ;; or start of first arg to hide leading control char. | 2963 ;; or start of first arg to hide leading control char. |
2867 (save-excursion | 2964 (save-excursion |
2876 ".SM -- Set the current line in small font, i.e. IGNORE!" | 2973 ".SM -- Set the current line in small font, i.e. IGNORE!" |
2877 nil) | 2974 nil) |
2878 | 2975 |
2879 (defalias 'woman1-SB 'woman1-B) | 2976 (defalias 'woman1-SB 'woman1-B) |
2880 ;; .SB -- Set the current line in small bold font, i.e. just embolden! | 2977 ;; .SB -- Set the current line in small bold font, i.e. just embolden! |
2881 ;; (This is what c:/usr/local/share/groff/tmac/tmac.an does. The | 2978 ;; (This is what /usr/local/share/groff/tmac/tmac.an does. The |
2882 ;; Linux man.7 is wrong about this!) | 2979 ;; Linux man.7 is wrong about this!) |
2883 | 2980 |
2884 (defun woman1-BI () | 2981 (defun woman1-BI () |
2885 ".BI -- Join words of current line alternating bold and italic fonts." | 2982 ".BI -- Join words of current line alternating bold and italic fonts." |
2886 (woman1-alt-fonts (list "\\fB" "\\fI"))) | 2983 (woman1-alt-fonts (list "\\fB" "\\fI"))) |
2919 (woman-forward-arg unquote 'concat)) ; unquote is bound above | 3016 (woman-forward-arg unquote 'concat)) ; unquote is bound above |
2920 (insert "\\fR") | 3017 (insert "\\fR") |
2921 )) | 3018 )) |
2922 | 3019 |
2923 (defun woman-forward-arg (&optional unquote concat) | 3020 (defun woman-forward-arg (&optional unquote concat) |
2924 "Move forward over one ?roff argument, optionally deleting quotes. | 3021 "Move forward over one ?roff argument, optionally unquoting and/or joining. |
2925 If optional arg UNQUOTE is non-nil, delete any argument quotes. | 3022 If optional arg UNQUOTE is non-nil then delete any argument quotes. |
2926 If optional arg CONCAT is non-nil, join arguments." | 3023 If optional arg CONCAT is non-nil then join arguments." |
2927 (if (eq (following-char) ?\") | 3024 (if (eq (following-char) ?\") |
2928 (progn | 3025 (progn |
2929 (if unquote (delete-char 1) (forward-char)) | 3026 (if unquote (delete-char 1) (forward-char)) |
2930 (re-search-forward "\"\\|$") | 3027 (re-search-forward "\"\\|$") |
2931 ;; Repeated double-quote represents single double-quote | 3028 ;; Repeated double-quote represents single double-quote |
2942 ((eq concat 'noskip)) ; do not skip following whitespace | 3039 ((eq concat 'noskip)) ; do not skip following whitespace |
2943 (t (woman-delete-following-space))) | 3040 (t (woman-delete-following-space))) |
2944 ) | 3041 ) |
2945 | 3042 |
2946 | 3043 |
2947 ;;; The following requests are not explicit font-change requests and | 3044 ;; The following requests are not explicit font-change requests and |
2948 ;;; so are flagged `notfont' to turn off automatic request deletion | 3045 ;; so are flagged `notfont' to turn off automatic request deletion |
2949 ;;; and further processing. | 3046 ;; and further processing. |
2950 | 3047 |
2951 (put 'woman1-TP 'notfont t) | 3048 (put 'woman1-TP 'notfont t) |
2952 (defun woman1-TP () | 3049 (defun woman1-TP () |
2953 ".TP -- After tag line, reset font to Roman for paragraph body." | 3050 ".TP -- After tag line, reset font to Roman for paragraph body." |
2954 ;; Same for .IP, but forward only 1 line? | 3051 ;; Same for .IP, but forward only 1 line? |
2967 (insert ".ft I\n") | 3064 (insert ".ft I\n") |
2968 (forward-line N) | 3065 (forward-line N) |
2969 (insert ".ft R\n") | 3066 (insert ".ft R\n") |
2970 )) | 3067 )) |
2971 | 3068 |
2972 ;; Other non-breaking requests: | 3069 ;;; Other non-breaking requests: |
2973 | 3070 |
2974 ;; Hyphenation | 3071 ;; Hyphenation |
2975 ;; Warnings commented out. | 3072 ;; Warnings commented out. |
2976 | 3073 |
2977 (put 'woman1-nh 'notfont t) | 3074 (put 'woman1-nh 'notfont t) |
3005 (defun woman1-hw () | 3102 (defun woman1-hw () |
3006 ".hw words -- Set hyphenation exception words, i.e. IGNORE!" | 3103 ".hw words -- Set hyphenation exception words, i.e. IGNORE!" |
3007 ;; (WoMan-log-1 ".hw request ignored -- hyphenation not supported!") | 3104 ;; (WoMan-log-1 ".hw request ignored -- hyphenation not supported!") |
3008 (woman-delete-whole-line)) | 3105 (woman-delete-whole-line)) |
3009 | 3106 |
3010 ;; Other non-breaking requests correctly ignored by nroff: | 3107 ;;; Other non-breaking requests correctly ignored by nroff: |
3011 | 3108 |
3012 (put 'woman1-ps 'notfont t) | 3109 (put 'woman1-ps 'notfont t) |
3013 (defalias 'woman1-ps 'woman-delete-whole-line) | 3110 (defalias 'woman1-ps 'woman-delete-whole-line) |
3014 ;; .ps -- Point size -- IGNORE! | 3111 ;; .ps -- Point size -- IGNORE! |
3015 | 3112 |
3031 | 3128 |
3032 (put 'woman1-bd 'notfont t) | 3129 (put 'woman1-bd 'notfont t) |
3033 (defalias 'woman1-bd 'woman-delete-whole-line) | 3130 (defalias 'woman1-bd 'woman-delete-whole-line) |
3034 ;; .bd -- Embolden font -- IGNORE! | 3131 ;; .bd -- Embolden font -- IGNORE! |
3035 | 3132 |
3036 ;; Non-breaking SunOS-specific macros: | 3133 ;;; Non-breaking SunOS-specific macros: |
3037 | 3134 |
3038 (defun woman1-TX () | 3135 (defun woman1-TX () |
3039 ".TX t p -- Resolve SunOS abbrev t and join to p (usually punctuation)." | 3136 ".TX t p -- Resolve SunOS abbrev t and join to p (usually punctuation)." |
3040 (insert "SunOS ") | 3137 (insert "SunOS ") |
3041 (woman-forward-arg 'unquote 'concat)) | 3138 (woman-forward-arg 'unquote 'concat)) |
3165 (prog1 (char-to-string (following-char)) | 3262 (prog1 (char-to-string (following-char)) |
3166 (delete-char 1)))) | 3263 (delete-char 1)))) |
3167 | 3264 |
3168 (defun woman2-tr (to) | 3265 (defun woman2-tr (to) |
3169 ".tr abcde -- Translate a -> b, c -> d, ..., e -> space. | 3266 ".tr abcde -- Translate a -> b, c -> d, ..., e -> space. |
3170 TO is the buffer position where the directive ends. | 3267 Format paragraphs upto TO. Supports special chars. |
3171 \(Breaks, but should not.) Supports special chars." | 3268 \(Breaks, but should not.)" |
3172 ;; This should be an update, but consing onto the front of the alist | 3269 ;; This should be an update, but consing onto the front of the alist |
3173 ;; has the same effect and match duplicates should not matter. | 3270 ;; has the same effect and match duplicates should not matter. |
3174 ;; Initialize translation data structures: | 3271 ;; Initialize translation data structures: |
3175 (let ((matches (car translations)) | 3272 (let ((matches (car translations)) |
3176 (alist (cdr translations)) | 3273 (alist (cdr translations)) |
3250 (woman2-process-escapes | 3347 (woman2-process-escapes |
3251 (save-excursion (end-of-line) (point-marker)) | 3348 (save-excursion (end-of-line) (point-marker)) |
3252 numeric)) | 3349 numeric)) |
3253 | 3350 |
3254 (defun woman2-nr (to) | 3351 (defun woman2-nr (to) |
3255 ".nr R +/-N M -- Assign +/-N to register R wrt to previous value, if any. | 3352 ".nr R +/-N M -- Assign +/-N (wrt to previous value, if any) to register R. |
3256 The increment for auto-incrementing is set to M. | 3353 The increment for auto-incrementing is set to M. |
3257 TO is where the directive ends. | 3354 Format paragraphs upto TO. (Breaks, but should not!)" |
3258 \[Breaks, but should not!]" | |
3259 (let* ((name (buffer-substring | 3355 (let* ((name (buffer-substring |
3260 (point) | 3356 (point) |
3261 (progn (skip-syntax-forward "^ ") (point)))) | 3357 (progn (skip-syntax-forward "^ ") (point)))) |
3262 (pm (progn ; increment | 3358 (pm (progn ; increment |
3263 (skip-chars-forward " \t") | 3359 (skip-chars-forward " \t") |
3293 | 3389 |
3294 | 3390 |
3295 ;;; Numeric (and "non-text") request arguments: | 3391 ;;; Numeric (and "non-text") request arguments: |
3296 | 3392 |
3297 (defsubst woman-get-numeric-arg () | 3393 (defsubst woman-get-numeric-arg () |
3298 "Get the value of a numeric argument at or after point, don't move point. | 3394 "Get the value of a numeric argument at or after point. |
3299 The argument can include the width function and scale indicators. | 3395 The argument can include the width function and scale indicators. |
3300 Assumes 10 characters per inch." | 3396 Assumes 10 characters per inch. Does not move point." |
3301 (woman2-process-escapes-to-eol 'numeric) | 3397 (woman2-process-escapes-to-eol 'numeric) |
3302 (save-excursion (woman-parse-numeric-arg))) | 3398 (save-excursion (woman-parse-numeric-arg))) |
3303 | 3399 |
3304 (defun woman-parse-numeric-arg () | 3400 (defun woman-parse-numeric-arg () |
3305 "Get the value of a numeric expression at or after point. | 3401 "Get the value of a numeric expression at or after point. |
3348 value | 3444 value |
3349 )) | 3445 )) |
3350 | 3446 |
3351 (defun woman-parse-numeric-value () | 3447 (defun woman-parse-numeric-value () |
3352 "Get a single numeric value at or after point. | 3448 "Get a single numeric value at or after point. |
3353 Leaving point after the value. It can be a number register or width | 3449 The value can be a number register or width function (which assumes 10 |
3354 function (which assumes 10 characters per inch) and can include scale | 3450 characters per inch) and can include scale indicators. It may be an |
3355 indicators. The value may be an expression in parentheses." | 3451 expression in parentheses. Leaves point after the value." |
3356 ;; Must replace every \' by some different single character first | 3452 ;; Must replace every \' by some different single character first |
3357 ;; before calling this function by calling | 3453 ;; before calling this function by calling |
3358 ;; (woman2-process-escapes-to-eol 'numeric) | 3454 ;; (woman2-process-escapes-to-eol 'numeric) |
3359 (if (eq (following-char) ?\() | 3455 (if (eq (following-char) ?\() |
3360 ;; Treat parenthesized expression as a single value. | 3456 ;; Treat parenthesized expression as a single value. |
3432 ))) | 3528 ))) |
3433 | 3529 |
3434 | 3530 |
3435 ;;; VERTICAL FORMATTING -- Formatting macros that cause a break: | 3531 ;;; VERTICAL FORMATTING -- Formatting macros that cause a break: |
3436 | 3532 |
3437 ; Vertical spacing philosophy: | 3533 ;; Vertical spacing philosophy: |
3438 ; Delete all vertical space as it is encountered. Then insert | 3534 ;; Delete all vertical space as it is encountered. Then insert |
3439 ; vertical space only before text, as required. | 3535 ;; vertical space only before text, as required. |
3440 | 3536 |
3441 (defun woman2-roff-buffer () | 3537 (defun woman2-roff-buffer () |
3442 "Process breaks. Format paragraphs and headings." | 3538 "Process breaks. Format paragraphs and headings." |
3443 (let ((case-fold-search t) | 3539 (let ((case-fold-search t) |
3444 (to (make-marker)) | 3540 (to (make-marker)) |
3518 (woman-delete-line 2))) | 3614 (woman-delete-line 2))) |
3519 (if to (1- to) (point-max)))) | 3615 (if to (1- to) (point-max)))) |
3520 | 3616 |
3521 (defun woman2-PD (to) | 3617 (defun woman2-PD (to) |
3522 ".PD d -- Set the interparagraph distance to d. | 3618 ".PD d -- Set the interparagraph distance to d. |
3523 Round to whole lines, default 1 line. (Breaks, but should not.) | 3619 Round to whole lines, default 1 line. Format paragraphs upto TO. |
3524 TO is the buffer position where the directive ends." | 3620 (Breaks, but should not.)" |
3525 ;; .ie \\n[.$] .nr PD (v;\\$1) | 3621 ;; .ie \\n[.$] .nr PD (v;\\$1) |
3526 ;; .el .nr PD .4v>?\n[.V] | 3622 ;; .el .nr PD .4v>?\n[.V] |
3527 (woman-set-interparagraph-distance) | 3623 (woman-set-interparagraph-distance) |
3528 (woman2-format-paragraphs to)) | 3624 (woman2-format-paragraphs to)) |
3529 | 3625 |
3530 (defun woman-set-interparagraph-distance () | 3626 (defun woman-set-interparagraph-distance () |
3531 "Set interparagraph distance from .PD directive at point." | 3627 "Set the interparagraph distance from a .PD request at point." |
3532 (setq woman-interparagraph-distance | 3628 (setq woman-interparagraph-distance |
3533 (if (eolp) 1 (woman-get-numeric-arg))) | 3629 (if (eolp) 1 (woman-get-numeric-arg))) |
3534 ;; Should allow .PD 0 to set zero line spacing | 3630 ;; Should allow .PD 0 to set zero line spacing |
3535 (woman-delete-line 1)) ; ignore remaining args | 3631 (woman-delete-line 1)) ; ignore remaining args |
3536 | 3632 |
3537 (defsubst woman-interparagraph-space () | 3633 (defsubst woman-interparagraph-space () |
3538 "Set `woman-leave-blank-lines' from `woman-interparagraph-distance'." | 3634 "Set variable `woman-leave-blank-lines' from `woman-interparagraph-distance'." |
3539 ; (if (> woman-interparagraph-distance 0) | 3635 ; (if (> woman-interparagraph-distance 0) |
3540 ; (forward-line 1) ; leave 1 blank line | 3636 ; (forward-line 1) ; leave 1 blank line |
3541 ; (woman-delete-line 1)) ; do not leave blank line | 3637 ; (woman-delete-line 1)) ; do not leave blank line |
3542 (setq woman-leave-blank-lines woman-interparagraph-distance) | 3638 (setq woman-leave-blank-lines woman-interparagraph-distance) |
3543 ) | 3639 ) |
3544 | 3640 |
3545 (defun woman2-TH (to) | 3641 (defun woman2-TH (to) |
3546 ".TH n c x v m -- Begin a page as per directive ending at TO. | 3642 ".TH n c x v m -- Begin a man page. Format paragraphs upto TO. |
3547 n is the name of the chapter c; x is extra commentary; v alters page | 3643 n is the name of the page in chapter c\; x is extra commentary\; |
3548 foot left; m alters page head center. | 3644 v alters page foot left; m alters page head center. |
3549 \(Should set prevailing indent (and tabs) to 5.)" | 3645 \(Should set prevailing indent and tabs to 5.)" |
3550 (woman-forward-arg 'unquote 'concat) | 3646 (woman-forward-arg 'unquote 'concat) |
3551 (insert ?\() | 3647 (insert ?\() |
3552 (woman-forward-arg 'unquote 'concat) | 3648 (woman-forward-arg 'unquote 'concat) |
3553 (insert ?\)) | 3649 (insert ?\)) |
3554 (let ((start (point)) here) | 3650 (let ((start (point)) here) |
3574 (setq woman-left-margin woman-default-indent) | 3670 (setq woman-left-margin woman-default-indent) |
3575 (setq woman-prevailing-indent woman-default-indent) | 3671 (setq woman-prevailing-indent woman-default-indent) |
3576 (woman2-format-paragraphs to woman-left-margin)) | 3672 (woman2-format-paragraphs to woman-left-margin)) |
3577 | 3673 |
3578 (defun woman2-SH (to) | 3674 (defun woman2-SH (to) |
3579 ".SH -- Sub-head. Leave blank line and subhead at TO. | 3675 ".SH -- Sub-head. Leave blank line and subhead. |
3580 Format following paragraph. Set prevailing indent to 5." | 3676 Format paragraphs upto TO. Set prevailing indent to 5." |
3581 (if (eolp) ; If no args then | 3677 (if (eolp) ; If no args then |
3582 (delete-char 1) ; apply to next line | 3678 (delete-char 1) ; apply to next line |
3583 (woman-unquote-args) ; else unquote to end of heading | 3679 (woman-unquote-args) ; else unquote to end of heading |
3584 (beginning-of-line)) | 3680 (beginning-of-line)) |
3585 (woman2-process-escapes-to-eol) | 3681 (woman2-process-escapes-to-eol) |
3594 woman-nofill nil) ; fill output lines | 3690 woman-nofill nil) ; fill output lines |
3595 (setq woman-prevailing-indent woman-default-indent) | 3691 (setq woman-prevailing-indent woman-default-indent) |
3596 (woman2-format-paragraphs to woman-left-margin)) | 3692 (woman2-format-paragraphs to woman-left-margin)) |
3597 | 3693 |
3598 (defun woman2-SS (to) | 3694 (defun woman2-SS (to) |
3599 ".SS -- Sub-sub-head at TO. Like .SH but indent heading 3 spaces." | 3695 ".SS -- Sub-sub-head. Like .SH but indent heading 3 spaces. |
3696 Format paragraphs upto TO." | |
3600 (if (eolp) ; If no args then | 3697 (if (eolp) ; If no args then |
3601 (delete-char 1)) ; apply to next line. | 3698 (delete-char 1)) ; apply to next line. |
3602 (insert " ") | 3699 (insert " ") |
3603 (beginning-of-line) | 3700 (beginning-of-line) |
3604 (woman2-SH to)) | 3701 (woman2-SH to)) |
3605 | 3702 |
3606 (defun woman2-LP (to) | 3703 (defun woman2-LP (to) |
3607 ".LP,.PP -- Begin paragraph at TO. Set prevailing indent to 5. | 3704 ".LP,.PP -- Begin paragraph. Set prevailing indent to 5. |
3608 Leave 1 blank line and format following paragraph." | 3705 Leave 1 blank line. Format paragraphs upto TO." |
3609 (woman-delete-line 1) ; ignore any arguments | 3706 (woman-delete-line 1) ; ignore any arguments |
3610 (woman-interparagraph-space) | 3707 (woman-interparagraph-space) |
3611 (setq woman-prevailing-indent woman-default-indent) | 3708 (setq woman-prevailing-indent woman-default-indent) |
3612 (woman2-format-paragraphs to woman-left-margin)) | 3709 (woman2-format-paragraphs to woman-left-margin)) |
3613 | 3710 |
3614 (defalias 'woman2-PP 'woman2-LP) | 3711 (defalias 'woman2-PP 'woman2-LP) |
3615 (defalias 'woman2-P 'woman2-LP) | 3712 (defalias 'woman2-P 'woman2-LP) |
3616 | 3713 |
3617 (defun woman2-ns (to) | 3714 (defun woman2-ns (to) |
3618 ".ns -- Turn on no-space mode at TO and format following paragraph." | 3715 ".ns -- Turn on no-space mode. Format paragraphs upto TO." |
3619 ;; Should not cause a break! | 3716 ;; Should not cause a break! |
3620 (woman-delete-line 1) ; ignore argument(s) | 3717 (woman-delete-line 1) ; ignore argument(s) |
3621 (setq woman-nospace t) | 3718 (setq woman-nospace t) |
3622 (woman2-format-paragraphs to)) | 3719 (woman2-format-paragraphs to)) |
3623 | 3720 |
3624 (defun woman2-rs (to) | 3721 (defun woman2-rs (to) |
3625 ".rs -- Turn off no-space mode at TO and format following paragraph." | 3722 ".rs -- Turn off no-space mode. Format paragraphs upto TO." |
3626 ;; Should not cause a break! | 3723 ;; Should not cause a break! |
3627 (woman-delete-line 1) ; ignore argument(s) | 3724 (woman-delete-line 1) ; ignore argument(s) |
3628 (setq woman-nospace nil) | 3725 (setq woman-nospace nil) |
3629 (woman2-format-paragraphs to)) | 3726 (woman2-format-paragraphs to)) |
3630 | 3727 |
3631 (defun woman2-sp (to) | 3728 (defun woman2-sp (to) |
3632 ".sp N -- If N > 0, leave 1 blank line at TO and format following paragraph." | 3729 ".sp N -- If N > 0 then leave 1 blank line. Format paragraphs upto TO." |
3633 (let ((N (if (eolp) 1 (woman-get-numeric-arg)))) | 3730 (let ((N (if (eolp) 1 (woman-get-numeric-arg)))) |
3634 (if (>= N 0) | 3731 (if (>= N 0) |
3635 (woman-delete-line 1) ; ignore argument(s) | 3732 (woman-delete-line 1) ; ignore argument(s) |
3636 (setq woman-negative-vertical-space t) | 3733 (setq woman-negative-vertical-space t) |
3637 (insert ".sp ") | 3734 (insert ".sp ") |
3784 )) | 3881 )) |
3785 | 3882 |
3786 ;;; 4. Text Filling, Adjusting, and Centering | 3883 ;;; 4. Text Filling, Adjusting, and Centering |
3787 | 3884 |
3788 (defun woman2-br (to) | 3885 (defun woman2-br (to) |
3789 ".br -- Break. Leave no blank line at TO and format following paragraph." | 3886 ".br -- Break. Leave no blank line. Format paragraphs upto TO." |
3790 (woman-delete-line 1) ; ignore any arguments | 3887 (woman-delete-line 1) ; ignore any arguments |
3791 (woman2-format-paragraphs to)) | 3888 (woman2-format-paragraphs to)) |
3792 | 3889 |
3793 (defun woman2-fi (to) | 3890 (defun woman2-fi (to) |
3794 ".fi -- Fill subsequent output lines at TO. | 3891 ".fi -- Fill subsequent output lines. Leave no blank line. |
3795 Leave no blank line and format following paragraph" | 3892 Format paragraphs upto TO." |
3796 (setq woman-nofill nil) | 3893 (setq woman-nofill nil) |
3797 (woman-delete-line 1) ; ignore any arguments | 3894 (woman-delete-line 1) ; ignore any arguments |
3798 ;; Preserve any final blank line in the nofill region: | 3895 ;; Preserve any final blank line in the nofill region: |
3799 (save-excursion | 3896 (save-excursion |
3800 (forward-line -1) | 3897 (forward-line -1) |
3801 (if (looking-at "[ \t]*$") (setq woman-leave-blank-lines 1))) | 3898 (if (looking-at "[ \t]*$") (setq woman-leave-blank-lines 1))) |
3802 (woman2-format-paragraphs to)) | 3899 (woman2-format-paragraphs to)) |
3803 | 3900 |
3804 (defun woman2-nf (to) | 3901 (defun woman2-nf (to) |
3805 ".nf -- Nofill at TO. Subsequent lines are neither filled nor adjusted. | 3902 ".nf -- Nofill. Subsequent lines are neither filled nor adjusted. |
3806 Input text lines are copied directly to output lines without regard for | 3903 Input text lines are copied directly to output lines without regard |
3807 the current line length." | 3904 for the current line length. Format paragraphs upto TO." |
3808 (setq woman-nofill t) | 3905 (setq woman-nofill t) |
3809 (woman-delete-line 1) ; ignore any arguments | 3906 (woman-delete-line 1) ; ignore any arguments |
3810 (woman2-format-paragraphs to)) | 3907 (woman2-format-paragraphs to)) |
3811 | 3908 |
3812 (defun woman2-ad (to) | 3909 (defun woman2-ad (to) |
3813 ".ad c -- Line adjustment is begun at TO (once fill mode is on). | 3910 ".ad c -- Line adjustment is begun (once fill mode is on). |
3814 Set justification mode to c if specified. (Breaks, but should not.)" | 3911 Set justification mode to c if specified. |
3912 Format paragraphs upto TO. (Breaks, but should not.)" | |
3815 ;; c = l -- left, r -- right, c -- center, b or n -- both, | 3913 ;; c = l -- left, r -- right, c -- center, b or n -- both, |
3816 ;; absent -- unchanged. Initial mode adj,both. | 3914 ;; absent -- unchanged. Initial mode adj,both. |
3817 (setq woman-adjust | 3915 (setq woman-adjust |
3818 (cond ((eolp) woman-adjust-previous) | 3916 (cond ((eolp) woman-adjust-previous) |
3819 ((eq (following-char) ?l) woman-adjust-left) | 3917 ((eq (following-char) ?l) woman-adjust-left) |
3825 woman-justify (nth woman-adjust woman-justify-list)) | 3923 woman-justify (nth woman-adjust woman-justify-list)) |
3826 (woman-delete-line 1) ; ignore any remaining arguments | 3924 (woman-delete-line 1) ; ignore any remaining arguments |
3827 (woman2-format-paragraphs to)) | 3925 (woman2-format-paragraphs to)) |
3828 | 3926 |
3829 (defun woman2-na (to) | 3927 (defun woman2-na (to) |
3830 ".na -- No adjusting at TO. | 3928 ".na -- No adjusting. Format paragraphs upto TO. |
3831 (Breaks, but should not.)" | 3929 (Breaks, but should not.)" |
3832 (setq woman-adjust-previous woman-adjust | 3930 (setq woman-adjust-previous woman-adjust |
3833 woman-justify-previous woman-justify | 3931 woman-justify-previous woman-justify |
3834 woman-adjust woman-adjust-left ; fill but do not adjust | 3932 woman-adjust woman-adjust-left ; fill but do not adjust |
3835 woman-justify (nth woman-adjust woman-justify-list)) | 3933 woman-justify (nth woman-adjust woman-justify-list)) |
3838 | 3936 |
3839 ;;; The main formatting functions: | 3937 ;;; The main formatting functions: |
3840 | 3938 |
3841 (defun woman-leave-blank-lines (&optional leave) | 3939 (defun woman-leave-blank-lines (&optional leave) |
3842 "Delete all blank lines around point. | 3940 "Delete all blank lines around point. |
3843 Leave one blank line if optional argument LEAVE is non-nil and non-zero, | 3941 Leave one blank line if optional argument LEAVE is non-nil and |
3844 or if LEAVE is nil and `woman-leave-blank-lines' is non-nil and non-zero." | 3942 non-zero, or if LEAVE is nil and variable `woman-leave-blank-lines' is |
3943 non-nil and non-zero." | |
3845 ;; ***** It may suffice to delete only lines ABOVE point! ***** | 3944 ;; ***** It may suffice to delete only lines ABOVE point! ***** |
3846 ;; NOTE: Function arguments are evaluated left to right | 3945 ;; NOTE: Function arguments are evaluated left to right |
3847 ;; (*note (elisp)Function Forms::.). | 3946 ;; (*note (elisp)Function Forms::.). |
3848 (delete-region | 3947 (delete-region |
3849 (save-excursion | 3948 (save-excursion |
3867 ;; text filling function, so that is what I use here. | 3966 ;; text filling function, so that is what I use here. |
3868 | 3967 |
3869 (defvar woman-temp-indent nil) | 3968 (defvar woman-temp-indent nil) |
3870 | 3969 |
3871 (defun woman2-format-paragraphs (to &optional new-left) | 3970 (defun woman2-format-paragraphs (to &optional new-left) |
3872 "Indent paragraphs at TO to current left margin. | 3971 "Indent, fill and adjust paragraphs upto TO to current left margin. |
3873 Optional argument NEW-LEFT, if non-nil, means set current left margin. | 3972 If optional arg NEW-LEFT is non-nil then reset current left margin. |
3874 If `woman-nofill' is nil, also fill and adjust." | 3973 If `woman-nofill' is non-nil then indent without filling or adjusting." |
3875 ;; Blank space should only ever be output before text. | 3974 ;; Blank space should only ever be output before text. |
3876 (if new-left (setq left-margin new-left)) | 3975 (if new-left (setq left-margin new-left)) |
3877 (if (looking-at "^\\s *$") | 3976 (if (looking-at "^\\s *$") |
3878 ;; A blank line should leave a space like .sp 1 (p. 14). | 3977 ;; A blank line should leave a space like .sp 1 (p. 14). |
3879 (setq woman-leave-blank-lines 1)) | 3978 (setq woman-leave-blank-lines 1)) |
3958 | 4057 |
3959 | 4058 |
3960 ;;; Tagged, indented and hanging paragraphs: | 4059 ;;; Tagged, indented and hanging paragraphs: |
3961 | 4060 |
3962 (defun woman2-TP (to) | 4061 (defun woman2-TP (to) |
3963 ".TP i -- Set prevailing indent to i at TO. | 4062 ".TP i -- Set prevailing indent to i. Format paragraphs upto TO. |
3964 Begin indented paragraph with hanging tag given by next text line. | 4063 Begin indented paragraph with hanging tag given by next text line. |
3965 If tag doesn't fit, place it on a separate line." | 4064 If tag doesn't fit, place it on a separate line." |
3966 (let ((i (woman2-get-prevailing-indent))) | 4065 (let ((i (woman2-get-prevailing-indent))) |
3967 (woman-leave-blank-lines woman-interparagraph-distance) | 4066 (woman-leave-blank-lines woman-interparagraph-distance) |
3968 (woman2-tagged-paragraph to i))) | 4067 (woman2-tagged-paragraph to i))) |
3969 | 4068 |
3970 (defun woman2-IP (to) | 4069 (defun woman2-IP (to) |
3971 ".IP x i -- Same as .TP with tag x. TO is where the directive ends." | 4070 ".IP x i -- Same as .TP with tag x. Format paragraphs upto TO." |
3972 (woman-interparagraph-space) | 4071 (woman-interparagraph-space) |
3973 (if (eolp) ; no args | 4072 (if (eolp) ; no args |
3974 ;; Like LP without resetting prevailing indent | 4073 ;; Like LP without resetting prevailing indent |
3975 (woman2-format-paragraphs to (+ woman-left-margin | 4074 (woman2-format-paragraphs to (+ woman-left-margin |
3976 woman-prevailing-indent)) | 4075 woman-prevailing-indent)) |
3985 (if (looking-at "^[.']") | 4084 (if (looking-at "^[.']") |
3986 (point) | 4085 (point) |
3987 (woman-find-next-control-line))) | 4086 (woman-find-next-control-line))) |
3988 | 4087 |
3989 (defun woman2-tagged-paragraph (to i) | 4088 (defun woman2-tagged-paragraph (to i) |
3990 "Set prevailing indent at TO to I. | 4089 "Begin indented paragraph with hanging tag given by current text line. |
3991 Begin indented paragraph with hanging tag given by current text line. | 4090 If tag doesn't fit, leave it on separate line. |
3992 If tag doesn't fit, leave it on separate line." | 4091 Format paragraphs upto TO. Set prevailing indent to I." |
3993 (if (not (looking-at "\\s *$")) ; non-empty tag | 4092 (if (not (looking-at "\\s *$")) ; non-empty tag |
3994 (setq woman-leave-blank-lines nil)) | 4093 (setq woman-leave-blank-lines nil)) |
3995 | 4094 |
3996 ;; Temporary hack for bash.1 and groff_mmse.7 until code is revised | 4095 ;; Temporary hack for bash.1 and groff_mmse.7 until code is revised |
3997 ;; to process all requests uniformly: | 4096 ;; to process all requests uniformly: |
4040 (goto-char to) ; necessary ??? | 4139 (goto-char to) ; necessary ??? |
4041 )) | 4140 )) |
4042 )) | 4141 )) |
4043 | 4142 |
4044 (defun woman2-HP (to) | 4143 (defun woman2-HP (to) |
4045 ".HP i -- Set prevailing indent at TO to i. | 4144 ".HP i -- Set prevailing indent to i. Format paragraphs upto TO. |
4046 Begin paragraph with hanging indent." | 4145 Begin paragraph with hanging indent." |
4047 (let ((i (woman2-get-prevailing-indent))) | 4146 (let ((i (woman2-get-prevailing-indent))) |
4048 (woman-interparagraph-space) | 4147 (woman-interparagraph-space) |
4049 (setq woman-temp-indent woman-left-margin) | 4148 (setq woman-temp-indent woman-left-margin) |
4050 (woman2-format-paragraphs to (+ woman-left-margin i)) | 4149 (woman2-format-paragraphs to (+ woman-left-margin i)) |
4051 )) | 4150 )) |
4052 | 4151 |
4053 (defun woman2-get-prevailing-indent (&optional leave-eol) | 4152 (defun woman2-get-prevailing-indent (&optional leave-eol) |
4054 "Set the prevailing indent to an integer argument at point, and return it. | 4153 "Set prevailing indent to integer argument at point, and return it. |
4055 If no argument at point, return prevailing indent. | 4154 If no argument then return the existing prevailing indent. |
4056 Delete line from point and eol unless LEAVE-EOL is non-nil." | 4155 Delete line from point and eol unless LEAVE-EOL is non-nil." |
4057 (if (eolp) | 4156 (if (eolp) |
4058 (or leave-eol (delete-char 1)) | 4157 (or leave-eol (delete-char 1)) |
4059 (let ((i (woman-get-numeric-arg))) | 4158 (let ((i (woman-get-numeric-arg))) |
4060 (woman-delete-line) (or leave-eol (delete-char 1)) | 4159 (woman-delete-line) (or leave-eol (delete-char 1)) |
4065 (defmacro woman-push (value stack) | 4164 (defmacro woman-push (value stack) |
4066 "Push VALUE onto STACK." | 4165 "Push VALUE onto STACK." |
4067 `(setq ,stack (cons ,value ,stack))) | 4166 `(setq ,stack (cons ,value ,stack))) |
4068 | 4167 |
4069 (defmacro woman-pop (variable stack) | 4168 (defmacro woman-pop (variable stack) |
4070 "Pop the value at the top of STACK into VARIABLE. | 4169 "Pop into VARIABLE the value at the top of STACK. |
4071 Allow for mismatched requests!" | 4170 Allow for mismatched requests!" |
4072 `(if ,stack | 4171 `(if ,stack |
4073 (setq ,variable (car ,stack) | 4172 (setq ,variable (car ,stack) |
4074 ,stack (cdr ,stack)))) | 4173 ,stack (cdr ,stack)))) |
4075 | 4174 |
4076 (defun woman2-RS (to) | 4175 (defun woman2-RS (to) |
4077 ".RS i -- Start relative indent at TO, move left margin in distance i. | 4176 ".RS i -- Start relative indent, move left margin in distance i. |
4078 Set prevailing indent to 5 for nested indents." | 4177 Set prevailing indent to 5 for nested indents. Format paragraphs upto TO." |
4079 (woman-push woman-left-margin woman-RS-left-margin) | 4178 (woman-push woman-left-margin woman-RS-left-margin) |
4080 (woman-push woman-prevailing-indent woman-RS-prevailing-indent) | 4179 (woman-push woman-prevailing-indent woman-RS-prevailing-indent) |
4081 (setq woman-left-margin (+ woman-left-margin | 4180 (setq woman-left-margin (+ woman-left-margin |
4082 (woman2-get-prevailing-indent)) | 4181 (woman2-get-prevailing-indent)) |
4083 woman-prevailing-indent woman-default-indent) | 4182 woman-prevailing-indent woman-default-indent) |
4084 (woman2-format-paragraphs to woman-left-margin)) | 4183 (woman2-format-paragraphs to woman-left-margin)) |
4085 | 4184 |
4086 (defun woman2-RE (to) | 4185 (defun woman2-RE (to) |
4087 ".RE -- End of relative indent at TO. | 4186 ".RE -- End of relative indent. Format paragraphs upto TO. |
4088 Set prevailing indent to amount of starting .RS." | 4187 Set prevailing indent to amount of starting .RS." |
4089 (woman-pop woman-left-margin woman-RS-left-margin) | 4188 (woman-pop woman-left-margin woman-RS-left-margin) |
4090 (woman-pop woman-prevailing-indent woman-RS-prevailing-indent) | 4189 (woman-pop woman-prevailing-indent woman-RS-prevailing-indent) |
4091 (woman-delete-line 1) ; ignore any arguments | 4190 (woman-delete-line 1) ; ignore any arguments |
4092 (woman2-format-paragraphs to woman-left-margin)) | 4191 (woman2-format-paragraphs to woman-left-margin)) |
4093 | 4192 |
4094 | 4193 |
4095 ;;; Line Length and Indenting: | 4194 ;;; Line Length and Indenting: |
4096 | 4195 |
4097 (defun woman-set-arg (arg &optional previous) | 4196 (defun woman-set-arg (arg &optional previous) |
4098 "Reset, increment or decrement ARG, delete the whole remaining control line. | 4197 "Reset, increment or decrement argument ARG, which must be quoted. |
4099 Argument must be quoted. | 4198 If no argument then use value of optional arg PREVIOUS if non-nil, |
4100 Optional argument PREVIOUS, if non-nil, is evaluated to set ARG at eol." | 4199 otherwise set PREVIOUS. Delete the whole remaining control line." |
4101 (if (eolp) ; space already skipped | 4200 (if (eolp) ; space already skipped |
4102 (set arg (if previous (eval previous) 0)) | 4201 (set arg (if previous (eval previous) 0)) |
4103 (if previous (set previous (eval arg))) | 4202 (if previous (set previous (eval arg))) |
4104 (woman2-process-escapes-to-eol 'numeric) | 4203 (woman2-process-escapes-to-eol 'numeric) |
4105 (let ((pm (if (looking-at "[+-]") | 4204 (let ((pm (if (looking-at "[+-]") |
4116 ;; NEED TO RATIONALIZE NAMES FOR PREVIOUS VALUES! | 4215 ;; NEED TO RATIONALIZE NAMES FOR PREVIOUS VALUES! |
4117 (defvar woman-ll-fill-column woman-fill-column) | 4216 (defvar woman-ll-fill-column woman-fill-column) |
4118 (defvar woman-in-left-margin woman-left-margin) | 4217 (defvar woman-in-left-margin woman-left-margin) |
4119 | 4218 |
4120 (defun woman2-ll (to) | 4219 (defun woman2-ll (to) |
4121 ".ll +/-N -- Set, increment or decrement line length at TO. | 4220 ".ll +/-N -- Set, increment or decrement line length. |
4122 \(Breaks, but should not.)" | 4221 Format paragraphs upto TO. (Breaks, but should not.)" |
4123 (woman-set-arg 'fill-column 'woman-ll-fill-column) | 4222 (woman-set-arg 'fill-column 'woman-ll-fill-column) |
4124 (woman2-format-paragraphs to)) | 4223 (woman2-format-paragraphs to)) |
4125 | 4224 |
4126 (defun woman2-in (to) | 4225 (defun woman2-in (to) |
4127 ".in +/-N -- Set, increment or decrement the indent at TO." | 4226 ".in +/-N -- Set, increment or decrement the indent. |
4227 Format paragraphs upto TO." | |
4128 (woman-set-arg 'left-margin 'woman-in-left-margin) | 4228 (woman-set-arg 'left-margin 'woman-in-left-margin) |
4129 (woman2-format-paragraphs to)) | 4229 (woman2-format-paragraphs to)) |
4130 | 4230 |
4131 (defun woman2-ti (to) | 4231 (defun woman2-ti (to) |
4132 ".ti +/-N -- Temporary indent at TO." | 4232 ".ti +/-N -- Temporary indent. Format paragraphs upto TO." |
4133 ;; Ignore if no argument. | 4233 ;; Ignore if no argument. |
4134 ;; Indent next output line only wrt current indent. | 4234 ;; Indent next output line only wrt current indent. |
4135 ;; Current indent is not changed. | 4235 ;; Current indent is not changed. |
4136 (setq woman-temp-indent left-margin) | 4236 (setq woman-temp-indent left-margin) |
4137 (woman-set-arg 'woman-temp-indent) | 4237 (woman-set-arg 'woman-temp-indent) |
4139 | 4239 |
4140 | 4240 |
4141 ;;; Tabs, Leaders, and Fields: | 4241 ;;; Tabs, Leaders, and Fields: |
4142 | 4242 |
4143 (defun woman2-ta (to) | 4243 (defun woman2-ta (to) |
4144 ".ta Nt ... -- Set tabs at TO, left type, unless t=R(right), C(centered). | 4244 ".ta Nt ... -- Set tabs, left type, unless t=R(right), C(centered). |
4145 \(Breaks, but should not.) The tab stops are separated by spaces; | 4245 \(Breaks, but should not.) The tab stops are separated by spaces\; |
4146 a value preceded by + represents an increment to the previous stop value." | 4246 a value preceded by + represents an increment to the previous stop value. |
4247 Format paragraphs upto TO." | |
4147 (setq tab-stop-list nil) | 4248 (setq tab-stop-list nil) |
4148 (woman2-process-escapes-to-eol 'numeric) | 4249 (woman2-process-escapes-to-eol 'numeric) |
4149 (save-excursion | 4250 (save-excursion |
4150 (let ((tab-stop 0)) | 4251 (let ((tab-stop 0)) |
4151 (while (not (eolp)) | 4252 (while (not (eolp)) |
4166 "If TAB-STOP-LIST is a cons, return its car, else return TAB-STOP-LIST." | 4267 "If TAB-STOP-LIST is a cons, return its car, else return TAB-STOP-LIST." |
4167 (if (consp tab-stop-list) (car tab-stop-list) tab-stop-list)) | 4268 (if (consp tab-stop-list) (car tab-stop-list) tab-stop-list)) |
4168 | 4269 |
4169 (defun woman-tab-to-tab-stop () | 4270 (defun woman-tab-to-tab-stop () |
4170 "Insert spaces to next defined tab-stop column. | 4271 "Insert spaces to next defined tab-stop column. |
4171 The variable `tab-stop-list' is a list of columns where there are tab stops: | 4272 The variable `tab-stop-list' is a list whose elements are either left |
4172 pairs (COLUMN . TYPE) where type is either R or C." | 4273 tab stop columns or pairs (COLUMN . TYPE) where TYPE is R or C." |
4173 ;; Based on tab-to-tab-stop in indent.el. | 4274 ;; Based on tab-to-tab-stop in indent.el. |
4174 ;; R & C tabs probably not quite right! | 4275 ;; R & C tabs probably not quite right! |
4175 (delete-backward-char 1) | 4276 (delete-backward-char 1) |
4176 (let ((tabs tab-stop-list)) | 4277 (let ((tabs tab-stop-list)) |
4177 (while (and tabs (>= (current-column) | 4278 (while (and tabs (>= (current-column) |
4193 (insert ?\ ) | 4294 (insert ?\ ) |
4194 (setq n (1- n)))) | 4295 (setq n (1- n)))) |
4195 (insert ?\ )))) | 4296 (insert ?\ )))) |
4196 | 4297 |
4197 (defun woman2-DT (to) | 4298 (defun woman2-DT (to) |
4198 ".DT -- Restore default tabs at TO. | 4299 ".DT -- Restore default tabs. Format paragraphs upto TO. |
4199 (Breaks, but should not.)" | 4300 \(Breaks, but should not.)" |
4200 ;; Currently just terminates special tab processing. | 4301 ;; Currently just terminates special tab processing. |
4201 (setq tab-stop-list nil) | 4302 (setq tab-stop-list nil) |
4202 (woman-delete-line 1) ; ignore any arguments | 4303 (woman-delete-line 1) ; ignore any arguments |
4203 (woman2-format-paragraphs to)) | 4304 (woman2-format-paragraphs to)) |
4204 | 4305 |
4205 (defun woman2-fc (to) | 4306 (defun woman2-fc (to) |
4206 ".fc a b -- Set field delimiter a and pad character b at TO. | 4307 ".fc a b -- Set field delimiter a and pad character b. |
4308 Format paragraphs upto TO. | |
4207 A VERY FIRST ATTEMPT to make fields at least readable! | 4309 A VERY FIRST ATTEMPT to make fields at least readable! |
4208 Needs doing properly!" | 4310 Needs doing properly!" |
4209 (if (eolp) | 4311 (if (eolp) |
4210 (woman-delete-whole-line) ; ignore! | 4312 (woman-delete-whole-line) ; ignore! |
4211 (let ((delim (following-char)) | 4313 (let ((delim (following-char)) |
4237 (woman2-format-paragraphs to)) | 4339 (woman2-format-paragraphs to)) |
4238 | 4340 |
4239 | 4341 |
4240 ;;; WoMan message logging: | 4342 ;;; WoMan message logging: |
4241 | 4343 |
4242 ;;; The basis for this logging code was shamelessly pirated from bytecomp.el | 4344 ;; The basis for this logging code was shamelessly pirated from bytecomp.el |
4243 ;;; by Jamie Zawinski <jwz@lucid.com> & Hallvard Furuseth <hbf@ulrik.uio.no> | 4345 ;; by Jamie Zawinski <jwz@lucid.com> & Hallvard Furuseth <hbf@ulrik.uio.no> |
4244 | 4346 |
4245 (defvar WoMan-current-file nil) ; bound in woman-really-find-file | 4347 (defvar WoMan-current-file nil) ; bound in woman-really-find-file |
4246 (defvar WoMan-Log-header-point-max nil) | 4348 (defvar WoMan-Log-header-point-max nil) |
4247 | 4349 |
4248 (defun WoMan-log-begin () | 4350 (defun WoMan-log-begin () |
4288 with the message." | 4390 with the message." |
4289 (WoMan-log-1 (format "Formatting time %d seconds." time) 'end)) | 4391 (WoMan-log-1 (format "Formatting time %d seconds." time) 'end)) |
4290 | 4392 |
4291 (defun WoMan-log-1 (string &optional end) | 4393 (defun WoMan-log-1 (string &optional end) |
4292 "Log a message STRING in *WoMan-Log*. | 4394 "Log a message STRING in *WoMan-Log*. |
4293 Optional argument END, if non-nil, means make buffer read-only after logging | 4395 If optional argument END is non-nil then make buffer read-only after |
4294 the message." | 4396 logging the message." |
4295 (save-excursion | 4397 (save-excursion |
4296 (set-buffer (get-buffer-create "*WoMan-Log*")) | 4398 (set-buffer (get-buffer-create "*WoMan-Log*")) |
4297 (goto-char (point-max)) | 4399 (goto-char (point-max)) |
4298 (or end (insert " ")) (insert string "\n") | 4400 (or end (insert " ")) (insert string "\n") |
4299 (if end | 4401 (if end |
4309 ))))) | 4411 ))))) |
4310 nil) ; for woman-file-readable-p etc. | 4412 nil) ; for woman-file-readable-p etc. |
4311 | 4413 |
4312 (provide 'woman) | 4414 (provide 'woman) |
4313 | 4415 |
4416 ;; RECENT CHANGE LOG | |
4417 ;; ================= | |
4418 | |
4419 ;; Changes in version 0.50 ([*] => user interface change) | |
4420 ;; [*] Requires GNU Emacs 20.3+. | |
4421 ;; [*] `defface' used to define faces. | |
4422 ;; [*] Follow `see also' references with mouse-2 click. | |
4423 ;; Number register increment support added (woman-registers). | |
4424 ;; .j must be a NUMBER acceptable by .ad request. | |
4425 ;; Very crude field support added. | |
4426 ;; Vertical unit specifier `v' added to register handling. | |
4427 ;; Improvement to local horizontal motion processing. | |
4428 ;; Minor fix to handle negative numeric arguments. | |
4429 ;; Handle horizontal motion escapes `\h' better. | |
4430 ;; Allow arbitrary delimiters in `.if', inc. special character escapes. | |
4431 ;; Allow `\n' within `.if' string comparisons. | |
4432 ;; Allow arbitrary delimiters in `\w', inc. special character escapes. | |
4433 ;; Processing of `\h' moved much later -- after indenting etc! | |
4434 | |
4435 ;; Changes in version 0.51 ([*] => user interface change) | |
4436 ;; [*] Improved handling of underlined faces (mainly for "italics"). | |
4437 ;; [*] Allow environment variables in directory path elements. | |
4438 ;; Display of pre-formatted files improved. | |
4439 ;; [*] Unintentional interaction with standard Man mode reduced. | |
4440 ;; [*] bzip2 decompression support added. All decompression now | |
4441 ;; works by turning on `auto-compression-mode' to decompress the | |
4442 ;; file if necessary, rather than decompressing explicitly. | |
4443 ;; Filename and compression regexps are now customizable user | |
4444 ;; options. | |
4445 | |
4446 ;; Changes in version 0.52 ([*] => user interface change) | |
4447 ;; Speeded up handling of underlined faces (mainly for "italics"). | |
4448 ;; [*] WoMan formatting time display and log added. Emacs `man' | |
4449 ;; formatting time display advice added. (This suggests that | |
4450 ;; WoMan formatting is faster than Emacs `man' *formatting*, | |
4451 ;; i.e. when man is not using `catman' caching. E.g. `woman | |
4452 ;; bash' takes 27s whereas `man bash' takes 35s and for smaller | |
4453 ;; files `woman' can be relatively much faster than `man'.) | |
4454 ;; [*] Experimental support for non-ASCII characters from the | |
4455 ;; default and symbol fonts added, initially only for MS-Windows. | |
4456 ;; NOTE: It is off by default, mainly because it may increase the | |
4457 ;; line spacing; customize `woman-use-symbols' to `on' to use it. | |
4458 ;; Pad character handling for .fc fixed. | |
4459 ;; Tested: see `woman.status'. | |
4460 | |
4461 ;; Changes in version 0.53 ([*] => user interface change) | |
4462 ;; [*] Customization option to use a separate frame for WoMan windows. | |
4463 ;; [*] Experimental option to emulate nroff (default) or troff (not tested). | |
4464 ;; [*] Separation of extended and symbol font options. | |
4465 ;; Only symbol font size 16 seems to work, and only with Win 95, not NT! | |
4466 ;; [*] `Advanced' sub-menu containing: | |
4467 ;; `View Source' option; | |
4468 ;; `Show Log' option; | |
4469 ;; `Extended Font' toggle and reformat; | |
4470 ;; `Symbol Font' toggle and reformat; | |
4471 ;; `Font Map' option; | |
4472 ;; `Emulation' radio buttons. | |
4473 ;; [*] Support for man config file added for default manpath. | |
4474 | |
4475 ;; Changes in version 0.54 | |
4476 ;; Revised for distribution with Emacs 21. | |
4477 ;; Comment order and doc strings changed substantially. | |
4478 ;; MS-DOS support added (by Eli Zaretskii). | |
4479 ;; checkdoc run: no real errors. | |
4480 | |
4314 ;;; woman.el ends here | 4481 ;;; woman.el ends here |