@end ignore
+@item
+There is a new @code{define-scheme-function} command in analogy to
+@code{define-music-function} which can be used to define functions
+evaluating to Scheme expressions while accepting arguments in Lilypond
+syntax.
+
@item
The construct @code{#@{ @dots{} #@}} can now be used not just for
constructing sequential music lists, but also for single music events,
(prep: 2 hours. discuss: 10 hours)
-@item @strong{Future release policy}:
-(how) should we change any policies pertaining to releases? Should
-an undocumented new feature count as release-blocking?
-
-(prep: 1 hour. discuss: 15 hours)
-
-@item @strong{lilypond-hackers mailing list}:
-Should we have a private mailing list for senior developers? If
-so, who should be on it?
-
-(prep: 2 hours+3 weeks. discuss: 10 hours)
-
-@item @strong{Hackers B}:
-
-
-@item @strong{Git repository(s)}:
-We currently have a web/ branch in our main repo; this seems
-misleading to new developers. More generally, should we have
-branches that aren't related to the master? i.e. should we
-restrict a git branch to code which is an actual "branch" of
-development? Also, some of our code (notably the windows and osx
-lilypad) isn't in a git repository at all.
-We can add new repositories very easily; should make repositories
-like
-@example
-git://git.sv.gnu.org/lilypond/gub.git
-git://git.sv.gnu.org/lilypond/lilypad.git
-git://git.sv.gnu.org/lilypond/misc.git
-@end example
-? More information here:
-@uref{http://code.google.com/p/lilypond/issues/detail?id=980}
-
-(prep: 2 hours. discuss: 10 hours)
-
-@item @strong{Roadmap of future development}:
-Many projects have a roadmap of planned (or desired) future work.
-Should we use one? If so, what should go on it, bearing in mind
-our volunteer status? Is there any way of having a roadmap that
-isn't vaporware?
-
-(prep: 1 hour. discuss: 5 hours)
-
@item @strong{Official links to other organizations?}:
There's something called the "software freedom conservancy", and
in general, there's a bunch of "umbrella organizations". Joining
(prep: 2 hours. discuss: 5 hours)
-@item @strong{Mailing lists}:
-We currently have a mix of official GNU mailing lists and lilynet
-lists. Is there a strong rationale for having separate mailing
-list servers? Why not pick one place, and put all our lists there?
-(or at least, all "permanent" lists?)
-
-(prep: 1 hour. discuss: 5 hours)
-
@item @strong{Issue tracking with google code}:
We use the google issue tracker, but this means that we are
relying on a commercial entity for a large part of our
(prep: 5 hours. discuss: 15 hours)
-@item @strong{Subdomains of *.lilypond.org}:
-Unless Jan has a really weird DNS hosting setup, there are no
-technical barriers to having names like lsr.lilypond.org,
-frog.lilypond.org, or news.lilypond.org. Is this something that we
-want to do?
-
-(prep: 1 hours+2 weeks. discuss: 5 hours)
-
-@item @strong{Authorship in source files}:
-Our documentation currently does not attempt to track individual
-authors of each file, while our source code makes a confused and
-jumbled attempt to track this. A number of guidelines for F/OSS
-projects explicitly recommends _not_ tracking this in individual
-files, since the code repository will track that for you.
-
-(prep: 2 hours. discuss: 15 hours)
-
@item @strong{Clarity for sponsorships}:
We currently do not advertize bounties and sponsorships on the
webpage. How much advertising do we want, and what type?
(prep: 2 hours. discuss: 10 hours)
-@item @strong{Separate branches for active development}:
-it might be good to have @emph{everybody} working on separate
-branches. This complicates the git setup, but with sufficient
-logic in lily-git.tcl, we can probably make it transparent to
-newbies. However, we'd need a reliable person to handle all the
-required merging and stuff.
-
-(prep: 2 hours. discuss: 10 hours)
-
-@item @strong{When do we add regtests?}:
-There is a discrepancy between our stated policy on adding
-regtests, and our actual practice in handling bugs and patches.
-Clarify.
-
-There is also a wider question how to organize the regtests, such
-as where to put interesting-console-output regtests, including
-stuff like lilypond-book and midi2ly in a sensible manner, and
-possibly including regtests for currently-broken functionality.
-
-(prep: 2 hours. discuss: 5 hours)
-
@item @strong{code readability}:
"Our aim when producing source code for Lilypond in whatever
language is that it should be totally comprehensible to a
* Adding a new font section::
* Adding a new glyph::
* Building the changed font::
+* METAFONT formatting rules::
@end menu
@node Overview of the feta font
rm mf/out/*
make
@end example
+
+@node METAFONT formatting rules
+@section METAFONT formatting rules
+
+There are special formatting rules for METAFONT files.
+
+Tabs are used for indentation.
+
+When a path contains more than two points, put each point on a
+separate line, with the operator at the beginning of the line:
+
+@example
+fill z1
+ -- z2
+ -- z3
+ .. cycle;
+@end example
+
@}
@end example
+Acknowledge functions are called in the order engravers are
+@code{\consist}-ed (the only exception is if you set
+@code{must-be-last} to @code{#t}).
+
+If useful things are to be done to the acknowledged grobs, this
+should be deferred until all the acknowledging has finished, i.e.,
+store the acknowledged grobs and process the information in a
+@code{process-acknowledged ()} or @code{stop-translation-timestep ()}
+function.
+
@node Engraver declaration/documentation
@subsection Engraver declaration/documentation
Install @command{git-cl} by entering:
@example
-git clone git://neugierig.org/git-cl.git
+git clone https://github.com/martine/git-cl
@end example
@item
diff -u $DEST/mass-link.py $GIT/scripts/build/mass-link.py
diff -u $DEST/website_post.py $GIT/scripts/build/website_post.py
diff -u $DEST/bib2texi.py $GIT/scripts/build/bib2texi.py
+diff -u $DEST/langdefs.py $GIT/python/langdefs.py
diff -u $DEST/lilypond.org.htaccess $GIT/Documentation/web/server/lilypond.org.htaccess
diff -u $DEST/website-dir.htaccess $GIT/Documentation/web/server/website-dir.htaccess
@end verbatim
cp $GIT/scripts/build/mass-link.py $DEST/mass-link.py
cp $GIT/scripts/build/website_post.py $DEST/website_post.py
cp $GIT/scripts/build/bib2texi.py $DEST/bib2texi.py
+cp $GIT/python/langdefs.py $DEST/langdefs.py
cp $GIT/Documentation/web/server/lilypond.org.htaccess $DEST/lilypond.org.htaccess
cp $GIT/Documentation/web/server/website-dir.htaccess $DEST/website-dir.htaccess
@end verbatim
make website
@end example
+This will make all the language variants of the website. To save
+a little time, just the English version can be made with the
+command @code{make WEB_LANGS='' website} or the English and (for
+example) the French with @code{make WEB_LANGS='fr' website}.
@item
Move the built stuff into those directories. It's highly
@item
Translations are not included by default in @code{make website}.
-To test your translation, edit the @code{WEB_LANGS} line in
-@file{make/website.make}. Do not submit a patch to add your language
-to this file unless @code{make website} completes with less than 5
-warnings.
+To test your translation, edit the @code{WEB_LANGUAGES =} line in
+@file{python/langdefs.py}. You will need to copy this updated
+script to @code{build/python/out}.
+
+Do not submit a patch to add your language to this file unless
+@code{make website} completes with fewer than 5 warnings.
@item
Links to manuals are done with macros like
@cindex compound time signatures
@cindex time signature, compound
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{time-signature-printing-only-the-numerator-as-a-number-instead-of-the-fraction.ly}
>>
@end lilypond
-@snippets
-
-@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
-{compound-time-signatures.ly}
-
-
@seealso
Glossar:
@rglos{polymetric},
@snippets
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{arabic-improvisation.ly}
@cindex compuesto, indicaciones de compás
@cindex compás compuesto, indicaciones de
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{time-signature-printing-only-the-numerator-as-a-number-instead-of-the-fraction.ly}
>>
@end lilypond
-@snippets
-
-@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
-{compound-time-signatures.ly}
-
-
@seealso
Glosario musical:
@rglos{polymetric},
@snippets
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{arabic-improvisation.ly}
@ref{Scheme tutorial}.
@menu
+* Lilypond code blocks::
+* Scheme functions::
* Music functions::
* Markup functions::
* Contexts for programmers::
* Difficult tweaks::
@end menu
+@node Lilypond code blocks
+@section Lilypond code blocks
-@node Music functions
-@section Music functions
+Lilypond code blocks look like
+@example
+ #@{ @var{Lilypond code} #@}
+@end example
+They can be used anywhere where you can write scheme code: the scheme
+reader actually is changed for accommodating Lilypond code blocks. When
+the Lilypond code block is being read, it is parsed superficially and
+replaced by a call to the Lilypond parser which is executed at runtime
+to interpret the Lilypond code block.
-@emph{Music functions} are scheme procedures that can create music
-expressions automatically, and can be used to greatly simplify the
-input file.
+The point of the superficial parsing is the interpretation of @code{$}
+signs which can be used for splicing in expressions from the surrounding
+lexical scheme context (like @code{let} variables and function
+parameters). @code{$} can be used in the following ways:
+
+@table @code
+@item $$
+just passes a single @code{$} to the Lilypond parser.
+@item $@var{form}
+will evaluate the Scheme form at runtime and splice its value as an
+identifier @code{\form} into the Lilypond parser. Depending on the
+value type, it may be interpreted as several different syntactic
+entities.
+@item #$@var{form}
+will evaluate the Scheme form at runtime and splice its value as a
+Scheme expression into the Lilypond parser.
+@item #@var{form}
+Forms in Scheme expressions started with @code{#} are read and parsed
+recursively for @code{$} signs. Those are treated as follows:
+@item #@dots{}$@var{variable}
+splices the value of the variable into the surrounding expression.
+@item #@dots{}($ @var{form} @dots{})
+splices the value of the form into the surrounding expression. As
+opposed to a Lilypond level @code{$@var{form}}, you need to separate the
+form with a blank, making @code{$} be recognizable as a separate Scheme
+symbol.
+@end table
+
+A LilyPond code block may contain anything that you can use on the right
+side of an assignment. In addition, an empty LilyPond block corresponds
+to a void music expression, and a LilyPond block containing multiple
+music events gets turned into a sequential music expression.
+
+@node Scheme functions
+@section Scheme functions
+
+@emph{Scheme functions} are scheme procedures that can create scheme
+expressions from input written in Lilypond syntax. They can be called
+in pretty much all places where using @code{#} for specifying a value in
+Scheme syntax is allowed. While scheme has functions of its own, this
+chapter is concerned with @emph{syntactic} functions, functions that
+receive arguments specified in Lilypond syntax.
@menu
-* Music function definitions::
-* Music function usage::
-* Simple substitution functions::
-* Intermediate substitution functions::
-* Mathematics in functions::
-* Functions without arguments::
-* Void functions::
+* Scheme function definitions::
+* Scheme function usage::
+* Void scheme functions::
@end menu
+@node Scheme function definitions
+@subsection Scheme function definitions
-@node Music function definitions
-@subsection Music function definitions
-
-The general form for defining music functions is:
+The general form for defining scheme functions is:
@example
function =
-#(define-music-function
+#(define-scheme-function
(parser location @var{arg1} @var{arg2} @dots{})
(@var{type1?} @var{type2?} @dots{})
- @var{music})
+ @var{body})
@end example
@noindent
must return @code{#t}. Some of these predicates are specially
recognized by the parser, see below.
-@item @code{@var{music}}
-@tab A music expression, optionally written in scheme, with any
-LilyPond code enclosed in hashed braces
-(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}). Within LilyPond code
-blocks, use @code{$} to reference function arguments (eg.,
-@samp{$arg1}) or to start an inline scheme expression containing
-function arguments (eg., @w{@samp{$(cons arg1 arg2)}}). A LilyPond code
-block may contain anything that you can use on the right side of an
-assignment. In addition, an empty LilyPond block corresponds to a void
-music expression, and a LilyPond block containing multiple music events
-gets turned into a sequential music expression.
-
+@item @code{@var{body}}
+@tab A sequence of scheme forms evaluated in order, the last one being
+used as the return value of the scheme function. It may contain
+LilyPond code blocks enclosed in hashed braces
+(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), like described in @ref{Lilypond
+code blocks}. Within LilyPond code blocks, use @code{$} to reference
+function arguments (eg., @samp{$arg1}) or to start an inline scheme
+expression containing function arguments (eg., @w{@samp{$(cons arg1
+arg2)}}).
@end multitable
@noindent
rather than in Scheme syntax. Currently these are @code{ly:music?},
@code{markup?}, @code{ly:pitch?}, and @code{ly:duration?}.
-If you really want to input one of those items as a Scheme rather than a
-Lilypond expression, you may write them as a Scheme expression that
-calls @code{ly:export} at its outermost level.
+If you really want to input one of the special items as a Scheme rather
+than a Lilypond expression, you may write them as a Scheme expression
+that calls @code{ly:export} at its outermost level.
Other type predicates, including user-defined ones, will make the
-respective argument only be accepted as a Scheme expression.
+respective argument only be accepted as a Scheme expression, usually
+introduced with @code{#} or as the result of calling a scheme function
+itself.
+
+For a list of available type predicates, see
+@ruser{Predefined type predicates}.
+
+@seealso
+
+Notation Reference:
+@ruser{Predefined type predicates}.
+
+Installed Files:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
+
+@node Scheme function usage
+@subsection Scheme function usage
+Scheme functions can be called pretty much anywhere where a Scheme
+expression starting with @code{#} can be written. You call a scheme
+function by writing its name preceded by @code{\}, followed by its
+arguments.
+
+Apart from places where a Scheme value is required, there are a few
+places where @code{#} expressions are accepted and evaluated for their
+side effects but otherwise ignored. Mostly those are the places where
+an assignment would be acceptable as well.
+
+There are a few special places where an argument matching
+@code{ly:music?} has to be either a music identifier or a music
+expression enclosed in @code{@{}@dots{}@code{@}} or
+@code{<<}@dots{}@code{>>} explicitly, so that possibly following
+optional durations or postevents can't be confused with additional
+arguments. One obvious place is before a @code{ly:duration?}
+predicate. Another is as the last argument of a scheme function when it
+is used in a place where such optional parts could be considered either
+part of the music argument or not.
+
+In those rare cases, you have to delimit your music arguments
+appropriately to spare Lilypond from getting confused.
+
+@node Void scheme functions
+@subsection Void scheme functions
+
+Sometimes a function is only executed for its side effects. In that
+case, using a Scheme function means that its value will not usually be
+considered:
+
+@example
+noPointAndClick =
+#(define-scheme-function
+ (parser location)
+ ()
+ (ly:set-option 'point-and-click #f))
+...
+\noPointAndClick % disable point and click
+@end example
+
+@node Music functions
+@section Music functions
+
+@emph{Music functions} are scheme procedures that can create music
+expressions automatically, and can be used to greatly simplify the
+input file.
+
+@menu
+* Music function definitions::
+* Music function usage::
+* Simple substitution functions::
+* Intermediate substitution functions::
+* Mathematics in functions::
+* Functions without arguments::
+* Void music functions::
+@end menu
+
+
+@node Music function definitions
+@subsection Music function definitions
+
+The general form for defining music functions is:
+
+@example
+function =
+#(define-music-function
+ (parser location @var{arg1} @var{arg2} @dots{})
+ (@var{type1?} @var{type2?} @dots{})
+ @var{body})
+@end example
+
+@noindent
+quite in analogy to @ref{Scheme function definitions}. More often than
+not, @var{body} will be a @ref{Lilypond code blocks, Lilypond code block}.
For a list of available type predicates, see
@ruser{Predefined type predicates}.
@end example
-@node Void functions
-@subsection Void functions
-
-A music function must return a music expression, but sometimes we
-may want to have a function that does not involve music (such as
-turning off Point and Click). To do this, we return a @code{void}
-music expression.
-
-Using the form @code{#@{ #@}} will actually achieve that. If you for
-some reason really need an empty sequential music expression, you would
-have to write @code{#@{ @{ @} #@}} instead.
+@node Void music functions
+@subsection Void music functions
-@example
-noPointAndClick =
-#(define-music-function
- (parser location)
- ()
- (ly:set-option 'point-and-click #f)
- #@{ #@})
-...
-\noPointAndClick % disable point and click
-@end example
+A music function must return a music expression. If you want to execute
+a function only for its side effect, it might make more sense to use a
+scheme function instead. But there may be cases where you sometimes
+want to produce a music expression, and sometimes not (like in the
+previous example). Returning a @code{void} music expression via
+@code{#@{ #@}} will do that.
@node Markup functions
Scheme code is evaluated as soon as the parser encounters it. To
define some Scheme code in a macro (to be called later), use
-@ref{Void functions}, or
+@ref{Void scheme functions}, or
@example
#(define (nopc)
@lilypondfile[verbatim,quote,texidoc,doctitle]
{polyphony-in-tablature.ly}
-@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
+@lilypondfile[verbatim,quote,texidoc,doctitle]
{open-string-harmonics-in-tablature.ly}
-@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
+@lilypondfile[verbatim,quote,texidoc,doctitle]
{fretted-string-harmonics-in-tablature.ly}
-@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
+@lilypondfile[verbatim,quote,texidoc,doctitle]
{slides-in-tablature.ly}
-@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
+@lilypondfile[verbatim,quote,texidoc,doctitle]
{chord-glissando-in-tablature.ly}
@lilypondfile[verbatim,quote,texidoc,doctitle]
{defining-predefined-fretboards-for-other-instruments.ly}
-@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
+@lilypondfile[verbatim,quote,texidoc,doctitle]
{chordchanges-for-fretboards.ly}
-@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
+@lilypondfile[verbatim,quote,texidoc,doctitle]
{fretboards-alternate-tables.ly}
@cindex métriques composites
@cindex métriques décomposées
-@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{time-signature-printing-only-the-numerator-as-a-number-instead-of-the-fraction.ly}
>>
@end lilypond
-@snippets
-
-@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
-{compound-time-signatures.ly}
-
-
@seealso
Glossaire musicologique :
@rglosnamed{polymetric,polymétrie},
@snippets
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{arabic-improvisation.ly}
@c use commas not colons
-Karin Hoethker
+Karin Hoethker,
+Julien Rioux
@c no comma for last entry
in those places; the only complete set of documentation is in
@file{out-www/offline-root/} from the top of the source tree.
+@code{make doc} compiles the documents for all languages. To save
+some compile time, the English language documents can be compiled
+on their own with:
+
+@example
+make LANGS='' doc
+@end example
+
Compilation of documentation in Info format with images can be
done separately by issuing:
@cindex compound time signatures
@cindex time signature, compound
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{time-signature-printing-only-the-numerator-as-a-number-instead-of-the-fraction.ly}
>>
@end lilypond
-@snippets
-
-@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
-{compound-time-signatures.ly}
-
-
@seealso
音楽用語集:
@rglos{polymetric},
@ref{compound meter}.
@item
-A time signature that additively combines two or more unequal meters, e.g.,
-@q{3/8 + 2/8} instead of @q{5/8}. Sometimes called additive time signatures.
+A time signature that additively combines two or more unequal meters,
+e.g., @q{3/8 + 2/8} instead of @q{5/8}. Sometimes called additive time
+signatures.
@end enumerate
-@lilypond[quote,line-width=13.0\cm]
-#(define ((compound-time one two three num) grob)
- (grob-interpret-markup grob
- (markup
- #:override '(baseline-skip . 0)
- #:number
- #:line (
- #:left-column (one num)
- #:vcenter "+"
- #:left-column (two num)
- #:vcenter "+"
- #:left-column (three num)))))
-
+@lilypond[quote,verbatim]
\relative c' {
\key f \major
- #(set-time-signature 8 8 '(3 2 3))
- \override Staff.TimeSignature #'stencil =
- #(compound-time "3" "2" "3" "8")
+ \compoundMeter #'((3 8) (2 8) (3 8))
c8 d e f4 d8 c bes
c4 g'8 e c f4.
\bar "||"
@end lilypond
@seealso
-@ref{compound meter}, @ref{meter}, @ref{polymetric time signature}.
+@ref{compound meter},
+@ref{meter},
+@ref{polymetric time signature}.
@node concert pitch
\new Staff \relative c' {
c1 d e f g a b c
}
- \lyrics {
- << { I II III IV V VI VII I }
- { T "" "" S D } >>
-}
+ \lyrics { I II III IV V VI VII I }
+ \lyrics { T "" "" S D }
>>
@end lilypond
}
@end lilypond
-@cindex Transposing guitar chords for capo
-
-If the @code{capoPitch} property is set, then the chords will additionally be printed
-transposed for a guitar with the capo set appropriately. By default the chords are
-printed on one line, but if the @code{capoVertical} property is set, the chords will be
-printed one above the other.
-
-In make-pitch, leave the first argument at 0, the second argument is the
-interval (-2 is a third), and the third argument adjusts it up or down a
-semitone.
-
-@lilypond[verbatim,quote,ragged-right]
-<<
- \new ChordNames \chordmode {
- c1
- r1
- g1
- c1
- \break
- c1
- r1
- g1
- c1
- \break
- c1
- r1
- g1
- c1
- }
- \chordmode {
- c1
- r1
- g1
- c1
- \break
- \set ChordNames.capoPitch = #(ly:make-pitch 0 -2 -1/2)
- c1
- r1
- g1
- c1
- \break
- \set ChordNames.capoVertical = ##t
- c1
- r1
- g1
- c1
- }
->>
-@end lilypond
-
@snippets
@c Keep index entries with following snippet
@lilypond[quote,ragged-right,verbatim]
\drums {
- \clef treble
- hh4 hh hh hh
- \break
\clef percussion
bd4 bd bd bd
+ \clef treble
+ hh4 hh hh hh
}
@end lilypond
eighth notes are shown with two slashes (the beam being the
third), and drum rolls shorter than eighths have one stem slash to
supplement the beams. This is achieved with the tremolo notation,
-@code{:32}, as described in @ref{Tremolo repeats}. Here is an
-example of some snare rolls:
+as described in @ref{Tremolo repeats}.
@lilypond[quote,verbatim]
\drums {
}
@end lilypond
-Sticking can be indicated by placing @code{^"R"} or @code{^"L"}
-after the note. The @code{staff-padding} property may be
-overridden to achieve a pleasing baseline.
+Sticking can be indicated by placing placing markup for @code{"R"}
+or @code{"L"} above or below notes, as discussed in
+@ref{Direction and placement}. The @code{staff-padding} property
+may be overridden to achieve a pleasing baseline.
@lilypond[quote,verbatim]
\drums {
\repeat unfold 2 {
- sn16 ^"L" sn^"R" sn^"L" sn^"L" sn^"R" sn^"L" sn^"R" sn^"R"
+ sn16^"L" sn^"R" sn^"L" sn^"L" sn^"R" sn^"L" sn^"R" sn^"R"
+ \stemUp
+ sn16_"L" sn_"R" sn_"L" sn_"L" sn_"R" sn_"L" sn_"R" sn_"R"
}
}
@end lilypond
@seealso
+
+Notation Reference:
+@ref{Tremolo repeats}.
+
Snippets:
@rlsr{Percussion}.
@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
{changing-the-time-signature-without-affecting-the-beaming.ly}
-@cindex compound time signatures
-@cindex time signature, compound
-
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{time-signature-printing-only-the-numerator-as-a-number-instead-of-the-fraction.ly}
@funindex \times
@funindex times
-Polymetric notation is supported, either explicitly or by modifying
-the visible time signature symbol and scaling the note durations.
+Polymetric notation is supported explicitly or by manually modifying the
+visible time signature symbol and/or scaling note durations.
-@strong{@i{Staves with different time signatures, equal measure lengths}}
+@subsubheading Different time signatures with equal-length measures
-This notation can be created by setting a common time signature
-for each staff but replacing the symbol manually by setting
-@code{timeSignatureFraction} to the desired fraction and scaling
-the printed durations in each staff to the common time
-signature; see @ref{Time signature}. The scaling is done with
-@code{\scaleDurations}, which is used in a similar way to
-@code{\times}, but does not create a tuplet bracket; see
-@ref{Scaling durations}.
+Set a common time signature for each staff, and set the
+@code{timeSignatureFraction} to the desired fraction. Then use the
+@code{\scaleDurations} function to scale the durations of the notes in
+each staff to the common time signature.
@cindex beams, with polymetric meters
@cindex polymetric meters, with beams
-In this example, music with the time signatures of 3/4, 9/8, and
-10/8 are used in parallel. In the second staff, shown durations
-are multiplied by 2/3, as 2/3 * 9/8 = 3/4, and in the third
-staff, shown durations are multiplied by 3/5, as 3/5 * 10/8 = 3/4.
-It will often be necessary to insert beams manually, as the
-duration scaling affects the autobeaming rules.
+In the following example, music with the time signatures of 3/4, 9/8 and
+10/8 are used in parallel. In the second staff, shown durations are
+multiplied by 2/3 (because 2/3 * 9/8 = 3/4) and in the third staff, the
+shown durations are multiplied by 3/5 (because 3/5 * 10/8 = 3/4). It
+may be necessary to insert beams manually, as the duration scaling will
+affect the autobeaming rules.
@lilypond[quote,verbatim]
\relative c' <<
\new Staff {
\time 3/4
c4 c c |
- c c c |
+ c4 c c |
}
\new Staff {
\time 3/4
\scaleDurations #'(3 . 5) {
\repeat unfold 2 { c8[ c c] }
\repeat unfold 2 { c8[ c] } |
- c4. c4. \times 2/3 { c8[ c c] } c4
+ c4. c \times 2/3 { c8[ c c] } c4
}
}
>>
@end lilypond
-@strong{@i{Staves with different time signatures, unequal bar lengths}}
+@subsubheading Different time signatures with unequal-length measures
Each staff can be given its own independent time signature by
moving the @code{Timing_translator} and the
>>
@end lilypond
-@snippets
+@funindex \compoundMeter
+@cindex compound time signatures
+@cindex time signature, compound
-@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
-{compound-time-signatures.ly}
+@subsubheading Compound time signatures
+
+These are created using the @code{\compoundMeter} function. The syntax
+for this is:
+
+@example
+\compoundMeter #'@code{(list of lists)}
+@end example
+
+The simplest construction is a single list, where the @emph{last} number
+indicates the bottom number of the time signature and those that come
+before it, the top numbers.
+@lilypond[quote,verbatim]
+\relative c' {
+ \compoundMeter #'((2 2 2 8))
+ \repeat unfold 6 c8 \repeat unfold 12 c16
+}
+@end lilypond
+
+More complex meters can be constructed using additional lists. Also,
+automatic beaming settings will be adjusted depending on the values.
+
+@lilypond[quote,verbatim]
+\relative c' {
+ \compoundMeter #'((1 4) (3 8))
+ \repeat unfold 5 c8 \repeat unfold 10 c16
+}
+
+\relative c' {
+ \compoundMeter #'((1 2 3 8) (3 4))
+ \repeat unfold 12 c8
+}
+@end lilypond
@seealso
Music Glossary:
@rglos{meter}.
Notation Reference:
+@ref{Automatic beams},
+@ref{Manual beams},
@ref{Time signature},
@ref{Scaling durations}.
@knownissues
-
-When using different time signatures in parallel, notes
-at the same moment will be placed at the same horizontal
-location. However, the bar lines in the different staves
-will cause the note spacing to be less regular in each of the
-individual staves than would be normal without the different
-time signatures.
+When using different time signatures in parallel, notes at the same
+moment will be placed at the same horizontal location. However, the bar
+lines in the different staves will cause the note spacing to be less
+regular in each of the individual staves than would be normal without
+the different time signatures.
@node Automatic note splitting
@unnumberedsubsubsec Automatic note splitting
@snippets
-@lilypondfile[verbatim,quote,texidoc,doctitle]
-{compound-time-signatures.ly}
-
@lilypondfile[verbatim,quote,texidoc,doctitle]
{arabic-improvisation.ly}
} % begin verbatim
-#(define ((compound-time one two num) grob)
- (grob-interpret-markup grob
- (markup #:override '(baseline-skip . 0) #:number
- (#:line ((#:column (one num))
- #:vcenter "+"
- (#:column (two num)))))))
-
-\relative c' {
- \override Staff.TimeSignature #'stencil = #(compound-time "2" "3" "8")
- \time 5/8
- \set Staff.beatStructure = #'(2 3)
- c8 d e fis gis
- c8 fis, gis e d
- c8 d e4 gis8
+\markup {
+ This snippet is deprecated as of 2.15.9 and will be removed in 2.16
}
doctitle = "Compound time signatures"
}
-#(define ((compound-time one two num) grob)
- (grob-interpret-markup grob
- (markup #:override '(baseline-skip . 0) #:number
- (#:line ((#:column (one num))
- #:vcenter "+"
- (#:column (two num)))))))
-
-\relative c' {
- \override Staff.TimeSignature #'stencil = #(compound-time "2" "3" "8")
- \time 5/8
- \set Staff.beatStructure = #'(2 3)
- c8 d e fis gis
- c8 fis, gis e d
- c8 d e4 gis8
+\markup {
+ This snippet is deprecated as of 2.15.9 and will be removed in 2.16
}
@c used for news about the upcoming release; see CG 10.2
@newsItem
-@subsubheading LilyPond 2.15.9 released! @emph{August 30, 2011}
+@subsubheading LilyPond 2.15.12 released! @emph{September 17, 2011}
-We are happy to announce the release of LilyPond 2.15.9. This
-release contains the usual number of bugfixes, and also adds
-support for MacOS X 10.7.
+We are happy to announce the release of LilyPond 2.15.12. This
+release contains the usual number of bugfixes.
It is strongly recommended that normal users do @strong{not} use
this release, and instead use the stable 2.14 version. Please
-note that due to a few outstanding Critical bugs, this is not the
-next release candidate.
+note that due to the possibility of a few Critical bugs, this is
+not the next release candidate.
@newsEnd
@newsItem
-@subsubheading Release candidate 1 of 2.16 - LilyPond 2.15.8 released! @emph{Aug 01, 2011}
+@subsubheading LilyPond 2.15.11 released! @emph{September 11, 2011}
-LilyPond 2.15.8 is out; this is the first release candidate of
-the upcoming 2.16 stable release. All users are invited to
-experiment with this version. New features since 2.14.2 are
-listed in the @qq{Changes} manual on the website section about
-@ref{Development}.
+We are happy to announce the release of LilyPond 2.15.11. This
+release contains the usual number of bugfixes.
-There are no known Critical issues with this release. If no
-Critical bugs are found, then the official 2.16.0 release will be
-on 08 Aug 2011. If you discover any problems, please send us
-@ref{Bug reports}.
+It is strongly recommended that normal users do @strong{not} use
+this release, and instead use the stable 2.14 version. Please
+note that due to the possibility of a few Critical bugs, this is
+not the next release candidate.
@newsEnd
@newsItem
-@subsubheading LilyPond 2.15.7 released! @emph{July 29, 2011}
+@subsubheading LilyPond 2.15.10 released! @emph{September 6, 2011}
-We are happy to announce the release of LilyPond 2.15.7. This
+We are happy to announce the release of LilyPond 2.15.10. This
release contains the usual number of bugfixes.
It is strongly recommended that normal users do @strong{not} use
-this release, and instead use the stable 2.14 version.
+this release, and instead use the stable 2.14 version. Please
+note that due to a few outstanding Critical bugs, this is not the
+next release candidate.
@newsEnd
@newsItem
-@subsubheading LilyPond 2.15.6 released! @emph{July 26, 2011}
+@subsubheading LilyPond 2.15.9 released! @emph{August 30, 2011}
-We are happy to announce the release of LilyPond 2.15.6. This
-release contains the usual number of bugfixes.
+We are happy to announce the release of LilyPond 2.15.9. This
+release contains the usual number of bugfixes, and also adds
+support for MacOS X 10.7.
It is strongly recommended that normal users do @strong{not} use
-this release, and instead use the stable 2.14 version.
+this release, and instead use the stable 2.14 version. Please
+note that due to a few outstanding Critical bugs, this is not the
+next release candidate.
@newsEnd
@newsItem
-@subsubheading LilyPond 2.14.2 released! @emph{July 25, 2011}
+@subsubheading Release candidate 1 of 2.16 - LilyPond 2.15.8 released! @emph{Aug 01, 2011}
-We are happy to announce the release of LilyPond 2.14.2. This
-fixes a few minor bugs in the stable version, and should cause no
-problems. We recommend that everybody upgrade to this version.
+LilyPond 2.15.8 is out; this is the first release candidate of
+the upcoming 2.16 stable release. All users are invited to
+experiment with this version. New features since 2.14.2 are
+listed in the @qq{Changes} manual on the website section about
+@ref{Development}.
+
+There are no known Critical issues with this release. If no
+Critical bugs are found, then the official 2.16.0 release will be
+on 08 Aug 2011. If you discover any problems, please send us
+@ref{Bug reports}.
@newsEnd
* don't duplicate entries from news-front.itexi
@end ignore
+@newsItem
+@subsubheading LilyPond 2.15.7 released! @emph{July 29, 2011}
+
+We are happy to announce the release of LilyPond 2.15.7. This
+release contains the usual number of bugfixes.
+
+It is strongly recommended that normal users do @strong{not} use
+this release, and instead use the stable 2.14 version.
+
+@newsEnd
+
+
+@newsItem
+@subsubheading LilyPond 2.15.6 released! @emph{July 26, 2011}
+
+We are happy to announce the release of LilyPond 2.15.6. This
+release contains the usual number of bugfixes.
+
+It is strongly recommended that normal users do @strong{not} use
+this release, and instead use the stable 2.14 version.
+
+@newsEnd
+
+
+@newsItem
+@subsubheading LilyPond 2.14.2 released! @emph{July 25, 2011}
+
+We are happy to announce the release of LilyPond 2.14.2. This
+fixes a few minor bugs in the stable version, and should cause no
+problems. We recommend that everybody upgrade to this version.
+
+@newsEnd
+
+
@newsItem
include $(depth)/make/stepmake.make
+.PHONY: test info website
local-dist: refresh-release-files dist-toplevel-txt-files
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=15
-PATCH_LEVEL=10
+PATCH_LEVEL=12
MY_PATCH_LEVEL=
VERSION_STABLE=2.14.2
-VERSION_DEVEL=2.15.9
+VERSION_DEVEL=2.15.11
--- /dev/null
+\version "2.14.1"
+\header {
+ texidoc = "Ambitus accidentals (whether present or not) are ignored by the
+slur engravers.
+"
+}
+
+\score {
+ \new Voice \with { \consists Ambitus_engraver } {
+ c'4( es')
+ }
+}
\ No newline at end of file
+++ /dev/null
-\version "2.14.0"
-
-\header{
- texidoc="Properties capoPitch, capoVertical: display chordnames, suitably
-transposed for a guitar capo, either in a line or one above the other.
-"
-}
-
-<<
- \new ChordNames \chordmode {
- c1
- g1
- c1
- g1
- c1
- g1
- }
- \chordmode {
- c1
- g1
- \set ChordNames.capoPitch = #(ly:make-pitch 0 -2 -1/2)
- c1
- g1
- \set ChordNames.capoVertical = ##t
- c1
- g1
- }
->>
--- /dev/null
+\version "2.15.12"
+
+\header {
+ texidoc = "@code{Dynamics} and @code{Lyrics} lines below
+a @code{PianoStaff} do not affect the placement of the instrument name."
+}
+
+upper = \relative c'' {
+ a4 b c d
+}
+
+lower = \relative c {
+ \clef bass
+ a2 c
+}
+
+\score {
+<<
+ \new PianoStaff
+ <<
+ \set PianoStaff.instrumentName = #"Piano"
+ \new Staff = "Staff_pfUpper" << \upper >>
+ \new Staff = "Staff_pfLower" << \lower >>
+ \new Dynamics { s2\sustainOn s\sustainOff }
+ >>
+
+ \new PianoStaff <<
+ \set PianoStaff.instrumentName = #"Piano"
+ \new Staff = "Staff_pfUpper" << \upper >>
+ \new Staff = "Staff_pfLower" << \lower >>
+ \new Lyrics \lyricmode { la2 la2 }
+ >>
+
+ \new PianoStaff <<
+ \set PianoStaff.instrumentName = #"Piano"
+ \new Staff = "Staff_pfUpper" << \upper >>
+ \new Staff = "Staff_pfLower" << \lower >>
+ >>
+>>
+}
\ No newline at end of file
--- /dev/null
+\version "2.15.12"
+
+\header {
+ texidoc = "
+@code{\laissezVibrer} ties should also work on individual notes of a chord.
+" }
+
+\relative c' {
+ <d-\laissezVibrer g>1
+ <d^\laissezVibrer g_\laissezVibrer>1
+}
-\version "2.14.0"
+\version "2.15.12"
\header {
texidoc = "Mensural ligatures show different shapes, depending on the
-\version "2.14.0"
+\version "2.15.12"
\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.
"
}
}
\new Voice {
\override Stem #'direction = #DOWN
- a4 a2. a1 a\breve*1/2 a\longa*1/4
+ g4 g2. g1 g\breve*1/2 g\longa*1/4
}
>>
\header {
texidoc = "The brackets of a piano pedal should start and end at
- the left side of the note. If a note is shared between two brackets,
- these ends are flared.
+ the left side of the main note-column. If a note is shared between
+ two brackets, these ends are flared.
At a line-break, there are no vertical endings. " }
\relative c'' {
\set Staff.pedalSustainStyle = #'bracket
- c4 d e \sustainOn b c c, \sustainOff \sustainOn d8[ c] e8[
- e \sustainOff \sustainOn] f4 d
- \sustainOff g \sustainOn b b, \sustainOff c'
+ c4 d <e f b,> \sustainOn b c c, \sustainOff \sustainOn d8[ c] e8[
+ e \sustainOff \sustainOn] f4 r \sustainOff
+ g \sustainOn bes bes, \sustainOff c'
\set Staff.pedalUnaCordaStyle = #'mixed
c4 d \unaCorda e f g
- b | \break c b c \treCorde c
+ b | \break c b <c e,>\arpeggio \treCorde c
}
\layout { ragged-right = ##t }
}
Interval result;
Grob *me = unsmob_grob (smob);
if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me))
- result = staff->extent (staff, Y_AXIS);
-
+ {
+ result = staff->extent (staff, Y_AXIS);
+
+ /* Due to rounding problems, bar lines extending to the outermost edges
+ of the staff lines appear wrongly in on-screen display
+ (and, to a lesser extent, in print) - they stick out a pixel.
+ The solution is to extend bar lines only to the middle
+ of the staff line - unless they have different colors,
+ when it would be undesirable.
+ */
+ SCM bar_line_color = me->get_property ("color");
+ SCM staff_color = staff->get_property ("color");
+ if (bar_line_color == staff_color)
+ result *= (1 - 0.5 * (Staff_symbol_referencer::line_thickness (me) /
+ Staff_symbol_referencer::staff_radius (me)));
+ }
return ly_interval2scm (result);
}
return filter_solutions (sol);
}
+/**
+ Assuming AX is X_AXIS, and D is UP, finds the
+ maximum value of curve_coordinate(t, Y_AXIS) subject to
+ l <= curve_coordinate(t, X_AXIS) <= r.
+*/
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);
+ Axis other = other_axis (ax);
Interval lr (l, r);
- Drul_array<vector<Real> > sol;
+ vector<Real> solutions;
+
+ // Possible solutions are:
+ // t = 0 or 1, or...
+ solutions.push_back (0);
+ solutions.push_back (1);
+
+ // t is a critical point for the other-axis polynomial, or...
+ Polynomial p_prime (polynomial (other));
+ p_prime.differentiate ();
+ vector<Real> criticals = p_prime.solve ();
+ solutions.insert (solutions.end (), criticals.begin (), criticals.end ());
+
+ // t solves curve_coordinate(t, X_AXIS) = l or r.
Direction dir = LEFT;
do
{
- Polynomial p (polynomial (axis));
+ Polynomial p (polynomial (ax));
p.coefs_[0] -= lr[dir];
- sol[dir] = filter_solutions (p.solve ());
+ vector<Real> sol = p.solve ();
+ solutions.insert (solutions.end (), sol.begin (), sol.end ());
}
while (flip (&dir) != LEFT);
- if (!sol[LEFT].size () || !sol[RIGHT].size ())
+ Polynomial p (polynomial (ax));
+ Polynomial other_p (polynomial (other));
+ vector<Real> values;
+ for (vsize i = solutions.size (); i--;)
{
- programming_error ("no solution found for Bezier intersection");
- return 0.0;
+ Real t = solutions[i];
+ if (t >= 0 && t <= 1 && p.eval (t) >= l && p.eval (t) <= r)
+ values.push_back (other_p.eval (t));
}
- Polynomial p (polynomial (other));
-
- Drul_array<vsize> indices(left_index, right_index);
- do
+ if (values.empty ())
{
- 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;
- }
+ programming_error ("no solution found for Bezier intersection");
+ return 0.0;
}
- while (flip (&dir) != LEFT);
- return p.minmax (sol[LEFT][indices[LEFT]], sol[RIGHT][indices[RIGHT]], d != LEFT);
+ vector_sort (values, less<Real> ());
+ return (d == DOWN) ? values[0] : values.back ();
}
/**
if (unsmob_grob (l->get_property ("cause")))
orig_string = unsmob_grob (l->get_property ("cause"))->name ();
- programming_error (_f ("No spacing entry from %s to `%s'",
- orig_string.c_str (),
- sym_string.c_str ()));
+ programming_error (to_string ("No spacing entry from %s to `%s'",
+ orig_string.c_str (),
+ sym_string.c_str ()));
}
Real distance = 1.0;
pitches = scm_sort_list (pitches, Pitch::less_p_proc);
- SCM capo_proc = ly_lily_module_constant ("capo-handler");
- markup = scm_call_4 (capo_proc, pitches, bass, inversion,
+ SCM name_proc = get_property ("chordNameFunction");
+ markup = scm_call_4 (name_proc, pitches, bass, inversion,
context ()->self_scm ());
}
/*
if (path.size () != 1)
{
- programming_error (_f ("Invalid CreateContext event: Cannot create %s context", type.c_str ()));
+ programming_error (to_string ("Invalid CreateContext event: Cannot create %s context", type.c_str ()));
return;
}
Context_def *cdef = path[0];
Real r (scm_to_double (s));
if (isinf (r) || isnan (r))
{
- programming_error (_ ("infinity or NaN encountered while converting Real number"));
- programming_error (_ ("setting to zero"));
+ programming_error ("infinity or NaN encountered while converting Real number, "
+ "setting to zero");
r = 0.0;
}
#ifndef NDEBUG
if (val == ly_symbol2scm ("calculation-in-progress"))
{
- programming_error (_f ("cyclic dependency: calculation-in-progress encountered for #'%s (%s)",
- ly_symbol2string (sym).c_str (),
- name ().c_str ()));
+ programming_error (to_string ("cyclic dependency: calculation-in-progress encountered for #'%s (%s)",
+ ly_symbol2string (sym).c_str (),
+ name ().c_str ()));
if (debug_property_callbacks)
{
message ("backtrace: ");
{
if (isinf (y) || isnan (y))
{
- programming_error (_ ("Infinity or NaN encountered"));
+ programming_error ("Infinity or NaN encountered");
return;
}
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;
SCM lookup_identifier (string s);
SCM lookup_identifier_symbol (SCM s);
void push_extra_token (int token_type);
- void push_embedded_token ();
void push_chord_state (SCM tab);
void push_figuredbass_state ();
void push_lyric_state ();
along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "align-interface.hh"
+#include "axis-group-interface.hh"
#include "engraver.hh"
+#include "page-layout-problem.hh"
#include "pointer-group-interface.hh"
#include "side-position-interface.hh"
-#include "axis-group-interface.hh"
-#include "align-interface.hh"
-#include "text-interface.hh"
#include "system.hh"
+#include "text-interface.hh"
#include "translator.icc"
{
if (dynamic_cast<Spanner *> (info.grob ())
&& Axis_group_interface::has_axis (info.grob (), Y_AXIS)
+ && Page_layout_problem::is_spaceable (info.grob ())
/* ugh. */
void
Laissez_vibrer_engraver::acknowledge_note_head (Grob_info inf)
{
- if (!event_)
+ /* use the heard event_ for all note heads, or an individual event for just
+ * a single note head (attached as an articulation inside a chord) */
+ Stream_event *tie_ev = event_;
+ Grob *head = inf.grob ();
+ Stream_event *note_ev = unsmob_stream_event (head->get_property ("cause"));
+ if (!tie_ev && note_ev && note_ev->in_event_class ("note-event"))
+ {
+ SCM articulations = note_ev->get_property ("articulations");
+ for (SCM s = articulations; !tie_ev && scm_is_pair (s); s = scm_cdr (s))
+ {
+ Stream_event *ev = unsmob_stream_event (scm_car (s));
+ if (ev && ev->in_event_class ("laissez-vibrer-event"))
+ tie_ev = ev;
+ }
+ }
+
+ if (!tie_ev)
return;
- SCM cause = event_->self_scm ();
+ SCM cause = tie_ev->self_scm ();
if (!lv_column_)
lv_column_ = make_item ("LaissezVibrerTieColumn", cause);
Grob *lv_tie = make_item ("LaissezVibrerTie", cause);
- lv_tie->set_object ("note-head", inf.grob ()->self_scm ());
+ lv_tie->set_object ("note-head", head->self_scm ());
Pointer_group_interface::add_grob (lv_column_, ly_symbol2scm ("ties"),
lv_tie);
ALPHAWORD {A}+
-DIGIT {N}
UNSIGNED {N}+
E_UNSIGNED \\{N}+
FRACTION {N}+\/{N}+
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 YYText ()[0];
}
- [^#{}"\\ \t\n\r\f]+ {
+ [^#{}\"\\ \t\n\r\f]+ {
string s (YYText ());
char c = s[s.length () - 1];
extra_token_types_.push_back (token_type);
}
-void
-Lily_lexer::push_embedded_token ()
-{
- push_extra_token (EMBEDDED_LILY);
-}
-
void
Lily_lexer::push_chord_state (SCM tab)
{
SCM sid = lookup_identifier (str);
if (is_music_function (sid))
{
+ int funtype = SCM_FUNCTION;
+
yylval.scm = get_music_function_transform (sid);
SCM s = scm_object_property (yylval.scm, ly_symbol2scm ("music-function-signature"));
+ SCM cs = scm_car (s);
+
+ if (scm_is_eq (cs, ly_lily_module_constant ("ly:music?")))
+ funtype = MUSIC_FUNCTION;
+ else if (ly_is_procedure (cs))
+ funtype = SCM_FUNCTION;
+ else programming_error ("Bad syntax function predicate");
+
push_extra_token (EXPECT_NO_MORE_ARGS);
- for (; scm_is_pair (s); s = scm_cdr (s))
+ for (s = scm_cdr (s); scm_is_pair (s); s = scm_cdr (s))
{
- SCM cs = scm_car (s);
+ cs = scm_car (s);
if (cs == ly_music_p_proc)
push_extra_token (EXPECT_MUSIC);
push_extra_token (EXPECT_SCM);
else programming_error ("Function parameter without type-checking predicate");
}
- return MUSIC_FUNCTION;
+ return funtype;
}
if (sid != SCM_UNDEFINED)
{"once", ONCE},
{"override", OVERRIDE},
{"paper", PAPER},
- {"partial", PARTIAL},
{"relative", RELATIVE},
{"remove", REMOVE},
{"repeat", REPEAT},
{"sequential", SEQUENTIAL},
{"set", SET},
{"simultaneous", SIMULTANEOUS},
- {"skip", SKIP},
{"tempo", TEMPO},
{"time", TIME_T},
{"times", TIMES},
- {"transpose", TRANSPOSE},
{"type", TYPE},
{"unset", UNSET},
{"with", WITH},
lexer_->new_input (lexer_->main_input_name_, ly_code, sources_);
SCM mod = lexer_->set_current_scope ();
- lexer_->push_embedded_token ();
+ lexer_->push_extra_token (EMBEDDED_LILY);
do_yyparse ();
- SCM result = lexer_->lookup_identifier_symbol (ly_symbol2scm ("$parseStringResult"));
- // $parseStringResult is set in the grammar rule for embedded_lilypond
+ SCM result = lexer_->lookup_identifier_symbol (ly_symbol2scm ("parseStringResult"));
+ // parseStringResult is set in the grammar rule for embedded_lilypond
scm_set_current_module (mod);
vector<Grob_info> primitives)
{
Real thickness
- = robust_scm2double (ligature->get_property ("thickness"), 1.4);
+ = robust_scm2double (ligature->get_property ("thickness"), 1.3);
thickness
*= ligature->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
#include "mensural-ligature.hh"
+#include "directional-element-interface.hh"
#include "font-interface.hh"
#include "international.hh"
#include "item.hh"
}
int primitive = scm_to_int (primitive_scm);
- Stencil out;
Real thickness = 0.0;
Real width = 0.0;
Real flexa_width = 0.0;
Real staff_space = Staff_symbol_referencer::staff_space (me);
- bool const color
- = me->get_property ("style") == ly_symbol2scm ("blackpetrucci");
+ SCM style = me->get_property ("style");
+ bool const black
+ = scm_is_eq (style, ly_symbol2scm ("blackpetrucci"));
bool const semi
- = me->get_property ("style") == ly_symbol2scm ("semipetrucci");
+ = scm_is_eq (style, ly_symbol2scm ("semipetrucci"));
if (primitive & MLP_ANY)
{
- thickness = robust_scm2double (me->get_property ("thickness"), .14);
+ thickness = robust_scm2double (me->get_property ("thickness"), .13);
width = robust_scm2double (me->get_property ("head-width"), staff_space);
}
if (primitive & MLP_FLEXA)
flexa_width = robust_scm2double (me->get_property ("flexa-width"), 2.0)
* staff_space;
+ Stencil out;
int const note_shape = primitive & MLP_ANY;
+ int duration_log = 0;
+ Font_metric *fm = Font_interface::get_default_font (me);
+ string prefix = "noteheads.";
+ string index;
+ string suffix;
+ string color = "";
+ if (black)
+ color = "black";
+ if (semi)
+ color = "semi";
switch (note_shape)
{
case MLP_NONE:
return Lookup::blank (Box (Interval (0, 0), Interval (0, 0)));
- case MLP_LONGA: // mensural brevis head with right cauda
- out = Font_interface::get_default_font (me)->find_by_name
- (color ? "noteheads.sM2blackmensural"
- : semi ? "noteheads.sM2semimensural" : "noteheads.sM2mensural");
- break;
- case MLP_BREVIS: // mensural brevis head
- out = Font_interface::get_default_font (me)->find_by_name
- (color ? "noteheads.sM1blackmensural"
- : semi ? "noteheads.sM1semimensural" : "noteheads.sM1mensural");
- break;
- case MLP_MAXIMA: // should be mensural maxima head without stem
- out = Font_interface::get_default_font (me)->find_by_name
- (color ? "noteheads.sM3blackligmensural"
- : semi ? "noteheads.sM3semiligmensural" : "noteheads.sM3ligmensural");
+ case MLP_MAXIMA:
+ duration_log--;
+ case MLP_LONGA:
+ duration_log--;
+ case MLP_BREVIS:
+ duration_log--;
+ suffix = to_string (duration_log) + color
+ + (duration_log == -3 ? "lig" : "") + "mensural";
+ index = prefix + "s";
+ out = fm->find_by_name (index + suffix);
+ if (out.is_empty ())
+ index = prefix + "d";
+ out = fm->find_by_name (index + "r" + suffix);
+ if (!out.is_empty ()
+ && !Staff_symbol_referencer::on_line
+ (me,
+ robust_scm2int (me->get_property ("staff-position"), 0)))
+ index += "r";
+ out = fm->find_by_name (index + suffix);
break;
case MLP_FLEXA_BEGIN:
case MLP_FLEXA_END:
- out = brew_flexa (me, color, flexa_width, thickness,
+ out = brew_flexa (me, black, flexa_width, thickness,
note_shape == MLP_FLEXA_BEGIN);
break;
default:
- programming_error (_ ("Mensural_ligature:"
- " unexpected case fall-through"));
+ programming_error ("Mensural_ligature:"
+ " unexpected case fall-through");
return Lookup::blank (Box (Interval (0, 0), Interval (0, 0)));
}
if (primitive & MLP_STEM)
{
// assume MLP_UP
- Real y_bottom = 0.0, y_top = 3.0 * staff_space;
+ Real y_bottom = 0.5 * staff_space, y_top = 2.5 * staff_space;
if (primitive & MLP_DOWN)
{
y_bottom = -y_top;
- y_top = 0.0;
+ y_top = -0.5 * staff_space;
}
Interval x_extent (0, thickness);
Font_interface::get_default_font (???)->find_by_name
("noteheads.s-2mensural").extent (Y_AXIS).length () * 0.5
*/
- y_bottom -= 3.0 * staff_space;
+ y_bottom -= 2.5 * staff_space;
}
Interval x_extent (width - thickness, width);
out.add_stencil (join);
}
else
- programming_error (_ ("Mensural_ligature: (join_right == 0)"));
+ programming_error ("Mensural_ligature: (join_right == 0)");
}
#if 0 /* what happend with the ledger lines? */
(SCM signature, SCM func),
"Make a function to process music, to be used for the"
" parser. @var{func} is the function, and @var{signature}"
- " describes its arguments. @var{signature} is a list"
+ " describes its arguments. @var{signature}'s cdr is a list"
" containing either @code{ly:music?} predicates or other type"
- " predicates.")
+ " predicates. Its car is the syntax function to call.")
{
LY_ASSERT_TYPE (ly_is_procedure, func, 1);
return make_music_function (signature, func);
FIXME: then don't do it.
*/
if (!m->is_mus_type ("event"))
- m->origin ()->programming_error (_ ("Sending non-event to context"));
+ m->origin ()->programming_error ("Sending non-event to context");
m->send_to_context (get_outlet ());
}
Font_metric *fm = Font_interface::get_default_font (me);
+ string prefix = "noteheads.";
string idx_symmetric;
string idx_directed;
- string idx_either;
- idx_symmetric = idx_either = "noteheads.s" + suffix;
- Stencil out = fm->find_by_name (idx_symmetric);
+ string idx_either = idx_symmetric = prefix + "s";
+ Stencil out = fm->find_by_name (idx_either + suffix);
if (out.is_empty ())
{
- string prefix = "noteheads.";
-
Grob *stem = unsmob_grob (me->get_object ("stem"));
Direction stem_dir = stem ? get_grob_direction (stem) : CENTER;
if (stem_dir == CENTER)
programming_error ("must have stem dir for note head");
- idx_directed = idx_either
- = prefix + ((stem_dir == UP) ? "u" : "d") + suffix;
- out = fm->find_by_name (idx_directed);
+ idx_either = idx_directed = prefix + ((stem_dir == UP) ? "u" : "d");
}
+ out = fm->find_by_name (idx_either + "r" + suffix);
+ if (!out.is_empty ()
+ && !Staff_symbol_referencer::on_line
+ (me,
+ robust_scm2int (me->get_property ("staff-position"), 0)))
+ idx_either += "r";
+
+ idx_either += suffix;
+ out = fm->find_by_name (idx_either);
if (out.is_empty ())
{
me->warning (_f ("none of note heads `%s' or `%s' found",
static Music *make_music_with_input (SCM name, Input where);
SCM make_music_relative (Pitch start, SCM music, Input loc);
-SCM run_music_function (Lily_parser *, SCM expr);
+SCM run_music_function (Lily_parser *parser, Input loc, SCM func, SCM args);
SCM get_first_context_id (SCM type, Music *m);
SCM make_chord_elements (SCM pitch, SCM dur, SCM modification_list);
SCM make_chord_step (int step, Rational alter);
%token FIGURES "\\figures"
%token GROBDESCRIPTIONS "\\grobdescriptions"
%token HEADER "\\header"
-%token INVALID "\\invalid"
+%token INVALID "\\version-error"
%token KEY "\\key"
%token LAYOUT "\\layout"
%token LYRICMODE "\\lyricmode"
%token MIDI "\\midi"
%token NAME "\\name"
%token NOTEMODE "\\notemode"
-%token OCTAVE "\\octave"
%token ONCE "\\once"
%token OVERRIDE "\\override"
%token PAPER "\\paper"
-%token PARTIAL "\\partial"
%token RELATIVE "\\relative"
%token REMOVE "\\remove"
%token REPEAT "\\repeat"
%token SEQUENTIAL "\\sequential"
%token SET "\\set"
%token SIMULTANEOUS "\\simultaneous"
-%token SKIP "\\skip"
%token TEMPO "\\tempo"
%token TIMES "\\times"
-%token TRANSPOSE "\\transpose"
%token TYPE "\\type"
%token UNSET "\\unset"
%token WITH "\\with"
%token MULTI_MEASURE_REST
-%token <i> DIGIT
%token <i> E_UNSIGNED
%token <i> UNSIGNED
%token <scm> CONTEXT_DEF_IDENTIFIER
%token <scm> CONTEXT_MOD_IDENTIFIER
%token <scm> DRUM_PITCH
+%token <scm> PITCH_IDENTIFIER
%token <scm> DURATION_IDENTIFIER
%token <scm> EVENT_IDENTIFIER
%token <scm> FRACTION
%token <scm> OUTPUT_DEF_IDENTIFIER
%token <scm> REAL
%token <scm> RESTNAME
+%token <scm> SCM_FUNCTION
%token <scm> SCM_IDENTIFIER
%token <scm> SCM_TOKEN
%token <scm> SCORE_IDENTIFIER
%type <scm> direction_reqd_event
%type <scm> embedded_lilypond
%type <scm> event_chord
+%type <scm> fingering
%type <scm> gen_text_def
%type <scm> music_property_def
%type <scm> note_chord_element
%type <scm> post_event
+%type <scm> post_event_nofinger
%type <scm> re_rhythmed_music
%type <scm> relative_music
%type <scm> simple_element
%type <scm> context_prop_spec
%type <scm> direction_less_char
%type <scm> duration_length
+%type <scm> closed_embedded_scm
%type <scm> embedded_scm
%type <scm> figure_list
%type <scm> figure_spec
%type <scm> markup_composed_list
%type <scm> markup_command_list
%type <scm> markup_command_list_arguments
+%type <scm> closed_markup_command_list_arguments
%type <scm> markup_command_basic_arguments
%type <scm> markup_head_1_item
%type <scm> markup_head_1_list
%type <scm> property_operation
%type <scm> property_path property_path_revved
%type <scm> scalar
+%type <scm> closed_scalar
+%type <scm> open_scm_function_call
+%type <scm> closed_scm_function_call
%type <scm> script_abbreviation
%type <scm> simple_chord_elements
%type <scm> simple_markup
PARSER->lexer_->push_note_state (alist_to_hashq (nn));
} embedded_lilypond {
PARSER->lexer_->pop_state ();
- PARSER->lexer_->set_identifier (ly_symbol2scm ("$parseStringResult"), $3);
+ PARSER->lexer_->set_identifier (ly_symbol2scm ("parseStringResult"), $3);
}
;
}
;
-embedded_scm:
+closed_embedded_scm:
SCM_TOKEN
| SCM_IDENTIFIER
+ | closed_scm_function_call
+ ;
+
+embedded_scm:
+ closed_embedded_scm
+ | open_scm_function_call
+ ;
+
+closed_scm_function_call:
+ SCM_FUNCTION closed_function_arglist
+ {
+ $$ = run_music_function (PARSER, @$,
+ $1, $2);
+ }
+ ;
+
+open_scm_function_call:
+ SCM_FUNCTION open_function_arglist
+ {
+ $$ = run_music_function (PARSER, @$,
+ $1, $2);
+ }
;
embedded_lilypond:
| error {
PARSER->error_level_ = 1;
}
- | embedded_lilypond INVALID {
+ | INVALID embedded_lilypond {
PARSER->error_level_ = 1;
}
;
else
$$ = MAKE_SYNTAX ("event-chord", @$, scm_list_1 ($1));
}
- | post_event {
+ | post_event_nofinger {
$$ = $1;
}
| number_expression {
| full_markup_list {
$$ = $1;
}
- | DIGIT {
- $$ = scm_from_int ($1);
- }
| context_modification {
$$ = $1;
}
TEMPO steno_duration '=' tempo_range {
$$ = MAKE_SYNTAX ("tempo", @$, SCM_EOL, $2, $4);
}
- | TEMPO scalar steno_duration '=' tempo_range {
+ | TEMPO closed_scalar steno_duration '=' tempo_range {
$$ = MAKE_SYNTAX ("tempo", @$, $2, $3, $5);
}
- | TEMPO scalar {
+ | TEMPO closed_scalar {
$$ = MAKE_SYNTAX ("tempo", @$, $2);
}
;
;
function_scm_argument:
- embedded_scm
+ closed_embedded_scm
| simple_string
;
EXPECT_MUSIC function_arglist open_music {
$$ = scm_cons ($3, $2);
}
+ | EXPECT_SCM function_arglist open_scm_function_call {
+ $$ = scm_cons ($3, $2);
+ }
;
/* a closed argument list is one that does not end in a music
| EXPECT_MARKUP function_arglist simple_string {
$$ = scm_cons ($3, $2);
}
- | EXPECT_PITCH function_arglist pitch {
+ | EXPECT_PITCH function_arglist pitch_also_in_chords {
$$ = scm_cons ($3, $2);
}
| EXPECT_DURATION closed_function_arglist duration_length {
generic_prefix_music_scm:
MUSIC_FUNCTION function_arglist {
- $$ = scm_cons2 ($1, make_input (@$), scm_reverse_x ($2, SCM_EOL));
+ $$ = run_music_function (PARSER, @$,
+ $1, $2);
}
;
prefix_composite_music:
- generic_prefix_music_scm {
- $$ = run_music_function (PARSER, $1);
- }
+ generic_prefix_music_scm
| CONTEXT simple_string optional_id optional_context_mod music {
Context_mod *ctxmod = unsmob_context_mod ($4);
SCM mods = SCM_EOL;
$$ = MAKE_SYNTAX ("time-scaled-music", @$, $2, $3);
}
| repeated_music { $$ = $1; }
- | TRANSPOSE pitch_also_in_chords pitch_also_in_chords music {
- Pitch from = *unsmob_pitch ($2);
- Pitch to = *unsmob_pitch ($3);
- SCM pitch = pitch_interval (from, to).smobbed_copy ();
- $$ = MAKE_SYNTAX ("transpose-music", @$, pitch, $4);
- }
| mode_changing_head grouped_music_list {
if ($1 == ly_symbol2scm ("chords"))
{
property_path_revved:
- embedded_scm {
+ closed_embedded_scm {
$$ = scm_cons ($1, SCM_EOL);
}
- | property_path_revved embedded_scm {
+ | property_path_revved closed_embedded_scm {
$$ = scm_cons ($2, $1);
}
;
}
;
-scalar: string {
+closed_scalar: string {
$$ = $1;
}
| lyric_element {
| bare_number {
$$ = $1;
}
- | embedded_scm {
+ | closed_embedded_scm {
$$ = $1;
}
| full_markup {
$$ = $1;
}
- | DIGIT {
- $$ = scm_from_int ($1);
- }
+ ;
+
+scalar: closed_scalar
+ | open_scm_function_call
;
event_chord:
}
$$ = n->unprotect ();
}
- | music_function_chord_body {
- $$ = run_music_function (PARSER, $1);
- }
+ | music_function_chord_body
;
/* We can't accept a music argument, not even a closed one,
music_function_chord_body:
MUSIC_FUNCTION music_function_chord_body_arglist {
- $$ = scm_cons2 ($1, make_input (@$), scm_reverse_x ($2, SCM_EOL));
+ $$ = run_music_function (PARSER, @$,
+ $1, $2);
}
;
music_function_event:
MUSIC_FUNCTION music_function_event_arglist {
- $$ = scm_cons2 ($1, make_input (@$), scm_reverse_x ($2, SCM_EOL));
+ $$ = run_music_function (PARSER, @$,
+ $1, $2);
}
;
command_event {
$$ = $1;
}
- | SKIP duration_length {
- $$ = MAKE_SYNTAX ("skip-music", @$, $2);
- }
| E_BRACKET_OPEN {
Music *m = MY_MAKE_MUSIC ("LigatureEvent", @$);
m->set_property ("span-direction", scm_from_int (START));
$$ = MAKE_SYNTAX ("bar-check", @$, SCM_UNDEFINED);
}
- | PARTIAL duration_length {
- $$ = MAKE_SYNTAX ("partial", @$, $2);
- }
-
| TIME_T fraction {
SCM proc = ly_lily_module_constant ("make-time-signature-set");
}
;
-post_event:
+post_event_nofinger:
direction_less_event {
$$ = $1;
}
| script_dir music_function_event {
- $$ = run_music_function (PARSER, $2);
+ $$ = $2;
if ($1)
{
unsmob_music ($$)->set_property ("direction", scm_from_int ($1));
| string_number_event
;
+post_event:
+ post_event_nofinger
+ | script_dir fingering {
+ if ($1)
+ {
+ Music *m = unsmob_music ($2);
+ m->set_property ("direction", scm_from_int ($1));
+ }
+ $$ = $2;
+ }
+ ;
+
string_number_event:
E_UNSIGNED {
Music *s = MY_MAKE_MUSIC ("StringNumberEvent", @$);
steno_pitch {
$$ = $1;
}
+ | PITCH_IDENTIFIER
;
pitch_also_in_chords:
make_simple_markup ($1));
$$ = t->unprotect ();
}
- | DIGIT {
+ ;
+
+fingering:
+ UNSIGNED {
Music *t = MY_MAKE_MUSIC ("FingeringEvent", @$);
t->set_property ("digit", scm_from_int ($1));
$$ = t->unprotect ();
absolute_pitch:
- steno_pitch {
+ pitch {
$$ = $1;
}
;
;
bass_number:
- DIGIT {
- $$ = scm_from_int ($1);
- }
- | UNSIGNED {
+ UNSIGNED {
$$ = scm_from_int ($1);
}
| STRING { $$ = $1; }
UNSIGNED {
$$ = $1;
}
- | DIGIT {
- $$ = $1;
- }
;
unsigned_number:
;
markup_command_list:
- MARKUP_LIST_FUNCTION markup_command_list_arguments {
+ MARKUP_LIST_FUNCTION closed_markup_command_list_arguments {
$$ = scm_cons ($1, scm_reverse_x($2, SCM_EOL));
}
;
EXPECT_MARKUP_LIST markup_command_list_arguments markup_list {
$$ = scm_cons ($3, $2);
}
- | EXPECT_SCM markup_command_list_arguments embedded_scm {
+ | EXPECT_SCM markup_command_list_arguments closed_embedded_scm {
$$ = scm_cons ($3, $2);
}
| EXPECT_NO_MORE_ARGS {
}
;
-markup_command_list_arguments:
+closed_markup_command_list_arguments:
markup_command_basic_arguments { $$ = $1; }
| EXPECT_MARKUP markup_command_list_arguments markup {
$$ = scm_cons ($3, $2);
}
;
+markup_command_list_arguments:
+ closed_markup_command_list_arguments
+ | EXPECT_SCM markup_command_list_arguments open_scm_function_call
+ {
+ $$ = scm_cons ($3, $2);
+ }
+ ;
+
markup_head_1_item:
MARKUP_FUNCTION EXPECT_MARKUP markup_command_list_arguments {
$$ = scm_cons ($1, scm_reverse_x ($3, SCM_EOL));
mus->unprotect ();
return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
+ } else if (unsmob_pitch (sid)) {
+ *destination = unsmob_pitch (sid)->smobbed_copy ();
+ return PITCH_IDENTIFIER;
} else if (unsmob_duration (sid)) {
*destination = unsmob_duration (sid)->smobbed_copy ();
return DURATION_IDENTIFIER;
SCM
-run_music_function (Lily_parser *parser, SCM expr)
+run_music_function (Lily_parser *parser, Input loc, SCM func, SCM args)
{
- SCM func = scm_car (expr);
- Input *loc = unsmob_input (scm_cadr (expr));
- SCM args = scm_cddr (expr);
SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
SCM type_check_proc = ly_lily_module_constant ("type-check-list");
- if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr (expr), sig, args)))
+ args = scm_reverse_x (args, SCM_EOL);
+
+ if (!to_boolean (scm_call_3 (type_check_proc, make_input (loc), scm_cdr (sig), args)))
{
parser->error_level_ = 1;
- return LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("void-music"), scm_list_2 (parser->self_scm (), make_input (*loc)));
+ return LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("void-music"), scm_list_2 (parser->self_scm (), make_input (loc)));
}
- SCM syntax_args = scm_list_4 (parser->self_scm (), make_input (*loc), func, args);
+ SCM syntax_args = scm_list_5 (parser->self_scm (), make_input (loc), scm_car (sig), func, args);
return LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("music-function"), syntax_args);
}
protected:
DECLARE_TRANSLATOR_LISTENER (phrasing_slur);
- DECLARE_ACKNOWLEDGER (accidental);
+ DECLARE_ACKNOWLEDGER (inline_accidental);
DECLARE_ACKNOWLEDGER (fingering);
DECLARE_ACKNOWLEDGER (note_column);
DECLARE_ACKNOWLEDGER (slur);
}
void
-Phrasing_slur_engraver::acknowledge_accidental (Grob_info info)
+Phrasing_slur_engraver::acknowledge_inline_accidental (Grob_info info)
{
acknowledge_extra_object (info);
}
objects_to_acknowledge_.clear ();
}
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, accidental);
+ADD_ACKNOWLEDGER (Phrasing_slur_engraver, inline_accidental);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, fingering)
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, note_column);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, slur);
height[d] = 0.0;
else
flare[d] = 0.0;
- }
- Interval ext = robust_relative_extent (b, common, X_AXIS);
- span_points[d] = ext [broken[d] ? RIGHT : LEFT];
+ span_points[d] = robust_relative_extent (b, common, X_AXIS)[RIGHT];
+ }
+ else
+ span_points[d] = b->relative_coordinate (common, X_AXIS);
}
while (flip (&d) != LEFT);
#include "warn.hh"
#include "ly-smobs.icc"
+#include <cmath>
Pitch::Pitch (int o, int n, Rational a)
{
int
Pitch::rounded_semitone_pitch () const
{
- return int (double (tone_pitch () * Rational (2)));
+ return int (floor (double (tone_pitch () * Rational (2) + Rational (1,2))));
}
int
Pitch::rounded_quartertone_pitch () const
{
- return int (double (tone_pitch () * Rational (4)));
+ return int (floor (double (tone_pitch () * Rational (4) + Rational (1,2))));
}
void
{
string help = get_help_string ();
puts (help.c_str ());
+ fflush (stdout);
return SCM_UNSPECIFIED;
}
protected:
DECLARE_TRANSLATOR_LISTENER (slur);
- DECLARE_ACKNOWLEDGER (accidental);
+ DECLARE_ACKNOWLEDGER (inline_accidental);
DECLARE_ACKNOWLEDGER (fingering);
DECLARE_ACKNOWLEDGER (note_column);
DECLARE_ACKNOWLEDGER (script);
}
void
-Slur_engraver::acknowledge_accidental (Grob_info info)
+Slur_engraver::acknowledge_inline_accidental (Grob_info info)
{
acknowledge_extra_object (info);
}
stop_events_.clear ();
}
-ADD_ACKNOWLEDGER (Slur_engraver, accidental);
+ADD_ACKNOWLEDGER (Slur_engraver, inline_accidental);
ADD_ACKNOWLEDGER (Slur_engraver, fingering);
ADD_ACKNOWLEDGER (Slur_engraver, note_column);
ADD_ACKNOWLEDGER (Slur_engraver, script);
}
if (!spring)
- programming_error (_f ("No spring between column %d and next one",
- Paper_column::get_rank (this_col)));
+ programming_error (to_string ("No spring between column %d and next one",
+ Paper_column::get_rank (this_col)));
return spring ? *spring : Spring ();
}
me->set_property ("stem-begin-position", scm_from_double (height[-d] * 2 / staff_space));
me->set_property ("length", scm_from_double (height.length () * 2 / staff_space));
- (void) me->extent (me, Y_AXIS);
}
/* Note head that determines hshift for upstems
Real r = real_attach;
/* If not centered: correct for stem thickness. */
- if (attach)
+ extract_grob_set (me, "note-heads", heads);
+ SCM style = heads[0]->get_property ("style");
+ if (attach && !scm_is_eq (style, ly_symbol2scm ("mensural"))
+ && !scm_is_eq (style, ly_symbol2scm ("neomensural"))
+ && !scm_is_eq (style, ly_symbol2scm ("petrucci")))
{
Real rule_thick = thickness (me);
r += -d * rule_thick * 0.5;
#include "modified-font-metric.hh"
#include "output-def.hh"
#include "pango-font.hh"
+#include "international.hh"
#include "warn.hh"
static void
scm_display (markup, scm_current_error_port ());
scm_puts ("\n", scm_current_error_port ());
- Box b;
- b[X_AXIS].set_empty ();
- b[Y_AXIS].set_empty ();
-
- Stencil s (b, SCM_EOL);
- return s.smobbed_copy ();
+ return Stencil ().smobbed_copy ();
}
}
Real staff_space = Staff_symbol_referencer::staff_space (me);
if (!delta_pitch)
{
- me->programming_error (_ ("Vaticana_ligature: "
- "zero join (delta_pitch == 0)"));
+ me->programming_error ("Vaticana_ligature: "
+ "zero join (delta_pitch == 0)");
return Lookup::blank (Box (Interval (0, 0), Interval (0, 0)));
}
Interval x_extent = Interval (0, join_thickness);
\accepts "VaticanaStaff"
\accepts "GregorianTranscriptionStaff"
\accepts "MensuralStaff"
+ \accepts "PetrucciStaff"
\accepts "StaffGroup"
\accepts "DrumStaff"
\accepts "Lyrics"
%% Set default head for notes outside of \[ \].
\override NoteHead #'style = #'mensural
\override Rest #'style = #'mensural
+ \override Flag #'style = #'mensural
%% There are no beams in mensural notation.
autoBeaming = ##f
printKeyCancellation = ##f
}
+\context {
+ \Voice
+ \name "PetrucciVoice"
+ \alias "Voice"
+ \description "Same as @code{Voice} context, except that it is
+accommodated for typesetting a piece in Petrucci style."
+
+ \remove "Ligature_bracket_engraver"
+ \consists "Mensural_ligature_engraver"
+
+ %% Set glyph styles.
+ \override NoteHead #'style = #'petrucci
+ \override Rest #'style = #'mensural
+
+ % Thickens and shortens stems.
+ \override Stem #'thickness = #1.7
+ \override Stem #'length = #5
+
+ %% There are no beams in Petrucci notation.
+ autoBeaming = ##f
+}
+
+\context {
+ \Staff
+ \name "PetrucciStaff"
+ \alias "Staff"
+ \denies "Voice"
+ \defaultchild "PetrucciVoice"
+ \accepts "PetrucciVoice"
+ \description "Same as @code{Staff} context, except that it is
+accommodated for typesetting a piece in Petrucci style."
+
+ \consists "Custos_engraver"
+
+ \override StaffSymbol #'thickness = #1.3
+
+ %% Choose Petrucci g clef on 2nd line as default.
+ clefGlyph = #"clefs.petrucci.g"
+ middleCClefPosition = #-6
+ middleCPosition = #-6
+ clefPosition = #-2
+ clefOctavation = #0
+
+ \override Custos #'style = #'mensural
+ \override Custos #'neutral-position = #3
+ \override Custos #'neutral-direction = #DOWN
+
+ %% Accidentals are valid only once (if the following note is different)
+ extraNatural = ##f
+ autoAccidentals = #`(Staff ,(make-accidental-rule 'same-octave 0)
+ ,neo-modern-accidental-rule)
+ autoCautionaries = #'()
+ printKeyCancellation = ##f
+}
+
%% Keep the old definitions in here for compatibility (they erase previous
%% settings to the corresponding context!).
%% For new scores, one should simply insert the \RemoveEmptyStaves settings
%% keep these two together
"instrument-definitions" = #'()
addInstrumentDefinition =
-#(define-music-function
+#(define-scheme-function
(parser location name lst) (string? list?)
(_i "Create instrument @var{name} with properties @var{list}.")
- (set! instrument-definitions (acons name lst instrument-definitions))
- (make-music 'SequentialMusic 'void #t))
+ (set! instrument-definitions (acons name lst instrument-definitions)))
addQuote =
-#(define-music-function (parser location name music) (string? ly:music?)
+#(define-scheme-function (parser location name music) (string? ly:music?)
(_i "Define @var{music} as a quotable music expression named
@var{name}")
- (add-quotable parser name music)
- (make-music 'SequentialMusic 'void #t))
+ (add-quotable parser name music))
%% keep these two together
afterGraceFraction = #(cons 6 8)
'delta-step delta))
bookOutputName =
-#(define-music-function (parser location newfilename) (string?)
+#(define-scheme-function (parser location newfilename) (string?)
(_i "Direct output for the current book block to @var{newfilename}.")
- (set! book-filename newfilename)
- (make-music 'SequentialMusic 'void #t))
+ (set! book-filename newfilename))
bookOutputSuffix =
-#(define-music-function (parser location newsuffix) (string?)
+#(define-scheme-function (parser location newsuffix) (string?)
(_i "Set the output filename suffix for the current book block to
@var{newsuffix}.")
- (set! book-output-suffix newsuffix)
- (make-music 'SequentialMusic 'void #t))
+ (set! book-output-suffix newsuffix))
%% \breathe is defined as a music function rather than an event identifier to
%% ensure it gets useful input location information: as an event identifier,
(_i "Insert @var{music} as grace notes."))
harmonicByFret = #(define-music-function (parser location fret music) (number? ly:music?)
+ (_i "Convert @var{music} into harmonics; the resulting notes resemble
+harmonics played on a fretted instrument by touching the strings above @var{fret}.")
(let* ((fret (number->string fret))
(pitch (fret->pitch fret)))
(make-sequential-music
#}))))
harmonicByRatio = #(define-music-function (parser location ratio music) (number? ly:music?)
+ (_i "Convert @var{music} into harmonics; the resulting notes resemble
+harmonics played on a fretted instrument by touching the strings above the point
+given through @var{ratio}.")
(let ((pitch (ratio->pitch ratio))
(fret (ratio->fret ratio)))
(make-sequential-music
language =
-#(define-music-function (parser location language) (string?)
+#(define-scheme-function (parser location language) (string?)
(_i "Set note names for language @var{language}.")
- (note-names-language parser language)
- (make-music 'Music 'void #t))
+ (note-names-language parser language))
languageSaveAndChange =
-#(define-music-function (parser location language) (string?)
+#(define-scheme-function (parser location language) (string?)
(_i "Store the previous pitchnames alist, and set a new one.")
(set! previous-pitchnames pitchnames)
- (note-names-language parser language)
- (make-music 'Music 'void #t))
+ (note-names-language parser language))
languageRestore =
-#(define-music-function (parser location) ()
+#(define-scheme-function (parser location) ()
(_i "Restore a previously-saved pitchnames alist.")
(if previous-pitchnames
(begin
(set! pitchnames previous-pitchnames)
(ly:parser-set-note-names parser pitchnames))
- (ly:input-warning location (_ "No other language was defined previously. Ignoring.")))
- (make-music 'Music 'void #t))
+ (ly:input-warning location (_ "No other language was defined previously. Ignoring."))))
makeClusters =
modalInversion =
#(define-music-function (parser location around to scale music)
- (ly:music? ly:music? ly:music? ly:music?)
+ (ly:pitch? ly:pitch? ly:music? ly:music?)
(_i "Invert @var{music} about @var{around} using @var{scale} and
transpose from @var{around} to @var{to}.")
(let ((inverter (make-modal-inverter around to scale)))
modalTranspose =
#(define-music-function (parser location from to scale music)
- (ly:music? ly:music? ly:music? ly:music?)
+ (ly:pitch? ly:pitch? ly:music? ly:music?)
(_i "Transpose @var{music} from pitch @var{from} to pitch @var{to}
using @var{scale}.")
(let ((transposer (make-modal-transposer from to scale)))
inversion =
#(define-music-function
- (parser location around to music) (ly:music? ly:music? ly:music?)
+ (parser location around to music) (ly:pitch? ly:pitch? ly:music?)
(_i "Invert @var{music} about @var{around} and
transpose from @var{around} to @var{to}.")
(music-invert around to music))
octaveCheck =
-#(define-music-function (parser location pitch-note) (ly:music?)
+#(define-music-function (parser location pitch) (ly:pitch?)
(_i "Octave check.")
(make-music 'RelativeOctaveCheck
- 'pitch (pitch-of-note pitch-note)))
+ 'pitch pitch))
ottava =
#(define-music-function (parser location octave) (integer?)
'break-permission 'force))))
parallelMusic =
-#(define-music-function (parser location voice-ids music) (list? ly:music?)
+#(define-scheme-function (parser location voice-ids music) (list? ly:music?)
(_i "Define parallel music sequences, separated by '|' (bar check signs),
and assign them to the identifiers provided in @var{voice-ids}.
(and (not (null? origins)) (car origins)))))))
;;
;; first, split the music and fill in voices
- (map-in-order (lambda (m)
+ (for-each (lambda (m)
(push-music m)
(if (bar-check? m) (change-voice)))
(ly:music-property music 'elements))
voices)
;;
;; bind voice identifiers to the voices
- (map (lambda (voice-id voice)
+ (for-each (lambda (voice-id voice)
(ly:parser-define! parser voice-id
(make-music 'SequentialMusic
'origin location
'elements voice)))
- voice-ids voices))
- ;; Return an empty sequence. This function is actually a "void" function.
- (make-music 'SequentialMusic 'void #t))
+ voice-ids voices)))
parenthesize =
#(define-music-function (parser loc arg) (ly:music?)
(if (memq 'event-chord (ly:music-property arg 'types))
;; arg is an EventChord -> set the parenthesize property
;; on all child notes and rests
- (map
+ (for-each
(lambda (ev)
(if (or (memq 'note-event (ly:music-property ev 'types))
(memq 'rest-event (ly:music-property ev 'types)))
partcombineAutomatic = \partcombineForce ##f ##f
partcombineAutomaticOnce = \partcombineForce ##f ##t
+partial =
+#(define-music-function (parser location dur) (ly:duration?)
+ (_i "Make a partial measure.")
+
+ ;; We use `descend-to-context' here instead of `context-spec-music' to
+ ;; ensure \partial still works if the Timing_translator is moved
+ (descend-to-context
+ (context-spec-music (make-music 'PartialSet
+ 'origin location
+ 'partial-duration dur)
+ 'Timing)
+ 'Score))
pitchedTrill =
#(define-music-function
music))
resetRelativeOctave =
-#(define-music-function (parser location reference-note) (ly:music?)
+#(define-music-function (parser location pitch) (ly:pitch?)
(_i "Set the octave inside a \\relative section.")
- (let* ((notes (ly:music-property reference-note 'elements))
- (pitch (ly:music-property (car notes) 'pitch)))
-
- (set! (ly:music-property reference-note 'elements) '())
- (set! (ly:music-property reference-note 'to-relative-callback)
- (lambda (music last-pitch)
- pitch))
-
- reference-note))
+ (make-music 'SequentialMusic
+ 'to-relative-callback
+ (lambda (music last-pitch) pitch)))
retrograde =
#(define-music-function (parser location music)
#(define-music-function (parser location finger) (number-or-string?)
(_i "Apply @var{finger} as a fingering indication.")
- (apply make-music
- (append
- (list
- 'StrokeFingerEvent
- 'origin location)
- (if (string? finger)
- (list 'text finger)
- (list 'digit finger)))))
-
-
+ (make-music
+ 'StrokeFingerEvent
+ 'origin location
+ (if (string? finger) 'text 'digit)
+ finger))
scaleDurations =
#(define-music-function (parser location fraction music)
(lambda (x)
(shift-one-duration-log x dur dots)) arg))
+skip =
+#(define-music-function (parser location dur) (ly:duration?)
+ (_i "Skip forward by @var{dur}.")
+ (make-music 'SkipMusic
+ 'duration dur))
+
+
slashedGrace =
#(def-grace-function startSlashedGraceMusic stopSlashedGraceMusic
(_i "Create slashed graces (slashes through stems, but no slur) from
(ly:music-property arg 'tags)))
arg)
+transpose =
+#(define-music-function
+ (parser location from to music)
+ (ly:pitch? ly:pitch? ly:music?)
+
+ (_i "Transpose @var{music} from pitch @var{from} to pitch @var{to}.")
+ (make-music 'TransposedMusic
+ 'element (ly:music-transpose music (ly:pitch-diff to from))))
+
transposedCueDuring =
#(define-music-function
- (parser location what dir pitch-note main-music)
- (string? ly:dir? ly:music? ly:music?)
+ (parser location what dir pitch main-music)
+ (string? ly:dir? ly:pitch? ly:music?)
(_i "Insert notes from the part @var{what} into a voice called @code{cue},
-using the transposition defined by @var{pitch-note}. This happens
+using the transposition defined by @var{pitch}. This happens
simultaneously with @var{main-music}, which is usually a rest. The
argument @var{dir} determines whether the cue notes should be notated
as a first or second voice.")
'quoted-context-id "cue"
'quoted-music-name what
'quoted-voice-direction dir
- 'quoted-transposition (pitch-of-note pitch-note)))
+ 'quoted-transposition pitch))
transposition =
-#(define-music-function (parser location pitch-note) (ly:music?)
+#(define-music-function (parser location pitch) (ly:pitch?)
(_i "Set instrument transposition")
(context-spec-music
(make-property-set 'instrumentTransposition
- (ly:pitch-negate (pitch-of-note pitch-note)))
+ (ly:pitch-negate pitch))
'Staff))
tweak =
#(define-music-function (parser location dash-fraction dash-period)
(number? number?)
(_i "Set up a custom style of dash pattern for @var{dash-fraction} ratio of
-line to space repeated at @var{dash-period} interval.")
+line to space repeated at @var{dash-period} interval for phrasing slurs.")
#{
\override PhrasingSlur #'dash-definition =
$(make-simple-dash-definition dash-fraction dash-period)
slurDashPattern =
#(define-music-function (parser location dash-fraction dash-period)
(number? number?)
+ (_i "Set up a custom style of dash pattern for @var{dash-fraction}
+ratio of line to space repeated at @var{dash-period} interval for slurs.")
#{
\override Slur #'dash-definition =
$(make-simple-dash-definition dash-fraction dash-period)
tieDashPattern =
#(define-music-function (parser location dash-fraction dash-period)
(number? number?)
+ (_i "Set up a custom style of dash pattern for @var{dash-fraction}
+ratio of line to space repeated at @var{dash-period} interval for ties.")
#{
\override Tie #'dash-definition =
$(make-simple-dash-definition dash-fraction dash-period)
+# We can't print the list in one go, as it might be longer than a
+# shell command is allowed (as of linux 2.6.3x >131000 chars)
+# Split it up into 10 300-element chunks, and one chunk containing the rest
+# if we have more than 3000 elements.
$(outdir)/collated-files.list: $(COLLATED_FILES)
echo "(Re-)Generating $@"
- # We can't print the list in one go, as it might be longer than a
- # shell command is allowed (as of linux 2.6.3x >131000 chars)
@echo $(wordlist 1, 299,$^)>$@
@echo $(wordlist 300, 599,$^)>>$@
@echo $(wordlist 600, 899,$^)>>$@
@echo $(wordlist 2100,2399,$^)>>$@
@echo $(wordlist 2400,2699,$^)>>$@
@echo $(wordlist 2700,2999,$^)>>$@
- # Print the rest, just in case the list is that long
- echo $(wordlist 3000,$(words $^),$^)>>$@
+ @echo $(wordlist 3000,$(words $^),$^)>>$@
$(outdir)/collated-files.tely: $(outdir)/collated-files.list
$(LYS_TO_TELY) --name=$(outdir)/collated-files.tely --title="$(TITLE)" --author="$(AUTHOR)" --input-filename=$^
TEXI2HTML_PROGRAM=$(HOME)/usr/bin/texi2html
EXAMPLES=$(HOME)/lilypond/media/ly-examples
PICTURES=$(HOME)/lilypond/media/pictures
+ PYTHON=python
+ PYTHONPATH=$(TRUSTED_DIR)
else
### for normal git
script-dir=$(top-src-dir)/scripts/build
quiet-flag=-q
endif
-
-
################################################################
OUT=out-website
-### only update this when the language compiles correctly!
-# LANGUAGES = (site, cs, de, es, fr, hu, it, ja, nl, zh)
-#WEB_LANGS = de es fr hu it ja nl zh cs
-WEB_LANGS = cs de es fr hu it ja nl zh
+WEB_LANGS = $(shell MAKEWEB=1 $(PYTHON) $(top-src-dir)/python/langdefs.py)
TEXI2HTML=ONLY_WEB=1 TOP_SRC_DIR=$(top-src-dir) DEPTH=$(depth) PERL_UNICODE=SD $(TEXI2HTML_PROGRAM)
FETA_MF_FILES = $(call src-wildcard,feta[0-9]*.mf) \
$(call src-wildcard,feta-braces-[a-z].mf) \
$(call src-wildcard,feta-alphabet*[0-9].mf) \
- $(call src-wildcard,feta-notehead*[0-9].mf) \
+ $(call src-wildcard,feta-noteheads*[0-9].mf) \
$(call src-wildcard,feta-flags*[0-9].mf) \
- $(call src-wildcard,parmesan[0-9]*.mf)
+ $(call src-wildcard,parmesan[0-9]*.mf) \
+ $(call src-wildcard,parmesan-noteheads*[0-9].mf)
STAFF_SIZES = 11 13 14 16 18 20 23 26
BRACES = a b c d e f g h i
$(outdir)/feta-flags%.pfb \
$(outdir)/feta-alphabet%.pfb \
$(outdir)/parmesan%.pfb \
+ $(outdir)/parmesan-noteheads%.pfb \
$(outdir)/feta%.otf-table \
$(outdir)/feta%.otf-gtable
cd $(outdir) && $(FONTFORGE) -script $(notdir $(basename ,$@).pe)
$(outdir)/%.otf-table: $(outdir)/%.lisp
cat $< $(if $(findstring brace,$<),,$(subst feta,parmesan,$<)) \
+ $(if $(findstring brace,$<),,$(subst feta,parmesan-noteheads,$<)) \
$(if $(findstring brace,$<),,$(subst feta,feta-noteheads,$<)) \
$(if $(findstring brace,$<),,$(subst feta,feta-flags,$<)) \
$(if $(findstring brace,$<),,$(subst feta,feta-alphabet,$<)) > $@
$(outdir)/feta-noteheads26.lisp \
$(outdir)/feta-flags26.lisp \
$(outdir)/parmesan26.lisp \
+ $(outdir)/parmesan-noteheads26.lisp \
$(outdir)/feta-alphabet26.lisp
$(outdir)/feta23.otf-table: $(outdir)/feta23.lisp \
$(outdir)/feta-noteheads23.lisp \
$(outdir)/feta-flags23.lisp \
$(outdir)/parmesan23.lisp \
+ $(outdir)/parmesan-noteheads23.lisp \
$(outdir)/feta-alphabet23.lisp
$(outdir)/feta20.otf-table: $(outdir)/feta20.lisp \
$(outdir)/feta-noteheads20.lisp \
$(outdir)/feta-flags20.lisp \
$(outdir)/parmesan20.lisp \
+ $(outdir)/parmesan-noteheads20.lisp \
$(outdir)/feta-alphabet20.lisp
$(outdir)/feta18.otf-table: $(outdir)/feta18.lisp \
$(outdir)/feta-noteheads18.lisp \
$(outdir)/feta-flags18.lisp \
$(outdir)/parmesan18.lisp \
+ $(outdir)/parmesan-noteheads18.lisp \
$(outdir)/feta-alphabet18.lisp
$(outdir)/feta16.otf-table: $(outdir)/feta16.lisp \
$(outdir)/feta-noteheads16.lisp \
$(outdir)/feta-flags16.lisp \
$(outdir)/parmesan16.lisp \
+ $(outdir)/parmesan-noteheads16.lisp \
$(outdir)/feta-alphabet16.lisp
$(outdir)/feta14.otf-table: $(outdir)/feta14.lisp \
$(outdir)/feta-noteheads14.lisp \
$(outdir)/feta-flags14.lisp \
$(outdir)/parmesan14.lisp \
+ $(outdir)/parmesan-noteheads14.lisp \
$(outdir)/feta-alphabet14.lisp
$(outdir)/feta13.otf-table: $(outdir)/feta13.lisp \
$(outdir)/feta-noteheads13.lisp \
$(outdir)/feta-flags13.lisp \
$(outdir)/parmesan13.lisp \
+ $(outdir)/parmesan-noteheads13.lisp \
$(outdir)/feta-alphabet13.lisp
$(outdir)/feta11.otf-table: $(outdir)/feta11.lisp \
$(outdir)/feta-noteheads11.lisp \
$(outdir)/feta-flags11.lisp \
$(outdir)/parmesan11.lisp \
+ $(outdir)/parmesan-noteheads11.lisp \
$(outdir)/feta-alphabet11.lisp
$(outdir)/emmentaler-brace.otf: $(outdir)/emmentaler-brace.subfonts \
enddef;
-%
-% dimensions aren't entirely right.
-%
def draw_longa (expr up) =
save stemthick, fudge;
stemthick# = 2 stafflinethickness#;
define_whole_blacker_pixels (stemthick);
- fudge = hround (blot_diameter / 2);
+ % Longas of smaller design sizes should have their lines farther
+ % apart (the overlap with notehead ellipsoid should be smaller).
+ fudge = hround (blot_diameter
+ * min (max (-0.15,
+ (0.9
+ - (20 / (design_size + 4)))),
+ 0.3));
draw_outside_ellipse (1.80, 0, 0.707, 0);
undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#);
+ set_char_box (stemthick#,
+ width# + stemthick#,
+ noteheight# / 2,
+ noteheight# / 2);
+
pickup pencircle scaled stemthick;
+ % Longas of smaller design sizes should have their lines longer.
+ line_length := min (max (0.7, (64/60 - (design_size / 60))), 0.85);
+
+ % Line lengths between 0.72 and 0.77 are not nice
+ % because they are neither separate nor connected
+ % when there is an interval of fourth.
+ if line_length < 0.75:
+ quanted_line_length := min (0.72, line_length);
+ else:
+ quanted_line_length := max (0.77, line_length);
+ fi;
+
+ final_line_length := quanted_line_length * staff_space;
+
if up:
- bot y1 = -d;
- top y2 = h;
+ bot y1 = -final_line_length;
+ top y2 = final_line_length;
rt x1 - fudge = 0;
x1 = x2;
- fudge + lft x3 = w;
+ fudge + lft x3 = width;
x4 = x3;
top y4 = h + 3.0 staff_space;
y3 = y1;
else:
bot y1 = -d - 3.0 staff_space;
- top y2 = h;
+ top y2 = final_line_length;
rt x1 - fudge = 0;
x1 = x2;
- fudge + lft x3 = w;
+ fudge + lft x3 = width;
x4 = x3;
y4 = y2;
- bot y3 = -d;
+ bot y3 = -final_line_length;
fi;
draw_gridline (z1, z2, stemthick);
def draw_brevis (expr linecount, line_thickness_multiplier) =
- save stemthick, fudge;
+ save stemthick, fudge, gap;
stemthick# = line_thickness_multiplier * 2 * stafflinethickness#;
define_whole_blacker_pixels (stemthick);
- % Breves of smaller design sizes should have their lines
- % farther apart (the overlap should be smaller).
+ % double-lined breves of smaller design sizes should have
+ % bigger gap between the lines.
+ gap# := (0.95 - 0.008 * design_size) * stemthick#;
+
+ % Breves of smaller design sizes should have their lines farther
+ % apart (the overlap with notehead ellipsoid should be smaller).
fudge = hround (blot_diameter
* min (max (-0.15,
(0.8
draw_outside_ellipse (1.80, 0, 0.707, 0);
undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#);
+ set_char_box (stemthick# * linecount + gap# * (linecount - 1),
+ width# + stemthick# * linecount + gap# * (linecount - 1),
+ noteheight# / 2,
+ noteheight# / 2);
+
+ define_pixels (gap);
pickup pencircle scaled stemthick;
% Breves of smaller design sizes should have their lines longer.
rt x1 - fudge = 0;
x1 = x2;
- fudge + lft x3 = w;
+ fudge + lft x3 = width;
x4 = x3;
y4 = y2;
y3 = y1;
- % Breves of smaller design sizes should have their lines
- % farther apart.
- line_distance := (1.95 - 0.008 * design_size) * stemthick;
for i := 0 step 1 until linecount - 1:
- draw_gridline (z1 - (i * line_distance, 0),
- z2 - (i * line_distance, 0),
+ line_distance := i * (gap + stemthick);
+ draw_gridline (z1 - (line_distance, 0),
+ z2 - (line_distance, 0),
stemthick);
- draw_gridline (z3 + (i * line_distance, 0),
- z4 + (i * line_distance, 0),
+ draw_gridline (z3 + (line_distance, 0),
+ z4 + (line_distance, 0),
stemthick);
endfor;
enddef;
fet_beginfont ("parmesan", design_size, "parmesanMusic");
if test = 0:
input parmesan-rests;
- input parmesan-noteheads;
input parmesan-clefs;
input parmesan-custodes
input parmesan-accidentals;
--- /dev/null
+% Feta (not the Font-En-Tja) music font -- generic stuff: include lots of files
+% This file is part of LilyPond, the GNU music typesetter.
+%
+% Copyright (C) 1997--2011 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/>.
+
+
+if test = -1:
+ mode := smoke;
+fi
+
+staffsize# := design_size * pt#;
+
+mode_setup;
+
+input feta-macros;
+
+input feta-params;
+
+input parmesan-macros;
+
+font_x_height staff_space#;
+
+fet_beginfont ("parmesan", design_size, "parmesanMusic");
+ input parmesan-noteheads;
+fet_endfont;
% Neo-mensural heads originally by
% Christian Mondrup and Mats Bengtsson
%
-%
% 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
%
%
%
-% MENSURAL NOTATION
+% NEO-MENSURAL NOTATION
%
%
%
-def draw_neomensural_brevis (expr brevwid, open, full) =
- save beamheight, head_width;
- save holeheight, stem_width;
- save serif_size, serif_protrude;
+def draw_neomensural_brevis (expr brevwid, holeheight, open, full) =
+ save beamheight, head_width, head_height;
+ save stem_width, serif_size, serif_protrude;
- head_width# = brevwid;
- holeheight = 3 stafflinethickness;
- stem_width = 1.4 stafflinethickness;
+ head_width# := brevwid;
+ head_height# := noteheight#;
+ stem_width := 1.3 linethickness;
- define_pixels (head_width);
+ define_pixels (head_width, head_height);
set_char_box (0, head_width#,
- noteheight# / 2, noteheight# / 2);
+ head_height# / 2, head_height# / 2);
- 2 beamheight + holeheight = noteheight;
- serif_size = (holeheight - stafflinethickness) / 2;
- serif_protrude = 1.5 serif_size;
+ 2 beamheight + holeheight = head_height;
+ serif_size := .75 linethickness;
+ serif_protrude := .15 head_height;
z1l = (0, 0);
- z2l = (0, -stafflinethickness / 2);
+ z2l = (0, - (holeheight - 2 serif_size) / 2);
z3r = z2r + serif_size * (1, -1);
y4r = y3r;
x4r = head_width / 2;
enddef;
-%%% This head does not seem to be used anywhere. Junk me? -- jr
-def draw_neomensural_left_stemmed_head (expr wid) =
- draw_neomensural_brevis (wid, true, true);
-
- x6 = x7 = stem_width / 2;
- y6 = y5;
- y7 = y5 - 2.25 staff_space;
-
- z17 = (x7, y7 - stem_width / 2);
-
- penpos6 (stem_width, 0);
- penpos7 (stem_width, 0);
-
- fill z7l
- -- z6l
- -- z6r
- -- z7r
- .. z17
- .. cycle;
-
- penlabels (6, 7);
- labels (17);
-enddef;
-
-
-%%% This head does not seem to be used anywhere. Junk me? -- jr
-fet_beginchar ("Left stemmed notehead", "slneomensural");
- draw_neomensural_left_stemmed_head (2 staff_space#);
-fet_endchar;
-
-
%
% Some sources (eg. Musix/OpusTeX) think that the appendage should be on
% the left, some say right. Right wins democratically.
%
-def draw_neomensural_longa (expr wid) =
- draw_neomensural_brevis (wid, true, true);
+def draw_neomensural_longa (expr wid, holeheight, direction) =
+ draw_neomensural_brevis (wid, holeheight, true, true);
- save theta;
+ save theta, dir;
+ dir := -direction;
- x7r = head_width;
- y7 = y5;
- z6 - z7 = (stem_width / 2, -staff_space);
- theta = angle (z6 - z7) + 90;
+ x7 = head_width - stem_width / 2;
+ y7 = dir * y5;
+ z6 - z7 = (stem_width / 2, -dir * staff_space);
+ theta = dir * angle (z6 - z7) + 90;
penpos7 (stem_width, 0);
penpos6 (1.2 stem_width, theta);
enddef;
-%
-% En wij presenteren U: de opvolgster van Emily
-%
-% (ze is wel breed)
-%
-fet_beginchar ("Neo-mensural maxima notehead", "sM3neomensural");
- draw_neomensural_longa (2.6 staff_space#);
-fet_endchar;
-
-
-fet_beginchar ("Neo-mensural longa notehead", "sM2neomensural");
- draw_neomensural_longa (2 staff_space#);
-fet_endchar;
-
-
-fet_beginchar ("Neo-mensural brevis notehead", "sM1neomensural");
- draw_neomensural_brevis (2 staff_space#, true, true);
-fet_endchar;
-
-
def draw_neomensural_black_head (expr wid, height) =
- save head_width;
- save ne, nw, ne_dist, nw_dist;
+ save head_height, head_width, stem_width,
+ ne, nw, ne_dist, nw_dist, penthickness;
pair ne, nw, ne_dist, nw_dist;
- head_width# = wid;
+ penthickness# = linethickness#;
+ head_height# := height + penthickness#;
+ head_width# := wid + penthickness#;
+ stem_width# := 1.3 linethickness#;
set_char_box (0, head_width#,
- height / 2, height / 2);
+ head_height# / 2, head_height# / 2);
charwx := head_width# / 2;
- charwy := height / 2;
+ charwy := head_height# / 2 - 2 stem_width#;
+
+ define_pixels (penthickness);
y3 = y1 = 0;
- x2 = x4 = (x1 + x3) / 2;
+ x2 = x4 = 1/2 [x1, x3];
- pickup pencircle scaled blot_diameter;
+ pickup pencircle scaled penthickness;
top y2 = h;
bot y4 = -d;
rt x3 = w;
ne := unitvector (z2 - z1);
- nw_dist := (ne rotated 90) * 0.5 blot_diameter;
+ nw_dist := (ne rotated 90) * penthickness / 2;
nw := unitvector (z2 - z3);
- ne_dist := (nw rotated -90) * 0.5 blot_diameter;
-
- fill lft z1{up}
- .. (z1 + nw_dist){ne}
- -- (z2 + nw_dist){ne}
- .. top z2{right}
- .. (z2 + ne_dist){-nw}
- -- (z3 + ne_dist){-nw}
- .. rt z3{down}
- .. (z3 - nw_dist){-ne}
- -- (z4 - nw_dist){-ne}
- .. bot z4{left}
- .. (z4 - ne_dist){nw}
- -- (z1 - ne_dist){nw}
+ ne_dist := (nw rotated -90) * penthickness / 2;
+
+ fill lft z1
+ .. (z1 + nw_dist)
+ -- (z2 + nw_dist)
+ .. top z2
+ .. (z2 + ne_dist)
+ -- (z3 + ne_dist)
+ .. rt z3
+ .. (z3 - nw_dist)
+ -- (z4 - nw_dist)
+ .. bot z4
+ .. (z4 - ne_dist)
+ -- (z1 - ne_dist)
.. cycle;
labels (1, 2, 3, 4);
def draw_neomensural_open_head (expr wid, height)=
draw_neomensural_black_head (wid, height);
- save diamNW, diamSW;
+ save headNW, headSW, stem_width;
- diamNW = length (z2 - z1) + blot_diameter;
- diamSW = length (z4 - z1) + blot_diameter;
+ headNW = length (z2 - z1) + penthickness;
+ headSW = length (z4 - z1) + penthickness;
+ stem_width = 1.3 linethickness;
save hole_widthNW, hole_widthSW;
- hole_widthNW = 0.34 diamNW ;
- hole_widthSW + 2.6 linethickness = diamSW;
-
- (z7 + z5) / 2 = (w / 2, 0);
- (z8 + z6) / 2 = (w / 2, 0);
- z6 - z5 = hole_widthNW * unitvector (z2 - z1);
- z7 - z6 = hole_widthSW * unitvector (z4 - z1);
-
- unfill z5
- -- z6
- -- z7
- -- z8
- -- cycle;
+ hole_widthNW = .25 headNW;
+ hole_widthSW + 2 stem_width = headSW;
+
+ (rt z7 + lft z5) / 2 = (w / 2, 0);
+ (bot z8 + top z6) / 2 = (w / 2, 0);
+ z6 - z5 = (hole_widthNW - penthickness) * unitvector (z2 - z1);
+ z7 - z6 = (hole_widthSW - penthickness) * unitvector (z4 - z1);
+
+ unfill lft z5
+ .. (z5 + nw_dist)
+ -- (z6 + nw_dist)
+ .. top z6
+ .. (z6 + ne_dist)
+ -- (z7 + ne_dist)
+ .. rt z7
+ .. (z7 - nw_dist)
+ -- (z8 - nw_dist)
+ .. bot z8
+ .. (z8 - ne_dist)
+ -- (z5 - ne_dist)
+ .. cycle;
labels (5, 6, 7, 8);
enddef;
%
-% WL says the thin lines should be thinner.
+% Neo-mensural maxima/longa/brevis
%
-fet_beginchar ("Harmonic notehead (Neo-mensural open)", "s0harmonic");
- draw_neomensural_open_head (1.3 staff_space#, 1.3 noteheight#);
- charwx := head_width#;
- charwy := 0;
+% En wij presenteren U: de opvolgster van Emily
+%
+% (ze is wel breed)
+%
+
+save nm_maxima_width, nm_longa_width, nm_brevis_width,
+ nm_holeheight, nm_red_holeheight;
+nm_maxima_width := 2.6 staff_space#;
+nm_longa_width := 2 staff_space#;
+nm_brevis_width := nm_longa_width;
+nm_holeheight := 4 linethickness;
+nm_red_holeheight := 2.5 linethickness;
+
+fet_beginchar ("Neo-mensural maxima notehead (up)", "uM3neomensural");
+ draw_neomensural_longa (nm_maxima_width, nm_holeheight, 1);
fet_endchar;
+fet_beginchar ("Neo-mensural maxima notehead (down)", "dM3neomensural");
+ draw_neomensural_longa (nm_maxima_width, nm_holeheight, -1);
+fet_endchar;
-fet_beginchar ("Harmonic notehead (Neo-mensural black)", "s2harmonic");
- draw_neomensural_black_head (1.3 staff_space#, 1.3 noteheight#);
- charwx := head_width#;
- charwy := 0;
+fet_beginchar ("Neo-mensural longa notehead (up)", "uM2neomensural");
+ draw_neomensural_longa (nm_longa_width, nm_holeheight, 1);
fet_endchar;
+fet_beginchar ("Neo-mensural longa notehead (down)", "dM2neomensural");
+ draw_neomensural_longa (nm_longa_width, nm_holeheight, -1);
+fet_endchar;
-fet_beginchar ("Neo-mensural semibrevis head", "s0neomensural");
- draw_neomensural_open_head (staff_space#, noteheight#);
+fet_beginchar ("Neo-mensural brevis notehead", "sM1neomensural");
+ draw_neomensural_brevis (nm_brevis_width, nm_holeheight, true, true);
+fet_endchar;
+
+fet_beginchar ("Neo-mensural maxima notehead (up, reduced hole)", "urM3neomensural");
+ draw_neomensural_longa (nm_maxima_width, nm_red_holeheight, 1);
fet_endchar;
+fet_beginchar ("Neo-mensural maxima notehead (down, reduced hole)", "drM3neomensural");
+ draw_neomensural_longa (nm_maxima_width, nm_red_holeheight, -1);
+fet_endchar;
-fet_beginchar ("Neo-mensural minima head", "s1neomensural");
- draw_neomensural_open_head (staff_space#, noteheight#);
+fet_beginchar ("Neo-mensural longa notehead (up, reduced hole)", "urM2neomensural");
+ draw_neomensural_longa (nm_longa_width, nm_red_holeheight, 1);
fet_endchar;
+fet_beginchar ("Neo-mensural longa notehead (down, reduced hole)", "drM2neomensural");
+ draw_neomensural_longa (nm_longa_width, nm_red_holeheight, -1);
+fet_endchar;
-fet_beginchar ("Neo-mensural semiminima head", "s2neomensural");
- draw_neomensural_black_head (staff_space#, noteheight#);
+fet_beginchar ("Neo-mensural brevis notehead (reduced hole)", "srM1neomensural");
+ draw_neomensural_brevis (nm_brevis_width, nm_red_holeheight, true, true);
fet_endchar;
-def draw_mensural_brevis (expr wid, open, full) =
- % TODO. For the moment, fall back to draw_neomensural_brevis.
- draw_neomensural_brevis (wid, open, full);
-enddef;
+%
+% Neo-mensural semibrevis/minima/semiminima
+%
+save nm_height, nm_width;
+nm_height := noteheight#;
+nm_width := staff_space#;
+fet_beginchar ("Neo-mensural semibrevis head", "s0neomensural");
+ draw_neomensural_open_head (nm_width, nm_height);
+fet_endchar;
-%%% This head does not seem to be used anywhere. Junk me? -- jr
-def draw_mensural_left_stemmed_head (expr wid, open, full) =
- draw_mensural_brevis (wid, open, full);
+fet_beginchar ("Neo-mensural minima head", "s1neomensural");
+ draw_neomensural_open_head (nm_width, nm_height);
+fet_endchar;
- x6 = x7 = stem_width / 2;
- y6 = y5;
- y7 = y5 - 2.25 staff_space;
+fet_beginchar ("Neo-mensural semiminima head", "s2neomensural");
+ draw_neomensural_black_head (nm_width, nm_height);
+fet_endchar;
- z17 = (x7, y7 - stem_width / 2);
+%%%%%%%%
+%
+%
+%
+% HARMONIC NOTATION
+%
+%
+%
- penpos6 (stem_width, 0);
- penpos7 (stem_width, 0);
+%
+% WL says the thin lines should be thinner.
+%
- fill z7l
- -- z6l
- -- z6r
- -- z7r
- .. z17
- .. cycle;
+fet_beginchar ("Harmonic notehead (Neo-mensural open)", "s0harmonic");
+ draw_neomensural_open_head (1.3 staff_space#, 1.3 noteheight#);
+ charwx := head_width#;
+ charwy := 0;
+fet_endchar;
- penlabels (6, 7);
- labels (17);
+fet_beginchar ("Harmonic notehead (Neo-mensural black)", "s2harmonic");
+ draw_neomensural_black_head (1.3 staff_space#, 1.3 noteheight#);
+ charwx := head_width#;
+ charwy := 0;
+fet_endchar;
+
+
+%%%%%%%%
+%
+%
+%
+% MENSURAL/PETRUCCI NOTATIONS
+%
+%
+%
+
+def draw_mensural_brevis (expr wid, holeheight, open, full) =
+ % TODO. For the moment, fall back to draw_neomensural_brevis.
+ draw_neomensural_brevis (wid, holeheight, open, full);
enddef;
-def draw_mensural_longa (expr wid, open, full) =
- draw_mensural_brevis (wid, open, full);
+def draw_mensural_longa (expr wid, holeheight, open, full, direction) =
+ draw_mensural_brevis (wid, holeheight, open, full);
+
+ save dir;
+ dir := -direction;
x6 = x7 = head_width - stem_width / 2;
- y6 = y5;
- y7 = y5 - 2.25 staff_space;
+ y6 = dir * y5;
+ y7 = dir * y5 -1.75 dir * staff_space;
- z17 = (x7, y7 - stem_width / 2);
+ z17 = (x7, y7 - dir * stem_width / 2);
penpos6 (stem_width, 0);
- penpos7 (stem_width, 0);
+ penpos7 (1.5 stem_width, 0);
fill z7l
-- z6l
enddef;
-%%% This head does not seem to be used anywhere. Junk me? -- jr
-fet_beginchar ("Mensural left stemmed notehead", "slmensural");
- draw_mensural_left_stemmed_head (staff_space#, true, true);
-fet_endchar;
-
-
-fet_beginchar ("Mensural maxima notehead", "sM3mensural");
- draw_mensural_longa (2.0 staff_space#, true, true);
-fet_endchar;
-
-
-fet_beginchar ("Mensural maxima notehead in ligaturae", "sM3ligmensural");
- draw_mensural_brevis (2.0 staff_space#, true, true);
-fet_endchar;
-
-
-fet_beginchar ("Mensural longa notehead", "sM2mensural");
- draw_mensural_longa (staff_space#, true, true);
-fet_endchar;
-
-
-fet_beginchar ("Mensural brevis notehead", "sM1mensural");
- draw_mensural_brevis (staff_space#, true, true);
-fet_endchar;
-
-
-fet_beginchar ("Black mensural maxima notehead", "sM3blackmensural");
- draw_mensural_longa (2.0 staff_space#, false, false);
-fet_endchar;
-
-
-fet_beginchar ("Black mensural maxima notehead in ligaturae", "sM3blackligmensural");
- draw_mensural_brevis (2.0 staff_space#, false, false);
-fet_endchar;
-
-
-fet_beginchar ("Black mensural longa notehead", "sM2blackmensural");
- draw_mensural_longa (staff_space#, false, false);
-fet_endchar;
-
-
-fet_beginchar ("Black mensural brevis notehead", "sM1blackmensural");
- draw_mensural_brevis (staff_space#, false, false);
-fet_endchar;
-
-
-fet_beginchar ("Semi-colored mensural maxima notehead", "sM3semimensural");
- draw_mensural_longa (2.0 staff_space#, true, false);
-fet_endchar;
-
-
-fet_beginchar ("Semi-colored mensural maxima notehead in ligaturae", "sM3semiligmensural");
- draw_mensural_brevis (2.0 staff_space#, true, false);
-fet_endchar;
-
-
-fet_beginchar ("Semi-colored mensural longa notehead", "sM2semimensural");
- draw_mensural_longa (staff_space#, true, false);
-fet_endchar;
-
-
-fet_beginchar ("Semi-colored mensural brevis notehead", "sM1semimensural");
- draw_mensural_brevis (staff_space#, true, false);
-fet_endchar;
-
-
def draw_diamond_head (expr head_h, pen_w, pen_h, angle, open) =
save head_width, head_height;
save ellipse, ellipse_r;
head_height# / 2, head_height# / 2);
charwx := head_width# / 2;
- charwy := head_height# / 2 - linethickness#;
+ charwy := head_height# / 2 - 2 linethickness#;
define_pixels (head_width, head_height);
enddef;
+%
+% Mensural/Petrucci maxima/longa/brevis
+%
+
+save m_maxima_width, m_longa_width, m_brevis_width,
+ m_holeheight, m_red_holeheight;
+m_maxima_width := 2.0 staff_space#;
+m_longa_width := staff_space#;
+m_brevis_width := m_longa_width;
+m_holeheight := nm_holeheight;
+m_red_holeheight := nm_red_holeheight;
+
+fet_beginchar ("Mensural maxima notehead (up)", "uM3mensural");
+ draw_mensural_longa (m_maxima_width, m_holeheight, true, true, 1);
+fet_endchar;
+
+fet_beginchar ("Mensural maxima notehead (down)", "dM3mensural");
+ draw_mensural_longa (m_maxima_width, m_holeheight, true, true, -1);
+fet_endchar;
+
+fet_beginchar ("Mensural maxima notehead (ligature)", "sM3ligmensural");
+ draw_mensural_brevis (m_maxima_width, m_holeheight, true, true);
+fet_endchar;
+
+fet_beginchar ("Mensural longa notehead (up)", "uM2mensural");
+ draw_mensural_longa (m_longa_width, m_holeheight, true, true, 1);
+fet_endchar;
+
+fet_beginchar ("Mensural longa notehead (down)", "dM2mensural");
+ draw_mensural_longa (m_longa_width, m_holeheight, true, true, -1);
+fet_endchar;
+
+fet_beginchar ("Mensural brevis notehead", "sM1mensural");
+ draw_mensural_brevis (m_brevis_width, m_holeheight, true, true);
+fet_endchar;
+
+fet_beginchar ("Mensural maxima notehead (up, reduced hole)", "urM3mensural");
+ draw_mensural_longa (m_maxima_width, m_red_holeheight, true, true, 1);
+fet_endchar;
+
+fet_beginchar ("Mensural maxima notehead (down, reduced hole)", "drM3mensural");
+ draw_mensural_longa (m_maxima_width, m_red_holeheight, true, true, -1);
+fet_endchar;
+
+fet_beginchar ("Mensural maxima notehead (ligature, reduced hole)", "srM3ligmensural");
+ draw_mensural_brevis (m_maxima_width, m_red_holeheight, true, true);
+fet_endchar;
+
+fet_beginchar ("Mensural longa notehead (up, reduced hole)", "urM2mensural");
+ draw_mensural_longa (m_longa_width, m_red_holeheight, true, true, 1);
+fet_endchar;
+
+fet_beginchar ("Mensural longa notehead (down, reduced hole)", "drM2mensural");
+ draw_mensural_longa (m_longa_width, m_red_holeheight, true, true, -1);
+fet_endchar;
+
+fet_beginchar ("Mensural brevis notehead (reduced hole)", "srM1mensural");
+ draw_mensural_brevis (m_brevis_width, m_red_holeheight, true, true);
+fet_endchar;
+
+
+%
+% Semi-colored mensural/Petrucci maxima/longa/brevis
+%
+
+fet_beginchar ("Semi-colored mensural maxima notehead (up)", "uM3semimensural");
+ draw_mensural_longa (m_maxima_width, m_holeheight, true, false, 1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural maxima notehead (down)", "dM3semimensural");
+ draw_mensural_longa (m_maxima_width, m_holeheight, true, false, -1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural maxima notehead (ligature)", "sM3semiligmensural");
+ draw_mensural_brevis (m_maxima_width, m_holeheight, true, false);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural longa notehead (up)", "uM2semimensural");
+ draw_mensural_longa (m_longa_width, m_holeheight, true, false, 1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural longa notehead (down)", "dM2semimensural");
+ draw_mensural_longa (m_longa_width, m_holeheight, true, false, -1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural brevis notehead", "sM1semimensural");
+ draw_mensural_brevis (m_brevis_width, m_holeheight, true, false);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural maxima notehead (up, reduced hole)", "urM3semimensural");
+ draw_mensural_longa (m_maxima_width, m_red_holeheight, true, false, 1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural maxima notehead (down, reduced hole)", "drM3semimensural");
+ draw_mensural_longa (m_maxima_width, m_red_holeheight, true, false, -1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural maxima notehead (ligature, reduced hole)", "srM3semiligmensural");
+ draw_mensural_brevis (m_maxima_width, m_red_holeheight, true, false);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural longa notehead (up, reduced hole)", "urM2semimensural");
+ draw_mensural_longa (m_longa_width, m_red_holeheight, true, false, 1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural longa notehead (down, reduced hole)", "drM2semimensural");
+ draw_mensural_longa (m_longa_width, m_red_holeheight, true, false, -1);
+fet_endchar;
+
+fet_beginchar ("Semi-colored mensural brevis notehead (reduced hole)", "srM1semimensural");
+ draw_mensural_brevis (m_brevis_width, m_red_holeheight, true, false);
+fet_endchar;
+
+
+%
+% Black mensural/Petrucci maxima/longa/brevis
+%
+
+fet_beginchar ("Black mensural maxima notehead (up)", "uM3blackmensural");
+ draw_mensural_longa (m_maxima_width, 0, false, false, 1);
+fet_endchar;
+
+fet_beginchar ("Black mensural maxima notehead (down)", "dM3blackmensural");
+ draw_mensural_longa (m_maxima_width, 0, false, false, -1);
+fet_endchar;
+
+fet_beginchar ("Black mensural maxima notehead (ligature)", "sM3blackligmensural");
+ draw_mensural_brevis (m_maxima_width, 0, false, false);
+fet_endchar;
+
+fet_beginchar ("Black mensural longa notehead (up)", "uM2blackmensural");
+ draw_mensural_longa (m_longa_width, 0, false, false, 1);
+fet_endchar;
+
+fet_beginchar ("Black mensural longa notehead (down)", "dM2blackmensural");
+ draw_mensural_longa (m_longa_width, 0, false, false, -1);
+fet_endchar;
+
+fet_beginchar ("Black mensural brevis notehead", "sM1blackmensural");
+ draw_mensural_brevis (m_brevis_width, 0, false, false);
+fet_endchar;
+
+
+%
+% Mensural semibrevis/minima/semiminima
+%
+
fet_beginchar ("Mensural semibrevis head", "s0mensural");
draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
fet_endchar;
-
fet_beginchar ("Mensural minima head", "s1mensural");
draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
fet_endchar;
-
fet_beginchar ("Mensural semiminima head", "s2mensural");
draw_diamond_head (staff_space#, 0.15, 0.30, 30, false);
fet_endchar;
+%
+% Black mensural semibrevis/minima/semiminima
+%
+
fet_beginchar ("Black mensural semibrevis head", "s0blackmensural");
draw_diamond_head (staff_space#, 0.15, 0.30, 30, false);
fet_endchar;
+%
+% Petrucci semibrevis/minima/semiminima
+%
+% These values can be measured in several sources.
+% I used "Modulis ex sacris literis delecti, Liber primus"
+% Josquin Desprez, BNF
+
+save petrucci_width, petrucci_height;
+petrucci_height := 1.3 noteheight#;
+petrucci_width := .72 petrucci_height;
+
fet_beginchar ("Petrucci semibrevis head", "s0petrucci");
-% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
- draw_neomensural_open_head (staff_space#, 1.8 staff_space#);
+ draw_neomensural_open_head (petrucci_width, petrucci_height);
fet_endchar;
-
fet_beginchar ("Petrucci minima head", "s1petrucci");
-% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
- draw_neomensural_open_head (staff_space#, 1.8 staff_space#);
+ draw_neomensural_open_head (petrucci_width, petrucci_height);
fet_endchar;
-
fet_beginchar ("Petrucci semiminima head", "s2petrucci");
-% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, false);
- draw_neomensural_black_head (staff_space#, 1.8 staff_space#);
+ draw_neomensural_black_head (petrucci_width, petrucci_height);
fet_endchar;
+%
+% Black Petrucci semibrevis/minima/semiminima
+%
+
fet_beginchar ("Petrucci colored semibrevis head", "s0blackpetrucci");
-% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
- draw_neomensural_black_head (staff_space#, 1.8 staff_space#);
+ draw_neomensural_black_head (petrucci_width, petrucci_height);
fet_endchar;
-
fet_beginchar ("Petrucci colored minima head", "s1blackpetrucci");
-% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
- draw_neomensural_black_head (staff_space#, 1.8 staff_space#);
+ draw_neomensural_black_head (petrucci_width, petrucci_height);
fet_endchar;
-
fet_beginchar ("Petrucci colored semiminima head", "s2blackpetrucci");
-% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
- draw_neomensural_black_head (staff_space#, 1.8 staff_space#);
+ draw_neomensural_black_head (petrucci_width, petrucci_height);
fet_endchar;
--- /dev/null
+% feta-noteheads11.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 11.22;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
--- /dev/null
+% feta-noteheads13.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 12.60;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
--- /dev/null
+% feta-noteheads14.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 14.14;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
--- /dev/null
+% feta-noteheads16.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 15.87;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
--- /dev/null
+% feta-noteheads18.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 17.82;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
--- /dev/null
+% feta-noteheads20.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 20;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
--- /dev/null
+% feta-noteheads23.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 22.45;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
--- /dev/null
+% feta-noteheads26.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 25.20;
+test := 0;
+
+
+input parmesan-noteheads-generic;
+
+end.
+
def basename (self):
cs = self.get_checksum ()
- name = '%s/lily-%s' % (cs[:2], cs[2:])
+ name = os.path.join (cs[:2], 'lily-%s' % cs[2:])
return name
final_basename = basename
# (please run 'make doc-clean' before doing that):
#fr.enabled = False
-# LANGUAGES = (site, cs, de, es, fr, hu, it, ja, nl, zh)
LANGUAGES = (site, cs, de, es, fr, hu, it, ja, nl, zh)
+WEB_LANGUAGES = (site, cs, de, es, fr, hu, it, ja, nl, zh)
+
+if os.getenv("MAKEWEB") == '1':
+ LANGUAGES=WEB_LANGUAGES
if __name__ == '__main__':
print ' '.join ([l.code for l in LANGUAGES if l.enabled and l.code != 'en'])
attributes._dict = attr._dict.copy ()
attributes._original_tag = attr
# copy only the relevant children over for the given staff
+ if staff == "None":
+ staff = "1"
for c in attr._children:
if (not (hasattr (c, 'number') and (c.number != staff)) and
not (isinstance (c, Hash_text))):
if voice_id:
vid = voice_id.get_text ()
elif isinstance (n, Note):
+ # TODO: Check whether we shall really use "None" here, or
+ # rather use "1" as the default?
vid = "None"
staff_id = n.get_maybe_exist_named_child (u'staff')
if staff_id:
sid = staff_id.get_text ()
else:
+ # TODO: Check whether we shall really use "None" here, or
+ # rather use "1" as the default?
+ # If this is changed, need to change the corresponding
+ # check in extract_attributes_for_staff, too.
sid = "None"
if vid and not voices.has_key (vid):
voices[vid] = Musicxml_voice()
(alist (map chord-to-exception-entry elts)))
(filter (lambda (x) (cdr x)) alist)))
-(define-public (capo-handler pitches bass inversion context)
- (let ((chord-function
- (ly:context-property context 'chordNameFunction 'jazz-chord-names))
- (capo-pitch (ly:context-property context 'capoPitch #f)))
- (if (not capo-pitch)
- (chord-function pitches bass inversion context) ;; call the chordNameFunction as of old
- (let* ((new-pitches ;; else transpose the pitches and do the chord twice
- (map (lambda (p)
- (ly:pitch-transpose p capo-pitch))
- pitches))
- (new-bass
- (if (ly:pitch? bass)
- (ly:pitch-transpose bass capo-pitch)
- '()))
- (new-inversion
- (if (ly:pitch? inversion)
- (ly:pitch-transpose inversion capo-pitch)
- '()))
- (capo-markup
- (make-parenthesize-markup
- (chord-function new-pitches new-bass new-inversion context)))
- (name-markup (chord-function pitches bass inversion context))
- (capo-vertical (ly:context-property context 'capoVertical #f)))
- (if capo-vertical
- (make-column-markup (list name-markup capo-markup))
- (make-line-markup (list name-markup
- (make-hspace-markup 1)
- capo-markup)))))))
(beatStructure ,list? "List of @code{baseMoment}s that are combined
to make beats.")
- (capoPitch ,ly:pitch? "The pitch to transpose chords down by when using the capo.")
- (capoVertical ,boolean? "Whether to display actual and transposed pitches above each other or not.")
(chordChanges ,boolean? "Only show changes in chords scheme?")
(chordNameExceptions ,list? "An alist of chord exceptions.
Contains @code{(@var{chord} . @var{markup})} entries.")
(break-visibility . ,begin-of-line-visible)
(direction . ,UP)
+ (extra-spacing-width . (+inf.0 . -inf.0))
(font-family . roman)
(font-size . -2)
(non-musical . #t)
(key-signature . (extra-space . 0.5))
(cue-clef . (extra-space . 0.5))
(right-edge . (extra-space . 0.5))
- (first-note . (semi-fixed-space . 2.5))))
+ (first-note . (fixed-space . 2.5))))
(stencil . ,ly:key-signature-interface::print)
- (extra-spacing-width . (0.0 . 0.5))
+ (extra-spacing-width . (0.0 . 1.0))
(Y-offset . ,ly:staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
(staff-bar . (extra-space . 1.1))
(cue-clef . (extra-space . 0.5))
(right-edge . (extra-space . 0.5))
- (first-note . (semi-fixed-space . 2.5))))
+ (first-note . (fixed-space . 2.5))))
(stencil . ,ly:key-signature-interface::print)
- (extra-spacing-width . (0.0 . 0.5))
+ (extra-spacing-width . (0.0 . 1.0))
(Y-offset . ,ly:staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
(MensuralLigature
. (
(stencil . ,ly:mensural-ligature::print)
- (thickness . 1.4)
+ (thickness . 1.3)
(meta . ((class . Spanner)
(interfaces . (font-interface
mensural-ligature-interface))))))
(break-align-anchor-alignment . ,LEFT)
(break-visibility . ,all-visible)
(extra-spacing-height . (-1.0 . 1.0))
+ (extra-spacing-width . (0.0 . 0.8))
(non-musical . #t)
(space-alist . (
(cue-clef . (extra-space . 1.5))
- (first-note . (semi-fixed-space . 2.0))
+ (first-note . (fixed-space . 2.0))
(right-edge . (extra-space . 0.5))
(staff-bar . (minimum-space . 2.0))))
(stencil . ,ly:time-signature::print)
"
name-sym
name-sym
- (if (pair? docstring) (cadar docstring) "(undocumented; fixme)")
+ (if (pair? docstring)
+ (cadar docstring)
+ (begin
+ (ly:warning "context modification `~a' not documented." name-sym)
+ "(undocumented; fixme)"))
(map document-mod-list mod-list))))
(define (document-mod obj-pair)
(doc (procedure-documentation func))
(sign (object-property func 'music-function-signature))
(type-names (map type-name sign))
-
(signature-str
(string-join
(map (lambda (x) (format #f "@var{~a} (~a)"
(car x)
(cadr x)))
- (zip arg-names type-names)))))
+ (zip arg-names (cdr type-names))))))
(format #f
- "@item @code{~a}~a~a
-@findex ~a
+ "@item @code{~a} (~a) ~a~a
+@funindex ~a
~a
"
- name-sym (if (equal? "" signature-str) "" " - ") signature-str
+ name-sym (car type-names)
+ (if (equal? "" signature-str) "" " - ") signature-str
name-sym
- (if doc doc "(undocumented; fixme)"))))
+ (if doc
+ doc
+ (begin
+ (ly:warning "music function `~a' not documented." name-sym)
+ "(undocumented; fixme)")))))
(define (document-object obj-pair)
(ly:set-option 'debug-gc-assert-parsed-dead #f)
(if (ly:get-option 'debug-gc)
(dump-gc-protects)
- (ly:reset-all-fonts))))
+ (ly:reset-all-fonts))
+ (flush-all-ports)))
files)
;; Ensure a notice re failed files is written to aggregate logfile.
m)))
;; Music function: Apply function and check return value.
-(define-ly-syntax-loc (music-function parser loc fun args)
- (let ((m (apply fun (cons* parser loc args))))
+(define-ly-syntax (music-function parser loc pred fun args)
+ (let ((m (apply fun parser loc args)))
(if (ly:music? m)
+ (set! (ly:music-property m 'origin) loc))
+ (if (pred m)
m
- (begin
- (ly:parser-error parser (_ "Music head function must return Music object") loc)
- (make-music 'Music)))))
+ (cond ((eq? pred ly:music?)
+ (ly:parser-error parser (_ "Music syntax function must return Music object") loc)
+ (make-music 'Music 'origin loc))
+ (else
+ (ly:parser-error parser
+ (format #f (_ "Scheme function must return ~a object") (type-name pred))
+ loc)
+ #f)))))
(define-ly-syntax-simple (void-music)
(make-music 'Music))
'numerator (car fraction)
'denominator (cdr fraction)))
-(define-ly-syntax-simple (transpose-music pitch music)
- (make-music 'TransposedMusic
- 'element (ly:music-transpose music pitch)))
-
(define-ly-syntax (tempo parser location text . rest)
(let* ((unit (and (pair? rest)
(car rest)))
(make-sequential-music (list tempo-change tempo-set))
tempo-change)))
-(define-ly-syntax-simple (skip-music dur)
- (make-music 'SkipMusic
- 'duration dur))
-
(define-ly-syntax-simple (repeat type num body alts)
(make-repeat type num body alts))
(begin
(set! (ly:music-property ev 'label) label)
ev))))
-
-(define-ly-syntax (partial parser location dur)
- "Make a partial measure."
-
- ;; We use `descend-to-context' here instead of `context-spec-music' to
- ;; ensure \partial still works if the Timing_translator is moved
- (descend-to-context
- (context-spec-music (make-music 'PartialSet
- 'origin location
- 'partial-duration dur)
- 'Timing)
- 'Score))
;; ------------- PUBLIC FUNCTIONS -----------------------------
-(define-public (make-modal-transposer from-pitch to-pitch scale)
+(define-public (make-modal-transposer from to scale)
"Wrapper function for transposer-factory."
- (let ((transposer (transposer-factory (make-extended-scale scale)))
- (from (car (extract-pitch-sequence from-pitch)))
- (to (car (extract-pitch-sequence to-pitch))))
-
+ (let ((transposer (transposer-factory (make-extended-scale scale))))
(lambda (p)
(transposer from to p))))
-(define-public (make-modal-inverter around-pitch to-pitch scale)
+(define-public (make-modal-inverter around to scale)
"Wrapper function for inverter-factory"
- (let ((inverter (inverter-factory (make-extended-scale scale)))
- (around (car (extract-pitch-sequence around-pitch)))
- (to (car (extract-pitch-sequence to-pitch))))
-
+ (let ((inverter (inverter-factory (make-extended-scale scale))))
(lambda (p)
(inverter around to p))))
(ly:pitch-transpose to (ly:pitch-diff around p))))
music))
-(define-public (music-invert around-pitch to-pitch music)
+(define-public (music-invert around to music)
"Applies pitch-invert to all pitches in @var{music}."
- (let ((around (car (extract-pitch-sequence around-pitch)))
- (to (car (extract-pitch-sequence to-pitch))))
- (music-map (lambda (x) (pitch-invert around to x)) music)))
-
+ (music-map (lambda (x) (pitch-invert around to x)) music))
music
(ly:music-deep-copy ,stop))))))
-(defmacro-public define-music-function (args signature . body)
+(defmacro-public define-syntax-function (type args signature . body)
"Helper macro for `ly:make-music-function'.
Syntax:
- (define-music-function (parser location arg1 arg2 ...) (arg1-type? arg2-type? ...)
+ (define-syntax-function (result-type? parser location arg1 arg2 ...) (result-type? arg1-type? arg2-type? ...)
...function body...)
"
-(if (and (pair? body) (pair? (car body)) (eqv? '_i (caar body)))
+ (if (and (pair? body) (pair? (car body)) (eqv? '_i (caar body)))
;; When the music function definition contains a i10n doc string,
;; (_i "doc string"), keep the literal string only
(let ((docstring (cadar body))
(body (cdr body)))
- `(ly:make-music-function (list ,@signature)
- (lambda (,@args)
+ `(ly:make-music-function (list ,type ,@signature)
+ (lambda ,args
,docstring
,@body)))
- `(ly:make-music-function (list ,@signature)
- (lambda (,@args)
+ `(ly:make-music-function (list ,type ,@signature)
+ (lambda ,args
,@body))))
+(defmacro-public define-music-function rest
+ "Helper macro for `ly:make-music-function'.
+Syntax:
+ (define-music-function (parser location arg1 arg2 ...) (arg1-type? arg2-type? ...)
+ ...function body...)
+"
+ `(define-syntax-function ly:music? ,@rest))
+
+
+(defmacro-public define-scheme-function rest
+ "Helper macro for `ly:make-music-function'.
+Syntax:
+ (define-scheme-function (parser location arg1 arg2 ...) (arg1-type? arg2-type? ...)
+ ...function body...)
+"
+ `(define-syntax-function scheme? ,@rest))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
import os
import glob
-# these links are relative from /website/ on lilypond.org
-depth = "../"
-
### translation data -- shouldn't be here; see issue
### http://code.google.com/p/lilypond/issues/detail?id=1050
-#langs = ['', 'cs', 'de', 'es', 'fr', 'hu', 'it', 'ja', 'nl', 'zh']
-langs = ['', 'cs', 'de', 'es', 'fr', 'hu', 'it', 'ja', 'nl', 'zh']
+import langdefs
+# GUB only has python 2.4 !!!
+# langs = [i.code if i.code != 'en' else '' for i in langdefs.WEB_LANGUAGES]
+langs = []
+for lang in langdefs.WEB_LANGUAGES:
+ if lang.code == 'en':
+ langs.append('')
+ else:
+ langs.append(lang.code)
+
+
+# these links are relative from /website/ on lilypond.org
+depth = "../"
# Get/update node translations
'''
MergeFonts("feta-noteheads%(design_size)d.pfb");
MergeFonts("feta-flags%(design_size)d.pfb");
MergeFonts("parmesan%(design_size)d.pfb");
+MergeFonts("parmesan-noteheads%(design_size)d.pfb");
# load nummer/din after setting PUA.
i = 0;
enc_name = 'FetaEncoding'
if re.search ('parmesan', filenm):
enc_name = 'ParmesanEncoding'
+ elif re.search ('parmesan-noteheads', filenm):
+ enc_name = 'ParmesanNoteheadsEncoding'
elif re.search ('feta-noteheads', filenm):
enc_name = 'FetaNoteheadsEncoding'
elif re.search ('feta-flags', filenm):
else:
global_options.lily_output_dir = os.path.abspath(global_options.output_dir)
+ relative_output_dir = global_options.output_dir
identify ()
try:
base_file_name = os.path.splitext (os.path.basename (files[0]))[0]
dep_file = os.path.join (global_options.output_dir, base_file_name + '.dep')
- final_output_file = os.path.join (global_options.output_dir,
- base_file_name
- + '.%s' % global_options.format)
+ final_output_file = os.path.join (relative_output_dir,
+ base_file_name + global_options.formatter.default_extension)
os.chdir (original_dir)
file (dep_file, 'w').write ('%s: %s'