-
Notifications
You must be signed in to change notification settings - Fork 3
/
print-doc.lisp
67 lines (59 loc) · 2.39 KB
/
print-doc.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
;; Author: Teemu Likonen <tlikonen@iki.fi>
;;
;; License: Creative Commons CC0 (public domain dedication)
;; https://creativecommons.org/publicdomain/zero/1.0/legalcode
(defpackage #:print-doc
(:use #:cl)
(:export #:print-doc))
(in-package #:print-doc)
(require 'sb-introspect)
(defun symbol-doc-type (symbol)
(let (docs)
(flet ((doc (symbol type key)
(push (list symbol key (documentation symbol type)) docs)))
(cond ((ignore-errors (macro-function symbol))
(doc symbol 'function :macro))
((ignore-errors (symbol-function symbol))
(doc symbol 'function :function)))
(when (ignore-errors (symbol-value symbol))
(doc symbol 'variable :variable))
(cond ((subtypep symbol 'condition)
(doc symbol 'type :condition))
((ignore-errors (find-class symbol))
(doc symbol 'type :class))))
docs))
(defun print-doc (package &key (stream *standard-output*) (prefix "### "))
(loop
:with *package* := (find-package package)
:with *print-right-margin* := 72
:with *print-case* := :downcase
:with data
:= (sort (loop :for symbol
:being :each :external-symbol :in package
:append (symbol-doc-type symbol))
(lambda (l1 l2)
(let ((s1 (symbol-name (first l1)))
(s2 (symbol-name (first l2)))
(t1 (symbol-name (second l1)))
(t2 (symbol-name (second l2))))
(or (string-lessp t1 t2)
(and (string-equal t1 t2)
(string-lessp s1 s2))))))
:for (symbol type doc) :in data
:if doc :do
(format stream "~A" prefix)
(case type
(:function
(format stream "Function: `~A`" symbol)
(let ((ll (sb-introspect:function-lambda-list symbol)))
(when ll
(format stream "~%~%The lambda list:~%~% ~S" ll))))
(:macro
(format stream "Macro: `~A`" symbol)
(let ((ll (sb-introspect:function-lambda-list symbol)))
(when ll
(format stream "~%~%The lambda list:~%~% ~S" ll))))
(:variable (format stream "Variable: `~A`" symbol))
(:condition (format stream "Condition: `~A`" symbol))
(:class (format stream "Class: `~A`" symbol)))
(format stream "~%~%~A~%~%~%" doc)))