summarize-guile-TODO 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #!/bin/sh
  2. # aside from this initial boilerplate, this is actually -*- scheme -*- code
  3. main='(module-ref (resolve-module '\''(scripts summarize-guile-TODO)) '\'main')'
  4. exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@"
  5. !#
  6. ;;; summarize-guile-TODO --- Display Guile TODO list in various ways
  7. ;; Copyright (C) 2002, 2006 Free Software Foundation, Inc.
  8. ;;
  9. ;; This program is free software; you can redistribute it and/or
  10. ;; modify it under the terms of the GNU General Public License as
  11. ;; published by the Free Software Foundation; either version 2, or
  12. ;; (at your option) any later version.
  13. ;;
  14. ;; This program is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. ;; General Public License for more details.
  18. ;;
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with this software; see the file COPYING. If not, write to
  21. ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  22. ;; Boston, MA 02110-1301 USA
  23. ;;; Author: Thien-Thi Nguyen <ttn@gnu.org>
  24. ;;; Commentary:
  25. ;; Usage: summarize-guile-TODO TODOFILE
  26. ;;
  27. ;; The TODOFILE is typically Guile's (see workbook/tasks/README)
  28. ;; presumed to serve as our signal to ourselves (lest we want real
  29. ;; bosses hassling us) wrt to the overt message "items to do" as well as
  30. ;; the messages that can be inferred from its structure.
  31. ;;
  32. ;; This program reads TODOFILE and displays interpretations on its
  33. ;; structure, including registered markers and ownership, in various
  34. ;; ways.
  35. ;;
  36. ;; A primary interest in any task is its parent task. The output
  37. ;; summarization by default lists every item and its parent chain.
  38. ;; Top-level parents are not items. You can use these command-line
  39. ;; options to modify the selection and display (selection criteria
  40. ;; are ANDed together):
  41. ;;
  42. ;; -i, --involved USER -- select USER-involved items
  43. ;; -p, --personal USER -- select USER-responsible items
  44. ;; -t, --todo -- select unfinished items (status "-")
  45. ;; -d, --done -- select finished items (status "+")
  46. ;; -r, --review -- select review items (marker "R")
  47. ;;
  48. ;; -w, --who -- also show who is associated w/ the item
  49. ;; -n, --no-parent -- do not show parent chain
  50. ;;
  51. ;;
  52. ;; Usage from a Scheme program:
  53. ;; (summarize-guile-TODO . args) ; uses first arg only
  54. ;;
  55. ;;
  56. ;; Bugs: (1) Markers are scanned in sequence: D R X N%. This means "XD"
  57. ;; and the like are completely dropped. However, such strings
  58. ;; are unlikely to be used if the markers are chosen to be
  59. ;; somewhat exclusive, which is currently the case for D R X.
  60. ;; N% used w/ these needs to be something like: "D25%" (this
  61. ;; means discussion accounts for 1/4 of the task).
  62. ;;
  63. ;; TODO: Implement more various ways. (Patches welcome.)
  64. ;; Add support for ORing criteria.
  65. ;;; Code:
  66. (debug-enable 'debug 'backtrace)
  67. (define-module (scripts summarize-guile-TODO)
  68. :use-module (scripts read-text-outline)
  69. :use-module (ice-9 getopt-long)
  70. :autoload (srfi srfi-13) (string-tokenize) ; string library
  71. :autoload (srfi srfi-14) (char-set) ; string library
  72. :autoload (ice-9 common-list) (remove-if-not)
  73. :export (summarize-guile-TODO))
  74. (define put set-object-property!)
  75. (define get object-property)
  76. (define (as-leaf x)
  77. (cond ((get x 'who)
  78. => (lambda (who)
  79. (put x 'who
  80. (map string->symbol
  81. (string-tokenize who (char-set #\:)))))))
  82. (cond ((get x 'pct-done)
  83. => (lambda (pct-done)
  84. (put x 'pct-done (string->number pct-done)))))
  85. x)
  86. (define (hang-by-the-leaves trees)
  87. (let ((leaves '()))
  88. (letrec ((hang (lambda (tree parent)
  89. (if (list? tree)
  90. (begin
  91. (put (car tree) 'parent parent)
  92. (for-each (lambda (child)
  93. (hang child (car tree)))
  94. (cdr tree)))
  95. (begin
  96. (put tree 'parent parent)
  97. (set! leaves (cons (as-leaf tree) leaves)))))))
  98. (for-each (lambda (tree)
  99. (hang tree #f))
  100. trees))
  101. leaves))
  102. (define (read-TODO file)
  103. (hang-by-the-leaves
  104. ((make-text-outline-reader
  105. "(([ ][ ])*)([-+])(D*)(R*)(X*)(([0-9]+)%)* *([^[]*)(\\[(.*)\\])*"
  106. '((level-substring-divisor . 2)
  107. (body-submatch-number . 9)
  108. (extra-fields . ((status . 3)
  109. (design? . 4)
  110. (review? . 5)
  111. (extblock? . 6)
  112. (pct-done . 8)
  113. (who . 11)))))
  114. (open-file file "r"))))
  115. (define (select-items p items)
  116. (let ((sub '()))
  117. (cond ((option-ref p 'involved #f)
  118. => (lambda (u)
  119. (let ((u (string->symbol u)))
  120. (set! sub (cons
  121. (lambda (x)
  122. (and (get x 'who)
  123. (memq u (get x 'who))))
  124. sub))))))
  125. (cond ((option-ref p 'personal #f)
  126. => (lambda (u)
  127. (let ((u (string->symbol u)))
  128. (set! sub (cons
  129. (lambda (x)
  130. (cond ((get x 'who)
  131. => (lambda (ls)
  132. (eq? (car (reverse ls))
  133. u)))
  134. (else #f)))
  135. sub))))))
  136. (for-each (lambda (pair)
  137. (cond ((option-ref p (car pair) #f)
  138. (set! sub (cons (cdr pair) sub)))))
  139. `((todo . ,(lambda (x) (string=? (get x 'status) "-")))
  140. (done . ,(lambda (x) (string=? (get x 'status) "+")))
  141. (review . ,(lambda (x) (get x 'review?)))))
  142. (let loop ((sub (reverse sub)) (items items))
  143. (if (null? sub)
  144. (reverse items)
  145. (loop (cdr sub) (remove-if-not (car sub) items))))))
  146. (define (make-display-item show-who? show-parent?)
  147. (let ((show-who
  148. (if show-who?
  149. (lambda (item)
  150. (cond ((get item 'who)
  151. => (lambda (who) (format #f " ~A" who)))
  152. (else "")))
  153. (lambda (item) "")))
  154. (show-parents
  155. (if show-parent?
  156. (lambda (item)
  157. (let loop ((parent (get item 'parent)) (indent 2))
  158. (and parent
  159. (begin
  160. (format #t "under : ~A~A\n"
  161. (make-string indent #\space)
  162. parent)
  163. (loop (get parent 'parent) (+ 2 indent))))))
  164. (lambda (item) #t))))
  165. (lambda (item)
  166. (format #t "status: ~A~A~A~A~A~A\nitem : ~A\n"
  167. (get item 'status)
  168. (if (get item 'design?) "D" "")
  169. (if (get item 'review?) "R" "")
  170. (if (get item 'extblock?) "X" "")
  171. (cond ((get item 'pct-done)
  172. => (lambda (pct-done)
  173. (format #f " ~A%" pct-done)))
  174. (else ""))
  175. (show-who item)
  176. item)
  177. (show-parents item))))
  178. (define (display-items p items)
  179. (let ((display-item (make-display-item (option-ref p 'who #f)
  180. (not (option-ref p 'no-parent #f))
  181. )))
  182. (for-each display-item items)))
  183. (define (summarize-guile-TODO . args)
  184. (let ((p (getopt-long (cons "summarize-guile-TODO" args)
  185. '((who (single-char #\w))
  186. (no-parent (single-char #\n))
  187. (involved (single-char #\i)
  188. (value #t))
  189. (personal (single-char #\p)
  190. (value #t))
  191. (todo (single-char #\t))
  192. (done (single-char #\d))
  193. (review (single-char #\r))
  194. ;; Add options here.
  195. ))))
  196. (display-items p (select-items p (read-TODO (car (option-ref p '() #f))))))
  197. #t) ; exit val
  198. (define main summarize-guile-TODO)
  199. ;;; summarize-guile-TODO ends here