]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/document-backend.scm
New upstream version 2.19.80
[lilypond.git] / scm / document-backend.scm
index 7603f5d94248961fa9f3dc466cb8853791a8c8e0..0ba63b2cfc46163b41850d7e8221a436c61b99c8 100644 (file)
-;;; backend-documentation-lib.scm -- Functions for backend documentation
-;;;
-;;; source file of the GNU LilyPond music typesetter
-;;; 
-;;; (c)  2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-;;; Jan Nieuwenhuizen <janneke@gnu.org>
-
-
-;;; This file generates documentation for the backend of lilypond.
-
-;; alist of property descriptions
-
-;;
-"
-TODO:
-
-
-Grob bla
-
-Created by:
-
-  * preset properties + explanation
-
-Interfaces:
-
-  * properties available.
-
-"
-
+;;;; This file is part of LilyPond, the GNU music typesetter.
+;;;;
+;;;; Copyright (C) 2000--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Jan Nieuwenhuizen <janneke@gnu.org>
+;;;;
+;;;; LilyPond is free software: you can redistribute it and/or modify
+;;;; it under the terms of the GNU General Public License as published by
+;;;; the Free Software Foundation, either version 3 of the License, or
+;;;; (at your option) any later version.
+;;;;
+;;;; LilyPond 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 General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+
+(define (sort-grob-properties props)
+  ;; force 'meta to the end of each prop-list
+  (let ((meta (assoc 'meta props)))
+    (append (sort (assoc-remove! props 'meta) ly:alist-ci<?)
+            (list meta))))
+
+;; properly sort all properties and interfaces
+;; within the all-grob-descriptions alist
+(set! all-grob-descriptions
+  (map!
+    (lambda (grob-description)
+      (let* ((grob-key      (car grob-description))
+             (props         (assoc-ref all-grob-descriptions grob-key))
+             (meta          (assoc-ref props 'meta))
+             (interfaces    (assoc-ref meta 'interfaces))
+             (sorted-ifaces (sort interfaces ly:symbol-ci<?))
+             (new-meta      (assoc-set! meta 'interfaces sorted-ifaces))
+             (new-props     (assoc-set! props 'meta new-meta))
+             (sorted-props  (sort-grob-properties new-props)))
+        (cons grob-key sorted-props)))
+    all-grob-descriptions))
+
+;; sort all grobs in the all-grob-descriptions alist
+(set! all-grob-descriptions (sort all-grob-descriptions ly:alist-ci<?))
 
 (define (interface-doc-string interface grob-description)
-  (let*
-      (
-       (name (car interface))
-       (desc (cadr interface))
-       (props (sort (caddr interface) symbol<?))
-       (docfunc (lambda (pr)
-                 (document-property
-                  pr 'backend grob-description )))
-       (propdocs (map docfunc props))
-       )
-    
+  (let* ((name (car interface))
+         (desc (cadr interface))
+         (props (caddr interface))
+         (docfunc (lambda (pr)
+                    (property->texi
+                     'backend pr grob-description)))
+         (iprops (filter (lambda (x) (object-property x 'backend-internal))
+                         props))
+         (uprops (filter
+                  (lambda (x) (not (object-property x 'backend-internal)))
+                  props))
+         (user-propdocs (map docfunc uprops))
+         (internal-propdocs (map docfunc iprops)))
+
     (string-append
      desc
-     "\n\n"
-     (description-list->texi propdocs))
 
-    ))
+     (if (pair? uprops)
+         (string-append
+          "\n\n@subsubheading User settable properties:\n"
+          (description-list->texi user-propdocs #t))
+         "")
 
+     (if (pair? iprops)
+         (string-append
+          "\n\n@subsubheading Internal properties:\n"
+          (description-list->texi internal-propdocs #t))
+         ""))))
 
-(define iface->grob-table (make-vector 61 '()))
+(define iface->grob-table (make-hash-table 61))
 ;; extract ifaces, and put grob into the hash table.
-(map
+(for-each
  (lambda (x)
-   (let*
-       (
-       (metah (assoc 'meta (cdr x)))
-       (meta (cdr metah))
-       (ifaces (cdr (assoc 'interfaces meta)))
-       )
-
-     (map (lambda (iface)
-           (hashq-set!
-            iface->grob-table iface
-            (cons (car x)
-                  (hashq-ref iface->grob-table iface '())
-                  )))
-         ifaces)
-     ))
+   (let* ((meta (assoc-get 'meta (cdr x)))
+          (ifaces (assoc-get 'interfaces meta)))
+
+     (for-each (lambda (iface)
+                 (hashq-set!
+                  iface->grob-table iface
+                  (cons (car x)
+                        (hashq-ref iface->grob-table iface '()))))
+               ifaces)))
  all-grob-descriptions)
 
 ;; First level Interface description
 (define (interface-doc interface)
-  (let ((name (symbol->string (car interface))))
+  (let* ((name (symbol->string (car interface)))
+         (interface-list (human-listify
+                          (map ref-ify
+                               (sort
+                                (map symbol->string
+                                     (hashq-ref iface->grob-table
+                                                (car interface)
+                                                '()))
+                                ly:string-ci<?)))))
     (make <texi-node>
       #:name name
       #:text (string-append
-             (interface-doc-string (cdr interface) #f)
-             "\n\n"
-             "This grob interface is used in the following graphical objects: "
-
-             (human-listify
-              (map ref-ify
-                   (map symbol->string
-                        (hashq-ref iface->grob-table (car interface) '() )))))
-
-      )))
+              (interface-doc-string (cdr interface) '())
+              "\n\n"
+              "This grob interface "
+              (if (equal? interface-list "none")
+                  "is not used in any graphical object"
+                  (string-append
+                   "is used in the following graphical object(s): "
+                   interface-list))
+              "."))))
+
+(define (grob-alist->texi alist)
+  (let* ((uprops (filter (lambda (x) (not (object-property x 'backend-internal)))
+                         (map car alist))))
+
+    (description-list->texi
+     (map (lambda (y) (property->texi 'backend y alist))
+          uprops)
+     #t)))
 
 (define (grob-doc description)
   "Given a property alist DESCRIPTION, make a documentation
 node."
-  
-  (let*
-      (
-       (metah (assoc 'meta description))
-       
-       (meta (cdr metah))
-       (name (cdr (assoc 'name meta)))
-       (ifaces (map lookup-interface (cdr (assoc 'interfaces meta))))
-       (ifacedoc (map (lambda (iface)
-                       (string-append
-"@html
-<hr>
-@end html
-
-@subsubheading "
-(ref-ify (symbol->string (car iface)))
-
-"\n\n"
-                       (interface-doc-string iface description)))
-                     (reverse ifaces)))
-       (engravers (filter
-                  (lambda (x) (engraver-makes-grob? name x)) all-engravers-list))
-       (namestr (symbol->string name))
-       (engraver-names (map ly:translator-name engravers))
-       )
+
+  (let* ((meta (assoc-get 'meta description))
+         (name (assoc-get 'name meta))
+         ;;       (bla (display name))
+         (ifaces (map lookup-interface (assoc-get 'interfaces meta)))
+         (ifacedoc (map ref-ify
+                        (sort
+                         (map (lambda (iface)
+                                (if (pair? iface)
+                                    (symbol->string (car iface))
+                                    (ly:error (_ "pair expected in doc ~s") name)))
+                              ifaces)
+                         ly:string-ci<?)))
+         (engravers (filter
+                     (lambda (x) (engraver-makes-grob? name x))
+                     all-engravers-list))
+         (namestr (symbol->string name))
+         (engraver-names (map symbol->string
+                              (map ly:translator-name engravers)))
+         (engraver-list (human-listify
+                         (map ref-ify
+                              (map engraver-name engraver-names)))))
 
     (make <texi-node>
       #:name namestr
       #:text
       (string-append
-       namestr " grobs are created by: "
-       (human-listify (map ref-ify
-                          (map engraver-name engraver-names)))
-       (apply string-append ifacedoc)
-       ))
-    ))
+       namestr " objects "
+       (if (equal? engraver-list "none")
+           "are not created by any engraver"
+           (string-append
+            "are created by: "
+            engraver-list))
+       "."
+
+       "\n\nStandard settings:\n"
+       (grob-alist->texi description)
+       "\n\nThis object supports the following interface(s):\n"
+       (human-listify ifacedoc)
+       "."))))
 
 (define (all-grobs-doc)
   (make <texi-node>
     #:name "All layout objects"
-    #:desc "Description and defaults for all Grobs"
+    #:desc "Description and defaults for all graphical objects (grobs)."
     #:children
     (map (lambda (x) (grob-doc (cdr x)))  all-grob-descriptions)))
 
 (define interface-description-alist
   (hash-fold
    (lambda (key val prior)
-     (cons (cons key val)  prior)
-     )
+     (cons (cons key val)  prior))
    '() (ly:all-grob-interfaces)))
 
-(set! interface-description-alist (sort interface-description-alist alist<?))
+;; sort user-settable and internal props within each grob-interface
+(set! interface-description-alist
+  (map! (lambda (iface-desc)
+          (let* ((key-name-docstr (list-head iface-desc 3))
+                 (props           (list-tail iface-desc 3))
+                 (sorted-props    (list (sort (car props) ly:symbol-ci<?))))
+            (append key-name-docstr sorted-props)))
+        interface-description-alist))
 
+;; sort list of grob interfaces
+(set! interface-description-alist
+      (sort interface-description-alist ly:alist-ci<?))
 
 ;;;;;;;;;; check for dangling backend properties.
 (define (mark-interface-properties entry)
-  (map (lambda (x) (set-object-property! x  'iface-marked #t)) (caddr (cdr entry)))
-  )
+  (for-each (lambda (x) (set-object-property! x 'iface-marked #t))
+            (caddr (cdr entry))))
 
-(map mark-interface-properties interface-description-alist)
+(for-each mark-interface-properties interface-description-alist)
 
 (define (check-dangling-properties prop)
   (if (not (object-property prop 'iface-marked))
-      (error  "\ngrob-property-description.scm: Can't find interface for property:" prop)))
+      (ly:error (string-append "define-grob-properties.scm: "
+                               (_ "cannot find interface for property: ~S")) prop)))
 
-(map check-dangling-properties all-backend-properties)
+(for-each check-dangling-properties all-backend-properties)
 
 ;;;;;;;;;;;;;;;;
 
 (define (lookup-interface name)
-  (let*  (
-         (entry  (hashq-ref (ly:all-grob-interfaces) name #f))
-         )
-
-    (if (equal? entry #f)
-       (error "Unknown interface" name))
-    
-    entry
-))
+  (let* ((entry (hashq-ref (ly:all-grob-interfaces) name #f)))
+    (if entry
+        entry
+        (ly:error (_ "unknown Grob interface: ~S") name))))
 
 (define (all-interfaces-doc)
   (make <texi-node>
     #:name "Graphical Object Interfaces"
-    #:desc "Building blocks of graphical objects"
+    #:desc "Building blocks of graphical objects."
     #:children
-    (map interface-doc interface-description-alist)
-    ))
-
-(define (all-backend-properties-doc)
-  (let*
-      (
-       (ps (sort (map symbol->string all-backend-properties) string<?))
-       (descs (map (lambda (prop)
-                    (document-property (string->symbol prop) 'backend #f))
-                  ps))
-       (texi (description-list->texi descs))
-       )
-    (make <texi-node>
-      #:name "backend properties"
-      #:desc "all the properties in use as grob properties"
-      #:text texi)
-  ))
+    (map interface-doc interface-description-alist)))
+
+(define (backend-properties-doc-string lst)
+  (let* ((ps (sort (map symbol->string lst) ly:string-ci<?))
+         (descs (map (lambda (prop)
+                       (property->texi 'backend (string->symbol prop) '())) ps))
+         (texi (description-list->texi descs #f)))
+    texi))
 
-;(dump-node (grob-doc (cdadr all-grob-descriptions))  (current-output-port) 0 )
+;;(dump-node (grob-doc (cdadr all-grob-descriptions)) (current-output-port) 0 )
 (define (backend-doc-node)
   (make <texi-node>
     #:name "Backend"
-    #:desc "Reference for the layout engine"
+    #:desc "Reference for the layout engine."
     #:children
     (list
      (all-grobs-doc)
      (all-interfaces-doc)
-     (all-backend-properties-doc)
-     )
-  ))
+     (make <texi-node>
+       #:name "User backend properties"
+       #:desc "All tunable properties in a big list."
+       #:text (backend-properties-doc-string all-user-grob-properties))
+     (make <texi-node>
+       #:name "Internal backend properties"
+       #:desc "All internal layout properties in a big list."
+       #:text (backend-properties-doc-string all-internal-grob-properties)))))