# of internals every time. however, this triggers
# compilation during install, which is a bad thing (tm).
-$(outdir)/internals.texi: $(LILYPOND_BINARY)
+$(outdir)/internals.texi: $(LILYPOND_BINARY) $(INIT_LY_SOURCES) $(SCHEME_SOURCES)
cd $(outdir) && $(buildscript-dir)/run-and-check "$(LILYPOND_BINARY) --verbose $(top-src-dir)/ly/generate-documentation" "generate-documentation.log"
###############################################
@end ignore
+@item
+Starting with version@tie{}2.17.10, error messages or the
+@code{textedit} @acronym{URI} used for point-and-click
+functionality specify column numbers starting with@tie{}1 rather
+than@tie{}0. The byte offset (also part of @code{textedit}
+@acronym{URI}s) still starts at@tie{}0.
+
@item
The @code{\clef} command supports optional octavation:
@lilypond[verbatim,quote,relative=1]
Appendices
+* LilyPond grammar::
* GNU Free Documentation License:: License of this document.
@end menu
@include contributor/feta-font.itexi
@include contributor/administration.itexi
+@node LilyPond grammar
+@appendix LilyPond grammar
+
+This appendix contains a description of the LilyPond grammar, as
+output from the parser.
+
+@verbatiminclude ly-grammar.txt
+
@include fdl.itexi
@bye
-
@end enumerate
+@subheading Contributions that contain examples using overrides
+
+Examples that use overrides, tweaks, customer Scheme functions etc. are
+(with very few exceptions) not included in the main text of the manuals;
+as there would be far too many, equally useful, candidates.
+
+The correct way is to submit your example, with appropriate explanatory
+text and tags, to the LilyPond Snippet Repository (LSR). Snippets that
+have the @qq{docs} tag can then be easily added as a
+@emph{selected snippet} in the documentation. It will also appear
+automatically in the Snippets lists. See @ref{Introduction to LSR}.
+
+Snippets that @emph{don't} have the @qq{docs} tage will still be
+searchable and viewable within the LSR, but will be not be included in
+the Snippets list or be able to be included as part of the main
+documentation.
+
+Generally, any new snippets that have the @qq{docs} tag are more
+carefully checked for syntax and formatting.
+
+@subheading Announcing your snippet
+
Once you have followed these guidelines, please send a message to
lilypond-devel with your documentation submissions. Unfortunately
-there is a strict “no top-posting” check on the mailing list; to avoid
+there is a strict @q{no top-posting} check on the mailing list; to avoid
this, add:
-> I'm not top posting.
+@code{> I'm not top posting}
+
+(you must include the > ) to the top of your documentation addition.
-(you must include the > ) to the top of your documentation
-addition.
+We may edit your suggestion for spelling, grammar, or style, and we may
+not place the material exactly where you suggested, but if you give us
+some material to work with, we can improve the manual much faster.
-We may edit your suggestion for spelling, grammar, or style, and
-we may not place the material exactly where you suggested, but if
-you give us some material to work with, we can improve the manual
-much faster. Thanks for your interest!
+Thanks for your interest!
@node Texinfo introduction and usage policy
like human language is structured into words and sentences. LilyPond
has a lexer that recognizes tokens (literal numbers, strings, Scheme
elements, pitches and so on), and a parser that understands the syntax,
-@ruser{LilyPond grammar}. Once it knows that a particular syntax rule
+@rcontrib{LilyPond grammar}. Once it knows that a particular syntax rule
applies, it executes actions associated with it.
The hash mark@tie{}@code{#} method of embedding Scheme is a natural fit
--- /dev/null
+@c -*- coding: utf-8; mode: texinfo; -*-
+@c This file is part of community.itexi
+
+@ignore
+
+ This file lists projects and institutions that support LilyPond by
+ providing infrastructure:
+
+@end ignore
+
+
+@macro acknowledgementsCurrent
+
+@itemize
+
+@item
+GNU, GNU Savannah
+@uref{http://savannah.gnu.org/}
+Source code and mailing lists
+
+@item
+Webdev.nl
+@uref{http://www.webdev.nl/}
+lilypond.org hosting
+
+@item
+Linuxaudio/VirgniaTech
+@uref{http://linuxaudio.org/}
+Release downloads
+
+@item
+Google Code
+@uref{http://code.google.com/}
+Issue tracker
+
+@item
+Rietveld
+@uref{https://codereview.appspot.com/}
+Code review
+
+@item
+Maison des Sciences de l'Homme Paris Nord
+@uref{http://www.mshparisnord.fr/}
+Automated build tests
+
+@end itemize
+@end macro
'("upbow"
"downbow"
"flageolet"
- "thumb"
"snappizzicato"
"open"
"halfopen"
* Notation manual tables:: Tables and charts.
* Cheat sheet:: Summary of LilyPond syntax.
-* LilyPond grammar:: Syntax diagram for LilyPond parser.
* GNU Free Documentation License:: License of this document.
* LilyPond command index::
* LilyPond index::
@include notation/cheatsheet.itely
-
-@node LilyPond grammar
-@appendix LilyPond grammar
-
-This appendix contains a description of the LilyPond grammar, as
-output from the parser.
-
-@verbatiminclude ly-grammar.txt
-
-
@include fdl.itexi
@menu
* Kievan contexts::
* Kievan clefs::
-* Kievan note heads::
+* Kievan notes::
* Kievan accidentals::
* Kievan bar line::
@end menu
@lilypond[quote,relative=1,notime,verbatim]
\clef "kievan-do"
- \override NoteHead.style = #'kievan
+ \kievanOn
c
@end lilypond
Notation Reference:
@ref{Clef}.
-@node Kievan note heads
-@unnumberedsubsubsec Kievan note heads
+@node Kievan notes
+@unnumberedsubsubsec Kievan notes
@cindex note heads, ancient
For Kievan square notation, the appropriate note head style needs
-to be chosen. This is accomplished by setting the @code{style}
-property of the @code{NoteHead} object to @code{kievan}.
+to be chosen and the flags and stems need to be turned off.
+This is accomplished by calling the @code{\kievanOn} function,
+which sets the appropriate properties of the note head, stems,
+and flags. Once Kievan note heads are not needed, these
+properties can be reverted by calling the @code{\kievanOff}
+function.
The Kievan final note, which usually comes at the end of a piece
of music, may be selected by setting the duration to
@lilypond[quote,fragment,ragged-right,verbatim]
\autoBeamOff
\cadenzaOn
-\override NoteHead.style = #'kievan
+\kievanOn
b'1 b'2 b'4 b'8 b'\breve b'\longa
+\kievanOff
+b'2
@end lilypond
@seealso
@lilypond[quote,relative=1,notime,verbatim]
\clef "kievan-do"
-\override NoteHead.style = #'kievan
\override Accidental.glyph-name-alist =
#alteration-kievan-glyph-name-alist
bes' dis,
It can be invoked as @code{\bar "k"}.
@lilypond[quote,relative=1,notime,verbatim]
+ \kievanOn
\clef "kievan-do"
- \override NoteHead.style = #'kievan
c \bar "k"
@end lilypond
@cindex parser
@cindex Bison
+@cindex LilyPond grammar
@cindex grammar for LilyPond
@cindex BNF
message is produced. The syntactic groupings and the rules for
constructing the groupings from their parts for the LilyPond syntax
are defined in @file{lily/parser.yy} and shown in Backus Normal Form
-(BNF) in @ref{LilyPond grammar}. This file is used to build the
-parser during the program build by the parser generator, Bison. It
-is part of the source code and is not included in the LilyPond
-binary installation.
+(BNF) in @rcontrib{LilyPond grammar}. This file is used to build the
+parser during the program build by the parser generator, Bison. It is
+part of the source code and is not included in the LilyPond binary
+installation.
@node parser variable
(middleCPosition . 6)
(clefPosition . 2)
(instrumentCueName . ,(markup #:fontsize 1 #:smallCaps "Melchior"))
- (midiInstrument . "voice aahs"))
+ (midiInstrument . "choir aahs"))
\relative c' {
\instrumentSwitch "kaspar"
@table @code
@item -d@var{[option-name]}=@var{[value]},--define-default=@var{[option-name]}=@var{[value]}
-This sets the equivalent internal Scheme function to @var{value}. If a
-@var{value} is not supplied, then the default value is used. The prefix
-@code{no-} may be added to @var{option-name} to switch @q{off} an
+This sets the equivalent internal Scheme function to @var{value}.
+
+@example
+-dbackend=svg
+@end example
+
+If a @var{value} is not supplied, then the default value is used. The
+prefix @code{no-} may be added to @var{option-name} to switch @q{off} an
option, e.g.
@cindex point and click, command line
@code{EPS} backend.
@item @code{backend}
-@tab @code{'ps}
+@tab @code{ps}
@tab Select backend. Postscript files (default) include @code{TTF},
@code{Type1} and @code{OTF} fonts. No subsetting of these fonts is
done. Using @q{oriental} character sets can lead to very large files.
@item
-@tab @code{'eps}
+@tab @code{eps}
@tab Encapsulated PostScript. This dumps every page (system) as a
separate @file{EPS} file, without fonts, and as one collated @file{EPS}
file with all pages (systems) including fonts. Used as default by
@command{lilypond-book}.
@item
-@tab @code{'null}
+@tab @code{null}
@tab Do not output a printed score; has the same effect as
@code{-dno-print-pages}.
@item
-@tab @code{'svg}
+@tab @code{svg}
@tab Scalable Vector Graphics. This creates a single @code{SVG} file,
without embedded fonts, for every page of output. It is recommended to
install the Century Schoolbook fonts, included with your LilyPond
font files in the SVG backend.
@item
-@tab @code{'scm}
+@tab @code{scm}
@tab Dump of the raw, internal Scheme-based drawing commands.
@item @code{check-internal-types}
@menu
* Music runs off the page::
* An extra staff appears::
-* Apparent error in ../ly/init.ly::
* Error message Unbound variable %::
* Error message FT_Get_Glyph_Name::
* Warning staff affinities should only decrease::
@end lilypond
-@node Apparent error in ../ly/init.ly
-@unnumberedsubsec Apparent error in @code{../ly/init.ly}
-
-Various obscure error messages may appear about syntax errors in
-@file{../ly/init.ly} if the input file is not correctly formed,
-for example, if it does not contain correctly
-matched braces or quote signs.
-
-The most common error is a missing brace, (@code{@}}), at the end of
-a @code{score} block. Here the solution is obvious: check the
-@code{score} block is correctly terminated. The correct structure
-of an input file is described in @rlearning{How LilyPond input files work}.
-Using an editor which automatically highlights matching brackets and
-braces is helpful to avoid such errors.
-
-A second common cause is no white space between the last syllable
-of a lyrics block and the terminating brace, (@code{@}}). Without
-this separation the brace is taken to be part of the syllable. It
-is always advisable to ensure there is white space before and after
-@emph{every} brace. For the importance of this when using lyrics,
-see @ruser{Entering lyrics}.
-
-This error message can also appear if a terminating quote sign,
-(@code{"}), is omitted. In this case an accompanying error message
-@c keep "-matching straight in fancy editors
-should give a line number close to the line in error. The
-mismatched quote will usually be on the line one or two above.
-
@node Error message Unbound variable %
@unnumberedsubsec Error message Unbound variable %
Guide, node Updating translation committishes..
@end ignore
+@include included/acknowledge.itexi
@include included/authors.itexi
@include included/helpus.itexi
@item
@ref{Authors}: the people who made LilyPond what it is today.
+@item
+@ref{Acknowledgements}: projects and institutions that support LilyPond
+
@end itemize
@divEnd
* Development::
* GSoC 2012::
* Authors::
+* Acknowledgements::
* Publications::
* Old news::
* Attic::
@divEnd
@divEnd
+@node Acknowledgements
+@unnumberedsec Acknowledgements
+
+@divClass{column-center-top}
+@subheading Acknowledgements
+
+@divClass{keep-bullets}
+@acknowledgementsCurrent
+@divEnd
+@divEnd
@node Publications
@divClass{keep-bullets}
@itemize
+@item
+A critical edition of Tommaso Traetta's @emph{Enea nel Lazio (1760)},
+opera series with libretto by Vittorio Amedeo Cigna-Santi, in four
+parts:
+@uref{http://www.academia.edu/1987651/Enea_nel_Lazio_opera_riformata_prima_lazione_poi_le_parole_-_Partitura_1_4_, Part One}
+@uref{http://www.academia.edu/1994533/Enea_nel_Lazio_opera_riformata_prima_lazione_poi_le_parole_-_Partitura_2_4_, Part Two}
+@uref{http://www.academia.edu/1994558/Enea_nel_Lazio_opera_riformata_prima_lazione_poi_le_parole_-_Partitura_3_4_, Part Three}
+@uref{http://www.academia.edu/1996242/Enea_nel_Lazio_opera_riformata_prima_lazione_poi_le_parole_-_Partitura_4_4_, Part Four}
+Created by
+@uref{http://unito.academia.edu/LucaRossettoCasel, Luca Rossetto Casel}
+for his Ph.D. Thesis.
+
@item
Mussorgsky's @emph{Pictures at an exhibition}, re-orchestrated and
conducted by @uref{http://www.aurelienbello.com/,Aurélien Bello} with
@uref{http://www.pnme.org/CurrentSeason/PreviousSeasons.html, Pittsburgh
New Music Ensemble}.
-
@item
@emph{Anonymous Student Compliment or Complaint}, by
@uref{http://www.mikesolomon.org, Mike Solomon}, winner chosen from among
172 entries from 22 countries of the
-@uref{http://leftcoastensemble.org/contest, 2011 Left Coast Composition Contest}.
+@uref{http://leftcoastensemble.org, 2011 Left Coast Composition Contest}.
Other works include, Norman (age 1) for clarinet solo, performed at the
@uref{http://emu.music.ufl.edu/fems_concerts.html, University of Florida}'s
Electroacoustic Music Festival (FEMF), October 2010.
in celebration of the composer's 350th birthday.
@item
-@uref{http://www.mercurybaroque.org/02/02109.aspx, Mercury Baroque}'s
-performance of Lully's @emph{Armide}, May 15-16, 2009, in Houston,
-Texas (engraving by @uref{http://nicolas.sceaux.free.fr/,
-Nicolas Sceaux}).
+@uref{http://www.mercurybaroque.org, Mercury Baroque}'s performance of
+Lully's @emph{Armide}, May 15-16, 2009, in Houston, Texas (engraving by
+@uref{http://nicolas.sceaux.free.fr/, Nicolas Sceaux}).
@item
Instrumental excerpts from Rameau's @emph{Hippolyte et Aricie} at
St. James's Church in Manhattan, May 8, 2009, by Frederick Renz
and his ensemble @uref{http://www.earlymusicny.org/, Early Music
-New York} (engraving by Nicolas Sceaux).
+New York} (engraving by
+@uref{http://nicolas.sceaux.free.fr/, Nicolas Sceaux}).
@item
@emph{Affaire étrangère}, an opera by
many different computer languages. Emacs is a highly extensible
editor and can be used as an Integrated Development Environment.
There is a @q{lilypond mode} which supplies the language
-definitions for working with LilyPond source files. As well, one of
-our developers has written
-@uref{http://nicolas.sceaux.free.fr/lilypond/lyqi.html,lyqi}, an
-Emacs major mode.
+definitions for working with LilyPond source files. A developer
+has written @uref{https://github.com/nsceaux/lyqi,lyqi}, an Emacs major
+mode.
@uref{http://www.vim.org}
@divEnd
+@divClass{column-center-bottom}
+@subheading Manual formats
+
+The LilyPond manuals generally come in three formats: split HTML, big HTML and
+PDF. Split HTML is good for reading online. Big HTML (and some of these can be
+very big) contains the whole manual in a single page. PDF is available for
+downloading and using offline. To get to these 3 formats, follow the links
+that read @code{details of} and then the manual name.
+
+@divEnd
+
@divEnd
@docLinks{Learning, learning,
@rlearningnamed{Top,Learning},
@manualStableLearningSplit,
- @manualStableLearningBig, 1.5 MB,
- @manualStableLearningPdf, 3 MB}
+ @manualStableLearningBig, 3 MB,
+ @manualStableLearningPdf, 5 MB}
@divEnd
@docLinks{Essay, essay,
@ressaynamed{Top,Essay},
@manualStableEssaySplit,
- @manualStableEssayBig, 2 MB,
- @manualStableEssayPdf, 2.5 MB}
+ @manualStableEssayBig, 1 MB,
+ @manualStableEssayPdf, 2 MB}
@divEnd
@docLinks{Notation, notation,
@rusernamed{Top,Notation},
@manualStableNotationSplit,
- @manualStableNotationBig, 7 MB,
- @manualStableNotationPdf, 18 MB}
+ @manualStableNotationBig, 9 MB,
+ @manualStableNotationPdf, 35 MB}
@divEnd
@rprogramnamed{Top,Usage},
@manualStableUsageSplit,
@manualStableUsageBig, 400 KB,
- @manualStableUsagePdf, 600 KB}
+ @manualStableUsagePdf, 650 KB}
@divEnd
@docLinks{Snippets, snippets,
@rlsrnamed{Top,Snippets},
@manualStableSnippetsSplit,
- @manualStableSnippetsBig, 2.5 MB,
- @manualStableSnippetsPdf, 8 MB}
+ @manualStableSnippetsBig, 1.5 MB,
+ @manualStableSnippetsPdf, 12.5 MB}
@divEnd
@docLinksBare{Web, web,
@ref{Top,Web},
@manualDevelWebSplit,
- @manualDevelWebBig, 1 MB,
- @manualDevelWebPdf, 2 MB}
+ @manualDevelWebBig, 2.5 MB,
+ @manualDevelWebPdf, 3.5 MB}
@divEnd
@docLinks{Changes, changes,
@rchangesnamed{Top,Changes},
@manualStableChangesSplit,
- @manualStableChangesBig, 6 KB,
- @manualStableChangesPdf, 200 KB}
+ @manualStableChangesBig, 90 KB,
+ @manualStableChangesPdf, 80 KB}
@divEnd
@docLinks{Extending, extending,
@rextendnamed{Top,Extending},
@manualStableExtendingSplit,
- @manualStableExtendingBig, 200 KB,
- @manualStableExtendingPdf, 400 KB}
+ @manualStableExtendingBig, 300 KB,
+ @manualStableExtendingPdf, 500 KB}
@divEnd
@docLinks{Internals, internals,
@rinternalsnamed{Top,Internals},
@manualStableInternalsSplit,
- @manualStableInternalsBig, 2.5 MB,
- @manualStableInternalsPdf, 2.8 MB}
+ @manualStableInternalsBig, 3 MB,
+ @manualStableInternalsPdf, 4 MB}
@divEnd
@divClass{keep-bullets}
@itemize
+@item @uref{http://lilypond.org/doc/v2.14/Documentation/web/manuals,
+LilyPond 2.14 Documentation}
+
@item @uref{http://lilypond.org/doc/v2.12/Documentation/,
LilyPond 2.12 Documentation}
-@item @uref{http://lilypond.org/doc/v2.11/Documentation/,
-LilyPond 2.11 Documentation}
-
@item @uref{http://lilypond.org/doc/v2.10/Documentation/,
LilyPond 2.10 Documentation}
(defun LilyPond-compile-file (command name)
;; We maybe should know what we run here (Lily, lilypond, tex)
;; and adjust our error-matching regex ?
- (compile-internal
+ (compilation-start
(if (eq LilyPond-command-current 'LilyPond-command-master)
command
;; use temporary directory for Commands on Buffer/Region
;; hm.. the directory is set twice, first to default-dir
- (concat "cd " (LilyPond-temp-directory) "; " command))
- "No more errors" name))
+ (concat "cd " (LilyPond-temp-directory) "; " command))))
-;; do we still need this, now that we're using compile-internal?
+;; do we still need this, now that we're using compilation-start?
(defun LilyPond-save-buffer ()
"Save buffer and set default command for compiling."
(interactive)
Hara_kiri_group_spanner::consider_suicide (Grob *me)
{
Spanner *sp = dynamic_cast<Spanner *> (me);
- int left = sp->get_bound (LEFT)->get_column ()->get_rank ();
- int right = sp->get_bound (RIGHT)->get_column ()->get_rank ();
+ int left = 0;
+ int right = INT_MAX;
+ if (Item *l = sp->get_bound (LEFT))
+ left = l->get_column ()->get_rank ();
+ if (Item *r = sp->get_bound (RIGHT))
+ right = r->get_column ()->get_rank ();
if (!request_suicide (me, left, right))
return;
%x incl
%x lyrics
%x longcomment
+%x maininput
%x markup
%x notes
%x quote
start_main_input ();
main_input_level_ = include_stack_.size ();
is_main_input_ = true;
+ int state = YYSTATE;
+ yy_push_state (maininput);
+ yy_push_state (state);
}
else
error (_ ("\\maininput not allowed outside init files"));
<longcomment><<EOF>> {
LexerError (_ ("EOF found inside a comment").c_str ());
- is_main_input_ = false; // should be safe , can't have \include in --safe.
- yylval = SCM_UNSPECIFIED;
- if (!close_input ())
- yyterminate (); // can't move this, since it actually rets a YY_NULL
+ yy_pop_state ();
}
+<quote><<EOF>> {
+ LexerError (_ ("EOF found inside string").c_str ());
+ yy_pop_state ();
+}
+
<<EOF>> {
yylval = SCM_UNSPECIFIED;
if (is_main_input_)
{
is_main_input_ = include_stack_.size () > main_input_level_;
if (!is_main_input_)
+ {
main_input_level_ = 0;
+ pop_state ();
+ if (YYSTATE != maininput)
+ {
+ LexerError (_ ("Unfinished main input").c_str ());
+ do {
+ pop_state ();
+ } while (YYSTATE != maininput);
+ }
+ pop_state ();
+ }
if (!close_input () || !is_main_input_)
/* Returns YY_NULL */
yyterminate ();
yyterminate ();
}
+<maininput>. {
+ while (include_stack_.size () > main_input_level_
+ && close_input ())
+ ;
+ yyterminate ();
+}
+
<INITIAL>{
{WORD}/[-_] | // backup rule
{WORD} {
transposed = transposed.normalized ();
}
+ if (prop == ly_symbol2scm ("tonic"))
+ transposed = Pitch (-1, transposed.get_notename (),
+ transposed.get_alteration ());
+
new_val = transposed.smobbed_copy ();
}
else if (prop == ly_symbol2scm ("element"))
lyric_element_music:
lyric_element optional_notemode_duration post_events {
+ if (!parser->lexer_->is_lyric_state ())
+ parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
$$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
if (scm_is_pair ($3))
unsmob_music ($$)->set_property
get_counts (context_str0, &l, &ch, &col, &offset);
return name_string () + ":" + to_string (l)
- + ":" + to_string (col);
+ + ":" + to_string (col + 1);
}
}
%
%%%USAGE
% In the \score section do:
-% \unfoldRepeats \articulate <<
+% \articulate <<
% all the rest of the score
% >>
% or use the lilywrap script.
\version "2.16.0"
+#(use-modules (srfi srfi-1))
#(use-modules (ice-9 debug))
#(use-modules (scm display-lily))
% Start with 1/4 seconds == 1/240 minutes
#(define ac:maxTwiddleTime (ly:make-moment 1 240))
+% How long ordinary grace notes should be relative to their notated
+% duration. 9/40 is LilyPond's built-in behaviour for MIDI output
+% (though the notation reference says 1/4).
+#(define ac:defaultGraceFactor 9/40)
+
+% What proportion of an ordinary grace note's time should be stolen
+% from preceding notes (as opposed to stealing from the principal note).
+% Composers' intentions for this vary. Taking all from the preceding
+% notes is LilyPond's built-in behaviour for MIDI output.
+#(define ac:defaultGraceBackwardness 1)
+
% Internal variables, don't touch.
% (should probably be part of a context somehow)
% for no good reason.
#(define ac:currentDuration (ly:make-duration 2 0 1 1))
+% Amount of musical time (in whole notes) that we need to steal from the
+% next events seen.
+#(define ac:stealForward 0)
+
+% List of events in the output so far, in reverse order, from which we can
+% steal time.
+#(define ac:eventsBackward '())
+
+% Log events for the backward chain.
+#(define (ac:logEventsBackward music)
+ (music-map
+ (lambda (m)
+ (case (ly:music-property m 'name)
+ ((EventChord)
+ (set! ac:eventsBackward (cons m ac:eventsBackward))
+ m)
+ ((BarCheck SkipMusic)
+ (let ((wm (make-sequential-music (list m))))
+ (set! ac:eventsBackward (cons wm ac:eventsBackward))
+ wm))
+ (else
+ m)))
+ music))
+
+% Steal time from the backward chain. Adds to ac:stealForward (with a
+% warning) if it couldn't backward-steal all that was desired.
+#(define (ac:stealTimeBackward tosteal)
+ (if (<= tosteal 0)
+ #t
+ (if (null? ac:eventsBackward)
+ (begin
+ (ly:warning (_ "articulation failed to steal ~a note backward at beginning of music; stealing forward instead") tosteal)
+ (set! ac:stealForward (+ ac:stealForward tosteal)))
+ (let*
+ ((lastev (car ac:eventsBackward))
+ (levlen (ly:moment-main (ly:music-length lastev))))
+ (if (< tosteal levlen)
+ (begin
+ (ly:music-compress lastev (ly:make-moment (/ (- levlen tosteal) levlen)))
+ #t)
+ (begin
+ (if (any (lambda (z) (eq? 'NoteEvent (ly:music-property z 'name)))
+ (ly:music-property lastev 'elements))
+ (ly:warning (_ "stealing the entirety of a note's time")))
+ (set! (ly:music-property lastev 'elements) '())
+ (set! ac:eventsBackward (cdr ac:eventsBackward))
+ (ac:stealTimeBackward (- tosteal levlen))))))))
+
% Debugging: display a moment plus some text.
% Returns its moment argument so can be used in-line.
#(define (display-moment text m)
(context-spec-music
(make-property-set 'tempoWholesPerMinute tempo) 'Score))))
+%
+% Totally unfold repeats, so that the non-obvious sequencing doesn't
+% confuse us. This is necessary for time stealing to work, because
+% that relies on the sequence in which we see events matching their
+% audible sequence. Also unfold multi-measure rests to equivalent
+% skips, with preceding and following bar checks, so that time stealing
+% can change the length of the pause without falling foul of the
+% implicit bar checks.
+%
+#(define (ac:unfoldMusic music)
+ (music-map
+ (lambda (m)
+ (case (ly:music-property m 'name)
+ ((UnfoldedRepeatedMusic)
+ (let
+ ((body (ly:music-property m 'element))
+ (altl (ly:music-property m 'elements))
+ (rc (ly:music-property m 'repeat-count)))
+ (if (null? altl)
+ (make-sequential-music
+ (list-tabulate rc (lambda (i) (ly:music-deep-copy body))))
+ (let ((ealtl (if (> (length altl) rc) (take altl rc) altl)))
+ (make-sequential-music
+ (apply append!
+ (append!
+ (list-tabulate
+ (- rc (length ealtl))
+ (lambda (i) (list (ly:music-deep-copy body) (ly:music-deep-copy (car ealtl)))))
+ (map (lambda (alt) (list (ly:music-deep-copy body) alt))))))))))
+ ((MultiMeasureRestMusic)
+ (make-sequential-music
+ (list
+ (make-music 'BarCheck)
+ (make-music 'SkipMusic 'duration (ly:music-property m 'duration))
+ (make-music 'BarCheck))))
+ (else
+ m)))
+ (unfold-repeats music)))
+
% If there's an articulation, use it.
% If in a slur, use (1 . 1) instead.
% Treat phrasing slurs as slurs, but allow explicit articulation.
(if (null? es)
(begin
(set! (ly:music-property music 'elements) (reverse newelements))
- (cond
- ((not (any (lambda (m) (music-is-of-type? m 'rhythmic-event))
- newelements))
- actions)
- (ac:inTrill (cons 'trill actions))
- ((and (eq? factor ac:normalFactor) (or ac:inSlur ac:inPhrasingSlur))
- (append actions (list 'articulation '(1 . 1)) ))
- (else (append actions (list 'articulation factor)))))
+ (if
+ (not (any (lambda (m) (music-is-of-type? m 'rhythmic-event))
+ newelements))
+ actions
+ (append
+ (let ((st ac:stealForward))
+ (if (= st 0)
+ '()
+ (begin
+ (set! ac:stealForward 0)
+ (list 'steal st))))
+ actions
+ (cond
+ (ac:inTrill '(trill))
+ ((and (eq? factor ac:normalFactor) (or ac:inSlur ac:inPhrasingSlur))
+ (list 'articulation '(1 . 1)))
+ (else (list 'articulation factor))))))
; else part
(let ((e (car es))
(tail (cdr es)))
#(define (ac:articulate-chord music)
- (begin
- (cond
-
- ((eq? 'EventChord (ly:music-property music 'name))
+ (cond
+ ((eq? 'EventChord (ly:music-property music 'name))
+ (ac:logEventsBackward
(let loop ((actions (ac:getactions music)))
(if (null? actions)
(if (ly:moment<? (ly:make-moment 1/4) (ly:music-length music))
(lambda (z) (eq? 'NoteEvent (ly:music-property z 'name)))
(ly:music-property above 'elements)))
newmusic)))))
- ))))
+ ((steal)
+ (let
+ ((totallen (ly:moment-main (ly:music-length music)))
+ (steallen (cadr actions)))
+ (if (>= steallen totallen)
+ (begin
+ (if (any (lambda (z) (eq? 'NoteEvent (ly:music-property z 'name)))
+ (ly:music-property music 'elements))
+ (ly:warning (_ "stealing the entirety of a note's time")))
+ (set! ac:stealForward (- steallen totallen))
+ (make-sequential-music '()))
+ (begin
+ (ly:music-compress music (ly:make-moment (/ (- totallen steallen) totallen)))
+ (loop (cddr actions))))))
+ )))))
+
+ ((eq? 'GraceMusic (ly:music-property music 'name))
+ (let
+ ((first-ev
+ (call-with-current-continuation
+ (lambda (yield-fev)
+ (music-map
+ (lambda (m)
+ (if (eq? 'EventChord (ly:music-property m 'name))
+ (yield-fev m)
+ m))
+ music)
+ #f))))
+ (if first-ev
+ (let ((fev-pos (find-tail (lambda (m) (eq? m first-ev)) ac:eventsBackward)))
+ (if fev-pos
+ (set! ac:eventsBackward (cdr fev-pos))
+ (ly:warning (_ "articulation of grace notes has gone awry"))))))
+ (let*
+ ((gmus (ly:music-compress (ly:music-property music 'element)
+ (ly:make-moment ac:defaultGraceFactor)))
+ (glen (ly:moment-main (ly:music-length gmus))))
+ (ac:stealTimeBackward (* glen ac:defaultGraceBackwardness))
+ (set! ac:stealForward (+ ac:stealForward (* glen (- 1 ac:defaultGraceBackwardness))))
+ gmus))
+
+ ((memq (ly:music-property music 'name) '(BarCheck SkipMusic))
+ (let ((totallen (ly:moment-main (ly:music-length music)))
+ (steallen ac:stealForward))
+ (cond
+ ((= steallen 0)
+ (ac:logEventsBackward music))
+ ((< steallen totallen)
+ (set! ac:stealForward 0)
+ (ac:logEventsBackward
+ (ly:music-compress music (ly:make-moment (/ (- totallen steallen) totallen)))))
+ (else
+ (set! ac:stealForward (- steallen totallen))
+ (make-sequential-music '())))))
- ((eq? 'KeyChangeEvent (ly:music-property music 'name))
- (set! ac:current-key music)
- music
- )
+ ((eq? 'KeyChangeEvent (ly:music-property music 'name))
+ (set! ac:current-key music)
+ music)
- ((eq? 'PropertySet (ly:music-property music 'name))
- (ac:adjust-props (ly:music-property music 'symbol) music)
- music)
+ ((eq? 'PropertySet (ly:music-property music 'name))
+ (ac:adjust-props (ly:music-property music 'symbol) music)
+ music)
- (else music))
- ))
+ (else music)))
"Adjust times of note to add tenuto, staccato and
normal articulations.
"
- (set! music (event-chord-wrap! music parser))
- (music-map ac:articulate-chord music)
- )
+ (dynamic-wind
+ (lambda ()
+ (set! ac:stealForward 0)
+ (set! ac:eventsBackward '()))
+ (lambda ()
+ (music-map
+ ac:articulate-chord
+ (event-chord-wrap! (ac:unfoldMusic music) parser)))
+ (lambda ()
+ (or (= ac:stealForward 0)
+ (begin
+ (ly:warning (_ "articulation failed to steal ~a note at end of music") ac:stealForward)
+ (set! ac:stealForward 0)))
+ (set! ac:eventsBackward '()))))
% Override \afterGrace to be in terms of audio, not spacing.
textLengthOn = {
\override TextScript.extra-spacing-width = #'(0 . 0)
\override TextScript.extra-spacing-height = #'(-inf.0 . +inf.0)
+ \override TextScript.outside-staff-horizontal-padding = #0
}
+
textLengthOff = {
\override TextScript.extra-spacing-width = #'(+inf.0 . -inf.0)
\override TextScript.extra-spacing-height = #'(0 . 0)
+ \revert TextScript.outside-staff-horizontal-padding
}
staccato = #(make-articulation "staccato")
stopped = #(make-articulation "stopped")
tenuto = #(make-articulation "tenuto")
-thumb = #(make-articulation "thumb")
+thumb = \tweak text \markup \scale #(cons (magstep 5) (magstep 5))
+ \musicglyph #"scripts.thumb"
+ #(make-music 'FingeringEvent)
trill = #(make-articulation "trill")
turn = #(make-articulation "turn")
upbow = #(make-articulation "upbow")
(if (> fretval maxfret) (set! maxfret fretval))
(if (< fretval minfret) (set! minfret fretval))
(updatemax (cdr fret-list)))))
- (if (> maxfret my-fret-count)
+ (if (or (> maxfret my-fret-count) (> capo-fret 1))
(set! fret-range
(cons minfret
(let ((upfret (- (+ minfret my-fret-count) 1)))
(define-public (version-not-seen-message input-file-name)
(ly:warning-located
- (ly:format "~a:0" input-file-name)
+ (ly:format "~a:1" input-file-name)
(_ "no \\version statement found, please add~afor future compatibility")
(format #f "\n\n\\version ~s\n\n" (lilypond-version))))
(define-public (old-relative-not-used-message input-file-name)
(ly:warning-located
- (ly:format "~a:0" input-file-name)
+ (ly:format "~a:1" input-file-name)
(_ "old relative compatibility not used")))
(cadr location)
(caddr location)
- (cadddr location))
+ (1+ (cadddr location)))
""))
""))
""))
(avoid-slur . inside)
(padding . 0.20)
(side-relative-direction . ,DOWN)))
- ("thumb"
- . (
- (script-stencil . (feta . ("thumb" . "thumb")))
- (avoid-slur . around)
- (padding . 0.50)
- (direction . ,UP)
- (staff-padding . 0.5)))
("trill"
. (
(script-stencil . (feta . ("trill" . "trill")))