src/clfswm-util.lisp (query-yes-or-no): New function.
[clfswm.git] / src / clfswm-autodoc.lisp
blob6ca8afeb6fab8f57f28de90e6b614780c0d9ccfb
1 ;;; --------------------------------------------------------------------------
2 ;;; CLFSWM - FullScreen Window Manager
3 ;;;
4 ;;; --------------------------------------------------------------------------
5 ;;; Documentation: Auto documentation tools
6 ;;; --------------------------------------------------------------------------
7 ;;;
8 ;;; (C) 2010 Philippe Brochard <hocwp@free.fr>
9 ;;;
10 ;;; This program is free software; you can redistribute it and/or modify
11 ;;; it under the terms of the GNU General Public License as published by
12 ;;; the Free Software Foundation; either version 3 of the License, or
13 ;;; (at your option) any later version.
14 ;;;
15 ;;; This program is distributed in the hope that it will be useful,
16 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;;; GNU General Public License for more details.
19 ;;;
20 ;;; You should have received a copy of the GNU General Public License
21 ;;; along with this program; if not, write to the Free Software
22 ;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 ;;;
24 ;;; --------------------------------------------------------------------------
26 (in-package :clfswm)
29 (defun is-string-keysym (k)
30 (when (stringp k)
31 (or (parse-integer k :junk-allowed t)
32 (intern (string-upcase k)))))
35 (defun produce-doc-html (hash-table-key-list &optional (stream t))
36 "Produce an html doc from a hash-table key"
37 (labels ((clean-string (str)
38 (cond ((string-equal str "#\\:") ":")
39 ((string-equal str "#\\#") "#")
40 ((string-equal str "#\\\\") "\\")
41 (t (substitute #\Space #\#
42 (substitute #\Space #\\
43 (substitute #\Space #\: str))))))
44 (produce-keys (hk)
45 `("table class=\"ex\" cellspacing=\"5\" border=\"0\" width=\"100%\""
46 (tr ("th align=\"right\" width=\"10%\"" "Modifiers")
47 ("th align=\"center\" width=\"10%\"" "Key/Button")
48 ("th align=\"left\"" "Function"))
49 ,@(let ((acc nil))
50 (maphash #'(lambda (k v)
51 (when (consp k)
52 (push `(tr
53 ("td align=\"right\" style=\"color:#FF0000\" nowrap"
54 ,(clean-string (format nil "~{~@(~S ~)~}" (state->modifiers (second k)))))
55 ("td align=\"center\" nowrap"
56 ,(clean-string (format nil "~@(~S~)"
57 (or (is-string-keysym (first k)) (first k)))))
58 ("td style=\"color:#0000FF\" nowrap" ,(documentation (or (first v) (third v)) 'function)))
59 acc)))
60 hk)
61 (nreverse acc)))))
62 (produce-html
63 `(html
64 (head
65 (title "CLFSWM Keys"))
66 (body
67 (h1 "CLFSWM Keys")
68 (p (small "Note: Mod-1 is the Meta or Alt key"))
69 ,@(let ((acc nil))
70 (dolist (hk hash-table-key-list)
71 (push `(h3 (u ,(gethash 'name hk))) acc)
72 (push (produce-keys hk) acc))
73 (nreverse acc))
74 (p (small "This documentation was produced with the CLFSWM auto-doc functions. To reproduce it, use the produce-doc-html-in-file or
75 the produce-all-docs function from the Lisp REPL."))
76 (p (small "Something like this:<br>
77 LISP> (in-package :clfswm)<br>
78 CLFSWM> (produce-doc-html-in-file \"my-keys.html\")<br>
79 or<br> CLFSWM> (produce-all-docs)"))))
80 0 stream)))
83 (defun produce-doc-html-in-file (filename)
84 (format t "Producing html keys documentation in ~S " filename)
85 (with-open-file (stream filename :direction :output
86 :if-exists :supersede :if-does-not-exist :create)
87 (produce-doc-html (list *main-keys* *main-mouse* *second-keys* *second-mouse*
88 *info-keys* *info-mouse* *circulate-keys* *expose-keys* *expose-mouse*)
89 stream))
90 (format t " done~%"))
94 (defun produce-doc (hash-table-key-list &optional (stream t) (display-producing-doc t))
95 "Produce a text doc from a hash-table key"
96 (format stream " * CLFSWM Keys *~%")
97 (format stream " -----------~%")
98 (format stream "~%Note: Mod-1 is the Meta or Alt key~%")
99 (dolist (hk hash-table-key-list)
100 (format stream "~2&~A:~%" (gethash 'name hk))
101 (dotimes (i (length (gethash 'name hk)))
102 (format stream "-"))
103 (format stream "~2%")
104 (maphash #'(lambda (k v)
105 (when (consp k)
106 (format stream "~& ~20@<~{~@(~A~) ~}~> ~13@<~@(~A~)~> ~A~%"
107 (state->modifiers (second k))
108 (remove #\# (remove #\\ (format nil "~S" (or (is-string-keysym (first k)) (first k)))))
109 (documentation (or (first v) (third v)) 'function))))
111 (format stream "~2&"))
112 (when display-producing-doc
113 (format stream "~2%This documentation was produced with the CLFSWM auto-doc functions.
114 To reproduce it, use the produce-doc-in-file or the produce-all-docs
115 function from the Lisp REPL.
117 Something like this:
118 LISP> (in-package :clfswm)
119 CLFSWM> (produce-doc-in-file \"my-keys.txt\")
121 CLFSWM> (produce-all-docs)~2%")))
125 (defun produce-doc-in-file (filename)
126 (format t "Producing text keys documentation in ~S " filename)
127 (with-open-file (stream filename :direction :output
128 :if-exists :supersede :if-does-not-exist :create)
129 (produce-doc (list *main-keys* *main-mouse* *second-keys* *second-mouse*
130 *info-keys* *info-mouse* *circulate-keys* *expose-keys* *expose-mouse*)
131 stream))
132 (format t " done~%"))
138 ;;; Menu autodoc functions
139 (defun produce-menu-doc (&optional (stream t))
140 (labels ((rec (base)
141 (format stream "~2&~:(~A~)~%" (menu-name base))
142 (dolist (item (menu-item base))
143 (typecase item
144 (menu (format stream "~A: ~A~%" (menu-name item) (menu-doc item)))
145 (menu-item (aif (menu-item-key item)
146 (format stream "~A: ~A~%" it
147 (typecase (menu-item-value item)
148 (menu (format nil "< ~A >" (menu-doc (menu-item-value item))))
149 (t (documentation (menu-item-value item) 'function))))
150 (format stream "~A~%" (menu-item-value item))))))
151 (dolist (item (menu-item base))
152 (typecase item
153 (menu (rec item))
154 (menu-item (when (menu-p (menu-item-value item))
155 (rec (menu-item-value item))))))))
156 (format stream "Here is the map of the CLFSWM menu:~%")
157 (format stream "(By default it is bound on second-mode + m)~%")
158 (rec *menu*)
159 (format stream "~2%This documentation was produced with the CLFSWM auto-doc functions. To reproduce it, use the produce-menu-doc-in-file or
160 the produce-all-docs function from the Lisp REPL.
162 Something like this:
163 LISP> (in-package :clfswm)
164 CLFSWM> (produce-menu-doc-in-file \"my-menu.txt\")
166 CLFSWM> (produce-all-docs)~2%")))
170 (defun produce-menu-doc-in-file (filename)
171 (format t "Producing text menus documentation in ~S " filename)
172 (with-open-file (stream filename :direction :output
173 :if-exists :supersede :if-does-not-exist :create)
174 (produce-menu-doc stream))
175 (format t " done~%"))
180 (defun produce-menu-doc-html (&optional (stream t))
181 (let ((menu-list nil))
182 (labels ((rec (base parent)
183 (push `(h3 ,(format nil "<a name=\"~A\"></a><a href=\"#~A\">~:(~A~)</a>"
184 (menu-name base)
185 (if parent (menu-name parent) "Top")
186 (menu-name base))) menu-list)
187 (dolist (item (menu-item base))
188 (typecase item
189 (menu (push `(p ,(format nil "~A: ~A" (menu-name item) (menu-doc item))) menu-list))
190 (menu-item (push `(p ,(aif (menu-item-key item)
191 (format nil "~A: ~A" it
192 (typecase (menu-item-value item)
193 (menu (format nil "<a href=\"#~A\">< ~A ></a>"
194 (menu-name (menu-item-value item))
195 (menu-doc (menu-item-value item))))
196 (t (documentation (menu-item-value item) 'function))))
197 (format nil "~A" (menu-item-value item))))
198 menu-list))))
199 (push '<hr> menu-list)
200 (dolist (item (menu-item base))
201 (typecase item
202 (menu (rec item base))
203 (menu-item (when (menu-p (menu-item-value item))
204 (rec (menu-item-value item) base)))))))
205 (rec *menu* nil)
206 (produce-html `(html
207 (head
208 (title "CLFSWM Menu"))
209 (body
210 (h1 ("a name=\"Top\"" "CLFSWM Menu"))
211 (p "Here is the map of the CLFSWM menu:"
212 "(By default it is bound on second-mode + m)")
213 ,@(nreverse menu-list)
214 (p (small "This documentation was produced with the CLFSWM auto-doc functions. To reproduce it, use the produce-menu-doc-html-in-file or
215 the produce-all-docs function from the Lisp REPL."))
216 (p (small "Something like this:<br>
217 LISP> (in-package :clfswm)<br>
218 CLFSWM> (produce-menu-doc-html-in-file \"my-menu.html\")<br>
219 or<br> CLFSWM> (produce-all-docs)"))))
220 0 stream))))
223 (defun produce-menu-doc-html-in-file (filename)
224 (format t "Producing html menus documentation in ~S " filename)
225 (with-open-file (stream filename :direction :output
226 :if-exists :supersede :if-does-not-exist :create)
227 (produce-menu-doc-html stream))
228 (format t " done~%"))
232 ;;; Corner autodoc functions
233 (defun produce-corner-doc (&optional (stream t))
234 (labels ((print-doc (corner-list)
235 (format stream "~2&~:(~A~):~%" corner-list)
236 (dolist (corner (symbol-value corner-list))
237 (format stream " ~:(~A:~) ~A~%" (first corner)
238 (if (fboundp (second corner))
239 (documentation (second corner) 'function)
240 "---")))))
241 (format stream "Here are the actions associated to screen corners in CLFSWM:")
242 (dolist (corner '(*corner-main-mode-left-button* *corner-main-mode-middle-button* *corner-main-mode-right-button*
243 *corner-second-mode-left-button* *corner-second-mode-middle-button* *corner-second-mode-right-button*))
244 (print-doc corner))
245 (format stream "~2%This documentation was produced with the CLFSWM auto-doc functions.
246 To reproduce it, use the produce-menu-doc-in-file or
247 the produce-all-docs function from the Lisp REPL.
249 Something like this:
250 LISP> (in-package :clfswm)
251 CLFSWM> (produce-corner-doc-in-file \"my-corner.txt\")
253 CLFSWM> (produce-all-docs)~2%")))
256 (defun produce-corner-doc-in-file (filename)
257 (format t "Producing text corner documentation in ~S " filename)
258 (with-open-file (stream filename :direction :output
259 :if-exists :supersede :if-does-not-exist :create)
260 (produce-corner-doc stream))
261 (format t " done~%"))
265 (defun produce-corner-doc-html (&optional (stream t))
266 (let ((corner-html nil))
267 (labels ((one-corner (corner-list)
268 (push `(h3 ,corner-list) corner-html)
269 (push `("table class=\"ex\" cellspacing=\"5\" border=\"0\" width=\"100%\""
270 ,@(loop :for corner :in (symbol-value corner-list)
271 :collect `(tr ("td align=\"left\" width=\"1%\" style=\"color:#FF0000\" nowrap"
272 ,(format nil "~:(~A~):" (first corner)))
273 ("td style=\"color:#0000FF\" nowrap"
274 ,(if (fboundp (second corner))
275 (documentation (second corner) 'function)
276 "---")))))
277 corner-html))
278 (fill-corner-list ()
279 (dolist (corner '(*corner-main-mode-left-button* *corner-main-mode-middle-button* *corner-main-mode-right-button*
280 *corner-second-mode-left-button* *corner-second-mode-middle-button* *corner-second-mode-right-button*))
281 (one-corner corner))))
282 (fill-corner-list)
283 (produce-html `(html
284 (head
285 (title "CLFSWM Corners"))
286 (body
287 (h1 ("a name=\"Top\"" "CLFSWM Corners"))
288 (p "Here are the actions associated to screen corners in CLFSWM:")
289 ,@(nreverse corner-html)
290 (p (small "This documentation was produced with the CLFSWM auto-doc functions. To reproduce it, use the produce-corner-doc-html-in-file or
291 the produce-all-docs function from the Lisp REPL."))
292 (p (small "Something like this:<br>
293 LISP> (in-package :clfswm)<br>
294 CLFSWM> (produce-corner-doc-html-in-file \"my-corner.html\")<br>
295 or<br> CLFSWM> (produce-all-docs)"))))
296 0 stream))))
299 (defun produce-corner-doc-html-in-file (filename)
300 (format t "Producing html corner documentation in ~S " filename)
301 (with-open-file (stream filename :direction :output
302 :if-exists :supersede :if-does-not-exist :create)
303 (produce-corner-doc-html stream))
304 (format t " done~%"))
307 ;;; Configuration variables
308 (defun produce-configuration-variables (stream &optional (group t))
309 (format stream " * CLFSWM Configuration variables *~%")
310 (format stream " ------------------------------~2%")
311 (format stream " <= ~A =>~2%" (if (equal group t) "" group))
312 (with-all-internal-symbols (symbol :clfswm)
313 (when (and (is-config-p symbol)
314 (or (equal group t)
315 (string-equal group (config-group symbol))))
316 (format stream "~A = ~S~%~A~%" symbol (symbol-value symbol)
317 (config-documentation symbol))))
318 (format stream "~2& Those variables can be changed in clfswm.
319 Maybe you'll need to restart clfswm to take care of new values~2%"))
327 (defun produce-all-docs ()
328 "Produce all docs in keys.html and keys.txt"
329 (produce-doc-in-file "doc/keys.txt")
330 (produce-doc-html-in-file "doc/keys.html")
331 (produce-menu-doc-in-file "doc/menu.txt")
332 (produce-menu-doc-html-in-file "doc/menu.html")
333 (produce-corner-doc-in-file "doc/corner.txt")
334 (produce-corner-doc-html-in-file "doc/corner.html"))