aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/Makefile12
-rw-r--r--doc/docstring-magic.el13
-rw-r--r--generic/texi-docstring-magic.el218
3 files changed, 240 insertions, 3 deletions
diff --git a/doc/Makefile b/doc/Makefile
index 9a2f0cbb..736d0761 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -21,7 +21,8 @@ MAKEINFO = makeinfo
TEXI2DVI = texi2dvi
DVI2PS = dvips
TEXI2PDF = texi2pdf
-TEXI2HTML = texi2html
+TEXI2HTML = texi2html
+EMACS = xemacs -batch
.SUFFIXES: .texi .info .dvi .html .pdf .ps
@@ -41,8 +42,6 @@ TEXI2HTML = texi2html
.texi.html:
$(TEXI2HTML) $<
-
-
##
## doc : build info and dvi files from $(DOCNAME).texi
##
@@ -76,6 +75,13 @@ clean:
distclean: clean
rm -f $(DOCNAME).info* $(DOCNAME).dvi $(DOCNAME).pdf $(DOCNAME)*.html
+##
+## magic: update magic comments in NewDoc.texi from docstrings in code.
+## (developer use only!)
+##
+magic:
+ $(EMACS) -l docstring-magic.el NewDoc.texi -f daves-docstring-magic -f save-buffer
+
diff --git a/doc/docstring-magic.el b/doc/docstring-magic.el
new file mode 100644
index 00000000..b36643ce
--- /dev/null
+++ b/doc/docstring-magic.el
@@ -0,0 +1,13 @@
+;; Ensure that non-compiled versions of everything is loaded
+(setq load-path
+ (append
+ '("../generic/" "../isa/" "../lego/" "../coq/") load-path))
+(load "proof-site.el")
+(load "proof-config.el")
+(load "proof.el")
+(load "isa.el")
+(load "thy-mode.el")
+(load "coq.el")
+(load "lego.el")
+
+(load "texi-docstring-magic.el") \ No newline at end of file
diff --git a/generic/texi-docstring-magic.el b/generic/texi-docstring-magic.el
new file mode 100644
index 00000000..8d42b2e3
--- /dev/null
+++ b/generic/texi-docstring-magic.el
@@ -0,0 +1,218 @@
+;;; texi-docstring-magic.el -- munge internal docstrings into texi
+;;
+;; Keywords: texi, docstrings
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Copyright (C) 1998 David Aspinall
+;;
+;; $Id$
+;;
+;; -----
+;;
+;; Useful binding
+;; (define-key texinfo-mode-map "C-cC-d" 'texi-docstring-magic-insert-magic)
+;;
+;; Useful enhancements to do:
+;; 1. Mention default value for user options
+;; 2. Use customize properties (e.g. group, simple types)
+;;
+
+(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
+ '(;; Indented lines 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))))
+ ;; Upper cased words ARG corresponding to arguments become @var{arg}
+ ("\\([A-Z0-9\\-]+\\)\\(\\s-\\|\\.\\|$\\)"
+ (member (downcase (match-string 1 docstring)) args)
+ (concat "@var{" (downcase (match-string 1 docstring)) "}"
+ (match-string 2 docstring)))
+ ;; Words sym which are symbols become @code{sym}.
+ ;; Must have at least one hyphen to be recognized.
+ ;; (Only consider symbols made from word constituents
+ ;; and hyphens).
+ ("\\(\\w+\\-\\(\\w\\|\\-\\)+\\)\\(\\s-\\|\\.\\|$\\)"
+ (or (boundp (intern (match-string 1 docstring)))
+ (fboundp (intern (match-string 1 docstring))))
+ (concat "@code{" (match-string 1 docstring) "}"
+ (match-string 3 docstring))))
+ "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)")
+
+
+(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 0))
+ (if (eval predicate)
+ (let* ((origlength (- i (match-beginning 0)))
+ (replacement (eval replace))
+ (newlength (length replacement)))
+ (setq docstring
+ (replace-match replacement t t docstring))
+ (setq i (+ i (- newlength origlength) 1)))))
+ (if in-quoted-region
+ (setq docstring (concat docstring "\n@end lisp")))))))
+
+(defun texi-docstring-magic-texi (env grp name docstring args &rest extras)
+ "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"
+ "@end def" env "\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.
+ ;; Don't handle macros, aliases, 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))))
+ ;; Chop off user option setting
+ (if useropt
+ (setq docstring (substring docstring 1)))
+ (texi-docstring-magic-texi
+ (if useropt "opt" "var")
+ nil name docstring nil)))
+ (t
+ (error "Don't know anything about symbol %s" (symbol-name symbol)))))
+
+(texi-docstring-magic-texi-for 'proof-rsh-command)
+
+
+
+(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)