X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Documentation%2Fextending%2Fprogramming-interface.itely;h=46d7fd512fa08490edcbfe5b993aa960a07c49ad;hb=446dc1f3ac9bfff6bfee31de929698b0425da6fe;hp=1e8e92dbbd8f084ea6f6e9684dc1049d4a98a67c;hpb=dc71d81b8b6846a01985d3c9eec422607bd076c8;p=lilypond.git diff --git a/Documentation/extending/programming-interface.itely b/Documentation/extending/programming-interface.itely index 1e8e92dbbd..46d7fd512f 100644 --- a/Documentation/extending/programming-interface.itely +++ b/Documentation/extending/programming-interface.itely @@ -8,7 +8,7 @@ Guide, node Updating translation committishes.. @end ignore -@c \version "2.14.0" +@c \version "2.15.18" @node Interfaces for programmers @chapter Interfaces for programmers @@ -37,38 +37,16 @@ Lilypond code blocks look like #@{ @var{Lilypond code} #@} @end example They can be used anywhere where you can write Scheme code: the Scheme -reader actually is changed for accommodating LilyPond code blocks. When -the LilyPond code block is being read, it is parsed superficially and -replaced by a call to the LilyPond @code{parser} which is executed at -runtime to interpret the LilyPond code block. +reader actually is changed for accommodating LilyPond code blocks and +can deal with embedded Scheme expressions starting with @code{$} +and@w{ }@code{#}. -The point of the superficial parsing is the interpretation of @code{$} -signs which can be used for splicing in expressions from the surrounding -lexical Scheme context (like @code{let} variables and function -parameters). @code{$} can be used in the following ways: - -@table @code -@item $$ -just passes a single @code{$} to the LilyPond parser. -@item $@var{form} -will evaluate the Scheme form at runtime and splice its value as an -identifier @code{\form} into the LilyPond parser. Depending on the -value type, it may be interpreted as several different syntactic -entities. -@item #$@var{form} -will evaluate the Scheme form at runtime and splice its value as a -Scheme expression into the LilyPond parser. -@item #@var{form} -Forms in Scheme expressions started with @code{#} are read and parsed -recursively for @code{$} signs. Those are treated as follows: -@item #@dots{}$@var{variable} -splices the value of the variable into the surrounding expression. -@item #@dots{}($ @var{form} @dots{}) -splices the value of the form into the surrounding expression. As -opposed to a LilyPond level @code{$@var{form}}, you need to separate the -form with a blank, making @code{$} be recognizable as a separate Scheme -symbol. -@end table +It extracts the Lilypond code block and generates a call to the +LilyPond @code{parser} which is executed at runtime to interpret the +LilyPond code block. Any embedded Scheme expression is executed in +the lexical environment of the Lilypond code block, so you have access +to local variables and function parameters at the point the Lilypond +code block is written. A LilyPond code block may contain anything that you can use on the right side of an assignment. In addition, an empty LilyPond block corresponds @@ -138,29 +116,49 @@ are copied while setting @code{origin} to the @code{location} parameter. used as the return value of the scheme function. It may contain LilyPond code blocks enclosed in hashed braces (@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), like described in @ref{Lilypond -code blocks}. 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)}}). If your function returns a music expression, it is cloned and -given the correct @code{origin}. +code blocks}. 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)}}). Where normal Scheme expressions using @code{#} don't do the +trick, you might need to revert to immediate Scheme expressions using +@code{$}, for example as @samp{$music}. + +If your function returns a music expression, it is given a useful value +of @code{origin}. @end multitable @noindent -Some type predicates are specially recognized by the parser and will -make the parser look for the respective arguments in LilyPond syntax -rather than in Scheme syntax. Currently these are @code{ly:music?}, -@code{markup?}, @code{ly:pitch?}, and @code{ly:duration?}. - -If you really want to input one of the special items as a Scheme rather -than a LilyPond expression, you may write them as a Scheme expression -that calls @code{ly:export} at its outermost level. - -Other type predicates, including user-defined ones, will make the -respective argument only be accepted as a Scheme expression, usually -introduced with @code{#} or as the result of calling a scheme function -itself. - -For a list of available type predicates, see +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 +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 +the result of calling a scheme function), but Lilypond will also convert +a number of Lilypond constructs into Scheme before actually checking the +predicate on them. Currently, those include music, postevents, simple +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 +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. + +For a list of available predefined type predicates, see @ruser{Predefined type predicates}. @seealso @@ -179,40 +177,55 @@ Installed Files: Scheme functions can be called pretty much anywhere where a Scheme expression starting with @code{#} can be written. You call a scheme function by writing its name preceded by @code{\}, followed by its -arguments. The last argument can't be an optional argument. If there -are several optional arguments in a row, they are filled with values -left to right. Once an optional argument can't match input, it and all -immediately following optional arguments are replaced with their default -values, and the matching continues with the next non-optional argument. +arguments. Once an optional argument predicate does not match an +argument, Lilypond skips this and all following optional arguments, +replacing them with their specified default, and @q{backs up} the +argument that did not match to the place of the next mandatory argument. +Since the backed up argument needs to go somewhere, optional arguments +are not actually considered optional unless followed by a mandatory +argument. + +There is one exception: if you write @code{\default} in the place of an +optional argument, this and all following optional arguments are skipped +and replaced by their default. This works even when no mandatory +argument follows since @code{\default} does not need to get backed up. +The @code{mark} and @code{key} commands make use of that trick to +provide their default behavior when just followed by @code{\default}. Apart from places where a Scheme value is required, there are a few -places where @code{#} expressions are accepted and evaluated for their -side effects but otherwise ignored. Mostly those are the places where -an assignment would be acceptable as well. - -There are a few special places where an argument matching -@code{ly:music?} has to be either a music identifier or a music -expression enclosed in @code{@{}@dots{}@code{@}} or -@code{<<}@dots{}@code{>>} explicitly, so that possibly following -optional durations or postevents can't be confused with additional -arguments. One obvious place is before a @code{ly:duration?} -predicate. Another is as the last argument of a scheme function when it -is used in a place where such optional parts could be considered either -part of the music argument or not. - -In those rare cases, you have to delimit your music arguments -appropriately to spare LilyPond from getting confused. +places where @code{#} expressions are currently accepted and evaluated +for their side effects but otherwise ignored. Mostly those are the +places where an assignment would be acceptable as well. + +Since it is a bad idea to return values that can be misinterpreted in +some context, you should use normal scheme functions only for those +cases where you always return a useful value, and use void scheme +functions (@pxref{Void scheme functions}) otherwise. @node Void scheme functions @subsection Void scheme functions - -Sometimes a function is only executed for its side effects. In that -case, using a scheme function means that its value will not usually be -considered: +@funindex define-void-function +@funindex \void + +Sometimes a procedure is executed in order to perform an action rather +than return a value. Some programming languages (like C and Scheme) use +functions for either concept and just discard the returned value +(usually by allowing any expression to act as statement, ignoring the +result). This is clever but error-prone: most C compilers nowadays +offer warnings for various non-``void'' expressions being discarded. +For many functions executing an action, the Scheme standards declare the +return value to be unspecified. Lilypond's Scheme interpreter Guile has +a unique value @code{*unspecified*} that it usually (such when using +@code{set!} directly on a variable) but unfortunately not consistently +returns in such cases. + +Defining a Lilypond function with @code{define-void-function} makes +sure that this special value (the only value satisfying the predicate +@code{void?}) will be returned. @example noPointAndClick = -#(define-scheme-function +#(define-void-function (parser location) () (ly:set-option 'point-and-click #f)) @@ -220,6 +233,18 @@ noPointAndClick = \noPointAndClick % disable point and click @end example +If you want to evaluate an expression only for its side-effect and +don't want any value it may return interpreted, you can do so by +prefixing it with @code{\void}: + +@example +\void #(hashq-set! some-table some-key some-value) +@end example + +That way, you can be sure that Lilypond will not assign meaning to the +returned value regardless of where it encounters it. This will also +work for music functions such as @code{\displayMusic}. + @node Music functions @section Music functions @@ -275,33 +300,31 @@ Installed Files: @node Music function usage @subsection Music function usage -Music functions may currently be used in three places. Depending on +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. @itemize @item -At top level in a music expression. There are no special restrictions -on the argument list. +At top level in a music expression. No restriction apply here. @item As a post-event, explicitly started with a direction indicator (one of -@code{-}, @code{^}, @w{and @code{_}}). All trailing arguments of the -music function with the predicate @code{ly:music?} will get parsed also -as post-events (if the last argument is a scheme function, this will -hold for trailing @code{ly:music?} arguments of the scheme function -instead). Note that returning a post-event will be acceptable for music -functions called as normal music, leading to a result roughly equivalent -to +@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. + @item -As a chord constituent. All trailing arguments of the music function -with the predicate @code{ly:music?} will get parsed also as chord -constituents. +As a chord constituent. The returned expression must be of +@code{rhythmic-event} type, most likely a @code{NoteEvent}. @end itemize @noindent @@ -336,7 +359,7 @@ manualBeam = (parser location beg-end) (pair?) #@{ - \once \override Beam #'positions = $beg-end + \once \override Beam #'positions = #beg-end #@}) \relative c' @{ @@ -355,7 +378,7 @@ manualBeam = (parser location beg end) (number? number?) #{ - \once \override Beam #'positions = $(cons beg end) + \once \override Beam #'positions = #(cons beg end) #}) \relative c' { @@ -376,9 +399,9 @@ AltOn = (parser location mag) (number?) #{ - \override Stem #'length = $(* 7.0 mag) + \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 = { @@ -401,9 +424,9 @@ withAlt = (parser location mag music) (number? ly:music?) #{ - \override Stem #'length = $(* 7.0 mag) + \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 @@ -450,12 +473,12 @@ lilypond -d display-bar-numbers FILENAME.ly @node Void music functions @subsection Void music functions -A music function must return a music expression. If you want to execute -a function only for its side effect, it might make more sense to use a -scheme function instead. But there may be cases where you sometimes -want to produce a music expression, and sometimes not (like in the -previous example). Returning a @code{void} music expression via -@code{#@{ #@}} will do that. +A music function must return a music expression. If you want to +execute a function only for its side effect, you should use +@code{define-void-function}. But there may be cases where you +sometimes want to produce a music expression, and sometimes not (like +in the previous example). Returning a @code{void} music expression +via @code{#@{ #@}} will achieve that. @node Event functions @section Event functions @@ -468,7 +491,7 @@ the syntax of constructs you want to replace. For example, if you want to write dynamics commands, those are usually attached without direction indicator, like @code{c'\pp}. Here is a way to write arbitrary dynamics: -@lilypond[quote,verbatim,raggedright] +@lilypond[quote,verbatim,ragged-right] dyn=#(define-event-function (parser location arg) (markup?) (make-dynamic-script arg)) \relative c' { c\dyn pfsss } @@ -775,8 +798,8 @@ now as follows: (box-padding 0.6)) "Draw a double box around text." (interpret-markup layout props - #@{\markup \override #`(box-padding . ,$inter-box-padding) \box - \override #`(box-padding . ,$box-padding) \box + #@{\markup \override #`(box-padding . ,inter-box-padding) \box + \override #`(box-padding . ,box-padding) \box @{ $text @} #@})) @end lisp @@ -811,8 +834,8 @@ customized: (box-padding 0.6)) "Draw a double box around text." (interpret-markup layout props - #{\markup \override #`(box-padding . ,$inter-box-padding) \box - \override #`(box-padding . ,$box-padding) \box + #{\markup \override #`(box-padding . ,inter-box-padding) \box + \override #`(box-padding . ,box-padding) \box { $text } #})) \markup \double-box A @@ -919,7 +942,7 @@ indented. The indent width is taken from the @code{props} argument. #(define-markup-list-command (paragraph layout props args) (markup-list?) #:properties ((par-indent 2)) (interpret-markup-list layout props - #@{\markuplines \justified-lines @{ \hspace #$par-indent $args @} #@})) + #@{\markuplist \justified-lines @{ \hspace #par-indent $args @} #@})) @end example @@ -948,7 +971,7 @@ interpreted using the @code{interpret-markup-list} function. This new markup list command can be used as follows: @example -\markuplines @{ +\markuplist @{ \paragraph @{ The art of music typography is called \italic @{(plate) engraving.@} The term derives from the traditional process of music printing. @@ -1128,6 +1151,14 @@ my-callback = #(lambda (grob) @node Inline Scheme code @section Inline Scheme code +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. + The main disadvantage of @code{\tweak} is its syntactical inflexibility. For example, the following produces a syntax error. @@ -1140,10 +1171,6 @@ F = \tweak #'font-size #-3 -\flageolet @end example @noindent -In other words, @code{\tweak} doesn't behave like an articulation -regarding the syntax; in particular, it can't be attached with -@code{^} and @code{_}. - Using Scheme, this problem can be avoided. The route to the result is given in @ref{Adding articulation to notes (example)}, especially how to use @code{\displayMusic} as a helping guide.