;;; ====================================================================
;;;  @Emacs-Lisp-file{
;;;     filename        = "tex-macro-catalogue.el",
;;;     version         = "2.00",
;;;     date            = "15 February 1993",
;;;     time            = "14:43:35 GMT",
;;;     author          = "David Carlisle",
;;;     address         = "Computer Science Department
;;;                        Manchester University
;;;                        Oxford Road
;;;                        Manchester
;;;                        England
;;;                        M13 9PL",
;;;     telephone       = "+44 61 275 6139",
;;;     FAX             = "+44 61 275 6236",
;;;     email           = "[email protected] (Internet)",
;;;     checksum        = "05502 349 1299 11389",
;;;     codetable       = "ISO/ASCII",
;;;     keywords        = "TeX, macros,styles,index,catalogue",
;;;     supported       = "yes",
;;;     docstring       = "
;;;
;;;     A GNU Emacs interface to David Jones' Catalogue of TeX macros.
;;;
;;;     The most recent version of the catalogue is always available
;;;     from theory.lcs.mit.edu in the directory
;;;     pub/tex/tex-styles-and-macros.txt.
;;;
;;;     Copies can also be obtained from the following locations:
;;;
;;;        ftp.tex.ac.uk:pub/archive/help/tex-styles-and-macros.txt
;;;        ftp.th-darmstadt.de:
;;;                  pub/tex/documentation/tex-styles-and-macros.txt[.Z]
;;;        ftp.uni-stuttgart.de:/soft/tex/documentation/TeX-index
;;;        ftp.SHSU.edu:[fileserv.tex-index]tex.index
;;;        ymir.claremont.edu:[anonymous.tex.documentation]tex-index.txt
;;;
;;;        ftp.cs.ruu.nl:pub/TEX/DOC/TeX-index.Z
;;;        ftp.math.utah.edu:pub/tex/tex-index
;;;        ftp.diku.dk:pub/TeX/misc/TeX-Index.Z
;;;
;;;
;;;     The checksum field above was produced by
;;;     Robert Solovay's checksum utility.",
;;;  }
;;; ====================================================================

;;; tex-macro-catalogue.el
;;; ;;;;;;;;;;;;;;;;;;;;;;

;;; This is an attempt at an emacs interface to the TeX macro catalogue
;;; produced by David Jones <[email protected]>

;;; INSTALLATION
;;;
;;; First obtain the catalogue and install it in a suitable directory.
;;; Then modify the setting of tmc-file below to refer to the path
;;; name of the catalogue file.
;;; This file may then be installed in an emacs-lisp directory, and
;;; byte compiled.


