@w{@code{-devel}} community into actually reviewing said patches, and
finally pushes the patches once they're accepted. This person is
@emph{not} responsible for training new programmers, because that
-would be far too much work -- he job is @qq{only} to guide
+would be far too much work -- his/her job is @qq{only} to guide
completed patches through our process.
Currently: Carl
@subheading Installing patchy
-To install patchy, you should run do the following:
+To install patchy, you should do the following:
@enumerate
@item
-Create a new user on your box to to run patchy; this is a security
+Create a new user on your box to run patchy; this is a security
step for your own protection. It is recommended that this should
not be an administrator. New users are created from System;
Administration; Users and Groups.
@end example
Not much appears to happen except you can see a lot of CPU gets
used if you open System Monitor. There's not much point running
-@code{lilypond-patchy-staging.py} unless there something in
+@code{lilypond-patchy-staging.py} unless there is something in
staging to be merged to master, however, if there's nothing in
staging then the script won't waste resources by compiling
anything.
@node Administrative mailing list
@section Administrative mailing list
-An mailing list for administrative issues is maintained at
+A mailing list for administrative issues is maintained at
@code{lilypond-hackers@@gnu.org}.
This list is intended to be used for discussions that should be kept
@itemize
@item
-Clarify the various development tasks by writing down the polices
+Clarify the various development tasks by writing down the policies
and techniques and/or simplifying the tasks directly.
@item
code.
Having 1 more normal user answering emails on lilypond-user won't
-have a dramatic trick-up affect all by himself, of course. But if
+have a dramatic @q{trickle-up} effect all by itself, of course. But if
we had 8 users volunteering to answer emails, 6 users starting to
write documentation, and 2 users editing LSR... well, that would
free up a lot of current bug-fixing-capable contributors to focus
Although GOP is a short-term project, the main goal is to train
more people to handle ongoing jobs. The more people doing these
-jobs, the ligher the work will be, and the more we can get done
+jobs, the lighter the work will be, and the more we can get done
with lilypond!
Also, it would be nice if we had at least one "replacement" /
The variable @code{depth} is used throughout the make system to
track how far down the directory structure the make is. The first
-include sets lots of variables but doesn't "do" anything. The
-second runs the file @file{GNUmakefile.in} from the top level
-source directory.
+include sets lots of variables but doesn't "do" anything. Default
+values for these variables are automatically detected at the
+./configure step, which creates the file @file{config.make}.
+The second include runs the file @file{GNUmakefile.in} from
+the top level source directory.
This sets another load of variables, and then includes (i.e.
immediately runs) @file{stepmake.make} from the @file{make}
The file @file{lily-bib.bst} also has fairly extensive commenting.
+
@node Website build
@section Website build
@c use commas not colons
+Aleksandr Andreev,
Sven Axelsson,
+Peter Chubb,
Karin Hoethker,
Mark Hohl,
Justin Ohmie,
+Benkő Pál,
Julien Rioux,
Patrick Schmidt,
Adam Spiers,
Heikki Taurainen,
-Piers Titus van der Torren
+Piers Titus van der Torren,
+Jan-Peter Voigt,
+Janek Warchol
@c no comma for last entry
@macro bugsquadCurrent
Colin Campbell,
+Eluze,
Phil Holmes,
-Derek Klinge,
-Dmytro O. Redchuk
+Marek Klein,
+Ralph Palmer,
+James Lowe
@c no comma for last entry
@c use commas not colons
+Jean-Charles Malahieude,
Till Paala,
Yoshiki Sawada
@c use commas not colons
James E. Bailey,
+Derek Klinge,
Urs Liska,
Kieren MacMillan,
-Ralph Palmer
+Ralph Palmer,
+Dmytro O. Redchuk
@c no comma for last entry
@end macro
make [-j@var{X}] @emph{## needed if editing outside}
@emph{## Documentation/, but useful anyway}
@emph{## for finding Texinfo errors.}
-touch Documentation/*te?? @emph{## bug workaround}
make [-j@var{X} CPU_COUNT=@var{X}] doc @emph{## usually faster than initial build.}
@end example
make LANGS='' doc
@end example
+@noindent Similarly, it is possible to compile a subset of the
+translated documentation by specifying their language codes on the
+command line. For example, the French and German translations are
+compiled with:
+
+@example
+make LANGS='de fr' doc
+@end example
+
+@noindent Note that this will also compile the English version.
+
Compilation of documentation in Info format with images can be
done separately by issuing:
indiscriminately---it is more efficient to @command{touch} only
the affected files.
+@noindent
+Another typical issue when switching branches between master and
+lilypond/translation is the appearance/disappearance of translated
+versions of some manuals. If you see such a warning from make:
+
+@example
+No rule to make target `X', needed by `Y'
+@end example
+
+@noindent
+Your best bet is to delete the file Y.dep and to try again.
+
@node Building a single document
@unnumberedsubsubsec Building a single document
It's possible to build a single document. For example, to rebuild
* Common chord modifiers::
* Predefined string tunings::
* Predefined fretboard diagrams::
+* Predefined paper sizes::
* MIDI instruments::
* List of colors::
* The Feta font::
@lilypondfile{display-predefined-mandolin-fretboards.ly}
+
+@node Predefined paper sizes
+@appendixsec Predefined paper sizes
+
+Paper sizes are defined in @file{scm/paper.scm}
+
+@noindent
+@strong{The @qq{ISO 216} A Series}
+@table @code
+@item "a10"
+(26 x 37 mm)
+@item "a9"
+(37 x 52 mm)
+@item "a8"
+(52 x 74 mm)
+@item "a7"
+(74 x 105 mm)
+@item "a6"
+(105 x 148 mm)
+@item "a5"
+(148 x 210 mm)
+@item "a4"
+(210 x 297 mm)
+@item "a3"
+(297 x 420 mm)
+@item "a2"
+(420 x 594 mm)
+@item "a1"
+(594 x 841 mm)
+@item "a0"
+(841 x 1189 mm)
+@end table
+
+@noindent
+@strong{The @qq{ISO 216} B Series}
+@table @code
+@item "b10"
+(31 x 44 mm)
+@item "b9"
+(44 x 62 mm)
+@item "b8"
+(62 x 88 mm)
+@item "b7"
+(88 x 125 mm)
+@item "b6"
+(125 x 176 mm)
+@item "b5"
+(176 x 250 mm)
+@item "b4"
+(250 x 353 mm)
+@item "b3"
+(353 x 500 mm)
+@item "b2"
+(500 x 707 mm)
+@item "b1"
+(707 x 1000 mm)
+@item "b0"
+(1000 x 1414 mm)
+@end table
+
+@noindent
+@strong{Two extended sizes as defined in @qq{DIN 476}}
+@table @code
+@item "4a0"
+(1682 x 2378 mm)
+@item "2a0"
+(1189 x 1682 mm)
+@end table
+
+@noindent
+@strong{@qq{ISO 269} standard C series}
+@table @code
+@item "c10"
+(28 x 40 mm)
+@item "c9"
+(40 x 57 mm)
+@item "c8"
+(57 x 81 mm)
+@item "c7"
+(81 x 114 mm)
+@item "c6"
+(114 x 162 mm)
+@item "c5"
+(162 x 229 mm)
+@item "c4"
+(229 x 324 mm)
+@item "c3"
+(324 x 458 mm)
+@item "c2"
+(458 x 648 mm)
+@item "c1"
+(648 x 917 mm)
+@item "c0"
+(917 x 1297 mm)
+@end table
+
+@noindent
+@strong{North American paper sizes}
+@table @code
+@item "junior-legal"
+(8.0 x 5.0 in)
+@item "legal"
+(8.5 x 14.0 in)
+@item "ledger"
+(17.0 x 11.0 in)
+@item "letter"
+(8.5 x 11.0 in)
+@item "tabloid"
+(11.0 x 17.0 in)
+@item "11x17"
+(11.0 x 17.0 in)
+@item "17x11"
+(17.0 x 11.0 in)
+@end table
+
+@noindent
+@strong{Government-letter by IEEE Printer Working Group, for children's
+writing}
+@table @code
+@item "government-letter"
+(8 x 10.5 in)
+@item "government-legal"
+(8.5 x 13.0 in)
+@item "philippine-legal"
+(8.5 x 13.0 in)
+@end table
+
+@noindent
+@strong{ANSI sizes}
+@table @code
+@item "ansi a"
+(8.5 x 11.0 in)
+@item "ansi b"
+(17.0 x 11.0 in)
+@item "ansi c"
+(17.0 x 22.0 in)
+@item "ansi d"
+(22.0 x 34.0 in)
+@item "ansi e"
+(34.0 x 44.0 in)
+@item "engineering f"
+(28.0 x 40.0 in)
+@end table
+
+@noindent
+@strong{North American Architectural sizes}
+@table @code
+@item "arch a"
+(9.0 x 12.0 in)
+@item "arch b"
+(12.0 x 18.0 in)
+@item "arch c"
+(18.0 x 24.0 in)
+@item "arch d"
+(24.0 x 36.0 in)
+@item "arch e"
+(36.0 x 48.0 in)
+@item "arch e1"
+(30.0 x 42.0 in)
+@end table
+
+@noindent
+@strong{Antique sizes still used in the United Kingdom}
+@table @code
+@item "statement"
+(5.5 x 8.5 in)
+@item "half letter"
+(5.5 x 8.5 in)
+@item "quarto"
+(8.0 x 10.0 in)
+@item "octavo"
+(6.75 x 10.5 in)
+@item "executive"
+(7.25 x 10.5 in)
+@item "monarch"
+(7.25 x 10.5 in)
+@item "foolscap"
+(8.27 x 13.0 in)
+@item "folio"
+(8.27 x 13.0 in)
+@item "super-b"
+(13.0 x 19.0 in)
+@item "post"
+(15.5 x 19.5 in)
+@item "crown"
+(15.0 x 20.0 in)
+@item "large post"
+(16.5 x 21.0 in)
+@item "demy"
+(17.5 x 22.5 in)
+@item "medium"
+(18.0 x 23.0 in)
+@item "broadsheet"
+(18.0 x 24.0 in)
+@item "royal"
+(20.0 x 25.0 in)
+@item "elephant"
+(23.0 x 28.0 in)
+@item "double demy"
+(22.5 x 35.0 in)
+@item "quad demy"
+(35.0 x 45.0 in)
+@item "atlas"
+(26.0 x 34.0 in)
+@item "imperial"
+(22.0 x 30.0 in)
+@item "antiquarian"
+(31.0 x 53.0 in)
+@end table
+
+@noindent
+@strong{PA4 based sizes}
+@table @code
+@item "pa0"
+(840 x 1120 mm)
+@item "pa1"
+(560 x 840 mm)
+@item "pa2"
+(420 x 560 mm)
+@item "pa3"
+(280 x 420 mm)
+@item "pa4"
+(210 x 280 mm)
+@item "pa5"
+(140 x 210 mm)
+@item "pa6"
+(105 x 140 mm)
+@item "pa7"
+(70 x 105 mm)
+@item "pa8"
+(52 x 70 mm)
+@item "pa9"
+(35 x 52 mm)
+@item "pa10"
+(26 x 35 mm)
+@end table
+
+@noindent
+@strong{Used in Southeast Asia and Australia}
+@table @code
+@item "f4"
+(210 x 330 mm)
+@end table
+
+@noindent
+@strong{Used for very small @code{@@lilypond} examples in the
+documentation based on a8 landscape.}
+@table @code
+@item "a8landscape"
+(74 x 52 mm)
+@end table
+
+
@node MIDI instruments
@appendixsec MIDI instruments
@funindex \paper
@menu
-* Setting paper size::
+* Setting the paper size::
* Automatic scaling to paper size::
@end menu
-@node Setting paper size
-@unnumberedsubsubsec Setting paper size
+@node Setting the paper size
+@unnumberedsubsubsec Setting the paper size
-Two functions are available for changing the paper size:
-@code{set-default-paper-size} and @code{set-paper-size}.
-@code{set-default-paper-size} must be placed in the toplevel
-scope, and @code{set-paper-size} must be placed in a @code{\paper}
-block:
+@q{A4} is the default value when no explicit paper size is set. However,
+there are two functions that can be used to change it
+@code{set-default-paper-size},
@example
-#(set-default-paper-size "a4")
+#(set-default-paper-size "quarto")
@end example
+which must always be placed at the toplevel scope. and
+@code{set-paper-size},
+
@example
\paper @{
- #(set-paper-size "a4")
+ #(set-paper-size "tabloid")
@}
@end example
-@noindent
-In the toplevel scope, the @code{set-default-paper-size} function
-can safely be called anywhere before the first @code{\paper}
-block. Within a @code{\paper} block, the safest place to call
-@code{set-paper-size} is at the top, above the list of variable
-declarations. The reasons for this are discussed in
-@ref{Automatic scaling to paper size}.
+which must always be placed in a @code{\paper} block.
-@code{set-default-paper-size} sets the size of all pages, whereas
-@code{set-paper-size} only sets the size of the pages that the
-@code{\paper} block applies to. For example, if the @code{\paper}
-block is at the top of the file, then it will apply the paper size
-to all pages. If the @code{\paper} block is inside a
+If the @code{set-default-paper-size} function is used in the toplevel
+scope, it must come before the any @code{\paper} block.
+@code{set-default-paper-size} sets the paper size for all pages,
+whereas @code{set-paper-size} only sets the paper size for the pages
+that the @code{\paper} block applies to. For example, if the
+@code{\paper} block is at the top of the file, then it will apply the
+paper size to all pages. If the @code{\paper} block is inside a
@code{\book}, then the paper size will only apply to that book.
-Common paper sizes are available, including @code{a4},
-@code{letter}, @code{legal}, and @code{11x17} (also known as
-tabloid). Many more paper sizes are supported by default. For
-details, see @file{scm/paper.scm}, and search for the
-definition of @code{paper-alist}.
+When the @code{set-paper-size} function is used, it must be
+placed @emph{before} any other functions used within the same
+@code{\paper} block. See @ref{Automatic scaling to paper size}.
-@c TODO add a new appendix for paper sizes (auto-generated) -pm
+Paper sizes are defined in @file{scm/paper.scm}, and while it is
+possible to add custom sizes, they will be overwritten on subsequent
+software updates.
-@warning{The default paper size is @code{a4}.}
+@c An appendix entry exists for paper sizes but is not auto-generated
-Extra sizes may be added by editing the definition of
-@code{paper-alist} in the initialization file
-@file{scm/paper.scm}, however they will be overridden on a
-subsequent install.
+The following command can be used in the file to add a custom paper size
+which can then be used with @code{set-default-paper-size} or
+@code{set-paper-size} as appropriate,
-@cindex orientation
-@cindex landscape
+@example
+#(set! paper-alist (cons '("my size" . (cons (* 15 in) (* 3 in))) paper-alist))
-If the symbol @code{'landscape} is supplied as an argument to
-@code{set-default-paper-size}, pages will be rotated by 90
-degrees, and wider line widths will be set accordingly.
+\paper @{
+ #(set-paper-size "my size")
+@}
+@end example
+
+The units @code{in} (inches), @code{cm} (centimeters) and @code{mm}
+(millimeters) can all be used.
+
+@cindex paper size, orientation
+@cindex page, orientation
+@cindex paper size, landscape
+
+If the symbol @code{'landscape} is added to the paper size function,
+pages will be rotated by 90 degrees, and wider line widths will be set
+accordingly.
@example
#(set-default-paper-size "a6" 'landscape)
@end example
+The music output will @emph{not} be rotated, just the paper size.
+
@seealso
Notation Reference:
@ref{Automatic scaling to paper size}.
@code{paper-width} can influence other values (this is separate
from scaling and is discussed below). The
@code{set-default-paper-size} and @code{set-paper-size} functions
-are described in @ref{Setting paper size}.
+are described in @ref{Setting the paper size}.
The vertical dimensions affected by automatic scaling are
@code{top-margin} and @code{bottom-margin} (see
@c used for news about the upcoming release; see CG 10.2
+@newsItem
+@subsubheading LilyPond 2.15.34 released! @emph{Mar 19, 2012}
+
+We are happy to announce the release of LilyPond 2.15.34. 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 Critical bugs, this is not the next release
+candidate.
+
+@newsEnd
+
+
@newsItem
@subsubheading LilyPond 2.15.33 released! @emph{Mar 08, 2012}
$(MAKE) -C input/regression/abc2ly out=test local-test
$(MAKE) -C input/regression/lilypond-book out=test local-test
-test-baseline:
+ifndef BASELINE_COMMIT
+BASELINE_COMMIT:=HEAD
+endif
+
+ifdef LILYPOND_BASELINES
+BASELINE_ARCHIVE:=$(LILYPOND_BASELINES)/baseline-$(shell git rev-list -1 $(BASELINE_COMMIT)).tar.gz
+
+test-baseline: $(BASELINE_ARCHIVE)
+ tar xzf $(BASELINE_ARCHIVE)
+ $(MAKE) test-snippets-clean
+
+$(BASELINE_ARCHIVE):
+ $(MAKE) test-baseline-create
+ tar czf $(BASELINE_ARCHIVE) input/regression/out-test-baseline \
+ input/regression/midi/out-test-baseline \
+ input/regression/musicxml/out-test-baseline \
+ input/regression/abc2ly/out-test-baseline \
+ input/regression/lilypond-book/out-test-baseline
+else
+test-baseline: test-baseline-create
+ $(MAKE) test-snippets-clean
+endif
+
+test-baseline-create:
@if test -d .git ; then \
- $(if $(shell git diff), echo "commit before base lining" && false,true) ; \
+ $(if $(shell git diff $(BASELINE_COMMIT)), echo "commit before base lining" && false,true) ; \
fi
$(MAKE)
$(MAKE) test
$(MAKE) out=test -C input/regression/musicxml local-test-baseline
$(MAKE) out=test -C input/regression/abc2ly local-test-baseline
$(MAKE) out=test -C input/regression/lilypond-book local-test-baseline
- $(MAKE) test-snippets-clean
-
local-check: test
rm -rf $(RESULT_DIR)
mkdir -p $(RESULT_DIR)
- $(buildscript-dir)/output-distance --create-images --output-dir $(RESULT_DIR) \
+ $(buildscript-dir)/output-distance --local-datadir --create-images --output-dir $(RESULT_DIR) \
input/regression/out-test-baseline input/regression/out-test \
input/regression/midi/out-test-baseline input/regression/midi/out-test
@find input ly -name '*.ly' -print |grep -v 'out.*/' | xargs grep '\\version' -L | grep -v "standard input" |sed 's/^/**** Missing version: /g'
| |-- notation/ Notation Reference
| |-- usage/ Usage
| |-- web/ The website
-| | `-- ly-examples/ .ly files for the "Examples" page
| |
| |
| | TRANSLATED MANUALS:
| | * individual chapters for each manual
| | 2) a texidocs/ directory for snippet translations
| |
+| |-- cs/ Czech
| |-- de/ German
| |-- es/ Spanish
| |-- fr/ French
| |-- it/ Italian
| |-- ja/ Japanese
| |-- nl/ Dutch
+| |-- zh/ Chinese
| |
| |
| | MISCELLANEOUS DOC STUFF:
| |-- css/ CSS files for HTML docs
| |-- included/ .ly files used in the manuals
| |-- logo/ Web logo and "note" icon
+| |-- ly-examples/ .ly files for the "Examples" webpage
| |-- misc/ Old announcements, ChangeLogs and NEWS
| |-- pictures/ Images used (eps/jpg/png/svg)
| | `-- pdf/ (pdf)
|-- input/
| `-- regression/ .ly regression tests
| |-- abc2ly/ .abc regression tests
+| |-- lilypond-book/ lilypond-book regression tests
+| |-- midi/ midi2ly regression tests
| `-- musicxml/ .xml and .itexi regression tests
|
|
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=15
-PATCH_LEVEL=34
+PATCH_LEVEL=35
MY_PATCH_LEVEL=
VERSION_STABLE=2.14.2
-VERSION_DEVEL=2.15.33
+VERSION_DEVEL=2.15.34
\version "2.14.0"
+\paper { ragged-right = ##t }
\header {
texidoc = "When a tie is broken, the spacing engine must consider the
-accidental after the line break, to prevent a collision from occurring."
+accidental after the line break. The second and third lines should have
+the same note spacing."
}
-{ \key g \major gis''1~ \break gis''4
-\repeat unfold 43 {d4 \noBreak} }
+{ \key bes \major r1 \break
+ eses''4 r2 eses''4~ \break
+ eses''4 r2 f''4
+}
--- /dev/null
+\version "2.15.34"
+
+\header {
+
+ texidoc = "Autobeam rechecking works properly with tuplets.
+In the example, the first beat should be beamed completely together."
+
+}
+
+\relative c' {
+ \time 2/4
+ c16 c
+ \times 2/3 { c8 c16 }
+ \times 2/3 { c8 c16 }
+ c16 c
+}
-
\version "2.14.0"
\header{
\relative c'{
- \override Beam #'skip-quanting = ##t
\stemUp
f'4 f8[ f] f16[ f] f32[ f] f64[ f] f128[ f]
}
-
-\version "2.14.0"
+\version "2.13.34"
\header {
- texidoc = "Seconds do not confuse the collision algorithm too much. The best
-way to format this would be to merge the two Ds, but we will be happy for now
-if the upstem D does not collide with the downstem C."
+ texidoc = "Seconds do not confuse the collision algorithm.
+The first pair of chords in each measure should merge, mesh,
+or come relatively close, but the second in each measure needs
+more space to make clear which notes belong to which voice."
}
-
-<< d' \\ <c' d'> >>
+\relative f << {
+ <a' b>2 <a b d e> <a e' f> <a e' f> <a b c> <f g a>
+ \bar "||" <f g c> <g a c> <f g c d> <f g c d>
+} \\ {
+ <g a> <a b> <g a e'> <g a c e> <f g a> <a b c>
+ <g a e'> <g a e'> <g c d> <g a b>
+} >>
--- /dev/null
+\version "2.15.34"
+
+\header {
+ texidoc = "Dot Columns are engraved in the Staff by default,
+enabling dots to move vertically to make room for dots from another voice.
+If Dot_column_engraver is moved to Voice, separate dot columns are engraved,
+and these dots avoid notes in other voices."
+}
+
+music = \relative c'' { \time 3/4 << {
+ <d f g>4. c c b g f a <a b> a <a' b>
+} \\ \times 1/2 {
+ <f, g b>2. a-- <a b> <g a>-. a2. a-- a a b <a b> \bar "|."
+} >> }
+
+\score{ \music }
+\markup "move Dot_column_engraver to Voice :"
+\score{ \music
+\layout {
+ \context {\Staff \remove Dot_column_engraver}
+ \context {\Voice \consists Dot_column_engraver}
+}}
a4\f d fis8-. a-. r4
d16(\downbow cis b a) g4 \breathe e8\p( g) fis4 |
- e4\< g8 fis g4-_\mp\>
+ e4\< \glissando g8 fis g4-_\mp\>
\st "III"
b8-_\startTextSpan a-_\stopTextSpan
b4\p\<( d8 cis) d4(-. fis8-.^"II" e-.^"II")
#(whitelist-grob 'NoteHead)
#(whitelist-grob 'Stem)
#(whitelist-grob 'Flag)
-#(whitelist-grob "NoteHead")
-#(whitelist-grob "Stem")
-#(whitelist-grob "Flag")
#(for-each whitelist-symbol '(stencil style duration-log
stem-attachment end-position staff-position
--- /dev/null
+\version "2.14.0"
+\score {
+ \relative c'' { d c b c }
+}
--- /dev/null
+myVar = { a b c a }
\documentclass{article}
\begin{document}
Including a LilyPond file without any options:
+
\lilypondfile{include2.ly}
+
+From a subdirectory:
+
+\lilypondfile{include/example.ly}
+
+Within a lilypond block:
+
+\begin{lilypond}
+ \include "include/myvar.ily"
+ \relative c'' { \myVar }
+\end{lilypond}
\end{document}
\documentclass{article}
\begin{document}
Including a LilyPond file with options (quote and noindent):
+
\lilypondfile[quote,noindent]{include2.ly}
+
+From a subdirectory:
+
+\lilypondfile[quote,noindent]{include/example.ly}
+
+Within a lilypond block:
+
+\begin{lilypond}[quote,noindent]
+ \include "include/myvar.ily"
+ \relative c'' { \myVar }
+\end{lilypond}
\end{document}
--- /dev/null
+\input texinfo @c -*- coding: utf-8; mode: texinfo; -*-
+@setfilename texinfo-include-file.info
+@settitle Include lilypond files in texinfo
+
+@node Top
+@top Include lilypond files in texinfo
+
+Lilypond files included in texinfo without any options:
+
+@lilypondfile{include2.ly}
+
+From a subdirectory:
+
+@lilypondfile{include/example.ly}
+
+Within a lilypond block:
+
+@lilypond
+ \include "include/myvar.ily"
+ \relative c'' { \myVar }
+@end lilypond
+
+@bye
--- /dev/null
+\version "2.15.35"
+
+\header {
+ texidoc = "Empty measures do not confuse @code{SpanBarStub}.
+These lyrics should remain clear of the span bars.
+"
+}
+
+\new StaffGroup <<
+ \new Staff { \repeat unfold 8 { R1 e'1 } }
+ \addlyrics {
+ Worked twice...
+ and then
+ I continued...
+ working... correctly.
+ }
+ \new Staff { R1*16 }
+>>
--- /dev/null
+\version "2.15.35"
+
+\header {
+ texidoc = "Tuplet number position is correct when slurs and scripts
+are present.
+"
+}
+
+\relative c'
+{
+ R1 |
+ \break
+ \times 2/3 { e8(-> e e) }
+}
tuplet_start_ = false;
}
-Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i, bool inv,
+Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i, bool inv,
Rational factor, bool tuplet_start)
{
start_moment_ = m;
Moment
Beaming_pattern::end_moment (int i) const
{
- Duration *dur = new Duration (2 + max (beamlet_count (i, LEFT),
- beamlet_count (i, RIGHT)),
- 0);
+ Duration dur (2 + max (beamlet_count (i, LEFT),
+ beamlet_count (i, RIGHT)),
+ 0);
- return infos_.at (i).start_moment_ + dur->get_length ();
+ return infos_.at (i).start_moment_
+ + infos_.at(i).factor_ * dur.get_length ();
}
bool
}
#endif
-static SCM modification_callback = SCM_EOL;
-static SCM cache_callback = SCM_EOL;
+static Protected_scm modification_callback = SCM_EOL;
+static Protected_scm cache_callback = SCM_EOL;
/*
FIXME: this should use ly:set-option interface instead.
class Stem
{
public:
- static vector<int> note_head_positions (Grob *);
+ static vector<int> note_head_positions (Grob *, bool filter = false);
static int duration_log (Grob *);
static void set_beaming (Grob *, int, Direction d);
static int get_beaming (Grob *, Direction d);
{
if (cached_pure_height_valid_)
return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
+ /* Note: cached_pure_height_ does not notice if start changes, implicitly
+ assuming that Items' pure_heights do not depend on 'start' or 'end'.
+ Accidental_interface::pure_height(), however, does depend on 'start'.
+ */
cache_pure_height (Grob::pure_height (this, start, end));
return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
Grob *head_up = Note_column::first_head (clash_up);
Grob *head_down = Note_column::first_head (clash_down);
- vector<int> ups = Stem::note_head_positions (Note_column::get_stem (clash_up));
- vector<int> dps = Stem::note_head_positions (Note_column::get_stem (clash_down));
+ /* Staff-positions of all noteheads on each stem */
+ vector<int> ups = Stem::note_head_positions (stems[UP]);
+ vector<int> dps = Stem::note_head_positions (stems[DOWN]);
/* Too far apart to collide. */
if (ups[0] > dps.back () + 1)
return;
+ /* If the chords just 'touch' their extreme noteheads,
+ then we can align their stems.
+ */
+ bool touch = false;
+ if (ups[0] >= dps.back ()
+ && (dps.size () < 2 || ups[0] >= dps[dps.size () - 2] + 2)
+ && (ups.size () < 2 || ups[1] >= dps.back () + 2))
+ touch = true;
+
+ /* Filter out the 'o's in this configuration, since they're no
+ * part in the collision.
+ *
+ * |
+ * x|o
+ * x|o
+ * x
+ *
+ */
+ ups = Stem::note_head_positions (stems[UP], true);
+ dps = Stem::note_head_positions (stems[DOWN], true);
+
/* Merge heads if the notes lie the same line, or if the "stem-up-note" is
above the "stem-down-note". */
bool merge_possible = (ups[0] >= dps[0]) && (ups.back () >= dps.back ());
*
*/
- /* TODO: filter out the 'o's in this configuration, since they're no
- * part in the collision.
- *
- * |
- * x|o
- * x|o
- * x
- *
- */
-
bool close_half_collide = false;
bool distant_half_collide = false;
bool full_collide = false;
full_collide = full_collide || (close_half_collide
&& distant_half_collide);
- /* If the only collision is in the extreme noteheads,
- then their stems can line up and the chords just 'touch'.
- A half collision with the next note along the chord prevents touching.
- */
- bool touch = false;
- if (ups[0] >= dps.back ()
- && (dps.size () < 2 || ups[0] >= dps[dps.size () - 2] + 2)
- && (ups.size () < 2 || ups[1] >= dps.back () + 2))
- touch = true;
-
/* Determine which chord goes on the left, and which goes right.
Up-stem usually goes on the right, but if chords just 'touch' we can put
both stems on a common vertical line. In the presense of collisions,
while ((flip (&d)) != UP);
/*
- do horizontal shifts of each direction
-
- |
- x||
- x||
- x|
+ * do horizontal shifts of each direction
+ *
+ * |
+ * x||
+ * x||
+ * x|
*/
do
int pos[2] = { -1, 0};
for (vsize i = 0; i < pure_relevants_.size (); i++)
{
- if (pos[1] < (int) need_pure_heights_from_neighbors.size ()
- && (pure_relevants_[i]->spanned_rank_interval ()[LEFT]
- > need_pure_heights_from_neighbors[pos[1]][0]->spanned_rank_interval ()[LEFT]))
+ while (pos[1] < (int) need_pure_heights_from_neighbors.size ()
+ && (pure_relevants_[i]->spanned_rank_interval ()[LEFT]
+ > need_pure_heights_from_neighbors[pos[1]][0]->spanned_rank_interval ()[LEFT]))
{
pos[0] = pos[1];
pos[1]++;
return exthead;
}
-/* The positions, in ascending order. */
+/* The staff positions, in ascending order.
+ * If FILTER, include the main column of noteheads only */
vector<int>
-Stem::note_head_positions (Grob *me)
+Stem::note_head_positions (Grob *me, bool filter)
{
vector<int> ps;
extract_grob_set (me, "note-heads", heads);
+ Grob *xref = common_refpoint_of_array (heads, me, X_AXIS);
for (vsize i = heads.size (); i--;)
{
Grob *n = heads[i];
- int p = Staff_symbol_referencer::get_rounded_position (n);
+ if (filter
+ && n->relative_coordinate (xref, X_AXIS) != 0.0)
+ continue;
+ int p = Staff_symbol_referencer::get_rounded_position (n);
ps.push_back (p);
}
if (scm_is_number (scripts[i]->get_property ("outside-staff-priority")))
continue;
+ // assume that if a script is avoiding slurs, it should not get placed
+ // under a tuplet bracket
+ SCM avoid = scripts[i]->get_property ("avoid-slur");
+ if (unsmob_grob (scripts[i]->get_object ("slur"))
+ && (avoid == ly_symbol2scm ("outside")
+ || avoid == ly_symbol2scm ("around")))
+ continue;
+
Interval script_x (scripts[i]->extent (commonx, X_AXIS));
Interval script_y (scripts[i]->extent (commony, Y_AXIS));
((string= articname "mordent")
(loop (cons 1 1) newelements tail (cons 'mordent actions)))
((string= articname "prall")
- (loop (cons 1 1) newelements tail (cons 'trill actions)))
+ (loop (cons 1 1) newelements tail (cons 'prall actions)))
((string= articname "trill")
(loop (cons 1 1) newelements tail (cons 'trill actions)))
((string= articname "turn")
((trill)
(ac:trill music))
+ ((prall)
+ ; A pralltriller symbol can either mean an inverted mordent
+ ; or a half-shake -- a short, two twiddle trill.
+ ; We implement as a half-shake.
+ (let*
+ ((totallength (ly:music-length music))
+ (newlen (ly:moment-sub totallength (ly:make-moment 3 32)))
+ (newdur (ly:make-duration
+ 0 0
+ (ly:moment-main-numerator newlen)
+ (ly:moment-main-denominator newlen)))
+ (gracedur (ly:make-duration 5 0 1 1))
+ (gracenote (ly:music-deep-copy music))
+ (abovenote (ly:music-deep-copy music))
+ (mainnote (ly:music-deep-copy music))
+ (prall (make-sequential-music (list gracenote abovenote)))
+ )
+ (music-map (lambda (n)
+ (if (eq? 'NoteEvent (ly:music-property n 'name))
+ (set! (ly:music-property n 'duration) gracedur))
+ n)
+ abovenote)
+ (music-map (lambda (n)
+ (if (eq? 'NoteEvent (ly:music-property n 'name))
+ (set! (ly:music-property n 'duration) gracedur))
+ n)
+ gracenote)
+ (music-map (lambda (n)
+ (if (eq? 'NoteEvent (ly:music-property n 'name))
+ (set! (ly:music-property n 'duration) newdur))
+ n)
+ mainnote)
+
+ (map (lambda (y) (ac:up y))
+ (filter
+ (lambda (z) (eq? 'NoteEvent (ly:music-property z 'name)))
+ (ly:music-property abovenote 'elements)))
+ (make-sequential-music (list abovenote gracenote abovenote mainnote))))
+
((mordent)
(let*
- ((dur (ly:music-property
+ ((totaldur (ly:music-property
(car (ly:music-property music 'elements)) 'duration))
- (factor (ly:duration-factor dur))
+ (dur (ly:duration-length totaldur))
+ (newlen (ly:moment-sub dur (ly:make-moment 2 32)))
+ (newdur (ly:make-duration
+ 0 0
+ (ly:moment-main-numerator newlen)
+ (ly:moment-main-denominator newlen)))
(gracenote (ly:music-deep-copy music))
- (mainnote (ly:music-deep-copy music))
(belownote (ly:music-deep-copy music))
+ (mainnote (ly:music-deep-copy music))
(mordent (make-sequential-music (list gracenote belownote)))
-)
+ )
(begin
(music-map (lambda (n)
(if (eq? 'NoteEvent (ly:music-property n 'name))
- (set! (ly:music-property n 'duration)(ly:make-duration 3 0 1 1)))
+ (set! (ly:music-property n 'duration)
+ (ly:make-duration 5 0 1 1)))
n)
mordent)
+ (music-map (lambda (n)
+ (if (eq? 'NoteEvent (ly:music-property n 'name))
+ (set! (ly:music-property n 'duration) newdur))
+ n)
+ mainnote)
(map (lambda (y) (ac:down y))
(filter
(lambda (z) (eq? 'NoteEvent (ly:music-property z 'name)))
(ly:music-property belownote 'elements)))
- (make-sequential-music (list (make-grace-music mordent) mainnote)))))
+ (make-sequential-music (list mordent mainnote)))))
((turn)
(let*
((dur (ly:music-property
\consists "Font_size_engraver"
\consists "Separating_line_group_engraver"
+ \consists "Dot_column_engraver"
\consists "Staff_collecting_engraver"
%% perhaps move to Voice context?
\consists "Breathing_sign_engraver"
\consists "Note_heads_engraver"
\consists "Dots_engraver"
- \consists "Dot_column_engraver"
\consists "Rest_engraver"
\consists "Tweak_engraver"
\consists "Footnote_engraver"
(print-line engraver
"breathe"))
+#(define (format-glissando engraver event)
+ (print-line engraver
+ "gliss"))
+
#(define (format-tie engraver event)
(print-line engraver
"tie"))
(crescendo-event . format-cresc)
(decrescendo-event . format-decresc)
(text-span-event . format-textspan)
+ (glissando-event . format-glissando)
(tie-event . format-tie)))
}
}
#(define (whitelist-symbol sym)
(set! sym-whitelist (cons sym sym-whitelist)))
-#(define (whitelist-grob str)
- (set! grob-whitelist (cons str grob-whitelist)))
+#(define (whitelist-grob sym)
+ (set! grob-whitelist (cons sym grob-whitelist)))
#(define graph (make-empty-graph (ly:parser-output-name parser)))
\version "2.15.18"
-\include "declarations-init.ly"
+#(if (not (pair? lilypond-declarations))
+ (ly:parser-include-string parser
+ "\\include \"declarations-init.ly\""))
+%% We need to save the variables of the current module along with
+%% their values: functions defined in the module might refer to the
+%% variables
+
+#(if lilypond-declarations
+ (if (pair? lilypond-declarations)
+ (begin
+ (for-each
+ (lambda (p)
+ (let ((var (cadr p))
+ (val (cddr p)))
+ (variable-set! var
+ (if (ly:output-def? val)
+ (ly:output-def-clone val)
+ val))
+ (module-add! (current-module) (car p) var)))
+ lilypond-declarations)
+ (note-names-language parser default-language))
+ (module-for-each
+ (lambda (s v)
+ (let ((val (variable-ref v)))
+ (if (not (ly:lily-parser? val))
+ (set! lilypond-declarations
+ (cons
+ (cons*
+ s v
+ (if (ly:output-def? val)
+ (ly:output-def-clone val)
+ val))
+ lilypond-declarations)))))
+ (current-module))))
#(ly:set-option 'old-relative #f)
#(define toplevel-scores (list))
#(define expect-error #f)
#(define output-empty-score-list #f)
#(define output-suffix #f)
+#(hash-clear! default-fret-table)
+#(hash-clear! chord-shape-table)
+#(hash-clear! musicQuotes)
+
#(use-modules (scm clip-region))
+#(use-modules (srfi srfi-1))
$(if (ly:get-option 'include-settings)
(ly:parser-include-string parser
cp $< $(outdir)
$(outdir)/%-midi.ly: $(outdir)/%.midi $(MIDI2LY)
- (echo '\header {'; for f in $(HEADER_FIELDS); do echo -n $$f'="'; cat $(outdir)/$*.$$f; echo '"'; done; echo '}') > $(outdir)/$*.header
+ (echo '\header {'; for f in $(HEADER_FIELDS); do printf $$f'="'; cat $(outdir)/$*.$$f; echo '"'; done; echo '}') > $(outdir)/$*.header
$(PYTHON) $(MIDI2LY) $(shell cat $(outdir)/$*.options) --quiet --include-header=$(outdir)/$*.header -o $(outdir) $<
$(outdir)/%.diff: %.ly $(outdir)/%-midi.ly
(SpanBarStub
. (
(X-extent . ,grob::x-parent-width)
- (Y-extent . ,(ly:make-unpure-pure-container #f ly:axis-group-interface::pure-height))
+ (extra-spacing-height . ,pure-from-neighbor-interface::extra-spacing-height)
+ (Y-extent . #f)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
(define (add-cluster graph node-id cluster-name)
(let* ((cs (clusters graph))
- (cluster (assq cluster-name cs))
+ (cluster (assoc cluster-name cs))
(already-in-cluster (if cluster
(cdr cluster)
'())))
- (set-clusters! graph (assq-set! cs
+ (set-clusters! graph (assoc-set! cs
cluster-name
(cons node-id already-in-cluster)))))
(define (add-node graph label . cluster-name)
(let* ((ns (nodes graph))
(id (length ns)))
- (set-nodes! graph (assq-set! ns id label))
+ (set-nodes! graph (assv-set! ns id label))
(if (and (not (null? cluster-name))
(string? (car cluster-name)))
(add-cluster graph id (car cluster-name)))
(dump-profile "lily-run-total" '(0 0) (profile-measurements)))
failed))
+(define-public lilypond-declarations '())
+
(define (lilypond-file handler file-name)
(catch 'ly-file-failed
(lambda () (ly:parse-file file-name))
(map loop arts)))
music))))
+(define-public (for-some-music stop? music)
+ "Walk through @var{music}, process all elements calling @var{stop?}
+and only recurse if this returns @code{#f}."
+ (let loop ((music music))
+ (if (not (stop? music))
+ (let ((elt (ly:music-property music 'element)))
+ (if (ly:music? elt)
+ (loop elt))
+ (for-each loop (ly:music-property music 'elements))
+ (for-each loop (ly:music-property music 'articulations))))))
+
+(define-public (fold-some-music pred? proc init music)
+ "This works recursively on music like @code{fold} does on a list,
+calling @samp{(@var{pred?} music)} on every music element. If
+@code{#f} is returned for an element, it is processed recursively
+with the same initial value of @samp{previous}, otherwise
+@samp{(@var{proc} music previous)} replaces @samp{previous}
+and no recursion happens.
+The top @var{music} is processed using @var{init} for @samp{previous}."
+ (let loop ((music music) (previous init))
+ (if (pred? music)
+ (proc music previous)
+ (fold loop
+ (fold loop
+ (let ((elt (ly:music-property music 'element)))
+ (if (null? elt)
+ previous
+ (loop elt previous)))
+ (ly:music-property music 'elements))
+ (ly:music-property music 'articulations)))))
+
(define-public (extract-music music pred?)
"Return a flat list of all music matching @var{pred?} inside of
@var{music}, not recursing into matches themselves."
- (reverse!
- (let loop ((music music) (res '()))
- (if (pred? music)
- (cons music res)
- (fold loop
- (fold loop
- (let ((elt (ly:music-property music 'element)))
- (if (null? elt)
- res
- (loop elt res)))
- (ly:music-property music 'elements))
- (ly:music-property music 'articulations))))))
+ (reverse! (fold-some-music pred? cons '() music)))
(define-public (extract-named-music music music-name)
"Return a flat list of all music named @var{music-name} (either a
(cons -0.1 0.1)))
(define-public (pure-from-neighbor-interface::extra-spacing-height grob)
- (let* ((height (ly:grob::stencil-height grob))
+ (let* ((height (ly:grob-pure-height grob grob 0 10000000))
(from-neighbors (interval-union
height
(ly:axis-group-interface::pure-height
;; don't use decimals.
;; ISO 216 has a tolerance of +- 2mm
+ ;; TODO Autogenerate the following list so it appears under the
+ ;; 'Predefined paper sizes' node in notation-appendices.itely
+ ;; currently the list below has been copied and formatted manually.
+ ;; Therefore, please add any new entries to the *itely file as well.
+
'(("a10" . (cons (* 26 mm) (* 37 mm)))
("a9" . (cons (* 37 mm) (* 52 mm)))
("a8" . (cons (* 52 mm) (* 74 mm)))
if (show_output):
sys.stdout.write ("Running bibtex on %s\n" % files)
+ sys.stdout.write (cmd)
#And invoke it
stat = os.system (cmd)
if stat <> 0:
- sys.exit(1)
+ sys.stderr.write ("Bibtex exited with nonzero exit status!")
+ sys.exit (1)
#TODO: do tex -> itexi on output
-# Following 2 lines copy tmpfile.bbl to the desired output file
+# Following lines copy tmpfile.bbl to the desired output file
bbl = open (tmpfile + '.bbl').read ()
+if bbl.strip () == '':
+ sys.stderr.write ("Bibtex generated an empty file!")
+ sys.exit (1)
+
open (output, 'w').write (bbl)
def cleanup (tmpfile):
def system (c):
print c
if os.system (c):
- raise 'barf'
+ raise Exception('The command exited with nonzero exit status!')
outputs = []
for sz in [48,32,16] :
def read_log_file (fn):
str = open (fn).read ()
- str = re.sub ('\n', '', str)
+ str = re.sub ('[\n\r]', '', str)
str = re.sub ('[\t ]+', ' ', str)
deps = []
}
group = ''
- for l in autolines:
+ for i, l in enumerate(autolines):
tags = l.split ('@:')
if tags[0] == 'group':
group = tags[1]
elif tags[0] == 'puorg':
group = ''
elif tags[0] == 'char':
- name = tags[9]
+ try:
+ name = tags[9]
+ except IndexError:
+ print 'Error in mf-to-table while processing file', fn
+ print 'Index 9 >', len(tags)-1, 'on line', i
+ print l
+ raise
if group:
name = group + '.' + name
sub get_bboxes ($)
{
execute_command 1, ("mpost", "-mem=mf2pt1", "-progname=mpost",
- "\\mode:=localfont; mag:=$mag; bpppix $bpppix; input $mffile");
+ "\\mode:=localfont; mag:=$mag; bpppix $bpppix; nonstopmode; input $mffile");
opendir (CURDIR, ".") || die "${progname}: $! ($filedir)\n";
@charfiles = sort
{ ($a=~ /\.(\d+)$/)[0] <=> ($b=~ /\.(\d+)$/)[0] }
else:
sys.exit (i)
-def identify ():
- ly.encoded_write (sys.stdout, '%s (GNU LilyPond) %s\n' % (ly.program_name, ly.program_version))
-
progress = ly.progress
warning = ly.warning
error = ly.error
+def identify ():
+ progress('%s (GNU LilyPond) %s' % (ly.program_name, ly.program_version))
def warranty ():
identify ()
progress (_ ("Removing `%s'") % output_filename)
raise BookSnippet.CompileError
+def inverse_relpath (path, relpath):
+ """Given two paths, the second relative to the first,
+ return the first path relative to the second."""
+ if os.path.isabs (relpath):
+ return os.path.abspath (path)
+ relparts = ['']
+ parts = os.path.normpath (path).split (os.path.sep)
+ for part in os.path.normpath (relpath).split (os.path.sep):
+ if part == '..':
+ relparts.append (parts[-1])
+ parts.pop ()
+ else:
+ relparts.append ('..')
+ parts.append (part)
+ return os.path.sep.join (relparts[::-1])
+
def do_options ():
global global_options
global_options.information = {'program_version': ly.program_version, 'program_name': ly.program_name }
global_options.original_dir = original_dir
+ if global_options.output_dir:
+ global_options.output_dir = os.path.expanduser (global_options.output_dir)
+ global_options.include_path.insert (0, inverse_relpath (original_dir, global_options.output_dir))
+
# Load the python packages (containing e.g. custom formatter classes)
# passed on the command line
nr = 0
exit 2
fi
+ abssrcdir="`cd $srcdir; pwd`"
+ absbuilddir="`pwd`"
for d in 2 3 4 ; do
for mf in `cd $srcdir ; find . -maxdepth $d -mindepth $d -name GNUmakefile`; do
- mkdir -p $(dirname $mf)
+ case "$abssrcdir" in
+ "$absbuilddir"/*)
+# source is below build directory, always copy
+ ;;
+ *)
+ case "$abssrcdir/${mf#./}" in
+ "$absbuilddir"/*)
+# find descended into build directory, don't copy
+ continue
+ esac
+ esac
+ mkdir -p ${mf%/*}
cat <<EOF | $PYTHON - > $mf
print 'depth=' + ('../' * ( $d-1 ) )
print 'include \$(depth)/config\$(if \$(conf),-\$(conf),).make'
EOF
done
for mf in `cd $srcdir ; find . -maxdepth $d -mindepth $d -name '*.make' | grep -v config.make `; do
- mkdir -p $(dirname $mf)
+ case "$abssrcdir" in
+ "$absbuilddir"/*)
+# source is below build directory, always copy
+ ;;
+ *)
+ case "$abssrcdir/${mf#./}" in
+ "$absbuilddir"/*)
+# find descended into build directory, don't copy
+ continue
+ esac
+ esac
+ mkdir -p ${mf%/*}
cat <<EOF | $PYTHON - > $mf
print 'include \$(depth)/config\$(if \$(conf),-\$(conf),).make'
print 'include \$(configure-srcdir)/$mf'