]> git.donarmstrong.com Git - lilypond.git/commitdiff
Doc & scm/: Music-functions and type-predicates.
authorMark Polesky <markpolesky@yahoo.com>
Fri, 7 May 2010 23:56:26 +0000 (16:56 -0700)
committerMark Polesky <markpolesky@yahoo.com>
Fri, 7 May 2010 23:58:43 +0000 (16:58 -0700)
- Clean up:
    NR 5.6 "Using music functions"
    EL 2.1 "Music functions"
- In Extending 2.1, move `Void functions' to end of section,
  so `Functions without arguments' comes first.
- Use a consistent indentation format for music functions.
- Make some minor formatting/wording changes.
- Categorize predicates in type-p-name-alist.
- Create type-predicates-doc-string to document
  type-p-name-alist automatically.
- Add notation appendix `Predefined type predicates' to
  include type-predicates-doc-string.
- Show predicate name instead of "unknown" in
  type-check error message (provided by Neil Puttock).
- Make `color?' predicate more specific.

Documentation/extending/programming-interface.itely
Documentation/notation/changing-defaults.itely
Documentation/notation/notation-appendices.itely
scm/c++.scm
scm/document-type-predicates.scm [new file with mode: 0644]
scm/documentation-generate.scm
scm/lily.scm
scm/output-lib.scm

index 7045b49daf552eb39878b956aedb8ae00773d19b..7c8b287552fede93f24346adeaf14aca550302f8 100644 (file)
@@ -30,137 +30,85 @@ not familiar with Scheme, you may wish to read our
 @node Music functions
 @section Music functions
 
-Music functions are scheme functions that are used to
-automatically create music expressions.  They can be used to
-greatly simplify the input file.
+@emph{Music functions} are scheme procedures that can create music
+expressions automatically, and can be used to greatly simplify the
+input file.
 
 @menu
 * Music function syntax::
 * Simple substitution functions::
 * Intermediate substitution functions::
 * Mathematics in functions::
-* Void functions::
 * Functions without arguments::
+* Void functions::
 @end menu
 
+
 @node Music function syntax
 @subsection Music function syntax
 
-The general syntax of a music function is:
+The general form for music functions is:
 
 @example
-myFunction =
-#(define-music-function (parser location @var{var_1} @var{var_2}...@var{var_n})
-                        (@var{var_1-type?} @var{var_2-type?}...@var{var_n-type?})
-    @var{...valid music expression...})
+function =
+#(define-music-function
+     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{type1?} @var{type2?} @dots{})
+   @var{music})
 @end example
 
 @noindent
 where
 
 @multitable @columnfractions .33 .66
-@item @var{var_i}         @tab @var{i}th variable
-@item @var{var_i-type?}   @tab type of @var{i}th variable
-@item @var{...valid music expression...}  @tab expression that returns
-valid music, generally in the form of a Scheme expression.  There is
-also special syntax that allows LilyPond input code in this music
-expression.
-@end multitable
+@item @code{@var{argN}}
+@tab @var{n}th argument
 