;;; BASIC USE
;;;
;;; Add the following lines (without the `;;;') to your .emacs. The
;;; catalogue may then be searched with M-x tex-macro-catalogue
;;;
;;; (autoload 'tex-macro-catalogue "tex-macro-catalogue"
;;;                                  "TeX macro catalogue browser" t)
;;;
;;; The browser will start by displaying a help screen, this screen
;;; may be recalled later by typing `?'.


;;; CUSTOMISATION & OTHER DETAILS
;;;
;;; The hook tmc-mode-hook may be set in your .emacs file, to
;;; customise the catalogue searching.
;;;
;;; You may wish to change the keybindings, or modify the list
;;; tmc-latex-sections of sections that you consider latex-related.
;;; (eg to add LAMSTeX, or remove FOILTeX.)
;;;
;;; The entries are returned with only the titles displayed.
;;; The bodies are hidden by outline mode. Typing `s' by a title shows
;;; the corresponding body. `S' shows all the returned entries.
;;; Hiding entries is done with `h' (one entry) or `H' all entries.
;;;
;;; Typing `?' displays a help screen, as long as you do not abort
;;; this with ^g, the previous contents of the tmc-entries buffer will
;;; be redisplayed at the next keypress.
;;;
;;; The first time you restrict the search to LaTeX `L', there will be
;;; a slight delay, as the positions of the LaTeX-related sections are
;;; determined. After the first time `L' and `A' should quickly switch
;;; between LaTeX-specific and unrestricted searching.
;;;
;;; If you usually require LaTeX-restricted searching, you could cause
;;; the browser to start off in that mode by placing a hook such as
;;; the following (without the ;;;) in your .emacs file.
;;;
;;; (setq tmc-mode-hook
;;;  (function
;;;   (lambda ()
;;;     (tmc-latex-only))))


;;; David Carlisle <[email protected]>
;;;
;;; Version 1:    May      1992
;;; Version 2: 15 February 1993

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(defconst tmc-file
 "/usr/common/lib/tex3/doc/tex-styles-and-macros.txt"
 "The path name for the catalogue file.
  MUST BE SET CORRECTLY FOR YOUR SITE.")

(defvar tmc-latex-sections
 (list "AMS-LATEX" "FOILTEX" "LATEX"  "SLITEX" "GENERIC MACROS")
 "The LaTeX-related sections of the catalogue.")

(defvar tmc-file-buffer nil
 "Buffer to store the catalogue.")

(defvar tmc-ranges nil
 "The current list of ranges to search.")

(defvar tmc-latex-ranges nil
 "The list of ranges corresponding to tmc-latex-sections.")

(defun tmc-all-formats ()
"Search the whole file, not just LaTeX-related sections."
(interactive)
(if (string= (buffer-name) "tmc-entries")
  (progn
    (setq mode-name "Macro Catalogue Entries")
;; Force an update to the modeline.
    (set-buffer-modified-p (buffer-modified-p))))
   (set-buffer tmc-file-buffer)
;; Set the range list to be one range, the whole file.
   (setq tmc-ranges (list (cons (point-min) (point-max)))))

(defun tmc-latex-only ()
"Search the whole file, not just LaTeX-related sections."
(interactive)
(if (string= (buffer-name) "tmc-entries")
  (progn
    (setq mode-name "Macro Catalogue Entries (LaTeX only)")
;; Force an update to the modeline.
    (set-buffer-modified-p (buffer-modified-p))))
   (set-buffer tmc-file-buffer)
;; If we have not already computed the ranges coresponding to the
;; section titles, compute them now.
   (setq tmc-ranges
     (or
       tmc-latex-ranges
      (prog2
        (message "Locating LaTeX sections...")
        (setq tmc-latex-ranges
        (mapcar 'tmc-find-section tmc-latex-sections))
        (message "done")))))


(defun tmc-find-section (secname)
"Return a cons-pair containing the markers corresponding to the start
and finish of the requested section"
(goto-char (point-min))
;; Section titles have a blank line before and after. (To distinguish
;; them from the list of sections at the beginning.)
(re-search-forward
      (concat "\n\\s-*\n%%Section [0-9]+: " secname " *$\n\\s-*\n"))
(cons (point)
 (progn (re-search-forward "\n%%Section [0-9]+:" (point-max) 1)
        (point))))

(defun tmc-list-search-section (range)
"Search for an entry within the specified range."
(set-buffer (get-buffer-create "tmc-entries"))
(set-buffer tmc-file-buffer)
(goto-char (car range))
(while (re-search-forward
        (concat "^"key-type": .*\\b"key"\\b") (cdr range) t)
   (save-excursion (tmc-get-entry)))
(switch-to-buffer "tmc-entries")
(hide-body)
(goto-char (point-min))
(forward-line 1))

(defun tmc-list-search (key-type key)
"Search for the entry in every range in the list tmc-ranges."
(message "Searching...")
(mapcar 'tmc-list-search-section tmc-ranges)
(message "done"))

(defun tmc-list-by-author (auth)
"Search for entries by author."
(interactive "sAuthor Name: ")
(tmc-list-search "Author" auth))

(defun tmc-list-by-keyword (key)
"Search for entries by keyword."
(interactive "sKeyword: ")
(tmc-list-search "Keywords" key))

(defun tmc-list-by-title (name)
"Search for entries by title (= name)."
(interactive "sTitle: ")
(tmc-list-search "Name" name))

(defun tmc-get-entry ()
"Insert the found entry into the tmc-entries buffer."
(re-search-backward "^[ ]*$")
  (let ((tmc-entry
        (buffer-substring (point)
           (progn
            (forward-line 1)(re-search-forward "^[ ]*$") (point)))))
    (set-buffer "tmc-entries")
    (goto-char (point-max))
    (insert tmc-entry)))

(defvar tmc-map (make-sparse-keymap)
 "Local keymap used in TeX macro catalogue entries buffer.")


(defun tex-macro-catalogue ()
"Initialise a buffer to control searching the TeX macro catalogue.
 The available commands are:
\\{tmc-map}"
(interactive)
;; Load the file if not already loaded,
;; without evaluating any hooks or local variables
(if tmc-file-buffer
  (set-buffer tmc-file-buffer)
;;else
  (setq tmc-file-buffer (create-file-buffer tmc-file))
  (set-buffer tmc-file-buffer)
  (insert-file-contents tmc-file))
(setq buffer-read-only t)
(switch-to-buffer (get-buffer-create "tmc-entries"))
;; Use outline mode to hide the entry bodies.
(outline-mode)
(make-local-variable 'outline-regexp)
(setq outline-regexp "Name")
(setq major-mode 'tex-macro-catalogue)
(tmc-all-formats)
(switch-to-buffer (get-buffer-create "tmc-entries"))
(use-local-map tmc-map)
;; Individual customisations.
(run-hooks 'tmc-mode-hook)
;; Start off with the help screen.
(tmc-help))

(defvar tmc-help nil "The help string")

(defun tmc-help ()
"Help for TeX macro catalogue searches."
(interactive)
(switch-to-buffer (get-buffer-create "tmc-entries"))
;; The help string is displayed until the next key sequence.
;; The previous contents of the buffer are then returned, unless the
;; help is quit with \C-g.
(let ((p (point))
      (tmc-temp (buffer-string)))
(erase-buffer)
;; Only initialise the help string now in case the user has changed
;; the key bindings in tmc-mode-hook.
(insert (or tmc-help
tmc-help
(setq tmc-help (substitute-command-keys
"TeX Macro Catalogue

Before Searching, type:

      `\\[tmc-latex-only]' \
Restrict search to LaTeX and related formats.
      `\\[tmc-all-formats]' \
Allow searching over the whole catalogue. (Default.)

To search, type:
      `\\[tmc-list-by-keyword]' \
to search the catalogue by Keyword.
      `\\[tmc-list-by-author]' \
to search the catalogue by Author.
      `\\[tmc-list-by-title]' \
to search the catalogue by Title (name) of package.

After a successful search, type:
      `\\[outline-next-visible-heading]' \
`\\[outline-previous-visible-heading]' \
Move to next (previous) entry.

      `\\[show-subtree]' `\\[show-all]' \
Show current entry (All entries).
      `\\[hide-subtree]' `\\[hide-body]' \
Hide current entry (All entries).

      `\\[tmc-clear]' Clear this buffer.
      `\\[tmc-quit]' Quit.

      `\\[tmc-help]' Get this help
 "))))
(goto-char (point-min))
(sit-for 60)
(erase-buffer)
(insert tmc-temp)
(goto-char p)))


(defun tmc-clear ()
 "Clear the tmc-entries buffer."
 (interactive)
 (set-buffer "tmc-entries")
 (erase-buffer))

(defun tmc-quit ()
 "Quit searching the catalogue."
 (interactive)
 (tmc-clear)
 (bury-buffer tmc-file-buffer)
 (let ((obuf (current-buffer)))
   (switch-to-buffer (other-buffer))
   (bury-buffer obuf)))


;; Set up the default key bindings.
(define-key tmc-map "S"    'show-all)
(define-key tmc-map "H"    'hide-body)
(define-key tmc-map "s"    'show-subtree)
(define-key tmc-map "h"    'hide-subtree)
(define-key tmc-map "n"    'outline-next-visible-heading)
(define-key tmc-map "p"    'outline-previous-visible-heading)

(define-key tmc-map "k"    'tmc-list-by-keyword)
(define-key tmc-map "a"    'tmc-list-by-author)
(define-key tmc-map "t"    'tmc-list-by-title)

(define-key tmc-map "c"    'tmc-clear)
(define-key tmc-map "q"    'tmc-quit)

(define-key tmc-map "L"    'tmc-latex-only)
(define-key tmc-map "A"    'tmc-all-formats)

(define-key tmc-map "?"    'tmc-help)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;