unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* my emacs minor-mode for generating docstrings, v180902d
@ 2018-09-02 21:19 Matt Wette
  2018-09-02 23:30 ` Arne Babenhauserheide
  0 siblings, 1 reply; 3+ messages in thread
From: Matt Wette @ 2018-09-02 21:19 UTC (permalink / raw)
  To: guile-user, guile-devel

It's been many years since I hacked on elisp, but I have the beginnings
of an emacs minor mode (to scheme) for generating docstrings from texi-
motivated comments.

Here is an example of how I like to document my procedures:

;; @deffn {Procedure} prece a b po
;; Return precedence for arguments @var{a}, @var{b} given the partial
;; order @var{po}.  The result is of the form @code{'lt}, @code{'gt},
;; @code{'eq} or @code{#f}.@*
;; Note: @var{po} may not a true partial order as we can have a<b and
;; b<a => a=b.  For example,
;; @example
;; @code{(prece a a po)} => @code{'eq}.
;; @end example
;; @end deffn
(define (prece a b po)
   (cond
    ((eqv? a b) 'eq)
    ((eqv? a '$error) 'lt)
    ((eqv? b '$error) 'gt)
    ((<? a b po) (if (<? b a po) 'eq 'lt))
    (else (if (<? b a po) 'gt #f))))


Now if I load my scheme-texidoc minor mode, place the point just before
`(define (' and hit [(control c) (control d)], I end up with a docstring
generated by running the comments through `texi2any --plaintext'.

;; @deffn {Procedure} prece a b po
;; Return precedence for arguments @var{a}, @var{b} given the partial
;; order @var{po}.  The result is of the form @code{'lt}, @code{'gt},
;; @code{'eq} or @code{#f}.@*
;; Note: @var{po} may not a true partial order as we can have a<b and
;; b<a => a=b.  For example,
;; @example
;; @code{(prece a a po)} => @code{'eq}.
;; @end example
;; @end deffn
(define (prece a b po)
   "- Procedure: prece a b po
      Return precedence for arguments A, B given the partial order PO.
      The result is of the form ''lt', ''gt', ''eq' or '#f'.
      Note: PO may not a true partial order as we can have a<b and b<a =>
      a=b.  For example,
           (prece a a po) => 'eq."
   (cond
    ((eqv? a b) 'eq)
    ((eqv? a '$error) 'lt)
    ((eqv? b '$error) 'gt)
    ((<? a b po) (if (<? b a po) 'eq 'lt))
    (else (if (<? b a po) 'gt #f))))


and in Guile I get

scheme@(guile-user)> ,d prece
- Procedure: prece a b po
      Return precedence for arguments A, B given the partial order PO.
      The result is of the form ''lt', ''gt', ''eq' or '#f'.
      Note: PO may not a true partial order as we can have a<b and b<a =>
      a=b.  For example,
           (prece a a po) => 'eq.



Here is scheme-texidoc.el:
;;; scheme-texidoc.el --- minor mode to make scheme doc-strings from texinfo

;; Copyright (C) 2018 Matthew R. Wette

;; Author: Matt Wette <mwette@alumni.caltech.edu>
;; Keywords: scheme, texinfo

;; This library is free software; you can redistribute it and/or
;; modify it under the terms of the GNU Lesser General Public
;; License as published by the Free Software Foundation; either
;; version 3 of the License, or (at your option) any later version.
;;
;; This library 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
;; Lesser General Public License for more details.
;;
;; You should have received a copy of the GNU Lesser General Public License
;; along with this library; if not, see <http://www.gnu.org/licenses/>.

;;; Notes:

;; M-x unload-feature RET scheme-texidoc RET

;; todo: remove old docstring, if present
;; todo: robustly find "(define ("
;; todo: handle (define foo (let (...) (lambda (...) "docstring"

;;; Code:

(require 'texinfmt)

(define-minor-mode scheme-texidoc
   "A minor-mode to create Scheme docstrings from texinfo comments.
Assume you have procedure that starts with
   (define (
and is preceeded by comments that provide documentation between
   ;; @deffn ...
and
   ;; @end deffn
Then set point to just before `(define (' and hit `C-cC->'.
A texi2any formatted docstring will be inserted."
   nil
   " Tx"
   '(([(control c) (control d)] . scheme-texidoc-transfer-deffn))
   )

(defvar scheme-texidoc-version "v180902e")

(defvar scheme-texidoc-texi-buffer-name "*scmtxi texi*")
(defvar scheme-texidoc-text-buffer-name "*scmtxi text*")

;; moves point
(defun find-deffn-above ()
   "find deffn to this point; give up if hit blank before"
   (interactive)
   (beginning-of-line)
   (while (and (not (looking-at ";; @deffn "))
	      (not (looking-at "\\($\\| \\)")))
     (forward-line -1))
   (if (looking-at ";; @deffn ") (point) nil))

;; moves point
(defun find-end-deffn-below ()
   "find end deffn blow non ;;"
   (interactive)
   (beginning-of-line)
   (while (and (not (looking-at ";; @end deffn"))
	      (looking-at ";;\\($\\| \\)"))
     (forward-line 1))
   (if (looking-at ";; @end deffn") (progn (forward-line) (point)) nil))

;; we want to find range for deffn and point for docstring
(defun find-deffn-posns ()
   "Find points of interest."
   (interactive)
   (save-excursion
     (beginning-of-line)
     (while (not (looking-at ";;")) (backward-line))
     (let ((txi-st (find-deffn-above))
	  (txi-nd (find-end-deffn-below))
	  (doc-pt nil)
	  )
       (while (not (looking-at "(")) (forward-line))
       (cond
        ((looking-at "(define *(")
	(skip-chars-forward 9)
	(forward-sexp)
	(set! doc-pt (point)))
        ((looking-at "(define *[^ (]")
	(re-search-forward "(lambda (" 100)
	(error "not implemented"))
        (t
	(error "couldn't find location for docstring")))
       (goto-char doc-pt)
       )))

;; run texi2any --plaintext on region
;; returns t or nil if success or failure to run command, respectively
;; error messages are not processed
(defun texi2any-on-region (start end)
   "run texi2any on region"
   (let ((text-buffer (get-buffer-create scheme-texidoc-text-buffer-name)))
     (save-excursion
       (set-buffer text-buffer)
       (erase-buffer))
     (zerop (call-process-region start end "texi2any" nil text-buffer nil
				"--plaintext"))
     (save-excursion
       (set-buffer text-buffer)
       ;; remove warning messages
       (goto-char (point-min))
       (while (looking-at "-:")
	(delete-region (point-min) (progn (forward-line) (point))))
       ;; clean up
       (goto-char (point-min))
       (if (looking-at " -") (delete-char 2))
       (while (> (forward-line) 0) (if (looking-at "  ") (delete-char 2)))
       (goto-char (point-max))
       (delete-trailing-whitespace)
       (delete-char -1))
     ))

(defun scheme-texidoc-transfer-deffn ()
   "Insert a docstring formatted from the leading texinfo-comments."
   (interactive)
   (save-excursion
     ;; Find the enclosing define.
     (beginning-of-line)
     (unless (looking-at "(define")
       (error "needs love to find (define"))
     (let* ((defpt (point))
	   (tx-st (find-deffn-above))	  ; texi start
	   (tx-nd (find-end-deffn-below)) ; texi end
	   (scm-buf (current-buffer)))	  ; user buffer
       ;; Copy texi to working buffer and remove leading comment chars.
       (set-buffer (get-buffer-create scheme-texidoc-texi-buffer-name))
       (texinfo-mode)
       (erase-buffer)
       (insert-buffer-substring scm-buf tx-st tx-nd)
       (goto-char (point-min))
       (while (looking-at ";;")
	(delete-char 2)
	(if (looking-at " ") (delete-char 1))
	(forward-line)
	(beginning-of-line))
       ;; Generate info format.
       (goto-char (point-min)) (insert "\n")
       (goto-char (point-max)) (insert "\n")
       (texi2any-on-region (point-min) (point-max))
       ;; Copy into working Scheme buffer.
       (set-buffer (get-buffer scheme-texidoc-text-buffer-name))
       (let* ((pt-st (point-min))
	     (pt-nd (point-max))
	     (text (buffer-substring pt-st pt-nd)))
	(switch-to-buffer scm-buf)
	;; Position to insert point.
	(goto-char defpt)
	(forward-line)
	(beginning-of-line)
	;; Insert text from bufffer and indent.
	(let ((inspt (point)))
	  (insert "\"" text "\"\n")
	  (goto-char inspt)
	  (indent-for-tab-command))
	))))

(provide 'scheme-texidoc)

;; --- last line ---





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: my emacs minor-mode for generating docstrings, v180902d
  2018-09-02 21:19 my emacs minor-mode for generating docstrings, v180902d Matt Wette
@ 2018-09-02 23:30 ` Arne Babenhauserheide
  2018-09-03 12:49   ` Matt Wette
  0 siblings, 1 reply; 3+ messages in thread
From: Arne Babenhauserheide @ 2018-09-02 23:30 UTC (permalink / raw)
  To: Matt Wette; +Cc: guile-user, guile-devel

[-- Attachment #1: Type: text/plain, Size: 1717 bytes --]


Matt Wette <matt.wette@gmail.com> writes:

> Now if I load my scheme-texidoc minor mode, place the point just before
> `(define (' and hit [(control c) (control d)], I end up with a docstring
> generated by running the comments through `texi2any --plaintext'.
>
> ;; @deffn {Procedure} prece a b po
> ;; Return precedence for arguments @var{a}, @var{b} given the partial
> ;; order @var{po}.  The result is of the form @code{'lt}, @code{'gt},
> ;; @code{'eq} or @code{#f}.@*
> ;; Note: @var{po} may not a true partial order as we can have a<b and
> ;; b<a => a=b.  For example,
> ;; @example
> ;; @code{(prece a a po)} => @code{'eq}.
> ;; @end example
> ;; @end deffn
> (define (prece a b po)
>   "- Procedure: prece a b po
>      Return precedence for arguments A, B given the partial order PO.
>      The result is of the form ''lt', ''gt', ''eq' or '#f'.
>      Note: PO may not a true partial order as we can have a<b and b<a =>
>      a=b.  For example,
>           (prece a a po) => 'eq."
>   (cond
>    ((eqv? a b) 'eq)
>    ((eqv? a '$error) 'lt)
>    ((eqv? b '$error) 'gt)
>    ((<? a b po) (if (<? b a po) 'eq 'lt))
>    (else (if (<? b a po) 'gt #f))))
>
>
> and in Guile I get
>
> scheme@(guile-user)> ,d prece
> - Procedure: prece a b po
>      Return precedence for arguments A, B given the partial order PO.
>      The result is of the form ''lt', ''gt', ''eq' or '#f'.
>      Note: PO may not a true partial order as we can have a<b and b<a =>
>      a=b.  For example,
>           (prece a a po) => 'eq.

This looks pretty useful. I don’t write texinfo yet (though I should),
but if I did, getting rid of the repetition is great!

Best wishes,
Arne

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 1076 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: my emacs minor-mode for generating docstrings, v180902d
  2018-09-02 23:30 ` Arne Babenhauserheide
@ 2018-09-03 12:49   ` Matt Wette
  0 siblings, 0 replies; 3+ messages in thread
From: Matt Wette @ 2018-09-03 12:49 UTC (permalink / raw)
  To: guile-user, guile-devel

On 09/02/2018 04:30 PM, Arne Babenhauserheide wrote:
> Matt Wette <matt.wette@gmail.com> writes:
>
>> Now if I load my scheme-texidoc minor mode, place the point just before
>> `(define (' and hit [(control c) (control d)], I end up with a docstring
>> generated by running the comments through `texi2any --plaintext'.
>>
>> ;; @deffn {Procedure} prece a b po
>> ;; Return precedence for arguments @var{a}, @var{b} given the partial
>> ;; order @var{po}.  The result is of the form @code{'lt}, @code{'gt},
>> ;; @code{'eq} or @code{#f}.@*
>> ;; Note: @var{po} may not a true partial order as we can have a<b and
>> ;; b<a => a=b.  For example,
>> ;; @example
>> ;; @code{(prece a a po)} => @code{'eq}.
>> ;; @end example
>> ;; @end deffn
>> (define (prece a b po)
>>    "- Procedure: prece a b po
>>       Return precedence for arguments A, B given the partial order PO.
>>       The result is of the form ''lt', ''gt', ''eq' or '#f'.
>>       Note: PO may not a true partial order as we can have a<b and b<a =>
>>       a=b.  For example,
>>            (prece a a po) => 'eq."
>>    (cond
>>     ((eqv? a b) 'eq)
>>     ((eqv? a '$error) 'lt)
>>     ((eqv? b '$error) 'gt)
>>     ((<? a b po) (if (<? b a po) 'eq 'lt))
>>     (else (if (<? b a po) 'gt #f))))
>>
>>
>> and in Guile I get
>>
>> scheme@(guile-user)> ,d prece
>> - Procedure: prece a b po
>>       Return precedence for arguments A, B given the partial order PO.
>>       The result is of the form ''lt', ''gt', ''eq' or '#f'.
>>       Note: PO may not a true partial order as we can have a<b and b<a =>
>>       a=b.  For example,
>>            (prece a a po) => 'eq.
> This looks pretty useful. I don’t write texinfo yet (though I should),
> but if I did, getting rid of the repetition is great!
>
Thanks.  I was after formatted docstrings.  I still need to add:
1) robust way to find insert point for docstring
2) ability to remove old docstring if present

The elisp code has been added to my repo at https://github.com/mwette/guile-contrib.

Matt

or




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-09-03 12:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-02 21:19 my emacs minor-mode for generating docstrings, v180902d Matt Wette
2018-09-02 23:30 ` Arne Babenhauserheide
2018-09-03 12:49   ` Matt Wette

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).