-The variable type checkers are scheme procedures that will return
-@code{#t} if a variable is of a given type.  Some common types
-are shown in the table below.  Other types can be found in the files
-@file{lily/music-scheme.cc} and @file{scm/c++.scm}.  The complete
-list of named type checkers for LilyPond is found in the
-@var{type-p-name-alist} of @file{scm/lily.scm}.
+@item @code{@var{typeN?}}
+@tab a scheme @emph{type predicate} for which @code{@var{argN}}
+must return @code{#t}.
 
-@c TODO -- automatically document type-p-name-alist
+@item @code{@var{music}}
+@tab A music expression, optionally written in scheme, with any
+LilyPond code enclosed in hashed braces
+(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}).  Within LilyPond code
+blocks, use @code{$} to reference function arguments (eg.,
+@samp{$arg1}) or to start an inline scheme expression containing
+function arguments (eg., @w{@samp{$(cons arg1 arg2)}}).
 
-@multitable @columnfractions .33 .66
-@headitem Input type          @tab @var{vari-type?} notation
-@item Integer                 @tab @code{integer?}
-@item Float (decimal number)  @tab @code{number?}
-@item Text string             @tab @code{string?}
-@item Markup                  @tab @code{markup?}
-@item Music expression        @tab @code{ly:music?}
-@item A pair of variables     @tab @code{pair?}
 @end multitable
 
-The @code{parser} and @code{location} arguments are mandatory.
-The @code{parser} argument is used in the body of the function
-to gain access to the value of another LilyPond variable.
-The @code{location} argument is used to set the @q{origin}
-of the music expression that is built by the music function,
-so that in case of a syntax error LilyPond
-can tell the user an appropriate place to look in the input file.
-
-@node Simple substitution functions
-@subsection Simple substitution functions
+@noindent
+For a list of available type predicates, see
+@ruser{Predefined type predicates}.  User-defined type predicates
+are also allowed.
 
-A simple substitution function is a music function whose output music
-expression is written in LilyPond code, but with an input variable
-substituted into the LilyPond code.  The general form of these functions is
 
-@example
-myFunction =
-#(define-music-function (parser location @var{var1})
-                        (@var{var1-type?})
-  #@{
-    @emph{... LilyPond input code with} @code{#$var1} @emph{for substition ...}
-  #@})
-@end example
+@seealso
 
-Note that the special characters @code{#@{} and @code{#@}} surround the
-LilyPond music.
+Notation Reference:
+@ruser{Predefined type predicates}.
 
-@multitable @columnfractions .33 .66
-@item @var{vari}         @tab @var{i}th variable
-@item @var{vari-type?}   @tab type of @var{i}th variable
-@item @var{...music...}  @tab normal LilyPond input, using
- variables as @code{#$var1}, etc.
-@end multitable
+Installed Files:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
 
-For example, a function can be defined that simplifies
-setting the padding of a TextScript:
 
-@lilypond[quote,verbatim,ragged-right]
-padText = #(define-music-function (parser location padding) (number?)
-  #{
-    \once \override TextScript #'padding = #$padding
-  #})
-
-\relative c''' {
-  c4^"piu mosso" b a b
-  \padText #1.8
-  c4^"piu mosso" d e f
-  \padText #2.6
-  c4^"piu mosso" fis a g
-}
-@end lilypond
+@node Simple substitution functions
+@subsection Simple substitution functions
 
-In addition to numbers, we can use music expressions such
-as notes for arguments to music functions:
+Simple substitution functions are music functions whose output
+music expression is written in LilyPond format and contains
+function arguments in the output expression.  They are described
+in @ruser{Substitution function examples}.
 
-@lilypond[quote,verbatim,ragged-right]
-custosNote = #(define-music-function (parser location note)
-                                     (ly:music?)
-  #{
-    \once \override Voice.NoteHead #'stencil =
-      #ly:text-interface::print
-    \once \override Voice.NoteHead #'text =
-      \markup \musicglyph #"custodes.mensural.u0"
-    \once \override Voice.Stem #'stencil = ##f
-    $note
-  #})
-@end lilypond
 
 @node Intermediate substitution functions
 @subsection Intermediate substitution functions
 
-Slightly more complicated than simple substitution function,
-intermediate substitution functions involve a mix of Scheme code and
-LilyPond code in the music expression to be
-returned.
+Intermediate substitution functions involve a mix of Scheme code
+and LilyPond code in the music expression to be returned.
 
 Some @code{\override} commands require an argument consisting of
 a pair of numbers (called a @code{cons cell} in Scheme).
@@ -168,20 +116,19 @@ a pair of numbers (called a @code{cons cell} in Scheme).
 The pair can be directly passed into the music function,
 using a @code{pair?} variable:
 
-@quotation
 @example
 manualBeam =
-#(define-music-function (parser location beg-end)
-                        (pair?)
-#@{
-  \once \override Beam #'positions = #$beg-end
-#@})
+#(define-music-function
+     (parser location beg-end)
+     (pair?)
+   #@{
+     \once \override Beam #'positions = $beg-end
+   #@})
 
 \relative c' @{
   \manualBeam #'(3 . 6) c8 d e f
 @}
 @end example
-@end quotation
 
 Alternatively, the numbers making up the pair can be
 passed as separate arguments, and the Scheme code
@@ -190,11 +137,12 @@ music expression:
 
 @lilypond[quote,verbatim,ragged-right]
 manualBeam =
-#(define-music-function (parser location beg end)
-                        (number? number?)
-#{
-  \once \override Beam #'positions = #(cons $beg $end)
-#})
+#(define-music-function
+     (parser location beg end)
+     (number? number?)
+   #{
+     \once \override Beam #'positions = $(cons beg end)
+   #})
 
 \relative c' {
   \manualBeam #3 #6 c8 d e f
@@ -209,61 +157,50 @@ Music functions can involve Scheme programming in
 addition to simple substitution,
 
 @lilypond[quote,verbatim,ragged-right]
-AltOn = #(define-music-function (parser location mag) (number?)
-  #{ \override Stem #'length = #$(* 7.0 mag)
+AltOn =
+#(define-music-function
+     (parser location mag)
+     (number?)
+   #{
+     \override Stem #'length = $(* 7.0 mag)
      \override NoteHead #'font-size =
-       #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) #})
+       $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+   #})
 
 AltOff = {
   \revert Stem #'length
   \revert NoteHead #'font-size
 }
 
-{ c'2 \AltOn #0.5 c'4 c'
-  \AltOn #1.5 c' c' \AltOff c'2 }
+\relative c' {
+  c2 \AltOn #0.5 c4 c
+  \AltOn #1.5 c c \AltOff c2
+}
 @end lilypond
 
 @noindent
 This example may be rewritten to pass in music expressions,
 
 @lilypond[quote,verbatim,ragged-right]
-withAlt = #(define-music-function (parser location mag music) (number? ly:music?)
-  #{ \override Stem #'length = #$(* 7.0 mag)
+withAlt =
+#(define-music-function
+     (parser location mag music)
+     (number? ly:music?)
+   #{
+     \override Stem #'length = $(* 7.0 mag)
      \override NoteHead #'font-size =
-       #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+       $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
      $music
      \revert Stem #'length
-     \revert NoteHead #'font-size #})
+     \revert NoteHead #'font-size
+   #})
 
-{ c'2 \withAlt #0.5 {c'4 c'}
-  \withAlt #1.5 {c' c'} c'2 }
+\relative c' {
+  c2 \withAlt #0.5 { c4 c }
+  \withAlt #1.5 { c c } c2
+}
 @end lilypond
 
-@node Void functions
-@subsection Void functions
-
-A music function must return a music expression, but sometimes we
-may want to have a function that does not involve music (such as
-turning off Point and Click).  To do this, we return a @code{void}
-music expression.
-
-That is why the form
-that is returned is the @code{(make-music ...)}.  With the
-@code{'void} property set to @code{#t}, the parser is told to
-actually disregard this returned music
-expression.  Thus the important part of the void music function is the
-processing done by the function, not the music expression that is
-returned.
-
-@example
-noPointAndClick =
-#(define-music-function (parser location) ()
-   (ly:set-option 'point-and-click #f)
-   (make-music 'SequentialMusic 'void #t))
-...
-\noPointAndClick   % disable point and click
-@end example
-
 
 @node Functions without arguments
 @subsection Functions without arguments
@@ -280,7 +217,9 @@ without arguments,
 
 @example
 displayBarNum =
-#(define-music-function (parser location) ()
+#(define-music-function
+     (parser location)
+     ()
    (if (eq? #t (ly:get-option 'display-bar-numbers))
        #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
        #@{#@}))
@@ -294,6 +233,32 @@ lilypond -d display-bar-numbers FILENAME.ly
 @end example
 
 
+@node Void functions
+@subsection Void functions
+
+A music function must return a music expression, but sometimes we
+may want to have a function that does not involve music (such as
+turning off Point and Click).  To do this, we return a @code{void}
+music expression.
+
+That is why the form that is returned is the
+@w{@code{(make-music @dots{})}}.  With the @code{'void} property
+set to @code{#t}, the parser is told to actually disregard this
+returned music expression.  Thus the important part of the void
+music function is the processing done by the function, not the
+music expression that is returned.
+
+@example
+noPointAndClick =
+#(define-music-function
+     (parser location)
+     ()
+   (ly:set-option 'point-and-click #f)
+   (make-music 'SequentialMusic 'void #t))
+...
+\noPointAndClick   % disable point and click
+@end example
+
 
 @node Markup functions
 @section Markup functions
index e743ac1683e5f20269f6f0eaf084c9a7d1c9c8ab..bbf6a4e0b20964c504f6076bf529b4a1659b2398 100644 (file)
@@ -3572,16 +3572,15 @@ of ties as required.
 
 @c TODO -- add @seealso, etc. to these subsections
 
-Where tweaks need to be reused with different music expressions, it
-is often convenient to make the tweak part of a music function.
-In this section, we discuss only @emph{substitution} functions, where
-the object is to substitute a variable into a piece of LilyPond
-input code.  Other more complex functions are described in
-@rextend{Music functions}.
+Where tweaks need to be reused with different music expressions,
+it is often convenient to make the tweak part of a @emph{music
+function}.  In this section, we discuss only @emph{substitution}
+functions, where the object is to substitute a variable into a
+piece of LilyPond input code.  Other more complex functions are
+described in @rextend{Music functions}.
 
 @menu
 * Substitution function syntax::
-* Common argument types::
 * Substitution function examples::
 @end menu
 
@@ -3593,91 +3592,88 @@ code is easy.  The general form of these functions is
 
 @example
 function =
-#(define-music-function (parser location @var{var1} @var{var2}...@var{vari}... )
-                        (@var{var1-type?} @var{var2-type?}...@var{vari-type?}...)
-  #@{
-    @emph{...music...}
-  #@})
+#(define-music-function
+     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{type1?} @var{type2?} @dots{})
+   #@{
+     @var{@dots{}music@dots{}}
+   #@})
 @end example
 
 @noindent
 where
 
 @multitable @columnfractions .33 .66
-@item @var{vari}         @tab @var{i}th variable
-@item @var{vari-type?}   @tab type of @var{i}th variable
-@item @var{...music...}  @tab normal LilyPond input, using
- variables as @code{#$var1}, etc.
-@end multitable
-
-Common variable types are described in @ref{Common argument types}.
-A more complete description of variable types is found in
-@rextend{Music function syntax}.  The complete list of defined variable
-types is found in the @var{type-p-name-alist} entry of
-@file{scm/lily.scm}.
-
-@c TODO -- find an automatic way of documenting the type-p-name-alist
+@item @code{@var{argN}}
+@tab @var{n}th argument
 
-The @code{parser} and @code{location} arguments are mandatory,
-and are used in some advanced situations as described in
-@rextend{Music function syntax}.  For substitution functions, just be sure
-to include them.
+@item @code{@var{typeN?}}
+@tab a scheme @emph{type predicate} for which @code{@var{argN}}
+must return @code{#t}.
 
-@seealso
+@item @code{@var{@dots{}music@dots{}}}
+@tab normal LilyPond input, using @code{$} to reference arguments
+(eg. @samp{$arg1}).
+@end multitable
 
-Notation Reference:
-@ref{Common argument types}.
 
-Extending LilyPond:
-@rextend{Music function syntax}.
+The @code{parser} and @code{location} arguments are mandatory, and
+are used in some advanced situations as described in the
+@q{Extending} manual (see @rextend{Music functions}).  For
+substitution functions, just be sure to include them.
 
-@node Common argument types
-@subsection Common argument types
+The list of type predicates is also required.  Some of the most
+common type predicates used in music functions are:
 
-In order to allow for error checking, the type of each argument
-that is passed to a music function must be defined.  Some of the
-common types of variables are shown in the table below.
+@example
+boolean?
+cheap-list?  @emph{(use instead of }@q{list?}@emph{ for faster processing)}
+ly:music?
+markup?
+number?
+pair?
+string?
+symbol?
+@end example
 
-The following input types may be used as variables in a music
-function.  This list is not exhaustive;
-more information about possible variable types
-can be found in @rextend{Music function syntax}.
+@noindent
+For a list of available type predicates, see
+@ref{Predefined type predicates}.  User-defined type predicates
+are also allowed.
 
-@multitable @columnfractions .33 .66
-@headitem Input type          @tab @var{vari-type?} notation
-@item Integer                 @tab @code{integer?}
-@item Float (decimal number)  @tab @code{number?}
-@item Text string             @tab @code{string?}
-@item Markup                  @tab @code{markup?}
-@item Music expression        @tab @code{ly:music?}
-@item A Scheme pair           @tab @code{pair?}
-@end multitable
 
 @seealso
 
-Extending LilyPond:
-@rextend {Music function syntax}.
+Notation Reference:
+@ref{Predefined type predicates}.
+
+Extending:
+@rextend{Music functions}.
 
 Installed Files:
 @file{lily/music-scheme.cc},
-@file{scm/c++.scm}.
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
 
 
 @node Substitution function examples
 @subsection Substitution function examples
 
-This section introduces some substitution function examples.  These
-are not intended to be exhaustive, but rather to demonstrate some
-of the possibilities of simple substitution functions.
+This section introduces some substitution function examples.
+These are not intended to be exhaustive, but rather to demonstrate
+some of the possibilities of simple substitution functions.
 
 In the first example, a function is defined that simplifies
 setting the padding of a TextScript:
 
 @lilypond[quote,verbatim,ragged-right]
-padText = #(define-music-function (parser location padding) (number?)
-  #{
-    \once \override TextScript #'padding = #$padding
-  #})
+padText =
+#(define-music-function
+     (parser location padding)
+     (number?)
+   #{
+     \once \override TextScript #'padding = $padding
+   #})
 
 \relative c''' {
   c4^"piu mosso" b a b
@@ -3691,30 +3687,36 @@ padText = #(define-music-function (parser location padding) (number?)
 In addition to numbers, we can use music expressions such
 as notes for arguments to music functions:
 
-@lilypond[quote,verbatim,ragged-right]
-custosNote = #(define-music-function (parser location note)
-                                     (ly:music?)
-  #{
-    \once \override Voice.NoteHead #'stencil =
-      #ly:text-interface::print
-    \once \override Voice.NoteHead #'text =
-      \markup \musicglyph #"custodes.mensural.u0"
-    \once \override Voice.Stem #'stencil = ##f
-    $note
-  #})
+@c TODO: use a better example (the music argument is redundant).
 
-{ c' d' e' f' \custosNote g' }
+@lilypond[quote,verbatim,ragged-right]
+custosNote =
+#(define-music-function
+     (parser location note)
+     (ly:music?)
+   #{
+     \once \override Voice.NoteHead #'stencil =
+       #ly:text-interface::print
+     \once \override Voice.NoteHead #'text =
+       \markup \musicglyph #"custodes.mensural.u0"
+     \once \override Voice.Stem #'stencil = ##f
+     $note
+   #})
+
+\relative c' { c4 d e f \custosNote g }
 @end lilypond
 
 Substitution functions with multiple arguments can be defined:
 
 @lilypond[quote,verbatim,ragged-right]
-tempoPadded = #(define-music-function (parser location padding tempotext)
-  (number? string?)
-#{
-  \once \override Score.MetronomeMark #'padding = $padding
-  \tempo \markup { \bold $tempotext }
-#})
+tempoPadded =
+#(define-music-function
+     (parser location padding tempotext)
+     (number? string?)
+   #{
+     \once \override Score.MetronomeMark #'padding = $padding
+     \tempo \markup { \bold $tempotext }
+   #})
 
 \relative c'' {
   \tempo \markup { "Low tempo" }
@@ -3726,3 +3728,4 @@ tempoPadded = #(define-music-function (parser location padding tempotext)
 
 @seealso
 
+TODO: add missing @@ref's here.
index b18810e872ef26a528061f7670f27664e8f7f38c..6b58d17b656dd69d4785a64e42d452e0c8d725a4 100644 (file)
@@ -47,6 +47,7 @@ and just before
 * All context properties::
 * Layout properties::
 * Available music functions::
+* Predefined type predicates::
 * Scheme functions::
 @end menu
 
@@ -1343,6 +1344,12 @@ Internals Reference:
 @include identifiers.tely
 
 
+@node Predefined type predicates
+@appendixsec Predefined type predicates
+
+@include type-predicates.tely
+
+
 @node Scheme functions
 @appendixsec Scheme functions
 
index 362e358b34d9929bf74f158ccdf31d7178e0fdf3..bc518030ae8304889cc98a3d37015839a98c3a7d 100644 (file)
@@ -74,4 +74,8 @@
   (type-name (match-predicate obj type-p-name-alist)))
 
 (define-public (type-name predicate)
-  (assoc-get predicate type-p-name-alist "unknown"))
+  (let ((entry (assoc predicate type-p-name-alist)))
+    (if (pair? entry) (cdr entry)
+        (string-trim-right
+         (symbol->string (procedure-name predicate))
+         #\?))))
diff --git a/scm/document-type-predicates.scm b/scm/document-type-predicates.scm
new file mode 100644 (file)
index 0000000..aff4034
--- /dev/null
@@ -0,0 +1,69 @@
+;;;; This file is part of LilyPond, the GNU music typesetter.
+;;;;
+;;;; Copyright (C) 2010 Mark Polesky <markpolesky@yahoo.com>
+;;;;
+;;;; 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 (document-type-predicate entry)
+  (let ((pred (procedure-name (car entry))))
+    (string-append
+     "@item @code{"
+     (case pred
+       ;; don't print "cheap-markup?"
+       ((cheap-markup?) "markup?")
+       (else (symbol->string pred)))
+     "} @tab \n"
+     (case pred
+       ;; clarify `list?' vs. `cheap-list?'
+       ((list?) "list @emph{(use} @code{cheap-list?}
+                @emph{for faster processing)}")
+       ((cheap-list?) "list @emph{(use this instead of}
+                      @code{list?} @emph{for faster processing)}")
+       (else (cdr entry)))
+     "\n")))
+
+(define (document-type-predicate-category alist nodename)
+  (string-append
+   "@node " nodename "\n"
+   "@unnumberedsubsec " nodename "\n"
+   "\n"
+   "@multitable @columnfractions .33 .66\n"
+   "@headitem Type predicate @tab Description\n"
+   (apply string-append
+          (sort (map document-type-predicate alist)
+                ly:string-ci<?))
+   "@end multitable\n"
+   "\n"))
+
+(define-public type-predicates-doc-string
+  (string-append
+   "@menu\n"
+   "* R5RS primary predicates::\n"
+   "* R5RS secondary predicates::\n"
+   "* Guile predicates::\n"
+   "* LilyPond scheme predicates::\n"
+   "* LilyPond exported predicates::\n"
+   "@end menu\n"
+   "\n"
+   (apply
+    string-append
+    (map
+     (lambda (alist-nodename-list)
+       (apply document-type-predicate-category
+              alist-nodename-list))
+     `((,r5rs-primary-predicates "R5RS primary predicates")
+       (,r5rs-secondary-predicates "R5RS secondary predicates")
+       (,guile-predicates "Guile predicates")
+       (,lilypond-scheme-predicates "LilyPond scheme predicates")
+       (,lilypond-exported-predicates "LilyPond exported predicates"))))))
index c64fb3a166e4ed69f8674e5e5af6c72ec68ae2ca..0e6cfe32bed7fd64a75b2a3bc497e9e47f12ea96 100644 (file)
@@ -32,6 +32,7 @@
               "document-functions.scm"
               "document-translation.scm"
               "document-music.scm"
+              "document-type-predicates.scm"
               "document-identifiers.scm"
               "document-backend.scm"
               "document-markup.scm"))
@@ -42,7 +43,7 @@
  (slot-ref (all-scheme-functions-doc) 'text)
  (open-output-file "scheme-functions.tely"))
 
-;;(display 
+;;(display
 ;; (markup-doc-string)
 ;; (open-output-file "markup-commands.tely"))
 
   (lambda (port)
     (dump-node (markup-list-doc-node) port 2)))
 
-(display 
+(display
+ type-predicates-doc-string
+ (open-output-file "type-predicates.tely"))
+
+(display
  (identifiers-doc-string)
  (open-output-file "identifiers.tely"))
 
index 8cfebbd0db26366f405b8f93712f82470eefbd52..2b6ca651b4adbc83a3e911b25b6acc65fb4ef3cf 100644 (file)
@@ -49,8 +49,8 @@
 "Render at higher resolution (using given factor)
 and scale down result to prevent jaggies in
 PNG images.")
-    (aux-files #t 
-"Create .tex, .texi, .count files in the 
+    (aux-files #t
+"Create .tex, .texi, .count files in the
 EPS backend.")
     (backend ps
 "Select backend.  Possible values: 'eps, 'null,
@@ -410,50 +410,119 @@ LilyPond safe mode.  The syntax is the same as `define*-public'."
 
 (for-each ly:load init-scheme-files)
 
+(define-public r5rs-primary-predicates
+  `((,boolean? . "boolean")
+    (,char? . "character")
+    (,number? . "number")
+    (,pair? . "pair")
+    (,port? . "port")
+    (,procedure? . "procedure")
+    (,string? . "string")
+    (,symbol? . "symbol")
+    (,vector? . "vector")))
+
+(define-public r5rs-secondary-predicates
+  `((,char-alphabetic? . "alphabetic character")
+    (,char-lower-case? . "lower-case character")
+    (,char-numeric? . "numeric character")
+    (,char-upper-case? . "upper-case character")
+    (,char-whitespace? . "whitespace character")
+
+    (,complex? . "complex number")
+    (,even? . "even number")
+    (,exact? . "exact number")
+    (,inexact? . "inexact number")
+    (,integer? . "integer")
+    (,negative? . "negative number")
+    (,odd? . "odd number")
+    (,positive? . "positive number")
+    (,rational? . "rational number")
+    (,real? . "real number")
+    (,zero? . "zero")
+
+    (,list? . "list")
+    (,null? . "null")
+
+    (,input-port? . "input port")
+    (,output-port? . "output port")
+
+    ;; would this ever be used?
+    (,eof-object? . "end-of-file object")
+    ))
+
+(define-public guile-predicates
+  `((,hash-table? . "hash table")
+  ))
+
+(define-public lilypond-scheme-predicates
+  `((,boolean-or-symbol? . "boolean or symbol")
+    (,color? . "color")
+    (,cheap-list? . "list")
+    (,grob-list? . "list of grobs")
+    ;; this is built on cheap-list
+    (,list-or-symbol? . "list or symbol")
+    (,markup? . "markup")
+    (,markup-command-list? . "markup command list")
+    (,markup-list? . "markup list")
+    (,moment-pair? . "pair of moment objects")
+    (,number-or-grob? . "number or grob")
+    (,number-or-string? . "number or string")
+    (,number-pair? . "pair of numbers")
+    (,rhythmic-location? . "rhythmic location")
+    (,scheme? . "any type")
+    (,string-or-pair? . "string or pair")
+    (,string-or-symbol? . "string or symbol")
+    ))
+
+(define-public lilypond-exported-predicates
+  `((,ly:box? . "box")
+    (,ly:context? . "context")
+    (,ly:dimension? . "dimension, in staff space")
+    (,ly:dir? . "direction")
+    (,ly:dispatcher? . "dispatcher")
+    (,ly:duration? . "duration")
+    (,ly:font-metric? . "font metric")
+    (,ly:grob? . "graphical (layout) object")
+    (,ly:grob-array? . "array of grobs")
+    (,ly:input-location? . "input location")
+    (,ly:item? . "item")
+    (,ly:iterator? . "iterator")
+    (,ly:lily-lexer? . "lily-lexer")
+    (,ly:lily-parser? . "lily-parser")
+    (,ly:listener? . "listener")
+    (,ly:moment? . "moment")
+    (,ly:music? . "music")
+    (,ly:music-function? . "music function")
+    (,ly:music-list? . "list of music objects")
+    (,ly:music-output? . "music output")
+    (,ly:otf-font? . "OpenType font")
+    (,ly:output-def? . "output definition")
+    (,ly:page-marker? . "page marker")
+    (,ly:pango-font? . "pango font")
+    (,ly:paper-book? . "paper book")
+    (,ly:paper-system? . "paper-system Prob")
+    (,ly:pitch? . "pitch")
+    (,ly:prob? . "property object")
+    (,ly:score? . "score")
+    (,ly:simple-closure? . "simple closure")
+    (,ly:skyline? . "skyline")
+    (,ly:skyline-pair? . "pair of skylines")
+    (,ly:source-file? . "source file")
+    (,ly:spanner? . "spanner")
+    (,ly:stencil? . "stencil")
+    (,ly:stream-event? . "stream event")
+    (,ly:translator? . "translator")
+    (,ly:translator-group? . "translator group")
+    ))
+
+
 (set! type-p-name-alist
-      `((,boolean? . "boolean")
-       (,boolean-or-symbol? . "boolean or symbol")
-       (,char? . "char")
-       (,grob-list? . "list of grobs")
-       (,hash-table? . "hash table")
-       (,input-port? . "input port")
-       (,integer? . "integer")
-       (,list? . "list")
-       (,list-or-symbol? . "list or symbol")
-       (,ly:context? . "context")
-       (,ly:dimension? . "dimension, in staff space")
-       (,ly:dir? . "direction")
-       (,ly:duration? . "duration")
-       (,ly:font-metric? . "font metric")
-       (,ly:grob? . "layout object")
-       (,ly:grob-array? . "array of grobs")
-       (,ly:input-location? . "input location")
-       (,ly:moment? . "moment")
-       (,ly:music? . "music")
-       (,ly:music-list? . "list of music objects")
-       (,ly:music-output? . "music output")
-       (,ly:pitch? . "pitch")
-       (,ly:translator? . "translator")
-        (,ly:score? . "score")
-       (,ly:simple-closure? . "simple closure")
-       (,ly:skyline-pair? . "pair of skylines")
-       (,ly:stencil? . "stencil")
-       (,markup-list? . "list of markups")
-       (,markup? . "markup")
-       (,number-or-grob? . "number or grob")
-       (,number-or-string? . "number or string")
-       (,number-pair? . "pair of numbers")
-       (,number? . "number")
-       (,output-port? . "output port")
-       (,pair? . "pair")
-       (,procedure? . "procedure")
-       (,real? . "real number")
-       (,rhythmic-location? . "rhythmic location")
-       (,scheme? . "any type")
-       (,string? . "string")
-       (,string-or-pair? . "string or pair")
-       (,symbol? . "symbol")
-       (,vector? . "vector")))
+      (append r5rs-primary-predicates
+              r5rs-secondary-predicates
+              guile-predicates
+              lilypond-scheme-predicates
+              lilypond-exported-predicates))
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; timing
index 04accee6652ee904a4e724caff31893520e13240..8e4697dd66b26a8d02b3289bd3312b58eda8e83e 100644 (file)
@@ -329,7 +329,12 @@ and duration-log @var{log}."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Color
 
-(define-public color? list?)
+(define-public (color? x)
+  (and (list? x)
+       (= 3 (length x))
+       (apply eq? #t (map number? x))
+       (apply eq? #t (map (lambda (y) (<= 0 y 1)) x))))
+
 (define-public (rgb-color r g b) (list r g b))
 
 ; predefined colors