]> 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
 
 @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::
 
 @menu
 * Music function syntax::
 * Simple substitution functions::
 * Intermediate substitution functions::
 * Mathematics in functions::
-* Void functions::
 * Functions without arguments::
 * Functions without arguments::
+* Void functions::
 @end menu
 
 @end menu
 
+
 @node Music function syntax
 @subsection Music function syntax
 
 @node Music function syntax
 @subsection Music function syntax
 
-The general syntax of a music function is:
+The general form for music functions is:
 
 @example
 
 @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
 @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
 
 @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
 
 
 @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).
 
 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:
 
 The pair can be directly passed into the music function,
 using a @code{pair?} variable:
 
-@quotation
 @example
 manualBeam =
 @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
 
 \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
 
 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 =
 
 @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
 
 \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]
 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 =
      \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
 }
 
 
 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]
 @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 =
      \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
      $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
 
 @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
 
 @node Functions without arguments
 @subsection Functions without arguments
@@ -280,7 +217,9 @@ without arguments,
 
 @example
 displayBarNum =
 
 @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 #@}
        #@{#@}))
    (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
 
 
 @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
 
 @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
 
 
 @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::
 
 @menu
 * Substitution function syntax::
-* Common argument types::
 * Substitution function examples::
 @end menu
 
 * Substitution function examples::
 @end menu
 
@@ -3593,91 +3592,88 @@ code is easy.  The general form of these functions is
 
 @example
 function =
 
 @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
 @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
 
 
 @seealso
 
-Extending LilyPond:
-@rextend {Music function syntax}.
+Notation Reference:
+@ref{Predefined type predicates}.
+
+Extending:
+@rextend{Music functions}.
 
 Installed Files:
 @file{lily/music-scheme.cc},
 
 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
 
 
 
 @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]
 
 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
 
 \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:
 
 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]
 @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" }
 
 \relative c'' {
   \tempo \markup { "Low tempo" }
@@ -3726,3 +3728,4 @@ tempoPadded = #(define-music-function (parser location padding tempotext)
 
 @seealso
 
 
 @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::
 * All context properties::
 * Layout properties::
 * Available music functions::
+* Predefined type predicates::
 * Scheme functions::
 @end menu
 
 * Scheme functions::
 @end menu
 
@@ -1343,6 +1344,12 @@ Internals Reference:
 @include identifiers.tely
 
 
 @include identifiers.tely
 
 
+@node Predefined type predicates
+@appendixsec Predefined type predicates
+
+@include type-predicates.tely
+
+
 @node Scheme functions
 @appendixsec Scheme functions
 
 @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)
   (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-functions.scm"
               "document-translation.scm"
               "document-music.scm"
+              "document-type-predicates.scm"
               "document-identifiers.scm"
               "document-backend.scm"
               "document-markup.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"))
 
  (slot-ref (all-scheme-functions-doc) 'text)
  (open-output-file "scheme-functions.tely"))
 
-;;(display 
+;;(display
 ;; (markup-doc-string)
 ;; (open-output-file "markup-commands.tely"))
 
 ;; (markup-doc-string)
 ;; (open-output-file "markup-commands.tely"))
 
   (lambda (port)
     (dump-node (markup-list-doc-node) port 2)))
 
   (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"))
 
  (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.")
 "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,
 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)
 
 
 (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
 (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
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; timing
index 04accee6652ee904a4e724caff31893520e13240..8e4697dd66b26a8d02b3289bd3312b58eda8e83e 100644 (file)
@@ -329,7 +329,12 @@ and duration-log @var{log}."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Color
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; 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
 (define-public (rgb-color r g b) (list r g b))
 
 ; predefined colors