summaryrefslogtreecommitdiff
path: root/util/texi-docstring-magic.el
diff options
context:
space:
mode:
Diffstat (limited to 'util/texi-docstring-magic.el')
-rw-r--r--util/texi-docstring-magic.el347
1 files changed, 0 insertions, 347 deletions
diff --git a/util/texi-docstring-magic.el b/util/texi-docstring-magic.el
deleted file mode 100644
index ab66c91..0000000
--- a/util/texi-docstring-magic.el
+++ /dev/null
@@ -1,347 +0,0 @@
-;; texi-docstring-magic.el -- munge internal docstrings into texi
-;;
-;; Keywords: lisp, docs, tex
-;; Author: David Aspinall <da@dcs.ed.ac.uk>
-;; Copyright (C) 1998 David Aspinall
-;; Maintainer: David Aspinall <da@dcs.ed.ac.uk>
-;;
-;; $Id: texi-docstring-magic.el,v 1.3 2007/07/01 21:20:33 karl Exp $
-;;
-;; This package is distributed under the terms of the
-;; GNU General Public License, Version 3.
-;; You should have a copy of the GPL with your version of
-;; GNU Emacs or the Texinfo distribution.
-;;
-;;
-;; This package generates Texinfo source fragments from Emacs
-;; docstrings. This avoids documenting functions and variables
-;; in more than one place, and automatically adds Texinfo markup
-;; to docstrings.
-;;
-;; It relies heavily on you following the Elisp documentation
-;; conventions to produce sensible output, check the Elisp manual
-;; for details. In brief:
-;;
-;; * The first line of a docstring should be a complete sentence.
-;; * Arguments to functions should be written in upper case: ARG1..ARGN
-;; * User options (variables users may want to set) should have docstrings
-;; beginning with an asterisk.
-;;
-;; Usage:
-;;
-;; Write comments of the form:
-;;
-;; @c TEXI DOCSTRING MAGIC: my-package-function-or-variable-name
-;;
-;; In your texi source, mypackage.texi. From within an Emacs session
-;; where my-package is loaded, visit mypackage.texi and run
-;; M-x texi-docstring-magic to update all of the documentation strings.
-;;
-;; This will insert @defopt, @deffn and the like underneath the
-;; magic comment strings.
-;;
-;; The default value for user options will be printed.
-;;
-;; Symbols are recognized if they are defined for faces, functions,
-;; or variables (in that order).
-;;
-;; Automatic markup rules:
-;;
-;; 1. Indented lines are gathered into @lisp environment.
-;; 2. Pieces of text `stuff' or surrounded in quotes marked up with @samp.
-;; 3. Words *emphasized* are made @strong{emphasized}
-;; 4. Words sym-bol which are symbols become @code{sym-bol}.
-;; 5. Upper cased words ARG corresponding to arguments become @var{arg}.
-;; In fact, you can any word longer than three letters, so that
-;; metavariables can be used easily.
-;; FIXME: to escape this, use `ARG'
-;; 6. Words 'sym which are lisp-quoted are marked with @code{'sym}.
-;;
-;; -----
-;;
-;; Useful key binding when writing Texinfo:
-;;
-;; (define-key TeXinfo-mode-map "C-cC-d" 'texi-docstring-magic-insert-magic)
-;;
-;; -----
-;;
-;; Useful enhancements to do:
-;;
-;; * Use customize properties (e.g. group, simple types)
-;; * Look for a "texi-docstring" property for symbols
-;; so TeXInfo can be defined directly in case automatic markup
-;; goes badly wrong.
-;; * Add tags to special comments so that user can specify face,
-;; function, or variable binding for a symbol in case more than
-;; one binding exists.
-;;
-;; ------
-
-(defun texi-docstring-magic-splice-sep (strings sep)
- "Return concatenation of STRINGS spliced together with separator SEP."
- (let (str)
- (while strings
- (setq str (concat str (car strings)))
- (if (cdr strings)
- (setq str (concat str sep)))
- (setq strings (cdr strings)))
- str))
-
-(defconst texi-docstring-magic-munge-table
- '(;; 1. Indented lines are gathered into @lisp environment.
- ("\\(^.*\\S-.*$\\)"
- t
- (let
- ((line (match-string 0 docstring)))
- (if (eq (char-syntax (string-to-char line)) ?\ )
- ;; whitespace
- (if in-quoted-region
- line
- (setq in-quoted-region t)
- (concat "@lisp\n" line))
- ;; non-white space
- (if in-quoted-region
- (progn
- (setq in-quoted-region nil)
- (concat "@end lisp\n" line))
- line))))
- ;; 2. Pieces of text `stuff' or surrounded in quotes
- ;; are marked up with @samp. NB: Must be backquote
- ;; followed by forward quote for this to work.
- ;; Can't use two forward quotes else problems with
- ;; symbols.
- ;; Odd hack: because ' is a word constituent in text/texinfo
- ;; mode, putting this first enables the recognition of args
- ;; and symbols put inside quotes.
- ("\\(`\\([^']+\\)'\\)"
- t
- (concat "@samp{" (match-string 2 docstring) "}"))
- ;; 3. Words *emphasized* are made @strong{emphasized}
- ("\\(\\*\\(\\w+\\)\\*\\)"
- t
- (concat "@strong{" (match-string 2 docstring) "}"))
- ;; 4. Words sym-bol which are symbols become @code{sym-bol}.
- ;; Must have at least one hyphen to be recognized,
- ;; terminated in whitespace, end of line, or punctuation.
- ;; (Only consider symbols made from word constituents
- ;; and hyphen.
- ("\\(\\(\\w+\\-\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
- (or (boundp (intern (match-string 2 docstring)))
- (fboundp (intern (match-string 2 docstring))))
- (concat "@code{" (match-string 2 docstring) "}"
- (match-string 4 docstring)))
- ;; 5. Upper cased words ARG corresponding to arguments become
- ;; @var{arg}
- ;; In fact, include any word so long as it is more than 3 characters
- ;; long. (Comes after symbols to avoid recognizing the
- ;; lowercased form of an argument as a symbol)
- ;; FIXME: maybe we don't want to downcase stuff already
- ;; inside @samp
- ;; FIXME: should - terminate? should _ be included?
- ("\\([A-Z0-9\\-]+\\)\\(/\\|\)\\|}\\|\\s-\\|\\s.\\|$\\)"
- (or (> (length (match-string 1 docstring)) 3)
- (member (downcase (match-string 1 docstring)) args))
- (concat "@var{" (downcase (match-string 1 docstring)) "}"
- (match-string 2 docstring)))
-
- ;; 6. Words 'sym which are lisp quoted are
- ;; marked with @code.
- ("\\(\\(\\s-\\|^\\)'\\(\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
- t
- (concat (match-string 2 docstring)
- "@code{'" (match-string 3 docstring) "}"
- (match-string 5 docstring)))
- ;; 7,8. Clean up for @lisp environments left with spurious newlines
- ;; after 1.
- ("\\(\\(^\\s-*$\\)\n@lisp\\)" t "@lisp")
- ("\\(\\(^\\s-*$\\)\n@end lisp\\)" t "@end lisp"))
- "Table of regexp matches and replacements used to markup docstrings.
-Format of table is a list of elements of the form
- (regexp predicate replacement-form)
-If regexp matches and predicate holds, then replacement-form is
-evaluated to get the replacement for the match.
-predicate and replacement-form can use variables arg,
-and forms such as (match-string 1 docstring)
-Match string 1 is assumed to determine the
-length of the matched item, hence where parsing restarts from.
-The replacement must cover the whole match (match string 0),
-including any whitespace included to delimit matches.")
-
-
-(defun texi-docstring-magic-munge-docstring (docstring args)
- "Markup DOCSTRING for texi according to regexp matches."
- (let ((case-fold-search nil))
- (dolist (test texi-docstring-magic-munge-table docstring)
- (let ((regexp (nth 0 test))
- (predicate (nth 1 test))
- (replace (nth 2 test))
- (i 0)
- in-quoted-region)
-
- (while (and
- (< i (length docstring))
- (string-match regexp docstring i))
- (setq i (match-end 1))
- (if (eval predicate)
- (let* ((origlength (- (match-end 0) (match-beginning 0)))
- (replacement (eval replace))
- (newlength (length replacement)))
- (setq docstring
- (replace-match replacement t t docstring))
- (setq i (+ i (- newlength origlength))))))
- (if in-quoted-region
- (setq docstring (concat docstring "\n@end lisp"))))))
- ;; Force a new line after (what should be) the first sentence,
- ;; if not already a new paragraph.
- (let*
- ((pos (string-match "\n" docstring))
- (needscr (and pos
- (not (string= "\n"
- (substring docstring
- (1+ pos)
- (+ pos 2)))))))
- (if (and pos needscr)
- (concat (substring docstring 0 pos)
- "@*\n"
- (substring docstring (1+ pos)))
- docstring)))
-
-(defun texi-docstring-magic-texi (env grp name docstring args &optional endtext)
- "Make a texi def environment ENV for entity NAME with DOCSTRING."
- (concat "@def" env (if grp (concat " " grp) "") " " name
- " "
- (texi-docstring-magic-splice-sep args " ")
- ;; " "
- ;; (texi-docstring-magic-splice-sep extras " ")
- "\n"
- (texi-docstring-magic-munge-docstring docstring args)
- "\n"
- (or endtext "")
- "@end def" env "\n"))
-
-(defun texi-docstring-magic-format-default (default)
- "Make a default value string for the value DEFAULT.
-Markup as @code{stuff} or @lisp stuff @end lisp."
- (let ((text (format "%S" default)))
- (concat
- "\nThe default value is "
- (if (string-match "\n" text)
- ;; Carriage return will break @code, use @lisp
- (if (stringp default)
- (concat "the string: \n@lisp\n" default "\n@end lisp\n")
- (concat "the value: \n@lisp\n" text "\n@end lisp\n"))
- (concat "@code{" text "}.\n")))))
-
-
-(defun texi-docstring-magic-texi-for (symbol)
- (cond
- ;; Faces
- ((find-face symbol)
- (let*
- ((face symbol)
- (name (symbol-name face))
- (docstring (or (face-doc-string face)
- "Not documented."))
- (useropt (eq ?* (string-to-char docstring))))
- ;; Chop off user option setting
- (if useropt
- (setq docstring (substring docstring 1)))
- (texi-docstring-magic-texi "fn" "Face" name docstring nil)))
- ((fboundp symbol)
- ;; Functions.
- ;; We don't handle macros, aliases, or compiled fns properly.
- (let*
- ((function symbol)
- (name (symbol-name function))
- (docstring (or (documentation function)
- "Not documented."))
- (def (symbol-function function))
- (argsyms (cond ((eq (car-safe def) 'lambda)
- (nth 1 def))))
- (args (mapcar 'symbol-name argsyms)))
- (if (commandp function)
- (texi-docstring-magic-texi "fn" "Command" name docstring args)
- (texi-docstring-magic-texi "un" nil name docstring args))))
- ((boundp symbol)
- ;; Variables.
- (let*
- ((variable symbol)
- (name (symbol-name variable))
- (docstring (or (documentation-property variable
- 'variable-documentation)
- "Not documented."))
- (useropt (eq ?* (string-to-char docstring)))
- (default (if useropt
- (texi-docstring-magic-format-default
- (default-value symbol)))))
- ;; Chop off user option setting
- (if useropt
- (setq docstring (substring docstring 1)))
- (texi-docstring-magic-texi
- (if useropt "opt" "var") nil name docstring nil default)))
- (t
- (error "Don't know anything about symbol %s" (symbol-name symbol)))))
-
-(defconst texi-docstring-magic-comment
- "@c TEXI DOCSTRING MAGIC:"
- "Magic string in a texi buffer expanded into @defopt, or @deffn.")
-
-(defun texi-docstring-magic ()
- "Update all texi docstring magic annotations in buffer."
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (let ((magic (concat "^"
- (regexp-quote texi-docstring-magic-comment)
- "\\s-*\\(\\(\\w\\|\\-\\)+\\)$"))
- p
- symbol)
- (while (re-search-forward magic nil t)
- (setq symbol (intern (match-string 1)))
- (forward-line)
- (setq p (point))
- ;; If comment already followed by an environment, delete it.
- (if (and
- (looking-at "@def\\(\\w+\\)\\s-")
- (search-forward (concat "@end def" (match-string 1)) nil t))
- (progn
- (forward-line)
- (delete-region p (point))))
- (insert
- (texi-docstring-magic-texi-for symbol))))))
-
-(defun texi-docstring-magic-face-at-point ()
- (ignore-errors
- (let ((stab (syntax-table)))
- (unwind-protect
- (save-excursion
- (set-syntax-table emacs-lisp-mode-syntax-table)
- (or (not (zerop (skip-syntax-backward "_w")))
- (eq (char-syntax (char-after (point))) ?w)
- (eq (char-syntax (char-after (point))) ?_)
- (forward-sexp -1))
- (skip-chars-forward "'")
- (let ((obj (read (current-buffer))))
- (and (symbolp obj) (find-face obj) obj)))
- (set-syntax-table stab)))))
-
-(defun texi-docstring-magic-insert-magic (symbol)
- (interactive
- (let* ((v (or (variable-at-point)
- (function-at-point)
- (texi-docstring-magic-face-at-point)))
- (val (let ((enable-recursive-minibuffers t))
- (completing-read
- (if v
- (format "Magic docstring for symbol (default %s): " v)
- "Magic docstring for symbol: ")
- obarray '(lambda (sym)
- (or (boundp sym)
- (fboundp sym)
- (find-face sym)))
- t nil 'variable-history))))
- (list (if (equal val "") v (intern val)))))
- (insert "\n" texi-docstring-magic-comment " " (symbol-name symbol)))
-
-
-(provide 'texi-docstring-magic)