[PATCH] WIP experimental extraction of elisp docstrings -> sphinx

David Bremner david at tethera.net
Sun May 27 11:55:30 PDT 2018


---
This is a proof of concept extracting docstrings for inclusion in the emacs manual.
It uses a new emacs lisp "package" called rstdoc.

Among the hinky things

. this |br| hack is quite gross, but it was the best I could do

. the dependency on the ${emacs_bytecode} needs to be guarded proprely so we can still build
  most of the docs without emacs. I don't really understand the whole .eldeps thing, it
  seems to cause constant rebuilds for me anyway.,

. using (rstdoc-defcustom ) instead of (defcustom ) confuses the
  byte-compiler to think the variable is undefined. A simple "fix" would
  be to throw in a (defvar ) for each of those.

On the plus side, this introduces no external dependencies.

 doc/Makefile.local    |  4 +--
 doc/notmuch-emacs.rst |  6 +++-
 emacs/Makefile.local  |  3 +-
 emacs/notmuch-tag.el  |  5 ++-
 emacs/rstdoc.el       | 77 +++++++++++++++++++++++++++++++++++++++++++
 emacs/rstdoc.rsti     | 12 +++++++
 6 files changed, 102 insertions(+), 5 deletions(-)
 create mode 100644 emacs/rstdoc.el
 create mode 100644 emacs/rstdoc.rsti

diff --git a/doc/Makefile.local b/doc/Makefile.local
index 16459e35..fed8e1e4 100644
--- a/doc/Makefile.local
+++ b/doc/Makefile.local
@@ -37,10 +37,10 @@ INFO_INFO_FILES := $(INFO_TEXI_FILES:.texi=.info)
 %.gz: %
 	rm -f $@ && gzip --stdout $^ > $@
 
-sphinx-html:
+sphinx-html: ${emacs_bytecode}
 	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(DOCBUILDDIR)/html
 
-sphinx-texinfo:
+sphinx-texinfo: ${emacs_bytecode}
 	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(DOCBUILDDIR)/texinfo
 
 sphinx-info: sphinx-texinfo
diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst
index ce2e358e..1979da03 100644
--- a/doc/notmuch-emacs.rst
+++ b/doc/notmuch-emacs.rst
@@ -275,7 +275,7 @@ operations specified in ``notmuch-tagging-keys``; i.e. each
 
 :index:`notmuch-tagging-keys`
 
-   A list of keys and corresponding tagging operations.
+  |docstring::notmuch-tagging-keys|
 
 Configuration
 =============
@@ -300,3 +300,7 @@ suffix exist it will be read instead (just one of these, chosen in this
 order). Most often users create ``~/.emacs.d/notmuch-config.el`` and just
 work with it. If Emacs was invoked with the ``-q`` or ``--no-init-file``
 options, ``notmuch-init-file`` is not read.
+
+.. include:: ../emacs/rstdoc.rsti
+
+.. include:: ../emacs/notmuch-tag-doc.rsti
diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 1b3ef584..f0557800 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -117,4 +117,5 @@ ifeq ($(WITH_DESKTOP),1)
 	-update-desktop-database "$(DESTDIR)$(desktop_dir)"
 endif
 
-CLEAN := $(CLEAN) $(emacs_bytecode) $(dir)/notmuch-version.el $(dir)/notmuch-pkg.el
+CLEAN := $(CLEAN) $(emacs_bytecode) $(dir)/notmuch-version.el $(dir)/notmuch-pkg.el\
+	$(dir)/notmuch-tag-doc.rsti
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 0500927d..372517df 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -28,6 +28,9 @@
 (require 'crm)
 (require 'notmuch-lib)
 
+(eval-when-compile (require 'rstdoc)
+		   (rstdoc-init "notmuch-tag-doc.rsti"))
+
 (declare-function notmuch-search-tag "notmuch" tag-changes)
 (declare-function notmuch-show-tag "notmuch-show" tag-changes)
 (declare-function notmuch-tree-tag "notmuch-tree" tag-changes)
@@ -44,7 +47,7 @@
 		       (variable :tag "Tag variable"))
 		(string :tag "Name"))))
 
