]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/extending/programming-interface.itely
Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation
[lilypond.git] / Documentation / extending / programming-interface.itely
index b2b13cbbc844fe2ddcbbd70ebb0b1643f2a5c3ed..be580034424071d97736417ecff76010be2b3fdb 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.6"
+@c \version "2.19.2"
 
 @node Interfaces for programmers
 @chapter Interfaces for programmers
@@ -25,7 +25,6 @@ not familiar with Scheme, you may wish to read our
 * Markup functions::
 * Contexts for programmers::
 * Callback functions::
-* Inline Scheme code::
 * Difficult tweaks::
 @end menu
 
@@ -138,8 +137,7 @@ with file names and line numbers.
 
 @item @code{@var{typeN?}}
 @tab a Scheme @emph{type predicate} for which @code{@var{argN}}
-must return @code{#t}.  Some of these predicates are specially
-recognized by the parser, see below.  There is also a special form
+must return @code{#t}.  There is also a special form
 @code{(@emph{predicate?} @emph{default})} for specifying optional
 arguments.  If the actual argument is missing when the function is being
 called, the default value is substituted instead.  Default values are
@@ -169,11 +167,7 @@ of @code{origin}.
 @end multitable
 
 @noindent
-Some type predicates are specially handled by the parser since it
-can't recognize the arguments reliably otherwise.  Currently these are
-@code{ly:pitch?} and @code{ly:duration?}.
-
-Suitability of arguments for all other predicates is determined by
+Suitability of arguments for the predicates is determined by
 actually calling the predicate after LilyPond has already converted them
 into a Scheme expression.  As a consequence, the argument can be
 specified in Scheme syntax if desired (introduced with @code{#} or as
@@ -184,20 +178,21 @@ strings (with or without quotes), numbers, full markups and markup
 lists, score, book, bookpart, context definition and output definition
 blocks.
 
-For some kinds of expression (like most music not enclosed in braces)
-LilyPond needs to look further than the expression itself in order to
-determine its end.  If such an expression were considered for an
-optional argument by evaluating its predicate, LilyPond would not be
-able to ``backup'' when it decides the expression does not fit the
-parameter.  So some forms of music might need to be enclosed in braces
-to make them acceptable to LilyPond.  There are also some other
-ambiguities that LilyPond sorts out by checking with predicate
+Some
+ambiguities LilyPond sorts out by checking with predicate
 functions: is @samp{-3} a fingering postevent or a negative number?  Is
 @code{"a" 4} in lyric mode a string followed by a number, or a lyric
-event of duration @code{4}?  LilyPond decides by asking the predicates.
-That means that you should avoid permissive predicates like
-@code{scheme?} if you have a particular use in mind instead of a general
-purpose function.
+event of duration @code{4}?  LilyPond tries the argument
+predicate on successive interpretations until success, with an
+order designed to minimize inconsistent interpretations and
+lookahead.
+
+For example, a predicate accepting both music expressions and
+pitches will consider @code{c''} to be a pitch rather than a music
+expression.  Immediately following durations or postevents will
+change that interpretation.  It's best to avoid overly
+permissive predicates like @code{scheme?} when the application
+rather calls for more specific argument types.
 
 For a list of available predefined type predicates, see
 @ruser{Predefined type predicates}.
@@ -270,7 +265,7 @@ noPointAndClick =
      (parser location)
      ()
    (ly:set-option 'point-and-click #f))
-...
+@dots{}
 \noPointAndClick   % disable point and click
 @end example
 
@@ -341,37 +336,32 @@ Installed Files:
 
 @node Music function usage
 @subsection Music function usage
-Music functions may currently be used in several places.  Depending on
-where they are used, restrictions apply in order to be able to parse
-them unambiguously.  The result a music function returns must be
-compatible with the context in which it is called.
+A @q{music function} has to return an expression matching the predicate
+@code{ly:music?}.  This makes music function calls suitable as arguments
+of type @code{ly:music?} for another music function call.
+
+When using a music function call in other contexts, the context may
+cause further semantic restrictions.
 
 @itemize
 @item
-At top level in a music expression.  No restriction apply here.
+At the top level in a music expression a post-event is not accepted.
 
 @item
-As a post-event, explicitly started with a direction indicator (one of
-@code{-}, @code{^}, @w{and @code{_}}).  Note that returning a post-event
-will be acceptable for music functions called as normal music, leading
-to a result roughly equivalent to
-@example
-s 1*0-\fun
-@end example
-
-In this case, you can't use an @emph{open} music expression as the last
-argument, one that would end with a music expression able to accept
-additional postevents.
+When a music function (as opposed to an event function) returns an
+expression of type post-event, LilyPond requires one of the named
+direction indicators (@code{-}, @code{^}, @w{and @code{_}})) in order to
+properly integrate the post-event produced by the music function call
+into the surrounding expression.
 
 @item
-As a chord constituent.  The returned expression must be of
+As a chord constituent.  The returned expression must be of a
 @code{rhythmic-event} type, most likely a @code{NoteEvent}.
 @end itemize
 
 @noindent
-The special rules for trailing arguments make it possible to write
-polymorphic functions like @code{\tweak} that can be applied to
-different constructs.
+@q{Polymorphic} functions, like @code{\tweak}, can be applied to
+post-events, chord constituent and top level music expressions.
 
 @node Simple substitution functions
 @subsection Simple substitution functions
@@ -609,21 +599,49 @@ Markups are implemented as special Scheme functions which produce a
 @subsection Markup construction in Scheme
 
 @cindex defining markup commands
+@funindex \displayScheme
+
+Markup expressions are internally represented in Scheme using the
+@code{markup} macro:
 
-The @code{markup} macro builds markup expressions in Scheme while
-providing a LilyPond-like syntax.  For example,
 @example
-(markup #:column (#:line (#:bold #:italic "hello" #:raise 0.4 "world")
-                  #:larger #:line ("foo" "bar" "baz")))
+(markup @var{expr})
+@end example
+
+To see a markup expression in its Scheme form, use the
+@code{\displayScheme} command:
+
+@example
+\displayScheme
+\markup @{
+  \column @{
+    \line @{ \bold \italic "hello" \raise #0.4 "world" @}
+    \larger \line @{ foo bar baz @}
+  @}
+@}
 @end example
 
 @noindent
-is equivalent to:
+Compiling the code above will send the following to the display
+console:
+
 @example
-#@{ \markup \column @{ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
-                  \larger \line @{ foo bar baz @} @} #@}
+(markup
+  #:line
+  (#:column
+   (#:line
+    (#:bold (#:italic "hello") #:raise 0.4 "world")
+    #:larger
+    (#:line
+     (#:simple "foo" #:simple "bar" #:simple "baz")))))
 @end example
 
+To prevent the markup from printing on the page, use
+@w{@samp{\void \displayScheme @var{markup}}}.  Also, as with the
+@code{\displayMusic} command, the output of @code{\displayScheme}
+can be saved to an external file.  See
+@ref{Displaying music expressions}.
+
 @noindent
 This example demonstrates the main translation rules between regular
 LilyPond markup syntax and Scheme markup syntax.  Using @code{#@{
@@ -635,11 +653,12 @@ Scheme-only solution.
 @multitable @columnfractions .3 .3
 @item @b{LilyPond} @tab @b{Scheme}
 @item @code{\markup markup1} @tab @code{(markup markup1)}
-@item @code{\markup @{ markup1 markup2 ... @}} @tab
-        @code{(markup markup1 markup2 ... )}
+@item @code{\markup @{ markup1 markup2 @dots{} @}} @tab
+        @code{(markup markup1 markup2 @dots{} )}
 @item @code{\markup-command} @tab @code{#:markup-command}
 @item @code{\variable} @tab @code{variable}
-@item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
+@item @code{\center-column @{ @dots{} @}} @tab
+        @code{#:center-column ( @dots{} )}
 @item @code{string} @tab @code{"string"}
 @item @code{#scheme-arg} @tab @code{scheme-arg}
 @end multitable
@@ -726,11 +745,11 @@ New markup commands can be defined using the
 @code{define-markup-command} Scheme macro, at top-level.
 
 @lisp
-(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
-    (@var{arg1-type?} @var{arg2-type?} ...)
+(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} @dots{})
+    (@var{arg1-type?} @var{arg2-type?} @dots{})
     [ #:properties ((@var{property1} @var{default-value1})
-                    ...) ]
-  ..command body..)
+                    @dots{}) ]
+  @dots{}command body@dots{})
 @end lisp
 
 The arguments are
@@ -775,6 +794,26 @@ you avoid performance pitfalls by just using Scheme arguments for
 the leading arguments of markup functions that take a markup as
 their last argument.
 
+@funindex \markup
+@cindex markup macro
+@funindex interpret-markup
+Markup commands have a rather complex life cycle.  The body of a
+markup command definition is responsible for converting the
+arguments of the markup command into a stencil expression which is
+returned.  Quite often this is accomplished by calling the
+@code{interpret-markup} function on a markup expression, passing
+the @var{layout} and @var{props} arguments on to it.  Those
+arguments are usually only known at a very late stage in
+typesetting.  Markup expressions have their components assembled
+into markup expressions already when @code{\markup} in a LilyPond
+expression or the @code{markup} macro in Scheme is expanded.  The
+evaluation and typechecking of markup command arguments happens at
+the time @code{\markup}/@code{markup} are interpreted.
+
+But the actual conversion of markup expressions into stencil
+expressions by executing the markup function bodies only happens
+when @code{interpret-markup} is called on a markup expression.
+
 @node On properties
 @unnumberedsubsubsec On properties
 
@@ -849,7 +888,7 @@ padding.
             \override #'(box-padding . 0.6) \box @{ #text @}#@}))
 @end lisp
 
-or, equivalently 
+or, equivalently
 
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
@@ -949,7 +988,7 @@ follow (documentation stripped):
   (number-pair?)
   #:category graphic
   #:properties ((thickness 1))
-  "..documentation.."
+  "@dots{}documentation@dots{}"
   (let ((th (* (ly:output-def-lookup layout 'line-thickness)
                thickness))
         (x (car dest))
@@ -966,7 +1005,7 @@ documentation, and is of no use for user-defined markup commands.
 (define-markup-command (draw-double-line layout props dest)
   (number-pair?)
   #:properties ((thickness 1))
-  "..documentation.."
+  "@dots{}documentation@dots{}"
   (let ((th (* (ly:output-def-lookup layout 'line-thickness)
                thickness))
         (x (car dest))
@@ -982,8 +1021,8 @@ Then, a property for setting the gap between two lines is added, called
   (number-pair?)
   #:properties ((thickness 1)
                 (line-gap 0.6))
-  "..documentation.."
-  ...
+  "@dots{}documentation@dots{}"
+  @dots{}
 @end lisp
 
 Finally, the code for drawing two lines is added.  Two calls to
@@ -1018,12 +1057,18 @@ stencils are combined using @code{ly:stencil-add}:
 
 @node New markup list command definition
 @subsection New markup list command definition
+@funindex define-markup-list-command
+@funindex interpret-markup-list
 Markup list commands are defined with the
 @code{define-markup-list-command} Scheme macro, which is similar to the
 @code{define-markup-command} macro described in
 @ref{New markup command definition}, except that where the latter returns
 a single stencil, the former returns a list of stencils.
 
+In a similar vein, @code{interpret-markup-list} is used instead of
+@code{interpret-markup} for converting a markup list into a list
+of stencils.
+
 In the following example, a @code{\paragraph} markup list command is
 defined, which returns a list of justified lines, the first one being
 indented.  The indent width is taken from the @code{props} argument.
@@ -1090,25 +1135,137 @@ This new markup list command can be used as follows:
 
 @cindex calling code during interpreting
 @funindex \applyContext
+@funindex make-apply-context
+@funindex ly:context-property
+@funindex ly:context-set-property!
+@funindex ly:context-grob-definition
+@funindex ly:assoc-get
+@funindex ly:context-pushpop-property
+
+Contexts can be modified during interpretation with Scheme code.
+In a LilyPond code block, the syntax for this is:
 
-Contexts can be modified during interpretation with Scheme code.  The
-syntax for this is
 @example
 \applyContext @var{function}
 @end example
 
+In Scheme code, the syntax is:
+
+@example
+(make-apply-context @var{function})
+@end example
+
 @code{@var{function}} should be a Scheme function that takes a
 single argument: the context in which the @code{\applyContext}
-command is being called.  The following code will print the
-current bar number on the standard output during the compile:
+command is being called.  The function can access as well as
+override/set grob properties and context properties.  Any actions
+taken by the function that depend on the state of the context are
+limited to the state of the context @emph{when the function is
+called}.  Also, changes effected by a call to @code{\applyContext}
+remain in effect until they are directly modified again, or
+reverted, even if the initial conditions that they depended on
+have changed.
+
+The following scheme functions are useful when using
+@code{\applyContext}:
 
-@example
+@table @code
+@item ly:context-property
+look up a context property value
+
+@item ly:context-set-property!
+set a context property
+
+@item ly:context-grob-definition
+@itemx ly:assoc-get
+look up a grob property value
+
+@item ly:context-pushpop-property
+do a @code{\temporary@tie{}\override}
+or a @code{\revert} on a grob property
+@end table
+
+
+The following example looks up the current @code{fontSize} value, and
+then doubles it:
+
+@lilypond[quote,verbatim]
+doubleFontSize =
 \applyContext
-  #(lambda (x)
-    (format #t "\nWe were called in barnumber ~a.\n"
-     (ly:context-property x 'currentBarNumber)))
-@end example
+  #(lambda (context)
+     (let ((fontSize (ly:context-property context 'fontSize)))
+       (ly:context-set-property! context 'fontSize (+ fontSize 6))))
+
+{
+  \set fontSize = -3
+  b'4
+  \doubleFontSize
+  b'
+}
+@end lilypond
+
+
+The following example looks up the current colors of the
+@code{NoteHead}, @code{Stem}, and @code{Beam} grobs, and then changes
+each to a less saturated shade.
+
+@lilypond[quote,verbatim]
+desaturate =
+\applyContext
+  #(lambda (context)
+     (define (desaturate-grob grob)
+       (let* ((grob-def (ly:context-grob-definition context grob))
+              (color (ly:assoc-get 'color grob-def black))
+              (new-color (map (lambda (x) (min 1 (/ (1+ x) 2))) color)))
+         (ly:context-pushpop-property context grob 'color new-color)))
+     (for-each desaturate-grob '(NoteHead Stem Beam)))
+
+\relative g' {
+  \time 3/4
+  g8[ g] \desaturate g[ g] \desaturate g[ g]
+  \override NoteHead.color = #darkred
+  \override Stem.color = #darkred
+  \override Beam.color = #darkred
+  g[ g] \desaturate g[ g] \desaturate g[ g]
+}
+@end lilypond
+
 
+This also could be implemented as a music function, in order to
+restrict the modifications to a single music block.  Notice how
+@code{ly:context-pushpop-property} is used both as a
+@code{\temporary@tie{}\override} and as a @code{\revert}:
+
+@lilypond[quote,verbatim]
+desaturate =
+#(define-music-function
+   (parser location music) (ly:music?)
+   #{
+     \applyContext
+     #(lambda (context)
+        (define (desaturate-grob grob)
+          (let* ((grob-def (ly:context-grob-definition context grob))
+                 (color (ly:assoc-get 'color grob-def black))
+                 (new-color (map (lambda (x) (min 1 (/ (1+ x) 2))) color)))
+            (ly:context-pushpop-property context grob 'color new-color)))
+        (for-each desaturate-grob '(NoteHead Stem Beam)))
+     #music
+     \applyContext
+     #(lambda (context)
+        (define (revert-color grob)
+          (ly:context-pushpop-property context grob 'color))
+        (for-each revert-color '(NoteHead Stem Beam)))
+   #})
+
+\relative g' {
+  \override NoteHead.color = #darkblue
+  \override Stem.color = #darkblue
+  \override Beam.color = #darkblue
+  g8 a b c
+  \desaturate { d c b a }
+  g b d b g2
+}
+@end lilypond
 
 
 @node Running a function on all layout objects
@@ -1205,38 +1362,19 @@ Properties that typically use callbacks include
 
 The procedure always takes a single argument, being the grob.
 
-If routines with multiple arguments must be called, the current grob
-can be inserted with a grob closure.  Here is a setting from
-@code{AccidentalSuggestion},
+That procedure may access the usual value of the property, by first
+calling the function that is the usual callback for that property, which
+can by found in the Internals Reference or the file 'define-grobs.scm':
 
 @example
-`(X-offset .
-  ,(ly:make-simple-closure
-    `(,+
-        ,(ly:make-simple-closure
-           (list ly:self-alignment-interface::centered-on-x-parent))
-      ,(ly:make-simple-closure
-           (list ly:self-alignment-interface::x-aligned-on-self)))))
-@end example
-
-@noindent
-In this example, both @code{ly:self-alignment-interface::x-aligned-on-self} and
-@code{ly:self-alignment-interface::centered-on-x-parent} are called
-with the grob as argument.  The results are added with the @code{+}
-function.  To ensure that this addition is properly executed, the whole
-thing is enclosed in @code{ly:make-simple-closure}.
-
-In fact, using a single procedure as property value is equivalent to
-
-@example
-(ly:make-simple-closure (ly:make-simple-closure (list @var{proc})))
+\relative c'' @{
+  \override Flag #'X-offset = #(lambda (flag)
+    (let ((default (ly:flag::calc-x-offset flag)))
+      (* default 4.0)))
+  c4. d8 a4. g8
+@}
 @end example
 
-@noindent
-The inner @code{ly:make-simple-closure} supplies the grob as argument
-to @var{proc}, the outer ensures that result of the function is
-returned, rather than the @code{simple-closure} object.
-
 From within a callback, the easiest method for evaluating a markup is
 to use grob-interpret-markup.  For example:
 
@@ -1245,19 +1383,20 @@ my-callback = #(lambda (grob)
                  (grob-interpret-markup grob (markup "foo")))
 @end example
 
-@node Inline Scheme code
-@section Inline Scheme code
+@ignore
 
-TODO: the example for this section is ill-chosen since
-@example
-F = -\tweak font-size #-3 -\flageolet
-@end example
-(note the @samp{-} marking it as a post event) will actually work fine
-for the stated purpose.  Until this section gets a rewrite, let's
-pretend we don't know.
+@n ode Inline Scheme code
+@s ection Inline Scheme code
+
+TODO: after this section had been written, LilyPond has improved
+to the point that finding a @emph{simple} example where one would
+@emph{have} to revert to Scheme has become rather hard.
+
+Until this section gets a rewrite, let's pretend we don't know.
 
 The main disadvantage of @code{\tweak} is its syntactical
-inflexibility.  For example, the following produces a syntax error.
+inflexibility.  For example, the following produces a syntax error
+(or rather, it did so at some point in the past).
 
 @example
 F = \tweak font-size #-3 -\flageolet
@@ -1294,6 +1433,7 @@ font size is prepended to the property list with the
 written back with @code{set!}.  The last element of the
 @code{let} block is the return value, @code{m} itself.
 
+@end ignore
 
 
 @node Difficult tweaks
@@ -1358,7 +1498,7 @@ of the broken tie is repositioned.
   \override Tie.after-line-breaking =
   #my-callback
   c1 ~ \break
-  c2 ~ c
+  c2 ~ 2
 }
 @end lilypond