@end ignore
@item
-New command-line option @code{--loglevel=LEVEL} to control how much output
+New command-line option @option{--loglevel=@var{level}} to control how much output
LilyPond creates. Possible values are ERROR, WARN, BASIC_PROGRESS, PROGRESS, DEBUG.
@item
The Contributor's Guide as a whole is still a work in progress,
but some chapters are much more complete than others. Chapters
which are @qq{almost finished} should not have major changes
-without a discussion on @code{-devel}; in other chapters, a
+without a discussion on @w{@code{-devel}}; in other chapters, a
disorganized @qq{wiki-style dump} of information is encouraged.
Do not change (other than spelling mistakes) without discussion:
@item
Frog Meister: is responsible for code patches from (relatively)
inexperienced contributors. Keeps track of patches, does initial
-reviewing of those patches, sends them to @code{-devel} when
+reviewing of those patches, sends them to @w{@code{-devel}} when
they've had some initial review on the Frog list, pesters the
-@code{-devel} community into actually reviewing said patches, and
+@w{@code{-devel}} community into actually reviewing said patches, and
finally pushes the patches once they're accepted. This person is
@emph{not} responsible for training new programmers, because that
would be far too much work -- he job is @qq{only} to guide
@end smallexample
I don't currently understand the @code{ifeq}, since @code{$(out)}
-is empty at this point, but the line starting @code{-$(INSTALL)}
+is empty at this point, but the line starting @w{@code{-$(INSTALL)}}
translates to:
@example
@@subsection @@code@{Foo@} Bar
@end example
+@item
+With the exception of @code{@@} commands, the section name must
+match the node name exactly.
+
+@item
+No commas may be used in the node names.
+
@item
If a heading is desired without creating a @code{@@node}, please use
the following:
\paper @{
indent = 0\mm
line-width = 160\mm - 2.0 * 0.4\in
- ragged-right = ##t
- force-assignment = #""
line-width = #(- line-width (* mm 3.000000))
@}
@item
Download the latest snippet tarball, extract it, and run
@code{convert-ly} on all files using the command-line option
-@code{--to=VERSION} to ensure snippets are updated to the
+@option{--to=@var{version}} to ensure snippets are updated to the
correct stable version.
@item
This command will search all the contents of the directory subdirectory/
and display every line in any of the files that contains
-functionName. The @code{-i} option makes @command{grep} ignore
+functionName. The @option{-i} option makes @command{grep} ignore
case -- this can be very useful if you are not yet familiar with
our capitalization conventions.
@item WARN: Only error messages and warnings
@item BASIC_PROGRESS: Warnings, errors and basic progress (success, etc.)
@item PROGRESS: Warnings, errors and full progress messages
-@item INFO: Warnings, errors, progress and more detailed information
+@item INFO: Warnings, errors, progress and more detailed information (default)
@item DEBUG: All messages, including vull debug messages (very verbose!)
@end itemize
The loglevel can either be set with the environment variable
-@code{LILYPOND_LOGLEVEL} or on the command line with the @code{--loglevel=...}
+@code{LILYPOND_LOGLEVEL} or on the command line with the @option{--loglevel=...}
option.
@unnumberedsubsec Functions for debug and log output
@end itemize
There are also Scheme functions to access all of these logging functions from
-scheme. In addition, the Grob class contains some convenience wrappers for
+scheme. In addition, the Grob class contains some convenience wrappers for
even easier access to these functions.
The message and debug functions in @code{warn.hh} also have an optional
argument @code{newline}, which specifies whether the message should always
-start on a new line or continue a previous message.
+start on a new line or continue a previous message.
By default, @code{progress_indication} does NOT start on a new line, but rather
-continue the previous output. All other functions by default start their
-output on a new line.
+continue the previous output. They also do not have a particular input
+position associated, so there are no progress functions in the Input class.
+All other functions by default start their output on a new line.
-@unnumberedsubsec All logging functions at a glance
+The error functions come in three different flavors: fatal error messages,
+programming error messages and normal error messages. Errors written
+by the @code{error ()} function will cause LilyPond to exit immediately,
+errors by @code{Input::error ()} will continue the compilation, but
+return a non-zero return value of the lilypond call (i.e. indicate an
+unsuccessful program execution). All other errors will be printed on the
+console, but not exit LilyPond or indicate an unsuccessful return code.
+Their only differences to a warnings are the displayed text and that
+they will be shown with loglevel @code{ERROR}.
+
+If the Scheme option @code{warning-as-error} is set, any warning will be
+treated as if @code{Input::error} was called.
-Currently, there are no particular message functions for the INFO loglevel,
-so it is basically identical to PROGRESS.
+@unnumberedsubsec All logging functions at a glance
@multitable @columnfractions 0.16 0.42 0.42
@headitem
@tab @code{Input::error (msg)}, @code{Input::programming_error (msg)}
@item WARN
-@tab @code{warning (msg)} @c WARN
-@tab @code{Input::warning (msg)} @c WARN
+@tab @code{warning (msg)}
+@tab @code{Input::warning (msg)}
@item BASIC
@tab @code{successful (msg)}
@tab -
@item PROGRESS
-@tab @code{progress_indication (msg)}, @code{message (msg)}
+@tab @code{progress_indication (msg)}
+@tab -
+
+@item INFO
+@tab @code{message (msg)}
@tab @code{Input::message (msg)}
@item DEBUG
@item PROGRESS
@tab -
+@tab -
+
+@item INFO
+@tab -
@tab @code{(ly:music-message music msg)}
@item DEBUG
@tab -
@item PROGRESS
-@tab (ly:progress msg args), (ly:message msg args)
+@tab @code{(ly:progress msg args)}
+@tab -
+
+@item INFO
+@tab @code{(ly:message msg args)}
@tab @code{(ly:input-message input msg args)}
@item DEBUG
@tab @code{(ly:debug msg args)}
@tab -
-
@end multitable
In order for the Graphviz tool to work, config.make must be modified.
It is probably a good idea to first save a copy of config.make under
a different name. Then, edit config.make by removing every occurrence
-of @code{-DNDEBUG}.
+of @option{-DNDEBUG}.
@item Rebuilding LilyPond
The pdf file can then be viewed with any pdf viewer.
-When compiled without @code{-DNDEBUG}, lilypond may run slower
+When compiled without @option{-DNDEBUG}, lilypond may run slower
than normal. The original configuration can be restored by either
renaming the saved copy of @code{config.make} or rerunning
@code{configure}. Then rebuild lilypond with
global and repository-specific options.
To configure settings that affect all repositories, use the
-@command{--global} command line option. For example, the first
+@option{--global} command line option. For example, the first
two options that you should always set are your @var{name} and
@var{email}, since Git needs these to keep track of commit
authors:
@end example
Using the @command{git@tie{}config} command @emph{without} the
-@command{--global} option configures repository-specific settings,
+@option{--global} option configures repository-specific settings,
which are stored in the file @file{.git/config}. This file is
created when a repository is initialized (using
@command{git@tie{}init}), and by default contains these lines:
@end example
If you're tracking the remote @code{master} branch, you should add
-the @code{-r} option (short for @code{--rebase}) to keep commits
+the @option{-r} option (short for @option{--rebase}) to keep commits
on your local branch current:
@example
@end example
If you don't edit translated documentation and don't want to type
-@code{-r} every time, configure the master branch to rebase by
+@option{-r} every time, configure the master branch to rebase by
default with this command:
@example
@end example
Git will ask you for confirmation if it sees that data would be
-lost by deleting the branch. Use @code{-D} instead of @code{-d}
+lost by deleting the branch. Use @option{-D} instead of @option{-d}
to bypass this. Note that you cannot delete a branch if it is
currently checked out.
@end example
@noindent
-The @code{-a} is short for @code{--all} which includes modified
+The @option{-a} is short for @option{--all} which includes modified
and deleted files, but only those newly created files that have
previously been added.
alternate method here.
You should always run @command{git@tie{}pull@tie{}-r} (translators
-should leave off the @code{-r}) before doing this to ensure that
+should leave off the @option{-r}) before doing this to ensure that
your patches are as current as possible.
Once you have made one or more commits in your local repository,
@item
-Generate an SSH @q{dsa} key pair. Enter the following at the
+Generate an SSH @q{rsa} key pair. Enter the following at the
command prompt:
@example
-ssh-keygen -t dsa
+ssh-keygen -t rsa
@end example
When prompted for a location to save the key, press <ENTER> to
-accept the default location (@file{~/.ssh/id_dsa}).
+accept the default location (@file{~/.ssh/id_rsa}).
Next you are asked to enter an optional passphrase. On most
systems, if you use a passphrase, you will likely be prompted for
You can change/enable/disable your passphrase at any time with:
@example
-ssh-keygen -f ~/.ssh/id_dsa -p
+ssh-keygen -f ~/.ssh/id_rsa -p
@end example
Note that the GNOME desktop has a feature which stores your
@end example
After setting up your passphrase, your private key is saved as
-@file{~/.ssh/id_dsa} and your public key is saved as
-@file{~/.ssh/id_dsa.pub}.
+@file{~/.ssh/id_rsa} and your public key is saved as
+@file{~/.ssh/id_rsa.pub}.
@item
-Register your public SSH @q{dsa} key with Savannah. From the
+Register your public SSH @q{rsa} key with Savannah. From the
@qq{My Account Configuration} page, click on @qq{Edit SSH Keys},
-then paste the contents of your @file{~/.ssh/id_dsa.pub} file into
+then paste the contents of your @file{~/.ssh/id_rsa.pub} file into
one of the @qq{Authorized keys} text fields, and click
@qq{Update}.
@end example
@noindent
-where @var{user} is your username on Savannah.
+replacing @var{user} with your Savannah username.
@item
@noindent
Then @code{git@tie{}push} should work as before. For more
details, consult the @code{git@tie{}push} man page.
-@end enumerate
+@item
+Repeat the steps from generating an RSA key through to testing
+your commit access, for each machine from which you will be
+making commits, or you may simply copy the files from your
+local @file{~/.ssh} folder to the same folder on the other
+machine.
+
+@end enumerate
+
@subsubheading Technical details
@itemize
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
/***********************************************************/
@media print {
- /* Hide the sidebar: */
- body { padding-left: 0; }
- #tocframe { display: none; }
+ /* Hide the sidebar and make the main contents take up the full width */
+ div#main { position: static; overflow: visible; left: 0; }
+ div#tocframe { display: none; }
+ /* Also don't show the navigation toolbars between all sections */
.nav_table { display: none; }
}
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
@item Numbers
Numbers are entered in the standard fashion,
-@code{1} is the (integer) number one, while @code{-1.5} is a
+@code{1} is the (integer) number one, while @w{@code{-1.5}} is a
floating point number (a non-integer number).
@item Strings
@subsection LilyPond Scheme syntax
The Guile interpreter is part of LilyPond, which means that
-Scheme can be included in LilyPond input files. The hash mark @code{#}
+Scheme can be included in LilyPond input files. The hash mark@tie{}@code{#}
is used to tell the LilyPond parser that the next value is a Scheme
value.
@end example
For the rest of this section, we will assume that the data is entered
-in a music file, so we add @code{#}s at the beginning of each Scheme
+in a music file, so we add@tie{}@code{#}s at the beginning of each Scheme
expression.
All of the top-level Scheme expressions in a LilyPond input file can
@knownissues
Mixing Scheme and LilyPond variables is not possible with the
-@code{--safe} option.
+@option{--safe} option.
@node Object properties
</div>
@end html
@iftex
-@image{examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
</div>
@end html
@iftex
-@image{examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
@item Valentin Villenave:
LSR editor and Bug squad member
+@item Jan Warchoł:
+happy nitpicker
+
@end itemize
@end macro
@c use commas not colons
-Karin Hoethker,
-Jan Warchoł
+Karin Hoethker
@c no comma for last entry
By default, `@command{make@tie{}install}' will install all the
files in @file{/usr/local/bin}, @file{/usr/local/lib} etc. You
can specify an installation prefix other than @file{/usr/local}
-using `@code{--prefix}', for instance `@code{--prefix=$HOME}'.
+using `@option{--prefix}', for instance `@option{--prefix=$HOME}'.
@end quotation
A typical installation prefix is @file{$HOME/usr}:
If you want to build multiple versions of LilyPond with different
configuration settings, you can use the
-@code{--enable-config=@var{CONF}} option of @command{configure}.
-You should use @code{make@tie{}conf=@var{CONF}} to generate the
-output in @file{out-@var{CONF}}. For example, suppose you want to
+@option{--enable-config=@var{conf}} option of @command{configure}.
+You should use @code{make@tie{}conf=@var{conf}} to generate the
+output in @file{out-@var{conf}}. For example, suppose you want to
build with and without profiling, then use the following for the
normal build
\version "2.14.0"
-\header{
+
+\header {
texidoc="
-Note head shapes may be set from several choices.
-The stem endings should be adjusted according to the note head.
+Note head shapes may be set from several choices.
+The stem endings should be adjusted according to the note head.
If you want different note head styles on one stem,
you must create a special context.
Harmonic notes have a different shape and different
-dimensions.
+dimensions.
"
}
\layout {
indent = 0.0
ragged-right = ##t
+
+ \context {
+ \Score
+ \remove "Bar_number_engraver"
+ }
}
pattern = <<
\new Voice {
- \override Stem #'direction = #UP
- e'4 e'2. e'1 e'\breve*1/2 e'\longa*1/4
+ \override Stem #'direction = #UP
+ e'4 e'2. e'1 e'\breve*1/2 e'\longa*1/4 \bar "||"
}
\new Voice {
- \override Stem #'direction = #DOWN
- a4 a2. a1 a\breve*1/2 a\longa*1/4
+ \override Stem #'direction = #DOWN
+ a4 a2. a1 a\breve*1/2 a\longa*1/4 \bar "||"
}
>>
s1*0^\markup { "slash" }
\pattern
}
-
-
-
\version "2.14.0"
-% yes, I know this is a mess. But I'm not going to fuss with
-% it one day before I leave. -gp
-
% this chart is used in the manual too.
\header {
- texidoc ="@cindex Percussion notes
+ texidoc ="@cindex Percussion notes
This chart shows all percussion and drum notes."
}
myBreak = { \bar " " \break }
\score {
- \new DrumStaff \with {
- \remove "Time_signature_engraver"
-} \context DrumVoice {
+ \new DrumStaff \with {
+ \remove "Time_signature_engraver"
+ } \context DrumVoice {
%% this stuff set up nice || bar lines to divide percussion notes
%% into related fields, but it should be placed in the actual
%% music, not as a separate voice. -gp
%{
-barlines = {
-\repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||"
-\repeat "unfold" 2 { s 1 \bar" " s 1 \bar" " s 1 \bar "||" }
-\repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||"
-\repeat "unfold" 7 {s 1 \bar" " } s 1 \bar "||"
-s 1 \bar" " s 1 \bar "||"
-\repeat "unfold" 2 { \repeat "unfold" 5 {s 1 \bar" " } s 1 \bar "||" }
-\repeat "unfold" 2 { s 1 \bar" " s 1 \bar "||" }
-\repeat "unfold" 2 {s 1 \bar" " } s 1 \bar "||"
-\repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||"
-s 1 \bar" " s 1 \bar "||"
-\repeat "unfold" 3 {s 1 \bar" " } s 1 \bar "||"
-\repeat "unfold" 2 {s 1 \bar" " } s 1 \bar "||"
-\repeat "unfold" 3 {\repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||" }
-}
+ barlines = {
+ \repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||"
+ \repeat "unfold" 2 { s 1 \bar" " s 1 \bar" " s 1 \bar "||" }
+ \repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||"
+ \repeat "unfold" 7 {s 1 \bar" " } s 1 \bar "||"
+ s 1 \bar" " s 1 \bar "||"
+ \repeat "unfold" 2 { \repeat "unfold" 5 {s 1 \bar" " } s 1 \bar "||" }
+ \repeat "unfold" 2 { s 1 \bar" " s 1 \bar "||" }
+ \repeat "unfold" 2 {s 1 \bar" " } s 1 \bar "||"
+ \repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||"
+ s 1 \bar" " s 1 \bar "||"
+ \repeat "unfold" 3 {s 1 \bar" " } s 1 \bar "||"
+ \repeat "unfold" 2 {s 1 \bar" " } s 1 \bar "||"
+ \repeat "unfold" 3 {\repeat "unfold" 4 {s 1 \bar" " } s 1 \bar "||" }
+ }
%}
-\drummode {
-\textLengthOn
-\cadenzaOn
-bda1 ^"acousticbassdrum: bda" bd ^"bassdrum: bd" sn ^"snare: sn" sne ^"electricsnare: sne" sna ^"acousticsnare: sna" \myBreak
-tomfl ^"lowfloortom: tomfl" tomfh ^"highfloortom: tomfh" toml ^"lowtom: toml" tomh ^"hightom: tomh"
-tomml ^"lowmidtom: tomml" tommh ^"himidtom: tommh" \myBreak
-hhc ^"closedhihat: hhc" hh ^"hihat: hh" hhp ^"pedalhihat: hhp" hho ^"openhihat: hho" hhho ^"halfopenhihat: hhho" \myBreak
-cymca ^"crashcymbala: cymca" cymc ^"crashcymbal: cymc" cymra ^"ridecymbala: cymra" cymr ^"ridecymbal: cymr" \myBreak cymch ^"chinesecymbal: cymch" cyms ^"splashcymbal: cyms"
-cymcb ^"crashcymbalb: cymcb" cymrb ^"ridecymbalb: cymrb"
-rb ^"ridebell: rb" cb ^"cowbell: cb" \myBreak
-bohm ^"mutehibongo: bohm" boh ^"hibongo: boh" boho ^"openhibongo: boho" bolm ^"mutelobongo: bolm" bol ^"lobongo: bol" bolo ^"openlobongo: bolo"\myBreak
-cghm ^"mutehiconga: cghm" cglm ^"muteloconga: cglm" cgho ^"openhiconga: cgho" cgh ^"hiconga: cgh" cglo ^"openloconga: cglo" cgl ^"loconga: cgl" \myBreak
-timh ^"hitimbale: timh" timl ^"lotimbale: timl"
-agh ^"hiagogo: agh" agl ^"loagogo: agl" \myBreak
-ssh ^"hisidestick: ssh" ss ^"sidestick: ss" ssl ^"losidestick: ssl" \myBreak
-guis ^"shortguiro: guis" guil ^"longguiro: guil" gui ^"guiro: gui" cab ^"cabasa: cab" mar ^"maracas: mar" \myBreak
-whs ^"shortwhistle: whs" whl ^"longwhistle: whl" \myBreak
-hc ^"handclap: hc" tamb ^"tambourine: tamb" vibs ^"vibraslap: vibs" tt ^"tamtam: tt" \myBreak
-cl ^"claves: cl" wbh ^"hiwoodblock: wbh" wbl ^"lowoodblock: wbl" \myBreak
-cuim ^"mutecuica: cuim" cuio ^"opencuica: cuio"
-trim ^"mutetriangle: trim" tri ^"triangle: tri" trio ^"opentriangle: trio" \myBreak
-ua ^"oneup: ua" ub ^"twoup: ub" uc ^"threeup: uc" ud ^"fourup: ud" ue ^"fiveup: ue" \myBreak
-da ^"onedown: da" db ^"twodown: db" dc ^"threedown: dc" dd ^"fourdown: dd" de ^"fivedown: de" \myBreak
-}
-}
+ \drummode {
+ \cadenzaOn
+
+ bda1^\markup { \center-align "acousticbassdrum: bda" }
+ bd _\markup { \center-align "bassdrum: bd" }
+ sn ^\markup { \center-align "snare: sn" }
+ sne _\markup { \center-align "electricsnare: sne" }
+ sna ^\markup { \center-align "acousticsnare: sna" } \myBreak
+
+ tomfl^\markup { \center-align "lowfloortom: tomfl" }
+ tomfh_\markup { \center-align "highfloortom: tomfh" }
+ toml ^\markup { \center-align "lowtom: toml" }
+ tomh _\markup { \center-align "hightom: tomh" }
+ tomml^\markup { \center-align "lowmidtom: tomml" }
+ tommh_\markup { \center-align "himidtom: tommh" } \myBreak
+
+ hhc ^\markup { \center-align "closedhihat: hhc" }
+ hh _\markup { \center-align "hihat: hh" }
+ hhp ^\markup { \center-align "pedalhihat: hhp" }
+ hho _\markup { \center-align "openhihat: hho" }
+ hhho^\markup { \center-align "halfopenhihat: hhho" } \myBreak
+
+ cymca^\markup { \center-align "crashcymbala: cymca" }
+ cymc _\markup { \center-align "crashcymbal: cymc" }
+ cymra^\markup { \center-align "ridecymbala: cymra" }
+ cymr _\markup { \center-align "ridecymbal: cymr" } \myBreak
+
+ cymch^\markup { \center-align "chinesecymbal: cymch" }
+ cyms _\markup { \center-align "splashcymbal: cyms" }
+ cymcb^\markup { \center-align "crashcymbalb: cymcb" }
+ cymrb_\markup { \center-align "ridecymbalb: cymrb" }
+ rb ^\markup { \center-align "ridebell: rb" }
+ cb _\markup { \center-align "cowbell: cb" } \myBreak
+
+ bohm^\markup { \center-align "mutehibongo: bohm" }
+ boh _\markup { \center-align "hibongo: boh" }
+ boho^\markup { \center-align "openhibongo: boho" }
+ bolm_\markup { \center-align "mutelobongo: bolm" }
+ bol ^\markup { \center-align "lobongo: bol" }
+ bolo_\markup { \center-align "openlobongo: bolo" } \myBreak
+
+ cghm^\markup { \center-align "mutehiconga: cghm" }
+ cglm_\markup { \center-align "muteloconga: cglm" }
+ cgho^\markup { \center-align "openhiconga: cgho" }
+ cgh _\markup { \center-align "hiconga: cgh" }
+ cglo^\markup { \center-align "openloconga: cglo" }
+ cgl _\markup { \center-align "loconga: cgl" } \myBreak
+
+ timh^\markup { \center-align "hitimbale: timh" }
+ timl_\markup { \center-align "lotimbale: timl" }
+ agh ^\markup { \center-align "hiagogo: agh" }
+ agl _\markup { \center-align "loagogo: agl" } \myBreak
+
+ ssh^\markup { \center-align "hisidestick: ssh" }
+ ss _\markup { \center-align "sidestick: ss" }
+ ssl^\markup { \center-align "losidestick: ssl" } \myBreak
+
+ guis^\markup { \center-align "shortguiro: guis" }
+ guil_\markup { \center-align "longguiro: guil" }
+ gui ^\markup { \center-align "guiro: gui" }
+ cab _\markup { \center-align "cabasa: cab" }
+ mar ^\markup { \center-align "maracas: mar" } \myBreak
+
+ whs^\markup { \center-align "shortwhistle: whs" }
+ whl_\markup { \center-align "longwhistle: whl" } \myBreak
+
+ hc ^\markup { \center-align "handclap: hc" }
+ tamb_\markup { \center-align "tambourine: tamb" }
+ vibs^\markup { \center-align "vibraslap: vibs" }
+ tt _\markup { \center-align "tamtam: tt" } \myBreak
+
+ cl ^\markup { \center-align "claves: cl" }
+ wbh_\markup { \center-align "hiwoodblock: wbh" }
+ wbl^\markup { \center-align "lowoodblock: wbl" } \myBreak
+
+ cuim^\markup { \center-align "mutecuica: cuim" }
+ cuio_\markup { \center-align "opencuica: cuio" }
+ trim^\markup { \center-align "mutetriangle: trim" }
+ tri _\markup { \center-align "triangle: tri" }
+ trio^\markup { \center-align "opentriangle: trio" } \myBreak
+
+ ua^\markup { \center-align "oneup: ua" }
+ ub_\markup { \center-align "twoup: ub" }
+ uc^\markup { \center-align "threeup: uc" }
+ ud_\markup { \center-align "fourup: ud" }
+ ue^\markup { \center-align "fiveup: ue" } \myBreak
+
+ da^\markup { \center-align "onedown: da" }
+ db_\markup { \center-align "twodown: db" }
+ dc^\markup { \center-align "threedown: dc" }
+ dd_\markup { \center-align "fourdown: dd" }
+ de^\markup { \center-align "fivedown: de" } \myBreak
+ }
+ }
+
\layout {
\context {
\Score
}
}
}
-
c d e f g a b c
}
-%% Optional helper for automatic updating by convert-ly. May be omitted.
+%% Optional helper for automatic updating by convert-ly.
+%% May be omitted.
\version "2.14.0"
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
If the above seems confusing, consider this: if you were playing a
piano, which key would you hit? If you would press a black key,
-then you @emph{must} add @code{-is} or @code{-es} to the note
+then you @emph{must} add @w{@code{-is}} or @w{@code{-es}} to the note
name!
Adding all alterations explicitly might require a little more
easily understood.
For now, don't worry about the @code{#'}, which must precede the
-layout property, and the @code{#}, which must precede the value.
+layout property, and the@tie{}@code{#}, which must precede the value.
These must always be present in exactly this form. This is the
most common command used in tweaking, and most of the rest of
this chapter will be directed to presenting examples of how it is
@end example
Don't forget the @code{#'} preceding the
-property name and a @code{#} preceding the new value!
+property name and a@tie{}@code{#} preceding the new value!
The final question is, @q{Where should this command be
placed?} While you are unsure and learning, the best
@tab A valid direction constant or its numerical equivalent (decimal
values between -1 and 1 are allowed)
@tab @code{LEFT}, @code{CENTER}, @code{UP},
- @code{1}, @code{-1}
+ @code{1}, @w{@code{-1}}
@item Integer
@tab A positive whole number
@tab @code{3}, @code{1}
@code{(ly:make-moment 3 8)}
@item Number
@tab Any positive or negative decimal value
- @tab @code{3.5}, @code{-2.45}
+ @tab @code{3.5}, @w{@code{-2.45}}
@item Pair (of numbers)
@tab Two numbers separated by a @q{space . space} and enclosed
in brackets preceded by an apostrophe
need is @code{'#(#f #f #f)}. Let's try that, remembering to include
the @code{Staff} context. Note also that in writing this value we
have @code{#'#} before the opening bracket. The @code{'#} is required
-as part of the value to introduce a vector, and the first @code{#} is
+as part of the value to introduce a vector, and the first@tie{}@code{#} is
required, as always, to precede the value itself in the
@code{\override} command.
@end lilypond
Here we use the constants @code{DOWN} and @code{UP}.
-These have the values @code{-1} and @code{+1} respectively, and
+These have the values @w{@code{-1}} and @code{+1} respectively, and
these numerical values may be used instead. The value @code{0}
may also be used in some cases. It is simply treated as meaning
@code{UP} for stems, but for some objects it means @q{center}.
@noindent
If the fingering seems a little crowded the @code{font-size}
could be reduced. The default value can be seen from the
-@code{Fingering} object in the IR to be @code{-5}, so let's
-try @code{-7}:
+@code{Fingering} object in the IR to be @w{@code{-5}}, so let's
+try @w{@code{-7}}:
@lilypond[quote,fragment,ragged-right,verbatim,relative=1]
\override Fingering #'font-size = #-7
the @code{self-alignment-interface}. In general these are objects
that contain text. The values are @code{LEFT}, @code{RIGHT}
or @code{CENTER}. Alternatively, a numerical value between
-@code{-1} and @code{+1} may be specified, where @code{-1} is
+@w{@code{-1}} and @code{+1} may be specified, where @w{@code{-1}} is
left-aligned, @code{+1} is right-aligned, and numbers in between
move the text progressively from left-aligned to right-aligned.
Numerical values greater than @code{1} may be specified to move
-the text even further to the left, or less than @code{-1} to
+the text even further to the left, or less than @w{@code{-1}} to
move the text even further to the right. A change of @code{1}
in the value corresponds to a movement of half the text's length.
the rest is in voice two. The default in @code{\voiceTwo} (i.e. in
the second voice of a @code{<<@{...@} \\ @{...@}>>} construct) is that
@code{staff-position} is set to -4 for MultiMeasureRest, so we need to
-move it, say, four half-staff spaces down to @code{-8}.
+move it, say, four half-staff spaces down to @w{@code{-8}}.
@cindex MultiMeasureRest, example of overriding
@cindex staff-position property, example
### makeinfo_like_foot_line_and_ref
### makeinfo_like_foot_lines
### makeinfo_like_paragraph
+### -) In tables, don't wrap <p> around the contents. Implemented in
+### makeinfo_like_paragraph
###
###
### Useful helper functions:
return $text if (($format eq 'itemize' or $format eq 'enumerate') and
($$paragraph_number == 1));
}
+ # The cells of a table should not be wrapped in a <p> tag, so just return the text
+ if (defined($command_stack_at_begin->[0]) and $command_stack_at_begin->[0] eq 'multitable')
+ {
+ return $text;
+ }
+
+ # Adjust all footnotes so that they look like good old makeinfo
my $open = '<p';
if ($align)
{
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
To avoid that syllables of different width (such as @qq{-ri} and
@qq{-rum}) spread the syllable note groups unevenly apart, the
-@code{#'X-extent} property of the @code{LyricText} object may be
+@code{'X-extent} property of the @code{LyricText} object may be
set to a fixed value. Another, more cumbersome way would be to
add the syllables as @code{\markup} elements. If further
adjustments are necessary, this can be easily done with
Internally, LilyPond uses Scheme (a LISP dialect) to provide
infrastructure. Overriding layout decisions in effect accesses the
program internals, which requires Scheme input. Scheme elements are
-introduced in a @file{.ly} file with the hash mark
-@code{#}.@footnote{@rextend{Scheme tutorial}, contains a short tutorial
-on entering numbers, lists, strings, and symbols in Scheme.}
+introduced in a @file{.ly} file with the hash
+mark@tie{}@code{#}.@footnote{@rextend{Scheme tutorial}, contains a
+short tutorial on entering numbers, lists, strings, and symbols in
+Scheme.}
@menu
on @code{FingeringEvent} and one on @code{Fingering}.
The page on @code{FingeringEvent} describes the properties of the music
-expression for the input @code{-2}. The page contains many links
+expression for the input @w{@code{-2}}. The page contains many links
forward. For example, it says
@quotation
@end example
@var{value} is a Scheme object, which is why it must be preceded by
-the @code{#} character.
+the @code{#}@tie{}character.
Contexts properties are usually named in
@code{studlyCaps}. They mostly control the translation from
@cindex internal documentation
For many properties, regardless of the data type of the property, setting the
-property to false ( @code{##f} ) will result in turning it off, causing
+property to false (@code{#f}) will result in turning it off, causing
LilyPond to ignore that property entirely. This is particularly useful for
turning off grob properties which may otherwise be causing problems.
@item @code{\markup} commands
@item @code{\tag} commands
@item string markups, e.g. -"string"
-@item fingering instructions, e.g. @code{-1}
-@item articulation shortcuts, e.g. @code{-.}, @code{->}, @code{--}
+@item fingering instructions, e.g. @w{@code{-1}}
+@item articulation shortcuts, e.g. @w{@code{-.}}, @w{@code{->}}, @w{@code{--}}
@end itemize
Direction indicators affect only the next note:
by the @code{direction} property.
The value of the @code{direction} property may be
-set to @code{1}, meaning @qq{up} or @qq{above}, or to @code{-1},
+set to @code{1}, meaning @qq{up} or @qq{above}, or to @w{@code{-1}},
meaning @qq{down} or @qq{below}. The symbols @code{UP} and
-@code{DOWN} may be used instead of @code{1} and @code{-1}
+@code{DOWN} may be used instead of @code{1} and @w{@code{-1}}
respectively. The default direction may be specified by setting
@code{direction} to @code{0} or @code{CENTER}. Alternatively,
in many cases predefined commands
In a few cases, arpeggio being the only common example, the value
of the @code{direction} property specifies whether the object
is to be placed to the right or left of the parent object. In
-this case @code{-1} or @code{LEFT} means @qq{to the left} and
+this case @w{@code{-1}} or @code{LEFT} means @qq{to the left} and
@code{1} or @code{RIGHT} means @qq{to the right}. @code{0}
or @code{CENTER} means @qq{use the default} direction, as before.
@item attach-dir
This determines where the line starts and ends in the X-direction,
-relative to the bound object. So, a value of @code{-1} (or
+relative to the bound object. So, a value of @w{@code{-1}} (or
@code{LEFT}) makes the line start/end at the left side of the note
head it is attached to.
@end lilypond
Note that negative values move the text @emph{up}, contrary to the
-effect that might be expected, as a value of @code{-1} or
+effect that might be expected, as a value of @w{@code{-1}} or
@code{DOWN} means align the @emph{bottom} edge of the text with
the spanner line. A value of @code{1} or @code{UP} aligns
the top edge of the text with the spanner line.
value of @code{1}, is drawn after the staff lines (default
@code{layer} value @code{0}), so overwriting them. To change this,
the @code{Clef} object must be given in a lower value of
-@code{layer}, say @code{-1}, so that it is drawn earlier:
+@code{layer}, say @w{@code{-1}}, so that it is drawn earlier:
@lilypond[quote,verbatim,relative=2]
\override Staff.Clef #'color = #white
e2 \glissando f
@end lilypond
-The value for @code{Y} is set to @code{-2} for the right end
+The value for @code{Y} is set to @w{@code{-2}} for the right end
point. The left side may be similarly adjusted by specifying
@code{left} instead of @code{right}.
real value, in units of half the total X extent of the
object. Negative values move the object to the right, positive
to the left. A value of @code{0} centers the object on the
-reference point of its parent, a value of @code{-1} aligns the
+reference point of its parent, a value of @w{@code{-1}} aligns the
left edge of the object on the reference point of its parent,
and a value of @code{1} aligns the right edge of the object on the
reference point of its parent. The symbols @code{LEFT},
-@code{CENTER} and @code{RIGHT} may be used instead of the values
-@code{-1, 0, 1} respectively.
+@code{CENTER}, and @code{RIGHT} may be used instead of the values
+@w{@code{-1}}, @code{0}, and @code{1}, respectively.
Normally the @code{\override} command would be used to modify the
value of @code{self-alignment-X}, but the @code{\tweak} command
This may make adjusting the value of some objects tricky.
The units are just half the vertical extent of the object, which
is usually quite small, so quite large numbers may be required.
-A value of @code{-1} aligns the lower edge of the object with
+A value of @w{@code{-1}} aligns the lower edge of the object with
the reference point of the parent object, a value of @code{0}
aligns the center of the object with the reference point of the
parent, and a value of @code{1} aligns the top edge of the object
with the reference point of the parent. The symbols @code{DOWN},
-@code{CENTER}, @code{UP} may be substituted for @code{-1, 0, 1}
-respectively.
+@code{CENTER}, and @code{UP} may be substituted for @w{@code{-1}},
+@code{0}, and @code{1}, respectively.
@emph{Self-aligning objects in both directions}
similarly named normal color.
Not all X11 colors are distinguishable in a web browser, i.e.,
-a web browser might not display a difference between @code{'LimeGreen}
-and @code{'ForestGreen}. For web use normal colors are recommended
-(i.e., @code{#blue}, @code{#green}, @code{#red}).
+a web browser might not display a difference between @code{LimeGreen}
+and @code{ForestGreen}. For web use normal colors are recommended
+(i.e., @code{blue}, @code{green}, @code{red}).
Notes in a chord cannot be colored with @code{\override}; use
@item After every command or variable, i.e. every item that
begins with a @code{\} sign.
@item After every item that is to be interpreted as a Scheme
-expression, i.e. every item that begins with a @code{#} sign.
+expression, i.e. every item that begins with a @code{#}@tie{}sign.
@item To separate all elements of a Scheme expression.
@item In @code{lyricmode} to separate all the terms in both
@code{\override} and @code{\set} commands. In particular, spaces
must all be relative to the directory containing the main file,
not the directory containing the included file. However,
this behavior can be changed by passing the option
-@code{-drelative-includes} option at the command line
+@option{-drelative-includes} option at the command line
(or by adding @code{#(ly:set-option 'relative-includes #t)}
at the top of the main input file). With @code{relative-includes}
set, the path for each @code{\include} command will be taken
rhythmic-locations to the list.
In order to use this feature, LilyPond must be invoked with
-@code{-dclip-systems}. The clips are output as EPS files, and are
+@option{-dclip-systems}. The clips are output as EPS files, and are
converted to PDF and PNG if these formats are switched on as well.
For more information on output formats, see @rprogram{Invoking lilypond}.
The property @code{measurePosition} contains a rational number
indicating how much of the measure has passed at this point. Note
that this is set to a negative number by the @code{\partial} command:
-i.e., @code{\partial 4} is internally translated to @code{-4}, meaning
+i.e., @code{\partial 4} is internally translated to @w{@code{-4}}, meaning
@qq{there is a quarter note left in the measure.}
@seealso
of beaming-rules.
At this time the only available value of rule-type is
-@code{#'end} for beam ending.
+@code{'end} for beam ending.
Beaming-rules is a scheme alist (or list of pairs) that indicates the
beam type and the grouping to be applied to beams containing notes with
The relative importance of page (vertical) spacing and line
(horizontal) spacing. High values will make page spacing more
-important. Default: @code{#10}.
+important. Default: @code{10}.
@item print-all-headers
@funindex print-all-headers
There are also analogous settings to @code{ragged-right} and
@code{ragged-last} which have the same effect on vertical spacing:
@code{ragged-bottom} and @code{ragged-last-bottom}. If set to
-@code{##t} the systems on all pages or just the last page
+@code{#t} the systems on all pages or just the last page
respectively will not be justified vertically. See
@ref{Fixed vertical spacing \paper variables}.
The @code{Page_turn_engraver} reads the context property
@code{minimumPageTurnLength} to determine how long a note-free section must
be before a page turn is considered. The default value for
-@code{minimumPageTurnLength} is @code{#(ly:make-moment 1 1)}. If you want
+@code{minimumPageTurnLength} is @code{(ly:make-moment 1 1)}. If you want
to disable page turns, you can set it to something very large.
@example
spaced. Note that @code{@var{item2}} is not necessarily below
@code{@var{item1}}; for example,
@code{nonstaff-relatedstaff-spacing} will measure upwards from the
-non-staff line if @code{staff-affinity} is @code{#UP}.
+non-staff line if @code{staff-affinity} is @code{UP}.
Each distance is measured between the @emph{reference points} of
the two items. The reference point for a staff is the vertical
duration is taken as the basis for the spacing, with the stipulation
that this shortest duration should always be equal to or shorter than
an 8th note. The shortest duration is printed when you run
-@code{lilypond} with the @code{--verbose} option.
+@code{lilypond} with the @option{--verbose} option.
These durations may also be customized. If you set the
@code{common-shortest-duration} in @rinternals{SpacingSpanner}, then
which is the reference duration against that all music will be spaced.
The LilyPond Scheme function @code{make-moment} takes two arguments
-- a numerator and denominator which together express some fraction of
-a whole note. The call @code{#(ly:make-moment 1 20)} therefore produces
+a whole note. The call @code{(ly:make-moment 1 20)} therefore produces
a reference duration of a twentieth note. Values such as
-@code{#(ly:make-moment 1 16)}, @code{#(ly:make-moment 1 8)}, and
-@code{#(ly:make-moment 3 97)} are all possible as well.
+@code{(ly:make-moment 1 16)}, @code{(ly:make-moment 1 8)}, and
+@code{(ly:make-moment 3 97)} are all possible as well.
How do we select the right reference duration to pass to
@code{proportionalNotationDuration}? Usually by a process of trial
It is possible to adjust which aspects of the music are quoted with
@code{\cueDuring} by setting the @code{quotedCueEventTypes}
-property. Its default value is @code{#'(note-event rest-event
+property. Its default value is @code{'(note-event rest-event
tie-event beam-event tuplet-span-event)}, which means that only
notes, rests, ties, beams and tuplets are quoted, but not
articulations, dynamic marks, markup etc.
-In this example, the @code{Voice} context must be
-explicitly declared, or else the entire music expression would
-belong to the @code{CueVoice} context.
+@warning{When a @code{Voice} starts with @code{\cueDuring}, as in the
+following example, the @code{Voice} context must be explicitly declared,
+or else the entire music expression would belong to the @code{CueVoice}
+context.}
@lilypond[verbatim,quote]
oboeNotes = \relative c'' {
A @code{\markup} block may also contain quoted text strings. Such
strings are treated as minimal text expressions, and therefore any
-markup command or special character (such as @code{\} and @code{#})
+markup command or special character (such as @code{\} and@tie{}@code{#})
will be printed verbatim without affecting the formatting of the text.
Double quotation marks themselves may be printed by preceding them
with backslashes.
When a melisma occurs on a syllable other that the last one in a
word, that syllable is usually joined to the following one with a
hyphenated line. This is indicated by placing a double hyphen,
-@code{--}, immediately after the syllable.
+@w{@code{--}}, immediately after the syllable.
Alternatively, when a melisma occurs on the last or only syllable in
a word an extender line is usually drawn from the end of the syllable
specify its key so the conversion of its cue notes will be done
automatically. The example below shows this transposition for a
B-flat clarinet. The notes in this example are low on the staff so
-@code{#DOWN} is specified in @code{\cueDuring} (so the stems are
+@code{DOWN} is specified in @code{\cueDuring} (so the stems are
down) and the instrument name is positioned below the staff. Note
also that the piano right-hand voice is explicitly declared. This
is because the cue notes in this example begin at the start of the
Al escribir un bajo cifrado, podemos situar las cifras encima o debajo
de las notas del bajo, mediante la definición de la propiedad
@code{BassFigureAlignmentPositioning #'direction} (exclusivamente
-dentro de un contexto @code{Staff}). Se puede elegir entre @code{#UP}
-(o @code{#1}, arriba), @code{#CENTER} (o @code{#0}, centrado) y
-@code{#DOWN} (o @code{#-1}, abajo).
+dentro de un contexto @code{Staff}). Se puede elegir entre @code{UP}
+(o @code{1}, arriba), @code{CENTER} (o @code{0}, centrado) y
+@code{DOWN} (o @w{@code{-1}}, abajo).
Esta propiedad se puede cambiar tantas veces como queramos. Utilice
@code{\\once \\override} si no quiere que la sobreescritura se aplique
texidoc = "
When writing a figured bass, you can place the figures above or below
the bass notes, by defining the @code{BassFigureAlignmentPositioning
-#'direction} property (exclusively in a @code{Staff} context). Choices
-are @code{#UP} (or @code{#1}), @code{#CENTER} (or @code{#0}) and
-@code{#DOWN} (or @code{#-1}).
+#'direction} property (exclusively in a @code{Staff} context). Choices
+are @code{UP} (or @code{1}), @code{CENTER} (or @code{0}) and
+@code{DOWN} (or @w{@code{-1}}).
This property can be changed as many times as you wish. Use
@code{\\once \\override} if you don't want the override to apply to the
(ly:bar-line::print grob)
X RIGHT
(grob-interpret-markup grob splitStaffBarLineMarkup)
- 0 0))
+ 0))
\break
}
notas guía orquestales a la reducción de piano en una partitura vocal.
La función musical @code{\\cueWhile} toma cuatro argumentos: la música
de la que se toma la cita, como viene definida por @code{\\addQuote},
-el nombre que insertar antes de las notas guía, y después @code{#UP} o
-@code{#DOWN} para especificar @code{\\voiceOne} con el nombre encima
+el nombre que insertar antes de las notas guía, y después @code{UP} o
+@code{DOWN} para especificar @code{\\voiceOne} con el nombre encima
del pentagrama o bien @code{\\voiceTwo} con el nombre debajo del
pentagrama, y finalmente la música de piano con la que las notas guía
deben aparecer en paralelo. El nombre del instrumento citado se
@code{\\cueWhile} braucht vier Argumente: Die Noten, von denen die
Stichnoten formatiert werden sollen, definiert durch @code{\\addQuote},
die Bezeichnung, die mit den Noten angegeben werden soll, dann entweder
-@code{#UP} (hoch) oder @code{#DOWN} (runter) zur Angabe von entweder
+@code{UP} (hoch) oder @code{DOWN} (runter) zur Angabe von entweder
@code{\\voiceOne} mit der Bezeichnung über dem System oder @code{\\voiceTwo}
mit der Bezeichnung unter dem System, und schließlich die Klaviermusik,
die parallel zu den Stichnoten gespielt werden soll. Die Bezeichnung des
pour gérer ces repères. La fonction musicale @code{\\cueWhile} prend
quatre arguments@tie{}: la musique d'où provient la citation, telle que
définie par @code{\\addQuote}, le nom qui sera mentionné en regard de
-cette citation, son positionnement -- @code{#UP} ou @code{#DOWN} selon
+cette citation, son positionnement -- @code{UP} ou @code{DOWN} selon
qu'il sera attribué à @code{\\voiceOne} et placé au-dessus ou
@code{\\voiceTwo} et placé en dessous -- et enfin la musique du piano
qui interviendra en parallèle. Le nom de l'instrument en question
piano reduction in a vocal score. The music function @code{\\cueWhile}
takes four arguments: the music from which the cue is to be taken, as
defined by @code{\\addQuote}, the name to be inserted before the cue
-notes, then either @code{#UP} or @code{#DOWN} to specify either
+notes, then either @code{UP} or @code{DOWN} to specify either
@code{\\voiceOne} with the name above the staff or @code{\\voiceTwo}
with the name below the staff, and finally the piano music in parallel
with which the cue notes are to appear. The name of the cued
Dentro de un acorde (entre ángulos simples @code{< >}), antes de la
nota que queremos alterar, situamos la instrucción @code{\\tweak}
-seguida por @code{#'font-size} y definimos el tamaño adecuado como
-@code{#-2} (una cabeza pequeña).
+seguida por @code{'font-size} y definimos el tamaño adecuado como
+@w{@code{-2}} (una cabeza pequeña).
"
doctitlees = "Modificar el tamaño de una nota suelta de un acorde"
Inside the chord (within the brackets @code{< >}), before the note to
be altered, place the @code{\\tweak} command, followed by
-@code{#'font-size} and define the proper size like @code{#-2} (a tiny
+@code{'font-size} and define the proper size like @w{@code{-2}} (a tiny
note head).
} % begin verbatim
\relative c' {
- <\tweak #'font-size #+2 c e g c \tweak #'font-size #-2 e>1^\markup { A tiny e }_\markup { A big c }
+ <\tweak #'font-size #+2 c e g c \tweak #'font-size #-2 e>1
+ ^\markup { A tiny e }_\markup { A big c }
}
texidoc = "
Though the simplest way to resize staves is to use
-@code{#(set-global-staff-size xx)}, an individual staff's size can be
+@code{#(set-global-staff-size @var{xx})}, an individual staff's size can be
changed by scaling the properties @code{'staff-space} and
@code{fontSize}.
partitura completa.
Este archivo tiene que procesarse de forma separada con la opción
-@code{-dclip-systems}; la página de fragmentos de código podría no
+@option{-dclip-systems}; la página de fragmentos de código podría no
mostrar el resultado adecuadamente.
La salida consiste en archivos con los nombres
texidoc = "
This code shows how to clip (extract) snippets from a full score.
-This file needs to be run separately with @code{-dclip-systems}; the
+This file needs to be run separately with @option{-dclip-systems}; the
snippets page may not adequately show the results.
The result will be files named
una barra de la misma longitud que el grupo especial. Para controlar
la visibilidad de los corchetes de grupo, establezca la propiedad
@code{'bracket-visibility} a @code{#t} (imprimir el corchete siempre),
-@code{#f} (no imprimirlo nunca) o @code{#'if-no-beam} (imprimir el
+@code{#f} (no imprimirlo nunca) o @code{'if-no-beam} (imprimir el
corchete solamente si no hay barra).
"
@code{'bracket-visibility}, de contôler précisément leur
affichage@tie{}: déterminée à @code{#t}, ils seront toujours
imprimés@tie{}; @code{#f} permet de ne jamais les imprimer, et
-@code{#'if-no-beam} les imprimera en l'absence de ligature.
+@code{'if-no-beam} les imprimera en l'absence de ligature.
"
doctitlefr = "Contrôle de l'impression des crochets de nolet"
unless there is a beam of the same length as the tuplet. To control the
visibility of tuplet brackets, set the property
@code{'bracket-visibility} to either @code{#t} (always print a
-bracket), @code{#f} (never print a bracket) or @code{#'if-no-beam}
+bracket), @code{#f} (never print a bracket) or @code{'if-no-beam}
(only print a bracket if there is no beam).
"
texidocfr = "
Il s'agit de fonctions postfix pour personnaliser l'extension des
crescendos textuels. L'extension devrait débuter sur la première notte
-de la mesure. Il faut utiliser @code{-\mycresc} -- comme une
+de la mesure. Il faut utiliser @w{@code{-\mycresc}} -- comme une
articulation -- sous peine que le départ de l'extension n'apparaisse
qu'à la note suivante.
"
texidoces = "
La alineación horizontal de la letra se puede ajustar sobreescribiendo
la propiedad @code{self-alignment-X} del objeto @code{LyricText}.
-@code{#-1} es izquierda, @code{#0} es centrado y @code{#1} es derecha;
-sin embargo, puede usar también @code{#LEFT}, @code{#CENTER} y
-@code{#RIGHT}.
+@w{@code{-1}} es izquierda, @code{0} es centrado y @code{1} es derecha;
+sin embargo, puede usar también @code{LEFT}, @code{CENTER} y
+@code{RIGHT}.
"
doctitlees = "Alineación de la letra"
texidocde = "
Die horizontale Ausrichtung von Gesangstext kann eingestellt werden, indem
man die @code{self-alignment-X}-Eigenschaft des @code{LyricText}-Objekts
-verändert. @code{#-1} bedeutet links, @code{#0} bedeutet mittig und @code{#1}
-bedeutet rechts, man kann aber genauso gut auch @code{#LEFT}, @code{#CENTER}
-und @code{#RIGHT} benutzen.
+verändert. @w{@code{-1}} bedeutet links, @code{0} bedeutet mittig und @code{1}
+bedeutet rechts, man kann aber genauso gut auch @code{LEFT}, @code{CENTER}
+und @code{RIGHT} benutzen.
"
doctitlede = "Ausrichtung von Gesangstext"
texidocfr = "
L'alignement horizontal des paroles peut se gérer à l'aide de la
propriété @code{self-alignment-X} de l'objet @code{LyricText}.
-Les valeurs @code{#-1} ou @code{#LEFT} produiront un alignement par la
-gauche, les valeurs @code{#0} ou @code{#CENTER} un alignement centré, et
-les valeurs @code{#1} ou @code{#RIGHT} un alignement par la droite.
+Les valeurs @w{@code{-1}} ou @code{LEFT} produiront un alignement par la
+gauche, les valeurs @code{0} ou @code{CENTER} un alignement centré, et
+les valeurs @code{1} ou @code{RIGHT} un alignement par la droite.
"
doctitlefr = "Alignement des syllabes"
texidoc = "
Horizontal alignment for lyrics cam be set by overriding the
@code{self-alignment-X} property of the @code{LyricText} object.
-@code{#-1} is left, @code{#0} is center and @code{#1} is right;
-however, you can use @code{#LEFT}, @code{#CENTER} and @code{#RIGHT} as
+@w{@code{-1}} is left, @code{0} is center and @code{1} is right;
+however, you can use @code{LEFT}, @code{CENTER} and @code{RIGHT} as
well.
"
(grob-interpret-markup grob
(markup #:center-align #:fontsize -4
#:musicglyph "noteheads.s2cross"))
- -2.3 0))))
+ -2.3))))
}
speakOff = {
@code{dashLarger}, @code{dashDot} y @code{dashUnderscore} reciben
valores predeterminados. Se pueden modificar estos valores
predeterminados para las abreviaturas. Por ejemplo, para asociar
-la abreviatura @code{-+} (@code{dashPlus}) con el símbolo del
+la abreviatura @w{@code{-+}} (@code{dashPlus}) con el símbolo del
semitrino en lugar del símbolo predeterminado +, asigne el valor
@code{trill} a la variable @code{dashPlus}:
@code{dashBar}, @code{dashLarger}, @code{dashDot} und
@code{dashUnderscore} Standardwerte zugewiesen werden. Diese Standardwerte
können verändert werden. Um zum Beispiel die Abkürzung
-@code{-+} (@code{dashPlus}) mit dem Triller anstatt mit dem +-Symbol zu
+@w{@code{-+}} (@code{dashPlus}) mit dem Triller anstatt mit dem +-Symbol zu
assoziieren, muss der Wert @code{trill} der Variable
@code{dashPlus} zugewiesen werden:
@code{dashHat}, @code{dashPlus}, @code{dashDash}, @code{dashBar},
@code{dashLarger}, @code{dashDot}, et @code{dashUnderscore} ainsi que
leur valeur par défaut. Ces valeurs peuvent être modifiées selon vos
-besoins. Il suffit par exemple, pour affecter au raccourci @code{-+}
+besoins. Il suffit par exemple, pour affecter au raccourci @w{@code{-+}}
(@code{dashPlus}) le symbole du trille en lieu et place du @code{+}
(caractère plus), d'assigner la valeur @code{trill} à la variable
@code{dashPlus} :
@code{dashBar}, @code{dashLarger}, @code{dashDot}, and
@code{dashUnderscore} are assigned default values. The default values
for the shorthands can be modified. For example, to associate the
-@code{-+} (@code{dashPlus}) shorthand with the trill symbol instead of
+@w{@code{-+}} (@code{dashPlus}) shorthand with the trill symbol instead of
the default + symbol, assign the value @code{trill} to the variable
@code{dashPlus}:
texidoc = "
This code shows how to clip (extract) snippets from a full score.
-This file needs to be run separately with @code{-dclip-systems}; the
+This file needs to be run separately with @option{-dclip-systems}; the
snippets page may not adequately show the results.
The result will be files named
tipográfica, se imprime un becuadro antes de un sostenido o un
bemol cuando se tiene que cancelar una alteración anterior en la
misma nota. Para modificar este comportamiento, establezca el
-valor de la propiedad @code{extraNatural} a @code{##f} (falso)
+valor de la propiedad @code{extraNatural} a @code{#f} (falso)
dentro del contexto de @code{Staff}.
"
En accord avec les règles standards de l'écriture musicale, on grave
un bécarre avant un dièse ou un bémol si on a besoin d'annuler une
altération précédente. Pour modifier ce comportement, assignez la propriété
-@code{extraNatural} du contexte @code{Staff} à la valeur @code{##f} (faux).
+@code{extraNatural} du contexte @code{Staff} à la valeur @code{#f} (faux).
"
doctitlefr = "Suppression des bécarres superflus"
In accordance with standard typesetting rules, a natural sign is
printed before a sharp or flat if a previous accidental on the same
note needs to be canceled. To change this behavior, set the
-@code{extraNatural} property to @code{f} in the @code{Staff} context.
+@code{extraNatural} property to @code{#f} in the @code{Staff} context.
Since @code{repeatCommands} takes a list, the simplest method of
including markup is to use an identifier for the text and embed it in
-the command list using the Scheme syntax @code{#(list (list 'volta
+the command list using the Scheme syntax @code{(list (list 'volta
textIdentifier))}. Start- and end-repeat commands can be added as
separate list elements:
It is possible to record a MIDI file using a digital keyboard, and
then convert it to @file{.ly}. However, human players are not
rhythmically exact enough to make a MIDI to LY conversion trivial.
-When invoked with quantizing (@code{-s} and @code{-d} options)
+When invoked with quantizing (@option{-s} and @option{-d} options)
@command{midi2ly} tries to compensate for these timing errors, but is not
very good at this. It is therefore not recommended to use @command{midi2ly}
for human-generated midi files.
Running @command{lilypond-book} and @command{latex} creates a lot of
temporary files, which would clutter up the working directory. To
-remedy this, use the @code{--output=@var{dir}} option. It will create
+remedy this, use the @option{--output=@var{dir}} option. It will create
the files in a separate subdirectory @file{dir}.
Finally the result of the @LaTeX{} example shown above.@footnote{This
@emph{The Not So Short Introduction to @LaTeX{}}} for an overview on how
to use @LaTeX{}.
-Music is entered using
+@code{lilypond-book} provides the following commands and environments to include
+music in @LaTeX{} files:
+
+@itemize
+
+@item
+the @code{\lilypond@{...@}} command, where you can directly enter short
+lilypond code
+
+@item
+the @code{\begin@{lilypond@}...\end@{lilypond@}} environment, where you
+can directly enter longer lilypond code
+
+@item
+the @code{\lilypondfile@{...@}} command to insert a lilypond file
+
+@item
+the @code{\musicxmlfile@{...@}} command to insert a MusicXML file, which
+will be processed by @code{musicxml2ly} and @code{lilypond}.
+
+@end itemize
+
+In the input file, music is specified with any of the following commands:
@example
\begin@{lilypond@}[options,go,here]
YOUR LILYPOND CODE
\end@{lilypond@}
-@end example
-@noindent
-or
+\lilypond[options,go,here]@{ YOUR LILYPOND CODE @}
-@example
\lilypondfile[options,go,here]@{@var{filename}@}
+
+\musicxmlfile[options,go,here]@{@var{filename}@}
@end example
-@noindent
-or
-@example
-\lilypond[options,go,here]@{ YOUR LILYPOND CODE @}
-@end example
+@noindent
Additionally, @code{\lilypondversion} displays the current version
of lilypond.
example of a Texinfo document is this manual. The HTML, PDF, and Info
versions of the manual are made from the Texinfo document.
-In the input file, music is specified with
+@code{lilypond-book} provides the following commands and environments to include
+music into Texinfo files:
+
+@itemize
+
+@item
+the @code{@@lilypond@{...@}} command, where you can directly enter short
+lilypond code
+
+@item
+the @code{@@lilypond...@@end lilypond} environment, where you can directly
+enter longer lilypond code
+
+@item
+the @code{@@lilypondfile@{...@}} command to insert a lilypond file
+
+@item
+the @code{@@musicxmlfile@{...@}} command to insert a MusicXML file, which
+will be processed by @code{musicxml2ly} and @code{lilypond}.
+
+@end itemize
+
+In the input file, music is specified with any of the following commands
@example
@@lilypond[options,go,here]
YOUR LILYPOND CODE
@@end lilypond
-@end example
-
-@noindent
-or
-@example
@@lilypond[options,go,here]@{ YOUR LILYPOND CODE @}
-@end example
-
-@noindent
-or
-@example
@@lilypondfile[options,go,here]@{@var{filename}@}
+
+@@musicxmlfile[options,go,here]@{@var{filename}@}
@end example
Additionally, @code{@@lilypondversion} displays the current version
@node HTML
@subsection HTML
-Music is entered using
+@code{lilypond-book} provides the following commands and environments to include
+music in HTML files:
+
+@itemize
+
+@item
+the @code{<lilypond .... />} command, where you can directly enter short lilypond code
+
+@item
+the @code{<lilyond>...</lilypond>} environment, where you can directly enter longer
+lilypond code
+
+@item
+the @code{<lilypondfile>...</lilypondfile>} command to insert a lilypond file
+
+@item
+the @code{<musicxmlfile>...</musicxmlfile>} command to insert a MusicXML file, which
+will be processed by @code{musicxml2ly} and @code{lilypond}.
+
+@end itemize
+
+In the input file, music is specified with any of the following commands:
+
+\begin@{lilypond@}[options,go,here]
+ YOUR LILYPOND CODE
+\end@{lilypond@}
+
+\lilypond[options,go,here]@{ YOUR LILYPOND CODE @}
+
+\lilypondfile[options,go,here]@{@var{filename}@}
+
+\musicxmlfile[options,go,here]@{@var{filename}@}
+@example
+<lilypond options go here>
+ YOUR LILYPOND CODE
+</lilypond>
+
+<lilypond options go here: YOUR LILYPOND CODE />
+<lilypondfile options go here>@var{filename}</lilypondfile>
+
+<musicxmlfile options go here>@var{filename}</musicxmlfile>
+@end example
+
+For example, you can write
@example
<lilypond fragment relative=2>
\key c \minor c4 es g2
<lilypondfile @var{option1} @var{option2} ...>@var{filename}</lilypondfile>
@end example
+@code{<musicxmlfile>} uses the same syntax as @code{<lilypondfile>}, but simply
+references a MusicXML file rather than a LilyPond file.
+
For a list of options to use with the @code{lilypond} or
@code{lilypondfile} tags, see @ref{Music fragment options}.
Running @command{dvips} may produce some warnings about fonts; these
are harmless and may be ignored. If you are running @command{latex} in
-twocolumn mode, remember to add @code{-t landscape} to the
+twocolumn mode, remember to add @option{-t landscape} to the
@command{dvips} options.
@subsubheading Texinfo
for already compiled snippets in the include path, and does not write
them back to the output directory, so in some cases it is necessary to
invoke further processing commands such as @command{makeinfo} or
-@command{latex} with the same @code{-I @var{dir}} options.
+@command{latex} with the same @option{-I @var{dir}} options.
@item -o @var{dir}
@itemx --output=@var{dir}
LilyPond Info documentation without images.
@itemx --lily-output-dir=@var{dir}
-Write lily-XXX files to directory @var{dir}, link into @code{--output}
+Write lily-XXX files to directory @var{dir}, link into @option{--output}
directory. Use this option to save building time for documents in
different directories which share a lot of identical snippets.
@item -P @var{command}
@itemx --process=@var{command}
Process LilyPond snippets using @var{command}. The default command is
-@code{lilypond}. @code{lilypond-book} will not @code{--filter} and
-@code{--process} at the same time.
+@code{lilypond}. @code{lilypond-book} will not @option{--filter} and
+@option{--process} at the same time.
@item --pdf
Create PDF files for use with PDF@LaTeX{}.
@itemx --use-source-file-names
Write snippet output files with the same base name as their source file.
This option works only for snippets included with @code{lilypondfile}
-and only if directories implied by @code{--output-dir} and
-@code{--lily-output-dir} options are different.
+and only if directories implied by @option{--output-dir} and
+@option{--lily-output-dir} options are different.
@item -V
@itemx --verbose
If you use the same filename extension for the input file than the
extension @command{lilypond-book} uses for the output file, and if the
input file is in the same directory as @command{lilypond-book} working
-directory, you must use @code{--output} option to make
+directory, you must use @option{--output} option to make
@command{lilypond-book} running, otherwise it will exit with an error
message like @qq{Output would overwrite input file}.
@item -e,--evaluate=@var{expr}
Evaluate the Scheme @var{expr} before parsing any @file{.ly} files.
-Multiple @code{-e} options may be given, they will be evaluated
+Multiple @option{-e} options may be given, they will be evaluated
sequentially.
The expression will be evaluated in the @code{guile-user} module, so
@table @samp
@item help
-Running @code{lilypond -dhelp} will print all of the @code{-d} options
+Running @code{lilypond -dhelp} will print all of the @option{-d} options
available.
@cindex paper-size, command line
Do not trust the @code{.ly} input.
When LilyPond formatting is available through a web server, either the
-@code{--safe} or the @code{--jail} option @b{MUST} be passed. The
-@code{--safe} option will prevent inline Scheme code from wreaking
+@option{--safe} or the @option{--jail} option @b{MUST} be passed. The
+@option{--safe} option will prevent inline Scheme code from wreaking
havoc, for example
@quotation
@end verbatim
@end quotation
-The @code{-dsafe} option works by evaluating in-line Scheme
+The @option{-dsafe} option works by evaluating in-line Scheme
expressions in a special safe module. This safe module is derived from
GUILE @file{safe-r5rs} module, but adds a number of functions of the
LilyPond API. These functions are listed in @file{scm/safe-lily.scm}.
In safe mode, it is not possible to import LilyPond variables
into Scheme.
-@code{-dsafe} does @emph{not} detect resource overuse. It is still possible to
+@option{-dsafe} does @emph{not} detect resource overuse. It is still possible to
make the program hang indefinitely, for example by feeding cyclic data
structures into the backend. Therefore, if using LilyPond on a
publicly accessible webserver, the process should be limited in both
CPU and memory usage.
The safe mode will prevent many useful LilyPond snippets from being
-compiled. The @code{--jail} is a more secure alternative, but
+compiled. The @option{--jail} is a more secure alternative, but
requires more work to set up.
@cindex output format, setting
for a dump of the raw, internal Scheme-based drawing commands.
@item null
- do not output a printed score; has the same effect as @code{-dno-print-pages}.
+ do not output a printed score; has the same effect as @option{-dno-print-pages}.
@end table
Example: @code{lilypond -dbackend=svg @var{filename}.ly}
Note to Windows users: By default @code{lilypond.exe} outputs all
progress information to the command window, @code{lilypond-windows.exe}
does not and returns a prompt, with no progress information, immediately
-at the command line. The @code{-dgui} option can be used in this case
+at the command line. The @option{-dgui} option can be used in this case
to redirect output to a log file.
@item print-pages
-Generate the full pages, the default. @code{-dno-print-pages} is
-useful in combination with @code{-dpreview}.
+Generate the full pages, the default. @option{-dno-print-pages} is
+useful in combination with @option{-dpreview}.
@end table
@item BASIC_PROGRESS
Basic progress messages (success), warnings and errors.
-@item PROGRESS (default)
+@item PROGRESS
All progress messages, warnings and errors.
+@item INFO (default)
+Progress messages, warnings, errors and further execution information.
+
@item DEBUG
All possible messages, including verbose debug output.
@end table
@item --png
Generate pictures of each page, in PNG format. This implies
-@code{--ps}. The resolution in DPI of the image may be set with
+@option{--ps}. The resolution in DPI of the image may be set with
@example
-dresolution=110
@end example
@cindex Portable Document Format (PDF) output
@item --pdf
-Generate PDF. This implies @code{--ps}.
+Generate PDF. This implies @option{--ps}.
@item -j,--jail=@var{user},@var{group},@var{jail},@var{dir}
Run @command{lilypond} in a chroot jail.
-The @code{--jail} option provides a more flexible alternative to
-@code{--safe} when LilyPond formatting is available through a web
+The @option{--jail} option provides a more flexible alternative to
+@option{--safe} when LilyPond formatting is available through a web
server or whenever LilyPond executes externally provided
sources.
-The @code{--jail} option works by changing the root of @command{lilypond} to
+The @option{--jail} option works by changing the root of @command{lilypond} to
@var{jail} just before starting the actual compilation process. The user
and group are then changed to match those provided, and the current
directory is changed to @var{dir}. This setup guarantees that it is not
possible (at least in theory) to escape from the jail. Note that for
-@code{--jail} to work @command{lilypond} must be run as root, which is usually
+@option{--jail} to work @command{lilypond} must be run as root, which is usually
accomplished in a safe way using @command{sudo}.
Setting up a jail is a slightly delicate matter, as we must be sure that
@item LILYPOND_LOGLEVEL
The default loglevel. If LilyPond is called without an explicit loglevel (i.e.
-no @code{--loglevel} command line option), this value is used.
+no @option{--loglevel} command line option), this value is used.
@item LILYPOND_GC_YIELD
A variable, as a percentage, that tunes memory management
@cindex call trace
@cindex Scheme error
Errors that occur while executing Scheme code are caught by the Scheme
-interpreter. If running with the verbose option (@code{-V} or
-@code{--verbose}) then a call trace of the offending
+interpreter. If running with the verbose option (@option{-V} or
+@option{--verbose}) then a call trace of the offending
function call is printed.
@item Programming error
@item -f,--from=@var{from-patchlevel}
Set the version to convert from. If this is not set, @command{convert-ly}
will guess this, on the basis of @code{\version} strings in the file.
-E.g. @code{--from=2.10.25}
+E.g. @option{--from=2.10.25}
@item -n,--no-version
Normally, @command{convert-ly} adds a @code{\version} indicator
@item --to=@var{to-patchlevel}
Set the goal version of the conversion. It defaults to the latest
-available version. E.g. @code{--to=2.12.2}
+available version. E.g. @option{--to=2.12.2}
@item -h, --help
Print usage help.
@imageFloat{text-input-1-annotate,png,center}
@imageFloat{text-input-1-output,png,center}
-Alterations are made with different names: add @code{-is} for
-sharp, and @code{-es} for flat (these are Dutch note names, other
+Alterations are made with different names: add @w{@code{-is}} for
+sharp, and @w{@code{-es}} for flat (these are Dutch note names, other
languages are available). LilyPond figures out where to put
accidentals.
@subsubheading February 2, 2004
LilyPond 2.1.17 is out. It adds texts
(solo, a due) for the part combiner. It also reinstates the
-@code{--safe} option which prevents havoc by Scheme exploits. More
+@option{--safe} option which prevents havoc by Scheme exploits. More
information in the
@ref{Changes}.
@newsEnd
</div>
@end html
@iftex
-@image{ly-examples/\IMAGE-FILE\-small,,,\IMAGE-FILE\,png}
+@image{ly-examples/\IMAGE-FILE\,6in,,\IMAGE-FILE\,png}
@end iftex
@ifinfo
@image{lilypond/ly-examples/\IMAGE-FILE\,,,\IMAGE-FILE\,png}
Real lc () const;
void print () const;
Real eval (Real) const;
+ Real minmax (Real, Real, bool) const;
void print_sols (vector<Real>) const;
void check_sols (vector<Real>) const;
void check_sol (Real x) const;
#define LOG_WARN 1<<1
#define LOG_BASIC 1<<2 // undocumented basic_progress, i.e. input file name and success
#define LOG_PROGRESS 1<<3
-// Currently, there is no separation between progress and other info messages:
#define LOG_INFO 1<<4
#define LOG_DEBUG 1<<8
#define LOGLEVEL_WARN (LOGLEVEL_ERROR | LOG_WARN)
#define LOGLEVEL_BASIC (LOGLEVEL_WARN | LOG_BASIC)
#define LOGLEVEL_PROGRESS (LOGLEVEL_BASIC | LOG_PROGRESS)
-// Currently, there is no separation between progress and other info messages:
#define LOGLEVEL_INFO (LOGLEVEL_PROGRESS | LOG_INFO)
#define LOGLEVEL_DEBUG (LOGLEVEL_INFO | LOG_DEBUG)
return dest;
}
+Real
+Polynomial::minmax (Real l, Real r, bool ret_max) const
+{
+ vector<Real> sols;
+ if (l > r)
+ {
+ programming_error ("left bound greater than right bound for polynomial minmax. flipping bounds.");
+ l = l + r;
+ r = l - r;
+ l = l - r;
+ }
+
+ sols.push_back (eval (l));
+ sols.push_back (eval (r));
+
+ Polynomial deriv (*this);
+ deriv.differentiate ();
+ vector<Real> maxmins = deriv.solve ();
+ for (vsize i = 0; i < maxmins.size (); i++)
+ if (maxmins[i] >= l && maxmins[i] <= r)
+ sols.push_back (eval (maxmins[i]));
+ vector_sort (sols, less<Real> ());
+
+ return ret_max ? sols.back () : sols[0];
+}
+
void
Polynomial::differentiate ()
{
and print the message only if that's the case
*/
-/* Define the loglevel (default is PROGRESS); for now, PROGRESS=INFO for a
- all relevant output, so be on the safe side and use INFO as default, just
- in case some output is generated with INFO */
+/* Define the loglevel (default is INFO) */
int loglevel = LOGLEVEL_INFO;
bool
set_loglevel (l);
else
{
- non_fatal_error (_f ("unknown log level `%s', using default (PROGRESS)",
+ non_fatal_error (_f ("unknown log level `%s', using default (INFO)",
level));
set_loglevel (LOGLEVEL_INFO);
}
\header {
texidoc = "Point-symmetric beams should receive the same
- quanting. There is no up/down bias in the quanting code."
+quanting. There is no up/@/down bias in the quanting code."
}
\layout{
--- /dev/null
+\version "2.15.9"
+
+\header {
+ texidoc = "Beamed rests are given a pure height approximation
+that gets their spacing correct in the majority of circumstances.
+"
+}
+
+\relative c'' {
+ <f b c f>16[ r <f bes c f> <f b c f>]
+ <f b c f>16[ r <f'' bes c f> <f b c f>]
+ <f b c f>16[ r <f,, bes c f> <f b c f>]
+ <f'' b c f>16[ r <f bes c f> <f b c f>]
+}
\version "2.14.0"
\header {
- texidoc = "The default callback for break-align-anchor in clefs and time/key
-signatures reads the break-align-anchor-aligment property to align
+ texidoc = "The default callback for break-align-anchor in clefs and time/@/key
+signatures reads the @code{break-align-anchor-aligment} property to align
the anchor to the extent of the break-aligned grob."
}
\header{
texidoc="
Gregorian chant notation sometimes also uses commas and ticks, but in
-smaller font size (we call it 'virgula' and 'caesura'). However, the
-most common breathing signs are divisio minima/maior/maxima and
+smaller font size (we call it `virgula' and `caesura'). However, the
+most common breathing signs are divisio minima/@/maior/@/maxima and
finalis, the latter three looking similar to bar glyphs.
-
" }
\include "gregorian.ly"
@item Regions can span multiple systems. In this case, multiple EPS files are generated.
@end itemize
-This file needs to be run separately with @code{-dclip-systems}; the
+This file needs to be run separately with @option{-dclip-systems}; the
collated-files.html of the regression test does not adequately show
the results.
\header {
texidoc = "Clefs for cue notes at the start of a score should print the
-standard clef plus a small cue clef after the time/key signature."
+standard clef plus a small cue clef after the time/@/key signature."
}
vI = \relative c'' { \clef "treble" \repeat unfold 40 g4 }
printed at the end of the line.
Cue notes going over a line break should print the standard clef on the new
-line plus an additional cue clef after the time/key signature."
+line plus an additional cue clef after the time/@/key signature."
}
vI = \relative c'' { \clef "treble" \repeat unfold 40 g4 }
texidoc = "When figures appear inside a voice, @code{ignoreFiguredBassRest}
causes all figures on rests to be discarded and all spanners ended.
- If set to @code{##f}, figures on rests are printed.
+ If set to @code{#f}, figures on rests are printed.
"
}
\header {
texidoc = "Ordering of the fingerings depends on vertical ordering of the notes, and
-is independent of up/down direction."
+is independent of up/@/down direction."
}
\header
{
- texidoc = "TM and No should not be changed into trademark/number symbols.
+ texidoc = "TM and No should not be changed into trademark/@/number symbols.
This may happen with incorrect font versions.
"
}
\header {
texidoc="
Fret diagrams can be scaled using the @code{size} property.
-The position and size of first fret label, mute/open signs, fingers,
+The position and size of first fret label, mute/@/open signs, fingers,
relative to the diagram grid, shall be the same in all cases.
"
--- /dev/null
+\header {
+ texidoc = "Glissandi stop before hitting accidentals."
+
+}
+\version "2.15.9"
+
+\relative c'' {
+ a1\glissando cis
+}
\version "2.14.0"
\header {
- texidoc = "Grace notes in different voices/staves are synchronized."
+ texidoc = "Grace notes in different voices/@/staves are synchronized."
}
\layout { ragged-right = ##t}
--- /dev/null
+<html>
+<body>
+Including a compressed MusicXML file:
+<musicxmlfile language="deutsch" absolute no-beaming printfilename>include.mxl</musicxmlfile>
+</body>
+</html>
--- /dev/null
+<html>
+<body>
+Including a MusicXML file:
+<musicxmlfile language="deutsch" absolute no-beaming printfilename>include.xml</musicxmlfile>
+</body>
+</html>
--- /dev/null
+<html>
+<body>
+Including a MusicXML file:
+<musicxmlfile>include.xml</musicxmlfile>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 0.6 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise>
+ <identification>
+ <miscellaneous>
+ <miscellaneous-field name="description">One simple chord
+ consisting of two notes.</miscellaneous-field>
+ </miscellaneous>
+ </identification>
+ <part-list>
+ <score-part id="P0">
+ <part-name>MusicXML Part</part-name>
+ </score-part>
+ </part-list>
+ <part id="P0">
+ <measure number="1">
+ <attributes>
+ <divisions>960</divisions>
+ <time>
+ <beats>4</beats>
+ <beat-type>4</beat-type>
+ </time>
+ <clef>
+ <sign>G</sign>
+ <line>2</line>
+ </clef>
+ </attributes>
+ <note>
+ <pitch>
+ <step>B</step>
+ <octave>4</octave>
+ </pitch>
+ <duration>960</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <chord/>
+ <pitch>
+ <step>G</step>
+ <octave>4</octave>
+ </pitch>
+ <duration>960</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <rest/>
+ <duration>960</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ </measure>
+ </part>
+</score-partwise>
--- /dev/null
+\documentclass{article}
+\begin{document}
+Including MusicMXL file:
+\musicxmlfile[language=deutsch,absolute,no-beaming]{include.xml}
+\end{document}
--- /dev/null
+\documentclass{article}
+\begin{document}
+Including MusicMXL file:
+\musicxmlfile{include.xml}
+\end{document}
--- /dev/null
+\input texinfo @c -*- coding: utf-8; mode: texinfo; -*-
+@setfilename texinfo-musicxml-file.info
+@settitle MusicXML inside texinfo
+
+@node Top
+@top MusicMXL in texinfo
+
+MusicXML included in texinfo
+@musicxmlfile[language=deutsch,absolute,no-beaming]{include.xml}
+
+
+@bye
--- /dev/null
+\input texinfo @c -*- coding: utf-8; mode: texinfo; -*-
+@setfilename texinfo-musicxml-file.info
+@settitle MusicXML inside texinfo
+
+@node Top
+@top MusicMXL in texinfo
+
+MusicXML included in texinfo
+@musicxmlfile{include.xml}
+
+
+@bye
have melismata either by setting a property melismaBusy, or by setting
automaticMelismas (which will set melismas during slurs and ties). If
you want a different order than first Music, then Lyrics, you must
-precook a chord of staves/lyrics and label those. Of course, the
+precook a chord of staves/@/lyrics and label those. Of course, the
lyrics ignore any other rhythms in the piece."
}
\header{
texidoc="
-The tempo command supports text markup and/or duration=count. Using
-@code{Score.tempoHideNote}, one can hide the duration=count in the tempo mark.
+The tempo command supports text markup and/@/or `duration=count'. Using
+@code{Score.tempoHideNote}, one can hide the `duration=count' in the tempo mark.
"
}
% included from ./out-www/option-key.header
\header {
-texidoc="midi2ly @code{--key} works, this is F major"
+texidoc="@code{midi2ly}'s option @option{--key} works, this is F major."
options="--key=-1"
}
% end
}
\header {
-texidoc="midi2ly @code{--duration-quant} preserves first note length (16)"
+texidoc="@code{midi2ly}'s option @option{--duration-quant} preserves first note length (16)."
options="--duration-quant=16"
}
% included from ./out-www/voice-2.header
\header {
-texidoc="midi2ly @code{--duration-quant} quantizes durations of notes"
+texidoc="@code{midi2ly}'s option @option{--duration-quant} quantizes durations of notes."
options="--duration-quant=4"
}
% end
% included from ./out-www/voice-2.header
\header {
-texidoc="midi2ly @code{--start-quant} quantizes start of notes"
+texidoc="@code{midi2ly}'s option @option{--start-quant} quantizes start of notes."
options="--start-quant=4"
}
% end
TEXI2HTML_FLAGS += --nomenu
-# Urgh, how can I do two replacements at once without messing up the order of the list?
-TMP = $(sort $(MUSICXML_FILES) $(MUSICMXL_FILES) $(TEXINFO_SOURCES) )
-TMP1 = ${TMP:%.xml=$(outdir)/%.ly}
-COLLATED_FILES = ${TMP1:%.mxl=$(outdir)/%.ly}
+COLLATED_FILES = $(sort $(MUSICXML_FILES) $(MUSICMXL_FILES) $(TEXINFO_SOURCES) )
include $(depth)/make/stepmake.make
TITLE=Unofficial MusicXML test suite
+AUTHOR=Reinhold Kainhofer
TEST_SUITE_VERSION=0.1
+LILYPOND_BOOK_FLAGS += --load-custom-package=$(src-dir)/book-musicxml-testsuite.py
+# This breaks since *.tex and *.texi still contains ac/lily-xxxxxx references!
+#LILYPOND_BOOK_FLAGS += --use-source-file-names
ifeq ($(out),www)
local-WWW-2: zip
--- /dev/null
+# -*- coding: utf-8 -*-
+
+import book_base as BookBase
+import book_texinfo as BookTexinfo
+import book_snippets as BookSnippet
+import lilylib as ly
+
+MusicXMLOutputImage = r'''@noindent
+@ifinfo
+@image{%(info_image_path)s,,,%(alt)s,%(ext)s}
+@end ifinfo
+@html
+<p>
+ <a href="%(base)s%(ext)s">
+ <img align="middle" border="0" src="%(image)s" alt="%(alt)s">
+ </a>
+</p>
+@end html
+'''
+
+MusicXMLOutput = r'''
+@iftex
+@include %(base)s-systems.texi
+@end iftex
+'''
+
+MusicXMLPrintFilename = r'''
+@html
+<a href="%(base)s%(ext)s">
+@end html
+@file{%(filename)s}
+@html
+</a>
+@end html
+'''
+
+
+
+
+class BookMusicXML (BookTexinfo.BookTexinfoOutputFormat):
+ def __init__ (self):
+ BookTexinfo.BookTexinfoOutputFormat.__init__ (self)
+ self.format = "MusicXMLTest"
+ self.output[BookBase.OUTPUTIMAGE] = MusicXMLOutputImage
+ self.output[BookBase.OUTPUT] = MusicXMLOutput
+ self.output[BookBase.PRINTFILENAME] = MusicXMLPrintFilename
+ def snippet_class (self, type):
+ if type == "musicxml_file":
+ return MusicXMLTestSuiteSnippet
+ else:
+ return BookSnippet.snippet_type_to_class.get (type, BookSnippet.Snippet)
+ def snippet_output (self, basename, snippet):
+ return BookTexinfo.BookTexinfoOutputFormat.snippet_output (self, basename, snippet)
+
+
+class MusicXMLTestSuiteSnippet (BookSnippet.MusicXMLFileSnippet):
+ def __init__ (self, type, match, formatter, line_number, global_options):
+ BookSnippet.MusicXMLFileSnippet.__init__ (self, type, match, formatter, line_number, global_options)
+
+## TODO: Customize output with renderings from other MusicXML-supporting
+# applications. Also add some link to the intermediate .ly file
+
+
+BookBase.register_format (BookMusicXML ());
\header{
texidoc="The optimal page breaker will make trade-offs between
horizontal and vertical stretching so that the overall spacing
-will be more acceptable. The page-spacing-weight parameter
-controls the relative importance of vertical/horizontal spacing.
-Because ragged-last-bottom is on, there is no penalty for odd
+will be more acceptable. The @code{page-spacing-weight} parameter
+controls the relative importance of vertical/@/horizontal spacing.
+Because @code{ragged-last-bottom} is on, there is no penalty for odd
vertical spacing on the final page. As a result, only the first
page should be horizontally stretched.
"
texidoc ="The new part combiner stays apart from:
@itemize @bullet
@item different durations,
-@item different articulations (taking into account only slur/beam/tie), and
+@item different articulations (taking into account only slur/@/beam/@/tie), and
@item wide pitch ranges.
@end itemize
"
\header {
- texidoc = "Beam/rest collision resolution and normal rest/note
+ texidoc = "Beam/rest collision resolution and normal rest/@/note
collisions can be combined."
}
\version "2.14.0"
\header {
- texidoc = "Rests can have pitches--these will be affected by
-transposition and relativization. If a rest has a pitch, rest/rest and
-beam/rest collision resolving will leave it alone."
+ texidoc = "Rests can have pitches -- these will be affected by
+transposition and relativization. If a rest has a pitch, rest/@/rest and
+beam/@/rest collision resolving will leave it alone."
}
\header {
- texidoc = "@code{-ddebug-skyline} draws the outline of the skyline used."
+ texidoc = "@option{-ddebug-skyline} draws the outline of the skyline used."
}
\version "2.14.0"
--- /dev/null
+
+\version "2.15.9"
+
+\header {
+ texidoc = "Slurs handle avoid objects better.
+"
+}
+
+{
+ a'8 ( b''4 \fermata )
+}
one big file, since changing one score parameter for one situation
may affect several other situations.
- Tunable parameters are in @file{scm/slur.scm}.
+ Tunable parameters are in @file{scm/@/slur.scm}.
"
}
\header {
texidoc = "An accidental following a bar gets space so
- the left edge of the acc is at 0.3 - 0.6 staff space of the bar line"
+ the left edge of the acc is at 0.3 staff space from the bar line"
}
\version "2.14.0"
\header {
- texidoc = "Span bars can be turned on/off on a staff-by-staff basis."
+ texidoc = "Span bars can be turned on/@/off on a staff-by-staff basis."
}
\layout {
--- /dev/null
+\version "2.15.8"
+
+\header {
+ texidoc = "Spanners align to musical grobs in paper columns,
+ignoring things like pedal marks.
+
+"
+}
+
+\score {
+ <<
+ \new PianoStaff <<
+ \new Staff = "up" {
+ \clef treble
+ \repeat unfold 32 c'4
+ }
+ \new Dynamics = "dynamics" {
+ \repeat unfold 2 {
+ s1\cresc s1\f s1\dim s1\p
+ }
+ }
+ \new Staff = "down" {
+ \clef bass
+ \repeat unfold 32 c4
+ }
+ \new Dynamics= "pedal" {
+ \repeat unfold 2 {
+ s1\sustainOn s1\sustainOff
+ }
+ }
+ >>
+ >>
+}
\relative c'' {
\textLengthOn
- <c\3>4-"inside"( d' <e,\2>-"inside" g
+ <c\3>4-"outside"( d' <e,\2>-"inside" g
<c\1>1-"outside")
}
f4\f g a^\fermata |
R2.*3 |
c8\<\( c16 c ~ c2\! |
- c'2.\) |
\mark \default
- R2. |
+ c'2.\) |
\ottava #1
r4 d'4 r8 e |
\ottava #0
\header {
-
texidoc = "In chords, ties keep closer to the note head vertically,
-but never collide with heads or stems. Seconds are formatted up/down;
+but never collide with heads or stems. Seconds are formatted up/@/down;
the rest of the ties are positioned according to their vertical
position.
-The code does not handle all cases. Sometimes ties will printed on top
-of or very close to each other. This happens in the last chords of
-each system. "
-
+The code does not handle all cases. Sometimes ties will printed on top
+of or very close to each other. This happens in the last chords of
+each system."
}
texidoc = "Like normal ties, single semities (LaissezVibrerTie or
RepeatTie) get their direction from the stem direction, and may be
-tweaked with @code{#'direction}."
+tweaked with @code{'direction}."
}
\header {
texidoc = "Individual ties may be formatted manually by
-specifying their @code{direction} and/or @code{staff-position}."
+specifying their @code{direction} and/@/or @code{staff-position}."
}
@code{#f} (never print a bracket)
@item
-@code{#'if-no-beam} (only print a bracket if there is no beam)
+@code{'if-no-beam} (only print a bracket if there is no beam)
@end itemize
"
Interval
Axis_group_interface::relative_group_extent (vector<Grob *> const &elts,
Grob *common, Axis a)
+{
+ return relative_maybe_bound_group_extent (elts, common, a, false);
+}
+
+Interval
+Axis_group_interface::relative_maybe_bound_group_extent (vector<Grob *> const &elts,
+ Grob *common, Axis a, bool bound)
{
Interval r;
for (vsize i = 0; i < elts.size (); i++)
Grob *se = elts[i];
if (!to_boolean (se->get_property ("cross-staff")))
{
- Interval dims = se->extent (common, a);
+ Interval dims = (bound && has_interface (se)
+ ? generic_bound_extent (se, common, a)
+ : se->extent (common, a));
if (!dims.is_empty ())
r.unite (dims);
}
return r;
}
+Interval
+Axis_group_interface::generic_bound_extent (Grob *me, Grob *common, Axis a)
+{
+ /* trigger the callback to do skyline-spacing on the children */
+ if (a == Y_AXIS)
+ (void) me->get_property ("vertical-skylines");
+
+ extract_grob_set (me, "elements", elts);
+ vector<Grob *> new_elts;
+
+ SCM interfaces = me->get_property ("bound-alignment-interfaces");
+
+ for (vsize i = 0; i < elts.size (); i++)
+ for (SCM l = interfaces; scm_is_pair (l); l = scm_cdr (l))
+ if (elts[i]->internal_has_interface (scm_car (l)))
+ new_elts.push_back (elts[i]);
+
+ if (!new_elts.size ())
+ return robust_relative_extent (me, common, a);
+
+ if (!common)
+ common = common_refpoint_of_array (new_elts, me, a);
+
+ return relative_maybe_bound_group_extent (new_elts, common, a, true);
+}
+
Interval
Axis_group_interface::sum_partial_pure_heights (Grob *me, int start, int end)
{
vector<Grob *> current_elts;
current_elts.push_back (elements[i]);
while (i + 1 < elements.size ()
- && scm_eq_p (elements[i + 1]->get_property ("outside-staff-priority"), priority))
+ && scm_is_eq (elements[i + 1]->get_property ("outside-staff-priority"), priority))
{
if (!to_boolean (elements[i + 1]->get_property ("cross-staff")))
current_elts.push_back (elements[i + 1]);
/* properties */
"adjacent-pure-heights "
"axes "
+ "bound-alignment-interfaces "
"default-staff-staff-spacing "
"elements "
"max-stretch "
#include "pointer-group-interface.hh"
#include "rhythmic-head.hh"
#include "spanner.hh"
+#include "staff-symbol.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
#include "warn.hh"
return scm_from_double (offset + staff_space * shift);
}
+MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, pure_rest_collision_callback, 4, 1, "");
+SCM
+Beam::pure_rest_collision_callback (SCM smob,
+ SCM, /* prev_offset */
+ SCM, /* start */
+ SCM /* end */)
+{
+ Real amount = 0.0;
+
+ Grob *me = unsmob_grob (smob);
+ Grob *stem = unsmob_grob (me->get_object ("stem"));
+ if (!stem)
+ return scm_from_double (amount);
+ Grob *beam = unsmob_grob (stem->get_object ("beam"));
+ if (!beam
+ || !Beam::normal_stem_count (beam))
+ return scm_from_double (amount);
+
+ Real ss = Staff_symbol_referencer::staff_space (me);
+
+ /*
+ This gives the extrema of rest positions.
+ In general, beams are never typeset more than one staff space away
+ from the staff in either direction.
+ */
+ Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
+ Interval rest_max_pos = staff ? Staff_symbol::line_span (staff) : Interval (0.0, 0.0);
+ rest_max_pos.widen (1);
+ rest_max_pos *= ss / 2;
+
+ extract_grob_set (beam, "stems", stems);
+ vector<Grob *> my_stems;
+
+ for (vsize i = 0; i < stems.size (); i++)
+ if (Stem::head_count (stems[i]) || stems[i] == stem)
+ my_stems.push_back (stems[i]);
+
+ vsize idx = -1;
+
+ for (vsize i = 0; i < my_stems.size (); i++)
+ if (my_stems[i] == stem)
+ {
+ idx = i;
+ break;
+ }
+ Grob *left;
+ Grob *right;
+
+ if (idx == (vsize)-1 || my_stems.size () == 1)
+ return scm_from_double (amount);
+ else if (idx == 0)
+ left = right = my_stems[1];
+ else if (idx == my_stems.size () - 1)
+ left = right = my_stems[idx - 1];
+ else
+ {
+ left = my_stems[idx - 1];
+ right = my_stems[idx + 1];
+ }
+ Direction beamdir = get_grob_direction (beam);
+ /*
+ Take the position between the two bounding head_positions,
+ then bound it by the minimum and maximum positions outside the staff.
+ 4.0 = 2.0 to get out of staff space * 2.0 for the average
+ */
+ amount = min (max ((Stem::head_positions (left)[beamdir] + Stem::head_positions (right)[beamdir]) / 4.0, rest_max_pos[DOWN]), rest_max_pos[UP]);
+
+ return scm_from_double (amount);
+}
+
+
bool
Beam::is_knee (Grob *me)
{
return curve_coordinate (ts[0], other);
}
+vector<Real>
+Bezier::get_other_coordinates (Axis a, Real x) const
+{
+ Axis other = other_axis (a);
+ vector<Real> ts = solve_point (a, x);
+ vector<Real> sols;
+ for (vsize i = 0; i < ts.size (); i++)
+ sols.push_back (curve_coordinate (ts[i], other));
+ return sols;
+}
+
Real
Bezier::curve_coordinate (Real t, Axis a) const
{
return filter_solutions (sol);
}
+Real
+Bezier::minmax (Axis ax, Real l, Real r, Direction d) const
+{
+ return minmax (ax, l, r, d, 0, 0);
+}
+
+Real
+Bezier::minmax (Axis axis, Real l, Real r, Direction d, vsize left_index, vsize right_index) const
+{
+ Axis other = other_axis (axis);
+ Interval lr (l, r);
+ Drul_array<vector<Real> > sol;
+ Direction dir = LEFT;
+ do
+ {
+ Polynomial p (polynomial (axis));
+ p.coefs_[0] -= lr[dir];
+
+ sol[dir] = filter_solutions (p.solve ());
+ }
+ while (flip (&dir) != LEFT);
+
+ if (!sol[LEFT].size () || !sol[RIGHT].size ())
+ {
+ programming_error ("no solution found for Bezier intersection");
+ return 0.0;
+ }
+
+ Polynomial p (polynomial (other));
+
+ Drul_array<vsize> indices(left_index, right_index);
+ do
+ {
+ vector_sort (sol[dir], less<Real> ());
+ if (!Interval (0, sol[LEFT].size () - 1).contains (indices[dir]))
+ {
+ programming_error ("requested bezier solution outside range of solutions. defaulting to lowest solution.");
+ indices[dir] = 0;
+ }
+ }
+ while (flip (&dir) != LEFT);
+
+ return p.minmax (sol[LEFT][indices[LEFT]], sol[RIGHT][indices[RIGHT]], d != LEFT);
+}
+
/**
Compute the bounding box dimensions in direction of A.
*/
SCM def = get_default_child (user_mod);
if (scm_is_symbol (def))
{
- if (scm_memq (def, acc))
- acc = scm_delete_x (def, acc);
+ acc = scm_delete_x (def, acc);
acc = scm_cons (def, acc);
}
{
Stream_event *ev = unsmob_stream_event (sev);
SCM class_symbol = ev->get_property ("class");
- if (!scm_symbol_p (class_symbol))
+ if (!scm_is_symbol (class_symbol))
{
warning (_ ("Event class should be a symbol"));
return;
return select_pango_font (layout, chain);
else
#endif
- if (scm_instance_p (name))
+ if (scm_is_true (scm_instance_p (name)))
{
SCM base_size = scm_slot_ref (name, ly_symbol2scm ("default-size"));
SCM vec = scm_slot_ref (name, ly_symbol2scm ("size-vector"));
LY_DEFINE (ly_dir_p, "ly:dir?",
1, 0, 0, (SCM s),
- "Is @var{s} a direction? Valid directions are @code{-1},"
- " @code{0}, or@tie{}@code{1}, where @code{-1} represents"
+ "Is @var{s} a direction? Valid directions are @w{@code{-1}},"
+ " @code{0}, or@tie{}@code{1}, where @w{@code{-1}} represents"
" left or down, @code{1}@tie{}represents right or up, and @code{0}"
" represents a neutral direction.")
{
1, 0, 0, (SCM str),
"Encode all characters in string @var{str} with hexadecimal"
" percent escape sequences, with the following exceptions:"
- " characters @code{-}, @code{.}, @code{/}, and @code{_}; and"
+ " characters @w{@code{-},} @code{.}, @code{/}, and @code{_}; and"
" characters in ranges @code{0-9}, @code{A-Z}, and @code{a-z}.")
{
LY_ASSERT_TYPE (scm_is_string, str, 1);
string m = "w";
string f = ly_scm2string (file_name);
FILE *stderrfile;
- if (mode != SCM_UNDEFINED && scm_string_p (mode))
+ if (scm_is_string (mode))
m = ly_scm2string (mode);
/* dup2 and (fileno (current-error-port)) do not work with mingw'c
gcc -mwindows. */
self_scm_ = SCM_EOL;
immutable_property_alist_ = s.immutable_property_alist_;
- mutable_property_alist_ = ly_deep_copy (s.mutable_property_alist_);
+ mutable_property_alist_ = SCM_EOL;
interfaces_ = s.interfaces_;
object_alist_ = SCM_EOL;
layout_ = 0;
smobify_self ();
+
+ mutable_property_alist_ = ly_deep_copy (s.mutable_property_alist_);
+
}
Grob::~Grob ()
#include "hairpin.hh"
+#include "axis-group-interface.hh"
#include "dimensions.hh"
#include "international.hh"
#include "line-interface.hh"
else
{
bool neighbor_found = false;
- Spanner *adjacent;
+ Spanner *adjacent = NULL;
extract_grob_set (me, "adjacent-spanners", neighbors);
for (vsize i = 0; i < neighbors.size (); i++)
{
}
}
- Interval e = robust_relative_extent (b, common, X_AXIS);
+ Interval e = (Axis_group_interface::has_interface (b)
+ ? Axis_group_interface::generic_bound_extent (b, common, X_AXIS)
+ : robust_relative_extent (b, common, X_AXIS));
if (neighbor_found)
{
if (Hairpin::has_interface (adjacent))
struct Axis_group_interface
{
static SCM generic_group_extent (Grob *me, Axis a);
+ static Interval generic_bound_extent (Grob *me, Grob *common, Axis a);
static Interval pure_group_height (Grob *me, int start, int end);
DECLARE_SCHEME_CALLBACK (width, (SCM smob));
DECLARE_SCHEME_CALLBACK (calc_x_common, (SCM smob));
DECLARE_SCHEME_CALLBACK (calc_pure_y_common, (SCM));
static Interval relative_group_extent (vector<Grob *> const &list,
Grob *common, Axis);
+ static Interval relative_maybe_bound_group_extent (vector<Grob *> const &list,
+ Grob *common, Axis, bool);
static Interval relative_pure_height (Grob *me, int start, int end);
static Interval combine_pure_heights (Grob *me, SCM, int, int);
static Interval sum_partial_pure_heights (Grob *me, int, int);
static Interval no_visible_stem_positions (Grob *me, Interval default_value);
DECLARE_SCHEME_CALLBACK (rest_collision_callback, (SCM element, SCM prev_off));
+ DECLARE_SCHEME_CALLBACK (pure_rest_collision_callback, (SCM element, SCM prev_off, SCM, SCM));
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (calc_beaming, (SCM));
DECLARE_SCHEME_CALLBACK (calc_stem_shorten, (SCM));
Bezier extract (Real, Real) const;
Real get_other_coordinate (Axis a, Real x) const;
+ vector<Real> get_other_coordinates (Axis a, Real x) const;
vector<Real> solve_point (Axis, Real coordinate) const;
+ Real minmax (Axis, Real, Real, Direction) const;
+ Real minmax (Axis, Real, Real, Direction, vsize, vsize) const;
vector<Real> solve_derivative (Offset) const;
Interval extent (Axis) const;
Interval control_point_extent (Axis) const;
public:
DECLARE_GROB_INTERFACE ();
- static Spring get_spacing (Grob *, Grob *right_col);
+ static Spring get_spacing (Grob *, Grob *, Real);
static Interval bar_y_positions (Grob *);
};
LY_DEFINE (ly_item_break_dir, "ly:item-break-dir",
1, 0, 0, (SCM it),
- "The break status direction of item @var{it}. @code{-1} means"
+ "The break status direction of item @var{it}. @w{@code{-1}} means"
" end of line, @code{0}@tie{}unbroken, and"
" @code{1}@tie{}beginning of line.")
{
"Whether these versions are visible and take up space is"
" determined by the outcome of the @code{break-visibility}"
" grob property, which is a function taking a direction"
- " (@code{-1}, @code{0} or@tie{}@code{1}) as an argument. It"
+ " (@w{@code{-1}}, @code{0} or@tie{}@code{1}) as an argument. It"
" returns a cons of booleans, signifying whether this grob"
" should be transparent and have no extent.\n"
"\n"
&& !scm_is_eq (last, key))
{
SCM restore = SCM_EOL;
- SCM *tail = &restore;
for (SCM s = last; scm_is_pair (s); s = scm_cdr (s))
{
SCM new_alter_pair = scm_assoc (scm_caar (s), key);
|| ((ly_scm2rational (scm_cdr (new_alter_pair)) - old_alter) * old_alter
< Rational (0)))
{
- *tail = scm_cons (scm_car (s), *tail);
- tail = SCM_CDRLOC (*tail);
+ restore = scm_cons (scm_car (s), restore);
}
}
key_event_
? key_event_->self_scm () : SCM_EOL);
- cancellation_->set_property ("alteration-alist", scm_reverse (restore));
+ cancellation_->set_property ("alteration-alist", restore);
cancellation_->set_property ("c0-position",
get_property ("middleCPosition"));
}
ACCENT \\[`'"^]
NATIONAL [\001-\006\021-\027\031\036]
TEX {AA}|-|{PUNCT}|{ACCENT}|{NATIONAL}
-WORD {A}{AN}*
DASHED_WORD {A}({AN}|-)*
DASHED_KEY_WORD \\{DASHED_WORD}
FRACTION {N}+\/{N}+
INT -?{UNSIGNED}
REAL ({INT}\.{N}*)|(-?\.{N}+)
-KEYWORD \\{WORD}
WHITE [ \n\t\f\r]
HORIZONTALWHITE [ \t]
BLACK [^ \n\t\f\r]
<*>\r {
- // windows-suck-suck-suck
+ // swallow and ignore carriage returns
}
<extratoken>{ANY_CHAR} {
this->here_input ().get_source_file ()->set_line (here_input ().start (), i);
}
-<version>. {
+<version>{ANY_CHAR} {
LexerError (_ ("quoted string expected after \\version").c_str ());
yy_pop_state ();
}
-<sourcefilename>. {
+<sourcefilename>{ANY_CHAR} {
LexerError (_ ("quoted string expected after \\sourcefilename").c_str ());
yy_pop_state ();
}
-<sourcefileline>. {
+<sourcefileline>{ANY_CHAR} {
LexerError (_ ("integer expected after \\sourcefileline").c_str ());
yy_pop_state ();
}
"%"+"}" {
yy_pop_state ();
}
- <<EOF>> {
- LexerError (_ ("EOF found inside a comment").c_str ());
- is_main_input_ = false; // should be safe , can't have \include in --safe.
- if (! close_input ())
- yyterminate (); // can't move this, since it actually rets a YY_NULL
- }
}
new_input (s, sources_);
yy_pop_state ();
}
-<incl>\\{BLACK}*{WHITE} { /* got the include identifier */
+<incl>\\{BLACK}*{WHITE}? { /* got the include identifier */
string s = YYText () + 1;
strip_trailing_white (s);
if (s.length () && (s[s.length () - 1] == ';'))
scm_display (sid, err);
}
}
-<incl>\"[^"]* { // backup rule
+<incl,version,sourcefilename>\"[^"]* { // backup rule
error (_ ("end quote missing"));
exit (1);
}
yylval.scm = scan_fraction (YYText ());
return FRACTION;
}
-
{DIGIT} {
yylval.i = String_convert::dec2int (string (YYText ()));
return DIGIT;
}
+ {UNSIGNED}/\/[^0-9] { // backup rule
+ yylval.i = String_convert::dec2int (string (YYText ()));
+ return UNSIGNED;
+ }
+ {UNSIGNED}/\/ | // backup rule
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
return UNSIGNED;
yylval.scm = scan_fraction (YYText ());
return FRACTION;
}
+ {UNSIGNED}/\/[^0-9] { // backup rule
+ yylval.i = String_convert::dec2int (string (YYText ()));
+ return UNSIGNED;
+ }
+ {UNSIGNED}/\/ | // backup rule
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
return UNSIGNED;
yylval.scm = scan_fraction (YYText ());
return FRACTION;
}
+ {UNSIGNED}/\/[^0-9] { // backup rule
+ yylval.i = String_convert::dec2int (string (YYText ()));
+ return UNSIGNED;
+ }
+ {UNSIGNED}/\/ | // backup rule
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
return UNSIGNED;
}
<*><<EOF>> {
- if (is_main_input_)
+ if (YY_START == longcomment)
+ {
+ LexerError (_ ("EOF found inside a comment").c_str ());
+ is_main_input_ = false; // should be safe , can't have \include in --safe.
+ if (!close_input ())
+ yyterminate (); // can't move this, since it actually rets a YY_NULL
+ }
+ else if (is_main_input_)
{
/* 2 = init.ly + current file.
> because we're before closing, but is_main_input_ should
}
}
-{WORD} {
- return scan_bare_word (YYText ());
-}
-{KEYWORD} {
- return scan_escaped_word (YYText () + 1);
-}
+-{UNSIGNED} | // backup rule
{REAL} {
Real r;
int cnv = sscanf (YYText (), "%lf", &r);
yylval.scm = scm_from_double (r);
return REAL;
}
+-\. { // backup rule
+ yylval.scm = scm_from_double (0.0);
+ return REAL;
+}
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
#include "item.hh"
#include "lily-proto.hh"
#include "line-interface.hh"
+#include "note-column.hh"
#include "output-def.hh"
+#include "paper-column.hh"
#include "pointer-group-interface.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
? columns[0] : columns.back ();
}
+ Real x_coord = (Paper_column::has_interface (bound_grob)
+ ? Axis_group_interface::generic_bound_extent (bound_grob, commonx, X_AXIS)
+ : robust_relative_extent (bound_grob, commonx, X_AXIS)).linear_combination (attach);
+
+ Grob *acc = Note_column::accidentals (bound_grob->get_parent (X_AXIS));
+ if (acc && to_boolean (ly_assoc_get (ly_symbol2scm ("end-on-accidental"), details, SCM_BOOL_F)))
+ x_coord = robust_relative_extent (acc, commonx, X_AXIS).linear_combination (attach);
+
details = scm_acons (ly_symbol2scm ("X"),
- scm_from_double (robust_relative_extent (bound_grob, commonx, X_AXIS)
- .linear_combination (attach)),
+ scm_from_double (x_coord),
details);
}
{
_i ("LOGLEVEL"), "loglevel", 'l', _i ("print log messages according to"
" LOGLEVEL. Possible values are:\n"
- "NONE, ERROR, WARNING, BASIC, PROGRESS (default) and DEBUG.")
+ "NONE, ERROR, WARNING, BASIC, PROGRESS, INFO (default) and DEBUG.")
},
{_i ("FILE"), "output", 'o', _i ("write output to FILE (suffix will be added)")},
{0, "relocate", 0, _i ("relocate using directory of lilypond program")},
Grob *f = ft.script_;
f->set_parent (ft.head_, X_AXIS);
f->set_parent (ft.head_, Y_AXIS);
- f->set_property ("avoid-slur", SCM_BOOL_F);
+ f->set_property ("avoid-slur", ly_symbol2scm ("inside"));
if (hordir == LEFT
&& unsmob_grob (ft.head_->get_object ("accidental-grob")))
Side_position_interface::add_support (f,
&& Rhythmic_head::dot_count (head_up) < Rhythmic_head::dot_count (head_down))
{
shift_amount = -1;
- if (!touch || full_collide)
+ if (!touch)
// remember to leave clearance between stems
stem_to_stem = true;
}
if (beams_drul[LEFT] && beams_drul[LEFT] == beams_drul[RIGHT])
{
correction = knee_correction (me, stems_drul[RIGHT], increment);
- *fixed += correction;
}
else
{
&& !acc_right)
correction = same_direction_correction (me, head_posns);
+ *fixed += correction;
*space += correction;
/* there used to be a correction for bar_xextent () here, but
Status last_playing_;
/*
- TODO: this is getting of hand...
+ TODO: this is getting off hand...
*/
Context_handle handles_[NUM_OUTLETS];
split_list_ = SCM_EOL;
state_ = APART;
playing_state_ = APART;
+ last_playing_ = APART;
busy_ = false;
notice_busy_ = false;
Outlet_type c1 = (last_playing_ == SOLO2) ? CONTEXT_NULL : CONTEXT_SHARED;
Outlet_type c2 = (last_playing_ == SOLO2) ? CONTEXT_SHARED : CONTEXT_NULL;
substitute_both (c1, c2);
- kill_mmrest ((last_playing_ == SOLO2)
- ? CONTEXT_ONE : CONTEXT_TWO);
+ kill_mmrest ((last_playing_ == SOLO2) ? CONTEXT_ONE : CONTEXT_TWO);
kill_mmrest (CONTEXT_SHARED);
if (playing_state_ != UNISONO
* though), we have to prepend it manually. */
if (g_without_BOM) // conversion to UTF-16be might have failed (shouldn't!)
{
- g = new char[bytes_written + 3];
+ g = (char*)malloc ( sizeof(char) * (bytes_written + 3));
char const *BOM = "\xFE\xFF";
strcpy (g, BOM);
memcpy (&g[2], g_without_BOM, bytes_written + 1); // Copy string + \0
- free (g_without_BOM);
+ g_free (g_without_BOM);
bytes_written += 2;
}
}
vector<Stream_event *> stop_events_;
vector<Grob *> slurs_;
vector<Grob *> end_slurs_;
+ vector<Grob_info> objects_to_acknowledge_;
protected:
DECLARE_TRANSLATOR_LISTENER (phrasing_slur);
void
Phrasing_slur_engraver::acknowledge_extra_object (Grob_info info)
{
- Slur::auxiliary_acknowledge_extra_object (info, slurs_, end_slurs_);
+ objects_to_acknowledge_.push_back (info);
}
void
void
Phrasing_slur_engraver::stop_translation_timestep ()
{
+ for (vsize i = 0; i < objects_to_acknowledge_.size (); i++)
+ Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slurs_, end_slurs_);
+
end_slurs_.clear ();
start_events_.clear ();
stop_events_.clear ();
+ objects_to_acknowledge_.clear ();
}
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, accidental);
amount += ss / 2;
if (!position_override)
- amount += 2 * ss * get_grob_direction (me);;
+ amount += 2 * ss * get_grob_direction (me);
+
return scm_from_double (amount);
}
vector<Grob *> rheads_;
Grob *stem_;
Grob *note_column_;
- Grob *dotcol_;
Grob *arpeggio_;
TRANSLATOR_DECLARATIONS (Rhythmic_column_engraver);
}
if (arpeggio_)
- note_column_->set_object ("arpeggio", arpeggio_->self_scm ());
+ {
+ Pointer_group_interface::add_grob (note_column_, ly_symbol2scm ("elements"), arpeggio_);
+ note_column_->set_object ("arpeggio", arpeggio_->self_scm ());
+ }
}
}
if (left)
elts = Accidental_placement::get_relevant_accidentals (read_only_elts, left);
else
- {
- elts = read_only_elts;
-
- /* This is a special-case for NoteColumn: we want to include arpeggio in its
- skyline (so spacing takes it into account) but we don't want to include it
- in the NoteColumn's extent because some spanners (eg. Hairpin) bound themselves
- on the NoteColumn and we don't want them to include arpeggios in their bounds.
- */
- if (Grob *a = Note_column::arpeggio (me))
- {
- elts.push_back (a);
- }
- }
+ elts = read_only_elts;
Grob *ycommon = common_refpoint_of_array (elts, me, Y_AXIS);
{
Music *m = get_music ();
SCM proc = m->get_property ("elements-callback");
- if (scm_procedure_p (proc))
+ if (ly_is_procedure (proc))
return scm_call_1 (proc, m->self_scm ());
else
return SCM_EOL;
vector<Stream_event *> stop_events_;
vector<Grob *> slurs_;
vector<Grob *> end_slurs_;
+ vector<Grob_info> objects_to_acknowledge_;
void set_melisma (bool);
void
Slur_engraver::acknowledge_extra_object (Grob_info info)
{
- Slur::auxiliary_acknowledge_extra_object (info, slurs_, end_slurs_);
+ objects_to_acknowledge_.push_back (info);
}
void
s->set_bound (RIGHT, unsmob_grob (get_property ("currentMusicalColumn")));
announce_end_grob (s, SCM_EOL);
}
+
+ for (vsize i = 0; i < objects_to_acknowledge_.size (); i++)
+ Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slurs_, end_slurs_);
+
+ objects_to_acknowledge_.clear ();
end_slurs_.clear ();
start_events_.clear ();
stop_events_.clear ();
0.0);
yext.widen (slur_padding);
- const Real EPS = 1e-3;
- Interval bezext (curve.control_[0][X_AXIS], curve.control_[3][X_AXIS]);
- bool consider[] = {false, false, false};
- Real ys[] = {0, 0, 0};
+ Interval exts[] = {xext, yext};
bool do_shift = false;
-
- for (int d = LEFT, k = 0; d <= RIGHT; d++, k++)
+ Real EPS = 1.0e-5;
+ if (avoid == ly_symbol2scm ("outside"))
{
- Real x = xext.linear_combination ((Direction) d);
- consider[k] = bezext.contains (x);
-
- if (consider[k])
+ Direction d = LEFT;
+ do
{
- ys[k]
- = (fabs (bezext[LEFT] - x) < EPS)
- ? curve.control_[0][Y_AXIS]
- : ((fabs (bezext[RIGHT] - x) < EPS)
- ? curve.control_[3][Y_AXIS]
- : curve.get_other_coordinate (X_AXIS, x));
-
- /* Request shift if slur is contained script's Y, or if
- script is inside slur and avoid == outside. */
- if (yext.contains (ys[k])
- || (dir * ys[k] > dir * yext[-dir] && avoid == ly_symbol2scm ("outside")))
- do_shift = true;
+ Real x = minmax (-d, xext[d], curve.control_[d == LEFT ? 0 : 3][X_AXIS] + -d * EPS);
+ Real y = curve.get_other_coordinate (X_AXIS, x);
+ do_shift = y == minmax (dir, yext[-dir], y);
+ if (do_shift)
+ break;
}
+ while (flip (&d) != LEFT);
}
-
- Real avoidance_offset = 0.0;
- if (do_shift)
+ else
{
- for (int d = LEFT, k = 0; d <= RIGHT; d++, k++)
- if (consider[k])
- avoidance_offset = dir * (max (dir * avoidance_offset,
- dir * (ys[k] - yext[-dir] + dir * slur_padding)));
+ for (int a = X_AXIS; a < NO_AXES; a++)
+ {
+ Direction d = LEFT;
+ do
+ {
+ vector<Real> coords = curve.get_other_coordinates (Axis (a), exts[a][d]);
+ for (vsize i = 0; i < coords.size (); i++)
+ {
+ do_shift = exts[(a + 1) % NO_AXES].contains (coords[i]);
+ if (do_shift)
+ break;
+ }
+ if (do_shift)
+ break;
+ }
+ while (flip (&d) != LEFT);
+ if (do_shift)
+ break;
+ }
}
+
+ Real avoidance_offset = do_shift ? curve.minmax (X_AXIS, max (xext[LEFT], curve.control_[0][X_AXIS] + EPS), min (xext[RIGHT], curve.control_[3][X_AXIS] - EPS), dir) - yext[-dir] : 0.0;
+
return scm_from_double (offset + avoidance_offset);
}
int *column,
int *byte_offset) const
{
+ // Initialize arguments to defaults, needed if pos_str0 is not in source
*line_number = 0;
+ *line_char = 0;
+ *column = 0;
+ *byte_offset = 0;
if (!contains (pos_str0))
return;
string line_begin (line_start, left);
char const *line_chars = line_begin.c_str ();
- *line_char = 0;
- *column = 0;
- *byte_offset = 0;
-
while (left > 0)
{
size_t thislen = utf8_char_len (*line_chars);
}
else if (Staff_spacing::has_interface (sp))
{
- Spring spring = Staff_spacing::get_spacing (sp, rc);
+ Spring spring = Staff_spacing::get_spacing (sp, rc, 0.0);
dists[d] = max (dists[d], spring.min_distance ());
}
vector<Spring> springs;
Spring spring;
+ Real full_measure_space = 0.0;
+ if (Paper_column::is_musical (r)
+ && l->break_status_dir () == CENTER
+ && fills_measure (me, l, r))
+ full_measure_space = robust_scm2double (l->get_property ("full-measure-extra-space"), 1.0);
+
Moment dt = Paper_column::when_mom (r) - Paper_column::when_mom (l);
if (dt == Moment (0, 0))
*/
assert (spacing_grob->get_column () == l);
- springs.push_back (Staff_spacing::get_spacing (spacing_grob, r));
+ springs.push_back (Staff_spacing::get_spacing (spacing_grob, r,
+ full_measure_space));
}
}
spring *= 0.8;
}
- if (Paper_column::is_musical (r)
- && l->break_status_dir () == CENTER
- && fills_measure (me, l, r))
- {
- Real full_measure_extra_space = robust_scm2double (l->get_property ("full-measure-extra-space"), 1.0);
- spring.set_distance (spring.distance () + full_measure_extra_space);
- spring.set_default_compress_strength ();
- }
-
if (options->stretch_uniformly_ && l->break_status_dir () != RIGHT)
{
spring.set_min_distance (0.0);
LY_DEFINE (ly_spanner_bound, "ly:spanner-bound",
2, 0, 0, (SCM spanner, SCM dir),
- "Get one of the bounds of @var{spanner}. @var{dir} is @code{-1}"
+ "Get one of the bounds of @var{spanner}. @var{dir} is @w{@code{-1}}"
" for left, and @code{1} for right.")
{
LY_ASSERT_TYPE (unsmob_spanner, spanner, 1);
We arrange things so that the fixed distance will be attained when the
line is compressed with a force of 1.0 */
Spring
-Staff_spacing::get_spacing (Grob *me, Grob *right_col)
+Staff_spacing::get_spacing (Grob *me, Grob *right_col, Real situational_space)
{
Item *me_item = dynamic_cast<Item *> (me);
Grob *left_col = me_item->get_column ();
}
SCM alist = last_grob->get_property ("space-alist");
- if (!scm_list_p (alist))
+ if (!ly_is_list (alist))
return Spring ();
SCM space_def = scm_sloppy_assq (ly_symbol2scm ("first-note"), alist);
ideal = fixed;
}
+ Real stretchability = ideal - fixed;
+
+ /* 'situational_space' passed by the caller
+ could include full-measure-extra-space */
+ ideal += situational_space;
+
Real optical_correction = next_notes_correction (me, last_grob);
+ fixed += optical_correction;
+ ideal += optical_correction;
+
Real min_dist = Paper_column::minimum_distance (left_col, right_col);
/* ensure that the "fixed" distance will leave a gap of at least 0.3 ss. */
Real min_dist_correction = max (0.0, 0.3 + min_dist - fixed);
- Real correction = max (optical_correction, min_dist_correction);
-
- fixed += correction;
- ideal += correction;
+ fixed += min_dist_correction;
+ ideal = max (ideal, fixed);
Spring ret (ideal, min_dist);
- ret.set_inverse_stretch_strength (max (0.0, ideal - fixed));
+ ret.set_inverse_stretch_strength (max (0.0, stretchability));
+ ret.set_inverse_compress_strength (max (0.0, ideal - fixed));
return ret;
}
}
LY_DEFINE (ly_stencil_combine_at_edge, "ly:stencil-combine-at-edge",
- 4, 2, 0, (SCM first, SCM axis, SCM direction,
+ 4, 1, 0, (SCM first, SCM axis, SCM direction,
SCM second,
SCM padding),
"Construct a stencil by putting @var{second} next to @var{first}."
LY_DEFINE (ly_stencil_aligned_to, "ly:stencil-aligned-to",
3, 0, 0, (SCM stil, SCM axis, SCM dir),
"Align @var{stil} using its own extents. @var{dir} is a number."
- " @code{-1} and @code{1} are left and right, respectively."
+ " @w{@code{-1}} and @code{1} are left and right, respectively."
" Other values are interpolated (so @code{0} means the center).")
{
LY_ASSERT_SMOB (Stencil, stil, 1);
// (*it).moment_ already stores the end of the tied note!
Moment skip = now_mom () - (*it).end_moment_;
an->tie_to (th, skip);
- // this invalidates the iterator, we are leaving the loop anyway
- heads_to_tie_.erase (it);
+ it = heads_to_tie_.erase (it);
}
}
}
(ly:stencil-combine-at-edge
(ly:accidental-interface::print grob) Y UP
(grob-interpret-markup grob (markup #:line
- (#:fontsize -1 (#:musicglyph "flags.ugrace")))) -1.3 0))
+ (#:fontsize -1 (#:musicglyph "flags.ugrace")))) -1.3))
}
%
reduced_ss# = staff_space# * reduction;
define_pixels (reduced_ss);
+ % G clef has now a smaller upper loop than it used to have.
+ % Too small loop in reduced clef (G_change) interacts badly
+ % with stafflines, so we make reduced clef's loop a bit bigger.
+ reduced_loop_correction := min (max (0.94, (0.6 + 0.46 * reduction)), 1);
+
thinness = 0.095 staff_space + 0.75 linethickness;
downstroke_dir = unitvector (14, -75);
downstroke_angle = angle downstroke_dir;
breapth_factor = 21/14;
inner_thick_end = 45;
inner_start_angle = downstroke_angle - 43;
- thickness = .32 reduced_ss + 1.1 linethickness;
+ thickness = .33 reduced_ss + 1.1 linethickness;
thinnib = thinness;
set_char_box (0, 1.71 * breapth_factor * reduced_ss#,
- 2.6 * reduced_ss#, 5 * reduced_ss#);
+ 2.55 * reduced_ss#, 4.8 * reduced_ss# / reduced_loop_correction);
center := (breapth_factor * reduced_ss, 0);
y5r = .37 reduced_ss + ypart center;
penpos5 (thickness, upward_swoosh_angle);
- z6 = center + whatever * downstroke_dir;
- y6 = ypart center + 2 reduced_ss;
+ z6 = center + whatever * downstroke_dir + (-0.02, 0) * reduced_ss;
+ y6 = ypart center + 1.95 reduced_ss / reduced_loop_correction;
% penpos6 is computed later
- z7l - z6 = whatever * (z5 - z6) ;
- y7l = 3.5 reduced_ss;
+ z7l - z6 = whatever * (z5 - z6);
+ y7l = 3.38 reduced_ss / reduced_loop_correction;
penpos7 (thickness, upward_swoosh_angle);
- x9 = .7 [x10, x7r];
- top y9l = 5 reduced_ss;
+ x9 = .75 [x10, x7r];
+ top y9l = 4.78 reduced_ss / reduced_loop_correction;
penpos9 (1.45 thickness, -70);
- x11 - x13r = 1.5 reduced_ss + 0.5 thinnib;
- y11 = ypart center - 47/28 reduced_ss;
- y12 = ypart center - 71/28 reduced_ss;
+ x11 - x13r = 1.44 * reduced_ss + 0.5 thinnib;
+ y11 = ypart center - 45/28 reduced_ss;
+ y12 = ypart center - 69/28 reduced_ss;
y13 = .48 [y12, y4r];
x12r = xpart (.45 [z13r, z11] + .75 reduced_ss * downstroke_dir);
% z10 = center + whatever * dir (downstroke_angle - 1.5);
- x10 = x6 - 2 thinnib;
- y10 = ypart center + 3.5 reduced_ss;
+ x10 = x6 - 1.85 thinnib * reduction / reduced_loop_correction;
+ y10 = ypart center + 3.32 reduced_ss / reduced_loop_correction;
y10l - y10r = 1.0 thickness;
z10r - z10l = .7 thinnib * dir (downstroke_angle + 90)
+ whatever * downstroke_dir;
z10 = .5 [z10l, z10r];
- z11 = center + whatever * downstroke_dir + (-0.05 reduced_ss, 0);
+ z11 = center + whatever * downstroke_dir + (0.03 reduced_ss, 0);
penpos11 (thinnib, start_angle + 90);
penpos12 (thinnib, bot_angle + 90);
z10' = point 0.3 of pat;
penpos10' (1.3 thinnib, angle (direction 0.3 of pat) + 50);
- z11' = point 1.5 of pat;
+ z11' = point 1.5 of pat + (0.033, -0.5) * reduced_ss;
penpos11' (thinnib, angle (direction 1.5 of pat) + 90);
z21l = z20l;
rep = snippet.get_replacements ()
if PRINTFILENAME in snippet.option_dict:
rep['base'] = basename
- rep['filename'] = os.path.basename (snippet.substring ('filename'))
+ rep['filename'] = os.path.basename (snippet.filename)
+ rep['ext'] = snippet.ext
str = self.output[PRINTFILENAME] % rep
return str
PRINTFILENAME: r'''<textobject>
<simpara>
- <ulink url="%(base)s.ly">
+ <ulink url="%(base)s%(ext)s">
<filename>
%(filename)s
</filename>
'multiline_comment':
r'''(?smx)(?P<match>\s*(?!@c\s+)(?P<code><!--\s.*?!-->)\s)''',
+ 'musicxml_file':
+ r'''(?mx)
+ (?P<match>
+ <musicxmlfile\s*(?P<options>.*?)\s*>
+ \s*(?P<filename>.*?)\s*
+ </musicxmlfile\s*>)''',
+
'verb':
r'''(?x)(?P<match>(?P<code><pre>.*?</pre>))''',
</p>''',
BEFORE: r'''<p>
- <a href="%(base)s.ly">''',
+ <a href="%(base)s%(ext)s">''',
OUTPUT: r'''
<img align="middle"
src="%(image)s"
alt="%(alt)s">''',
- PRINTFILENAME: '<p><tt><a href="%(base)s.ly">%(filename)s</a></tt></p>',
+ PRINTFILENAME: '<p><tt><a href="%(base)s%(ext)s">%(filename)s</a></tt></p>',
QUOTE: r'''<blockquote>
%(str)s
str = ''
rep = snippet.get_replacements ();
rep['base'] = basename
+ rep['filename'] = os.path.basename (snippet.filename)
+ rep['ext'] = snippet.ext
str += self.output_print_filename (basename, snippet)
if VERBATIM in snippet.option_dict:
rep['verb'] = BookBase.verbatim_html (snippet.verb_ly ())
(?P<filename>\S+?)
})''',
+ 'musicxml_file':
+ r'''(?smx)
+ ^[^%\n]*?
+ (?P<match>
+ \\musicxmlfile\s*(
+ \[
+ \s*(?P<options>.*?)\s*
+ \])?\s*\{
+ (?P<filename>\S+?)
+ })''',
+
'singleline_comment':
r'''(?mx)
^.*?
FILENAME = 'filename'
FILTER = 'filter'
FRAGMENT = 'fragment'
-LANG = 'lang' ## TODO: This is handled nowhere!
LAYOUT = 'layout'
LILYQUOTE = 'lilyquote'
LINE_WIDTH = 'line-width'
NOFRAGMENT = 'nofragment'
NOGETTEXT = 'nogettext'
NOINDENT = 'noindent'
-NOQUOTE = 'noquote'
INDENT = 'indent'
NORAGGED_RIGHT = 'noragged-right'
NOTES = 'body'
# NOTIME and NOGETTEXT have no opposite so they aren't part of this
# dictionary.
-# NOQUOTE is used internally only.
no_options = {
NOFRAGMENT: FRAGMENT,
NOINDENT: INDENT,
PRINTFILENAME,
DOCTITLE,
TEXIDOC,
- LANG,
VERBATIM,
FILENAME,
ALT,
-FRAGMENT_LY = r'''
-%(notes_string)s
-{
-
-
-%% ****************************************************************
-%% ly snippet contents follows:
-%% ****************************************************************
-%(code)s
-
-
-%% ****************************************************************
-%% end ly snippet
-%% ****************************************************************
-}
-'''
-
def classic_lilypond_book_compatibility (key, value):
if key == 'singleline' and value == None:
return (RAGGED_RIGHT, None)
\paper {
%(paper_string)s
- force-assignment = #""
line-width = #(- line-width (* mm %(padding_mm)f))
}
%% ****************************************************************
'''
+FRAGMENT_LY = r'''
+%(notes_string)s
+{
+%% ****************************************************************
+%% ly snippet contents follows:
+%% ****************************************************************
+%(code)s
+%% ****************************************************************
+%% end ly snippet
+%% ****************************************************************
+}
+'''
+
return self.option_list
def compose_ly (self, code):
- if FRAGMENT in self.option_dict:
- body = FRAGMENT_LY
- else:
- body = FULL_LY
# Defaults.
relative = 1
d = globals().copy()
d.update (locals())
d.update (self.global_options.information)
+ if FRAGMENT in self.option_dict:
+ body = FRAGMENT_LY
+ else:
+ body = FULL_LY
return (PREAMBLE_LY + body) % d
def get_checksum (self):
os.makedirs (dst_path)
os.link (src, dst)
+ def additional_files_to_consider (self, base, full):
+ return []
+ def additional_files_required (self, base, full):
+ return []
+
def all_output_files (self, output_dir, output_dir_files):
"""Return all files generated in lily_output_dir, a set.
if 'ddump-signature' in self.global_options.process_cmd:
consider_file (systemfile + '.signature')
+ map (consider_file, self.additional_files_to_consider (base, full))
+ map (require_file, self.additional_files_required (base, full))
return (result, missing)
"""Pass input through cmd, and return the result."""
if self.global_options.verbose:
- progress (_ ("Opening filter `%s'\n") % cmd)
+ progress (_ ("Running through filter `%s'\n") % cmd)
# TODO: Use Popen once we resolve the problem with msvcrt in Windows:
(stdin, stdout, stderr) = os.popen3 (cmd)
status = 0
output = stdout.read ()
status = stdout.close ()
- error = stderr.read ()
+ err = stderr.read ()
if not status:
status = 0
signal = 0x0f & status
- if status or (not output and error):
+ if status or (not output and err):
exit_status = status >> 8
ly.error (_ ("`%s' failed (%d)") % (cmd, exit_status))
ly.error (_ ("The error log is as follows:"))
- ly.stderr_write (error)
+ ly.stderr_write (err)
ly.stderr_write (stderr.read ())
exit (status)
class LilypondFileSnippet (LilypondSnippet):
def __init__ (self, type, match, formatter, line_number, global_options):
LilypondSnippet.__init__ (self, type, match, formatter, line_number, global_options)
- self.contents = file (BookBase.find_file (self.substring ('filename'), global_options.include_path)).read ()
+ self.filename = self.substring ('filename')
+ self.ext = os.path.splitext (os.path.basename (self.filename))[1]
+ self.contents = file (BookBase.find_file (self.filename, global_options.include_path)).read ()
def get_snippet_code (self):
return self.contents;
return s
def ly (self):
- name = self.substring ('filename')
+ name = self.filename
return ('\\sourcefilename \"%s\"\n\\sourcefileline 0\n%s'
% (name, self.contents))
def final_basename (self):
if self.global_options.use_source_file_names:
- base = os.path.splitext (os.path.basename (self.substring ('filename')))[0]
+ base = os.path.splitext (os.path.basename (self.filename))[0]
return base
else:
return self.basename ()
+class MusicXMLFileSnippet (LilypondFileSnippet):
+ def __init__ (self, type, match, formatter, line_number, global_options):
+ LilypondFileSnippet.__init__ (self, type, match, formatter, line_number, global_options)
+ self.compressed = False
+ self.converted_ly = None
+ self.musicxml_options_dict = {
+ 'verbose': '--verbose',
+ 'lxml': '--lxml',
+ 'compressed': '--compressed',
+ 'relative': '--relative',
+ 'absolute': '--absolute',
+ 'no-articulation-directions': '--no-articulation-directions',
+ 'no-rest-positions': '--no-rest-positions',
+ 'no-page-layout': '--no-page-layout',
+ 'no-beaming': '--no-beaming',
+ 'language': '--language',
+ }
+
+ def snippet_options (self):
+ return self.musicxml_options_dict.keys ()
+
+ def convert_from_musicxml (self):
+ name = self.filename
+ xml2ly_option_list = []
+ for (key, value) in self.option_dict.items ():
+ cmd_key = self.musicxml_options_dict.get (key, None)
+ if cmd_key == None:
+ continue
+ if value == None:
+ xml2ly_option_list.append (cmd_key)
+ else:
+ xml2ly_option_list.append (cmd_key + '=' + value)
+ if ('.mxl' in name) and ('--compressed' not in xml2ly_option_list):
+ xml2ly_option_list.append ('--compressed')
+ self.compressed = True
+ opts = " ".join (xml2ly_option_list)
+ progress (_ ("Converting MusicXML file `%s'...\n") % self.filename)
+
+ ly_code = self.filter_pipe (self.contents, 'musicxml2ly %s --out=- - ' % opts)
+ return ly_code
+
+ def ly (self):
+ if self.converted_ly == None:
+ self.converted_ly = self.convert_from_musicxml ()
+ name = self.filename
+ return ('\\sourcefilename \"%s\"\n\\sourcefileline 0\n%s'
+ % (name, self.converted_ly))
+
+ def additional_files_required (self, base, full):
+ result = [];
+ if self.compressed:
+ result.append (base + '.mxl')
+ else:
+ result.append (base + '.xml')
+ return result
+
+ def write_ly (self):
+ base = self.basename ()
+ path = os.path.join (self.global_options.lily_output_dir, base)
+ directory = os.path.split(path)[0]
+ if not os.path.isdir (directory):
+ os.makedirs (directory)
+
+ # First write the XML to a file (so we can link it!)
+ if self.compressed:
+ xmlfilename = path + '.mxl'
+ else:
+ xmlfilename = path + '.xml'
+ if os.path.exists (xmlfilename):
+ diff_against_existing = self.filter_pipe (self.contents, 'diff -u %s - ' % xmlfilename)
+ if diff_against_existing:
+ warning (_ ("%s: duplicate filename but different contents of orginal file,\n\
+printing diff against existing file.") % xmlfilename)
+ ly.stderr_write (diff_against_existing)
+ else:
+ out = file (xmlfilename, 'w')
+ out.write (self.contents)
+ out.close ()
+
+ # also write the converted lilypond
+ filename = path + '.ly'
+ if os.path.exists (filename):
+ diff_against_existing = self.filter_pipe (self.full_ly (), 'diff -u %s -' % filename)
+ if diff_against_existing:
+ warning (_ ("%s: duplicate filename but different contents of converted lilypond file,\n\
+printing diff against existing file.") % filename)
+ ly.stderr_write (diff_against_existing)
+ else:
+ out = file (filename, 'w')
+ out.write (self.full_ly ())
+ out.close ()
+ file (path + '.txt', 'w').write ('image of music')
+
+
+
class LilyPondVersionString (Snippet):
"""A string that does not require extra memory."""
def __init__ (self, type, match, formatter, line_number, global_options):
'lilypond': LilypondSnippet,
'include': IncludeSnippet,
'lilypondversion': LilyPondVersionString,
+ 'musicxml_file': MusicXMLFileSnippet,
}
.*?
@end\s+ignore))\s''',
+ 'musicxml_file': r'''(?mx)
+ ^(?P<match>
+ @musicxmlfile\s*(
+ \[
+ \s*(?P<options>.*?)\s*
+ \])?\s*{
+ (?P<filename>\S+)
+ })''',
+
'singleline_comment': r'''(?mx)
^.*
(?P<match>
@end ifinfo
@html
<p>
- <a href="%(base)s.ly">
+ <a href="%(base)s%(ext)s">
<img align="middle"
border="0"
src="%(image)s"
PRINTFILENAME: '''
@html
-<a href="%(base)s.ly">
+<a href="%(base)s%(ext)s">
@end html
@file{%(filename)s}
@html
QUOTE: r'''@quotation
%(str)s@end quotation
-''',
-
- NOQUOTE: r'''@format
-%(str)s@end format
''',
VERBATIM: r'''@exampleindent 0
str = re.sub (r'\\(cresc|dim|endcresc|enddim)\b', r'\\deprecated\1', str)
return str
+@rule ((2, 13, 27),
+ ("interval-translate -> coord-translate"))
+def conv (str):
+ str = re.sub ('interval-translate', 'coord-translate', str)
+ return str
+
@rule ((2, 13, 29),
_ ("Eliminate beamSettings, beatLength, \\setBeatGrouping, \\overrideBeamSettings and \\revertBeamSettings.\n\
\"accordion.accEtcbase\" -> \"accordion.etcbass\""))
def conv (str):
return str
-@rule ((2, 15, 2),
- _ ("Change in internal property for MultiMeasureRest"))
-def conv (str):
- if re.search (r'use-breve-rest',str):
- stderr_write (NOT_SMART % _("use-breve-rest. This internal property has been replaced by round-to-longer-rest and usable-duration-logs.\n"))
- stderr_write (UPDATE_MANUALLY)
- return str
-
@rule ((2, 15, 7),
_ ("Handling of non-automatic footnotes."))
def conv(str):
stderr_write (UPDATE_MANUALLY)
return str
+@rule ((2, 15, 9),
+ _ ("Change in internal property for MultiMeasureRest"))
+def conv (str):
+ if re.search (r'use-breve-rest',str):
+ stderr_write ("\n")
+ stderr_write (NOT_SMART % "use-breve-rest.\n")
+ stderr_write (_ ("This internal property has been replaced by round-up-to-longer-rest, round-up-exceptions and usable-duration-logs.\n"))
+ stderr_write (UPDATE_MANUALLY)
+ return str
+
# Guidelines to write rules (please keep this at the end of this file)
#
See @file{double-plus-new-chord-name.scm} for the signature of @var{style}.
@var{pitches}, @var{bass}, and @var{inversion} are lily pitches.
-@var{options} is an alist-alist (see @file{input/test/dpncnt.ly})."
+@var{options} is an alist-alist (see @file{input/@/test/@/dpncnt.ly})."
(define (step-nr pitch)
(let* ((pitch-nr (+ (* 7 (ly:pitch-octave pitch))
(list-ref '("eses" "es" "" "is" "isis") (+ 2 (cdr n-a)))))))))
(define-public ((chord-name->italian-markup re-with-eacute) pitch lowercase?)
- "Return pitch markup for @var{pitch}, using italian/french note names.
+ "Return pitch markup for @var{pitch}, using Italian/@/French note names.
If @var{re-with-eacute} is set to @code{#t}, french `ré' is returned for
pitch@tie{}D instead of `re'."
@end table")
(autoBeamCheck ,procedure? "A procedure taking three
-arguments, @var{context}, @var{dir} [start/stop (-1 or 1)], and
+arguments, @var{context}, @var{dir} [start/@/stop (-1 or 1)], and
@var{test} [shortest note in the beam]. A non-@code{#f} return value
starts or stops the auto beam.")
(autoBeaming ,boolean? "If set to true then beams are generated
(figuredBassPlusDirection ,ly:dir? "Where to put plus signs
relative to the main figure.")
(fingeringOrientations ,list? "A list of symbols, containing
-@samp{left}, @samp{right}, @samp{up} and/or @samp{down}. This list
+@samp{left}, @samp{right}, @samp{up} and/@/or @samp{down}. This list
determines where fingerings are put relative to the chord being
fingered.")
(firstClef ,boolean? "If true, create a new clef when starting a
(followVoice ,boolean? "If set, note heads are tracked across
staff switches by a thin line.")
(fontSize ,number? "The relative size of all grobs in a context.")
- (forbidBreak ,boolean? "If set to @code{##t}, prevent a line break
+ (forbidBreak ,boolean? "If set to @code{#t}, prevent a line break
at this point.")
(forceClef ,boolean? "Show clef symbol, even if it has not
changed. Only active for the first clef after the property is set, not
(melismaBusyProperties ,list? "A list of properties (symbols) to
determine whether a melisma is playing. Setting this property will
influence how lyrics are aligned to notes. For example, if set to
-@code{#'(melismaBusy beamMelismaBusy)}, only manual melismata and
+@code{'(melismaBusy beamMelismaBusy)}, only manual melismata and
manual beams are considered. Possible values include
@code{melismaBusy}, @code{slurMelismaBusy}, @code{tieMelismaBusy}, and
@code{beamMelismaBusy}.")
(suggestAccidentals ,boolean? "If set, accidentals are typeset as
cautionary suggestions over the note.")
(systemStartDelimiter ,symbol? "Which grob to make for the start
-of the system/staff? Set to @code{SystemStartBrace},
+of the system/@/staff? Set to @code{SystemStartBrace},
@code{SystemStartBracket} or @code{SystemStartBar}.")
(systemStartDelimiterHierarchy ,pair? "A nested list, indicating
the nesting of a start delimiters.")
follow each other directly. This can be used for writing out
arpeggios.")
(timeSignatureFraction ,number-pair? "A pair of numbers,
-signifying the time signature. For example, @code{#'(4 . 4)} is a
+signifying the time signature. For example, @code{'(4 . 4)} is a
4/4 time signature.")
(timeSignatureSettings ,cheap-list? "A nested alist of settings for
time signatures. Contains elements for various time signatures. The
barcheck fail?")
(beamMelismaBusy ,boolean? "Signal if a beam is present.")
(busyGrobs ,list? "A queue of @code{(@var{end-moment} .
-@var{GROB})} cons cells. This is for internal (C++) use only. This
+@var{grob})} cons cells. This is for internal (C++) use only. This
property contains the grobs which are still busy (e.g. note heads,
spanners, etc.).")
(scriptDefinitions ,list? "The description of scripts. This is
used by the @code{Script_engraver} for typesetting note-superscripts
-and subscripts. See @file{scm/script.scm} for more information.")
+and subscripts. See @file{scm/@/script.scm} for more information.")
(slurMelismaBusy ,boolean? "Signal if a slur is present.")
(stavesFound ,grob-list? "A list of all staff-symbols found.")
included in this script's support.")
(after-line-breaking ,boolean? "Dummy property, used to trigger
callback for @code{after-line-breaking}.")
- (align-dir ,ly:dir? "Which side to align? @code{-1}: left side,
+ (align-dir ,ly:dir? "Which side to align? @w{@code{-1}}: left side,
@code{0}: around center of width, @code{1}: right side.")
(allow-loose-spacing ,boolean? "If set, column can be detached
from main spacing.")
;;
(c0-position ,integer? "An integer indicating the position of
middle@tie{}C.")
- (circled-tip ,boolean? "Put a circle at start/end of
-hairpins (al/del niente).")
+ (circled-tip ,boolean? "Put a circle at start/@/end of
+hairpins (al/@/del niente).")
(clip-edges ,boolean? "Allow outward pointing beamlets at the
edges of beams?")
(collapse-height ,ly:dimension? "Minimum height of system start
-delimiter. If equal or smaller, the bracket/brace/line is removed.")
+delimiter. If equal or smaller, the bracket/@/brace/@/line is removed.")
(collision-interfaces ,list? "A list of interfaces for which
automatic beam-collision resolution is run.")
(collision-voice-only ,boolean? "Does automatic beam collsion apply
having a @code{details} property.")
(digit-names ,vector? "Names for string finger digits.")
(direction ,ly:dir? "If @code{side-axis} is @code{0} (or
-@code{#X}), then this property determines whether the object is placed
-@code{#LEFT}, @code{#CENTER} or @code{#RIGHT} with respect to the
+@code{X}), then this property determines whether the object is placed
+@code{LEFT}, @code{CENTER} or @code{RIGHT} with respect to the
other object. Otherwise, it determines whether the object is placed
-@code{#UP}, @code{#CENTER} or @code{#DOWN}. Numerical values may also
-be used: @code{#UP}=@code{1}, @code{#DOWN}=@code{-1},
-@code{#LEFT}=@code{-1}, @code{#RIGHT}=@code{1},
-@code{#CENTER}=@code{0}.")
+@code{UP}, @code{CENTER} or @code{DOWN}. Numerical values may also
+be used: @code{UP}=@code{1}, @code{DOWN}=@w{@code{-1}},
+@code{LEFT}=@w{@code{-1}}, @code{RIGHT}=@code{1},
+@code{CENTER}=@code{0}.")
(dot-count ,integer? "The number of dots.")
(dot-negative-kern ,number? "The space to remove between a dot
and a slash in percent repeat glyphs. Larger values bring the two
include @code{upright}, @code{italic}, @code{caps}.")
(font-size ,number? "The font size, compared to the
@q{normal}@tie{}size. @code{0}@tie{}is style-sheet's normal size,
-@code{-1} is smaller, @code{+1} is bigger. Each step of@tie{}1 is
+@w{@code{-1}} is smaller, @code{+1} is bigger. Each step of@tie{}1 is
approximately 12% larger; 6@tie{}steps are exactly a factor@tie{}2
larger. Fractional values are allowed.")
(footnote-text ,markup? "A footnote for the grob.")
Default@tie{}0.
@item
@code{label-dir} -- Side to which the fret label is attached.
-@code{-1}, @code{#LEFT}, or @code{#DOWN} for left or down; @code{1},
-@code{#RIGHT}, or @code{#UP} for right or up. Default @code{#RIGHT}.
+@w{@code{-1}}, @code{LEFT}, or @code{DOWN} for left or down; @code{1},
+@code{RIGHT}, or @code{UP} for right or up. Default @code{RIGHT}.
@item
@code{mute-string} -- Character string to be used to indicate muted
string. Default @code{\"x\"}.
@itemize @bullet
@item
-@code{box-offset} -- Vertical shift of the center of flat/sharp pedal
-boxes above/below the horizontal line. Default value@tie{}0.8.
+@code{box-offset} -- Vertical shift of the center of flat/@/sharp pedal
+boxes above/@/below the horizontal line. Default value@tie{}0.8.
@item
@code{box-width} -- Width of each pedal box. Default value@tie{}0.4.
@item
(right-padding ,ly:dimension? "Space to insert on the right side
of an object (e.g., between note and its accidentals).")
(rotation ,list? "Number of degrees to rotate this object, and
-what point to rotate around. For example, @code{#'(45 0 0)} rotates
+what point to rotate around. For example, @code{'(45 0 0)} rotates
by 45 degrees around the center of this object.")
(round-up-to-longer-rest ,boolean? "Displays the longer multi-measure
rest when the length of a measure is between two values of
(script-priority ,number? "A sorting key that determines in what
order a script is within a stack of scripts.")
(self-alignment-X ,number? "Specify alignment of an object. The
-value @code{-1} means left aligned, @code{0}@tie{}centered, and
+value @w{@code{-1}} means left aligned, @code{0}@tie{}centered, and
@code{1}@tie{}right-aligned in X@tie{}direction. Other numerical
values may also be specified.")
(self-alignment-Y ,number? "Like @code{self-alignment-X} but for
shortest note playing here.")
(shortest-starter-duration ,ly:moment? "The duration of the
shortest note that starts here.")
- (side-axis ,number? "If the value is @code{#X} (or
+ (side-axis ,number? "If the value is @code{X} (or
equivalently@tie{}@code{0}), the object is placed horizontally next to
-the other object. If the value is @code{#Y} or@tie{}@code{1}, it is
+the other object. If the value is @code{Y} or@tie{}@code{1}, it is
placed vertically.")
(side-relative-direction ,ly:dir? "Multiply direction of
@code{direction-source} with this to get the direction of this
override:
@example
-\\override MultiMeasureRest #'spacing-pair = #'(staff-bar . staff-bar)
+\\override MultiMeasureRest
+ #'spacing-pair = #'(staff-bar . staff-bar)
@end example")
(spanner-id ,string? "An identifier to distinguish concurrent spanners.")
(springs-and-rods ,boolean? "Dummy variable for triggering
@var{dir})} pairs, indicating the desired tie configuration, where
@var{position} is the offset from the center of the staff in staff
space and @var{dir} indicates the direction of the tie
-(@code{1}=>up, @code{-1}=>down, @code{0}=>center). A non-pair entry
+(@code{1}=>up, @w{@code{-1}}=>down, @code{0}=>center). A non-pair entry
in the list causes the corresponding tie to be formatted
automatically.")
(to-barline ,boolean? "If true, the spanner will stop at the bar
(bars ,ly:grob-array? "An array of bar line pointers.")
(beam ,ly:grob? "A pointer to the beam, if applicable.")
+ (bound-alignment-interfaces ,list "Interfaces to be used
+for positioning elements that align with a column.")
(bounded-by-me ,ly:grob-array? "An array of spanners that have this
-column as start/begin point. Only columns that have grobs or act as
+column as start/@/begin point. Only columns that have grobs or act as
bounds are spaced.")
(bracket ,ly:grob? "The bracket for a number.")
(spanner-broken ,boolean? "Indicates whether spanner
alignment should be broken after the current spanner.")
(spanner-placement ,ly:dir? "The place of an annotation on a spanner.
-LEFT is for the first spanner, and RIGHT is for the last. CENTER will
-place it on the broken spanner that falls closest to the center of the length
-of the entire spanner, although this behavior is unpredictable in situations
-with lots of rhythmic diversity. For predictable results, use LEFT and RIGHT.")
+@code{LEFT} is for the first spanner, and @code{RIGHT} is for the last.
+@code{CENTER} will place it on the broken spanner that falls closest to the
+center of the length of the entire spanner, although this behavior is
+unpredictable in situations with lots of rhythmic diversity. For predictable
+results, use @code{LEFT} and @code{RIGHT}.")
(staff-grouper ,ly:grob? "The staff grouper we belong to.")
(staff-symbol ,ly:grob? "The staff symbol grob that we are in.")
(stem ,ly:grob? "A pointer to a @code{Stem} object.")
(cavum ,boolean? "Is this neume outlined?")
(context-info ,integer? "Within a ligature, the final glyph or shape of
-a head may be affected by the left and/or right neighbour head.
+a head may be affected by the left and/@/or right neighbour head.
@code{context-info} holds for each head such information about the left and
right neighbour, encoded as a bit mask.")
(key-signature . (minimum-space . 3.5))
(time-signature . (minimum-space . 4.2))
(first-note . (minimum-fixed-space . 5.0))
- (next-note . (extra-space . 0.5))
+ (next-note . (extra-space . 1.0))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
(Y-offset . ,ly:staff-symbol-referencer::callback)
(time-signature . (minimum-space . 4.2))
(custos . (minimum-space . 0.0))
(first-note . (minimum-fixed-space . 3.0))
- (next-note . (extra-space . 0.5))
+ (next-note . (extra-space . 1.0))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
(Y-offset . ,ly:staff-symbol-referencer::callback)
(key-signature . (minimum-space . 3.5))
(time-signature . (minimum-space . 4.2))
(first-note . (minimum-fixed-space . 5.0))
- (next-note . (extra-space . 0.5))
+ (next-note . (extra-space . 1.0))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
(Y-offset . ,ly:staff-symbol-referencer::callback)
(fret-diagram-details . ((finger-code . below-string)))
(stencil . ,fret-board::calc-stencil)
(extra-spacing-height . (0.2 . -0.2))
+ (extra-spacing-width . (-0.5 . 0.5))
(meta . ((class . Item)
(interfaces . (chord-name-interface
font-interface
(Glissando
. (
(after-line-breaking . ,ly:spanner::kill-zero-spanned-time)
- (bound-details . ((right . ((attach-dir . ,CENTER)
- (padding . 1.5)
+ (bound-details . ((right . ((attach-dir . ,LEFT)
+ (end-on-accidental . #t)
+ (padding . 0.5)
))
- (left . ((attach-dir . ,CENTER)
- (padding . 1.5)
+ (left . ((attach-dir . ,RIGHT)
+ (padding . 0.5)
))
))
(gap . 0.5)
(key-signature . (extra-space . 0.5))
(cue-clef . (extra-space . 0.5))
(right-edge . (extra-space . 0.5))
- (first-note . (fixed-space . 2.5))))
+ (first-note . (semi-fixed-space . 2.5))))
(stencil . ,ly:key-signature-interface::print)
(extra-spacing-width . (0.0 . 0.5))
(Y-offset . ,ly:staff-symbol-referencer::callback)
(staff-bar . (extra-space . 1.1))
(cue-clef . (extra-space . 0.5))
(right-edge . (extra-space . 0.5))
- (first-note . (fixed-space . 2.5))))
+ (first-note . (semi-fixed-space . 2.5))))
(stencil . ,ly:key-signature-interface::print)
(extra-spacing-width . (0.0 . 0.5))
(Y-offset . ,ly:staff-symbol-referencer::callback)
(NoteColumn
. (
(axes . (,X ,Y))
+ (bound-alignment-interfaces . (rhythmic-head-interface stem-interface))
(horizontal-skylines . ,ly:separation-item::calc-skylines)
(skyline-vertical-padding . 0.15)
(X-extent . ,ly:axis-group-interface::width)
(allow-loose-spacing . #t)
(axes . (,X))
(before-line-breaking . ,ly:paper-column::before-line-breaking)
+ (bound-alignment-interfaces . (note-column-interface))
(horizontal-skylines . ,ly:separation-item::calc-skylines)
(keep-inside-line . #t)
;; (stencil . ,ly:paper-column::print)
(side-axis . ,Y)
;; padding set in script definitions.
+ (slur-padding . 0.2)
(staff-padding . 0.25)
(stencil . ,ly:script-interface::print)
(non-musical . #t)
(space-alist . (
(cue-clef . (extra-space . 1.5))
- (first-note . (fixed-space . 2.0))
+ (first-note . (semi-fixed-space . 2.0))
(right-edge . (extra-space . 0.5))
(staff-bar . (minimum-space . 2.0))))
(stencil . ,ly:time-signature::print)
(,ly:accidental-interface::height . ,ly:accidental-interface::pure-height)
(,ly:axis-group-interface::calc-staff-staff-spacing . ,ly:axis-group-interface::calc-pure-staff-staff-spacing)
(,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height)
+ (,ly:beam::rest-collision-callback . ,ly:beam::pure-rest-collision-callback)
(,ly:grob::stencil-height . ,pure-stencil-height)
(,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height)
(,ly:rest-collision::force-shift-callback-rest . ,pure-chain-offset-callback)
;;; functions that take a markup as their last argument.
;;;
;;; args-signature
-;;; the arguments signature, i.e. a list of type predicates which
+;;; the arguments signature, i.e., a list of type predicates which
;;; are used to type check the arguments, and also to define the general
;;; argument types (markup, markup-list, scheme) that the command is
;;; expecting.
;;;
;;; category
;;; for documentation purpose, builtin markup commands are grouped by
-;;; category. This can be any symbol. When documentation is generated,
+;;; category. This can be any symbol. When documentation is generated,
;;; the symbol is converted to a capitalized string, where hyphens are
;;; replaced by spaces.
;;;
;;; property-bindings
;;; this is used both for documentation generation, and to ease
-;;; programming the command itself. It is list of
+;;; programming the command itself. It is list of
;;; (property-name default-value)
;;; or (property-name)
-;;; elements. Each property is looked-up in the `props' argument, and
+;;; elements. Each property is looked-up in the `props' argument, and
;;; the symbol naming the property is bound to its value.
;;; When the property is not found in `props', then the symbol is bound
-;;; to the given default value. When no default value is given, #f is
+;;; to the given default value. When no default value is given, #f is
;;; used instead.
;;; Thus, using the following property bindings:
;;; ((thickness 0.1)
;;; ..body..)
;;; When a command `B' internally calls an other command `A', it may
;;; desirable to see in `B' documentation all the properties and
-;;; default values used by `A'. In that case, add `A-markup' to the
-;;; property-bindings of B. (This is used when generating
+;;; default values used by `A'. In that case, add `A-markup' to the
+;;; property-bindings of B. (This is used when generating
;;; documentation, but won't create bindings.)
;;;
;;; documentation-string
;;; the command documentation string (used to generate manuals)
;;;
;;; body
-;;; the command body. The function is supposed to return a stencil.
+;;; the command body. The function is supposed to return a stencil.
;;;
;;; Each markup command definition shall have a documentation string
;;; with description, syntax and example.
"
@cindex referencing page numbers in text
-Add a link to the page @var{page-number} around @var{arg}. This only works in
-the PDF backend.
+Add a link to the page @var{page-number} around @var{arg}. This only works
+in the PDF backend.
@lilypond[verbatim,quote]
\\markup {
"
@cindex referencing page labels in text
-Add a link to the page holding label @var{label} around @var{arg}. This
+Add a link to the page holding label @var{label} around @var{arg}. This
only works in the PDF backend.
@lilypond[verbatim,quote]
\\markup {
- \\with-link #\"label\" { \\italic { This links to the page containing the label... } }
+ \\with-link #\"label\" {
+ \\italic { This links to the page containing the label... }
+ }
}
@end lilypond"
(let* ((arg-stencil (interpret-markup layout props arg))
indent = 0.0\\cm
\\context {
\\Score
- \\override RehearsalMark #'break-align-symbols =
- #'(time-signature key-signature)
- \\override RehearsalMark #'self-alignment-X = #LEFT
+ \\override RehearsalMark
+ #'break-align-symbols = #'(time-signature key-signature)
+ \\override RehearsalMark
+ #'self-alignment-X = #LEFT
}
\\context {
\\Staff
- \\override TimeSignature #'break-align-anchor-alignment = #LEFT
+ \\override TimeSignature
+ #'break-align-anchor-alignment = #LEFT
}
}
}
\\header {
title = \"My title\"
myText = \"Lorem ipsum dolor sit amet, consectetur adipisicing
- elit, sed do eiusmod tempor incididunt ut labore et dolore magna
- aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
- laboris nisi ut aliquip ex ea commodo consequat.\"
+ elit, sed do eiusmod tempor incididunt ut labore et dolore
+ magna aliqua. Ut enim ad minim veniam, quis nostrud
+ exercitation ullamco laboris nisi ut aliquip ex ea commodo
+ consequat.\"
}
\\paper {
"
@cindex setting horizontal text alignment
-Set horizontal alignment. If @var{dir} is @code{-1}, then it is
+Set horizontal alignment. If @var{dir} is @w{@code{-1}}, then it is
left-aligned, while @code{+1} is right. Values in between interpolate
alignment accordingly.
@lilypond[verbatim,quote]
\\markup {
\\huge \\bold \\sans \\caps {
- Some text with font overrides
+ huge bold sans caps
\\hspace #2
\\normal-text {
- Default text, same font-size
+ huge normal
}
\\hspace #2
- More text as before
+ as before
}
}
@end lilypond"
"
@cindex referencing page numbers in text
-Reference to a page number. @var{label} is the label set on the referenced
+Reference to a page number. @var{label} is the label set on the referenced
page (using the @code{\\label} command), @var{gauge} a markup used to estimate
the maximum width of the page number, and @var{default} the value to display
when @var{label} is not found."
\\fill-with-pattern #1.5 #CENTER - left right
\\null
\"left-aligned :\"
- \\override #'(line-width . 50) \\fill-with-pattern #2 #LEFT : left first
- \\override #'(line-width . 50) \\fill-with-pattern #2 #LEFT : left second
+ \\override #'(line-width . 50)
+ \\fill-with-pattern #2 #LEFT : left first
+ \\override #'(line-width . 50)
+ \\fill-with-pattern #2 #LEFT : left second
}
@end lilypond"
(let* ((pattern-x-extent (ly:stencil-extent (interpret-markup layout props pattern) X))
(ArpeggioEvent
. ((description . "Make an arpeggio on this note.
-Syntax: @var{note}@code{-\\arpeggio}")
+Syntax: @w{@var{note}@code{-\\arpeggio}}")
(types . (general-music arpeggio-event event))
))
Syntax: @var{note}@code{x}@code{y}, where @code{x} is a direction
(@code{^} for up or @code{_} for down), or LilyPond's choice
(no direction specified), and where @code{y} is an articulation
-(such as @code{-.}, @code{->}, @code{\\tenuto}, @code{\\downbow}).
+(such as @w{@code{-.}}, @w{@code{->}}, @code{\\tenuto}, @code{\\downbow}).
See the Notation Reference for details.")
(types . (general-music event articulation-event script-event))
))
))
(BendAfterEvent
- . ((description . "A drop/fall/doit jazz articulation.")
+ . ((description . "A drop/@/fall/@/doit jazz articulation.")
(types . (general-music bend-after-event event))))
(BreathingEvent
(TieEvent
. ((description . "A tie.
-Syntax: @var{note}@code{-~}")
+Syntax: @w{@var{note}@code{-~}}")
(types . (general-music tie-event event))
))
(define-public (ly:all-output-backend-commands)
"Return the list of extra output backend commands that
-are used internally in @file{lily/stencil-interpret.cc}."
+are used internally in @file{lily/@/stencil-interpret.cc}."
'(color
combine-stencil
delay-stencil-evaluation
"Make a woodwind-instrument diagram. For example, say
@example
-\\markup \\woodwind-diagram #'oboe #'((lh . (d ees)) (cc . (five3qT1q)) (rh . (gis)))
+\\markup \\woodwind-diagram
+ #'oboe #'((lh . (d ees)) (cc . (five3qT1q)) (rh . (gis)))
@end example
@noindent
@var{design-size-alist} is a list of @code{(rounded . designsize)}.
@code{rounded} is a suffix for font filenames, while @code{designsize}
should be the actual design size. The latter is used for text fonts
-loaded through pango/fontconfig.
+loaded through pango/@/fontconfig.
@item
@var{factor} is a size factor relative to the default size that is being
should be separated by spaces.
@item
-Fingerings are given by following the fret number with a @code{-},
+Fingerings are given by following the fret number with a @w{@code{-},}
followed by the finger indicator, e.g. @samp{3-2} for playing the third
fret with the second finger.
@item
Where a barre indicator is desired, follow the fret (or fingering) symbol
-with @code{-(} to start a barre and @code{-)} to end the barre.
+with @w{@code{-(}} to start a barre and @w{@code{-)}} to end the barre.
@end itemize"
;; TODO -- change syntax to fret\string-finger
(debug-enable 'debug)
(begin
(debug-enable 'backtrace)
- (debug-enable 'show-file-name)))
+ (debug-set! show-file-name #t)))
(define-public PLATFORM
(string->symbol
"If string FOO is given as argument, redirect
output to log file `FOO.log'.")
(midi-extension ,(if (eq? PLATFORM 'windows)
- "mid"
- "midi")
+ "mid"
+ "midi")
"Set the default file extension for MIDI output
file to given string.")
(music-strings-to-paths #f
;; initialization depend on these options.
(for-each (lambda (x)
- (ly:add-option (car x) (cadr x) (caddr x)))
- scheme-options-definitions)
+ (ly:add-option (car x) (cadr x) (caddr x)))
+ scheme-options-definitions)
(for-each (lambda (x)
- (ly:set-option (car x) (cdr x)))
- (eval-string (ly:command-line-options)))
+ (ly:set-option (car x) (cdr x)))
+ (eval-string (ly:command-line-options)))
(debug-set! stack 0)
;;(set-debug-cell-accesses! 1000)
(use-modules (ice-9 regex)
- (ice-9 safe)
- (ice-9 format)
- (ice-9 rdelim)
- (ice-9 optargs)
- (oop goops)
- (srfi srfi-1)
- (srfi srfi-13)
- (srfi srfi-14)
- (scm clip-region)
- (scm memory-trace)
- (scm coverage))
+ (ice-9 safe)
+ (ice-9 format)
+ (ice-9 rdelim)
+ (ice-9 optargs)
+ (oop goops)
+ (srfi srfi-1)
+ (srfi srfi-13)
+ (srfi srfi-14)
+ (scm clip-region)
+ (scm memory-trace)
+ (scm coverage))
(define-public _ gettext)
;;; There are new modules defined in Guile V2.0 which we need to use.
;;; Debugging evaluator is slower. This should have a more sensible
;;; default.
+
(if (or (ly:get-option 'verbose)
- (ly:get-option 'trace-memory-frequency)
- (ly:get-option 'trace-scheme-coverage))
+ (ly:get-option 'trace-memory-frequency)
+ (ly:get-option 'trace-scheme-coverage))
(begin
(ly:set-option 'protected-scheme-parsing #f)
(debug-enable 'backtrace)
(define-public DOS
(let ((platform (string-tokenize
- (vector-ref (uname) 0) char-set:letter+digit)))
+ (vector-ref (uname) 0) char-set:letter+digit)))
(if (null? (cdr platform)) #f
- (member (string-downcase (cadr platform)) '("95" "98" "me")))))
+ (member (string-downcase (cadr platform)) '("95" "98" "me")))))
(define (slashify x)
(if (string-index x #\\)
x
(string-regexp-substitute
- "//*" "/"
- (string-regexp-substitute "\\\\" "/" x))))
+ "//*" "/"
+ (string-regexp-substitute "\\\\" "/" x))))
(define-public (ly-getcwd)
(if (eq? PLATFORM 'windows)
(define-public (is-absolute? file-name)
(let ((file-name-length (string-length file-name)))
(if (= file-name-length 0)
- #f
- (or (eq? (string-ref file-name 0) #\/)
- (and (eq? PLATFORM 'windows)
- (> file-name-length 2)
- (eq? (string-ref file-name 1) #\:)
- (eq? (string-ref file-name 2) #\/))))))
+ #f
+ (or (eq? (string-ref file-name 0) #\/)
+ (and (eq? PLATFORM 'windows)
+ (> file-name-length 2)
+ (eq? (string-ref file-name 1) #\:)
+ (eq? (string-ref file-name 2) #\/))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; If necessary, emulate Guile V2 module_export_all! for Guile V1.8.n
(define (module-export-all! mod)
(define (fresh-interface!)
(let ((iface (make-module)))
- (set-module-name! iface (module-name mod))
- ;; for guile 2: (set-module-version! iface (module-version mod))
- (set-module-kind! iface 'interface)
- (set-module-public-interface! mod iface)
- iface))
+ (set-module-name! iface (module-name mod))
+ ;; for guile 2: (set-module-version! iface (module-version mod))
+ (set-module-kind! iface 'interface)
+ (set-module-public-interface! mod iface)
+ iface))
(let ((iface (or (module-public-interface mod)
- (fresh-interface!))))
+ (fresh-interface!))))
(set-module-obarray! iface (module-obarray mod))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (recursion-helper signature arguments count)
(define (helper pred? arg count)
(if (not (pred? arg))
- (begin
- (ly:input-message
- location
- (format
- #f (_ "wrong type for argument ~a. Expecting ~a, found ~s")
- count (type-name pred?) arg))
- #f)
- #t))
+ (begin
+ (ly:input-message
+ location
+ (format
+ #f (_ "wrong type for argument ~a. Expecting ~a, found ~s")
+ count (type-name pred?) arg))
+ #f)
+ #t))
(if (null? signature)
- #t
- (and (helper (car signature) (car arguments) count)
- (recursion-helper (cdr signature) (cdr arguments) (1+ count)))))
+ #t
+ (and (helper (car signature) (car arguments) count)
+ (recursion-helper (cdr signature) (cdr arguments) (1+ count)))))
(recursion-helper signature arguments 1))
(define-safe-public (lilypond-version)
(string-join
(map (lambda (x) (if (symbol? x)
- (symbol->string x)
- (number->string x)))
- (ly:version))
+ (symbol->string x)
+ (number->string x)))
+ (ly:version))
"."))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; other files.
-(define init-scheme-files
+;;
+;; List of Scheme files to be loaded into the (lily) module.
+;;
+;; - Library definitions, need to be at the head of the list
+(define init-scheme-files-lib
'("lily-library.scm"
- "file-cache.scm"
+ "output-lib.scm"))
+;; - Files containing definitions used later by other files later in load
+(define init-scheme-files-used
+ '("markup-macros.scm"))
+;; - Main body of files to be loaded
+(define init-scheme-files-body
+ '("file-cache.scm"
"define-event-classes.scm"
"define-music-callbacks.scm"
"define-music-types.scm"
"define-note-names.scm"
- "output-lib.scm"
"c++.scm"
- "chord-ignatzek-names.scm"
"chord-entry.scm"
- "chord-generic-names.scm"
"stencil.scm"
+ "define-markup-commands.scm"
"markup.scm"
"modal-transforms.scm"
+ "chord-generic-names.scm"
+ "chord-ignatzek-names.scm"
"music-functions.scm"
"part-combiner.scm"
"autochange.scm"
"define-music-properties.scm"
"time-signature-settings.scm"
"auto-beam.scm"
+ "chord-name.scm"
"bezier-tools.scm"
"parser-ly-from-scheme.scm"
"ly-syntax-constructors.scm"
"define-context-properties.scm"
- ;; guile 1.9 wants markups defined before referenced
- "define-markup-commands.scm"
-
- "chord-name.scm"
"translation-functions.scm"
"script.scm"
"midi.scm"
"paper.scm"
"backend-library.scm"
- "x11-color.scm"
-
- ;; must be after everything has been defined
- "safe-lily.scm"))
+ "x11-color.scm"))
+;; - Files to be loaded last
+(define init-scheme-files-tail
+;; - must be after everything has been defined
+ '("safe-lily.scm"))
+;;
+;; Now construct the load list
+;;
+(define init-scheme-files
+ (append init-scheme-files-lib
+ init-scheme-files-used
+ init-scheme-files-body
+ init-scheme-files-tail))
(for-each ly:load init-scheme-files)
(define (profile-measurements)
(let* ((t (times))
- (stats (gc-stats)))
+ (stats (gc-stats)))
(list (- (+ (tms:cutime t)
- (tms:utime t))
- (assoc-get 'gc-time-taken stats))
- (assoc-get 'total-cells-allocated stats 0))))
+ (tms:utime t))
+ (assoc-get 'gc-time-taken stats))
+ (assoc-get 'total-cells-allocated stats 0))))
(define (dump-profile base last this)
(let* ((outname (format #f "~a.profile" (dir-basename base ".ly")))
- (diff (map (lambda (y) (apply - y)) (zip this last))))
+ (diff (map (lambda (y) (apply - y)) (zip this last))))
(ly:progress "\nWriting timing to ~a..." outname)
(format (open-file outname "w")
- "time: ~a\ncells: ~a\n"
- (if (ly:get-option 'dump-cpu-profile)
- (car diff)
- 0)
- (cadr diff))))
+ "time: ~a\ncells: ~a\n"
+ (if (ly:get-option 'dump-cpu-profile)
+ (car diff)
+ 0)
+ (cadr diff))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; debug memory leaks
(define-public (dump-live-object-stats outfile)
(for-each (lambda (x)
- (format outfile "~a: ~a\n" (car x) (cdr x)))
- (sort (gc-live-object-stats)
- (lambda (x y)
- (string<? (car x) (car y))))))
+ (format outfile "~a: ~a\n" (car x) (cdr x)))
+ (sort (gc-live-object-stats)
+ (lambda (x y)
+ (string<? (car x) (car y))))))
(define-public (dump-gc-protects)
(set! gc-protect-stat-count (1+ gc-protect-stat-count))
(let* ((protects (sort (hash-table->alist (ly:protects))
- (lambda (a b)
- (< (object-address (car a))
- (object-address (car b))))))
- (out-file-name (string-append
- "gcstat-" (number->string gc-protect-stat-count)
- ".scm"))
- (outfile (open-file out-file-name "w")))
+ (lambda (a b)
+ (< (object-address (car a))
+ (object-address (car b))))))
+ (out-file-name (string-append
+ "gcstat-" (number->string gc-protect-stat-count)
+ ".scm"))
+ (outfile (open-file out-file-name "w")))
(set! gc-dumping #t)
(format #t "Dumping GC statistics ~a...\n" out-file-name)
(for-each (lambda (y)
- (let ((x (car y))
- (c (cdr y)))
- (format outfile "~a (~a) = ~a\n" (object-address x) c x)))
- (filter
- (lambda (x)
- (not (symbol? (car x))))
- protects))
+ (let ((x (car y))
+ (c (cdr y)))
+ (format outfile "~a (~a) = ~a\n" (object-address x) c x)))
+ (filter
+ (lambda (x)
+ (not (symbol? (car x))))
+ protects))
(format outfile "\nprotected symbols: ~a\n"
- (apply + (map (lambda (obj-count)
- (if (symbol? (car obj-count))
- (cdr obj-count)
- 0))
- protects)))
+ (apply + (map (lambda (obj-count)
+ (if (symbol? (car obj-count))
+ (cdr obj-count)
+ 0))
+ protects)))
;; (display (ly:smob-protects))
(newline outfile)
(if (defined? 'gc-live-object-stats)
- (let* ((stats #f))
- (display "Live object statistics: GC'ing\n")
- (ly:reset-all-fonts)
- (gc)
- (gc)
- (display "Asserting dead objects\n")
- (ly:set-option 'debug-gc-assert-parsed-dead #t)
- (gc)
- (ly:set-option 'debug-gc-assert-parsed-dead #f)
- (set! stats (gc-live-object-stats))
- (display "Dumping live object statistics.\n")
- (dump-live-object-stats outfile)))
+ (let* ((stats #f))
+ (display "Live object statistics: GC'ing\n")
+ (ly:reset-all-fonts)
+ (gc)
+ (gc)
+ (display "Asserting dead objects\n")
+ (ly:set-option 'debug-gc-assert-parsed-dead #t)
+ (gc)
+ (ly:set-option 'debug-gc-assert-parsed-dead #f)
+ (set! stats (gc-live-object-stats))
+ (display "Dumping live object statistics.\n")
+ (dump-live-object-stats outfile)))
(newline outfile)
(let* ((stats (gc-stats)))
(for-each (lambda (sym)
- (format outfile "~a ~a ~a\n"
- gc-protect-stat-count
- sym
- (assoc-get sym stats "?")))
- '(protected-objects bytes-malloced cell-heap-size)))
+ (format outfile "~a ~a ~a\n"
+ gc-protect-stat-count
+ sym
+ (assoc-get sym stats "?")))
+ '(protected-objects bytes-malloced cell-heap-size)))
(set! gc-dumping #f)
(close-port outfile)))
"Read `/proc/self' to check up on memory use."
(define (gulp-file name)
(let* ((file (open-input-file name))
- (text (read-delimited "" file)))
+ (text (read-delimited "" file)))
(close file)
text))
(let* ((stat (gulp-file "/proc/self/status"))
- (lines (string-split stat #\newline))
- (interesting (filter identity
- (map
- (lambda (l)
- (string-match "^VmData:[ \t]*([0-9]*) kB" l))
- lines)))
- (mem (string->number (match:substring (car interesting) 1))))
+ (lines (string-split stat #\newline))
+ (interesting (filter identity
+ (map
+ (lambda (l)
+ (string-match "^VmData:[ \t]*([0-9]*) kB" l))
+ lines)))
+ (mem (string->number (match:substring (car interesting) 1))))
(format #t "VMDATA: ~a\n" mem)
(display (gc-stats))
(if (> mem 100000)
- (begin (dump-gc-protects)
- (raise 1)))))
+ (begin (dump-gc-protects)
+ (raise 1)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PIDs or the number of the process."
(define (helper count acc)
(if (> count 0)
- (let* ((pid (primitive-fork)))
- (if (= pid 0)
- (1- count)
- (helper (1- count) (cons pid acc))))
- acc))
+ (let* ((pid (primitive-fork)))
+ (if (= pid 0)
+ (1- count)
+ (helper (1- count) (cons pid acc))))
+ acc))
(helper count '()))
"Exit function for lilypond"
(if (not silently)
(case status
- ((0) (ly:success (_ "Compilation successfully completed")))
- ((1) (ly:warning (_ "Compilation completed with warnings or errors")))
- (else (ly:message ""))))
+ ((0) (ly:success (_ "Compilation successfully completed")))
+ ((1) (ly:warning (_ "Compilation completed with warnings or errors")))
+ (else (ly:message ""))))
(exit status))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(eval-string (ly:command-line-code))
(if (ly:get-option 'help)
(begin (ly:option-usage)
- (ly:exit 0 #t)))
+ (ly:exit 0 #t)))
(if (ly:get-option 'show-available-fonts)
(begin (ly:font-config-display-fonts)
- (ly:exit 0 #t)))
+ (ly:exit 0 #t)))
(if (ly:get-option 'gui)
(gui-main files))
(if (null? files)
(begin (ly:usage)
- (ly:exit 2 #t)))
+ (ly:exit 2 #t)))
(if (ly:get-option 'read-file-list)
(set! files
- (filter (lambda (s)
- (> (string-length s) 0))
- (apply append
- (map (lambda (f)
- (string-split (ly:gulp-file f) #\nl))
- files)))))
+ (filter (lambda (s)
+ (> (string-length s) 0))
+ (apply append
+ (map (lambda (f)
+ (string-split (ly:gulp-file f) #\nl))
+ files)))))
(if (and (number? (ly:get-option 'job-count))
- (>= (length files) (ly:get-option 'job-count)))
+ (>= (length files) (ly:get-option 'job-count)))
(let* ((count (ly:get-option 'job-count))
- (split-todo (split-list files count))
- (joblist (multi-fork count))
- (errors '()))
- (if (not (string-or-symbol? (ly:get-option 'log-file)))
- (ly:set-option 'log-file "lilypond-multi-run"))
- (if (number? joblist)
- (begin (ly:set-option
- 'log-file (format #f "~a-~a"
- (ly:get-option 'log-file) joblist))
- (set! files (vector-ref split-todo joblist)))
- (begin (ly:progress "\nForking into jobs: ~a\n" joblist)
- (for-each
- (lambda (pid)
- (let* ((stat (cdr (waitpid pid))))
- (if (not (= stat 0))
- (set! errors
- (acons (list-element-index joblist pid)
- stat errors)))))
- joblist)
- (for-each
- (lambda (x)
- (let* ((job (car x))
- (state (cdr x))
- (logfile (format #f "~a-~a.log"
- (ly:get-option 'log-file) job))
- (log (ly:gulp-file logfile))
- (len (string-length log))
- (tail (substring log (max 0 (- len 1024)))))
- (if (status:term-sig state)
- (ly:message
- "\n\n~a\n"
- (format #f (_ "job ~a terminated with signal: ~a")
- job (status:term-sig state)))
- (ly:message
- (_ "logfile ~a (exit ~a):\n~a")
- logfile (status:exit-val state) tail))))
- errors)
- (if (pair? errors)
- (ly:error "Children ~a exited with errors."
- (map car errors)))
- ;; must overwrite individual entries
- (if (ly:get-option 'dump-profile)
- (dump-profile "lily-run-total"
- '(0 0) (profile-measurements)))
- (if (null? errors)
- (ly:exit 0 #f)
- (ly:exit 1 #f))))))
+ (split-todo (split-list files count))
+ (joblist (multi-fork count))
+ (errors '()))
+ (if (not (string-or-symbol? (ly:get-option 'log-file)))
+ (ly:set-option 'log-file "lilypond-multi-run"))
+ (if (number? joblist)
+ (begin (ly:set-option
+ 'log-file (format #f "~a-~a"
+ (ly:get-option 'log-file) joblist))
+ (set! files (vector-ref split-todo joblist)))
+ (begin (ly:progress "\nForking into jobs: ~a\n" joblist)
+ (for-each
+ (lambda (pid)
+ (let* ((stat (cdr (waitpid pid))))
+ (if (not (= stat 0))
+ (set! errors
+ (acons (list-element-index joblist pid)
+ stat errors)))))
+ joblist)
+ (for-each
+ (lambda (x)
+ (let* ((job (car x))
+ (state (cdr x))
+ (logfile (format #f "~a-~a.log"
+ (ly:get-option 'log-file) job))
+ (log (ly:gulp-file logfile))
+ (len (string-length log))
+ (tail (substring log (max 0 (- len 1024)))))
+ (if (status:term-sig state)
+ (ly:message
+ "\n\n~a\n"
+ (format #f (_ "job ~a terminated with signal: ~a")
+ job (status:term-sig state)))
+ (ly:message
+ (_ "logfile ~a (exit ~a):\n~a")
+ logfile (status:exit-val state) tail))))
+ errors)
+ (if (pair? errors)
+ (ly:error "Children ~a exited with errors."
+ (map car errors)))
+ ;; must overwrite individual entries
+ (if (ly:get-option 'dump-profile)
+ (dump-profile "lily-run-total"
+ '(0 0) (profile-measurements)))
+ (if (null? errors)
+ (ly:exit 0 #f)
+ (ly:exit 1 #f))))))
(if (string-or-symbol? (ly:get-option 'log-file))
(ly:stderr-redirect (format #f "~a.log" (ly:get-option 'log-file)) "w"))
(let ((failed (lilypond-all files)))
(if (ly:get-option 'trace-scheme-coverage)
- (begin
- (coverage:show-all (lambda (f)
- (string-contains f "lilypond")))))
+ (begin
+ (coverage:show-all (lambda (f)
+ (string-contains f "lilypond")))))
(if (pair? failed)
- (begin (ly:error (_ "failed files: ~S") (string-join failed))
- (ly:exit 1 #f))
- (begin
- (ly:exit 0 #f)))))
+ (begin (ly:error (_ "failed files: ~S") (string-join failed))
+ (ly:exit 1 #f))
+ (begin
+ (ly:exit 0 #f)))))
(define-public (lilypond-all files)
(let* ((failed '())
- (separate-logs (ly:get-option 'separate-log-files))
- (ping-log
- (if separate-logs
- (open-file (if (string-or-symbol? (ly:get-option 'log-file))
- (format #f "~a.log" (ly:get-option 'log-file))
- "/dev/stderr") "a") #f))
- (do-measurements (ly:get-option 'dump-profile))
- (handler (lambda (key failed-file)
- (set! failed (append (list failed-file) failed)))))
+ (separate-logs (ly:get-option 'separate-log-files))
+ (ping-log
+ (if separate-logs
+ (open-file (if (string-or-symbol? (ly:get-option 'log-file))
+ (format #f "~a.log" (ly:get-option 'log-file))
+ "/dev/stderr") "a") #f))
+ (do-measurements (ly:get-option 'dump-profile))
+ (handler (lambda (key failed-file)
+ (set! failed (append (list failed-file) failed)))))
(gc)
(for-each
(lambda (x)
(let* ((start-measurements (if do-measurements
- (profile-measurements)
- #f))
- (base (dir-basename x ".ly"))
- (all-settings (ly:all-options)))
- (if separate-logs
- (ly:stderr-redirect (format #f "~a.log" base) "w"))
- (if ping-log
- (format ping-log "Processing ~a\n" base))
- (if (ly:get-option 'trace-memory-frequency)
- (mtrace:start-trace (ly:get-option 'trace-memory-frequency)))
- (lilypond-file handler x)
- (if start-measurements
- (dump-profile x start-measurements (profile-measurements)))
- (if (ly:get-option 'trace-memory-frequency)
- (begin (mtrace:stop-trace)
- (mtrace:dump-results base)))
- (for-each (lambda (s)
- (ly:set-option (car s) (cdr s)))
- all-settings)
- (ly:set-option 'debug-gc-assert-parsed-dead #t)
- (gc)
- (ly:set-option 'debug-gc-assert-parsed-dead #f)
- (if (ly:get-option 'debug-gc)
- (dump-gc-protects)
+ (profile-measurements)
+ #f))
+ (base (dir-basename x ".ly"))
+ (all-settings (ly:all-options)))
+ (if separate-logs
+ (ly:stderr-redirect (format #f "~a.log" base) "w"))
+ (if ping-log
+ (format ping-log "Processing ~a\n" base))
+ (if (ly:get-option 'trace-memory-frequency)
+ (mtrace:start-trace (ly:get-option 'trace-memory-frequency)))
+ (lilypond-file handler x)
+ (if start-measurements
+ (dump-profile x start-measurements (profile-measurements)))
+ (if (ly:get-option 'trace-memory-frequency)
+ (begin (mtrace:stop-trace)
+ (mtrace:dump-results base)))
+ (for-each (lambda (s)
+ (ly:set-option (car s) (cdr s)))
+ all-settings)
+ (ly:set-option 'debug-gc-assert-parsed-dead #t)
+ (gc)
+ (ly:set-option 'debug-gc-assert-parsed-dead #f)
+ (if (ly:get-option 'debug-gc)
+ (dump-gc-protects)
(ly:reset-all-fonts))))
files)
;; Ensure a notice re failed files is written to aggregate logfile.
(if ping-log
- (format ping-log "Failed files: ~a\n" failed))
+ (format ping-log "Failed files: ~a\n" failed))
(if (ly:get-option 'dump-profile)
- (dump-profile "lily-run-total" '(0 0) (profile-measurements)))
+ (dump-profile "lily-run-total" '(0 0) (profile-measurements)))
failed))
(define (lilypond-file handler file-name)
(catch 'ly-file-failed
- (lambda () (ly:parse-file file-name))
- (lambda (x . args) (handler x file-name))))
+ (lambda () (ly:parse-file file-name))
+ (lambda (x . args) (handler x file-name))))
(use-modules (scm editor))
(gui-no-files-handler))
(if (not (string? (ly:get-option 'log-file)))
(let* ((base (dir-basename (car files) ".ly"))
- (log-name (string-append base ".log")))
- (if (not (ly:get-option 'gui))
- (ly:message (_ "Redirecting output to ~a...") log-name))
- (ly:stderr-redirect log-name "w")
- (ly:message "# -*-compilation-*-"))
+ (log-name (string-append base ".log")))
+ (if (not (ly:get-option 'gui))
+ (ly:message (_ "Redirecting output to ~a...") log-name))
+ (ly:stderr-redirect log-name "w")
+ (ly:message "# -*-compilation-*-"))
(let ((failed (lilypond-all files)))
- (if (pair? failed)
- (begin
- ;; ugh
- (ly:stderr-redirect "foo" "r")
- (system (get-editor-command log-name 0 0 0))
- (ly:error (_ "failed files: ~S") (string-join failed))
- ;; not reached?
- (exit 1))
- (ly:exit 0 #f)))))
+ (if (pair? failed)
+ (begin
+ ;; ugh
+ (ly:stderr-redirect "foo" "r")
+ (system (get-editor-command log-name 0 0 0))
+ (ly:error (_ "failed files: ~S") (string-join failed))
+ ;; not reached?
+ (exit 1))
+ (ly:exit 0 #f)))))
(define (gui-no-files-handler)
(let* ((ly (string-append (ly:effective-prefix) "/ly/"))
- ;; FIXME: soft-code, localize
- (welcome-ly (string-append ly "Welcome_to_LilyPond.ly"))
- (cmd (get-editor-command welcome-ly 0 0 0)))
+ ;; FIXME: soft-code, localize
+ (welcome-ly (string-append ly "Welcome_to_LilyPond.ly"))
+ (cmd (get-editor-command welcome-ly 0 0 0)))
(ly:message (_ "Invoking `~a'...\n") cmd)
(system cmd)
(ly:exit 1 #f)))
--- /dev/null
+;;;; This file is part of LilyPond, the GNU music typesetter.
+;;;;
+;;;; Copyright (C) 2003--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;;
+;;;; 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/>.
+
+"
+Internally markup is stored as lists, whose head is a function.
+
+ (FUNCTION ARG1 ARG2 ... )
+
+When the markup is formatted, then FUNCTION is called as follows
+
+ (FUNCTION GROB PROPS ARG1 ARG2 ... )
+
+GROB is the current grob, PROPS is a list of alists, and ARG1.. are
+the rest of the arguments.
+
+The function should return a stencil (i.e. a formatted, ready to
+print object).
+
+
+To add a markup command, use the define-markup-command utility.
+
+ (define-markup-command (mycommand layout prop arg1 ...) (arg1-type? ...)
+ \"my command usage and description\"
+ ...function body...)
+
+The command is now available in markup mode, e.g.
+
+ \\markup { .... \\MYCOMMAND #1 argument ... }
+
+" ; "
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; markup definer utilities
+
+;; For documentation purposes
+;; category -> markup functions
+(define-public markup-functions-by-category (make-hash-table 150))
+;; markup function -> used properties
+(define-public markup-functions-properties (make-weak-key-hash-table 151))
+;; List of markup list functions
+(define-public markup-list-functions (make-weak-key-hash-table 151))
+
+(use-modules (ice-9 optargs))
+
+(defmacro*-public define-markup-command
+ (command-and-args signature
+ #:key (category '()) (properties '())
+ #:rest body)
+ "
+* Define a COMMAND-markup function after command-and-args and body,
+register COMMAND-markup and its signature,
+
+* add COMMAND-markup to markup-functions-by-category,
+
+* sets COMMAND-markup markup-signature object property,
+
+* define a make-COMMAND-markup function.
+
+Syntax:
+ (define-markup-command (COMMAND layout props . arguments)
+ argument-types
+ [ #:properties properties ]
+ \"documentation string\"
+ ...command body...)
+
+where:
+ `argument-types' is a list of type predicates for arguments
+ `properties' a list of (property default-value) lists
+
+The specified properties are available as let-bound variables in the
+command body, using the respective `default-value' as fallback in case
+`property' is not found in `props'. `props' itself is left unchanged:
+if you want defaults specified in that manner passed down into other
+markup functions, you need to adjust `props' yourself.
+
+The autogenerated documentation makes use of some optional
+specifications that are otherwise ignored:
+
+After `argument-types', you may also specify
+ [ #:category category ]
+where:
+ `category' is either a symbol or a symbol list specifying the
+ category for this markup command in the docs.
+
+As an element of the `properties' list, you may directly use a
+COMMANDx-markup symbol instead of a `(prop value)' list to indicate
+that this markup command is called by the newly defined command,
+adding its properties to the documented properties of the new
+command. There is no protection against circular definitions.
+"
+ (let* ((command (car command-and-args))
+ (args (cdr command-and-args))
+ (command-name (string->symbol (format #f "~a-markup" command)))
+ (make-markup-name (string->symbol (format #f "make-~a-markup" command))))
+ (while (and (pair? body) (keyword? (car body)))
+ (set! body (cddr body)))
+ `(begin
+ ;; define the COMMAND-markup function
+ ,(let* ((documentation (if (string? (car body))
+ (list (car body))
+ '()))
+ (real-body (if (or (null? documentation)
+ (null? (cdr body)))
+ body (cdr body))))
+ `(define-public (,command-name ,@args)
+ ,@documentation
+ (let ,(map (lambda (prop-spec)
+ (let ((prop (car prop-spec))
+ (default-value (if (null? (cdr prop-spec))
+ #f
+ (cadr prop-spec)))
+ (props (cadr args)))
+ `(,prop (chain-assoc-get ',prop ,props ,default-value))))
+ (filter pair? properties))
+ ,@real-body)))
+ (set! (markup-command-signature ,command-name) (list ,@signature))
+ ;; Register the new function, for markup documentation
+ ,@(map (lambda (category)
+ `(hashq-set!
+ (or (hashq-ref markup-functions-by-category ',category)
+ (let ((hash (make-weak-key-hash-table 151)))
+ (hashq-set! markup-functions-by-category ',category
+ hash)
+ hash))
+ ,command-name #t))
+ (if (list? category) category (list category)))
+ ;; Used properties, for markup documentation
+ (hashq-set! markup-functions-properties
+ ,command-name
+ (list ,@(map (lambda (prop-spec)
+ (cond ((symbol? prop-spec)
+ prop-spec)
+ ((not (null? (cdr prop-spec)))
+ `(list ',(car prop-spec) ,(cadr prop-spec)))
+ (else
+ `(list ',(car prop-spec)))))
+ (if (pair? args)
+ properties
+ (list)))))
+ ;; define the make-COMMAND-markup function
+ (define-public (,make-markup-name . args)
+ (let ((sig (list ,@signature)))
+ (make-markup ,command-name ,(symbol->string make-markup-name) sig args))))))
+
+(defmacro*-public define-markup-list-command
+ (command-and-args signature #:key (properties '()) #:rest body)
+ "Same as `define-markup-command', but defines a command that, when
+interpreted, returns a list of stencils instead of a single one"
+ (let* ((command (car command-and-args))
+ (args (cdr command-and-args))
+ (command-name (string->symbol (format #f "~a-markup-list" command)))
+ (make-markup-name (string->symbol (format #f "make-~a-markup-list" command))))
+ (while (and (pair? body) (keyword? (car body)))
+ (set! body (cddr body)))
+ `(begin
+ ;; define the COMMAND-markup-list function
+ ,(let* ((documentation (if (string? (car body))
+ (list (car body))
+ '()))
+ (real-body (if (or (null? documentation)
+ (null? (cdr body)))
+ body (cdr body))))
+ `(define-public (,command-name ,@args)
+ ,@documentation
+ (let ,(map (lambda (prop-spec)
+ (let ((prop (car prop-spec))
+ (default-value (if (null? (cdr prop-spec))
+ #f
+ (cadr prop-spec)))
+ (props (cadr args)))
+ `(,prop (chain-assoc-get ',prop ,props ,default-value))))
+ (filter pair? properties))
+ ,@real-body)))
+ (set! (markup-command-signature ,command-name) (list ,@signature))
+ ;; add the command to markup-list-function-list, for markup documentation
+ (hashq-set! markup-list-functions ,command-name #t)
+ ;; Used properties, for markup documentation
+ (hashq-set! markup-functions-properties
+ ,command-name
+ (list ,@(map (lambda (prop-spec)
+ (cond ((symbol? prop-spec)
+ prop-spec)
+ ((not (null? (cdr prop-spec)))
+ `(list ',(car prop-spec) ,(cadr prop-spec)))
+ (else
+ `(list ',(car prop-spec)))))
+ (if (pair? args)
+ properties
+ (list)))))
+ ;; it's a markup-list command:
+ (set-object-property! ,command-name 'markup-list-command #t)
+ ;; define the make-COMMAND-markup-list function
+ (define-public (,make-markup-name . args)
+ (let ((sig (list ,@signature)))
+ (list (make-markup ,command-name
+ ,(symbol->string make-markup-name) sig args)))))))
+
+;;;;;;;;;;;;;;;
+;;; Utilities for storing and accessing markup commands signature
+;;; Examples:
+;;;
+;;; (set! (markup-command-signature raise-markup) (list number? markup?))
+;;; ==> (#<primitive-procedure number?> #<procedure markup? (obj)>)
+;;;
+;;; (markup-command-signature raise-markup)
+;;; ==> (#<primitive-procedure number?> #<procedure markup? (obj)>)
+;;;
+
+(define-public (markup-command-signature-ref markup-command)
+ "Return markup-command's signature (the 'markup-signature object property)"
+ (object-property markup-command 'markup-signature))
+
+(define-public (markup-command-signature-set! markup-command signature)
+ "Set markup-command's signature (as object property)"
+ (set-object-property! markup-command 'markup-signature signature)
+ signature)
+
+(define-public markup-command-signature
+ (make-procedure-with-setter markup-command-signature-ref
+ markup-command-signature-set!))
+
+;;;;;;;;;;;;;;;;;;;;;;
+;;; markup type predicates
+
+(define (markup-function? x)
+ (and (markup-command-signature x)
+ (not (object-property x 'markup-list-command))))
+
+(define (markup-list-function? x)
+ (and (markup-command-signature x)
+ (object-property x 'markup-list-command)))
+
+(define-public (markup-command-list? x)
+ "Determine if `x' is a markup command list, ie. a list composed of
+a markup list function and its arguments."
+ (and (pair? x) (markup-list-function? (car x))))
+
+(define-public (markup-list? arg)
+ "Return a true value if `x' is a list of markups or markup command lists."
+ (define (markup-list-inner? lst)
+ (or (null? lst)
+ (and (or (markup? (car lst)) (markup-command-list? (car lst)))
+ (markup-list-inner? (cdr lst)))))
+ (not (not (and (list? arg) (markup-list-inner? arg)))))
+
+(define (markup-argument-list? signature arguments)
+ "Typecheck argument list."
+ (if (and (pair? signature) (pair? arguments))
+ (and ((car signature) (car arguments))
+ (markup-argument-list? (cdr signature) (cdr arguments)))
+ (and (null? signature) (null? arguments))))
+
+
+(define (markup-argument-list-error signature arguments number)
+ "return (ARG-NR TYPE-EXPECTED ARG-FOUND) if an error is detected, or
+#f is no error found.
+"
+ (if (and (pair? signature) (pair? arguments))
+ (if (not ((car signature) (car arguments)))
+ (list number (type-name (car signature)) (car arguments))
+ (markup-argument-list-error (cdr signature) (cdr arguments) (+ 1 number)))
+ #f))
+
+;;
+;; full recursive typecheck.
+;;
+(define (markup-typecheck? arg)
+ (or (string? arg)
+ (and (pair? arg)
+ (markup-function? (car arg))
+ (markup-argument-list? (markup-command-signature (car arg))
+ (cdr arg)))))
+
+;;
+;;
+;;
+;;
+(define (markup-thrower-typecheck arg)
+ "typecheck, and throw an error when something amiss.
+
+Uncovered - cheap-markup? is used."
+
+ (cond ((string? arg) #t)
+ ((not (pair? arg))
+ (throw 'markup-format "Not a pair" arg))
+ ((not (markup-function? (car arg)))
+ (throw 'markup-format "Not a markup function " (car arg)))
+ ((not (markup-argument-list? (markup-command-signature (car arg))
+ (cdr arg)))
+ (throw 'markup-format "Arguments failed typecheck for " arg)))
+ #t)
+
+;;
+;; good enough if you only use make-XXX-markup functions.
+;;
+(define (cheap-markup? x)
+ (or (string? x)
+ (and (pair? x)
+ (markup-function? (car x)))))
+
+;;
+;; replace by markup-thrower-typecheck for more detailed diagnostics.
+;;
+(define-public markup? cheap-markup?)
+
+(define-public (make-markup markup-function make-name signature args)
+ " Construct a markup object from MARKUP-FUNCTION and ARGS. Typecheck
+against SIGNATURE, reporting MAKE-NAME as the user-invoked function.
+"
+ (let* ((arglen (length args))
+ (siglen (length signature))
+ (error-msg (if (and (> siglen 0) (> arglen 0))
+ (markup-argument-list-error signature args 1)
+ #f)))
+ (if (or (not (= arglen siglen)) (< siglen 0) (< arglen 0))
+ (ly:error (string-append make-name ": "
+ (_ "Wrong number of arguments. Expect: ~A, found ~A: ~S"))
+ siglen arglen args))
+ (if error-msg
+ (ly:error
+ (string-append
+ make-name ": "
+ (_ "Invalid argument in position ~A. Expect: ~A, found: ~S."))
+ (car error-msg) (cadr error-msg)(caddr error-msg))
+ (cons markup-function args))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; markup constructors
+;;; lilypond-like syntax for markup construction in scheme.
+
+(use-modules (ice-9 receive))
+
+(defmacro*-public markup* (#:rest body)
+ "Same as `markup', for use in a \\notes block."
+ `(ly:export (markup ,@body)))
+
+
+(define (compile-all-markup-expressions expr)
+ "Return a list of canonical markups expressions, e.g.:
+ (#:COMMAND1 arg11 arg12 #:COMMAND2 arg21 arg22 arg23)
+ ===>
+ ((make-COMMAND1-markup arg11 arg12)
+ (make-COMMAND2-markup arg21 arg22 arg23) ...)"
+ (do ((rest expr rest)
+ (markps '() markps))
+ ((null? rest) (reverse markps))
+ (receive (m r) (compile-markup-expression rest)
+ (set! markps (cons m markps))
+ (set! rest r))))
+
+(define (keyword->make-markup key)
+ "Transform a keyword, e.g. #:COMMAND, in a make-COMMAND-markup symbol."
+ (string->symbol (string-append "make-" (symbol->string (keyword->symbol key)) "-markup")))
+
+(define (compile-markup-expression expr)
+ "Return two values: the first complete canonical markup expression
+ found in `expr', e.g. (make-COMMAND-markup arg1 arg2 ...),
+ and the rest expression."
+ (cond ((and (pair? expr)
+ (keyword? (car expr)))
+ ;; expr === (#:COMMAND arg1 ...)
+ (let ((command (symbol->string (keyword->symbol (car expr)))))
+ (if (not (pair? (lookup-markup-command command)))
+ (ly:error (_ "Not a markup command: ~A") command))
+ (let* ((sig (markup-command-signature
+ (car (lookup-markup-command command))))
+ (sig-len (length sig)))
+ (do ((i 0 (1+ i))
+ (args '() args)
+ (rest (cdr expr) rest))
+ ((>= i sig-len)
+ (values (cons (keyword->make-markup (car expr)) (reverse args)) rest))
+ (cond ((eqv? (list-ref sig i) markup-list?)
+ ;; (car rest) is a markup list
+ (set! args (cons `(list ,@(compile-all-markup-expressions (car rest))) args))
+ (set! rest (cdr rest)))
+ (else
+ ;; pick up one arg in `rest'
+ (receive (a r) (compile-markup-arg rest)
+ (set! args (cons a args))
+ (set! rest r))))))))
+ ((and (pair? expr)
+ (pair? (car expr))
+ (keyword? (caar expr)))
+ ;; expr === ((#:COMMAND arg1 ...) ...)
+ (receive (m r) (compile-markup-expression (car expr))
+ (values m (cdr expr))))
+ ((and (pair? expr)
+ (string? (car expr))) ;; expr === ("string" ...)
+ (values `(make-simple-markup ,(car expr)) (cdr expr)))
+ (else
+ ;; expr === (symbol ...) or ((funcall ...) ...)
+ (values (car expr)
+ (cdr expr)))))
+
+(define (compile-all-markup-args expr)
+ "Transform `expr' into markup arguments"
+ (do ((rest expr rest)
+ (args '() args))
+ ((null? rest) (reverse args))
+ (receive (a r) (compile-markup-arg rest)
+ (set! args (cons a args))
+ (set! rest r))))
+
+(define (compile-markup-arg expr)
+ "Return two values: the desired markup argument, and the rest arguments"
+ (cond ((null? expr)
+ ;; no more args
+ (values '() '()))
+ ((keyword? (car expr))
+ ;; expr === (#:COMMAND ...)
+ ;; ==> build and return the whole markup expression
+ (compile-markup-expression expr))
+ ((and (pair? (car expr))
+ (keyword? (caar expr)))
+ ;; expr === ((#:COMMAND ...) ...)
+ ;; ==> build and return the whole markup expression(s)
+ ;; found in (car expr)
+ (receive (markup-expr rest-expr) (compile-markup-expression (car expr))
+ (if (null? rest-expr)
+ (values markup-expr (cdr expr))
+ (values `(list ,markup-expr ,@(compile-all-markup-args rest-expr))
+ (cdr expr)))))
+ ((and (pair? (car expr))
+ (pair? (caar expr)))
+ ;; expr === (((foo ...) ...) ...)
+ (values (cons 'list (compile-all-markup-args (car expr))) (cdr expr)))
+ (else (values (car expr) (cdr expr)))))
+
+(define (lookup-markup-command-aux symbol)
+ (let ((proc (catch 'misc-error
+ (lambda ()
+ (module-ref (current-module) symbol))
+ (lambda (key . args) #f))))
+ (and (procedure? proc) proc)))
+
+(define-public (lookup-markup-command code)
+ (let ((proc (lookup-markup-command-aux
+ (string->symbol (format #f "~a-markup" code)))))
+ (and proc (markup-function? proc)
+ (cons proc (markup-command-signature proc)))))
+
+(define-public (lookup-markup-list-command code)
+ (let ((proc (lookup-markup-command-aux
+ (string->symbol (format #f "~a-markup-list" code)))))
+ (and proc (markup-list-function? proc)
+ (cons proc (markup-command-signature proc)))))
+
+;;;;;;;;;;;;;;;;;;;;;;
+;;; used in parser.yy to map a list of markup commands on markup arguments
+(define-public (map-markup-command-list commands markups)
+ "`markups' being a list of markups, eg (markup1 markup2 markup3),
+and `commands' a list of commands with their scheme arguments, in reverse order,
+eg: ((italic) (raise 4) (bold)), maps the commands on each markup argument, eg:
+ ((bold (raise 4 (italic markup1)))
+ (bold (raise 4 (italic markup2)))
+ (bold (raise 4 (italic markup3))))
+"
+ (map-in-order (lambda (arg)
+ (let ((result arg))
+ (for-each (lambda (cmd)
+ (set! result (append cmd (list result))))
+ commands)
+ result))
+ markups))
;;;; You should have received a copy of the GNU General Public License
;;;; along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-"
-Internally markup is stored as lists, whose head is a function.
-
- (FUNCTION ARG1 ARG2 ... )
-
-When the markup is formatted, then FUNCTION is called as follows
-
- (FUNCTION GROB PROPS ARG1 ARG2 ... )
-
-GROB is the current grob, PROPS is a list of alists, and ARG1.. are
-the rest of the arguments.
-
-The function should return a stencil (i.e. a formatted, ready to
-print object).
-
-
-To add a markup command, use the define-markup-command utility.
-
- (define-markup-command (mycommand layout prop arg1 ...) (arg1-type? ...)
- \"my command usage and description\"
- ...function body...)
-
-The command is now available in markup mode, e.g.
-
- \\markup { .... \\MYCOMMAND #1 argument ... }
-
-" ; "
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; markup definer utilities
-
-;; For documentation purposes
-;; category -> markup functions
-(define-public markup-functions-by-category (make-hash-table 150))
-;; markup function -> used properties
-(define-public markup-functions-properties (make-weak-key-hash-table 151))
-;; List of markup list functions
-(define-public markup-list-functions (make-weak-key-hash-table 151))
-
-(use-modules (ice-9 optargs))
-
-(defmacro*-public define-markup-command
- (command-and-args signature
- #:key (category '()) (properties '())
- #:rest body)
- "
-* Define a COMMAND-markup function after command-and-args and body,
-register COMMAND-markup and its signature,
-
-* add COMMAND-markup to markup-functions-by-category,
-
-* sets COMMAND-markup markup-signature object property,
-
-* define a make-COMMAND-markup function.
-
-Syntax:
- (define-markup-command (COMMAND layout props . arguments)
- argument-types
- [ #:properties properties ]
- \"documentation string\"
- ...command body...)
-
-where:
- `argument-types' is a list of type predicates for arguments
- `properties' a list of (property default-value) lists
-
-The specified properties are available as let-bound variables in the
-command body, using the respective `default-value' as fallback in case
-`property' is not found in `props'. `props' itself is left unchanged:
-if you want defaults specified in that manner passed down into other
-markup functions, you need to adjust `props' yourself.
-
-The autogenerated documentation makes use of some optional
-specifications that are otherwise ignored:
-
-After `argument-types', you may also specify
- [ #:category category ]
-where:
- `category' is either a symbol or a symbol list specifying the
- category for this markup command in the docs.
-
-As an element of the `properties' list, you may directly use a
-COMMANDx-markup symbol instead of a `(prop value)' list to indicate
-that this markup command is called by the newly defined command,
-adding its properties to the documented properties of the new
-command. There is no protection against circular definitions.
-"
- (let* ((command (car command-and-args))
- (args (cdr command-and-args))
- (command-name (string->symbol (format #f "~a-markup" command)))
- (make-markup-name (string->symbol (format #f "make-~a-markup" command))))
- (while (and (pair? body) (keyword? (car body)))
- (set! body (cddr body)))
- `(begin
- ;; define the COMMAND-markup function
- ,(let* ((documentation (if (string? (car body))
- (list (car body))
- '()))
- (real-body (if (or (null? documentation)
- (null? (cdr body)))
- body (cdr body))))
- `(define-public (,command-name ,@args)
- ,@documentation
- (let ,(map (lambda (prop-spec)
- (let ((prop (car prop-spec))
- (default-value (if (null? (cdr prop-spec))
- #f
- (cadr prop-spec)))
- (props (cadr args)))
- `(,prop (chain-assoc-get ',prop ,props ,default-value))))
- (filter pair? properties))
- ,@real-body)))
- (set! (markup-command-signature ,command-name) (list ,@signature))
- ;; Register the new function, for markup documentation
- ,@(map (lambda (category)
- `(hashq-set!
- (or (hashq-ref markup-functions-by-category ',category)
- (let ((hash (make-weak-key-hash-table 151)))
- (hashq-set! markup-functions-by-category ',category
- hash)
- hash))
- ,command-name #t))
- (if (list? category) category (list category)))
- ;; Used properties, for markup documentation
- (hashq-set! markup-functions-properties
- ,command-name
- (list ,@(map (lambda (prop-spec)
- (cond ((symbol? prop-spec)
- prop-spec)
- ((not (null? (cdr prop-spec)))
- `(list ',(car prop-spec) ,(cadr prop-spec)))
- (else
- `(list ',(car prop-spec)))))
- (if (pair? args)
- properties
- (list)))))
- ;; define the make-COMMAND-markup function
- (define-public (,make-markup-name . args)
- (let ((sig (list ,@signature)))
- (make-markup ,command-name ,(symbol->string make-markup-name) sig args))))))
-
-(defmacro*-public define-markup-list-command
- (command-and-args signature #:key (properties '()) #:rest body)
- "Same as `define-markup-command', but defines a command that, when
-interpreted, returns a list of stencils instead of a single one"
- (let* ((command (car command-and-args))
- (args (cdr command-and-args))
- (command-name (string->symbol (format #f "~a-markup-list" command)))
- (make-markup-name (string->symbol (format #f "make-~a-markup-list" command))))
- (while (and (pair? body) (keyword? (car body)))
- (set! body (cddr body)))
- `(begin
- ;; define the COMMAND-markup-list function
- ,(let* ((documentation (if (string? (car body))
- (list (car body))
- '()))
- (real-body (if (or (null? documentation)
- (null? (cdr body)))
- body (cdr body))))
- `(define-public (,command-name ,@args)
- ,@documentation
- (let ,(map (lambda (prop-spec)
- (let ((prop (car prop-spec))
- (default-value (if (null? (cdr prop-spec))
- #f
- (cadr prop-spec)))
- (props (cadr args)))
- `(,prop (chain-assoc-get ',prop ,props ,default-value))))
- (filter pair? properties))
- ,@real-body)))
- (set! (markup-command-signature ,command-name) (list ,@signature))
- ;; add the command to markup-list-function-list, for markup documentation
- (hashq-set! markup-list-functions ,command-name #t)
- ;; Used properties, for markup documentation
- (hashq-set! markup-functions-properties
- ,command-name
- (list ,@(map (lambda (prop-spec)
- (cond ((symbol? prop-spec)
- prop-spec)
- ((not (null? (cdr prop-spec)))
- `(list ',(car prop-spec) ,(cadr prop-spec)))
- (else
- `(list ',(car prop-spec)))))
- (if (pair? args)
- properties
- (list)))))
- ;; it's a markup-list command:
- (set-object-property! ,command-name 'markup-list-command #t)
- ;; define the make-COMMAND-markup-list function
- (define-public (,make-markup-name . args)
- (let ((sig (list ,@signature)))
- (list (make-markup ,command-name
- ,(symbol->string make-markup-name) sig args)))))))
-
-(define-public (make-markup markup-function make-name signature args)
- "Construct a markup object from @var{markup-function} and @var{args}.
-Typecheck against @var{signature}, reporting @var{make-name} as the
-user-invoked function."
- (let* ((arglen (length args))
- (siglen (length signature))
- (error-msg (if (and (> siglen 0) (> arglen 0))
- (markup-argument-list-error signature args 1)
- #f)))
- (if (or (not (= arglen siglen)) (< siglen 0) (< arglen 0))
- (ly:error (string-append make-name ": "
- (_ "Wrong number of arguments. Expect: ~A, found ~A: ~S"))
- siglen arglen args))
- (if error-msg
- (ly:error
- (string-append
- make-name ": "
- (_ "Invalid argument in position ~A. Expect: ~A, found: ~S."))
- (car error-msg) (cadr error-msg)(caddr error-msg))
- (cons markup-function args))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; markup constructors
-;;; lilypond-like syntax for markup construction in scheme.
-
-(use-modules (ice-9 receive))
-
(defmacro*-public markup (#:rest body)
"The `markup' macro provides a lilypond-like syntax for building markups.
(car (compile-all-markup-expressions `(#:line ,body))))
-(defmacro*-public markup* (#:rest body)
- "Same as `markup', for use in a \\notes block."
- `(ly:export (markup ,@body)))
-
-
-(define (compile-all-markup-expressions expr)
- "Return a list of canonical markups expressions, e.g.:
- (#:COMMAND1 arg11 arg12 #:COMMAND2 arg21 arg22 arg23)
- ===>
- ((make-COMMAND1-markup arg11 arg12)
- (make-COMMAND2-markup arg21 arg22 arg23) ...)"
- (do ((rest expr rest)
- (markps '() markps))
- ((null? rest) (reverse markps))
- (receive (m r) (compile-markup-expression rest)
- (set! markps (cons m markps))
- (set! rest r))))
-
-(define (keyword->make-markup key)
- "Transform a keyword, e.g. #:COMMAND, in a make-COMMAND-markup symbol."
- (string->symbol (string-append "make-" (symbol->string (keyword->symbol key)) "-markup")))
-
-(define (compile-markup-expression expr)
- "Return two values: the first complete canonical markup expression
- found in `expr', e.g. (make-COMMAND-markup arg1 arg2 ...),
- and the rest expression."
- (cond ((and (pair? expr)
- (keyword? (car expr)))
- ;; expr === (#:COMMAND arg1 ...)
- (let ((command (symbol->string (keyword->symbol (car expr)))))
- (if (not (pair? (lookup-markup-command command)))
- (ly:error (_ "Not a markup command: ~A") command))
- (let* ((sig (markup-command-signature
- (car (lookup-markup-command command))))
- (sig-len (length sig)))
- (do ((i 0 (1+ i))
- (args '() args)
- (rest (cdr expr) rest))
- ((>= i sig-len)
- (values (cons (keyword->make-markup (car expr)) (reverse args)) rest))
- (cond ((eqv? (list-ref sig i) markup-list?)
- ;; (car rest) is a markup list
- (set! args (cons `(list ,@(compile-all-markup-expressions (car rest))) args))
- (set! rest (cdr rest)))
- (else
- ;; pick up one arg in `rest'
- (receive (a r) (compile-markup-arg rest)
- (set! args (cons a args))
- (set! rest r))))))))
- ((and (pair? expr)
- (pair? (car expr))
- (keyword? (caar expr)))
- ;; expr === ((#:COMMAND arg1 ...) ...)
- (receive (m r) (compile-markup-expression (car expr))
- (values m (cdr expr))))
- ((and (pair? expr)
- (string? (car expr))) ;; expr === ("string" ...)
- (values `(make-simple-markup ,(car expr)) (cdr expr)))
- (else
- ;; expr === (symbol ...) or ((funcall ...) ...)
- (values (car expr)
- (cdr expr)))))
-
-(define (compile-all-markup-args expr)
- "Transform `expr' into markup arguments"
- (do ((rest expr rest)
- (args '() args))
- ((null? rest) (reverse args))
- (receive (a r) (compile-markup-arg rest)
- (set! args (cons a args))
- (set! rest r))))
-
-(define (compile-markup-arg expr)
- "Return two values: the desired markup argument, and the rest arguments"
- (cond ((null? expr)
- ;; no more args
- (values '() '()))
- ((keyword? (car expr))
- ;; expr === (#:COMMAND ...)
- ;; ==> build and return the whole markup expression
- (compile-markup-expression expr))
- ((and (pair? (car expr))
- (keyword? (caar expr)))
- ;; expr === ((#:COMMAND ...) ...)
- ;; ==> build and return the whole markup expression(s)
- ;; found in (car expr)
- (receive (markup-expr rest-expr) (compile-markup-expression (car expr))
- (if (null? rest-expr)
- (values markup-expr (cdr expr))
- (values `(list ,markup-expr ,@(compile-all-markup-args rest-expr))
- (cdr expr)))))
- ((and (pair? (car expr))
- (pair? (caar expr)))
- ;; expr === (((foo ...) ...) ...)
- (values (cons 'list (compile-all-markup-args (car expr))) (cdr expr)))
- (else (values (car expr) (cdr expr)))))
-
-;;;;;;;;;;;;;;;
-;;; Utilities for storing and accessing markup commands signature
-;;; Examples:
-;;;
-;;; (set! (markup-command-signature raise-markup) (list number? markup?))
-;;; ==> (#<primitive-procedure number?> #<procedure markup? (obj)>)
-;;;
-;;; (markup-command-signature raise-markup)
-;;; ==> (#<primitive-procedure number?> #<procedure markup? (obj)>)
-;;;
-
-(define-public (markup-command-signature-ref markup-command)
- "Return @var{markup-command}'s signature (the @code{'markup-signature}
-object property)."
- (object-property markup-command 'markup-signature))
-
-(define-public (markup-command-signature-set! markup-command signature)
- "Set @var{markup-command}'s signature (as object property)."
- (set-object-property! markup-command 'markup-signature signature)
- signature)
-
-(define-public markup-command-signature
- (make-procedure-with-setter markup-command-signature-ref
- markup-command-signature-set!))
-
-(define (lookup-markup-command-aux symbol)
- (let ((proc (catch 'misc-error
- (lambda ()
- (module-ref (current-module) symbol))
- (lambda (key . args) #f))))
- (and (procedure? proc) proc)))
-
-(define-public (lookup-markup-command code)
- (let ((proc (lookup-markup-command-aux
- (string->symbol (format #f "~a-markup" code)))))
- (and proc (markup-function? proc)
- (cons proc (markup-command-signature proc)))))
-
-(define-public (lookup-markup-list-command code)
- (let ((proc (lookup-markup-command-aux
- (string->symbol (format #f "~a-markup-list" code)))))
- (and proc (markup-list-function? proc)
- (cons proc (markup-command-signature proc)))))
-
-;;;;;;;;;;;;;;;;;;;;;;
-;;; used in parser.yy to map a list of markup commands on markup arguments
-(define-public (map-markup-command-list commands markups)
- "@var{markups} being a list of markups, for example
-@code{(markup1 markup2 markup3)}, and @var{commands} a list of commands with
-their scheme arguments, in reverse order, for example
-@code{((italic) (raise 4) (bold))}, map the commands on each markup argument,
-for example
-@example
-((bold (raise 4 (italic markup1)))
- (bold (raise 4 (italic markup2)))
- (bold (raise 4 (italic markup3))))
-@end example"
- (map-in-order (lambda (arg)
- (let ((result arg))
- (for-each (lambda (cmd)
- (set! result (append cmd (list result))))
- commands)
- result))
- markups))
-
-;;;;;;;;;;;;;;;;;;;;;;
-;;; markup type predicates
-
-(define (markup-function? x)
- (and (markup-command-signature x)
- (not (object-property x 'markup-list-command))))
-
-(define (markup-list-function? x)
- (and (markup-command-signature x)
- (object-property x 'markup-list-command)))
-
-(define-public (markup-command-list? x)
- "Determine whether @var{x} is a markup command list, i.e. a list
-composed of a markup list function and its arguments."
- (and (pair? x) (markup-list-function? (car x))))
-
-(define-public (markup-list? arg)
- "Return @code{#t} if @var{x} is a list of markups or markup command lists."
- (define (markup-list-inner? lst)
- (or (null? lst)
- (and (or (markup? (car lst)) (markup-command-list? (car lst)))
- (markup-list-inner? (cdr lst)))))
- (not (not (and (list? arg) (markup-list-inner? arg)))))
-
-(define (markup-argument-list? signature arguments)
- "Typecheck argument list."
- (if (and (pair? signature) (pair? arguments))
- (and ((car signature) (car arguments))
- (markup-argument-list? (cdr signature) (cdr arguments)))
- (and (null? signature) (null? arguments))))
-
-
-(define (markup-argument-list-error signature arguments number)
- "return (ARG-NR TYPE-EXPECTED ARG-FOUND) if an error is detected, or
-#f is no error found.
-"
- (if (and (pair? signature) (pair? arguments))
- (if (not ((car signature) (car arguments)))
- (list number (type-name (car signature)) (car arguments))
- (markup-argument-list-error (cdr signature) (cdr arguments) (+ 1 number)))
- #f))
-
-;;
-;; full recursive typecheck.
-;;
-(define (markup-typecheck? arg)
- (or (string? arg)
- (and (pair? arg)
- (markup-function? (car arg))
- (markup-argument-list? (markup-command-signature (car arg))
- (cdr arg)))))
-
-;;
-;;
-;;
-;;
-(define (markup-thrower-typecheck arg)
- "typecheck, and throw an error when something amiss.
-
-Uncovered - cheap-markup? is used."
-
- (cond ((string? arg) #t)
- ((not (pair? arg))
- (throw 'markup-format "Not a pair" arg))
- ((not (markup-function? (car arg)))
- (throw 'markup-format "Not a markup function " (car arg)))
- ((not (markup-argument-list? (markup-command-signature (car arg))
- (cdr arg)))
- (throw 'markup-format "Arguments failed typecheck for " arg)))
- #t)
-
-;;
-;; good enough if you only use make-XXX-markup functions.
-;;
-(define (cheap-markup? x)
- (or (string? x)
- (and (pair? x)
- (markup-function? (car x)))))
-
-;;
-;; replace by markup-thrower-typecheck for more detailed diagnostics.
-;;
-(define-public markup? cheap-markup?)
-
;; utility
(define (markup-join markups sep)
(define-public (interpret-markup-list layout props markup-list)
(let ((stencils (list)))
(for-each (lambda (m)
- (set! stencils
- (if (markup-command-list? m)
- (append! (reverse! (apply (car m) layout props (cdr m)))
- stencils)
- (cons (interpret-markup layout props m) stencils))))
- markup-list)
+ (set! stencils
+ (if (markup-command-list? m)
+ (append! (reverse! (apply (car m) layout props (cdr m)))
+ stencils)
+ (cons (interpret-markup layout props m) stencils))))
+ markup-list)
(reverse! stencils)))
(define-public (prepend-alist-chain key val chain)
(define-public (stack-stencil-line space stencils)
"DOCME"
(if (and (pair? stencils)
- (ly:stencil? (car stencils)))
+ (ly:stencil? (car stencils)))
(if (and (pair? (cdr stencils))
- (ly:stencil? (cadr stencils)))
+ (ly:stencil? (cadr stencils)))
(let* ((tail (stack-stencil-line space (cdr stencils)))
(head (car stencils))
(xoff (+ space (interval-length (ly:stencil-extent head X)))))
(ly:stencil-add head
- (ly:stencil-translate-axis tail xoff X)))
+ (ly:stencil-translate-axis tail xoff X)))
(car stencils))
(ly:make-stencil '() '(0 . 0) '(0 . 0))))
(define-public (markup->string m)
;; markup commands with one markup argument, formatting ignored
(define markups-first-argument '(list
- bold-markup box-markup caps-markup dynamic-markup finger-markup
- fontCaps-markup huge-markup italic-markup large-markup larger-markup
- medium-markup normal-size-sub-markup normal-size-super-markup
- normal-text-markup normalsize-markup number-markup roman-markup
- sans-markup simple-markup small-markup smallCaps-markup smaller-markup
- sub-markup super-markup teeny-markup text-markup tiny-markup
- typewriter-markup underline-markup upright-markup bracket-markup
- circle-markup hbracket-markup parenthesize-markup rounded-box-markup
-
- center-align-markup center-column-markup column-markup dir-column-markup
- fill-line-markup justify-markup justify-string-markup left-align-markup
- left-column-markup line-markup right-align-markup right-column-markup
- vcenter-markup wordwrap-markup wordwrap-string-markup ))
+ bold-markup box-markup caps-markup dynamic-markup finger-markup
+ fontCaps-markup huge-markup italic-markup large-markup larger-markup
+ medium-markup normal-size-sub-markup normal-size-super-markup
+ normal-text-markup normalsize-markup number-markup roman-markup
+ sans-markup simple-markup small-markup smallCaps-markup smaller-markup
+ sub-markup super-markup teeny-markup text-markup tiny-markup
+ typewriter-markup underline-markup upright-markup bracket-markup
+ circle-markup hbracket-markup parenthesize-markup rounded-box-markup
+
+ center-align-markup center-column-markup column-markup dir-column-markup
+ fill-line-markup justify-markup justify-string-markup left-align-markup
+ left-column-markup line-markup right-align-markup right-column-markup
+ vcenter-markup wordwrap-markup wordwrap-string-markup ))
;; markup commands with markup as second argument, first argument
;; specifies some formatting and is ignored
(define markups-second-argument '(list
- abs-fontsize-markup fontsize-markup magnify-markup lower-markup
- pad-around-markup pad-markup-markup pad-x-markup raise-markup
- halign-markup hcenter-in-markup rotate-markup translate-markup
- translate-scaled-markup with-url-markup scale-markup ))
+ abs-fontsize-markup fontsize-markup magnify-markup lower-markup
+ pad-around-markup pad-markup-markup pad-x-markup raise-markup
+ halign-markup hcenter-in-markup rotate-markup translate-markup
+ translate-scaled-markup with-url-markup scale-markup ))
;; helper functions to handle string cons like string lists
(define (markup-cons->string-cons c)
(if (not (pair? c)) (markup->string c)
- (cons (markup->string (car c)) (markup-cons->string-cons (cdr c)))))
+ (cons (markup->string (car c)) (markup-cons->string-cons (cdr c)))))
(define (string-cons-join c)
(if (not (pair? c)) c
(string-join (list (car c) (string-cons-join (cdr c))) "")))
(cond
- ((string? m) m)
- ((null? m) "")
+ ((string? m) m)
+ ((null? m) "")
- ;; handle \concat (string-join without spaces)
- ((and (pair? m) (equal? (car m) concat-markup))
- (string-cons-join (markup-cons->string-cons (cadr m))) )
+ ;; handle \concat (string-join without spaces)
+ ((and (pair? m) (equal? (car m) concat-markup))
+ (string-cons-join (markup-cons->string-cons (cadr m))) )
- ;; markup functions with the markup as first arg
- ((member (car m) (primitive-eval markups-first-argument))
- (markup->string (cadr m)))
+ ;; markup functions with the markup as first arg
+ ((member (car m) (primitive-eval markups-first-argument))
+ (markup->string (cadr m)))
- ;; markup functions with markup as second arg
- ((member (car m) (primitive-eval markups-second-argument))
- (markup->string (cddr m)))
+ ;; markup functions with markup as second arg
+ ((member (car m) (primitive-eval markups-second-argument))
+ (markup->string (cddr m)))
- ;; ignore all other markup functions
- ((markup-function? (car m)) "")
+ ;; ignore all other markup functions
+ ((markup-function? (car m)) "")
- ;; handle markup lists
- ((list? m)
- (string-join (map markup->string m) " "))
+ ;; handle markup lists
+ ((list? m)
+ (string-join (map markup->string m) " "))
- (else "ERROR, unable to extract string from markup")))
+ (else "ERROR, unable to extract string from markup")))
@var{laziness} states over how many bars an accidental should be remembered.
@code{0}@tie{}is the default -- accidental lasts over 0@tie{}bar lines, that
is, to the end of current measure. A positive integer means that the
-accidental lasts over that many bar lines. @code{-1} is `forget
+accidental lasts over that many bar lines. @w{@code{-1}} is `forget
immediately', that is, only look at key signature. @code{#t} is `forever'."
(check-pitch-against-signature context pitch barnum laziness octaveness))
(my-system
be-verbose #t
(format #f
- "pngtopnm ~a | pnmscale -reduce ~a 2>/dev/null | pnmtopng -compression 9 2>/dev/null > ~a"
+ "pngtopnm \"~a\" | pnmscale -reduce ~a 2>/dev/null | pnmtopng -compression 9 2>/dev/null > \"~a\""
old factor file))
(delete-file old)))
. (
(script-stencil . (feta . ("uportato" . "dportato")))
(avoid-slur . around)
- (slur-padding . 0.3)
(padding . 0.45)
(side-relative-direction . ,DOWN)))
("prall"
(avoid-slur . around)
(padding . 0.50)
(direction . ,UP)
- (slur-padding . 0.2)
(staff-padding . 0.5)))
("trill"
. (
orig_ln = ln
+ ln = junk_space (ln, state)
ln = try_parse_header_line (ln, state)
# Try nibbling characters off until the line doesn't change.
texi_file_re = re.compile ('.*\.i?te(ly|xi)$')
html_file_re = re.compile ('.*\.i?htm(l)?$')
-xml_file_re = re.compile ('.*\.i?xml$')
+xml_file_re = re.compile ('.*\.i?(xm|mx)l$')
tex_file_re = re.compile ('.*\.i?(la)?tex$')
pdf_file_re = re.compile ('.*\.i?pdf$')
# We have a texi include file, simply include it:
s = r"@include %s" % os.path.basename (n)
elif (html_file_re.match (n) or pdf_file_re.match (n) or
- xml_file_re.match (n) or tex_file_re.match (n)):
+ tex_file_re.match (n)):
s = r"""
@ifhtml
@html
@end html
@end ifhtml
""" % (os.path.basename (n), os.path.basename (n))
- return s
+
+ elif (xml_file_re.match (n)):
+ # Assume it's a MusicXML file -> convert, create image etc.
+ s = r"""
+@ifhtml
+@html
+<a name="%s"></a>
+@end html
+@end ifhtml
+
+@musicxmlfile[%s]{%s}
+""" % (os.path.basename (n), fragment_options, n)
+
else:
# Assume it's a lilypond file -> create image etc.
s = r"""
self.geometric_distance ())
def scheme_float (s) :
- return float(s) if 'nan' not in s else float(s.split('.')[0])
+ if 'nan' not in s :
+ return float(s)
+ return float(s.split('.')[0])
def read_signature_file (name):
print 'reading', name
s = tag
s += r'''
-\version "2.13.53"
+\version "2.14.0"
'''
s += r'''
\normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
% Flag to tell @lisp, etc., not to narrow margin.
\let\nonarrowing = t%
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \fi
+ %
\vbox\bgroup
\baselineskip=0pt\parskip=0pt\lineskip=0pt
\carttop