-(defcustom notmuch-tagging-keys
+(rstdoc-defcustom notmuch-tagging-keys
   `((,(kbd "a") notmuch-archive-tags "Archive")
     (,(kbd "u") notmuch-show-mark-read-tags "Mark read")
     (,(kbd "f") ("+flagged") "Flag")
diff --git a/emacs/rstdoc.el b/emacs/rstdoc.el
new file mode 100644
index 00000000..d5e78568
--- /dev/null
+++ b/emacs/rstdoc.el
@@ -0,0 +1,77 @@
+;;; rstdoc.el --- help generate documentation from docstrings -*-lexical-binding: t-*-
+     
+;; Copyright (C) 2018 David Bremner
+     
+;; Author: David Bremner <david at tethera.net>
+;; Created: 26 May 2018
+;; Keywords: emacs lisp, documentation
+;; Homepage: https://notmuchmail.org
+
+;; This file is not part of GNU Emacs.
+
+;; rstdoc.el is free software: you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; rstdoc.el is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with rstdoc.el.  If not, see <https://www.gnu.org/licenses/>.
+;;
+
+;;; Commentary:
+;; 
+
+;; Rstdoc provides some macros that wrap standard emacs forms for
+;; defining variables and functions, while capturing the docstrings
+;; for later re-use.
+
+;;; Code:
+
+(provide 'rstdoc)
+
+(defvar rstdoc-file nil
+    "File into which to write docstrings.")
+
+(defun rstdoc-init (&optional file-name)
+  "Initialize output of docstrings to FILE-NAME"
+  (when (or file-name rstdoc-file)
+    (make-local-variable 'rstdoc-file)
+    (let ((out-file (or file-name rstdoc-file))) ;; save buffer-local binding
+      (setq rstdoc-file out-file)
+      (with-temp-buffer
+	(insert (format ".. generated by rstdoc on %s \n" (current-time-string)))
+	(write-region (point-min) (point-max) out-file)))))
+
+(defmacro rstdoc-defcustom (symbol standard doc &rest args)
+  `(defcustom symbol standard doc , at args)
+  (rstdoc-save-docstring symbol doc))
+
+(defun rstdoc-save-docstring (symbol docstring)
+  (when rstdoc-file
+    (let ((out-file rstdoc-file)) ;; save buffer local value
+      (with-temp-buffer
+	(insert (format "\n.. |docstring::%s| replace::\n" symbol))
+	(insert (replace-regexp-in-string "^" "    " (rstdoc--rst-quote-string docstring)))
+	(insert "\n")
+	(append-to-file (point-min) (point-max) out-file)))))
+
+(defvar rst--escape-alist
+  '( ("'" . "`")
+     ("^[[:space:]\t]*$" . "|br|"))
+    "list of (regex . replacement) pairs")
+
+(defun rstdoc--rst-quote-string (str)
+  (with-temp-buffer
+    (insert str)
+    (dolist (pair rst--escape-alist)
+      (goto-char (point-min))
+      (while (re-search-forward (car pair) nil t)
+	(replace-match (cdr pair))))
+    (buffer-substring (point-min) (point-max))))
+
+;;; rstdoc.el ends here
diff --git a/emacs/rstdoc.rsti b/emacs/rstdoc.rsti
new file mode 100644
index 00000000..857dab58
--- /dev/null
+++ b/emacs/rstdoc.rsti
@@ -0,0 +1,12 @@
+.. -*- rst -*-
+
+.. |br| replace:: |br-texinfo| |br-html|
+       
+.. |br-texinfo| raw:: texinfo
+
+   @* @*
+
+.. |br-html| raw:: html
+
+   <br /><br />
+
-- 
2.17.0



More information about the notmuch mailing list