]> git.donarmstrong.com Git - lilypond.git/blob - scm/documentation-lib.scm
a73b3b558625714052dbc50355b7b0ada03cc56a
[lilypond.git] / scm / documentation-lib.scm
1 ;;;
2 ;;; documentation-lib.scm -- Assorted Functions for generated documentation
3 ;;;
4 ;;; source file of the GNU LilyPond music typesetter
5 ;;; 
6 ;;; (c) 2000--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 ;;; Jan Nieuwenhuizen <janneke@gnu.org>
8
9 (use-modules (oop goops))
10
11 (define-class <texi-node> ()
12   (children #:init-value '() #:accessor node-children #:init-keyword #:children)
13   (text #:init-value "" #:accessor node-text #:init-keyword #:text)
14   (name #:init-value "" #:accessor node-name #:init-keyword #:name)
15   (description #:init-value "" #:accessor node-desc #:init-keyword #:desc)
16   )
17
18 (define (menu-entry x)
19   (cons
20    (node-name x)
21    (node-desc x))
22   )
23
24 (define (dump-node node port level)
25   (display
26    (string-append
27     "\n@html"
28     "\n<hr>"
29     "\n@end html\n@node "
30     (node-name node)
31     "\n\n"
32     (texi-section-command level) " "
33     (node-name node)
34     "\n\n"
35     (node-text node)
36     "\n\n"
37     (if (pair? (node-children node))
38         (texi-menu
39          (map (lambda (x) (menu-entry x) )
40               (node-children node)))
41          ""))
42    port)
43   (map (lambda (x) (dump-node x port (+ 1 level)))
44         (node-children node))
45   )
46
47 (define (processing name)
48   (display (string-append "\nProcessing " name " ... ") (current-error-port)))
49
50 (define (self-evaluating? x)
51   (or (number? x) (string? x) (procedure? x) (boolean? x)))
52
53 (define (texify x)
54   x)
55
56 (define (scm->texi x)
57   (string-append "@code{" (texify (scm->string x)) "}")
58   )
59
60
61 ;;
62 ;; don't confuse users with #<procedure .. > syntax. 
63 ;; 
64 (define (scm->string val)
65   (if (and (procedure? val) (symbol? (procedure-name val)))
66       (symbol->string (procedure-name val))
67       (string-append
68        (if (self-evaluating? val) "" "'")
69        (call-with-output-string (lambda (port) (display val port)))
70        )))
71
72
73 (define (texi-section-command level)
74   (cdr (assoc level '(
75     ;; Hmm, texinfo doesn't have ``part''
76     (0 . "@top")
77     (1 . "@unnumbered")
78     (2 . "@unnumberedsec")
79     (3 . "@unnumberedsubsec")
80     (4 . "@unnumberedsubsubsec")
81     (5 . "@unnumberedsubsubsec")
82     ))))
83
84 (define (one-item->texi label-desc-pair)
85   "Document one (LABEL . DESC); return empty string if LABEL is empty string. 
86 "
87   (if (eq? (car label-desc-pair) "")
88       ""
89       (string-append "\n@item " (car label-desc-pair) "\n" (cdr label-desc-pair))
90   ))
91
92
93 (define (description-list->texi items-alist)
94   "Document ITEMS-ALIST in a table. entries contain (item-label
95 . string-to-use)
96 "
97   (string-append
98    "\n@table @asis\n"
99    (apply string-append (map one-item->texi items-alist))
100    "\n@end table\n"))
101
102 (define (texi-menu items-alist)
103   "Generate what is between @menu and @end menu."
104   (let
105       (
106        (maxwid (apply max (map (lambda (x) (string-length (car x)))
107                                items-alist)))
108        )
109     
110
111     
112   (string-append
113   "\n@menu"
114   (apply string-append
115          (map (lambda (x)
116                 (string-append
117                 (pad-string-to 
118                  (string-append "\n* " (car x) ":: ")
119                  (+ maxwid 8)
120                  )
121                 (cdr x))
122                 )
123               items-alist))
124   "\n@end menu\n"
125   ;; Menus don't appear in html, so we make a list ourselves
126   "\n@ignore\n"
127   "\n@ifhtml\n"
128   (description-list->texi (map (lambda (x) (cons (ref-ify (car x)) (cdr x)))
129                          items-alist))
130   "\n@end ifhtml\n"
131   "\n@end ignore\n")))
132
133   
134
135
136 (define (texi-file-head name file-name top)
137   (string-append
138    "\\input texinfo @c -*-texinfo-*-"
139    "\n@setfilename " file-name ".info"
140    "\n@settitle " name
141    "\n@dircategory GNU music project"
142    "\n@direntry"
143    ;; prepend GNU for dir, must be unique
144    "\n* GNU " name ": (" file-name ").          " name "."
145    "\n@end direntry"
146    ))
147
148
149 (define (context-name name)
150   name)
151
152 (define (engraver-name name)
153   name)
154
155 (define (grob-name name)
156   (if (symbol? name)
157       (symbol->string name)
158       name))
159
160 (define (interface-name name)
161   name)
162
163 (define (ref-ify x)
164   "Add ref to X"
165   (string-append "@ref{" x "}"))
166
167 (define (human-listify l)
168   "Produce a textual enumeration from L, a list of strings"
169   
170   (cond
171    ((null? l) "none")
172    ((null? (cdr l)) (car l))
173    ((null? (cddr l)) (string-append (car l) " and " (cadr l)))
174    (else (string-append (car l) ", " (human-listify (cdr l))))
175    ))
176
177 (define (writing-wip x)
178   (display (string-append "\nWriting " x " ... ") (current-error-port)))
179
180
181
182 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
183 ;; property  stuff.
184
185 (define (property->texi where sym)
186   "Document SYM for WHERE (which can be translation, backend, music)"
187   (let* (
188          (name (symbol->string sym))
189          (type?-name (string->symbol
190                       (string-append (symbol->string where) "-type?")))
191          (doc-name (string->symbol                  
192                     (string-append (symbol->string where) "-doc")))
193          (type (object-property sym type?-name))
194          (typename (type-name type))
195          (desc (object-property sym doc-name)))
196
197     (if (eq? desc #f)
198         (error "No description for property ~S" sym)
199         )
200     (cons
201      (string-append "@code{" name "} "
202                     "(" typename ")")
203      desc)
204      
205     ))
206
207 (define (document-property-value sym alist)
208   "Extract value for SYM from ALIST, return as texi string"
209   (let* ((handle (assoc sym alist)))
210     (if (eq? handle #f)
211         "(unset)"
212         (scm->texi (cdr handle)))))
213
214
215 (define (backend-property->texi sym)
216   (property->texi 'backend sym))
217
218 (define (document-property sym where alist)
219   "Document SYM. If GROB-DESCRIPTION is not #f, it's an alist
220 containing default values."
221   (let*
222       ((without (property->texi where sym))
223        (rv
224
225     (cons (car without)
226           (if (eq? alist #f)
227               (cdr without)
228               (string-append
229                (cdr without)
230                "\nDefault value: "
231                (document-property-value sym alist)))))
232
233        )
234 ;    (display rv)
235     rv  ))