@end ignore
@item
-Lilypond typesets woodwind fingering charts.
+Single beat repeats for sixteenth or shorter notes and beat repeats for
+measures containing notes of varying durations are now supported.
+
+@lilypond[fragment,relative=2]
+\repeat percent 2 { c16 d }
+\repeat percent 2 { c32 e }
+\repeat percent 2 { c64 f }
+\repeat percent 2 { c128 g' }
+@end lilypond
+
+
+@item
+Lilypond now engraves woodwind fingering charts.
+
@lilypond
\relative c' {
\textLengthOn
}
@end lilypond
+@item
+MIDI output has been improved
+@itemize @bullet
+@item voices are kept separated, which makes the MIDI much more useful for postprocessing
+@item optimal channel distribution: identical instruments share the same channel. This means that e.g. for a full orchestral score there are always 16 (15 plus percussion) diffently sounding instruments available, unrestricted by the number of staves or voices.
+@item dynamics are now rendered as note velocities, no longer as midi dynamics. This improves the sound on [high end] midi renderers.
+@end itemize
+
@item
MIDI-import through Midi2ly is improved
@itemize @bullet
@end lilypond
@item
-Black mensural notation has minimal support.
+Added minimal support for black mensural notation.
@item
-Support for obliqua shapes within white mensural ligatures enhanced.
+Enhanced support for obliqua shapes within white mensural ligatures.
+
@lilypond
\context MensuralStaff
{
@item
Compound time signatures are now supported by the @code{\compoundMeter} command,
which can be used instead of @code{\time}:
+
@lilypond
\relative c'' {
\compoundMeter #'(3 1 8)
clef, which is correctly reset at the end of the cue notes. At the begin
of each line, the standard clef is still displayed, but the cue clef is
shown after the time/key signature in smaller size.
+
@lilypond
vI = \relative c'' { \clef "treble" \repeat unfold 40 g4 }
\addQuote vIQuote { \vI }
@item
The part-combiner's decision to combine/not combine notes can now be customized
+
@lilypond[quote,relative=2]
\partcombine
\relative c' { c2 \partcombineApart c | \partcombineChordsOnce e' e }
@menu
* Build system overview::
* Tips for working on the build system::
+* General build system notes::
* Doc build::
* Website build::
* Building an Ubuntu distro::
to the build system files in various places. This will let you
track where the program is, in various points of the build.
+PH note. There are lots of places where Make doesn't let you put
+echo commands. My top tip for tracing how make runs is to put
+
+@example
+$(error Some Text to display)
+@end example
+
+This will stop make running and print the text @code{Some Text to
+display}.
+
+End PH note.
+
@item
First task: understand how @code{make website} works,
@emph{without} the translations. Looking at the english-only
@end itemize
-
-@node Doc build
-@section Doc build
+@node General build system notes
+@section General build system notes
@menu
-* Building a bibliography::
+* How stepmake works::
@end menu
-@node Building a bibliography
-@subsection Building a bibliography
-
-Bibliography files contain a list of citations, like this:
-
-@example
-@@Book@{vinci,
- author = @{Vinci, Albert C.@},
- title = @{Fundamentals of Traditional Music Notation@},
- publisher = @{Kent State University Press@},
- year = @{1989@}
-@}
-@end example
-
-There are a variety of types of citation (e.g. Book (as above),
-article, publication). Each cited publication has a list of
-entries that can be used to identify the publication.
-Bibliograpies are normally stored as files with a .bib
-extension. One part of the doc-build process is transforming the
-bibliography information into @code{texinfo} files. The commands
-to do this are in the @file{GNUmakefile} in the
-@file{Documentation} directory.
-
-A typical line of the makefile to translate a single bibliography
-is:
-
-@example
-$(outdir)/colorado.itexi:
- BSTINPUTS=$(src-dir)/essay $(buildscript-dir)/bib2texi \
- -s $(top-src-dir)/Documentation/lily-bib \
- -o $(outdir)/colorado.itexi \
- $(src-dir)/essay/colorado.bib
-@end example
-
-Line by line:
-
-@example
-$(outdir)/colorado.itexi:
-@end example
-
-We're making the file @file{colorado.itexi} and so this is the
-make instruction.
-
-@example
- BSTINPUTS=$(src-dir)/essay $(buildscript-dir)/bib2texi \
-@end example
-
-It's in the @file{essay} directory and we want to run the
-bib2texi.py script against it.
-
-@example
- -s $(top-src-dir)/Documentation/lily-bib \
-@end example
-
-The style template is @file{lily-bib.bst} and is found in the
-@file{Documentation} directory.
-
-@example
- -o $(outdir)/colorado.itexi \
-@end example
-
-The output file in @file{colorado.itexi}.
-
-@example
- $(src-dir)/essay/colorado.bib
-@end example
-
-The input file is @file{colorado.bib} in the @file{essay}
-directory.
-
-The @code{bib2texi} Python script used to be used with a variety
-of options, but now is always called using the same options, as
-above. Its job is to create the file containing the options for
-@code{bibtex} (the program that actually does the translation),
-run bibtex, and then clean up some temporary files. Its main
-"value add" is the creation of the options file, using this code:
-
-@example
-open (tmpfile + '.aux', 'w').write (r'''
-\relax
-\citation@{*@}
-\bibstyle@{%(style)s@}
-\bibdata@{%(files)s@}''' % vars ())
-@end example
-
-The key items are the style file (now always lily-bib for us) and
-the input file.
-
-The style file is written in its own specialised language,
-described to some extent at
-
-@example
-@uref{http://amath.colorado.edu/documentation/LaTeX/reference/faq/bibtex.pdf}
-@end example
-
-The file @file{lily-bib.bst} also has fairly extensive commenting.
-
-@node Website build
-@section Website build
-
-Start here: @file{make/website.make}
+@node How stepmake works
+@subsection How stepmake works
Typing make website runs the file @file{GNUmakefile} from the
build directory. This only contains 3 lines:
experimented with it 5 years ago or something. It seems like we
still have bits and pieces of it floating around.
-GP: note that *none* of the variables that are loaded (from depth
-to version numbers to whatever) are used in website.make.
-Instead, website.make sets up its own variables at the top of the
-file. If you're wondering if there's some smart reason for this,
-then the answer is "no". It's because I didn't know/trust the
-original variables when I was writing that file.
-
Next, it runs @file{make/toplevel-version.make}, which sets the
version variables for major, minor, patch, stable, development and
mypatchlevel (which seems to be used for patch numbers for
@end example
@file{lilypond-rules.make} is @code{#empty}
+
@file{generic-rules.make} does seem to have 2 rules in it. They
are:
can comment on exactly what the rules mean/do.
@file{toplevel-rules.make} is @code{#empty}
+
@file{po-rules.make} is @code{#empty}
+
@file{install-rules.make} is @code{#empty}
+
@file{generic-targets.make} contains 2 lines of comments.
+
@file{lilypond-targets.make} contains only:
@example
@file{stepmake/install-targets.make} has rules for local-install*.
And that's the end of stepmake.make. Back to
-@file{GNUmakefile.in}. More some other time.
+@file{GNUmakefile.in}.
+
+A bit more info from 27 March. I've put some error traces into
+@code{GNUmakefile} in the build directory, and it looks like the
+following lines actually cause the make to run (putting an error
+call above them - no make; below them - make):
+
+@example
+ifeq ($(out),www)
+# All web targets, except info image symlinks and info docs are
+# installed in non-recursing target from TOP-SRC-DIR
+install-WWW:
+ -$(INSTALL) -m 755 -d $(DESTDIR)$(webdir)
+ rsync -rl --exclude='*.signature' $(outdir)/offline-root $(DESTDIR)$(webdir)
+ $(MAKE) -C Documentation omf-local-install
+@end example
+
+I don't currently understand the @code{ifeq}, since @code{$(out)}
+is empty at this point, but the line starting @code{-$(INSTALL)}
+translates to:
+
+@example
+-/usr/bin/python /home/phil/lilypond-git/stepmake/bin/install.py -c -m 755 -d /usr/local/share/doc/lilypond/html
+@end example
+
+End of work for Sunday 27th.
Another alterative approach to understanding the website build
would be to redirect @code{make -n website} and @code{make website}
begin from the command-line that I want to modify, figure out
where it's generated, and then figure out how to change the
generated command-line), rather than a "front first" (where you
-begin from the "make" command). In the long term, we should
-probably move it to a general "how stepmake works" section,
-because it's not particularly relevant to the website build.
+begin from the "make" command).
+
+
+@node Doc build
+@section Doc build
+
+@menu
+* Building a bibliography::
+@end menu
+
+@node Building a bibliography
+@subsection Building a bibliography
+
+Bibliography files contain a list of citations, like this:
+
+@example
+@@Book@{vinci,
+ author = @{Vinci, Albert C.@},
+ title = @{Fundamentals of Traditional Music Notation@},
+ publisher = @{Kent State University Press@},
+ year = @{1989@}
+@}
+@end example
+
+There are a variety of types of citation (e.g. Book (as above),
+article, publication). Each cited publication has a list of
+entries that can be used to identify the publication.
+Bibliograpies are normally stored as files with a .bib
+extension. One part of the doc-build process is transforming the
+bibliography information into @code{texinfo} files. The commands
+to do this are in the @file{GNUmakefile} in the
+@file{Documentation} directory.
+
+A typical line of the makefile to translate a single bibliography
+is:
+
+@example
+$(outdir)/colorado.itexi:
+ BSTINPUTS=$(src-dir)/essay $(buildscript-dir)/bib2texi \
+ -s $(top-src-dir)/Documentation/lily-bib \
+ -o $(outdir)/colorado.itexi \
+ $(src-dir)/essay/colorado.bib
+@end example
+
+Line by line:
+
+@example
+$(outdir)/colorado.itexi:
+@end example
+
+We're making the file @file{colorado.itexi} and so this is the
+make instruction.
+
+@example
+ BSTINPUTS=$(src-dir)/essay $(buildscript-dir)/bib2texi \
+@end example
+
+It's in the @file{essay} directory and we want to run the
+bib2texi.py script against it.
+
+@example
+ -s $(top-src-dir)/Documentation/lily-bib \
+@end example
+
+The style template is @file{lily-bib.bst} and is found in the
+@file{Documentation} directory.
+
+@example
+ -o $(outdir)/colorado.itexi \
+@end example
+
+The output file in @file{colorado.itexi}.
+
+@example
+ $(src-dir)/essay/colorado.bib
+@end example
+
+The input file is @file{colorado.bib} in the @file{essay}
+directory.
+
+The @code{bib2texi} Python script used to be used with a variety
+of options, but now is always called using the same options, as
+above. Its job is to create the file containing the options for
+@code{bibtex} (the program that actually does the translation),
+run bibtex, and then clean up some temporary files. Its main
+"value add" is the creation of the options file, using this code:
+
+@example
+open (tmpfile + '.aux', 'w').write (r'''
+\relax
+\citation@{*@}
+\bibstyle@{%(style)s@}
+\bibdata@{%(files)s@}''' % vars ())
+@end example
+
+The key items are the style file (now always lily-bib for us) and
+the input file.
+
+The style file is written in its own specialised language,
+described to some extent at
+
+@example
+@uref{http://amath.colorado.edu/documentation/LaTeX/reference/faq/bibtex.pdf}
+@end example
+
+The file @file{lily-bib.bst} also has fairly extensive commenting.
+
+@node Website build
+@section Website build
+
+Start here: @file{make/website.make}
+
+The overall build system begins with @ref{How stepmake works}.
+
+However, we do believe that note that *none* of the variables that
+are loaded (from depth to version numbers to whatever) are used in
+@file{website.make}. Instead, @file{website.make} sets up its own
+variables at the top of the file. If you're wondering if there's
+some smart reason for this, then the answer is "no". It's because
+I didn't know/trust the original variables when I was writing that
+file.
+
Website build includes @ref{Building a bibliography}.
+@subsubheading Output from @code{make -n website}
+
+Running @code{make -n website} gives the following output:
+
+@smallexample
+make --no-builtin-rules config_make=./config.make \
+ top-src-dir=/home/phil/lilypond-git \
+ -f /home/phil/lilypond-git/make/website.make \
+ website
+make[1]: Entering directory `/home/phil/lilypond-git/build'
+mkdir -p out-website
+python /home/phil/lilypond-git/scripts/build/create-version-itexi.py /home/phil/lilypond-git > out-website/version.itexi
+python /home/phil/lilypond-git/scripts/build/create-weblinks-itexi.py /home/phil/lilypond-git > out-website/weblinks.itexi
+for l in '' cs de es fr hu it ja nl zh; do \
+ python /home/phil/lilypond-git/scripts/build/extract_texi_filenames.py \
+ -I /home/phil/lilypond-git/Documentation \
+ -I /home/phil/lilypond-git/Documentation/"$l" \
+ -I out-website -o out-website --split=node \
+ /home/phil/lilypond-git/Documentation/"$l"/web.texi ;\
+ for m in /home/phil/lilypond-git/Documentation/changes.tely /home/phil/lilypond-git/Documentation/essay.tely /home/phil/lilypond-git/Documentation/extending.tely /home/phil/lilypond-git/Documentation/learning.tely /home/phil/lilypond-git/Documentation/music-glossary.tely /home/phil/lilypond-git/Documentation/notation.tely /home/phil/lilypond-git/Documentation/snippets.tely /home/phil/lilypond-git/Documentation/usage.tely /home/phil/lilypond-git/Documentation/contributor.texi; do \
+ n=`echo "$m" | sed 's/Documentation/Documentation\/'$l'/'` ; \
+ b=`basename "$n" .texi`; \
+ d=`basename "$b" .tely`; \
+ if [ -e "$n" ] ; then \
+ python /home/phil/lilypond-git/scripts/build/extract_texi_filenames.py \
+ -I /home/phil/lilypond-git/Documentation \
+ -I /home/phil/lilypond-git/Documentation/"$l" \
+ -I /home/phil/lilypond-git/Documentation/"$l"/"$d" \
+ -I out-website -o out-website "$n" ; \
+ fi ; \
+ done; \
+ done;
+BSTINPUTS=/home/phil/lilypond-git/Documentation/web \
+ python /home/phil/lilypond-git/scripts/build/bib2texi.py -s web \
+ -s /home/phil/lilypond-git/Documentation/lily-bib \
+ -o out-website/others-did.itexi \
+ /home/phil/lilypond-git/Documentation/web/others-did.bib
+BSTINPUTS=/home/phil/lilypond-git/Documentation/web \
+ python /home/phil/lilypond-git/scripts/build/bib2texi.py -s web \
+ -s /home/phil/lilypond-git/Documentation/lily-bib \
+ -o out-website/we-wrote.itexi \
+ /home/phil/lilypond-git/Documentation/web/we-wrote.bib
+for l in '' cs de es fr hu it ja nl zh; do \
+ if test -n "$l"; then \
+ langopt=--lang="$l"; \
+ langsuf=.$l; \
+ fi; \
+ ONLY_WEB=1 TOP_SRC_DIR=/home/phil/lilypond-git DEPTH= PERL_UNICODE=SD texi2html --prefix=index \
+ --split=section \
+ --I=/home/phil/lilypond-git/Documentation/"$l" \
+ --I=/home/phil/lilypond-git/Documentation \
+ --I=out-website \
+ $langopt \
+ --init-file=/home/phil/lilypond-git/Documentation/lilypond-texi2html.init \
+ -D web_version \
+ --output=out-website/"$l" \
+ /home/phil/lilypond-git/Documentation/"$l"/web.texi ; \
+ ls out-website/$l/*.html | xargs grep -L 'UNTRANSLATED NODE: IGNORE ME' | sed 's!out-website/'$l'/!!g' | xargs python /home/phil/lilypond-git/scripts/build/mass-link.py --prepend-suffix="$langsuf" hard out-website/$l/ out-website/website/ ; \
+ done
+cp /home/phil/lilypond-git/Documentation/css/*.css out-website/website
+mkdir -p out-website/website/pictures
+if [ -d Documentation/pictures/out-www ]; \
+ then \
+ cp Documentation/pictures/out-www/* out-website/website/pictures ; \
+ ln -sf website/pictures out-website/pictures ;\
+ fi
+mkdir -p out-website/website/ly-examples
+if [ -d Documentation/web/ly-examples/out-www ]; \
+ then \
+ cp Documentation/web/ly-examples/out-www/* out-website/website/ly-examples ; \
+ fi
+python /home/phil/lilypond-git/scripts/build/website_post.py out-website/website
+cp /home/phil/lilypond-git/Documentation/web/server/favicon.ico out-website/website
+cp /home/phil/lilypond-git/Documentation/web/server/robots.txt out-website/website
+cp /home/phil/lilypond-git/Documentation/web/server/lilypond.org.htaccess out-website/.htaccess
+cp /home/phil/lilypond-git/Documentation/web/server/website-dir.htaccess out-website/website/.htaccess
+make[1]: Leaving directory `/home/phil/lilypond-git/build'
+@end smallexample
+
+And, although there's rather a lot of text here, here's the output
+when @code{make website} is run:
+
+@smallexample
+make --no-builtin-rules config_make=./config.make \
+ top-src-dir=/home/phil/lilypond-git \
+ -f /home/phil/lilypond-git/make/website.make \
+ website
+make[1]: Entering directory `/home/phil/lilypond-git/build'
+mkdir -p out-website
+python /home/phil/lilypond-git/scripts/build/create-version-itexi.py /home/phil/lilypond-git > out-website/version.itexi
+python /home/phil/lilypond-git/scripts/build/create-weblinks-itexi.py /home/phil/lilypond-git > out-website/weblinks.itexi
+for l in '' cs de es fr hu it ja nl zh; do \
+ python /home/phil/lilypond-git/scripts/build/extract_texi_filenames.py \
+ -I /home/phil/lilypond-git/Documentation \
+ -I /home/phil/lilypond-git/Documentation/"$l" \
+ -I out-website -o out-website --split=node \
+ /home/phil/lilypond-git/Documentation/"$l"/web.texi ;\
+ for m in /home/phil/lilypond-git/Documentation/changes.tely /home/phil/lilypond-git/Documentation/essay.tely /home/phil/lilypond-git/Documentation/extending.tely /home/phil/lilypond-git/Documentation/learning.tely /home/phil/lilypond-git/Documentation/music-glossary.tely /home/phil/lilypond-git/Documentation/notation.tely /home/phil/lilypond-git/Documentation/snippets.tely /home/phil/lilypond-git/Documentation/usage.tely /home/phil/lilypond-git/Documentation/contributor.texi; do \
+ n=`echo "$m" | sed 's/Documentation/Documentation\/'$l'/'` ; \
+ b=`basename "$n" .texi`; \
+ d=`basename "$b" .tely`; \
+ if [ -e "$n" ] ; then \
+ python /home/phil/lilypond-git/scripts/build/extract_texi_filenames.py \
+ -I /home/phil/lilypond-git/Documentation \
+ -I /home/phil/lilypond-git/Documentation/"$l" \
+ -I /home/phil/lilypond-git/Documentation/"$l"/"$d" \
+ -I out-website -o out-website "$n" ; \
+ fi ; \
+ done; \
+ done;
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//web.texi
+writing: out-website/web.xref-map
+NOT A DIR from: /home/phil/lilypond-git/build /home/phil/lilypond-git/Documentation//changes
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//changes.tely
+writing: out-website/changes.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//essay.tely
+No such file: colorado.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//essay:out-website
+No such file: computer-notation.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//essay:out-website
+No such file: engravingbib.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//essay:out-website
+writing: out-website/essay.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//extending.tely
+writing: out-website/extending.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//learning.tely
+writing: out-website/learning.xref-map
+NOT A DIR from: /home/phil/lilypond-git/build /home/phil/lilypond-git/Documentation//music-glossary
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//music-glossary.tely
+writing: out-website/music-glossary.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//notation.tely
+No such file: markup-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//notation:out-website
+No such file: markup-list-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//notation:out-website
+No such file: context-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//notation:out-website
+No such file: layout-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//notation:out-website
+No such file: identifiers.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//notation:out-website
+No such file: type-predicates.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//notation:out-website
+No such file: scheme-functions.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//notation:out-website
+writing: out-website/notation.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//snippets.tely
+No such file: pitches.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: rhythms.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: expressive-marks.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: repeats.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: simultaneous-notes.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: staff-notation.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: editorial-annotations.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: text.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: vocal-music.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: chords.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: keyboards.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: percussion.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: fretted-strings.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: unfretted-strings.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: winds.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: ancient-notation.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: world-music.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: contexts-and-engravers.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: tweaks-and-overrides.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: paper-and-layout.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: titles.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: spacing.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: midi.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+No such file: template.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/:/home/phil/lilypond-git/Documentation//snippets:out-website
+writing: out-website/snippets.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//usage.tely
+writing: out-website/usage.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation//contributor.texi
+writing: out-website/contributor.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/cs/web.texi
+writing: out-website/web.cs.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/cs/learning.tely
+No such file: learning/working.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/cs:/home/phil/lilypond-git/Documentation/cs/learning:out-website
+No such file: learning/scheme-tutorial.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/cs:/home/phil/lilypond-git/Documentation/cs/learning:out-website
+writing: out-website/learning.cs.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/de/web.texi
+writing: out-website/web.de.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/de/essay.tely
+No such file: colorado.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/essay:out-website
+No such file: computer-notation.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/essay:out-website
+No such file: engravingbib.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/essay:out-website
+writing: out-website/essay.de.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/de/extending.tely
+writing: out-website/extending.de.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/de/learning.tely
+No such file: learning/working.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/learning:out-website
+No such file: learning/scheme-tutorial.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/learning:out-website
+writing: out-website/learning.de.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/de/notation.tely
+No such file: notation/programming-interface.itely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+No such file: markup-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+No such file: markup-list-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+No such file: context-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+No such file: layout-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+No such file: identifiers.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+No such file: type-predicates.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+No such file: scheme-functions.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/de:/home/phil/lilypond-git/Documentation/de/notation:out-website
+writing: out-website/notation.de.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/de/usage.tely
+writing: out-website/usage.de.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/es/web.texi
+writing: out-website/web.es.xref-map
+NOT A DIR from: /home/phil/lilypond-git/build /home/phil/lilypond-git/Documentation/es/changes
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/es/changes.tely
+writing: out-website/changes.es.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/es/essay.tely
+No such file: colorado.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/essay:out-website
+No such file: computer-notation.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/essay:out-website
+No such file: engravingbib.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/essay:out-website
+writing: out-website/essay.es.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/es/extending.tely
+writing: out-website/extending.es.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/es/learning.tely
+writing: out-website/learning.es.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/es/notation.tely
+No such file: markup-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/notation:out-website
+No such file: markup-list-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/notation:out-website
+No such file: context-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/notation:out-website
+No such file: layout-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/notation:out-website
+No such file: identifiers.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/notation:out-website
+No such file: type-predicates.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/notation:out-website
+No such file: scheme-functions.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/es:/home/phil/lilypond-git/Documentation/es/notation:out-website
+writing: out-website/notation.es.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/es/usage.tely
+writing: out-website/usage.es.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/fr/web.texi
+writing: out-website/web.fr.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/fr/essay.tely
+No such file: colorado.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/essay:out-website
+No such file: computer-notation.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/essay:out-website
+No such file: engravingbib.itexi
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/essay:out-website
+writing: out-website/essay.fr.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/fr/learning.tely
+writing: out-website/learning.fr.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/fr/notation.tely
+No such file: markup-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/notation:out-website
+No such file: markup-list-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/notation:out-website
+No such file: context-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/notation:out-website
+No such file: layout-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/notation:out-website
+No such file: identifiers.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/notation:out-website
+No such file: type-predicates.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/notation:out-website
+No such file: scheme-functions.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/fr:/home/phil/lilypond-git/Documentation/fr/notation:out-website
+writing: out-website/notation.fr.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/fr/usage.tely
+writing: out-website/usage.fr.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/hu/web.texi
+writing: out-website/web.hu.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/hu/learning.tely
+writing: out-website/learning.hu.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/hu/usage.tely
+writing: out-website/usage.hu.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/it/web.texi
+writing: out-website/web.it.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/it/learning.tely
+writing: out-website/learning.it.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/ja/web.texi
+writing: out-website/web.ja.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/ja/learning.tely
+writing: out-website/learning.ja.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/ja/notation.tely
+No such file: markup-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/ja:/home/phil/lilypond-git/Documentation/ja/notation:out-website
+No such file: markup-list-commands.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/ja:/home/phil/lilypond-git/Documentation/ja/notation:out-website
+No such file: context-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/ja:/home/phil/lilypond-git/Documentation/ja/notation:out-website
+No such file: layout-properties.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/ja:/home/phil/lilypond-git/Documentation/ja/notation:out-website
+No such file: identifiers.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/ja:/home/phil/lilypond-git/Documentation/ja/notation:out-website
+No such file: type-predicates.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/ja:/home/phil/lilypond-git/Documentation/ja/notation:out-website
+No such file: scheme-functions.tely
+Search path: .:/home/phil/lilypond-git/Documentation:/home/phil/lilypond-git/Documentation/ja:/home/phil/lilypond-git/Documentation/ja/notation:out-website
+writing: out-website/notation.ja.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/ja/usage.tely
+writing: out-website/usage.ja.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/nl/web.texi
+writing: out-website/web.nl.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/nl/learning.tely
+writing: out-website/learning.nl.xref-map
+extract_texi_filenames.py: Processing /home/phil/lilypond-git/Documentation/zh/web.texi
+writing: out-website/web.zh.xref-map
+BSTINPUTS=/home/phil/lilypond-git/Documentation/web \
+ python /home/phil/lilypond-git/scripts/build/bib2texi.py -s web \
+ -s /home/phil/lilypond-git/Documentation/lily-bib \
+ -o out-website/others-did.itexi \
+ /home/phil/lilypond-git/Documentation/web/others-did.bib
+This is BibTeX, Version 0.99c (TeX Live 2009/Debian)
+The top-level auxiliary file: /tmp/tmpvZPaJNbib2texi.aux
+The style file: /home/phil/lilypond-git/Documentation/lily-bib.bst
+Database file #1: /home/phil/lilypond-git/Documentation/web/others-did.bib
+Invoking `TEXMFOUTPUT=/tmp bibtex /tmp/tmpvZPaJNbib2texi'
+BSTINPUTS=/home/phil/lilypond-git/Documentation/web \
+ python /home/phil/lilypond-git/scripts/build/bib2texi.py -s web \
+ -s /home/phil/lilypond-git/Documentation/lily-bib \
+ -o out-website/we-wrote.itexi \
+ /home/phil/lilypond-git/Documentation/web/we-wrote.bib
+This is BibTeX, Version 0.99c (TeX Live 2009/Debian)
+The top-level auxiliary file: /tmp/tmpgB8NhBbib2texi.aux
+The style file: /home/phil/lilypond-git/Documentation/lily-bib.bst
+Database file #1: /home/phil/lilypond-git/Documentation/web/we-wrote.bib
+Invoking `TEXMFOUTPUT=/tmp bibtex /tmp/tmpgB8NhBbib2texi'
+for l in '' cs de es fr hu it ja nl zh; do \
+ if test -n "$l"; then \
+ langopt=--lang="$l"; \
+ langsuf=.$l; \
+ fi; \
+ ONLY_WEB=1 TOP_SRC_DIR=/home/phil/lilypond-git DEPTH= PERL_UNICODE=SD texi2html --prefix=index \
+ --split=section \
+ --I=/home/phil/lilypond-git/Documentation/"$l" \
+ --I=/home/phil/lilypond-git/Documentation \
+ --I=out-website \
+ $langopt \
+ --init-file=/home/phil/lilypond-git/Documentation/lilypond-texi2html.init \
+ -D web_version \
+ --output=out-website/"$l" \
+ /home/phil/lilypond-git/Documentation/"$l"/web.texi ; \
+ ls out-website/$l/*.html | xargs grep -L 'UNTRANSLATED NODE: IGNORE ME' | sed 's!out-website/'$l'/!!g' | xargs python /home/phil/lilypond-git/scripts/build/mass-link.py --prepend-suffix="$langsuf" hard out-website/$l/ out-website/website/ ; \
+ done
+Initializing settings for web site: []
+mass-link.py
+Initializing settings for web site: [cs]
+WARNING: Unable to find node 'Řešení potíží' in book usage.
+WARNING: Unable to find node 'Proč se mění skladba?' in book usage.
+mass-link.py
+Initializing settings for web site: [de]
+mass-link.py
+Initializing settings for web site: [es]
+mass-link.py
+Initializing settings for web site: [fr]
+mass-link.py
+Initializing settings for web site: [hu]
+mass-link.py
+Initializing settings for web site: [it]
+mass-link.py
+Initializing settings for web site: [ja]
+mass-link.py
+Initializing settings for web site: [nl]
+mass-link.py
+Initializing settings for web site: [zh]
+mass-link.py
+cp /home/phil/lilypond-git/Documentation/css/*.css out-website/website
+mkdir -p out-website/website/pictures
+if [ -d Documentation/pictures/out-www ]; \
+ then \
+ cp Documentation/pictures/out-www/* out-website/website/pictures ; \
+ ln -sf website/pictures out-website/pictures ;\
+ fi
+mkdir -p out-website/website/ly-examples
+if [ -d Documentation/web/ly-examples/out-www ]; \
+ then \
+ cp Documentation/web/ly-examples/out-www/* out-website/website/ly-examples ; \
+ fi
+python /home/phil/lilypond-git/scripts/build/website_post.py out-website/website
+cp /home/phil/lilypond-git/Documentation/web/server/favicon.ico out-website/website
+cp /home/phil/lilypond-git/Documentation/web/server/robots.txt out-website/website
+cp /home/phil/lilypond-git/Documentation/web/server/lilypond.org.htaccess out-website/.htaccess
+cp /home/phil/lilypond-git/Documentation/web/server/website-dir.htaccess out-website/website/.htaccess
+make[1]: Leaving directory `/home/phil/lilypond-git/build'
+@end smallexample
+
+
@subsubheading website.make variables
about those variables, I thought it would be simpler to keep
everything in the same file.
-Note that for security reasons, we *don't* call scripts in the git
-dir when building on the web server. See @ref{Uploading and
-security}. So we definitely want to keep those definitions for
-the WEBSITE_ONLY_BUILD.
+Note that for security reasons, we @strong{don't} call scripts in
+the git dir when building on the web server. See @ref{Uploading
+and security}. So we definitely want to keep those definitions
+for the WEBSITE_ONLY_BUILD.
After some split WEBSITE_ONLY_BUILD vs. normal build definitions,
there's another bunch of lines setting up generic variables.
@subsubheading website.make building parts
-The website-version rule creates files that define macros for
-commands like @@stableDocsNotationPdf@{@}, by calling python scripts.
-Those scripts are scripts/build/create-version-itexi.py and
-scripts/build/create-weblinks-itexi.py.
+Parts of @file{website.make}:
+
+@itemize
-website-xrefs: creates files used for complicated "out-of-build"
-references. If you just write @@ref@{@}, then all's groovy. But
-if you do @@rlearning@{@}, then our custom texi2html init file
-needs to know about our custom xref file format, which tells our
-custom texi2html init file how to create the link.
+@item
+@code{website-version}:
+this calls python scripts to define teinxfo macros.
-We should have a separate @@node to discuss xrefs. Also, take a
+@itemize
+@item
+@example
+scripts/build/create-version-itexi.py
+@end example
+
+This writes a @@version, @@versionStable, and @@versionDevel based
+on the top-level VERSIONS file, to
+@code{out-website/version.itexi}
+
+@item
+@example
+scripts/build/create-weblinks-itexi.py
+@end example
+
+This creates a ton of macros in @code{out-website/weblinks.itexi}.
+Stuff like @@downloadStableLinuxNormal, @@downloadStableWidows,
+@code{@@stableDocsNotationPdf@{@}}, @@downloadDevelSourch-zh.
+
+It's quite monstrous because it deals with combinations of
+stable/devel, source/docs, lang/lang/lang*10, etc.
+
+@end itemize
+
+
+@item
+@code{website-xrefs:}
+creates files used for complicated "out-of-build" references to
+@code{out-website/*.xref-map}
+
+If you just write @@ref@{@}, then all's groovy and we wouldn't
+need this. But if you write @@rlearning@{@}, then our custom
+texi2html init file needs to know about our custom xref file
+format, which tells our custom texi2html init file how to create
+the link.
+
+GP: we should have a separate @@node to discuss xrefs. Also, take a
quick look at a generated xref file -- it's basically just a list
of @@node's [sic teenager pluralization rule] from the file.
-website-bib: generates the bibliography texinfo files from the
-.bib files.
+@item
+@code{website-bib:}
+generates the bibliography texinfo files from the .bib files.
-website-texinfo: this is the money shot; it calles texi2html to
-generate the actual html. It also has a ton of options to
-texi2html to pass info to our custom init file.
+@item
+@code{website-texinfo:}
+this is the main part; it calles texi2html to generate the actual
+html. It also has a ton of options to texi2html to pass info to
+our custom init file.
+
+We have somewhere between 2-4 different ways "to pass info to our
+custom init file". This is highly Not Good (tm), but that's how
+things work at the moment.
After texi2html, it does some black magick to deal with
untranslated nodes in the translations. Despite writing that
figure it out by copy&pasting each part of the command (by "part",
I mean "stuff before each | pipe"), substituting the variables,
then looking at the text that's output. For example,
+
+@example
ls $(OUT)/$$l/*.html
+@end example
+
is going to print a list of all html files, in all languages, in
the build directory. Then more stuff happens to each of those
files (that's what xargs does).
-website-css: just copies files to the build dir.
+@item
+@code{website-css:}
+just copies files to the build dir.
-website-pictures, website-examples: more file copies, with an if
-statement to handle if you don't have any generated
-pictures/examples.
+@item
+@code{website-pictures, website-examples:}
+more file copies, with an if statement to handle if you don't have
+any generated pictures/examples.
+
+@item
+@code{web-post:}
+runs:
+
+@example
+scripts/build/website_post.py
+@end example
-web-post: buggered if I know. Apparently it runs the
-scripts/build/website_post.py file, which despite writing, I
-can't remember what it does.
+which, it adds the "this page is translated in klingon" to the
+bottom of html pages, and adds the google analytics javascript.
+It also has hard-coded lilypond version numbers, which is Bad
+(tm).
-ok, it adds the "this page is translated in klingon" to the bottom
-of html pages, and adds the google analytics javascript. It also
-has hard-coded lilypond version numbers.
+@item
+@code{website:}
+this is the "master" rule. It calls the bits and pieces in order,
+then copies some extra files around.
-website: this is the "master" rule. It calls the bits and pieces
-in order, then copies some extra files around.
+@end itemize
@node Building an Ubuntu distro
@c TITLE PAGE
@ifnottex
-@node Arriba
+@node Top
@top LilyPond... notación musical para todos
@translationof Top
@end ifnottex
Preguntas más frecuentes (Frequently Asked Questions).
@item
-@ref{Web}:
+@ref{Top,Web}:
este documento.
@details{Web}
Patterns that are shorter than one measure are replaced by slashes.
@lilypond[verbatim,quote,relative=2]
+\repeat percent 4 { c128 d e f }
+\repeat percent 4 { c64 d e f }
+\repeat percent 5 { c32 d e f }
+\repeat percent 4 { c16 d e f }
\repeat percent 4 { c8 d }
\repeat percent 4 { c4 }
\repeat percent 2 { c2 }
@end lilypond
-Patterns of one or two measures are replaced by percent-like signs.
+Patterns of one or two measures are replaced by percent-like symbols.
@lilypond[verbatim,quote,relative=2]
-\repeat percent 3 { c4 d e f }
-\repeat percent 4 { c2 d }
+\repeat percent 2 { c4 d e f }
+\repeat percent 2 { c2 d }
+\repeat percent 2 { c1 }
@end lilypond
@lilypond[verbatim,quote,relative=2]
\repeat percent 3 { c4 d e f | c2 g' }
@end lilypond
+Patterns that are shorter than one measure but contain mixed durations
+use a double-percent symbol.
+
+@lilypond[verbatim,quote,relative=2]
+\repeat percent 4 { c8. <d f>16 }
+\repeat percent 2 { \times 2/3 { r8 c d } e4 }
+@end lilypond
+
@snippets
@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
@lilypondfile[verbatim,lilyquote,texidoc,doctitle]
{isolated-percent-repeats.ly}
-
@seealso
Music Glossary:
@rglos{percent repeat},
Internals Reference:
@rinternals{RepeatSlash},
+@rinternals{RepeatSlashEvent},
+@rinternals{DoubleRepeatSlash},
@rinternals{PercentRepeat},
+@rinternals{PercentRepeatCounter},
+@rinternals{PercentRepeatedMusic},
+@rinternals{Percent_repeat_engraver},
+@rinternals{DoublePercentEvent},
@rinternals{DoublePercentRepeat},
@rinternals{DoublePercentRepeatCounter},
-@rinternals{PercentRepeatCounter},
-@rinternals{PercentRepeatedMusic}.
-
-
-@knownissues
-
-Only three kinds of percent repeats are supported: a single slash
-representing a single beat (regardless of the duration of the repeated
-notes); a single slash with dots representing one full measure; and
-two slashes with dots crossing a bar line representing two full
-measures. Neither multiple slashes representing single beat repeats
-consisting of sixteenth or shorter notes, nor two slashes with dots
-representing single beat repeats consisting of notes of varying
-durations, are supported.
+@rinternals{Double_percent_repeat_engraver},
+@rinternals{Slash_repeat_engraver}.
@node Tremolo repeats
@rinternals{beam-interface},
@rinternals{unbreakable-spanner-interface}.
-@knownissues
-Beams can collide with note heads and accidentals in other
-voices. In this case use @ref{Manual beams}.
-
-@lilypond[quote,relative=1,verbatim]
-c8 des'! c, [ des'! ]
-@end lilypond
-
-
@node Setting automatic beam behavior
@unnumberedsubsubsec Setting automatic beam behavior
@code{DOWN}; those at the bottom should use @code{UP}. Setting
@code{staff-affinity} for a staff causes it to be treated as a
non-staff line. Setting @code{staff-affinity} to @code{#f} causes
-a non-staff line to be treated as a staff.
-
-@c TODO: verify last clause below ("even if other...")
+a non-staff line to be treated as a staff. Setting
+@code{staff-affinity} to @code{UP}, @code{CENTER}, or @code{DOWN}
+causes a staff to be spaced as a non-staff line.
@item nonstaff-relatedstaff-spacing
The distance between the current non-staff line and the nearest
@code{CENTER}, then @code{nonstaff-relatedstaff-spacing} is used
for the nearest staves on @emph{both} sides, even if other
non-staff lines appear between the current one and either of the
-staves.
+staves. This means that the placement of a non-staff line depends
+on both the surrounding staves and the surrounding non-staff lines.
+Setting the @code{stretchability} of one of these types of spacing to
+a small value will make that spacing dominate. Setting the
+@code{stretchability} to a large value will make that spacing have
+little effect.
@item nonstaff-nonstaff-spacing
The distance between the current non-staff line and the next
@lilypondfile[quote,noindent]{screech-boink.ly}
+If a @code{tagline} is required, either default or custom, then the
+entire snippet must be enclosed in a @code{\book @{ @}} construct.
+
+@lilypond[papersize=a8,verbatim]
+\book{
+ \header{
+ title = "A scale in LilyPond"
+ }
+
+ \relative c' {
+ c d e f g a b c
+ }
+}
+@end lilypond
@page
guess a default for @code{lilypond} environments which don't use the
@code{ragged-right} option.
+@item papersize=@var{string}
+Where @var{string} is a paper size defined in @file{scm/paper.scm} i.e.
+@code{a5}, @code{quarto}, @code{11x17} etc.
+
+Values not defined in @file{scm/paper.scm} will be ignored, a warning
+will be posted and the snippet will be printed using the default
+@code{a4} size.
+
@item notime
Do not print the time signature, and turns off the timing (time signature,
bar lines) in the score.
@docLinks{Usage, usage,
@rprogramnamed{Top,Usage},
@manualStableUsageSplit,
- @manualStableUsageBig, 300 KB,
- @manualStableUsagePdf, 400 KB}
+ @manualStableUsageBig, 400 KB,
+ @manualStableUsagePdf, 600 KB}
@divEnd
@c used for news about the upcoming release; see CG 10.2
+@newsItem
+@subsubheading Release candidate 5 of 2.14 - LilyPond 2.13.57 released! @emph{April 3, 2011}
+
+LilyPond 2.13.57 is out; this is the fourth release candidate of
+the upcoming 2.14 stable release. All users are invited to
+experiment with this version. New features since 2.12.3 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.14.0 release will be
+on April 10, 2011. If you discover any problems, please send us
+@ref{Bug reports}.
+
+@newsEnd
+
+
+@newsItem
+@subsubheading Release candidate 4 of 2.14 - LilyPond 2.13.56 released! @emph{Mar 29, 2011}
+
+LilyPond 2.13.56 is out; this is the fourth release candidate of
+the upcoming 2.14 stable release. All users are invited to
+experiment with this version. New features since 2.12.3 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.14.0 release will be
+on April 5, 2011. If you discover any problems, please send us
+@ref{Bug reports}.
+
+@newsEnd
+
@newsItem
@subsubheading LilyPond 2.13.55 released! @emph{Mar 22, 2011}
local-check: test
rm -rf $(RESULT_DIR)
mkdir -p $(RESULT_DIR)
- $(buildscript-dir)/output-distance --create-images --output-dir $(RESULT_DIR) input/regression/out-test-baseline input/regression/out-test
+ $(buildscript-dir)/output-distance --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'
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=13
-PATCH_LEVEL=56
+PATCH_LEVEL=58
MY_PATCH_LEVEL=
VERSION_STABLE=2.12.3
-VERSION_DEVEL=2.13.55
+VERSION_DEVEL=2.13.57
--- /dev/null
+\version "2.13.57"
+
+\header {
+ texidoc = "Broken glissandi anticipate the pitch on the next line."
+}
+
+\score {
+ \relative c' {
+ \override Glissando #'after-line-breaking = ##t
+ \override Glissando #'breakable = ##t
+ c1\glissando
+ \break
+ c'1
+ \break
+ c,1\glissando
+ \break
+ s2 c'2
+ }
+ \layout {
+ ragged-right = ##t
+ }
+}
+
+\score {
+ \relative c' {
+ \override Glissando #'after-line-breaking = ##t
+ \override Glissando #'breakable = ##t
+ c1\glissando
+ \break
+ c'1
+ \break
+ c,1\glissando
+ \break
+ s2 c'2
+ }
+}
are removed: this example has three staves, but some of them
disappear: note how the 2nd line only has the bar number 2. (That the
bar number is printed might be considered a bug, however, the scenario
-of all staves disappearing does not happen in practice.)
-
-Any staff brackets and braces are removed, both in the single staff
-and no staff case."
+of all staves disappearing does not happen in practice.)"
}
}
-\context PianoStaff <<
+\new GrandStaff <<
\new TabStaff {
c4 c c c \break
s1 \break
}
>>
-
-
--- /dev/null
+\header {
+
+ texidoc = "No hyphen should be printed under a grace note at the start
+of a line if the grace's main note starts a new syllable."
+}
+
+\version "2.13.56"
+<<
+ \new Staff {
+ \appoggiatura f'8 g'2 g'( | \break
+ \appoggiatura f'8 g'2) \appoggiatura f'8 g'2 | \break
+ \appoggiatura f'8 g'2 g' | \break
+ g'2 g' |
+ }
+ \addlyrics {
+ \lyricmode {
+ bla -- bla -- bla -- bla -- bla -- bla -- bla
+ }
+ }
+ \new Staff {
+ g'2 g' |
+ g'2 g' |
+ g'2 g' |
+ g'2 g' |
+ }
+ \addlyrics {
+ \lyricmode {
+ bla -- bla -- bla -- bla -- bla -- bla -- bla -- bla
+ }
+ }
+>>
% included from ./out/initial-key.header
\header {
-texidoc="keys work in MIDI, this is a-minor"
+texidoc="keys work in MIDI, this is d-minor"
options=""
}
% end
trackAchannelA = {
- \key a \minor
+ \key d \minor
% [SEQUENCE_TRACK_NAME] control track
trackBchannelA = \relative c {
\set Staff.instrumentName = "trackB:voiceA"
- a'4 b c d
+ d'4 e f g
| % 2
- e f gis a
+ a bes cis d
| % 3
}
\set Staff.instrumentName = "trackB:"
- \key a \minor
+ \key d \minor
}
--- /dev/null
+\version "2.13.53"
+
+\header {
+texidoc="Midi2ly --key works on all staves, this is G major (--key=1)"
+options="--key=1"
+}
+
+\score {
+ <<
+ \context Staff = "treble" <<
+ \context Voice="one" \relative c'' {
+ fis
+ }
+ >>
+ \context Staff = "bass" <<
+ \context Voice="two" \relative c {
+ \clef bass
+ fis
+ }
+ >>
+ >>
+ \layout {}
+ \midi {}
+}
--- /dev/null
+% Lily was here -- automatically converted by ../../../scripts/midi2ly.py from out-www/voice-4.midi
+\version "2.13.53"
+
+\layout {
+ \context {
+ \Voice
+ \remove "Note_heads_engraver"
+ \consists "Completion_heads_engraver"
+ \remove "Rest_engraver"
+ \consists "Completion_rest_engraver"
+ }
+}
+
+% included from ./out-www/voice-5.header
+\header {
+texidoc="midi2ly still produces output for a staff with five voices. However, in such cases, most probably the the correct \voiceOne, \voiceX... mapping is lost."
+options=""
+}
+% end
+
+trackAchannelA = {
+
+ % [SEQUENCE_TRACK_NAME] control track
+
+ % [TEXT_EVENT] creator:
+
+ % [TEXT_EVENT] GNU LilyPond 2.13.54
+
+ \time 4/4
+
+ \tempo 4 = 60
+
+}
+
+trackA = <<
+ \context Voice = voiceA \trackAchannelA
+>>
+
+
+trackBchannelA = \relative c {
+ \voiceOne
+
+ \set Staff.instrumentName = ":1"
+ <c''' a >2 b
+ | % 2
+
+}
+
+trackBchannelB = \relative c {
+ \voiceThree
+ c''4. d8 e4 f
+ | % 2
+
+}
+
+trackBchannelC = \relative c {
+ \voiceFour
+ d'1
+ | % 2
+
+}
+
+trackBchannelD = \relative c {
+ \voiceTwo
+ c'4 c2 c4
+ | % 2
+
+}
+
+trackBchannelE = \relative c {
+ s1 d1
+ | % 2
+
+}
+
+trackB = <<
+ \context Voice = voiceA \trackBchannelA
+ \context Voice = voiceB \trackBchannelB
+ \context Voice = voiceC \trackBchannelC
+ \context Voice = voiceD \trackBchannelD
+ \context Voice = voiceE \trackBchannelE
+>>
+
+
+\score {
+ <<
+ \context Staff=trackB \trackA
+ \context Staff=trackB \trackB
+ >>
+ \layout {}
+ \midi {}
+}
--- /dev/null
+\version "2.13.56"
+
+\header {
+
+ texidoc = "
+ NoteNames context should be close to the related notes,
+ and should not collide with the tempo markings.
+ "
+}
+
+\paper {
+ system-system-spacing
+ #'basic-distance = #10 % increase this value for more space
+}
+
+notes = \relative c {
+ c'4 c c c
+}
+
+mylyrics = \lyricmode {
+ \tempo "Allegro"
+ ly -- ric ly -- ric
+}
+
+\score {
+ <<
+ \new Voice = "voice" {
+ \repeat unfold 13 \notes
+ }
+ \context NoteNames {
+ \repeat unfold 13 \notes
+ }
+ \new Lyrics \lyricsto "voice" {
+ \repeat unfold 13 \mylyrics
+ }
+ >>
+}
}
Audio_note::Audio_note (Pitch p, Moment m, bool tie_event, Pitch transposing)
+ : pitch_ (p)
+ , length_mom_ (m)
+ , transposing_ (transposing)
+ , dynamic_ (0)
+ , tied_ (0)
+ , tie_event_ (tie_event)
{
- pitch_ = p;
- length_mom_ = m;
- tied_ = 0;
- transposing_ = transposing;
- tie_event_ = tie_event;
- volume_ = 0;
}
void
}
Audio_dynamic::Audio_dynamic ()
+ : volume_ (-1)
+ , silent_ (false)
{
- volume_ = -1;
}
Audio_span_dynamic::Audio_span_dynamic ()
class Beam_collision_engraver : public Engraver
{
protected:
- vector<Grob *> active_beams_;
- vector<Grob *> signaled_beams_;
- vector<Grob *> end_beams_;
+ vector<Grob *> beams_;
vector<Grob *> covered_grobs_;
- vector<Grob *> covered_interior_grobs_;
DECLARE_ACKNOWLEDGER (note_head);
DECLARE_ACKNOWLEDGER (accidental);
DECLARE_ACKNOWLEDGER (key_signature);
DECLARE_ACKNOWLEDGER (time_signature);
DECLARE_ACKNOWLEDGER (beam);
- DECLARE_END_ACKNOWLEDGER (beam);
- void stop_translation_timestep ();
+
+ virtual void finalize ();
+
public:
TRANSLATOR_DECLARATIONS (Beam_collision_engraver);
};
+Beam_collision_engraver::Beam_collision_engraver () {}
+
void
-Beam_collision_engraver::stop_translation_timestep ()
+Beam_collision_engraver::finalize ()
{
- /*
- First, for all grobs that fall to the left of a beam during
- a timestep (i.e. clefs, time signatures), add these to
- the beams that are currently active.
- */
- for (vsize i = 0; i < covered_interior_grobs_.size (); i++)
- for (vsize j = 0; j < active_beams_.size (); j++)
- Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), covered_interior_grobs_[i]);
-
- covered_interior_grobs_.clear ();
-
- /*
- If a signaled beam is already in active_beams_, we erase it so as
- not to have a beam represented in active_beams_ more than once.
- */
-
- for (vsize i = 0; i < active_beams_.size (); i++)
- for (vsize j = 0; j < signaled_beams_.size (); j++)
- if (active_beams_[i] == signaled_beams_[j])
+ if (!covered_grobs_.size ())
+ return;
+
+ vector_sort (covered_grobs_, Grob::less);
+ vector_sort (beams_, Grob::less);
+ vsize start = 0;
+
+ for (vsize i = 0; i < beams_.size (); i++)
+ {
+ Interval_t<int> beam_spanned_rank_ = beams_[i]->spanned_rank_interval ();
+ // Start considering grobs at the first grob whose end falls at or after the beam's beginning.
+ while (covered_grobs_[start]->spanned_rank_interval ()[RIGHT] < beam_spanned_rank_[LEFT])
+ start++;
+
+ // Stop when the grob's beginning comes after the beam's end.
+ for (vsize j = start; j < covered_grobs_.size (); j++)
{
- signaled_beams_.erase (signaled_beams_.begin () + j);
- break;
+ Interval_t<int> covered_grob_spanned_rank = covered_grobs_[j]->spanned_rank_interval ();
+ if (covered_grob_spanned_rank[LEFT] > beam_spanned_rank_[RIGHT])
+ break;
+ /*
+ Only consider grobs whose end falls at or after the beam's beginning.
+ If the grob is a beam, it cannot start before beams_[i]
+ */
+ if ((covered_grob_spanned_rank[RIGHT] >= beam_spanned_rank_[LEFT])
+ && !(Beam::has_interface (covered_grobs_[j])
+ && (covered_grob_spanned_rank[LEFT] <= beam_spanned_rank_[LEFT])))
+ {
+ // Do not consider note heads attached to the beam.
+ bool my_beam = false;
+ if (Grob *stem = unsmob_grob (covered_grobs_[j]->get_object ("stem")))
+ if (Grob *beam = unsmob_grob (stem->get_object ("beam")))
+ if (beam == beams_[i])
+ my_beam = true;
+
+ if (!my_beam)
+ Pointer_group_interface::add_grob (beams_[i], ly_symbol2scm ("covered-grobs"), covered_grobs_[j]);
+ }
}
-
- /*
- In auto beaming, beams both begin and end during the same timestep.
- This means that if there is a beam that is both in signaled_beams_ and
- end_beams_, it must either be an auto beam (likely) or a beam that
- has no notes under it (highly unlikely). In either case, we cannot account
- for the grobs under this beam, and we erase it from signaled beams.
- */
- for (vsize i = 0; i < end_beams_.size (); i++)
- for (vsize j = 0; j < signaled_beams_.size (); j++)
- if (end_beams_[i] == signaled_beams_[j])
- {
- signaled_beams_.erase (signaled_beams_.begin () + j);
- break;
- }
-
- /*
- We want to know how big active beams was originally so that we do not
- get any cyclical dependencies (see below).
- */
- vsize orig_size = active_beams_.size ();
-
- /*
- All signaled beams that are left now become active beams that are fair
- game to collect covered grobs.
- */
- for (vsize i=0; i < signaled_beams_.size (); i++)
- active_beams_.push_back (signaled_beams_[i]);
-
- /*
- Add all covered grobs that fall to the right of a beam (like noteheads)
- as to covered-grobs of the beam. Note that noteheads that part of a beam
- are not added to that list, as note heads should not never collide with
- their own beams due to minimum stem length penalties in beam-quanting.cc.
- */
- for (vsize i = 0; i < covered_grobs_.size (); i++)
- for (vsize j = 0; j < active_beams_.size (); j++)
- {
- bool my_beam = false;
- if (Grob *stem = unsmob_grob (covered_grobs_[i]->get_object ("stem")))
- if (Grob *beam = unsmob_grob (stem->get_object ("beam")))
- if (beam == active_beams_.at (j))
- my_beam = true;
- if (!my_beam)
- Pointer_group_interface::add_grob (active_beams_.at (j), ly_symbol2scm ("covered-grobs"), covered_grobs_[i]);
- }
-
- covered_grobs_.clear ();
-
- /*
- This is where cyclical dependencies are avoided. In beam collision avoidance,
- beams often need to avoid other beams. To do this, they need to know the beam's
- position. But, if that second beam needs to know the first beam's position, we
- have a cyclical dependency. So, we only ever add signaled beams to active_beams_
- that existed BEFORE this time step. This is controlled by the orig_size variable.
- The for loop stops before it gets to the signaled beams added above so that beams
- added during this timestep are never dependent on each other for positioning.
- */
- for (vsize i = 0; i < signaled_beams_.size (); i++)
- for (vsize j = 0; j < orig_size; j++)
- Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), signaled_beams_[i]);
-
- signaled_beams_.clear ();
-
- /*
- If the end of a beam has been announced, it is no longer active. So, remove this beam
- from active_beams_.
- */
- for (vsize i = 0; i < end_beams_.size (); i++)
- for (vsize j = 0; j < active_beams_.size (); j++)
- if (end_beams_[i] == active_beams_[j])
- {
- active_beams_.erase (active_beams_.begin () + j);
- break;
- }
-
- end_beams_.clear ();
+ }
}
-Beam_collision_engraver::Beam_collision_engraver () {}
-
void
Beam_collision_engraver::acknowledge_note_head (Grob_info i)
{
void
Beam_collision_engraver::acknowledge_clef (Grob_info i)
{
- covered_interior_grobs_.push_back (i.grob ());
+ covered_grobs_.push_back (i.grob ());
}
void
Beam_collision_engraver::acknowledge_key_signature (Grob_info i)
{
- covered_interior_grobs_.push_back (i.grob ());
+ covered_grobs_.push_back (i.grob ());
}
void
Beam_collision_engraver::acknowledge_time_signature (Grob_info i)
{
- covered_interior_grobs_.push_back (i.grob ());
+ covered_grobs_.push_back (i.grob ());
}
void
Beam_collision_engraver::acknowledge_beam (Grob_info i)
{
- signaled_beams_.push_back (i.grob ());
-}
-
-void
-Beam_collision_engraver::acknowledge_end_beam (Grob_info i)
-{
- end_beams_.push_back (i.grob ());
+ beams_.push_back (i.grob ());
+ covered_grobs_.push_back (i.grob ());
}
#include "translator.icc"
ADD_ACKNOWLEDGER (Beam_collision_engraver, key_signature);
ADD_ACKNOWLEDGER (Beam_collision_engraver, time_signature);
ADD_ACKNOWLEDGER (Beam_collision_engraver, beam);
-ADD_END_ACKNOWLEDGER (Beam_collision_engraver, beam);
ADD_TRANSLATOR (Beam_collision_engraver,
/* doc */
vector<Beam_configuration*> configs;
generate_quants (&configs);
+ if (configs.empty ())
+ {
+ programming_error ("No viable beam quanting found. Using unquanted y value.");
+ return unquanted_y;
+ }
+
Beam_configuration *best = NULL;
bool debug =
announce_element (info);
}
-
if (span_dynamic_)
span_dynamic_->add_absolute (absolute_);
Audio_dynamic ();
Real volume_;
+ bool silent_;
};
class Audio_span_dynamic : public Audio_element
Pitch pitch_;
Moment length_mom_;
Pitch transposing_;
- Real volume_;
+ Audio_dynamic* dynamic_;
Audio_note *tied_;
bool tie_event_;
bool to_bool () const;
I64 den () const;
I64 num () const;
+ Rational main_part () const;
+ Rational grace_part () const;
/*
Deliver a copy of THIS as a smobified SCM
*/
bool moment_less (SCM a, SCM b);
#endif /* MOMENT_HH */
-
common_y[d] = unsmob_grob (ly_assoc_get (ly_symbol2scm ("common-Y"),
bounds[d], SCM_BOOL_F));
if (!common_y[d])
- common_y[d] = me;
+ common_y[d] = me;
}
while (flip (&d) != LEFT);
span_points[d][Y_AXIS] += common_y[d]->relative_coordinate (my_common_y, Y_AXIS);
while (flip (&d) != LEFT);
+ Interval normalized_endpoints = robust_scm2interval (me->get_property ("normalized-endpoints"), Interval (0, 1));
+ Real y_length = span_points[RIGHT][Y_AXIS] - span_points[LEFT][Y_AXIS];
+
+ span_points[LEFT][Y_AXIS] += normalized_endpoints[LEFT] * y_length;
+ span_points[RIGHT][Y_AXIS] -= (1 - normalized_endpoints[RIGHT]) * y_length;
+
Offset dz = (span_points[RIGHT] - span_points[LEFT]);
Offset dz_dir = dz.direction ();
if (gaps[LEFT] + gaps[RIGHT] > dz.length ())
SCM off = ly_assoc_get (ly_symbol2scm ("stencil-offset"),
bounds[d], SCM_BOOL_F);
- if (scm_is_number (align))
+ if (scm_is_number (align))
s.align_to (Y_AXIS, scm_to_double (align));
if (is_number_pair (off))
if (line_right[X_AXIS] > line_left[X_AXIS])
{
line.add_stencil (Line_interface::line (me, line_left, line_right));
-
+
line.add_stencil (Line_interface::arrows (me,
span_points[LEFT],
span_points[RIGHT],
}
Context *voice = get_voice_to_lyrics (context ());
- if (last_text_ && voice &&
- to_boolean (voice->get_property ("melismaBusy")))
+ if (last_text_
+ && voice
+ && to_boolean (voice->get_property ("melismaBusy"))
+ && !to_boolean (context ()->get_property ("ignoreMelismata")))
last_text_->set_property ("self-alignment-X",
get_property ("lyricMelismaAlignment"));
}
SCM
Lyric_hyphen::print (SCM smob)
{
+
Spanner *me = unsmob_spanner (smob);
Drul_array<Item *> bounds (me->get_bound (LEFT),
me->get_bound (RIGHT));
+ /* No hyphen should be printed under a grace note at the start
+ of a line if the grace's main note starts a new syllable. */
+
+ if (Paper_column::when_mom (bounds[LEFT]->get_column ()).grace_part () != Rational (0)
+ && Paper_column::when_mom (bounds[LEFT]->get_column ()).main_part ()
+ == Paper_column::when_mom (bounds[RIGHT]->get_column ()).main_part ())
+ return SCM_EOL;
+
if (bounds[LEFT]->break_status_dir ()
&& (Paper_column::when_mom (bounds[LEFT])
== Paper_column::when_mom (bounds[RIGHT]->get_column ())))
"padding "
"thickness "
);
-
static char const *WARRANTY
= _i (" This program is free software; you can redistribute it and/or\n"
- "modify it under the terms of the GNU General Public License version 2\n"
- "as published by the Free Software Foundation.\n"
+ "modify it under the terms of the GNU General Public License as \n"
+ "published by the Free Software Foundation, either version 3 of\n"
+ "the License, or (at your option) any later version.\n"
"\n"
" This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
{
string delta_string = int2midi_varint_string (delta_ticks_);
string midi_string = midi_->to_string ();
- assert (midi_string.length ());
+ if (midi_string.empty ())
+ return "";
return delta_string + midi_string;
}
/****************************************************************
Midi_note::Midi_note (Audio_note *a)
: Midi_channel_item (a)
, audio_ (a)
- , dynamic_byte_ (a->volume_ > 0 ? Byte (a->volume_ * 0x7f) : Byte (0x5a))
+ , dynamic_byte_ (a->dynamic_ && a->dynamic_->volume_ > 0
+ ? Byte (a->dynamic_->volume_ * 0x7f) : Byte (0x5a))
{
}
string
Midi_dynamic::to_string () const
{
- if (audio_->volume_ < 0)
+ if (audio_->volume_ < 0 || audio_->silent_)
return "";
Byte status_byte = (char) (0xB0 + channel_);
return main_part_ || grace_part_;
}
+Rational
+Moment::main_part () const
+{
+ return main_part_;
+}
+
+Rational
+Moment::grace_part () const
+{
+ return grace_part_;
+}
+
void
Moment::set_infinite (int k)
{
{
return *unsmob_moment (a) < *unsmob_moment (b);
}
-
int get_channel (string instrument);
Audio_staff* get_audio_staff (string voice);
Audio_staff* new_audio_staff (string voice);
- Real get_dynamic (string voice);
+ Audio_dynamic* get_dynamic (string voice);
string instrument_string_;
int channel_;
Audio_tempo *tempo_;
map<string, Audio_staff*> staff_map_;
map<string, int> channel_map_;
- map<string, Real> dynamic_map_;
+ map<string, Audio_dynamic*> dynamic_map_;
static map<string, int> static_channel_map_;
static int channel_count_;
};
return new_audio_staff (voice);
}
-Real
+Audio_dynamic*
Staff_performer::get_dynamic (string voice)
{
- map<string, Real>::const_iterator i = dynamic_map_.find (voice);
+ map<string, Audio_dynamic*>::const_iterator i = dynamic_map_.find (voice);
if (i != dynamic_map_.end ())
return i->second;
return 0;
}
Audio_staff* audio_staff = get_audio_staff (voice);
ai->channel_ = channel_;
- // Output volume as velocity and disable Midi_dynamic output
- if (Audio_dynamic *d = dynamic_cast<Audio_dynamic *> (inf.elem_))
+ bool encode_dynamics_as_velocity_ = true;
+ if (encode_dynamics_as_velocity_)
{
- dynamic_map_[voice] = d->volume_;
- d->volume_ = -1;
+ if (Audio_dynamic *d = dynamic_cast<Audio_dynamic *> (inf.elem_))
+ {
+ dynamic_map_[voice] = d;
+ // Output volume as velocity: must disable Midi_dynamic output
+ d->silent_ = true;
+ }
+ if (Audio_dynamic *d = get_dynamic (voice))
+ if (Audio_note *n = dynamic_cast<Audio_note *> (inf.elem_))
+ n->dynamic_ = d;
}
- if (Real d = get_dynamic (voice))
- if (Audio_note *n = dynamic_cast<Audio_note *> (inf.elem_))
- n->volume_ = d;
audio_staff->add_audio_item (ai);
}
}
// This is needed for tied chords, e.g. <c e g>~ g, because otherwise the c
// and e will trigger a warning for an unterminated tie!
bool tie_from_chord_created;
-
+
Head_event_tuple ()
{
head_ = 0;
*/
if (!right_ev || !left_ev)
continue;
-
+
if (ly_is_equal (right_ev->get_property ("pitch"),
left_ev->get_property ("pitch")))
{
SCM cause = heads_to_tie_[i].tie_event_
? heads_to_tie_[i].tie_event_->self_scm ()
: heads_to_tie_[i].tie_stream_event_->self_scm ();
-
+
announce_grob (p, cause);
Tie::set_head (p, LEFT, th);
Tie::set_head (p, RIGHT, h);
if (is_direction (unsmob_stream_event (cause)->get_property ("direction")))
{
Direction d = to_dir (unsmob_stream_event (cause)->get_property ("direction"));
- p->set_property ("direction", scm_from_int (d));
+ p->set_property ("direction", scm_from_int (d));
}
-
+
ties_.push_back (p);
heads_to_tie_.erase (heads_to_tie_.begin () + i);
void
Tie_engraver::start_translation_timestep ()
{
- context ()->set_property ("tieMelismaBusy",
- ly_bool2scm (heads_to_tie_.size ()));
-
if (heads_to_tie_.size () && !to_boolean (get_property ("tieWaitForNote")))
{
Moment now = now_mom ();
}
}
}
+
+ context ()->set_property ("tieMelismaBusy",
+ ly_bool2scm (heads_to_tie_.size ()));
}
void
}
vector<Head_event_tuple> new_heads_to_tie;
-
+
for (vsize i = 0; i < now_heads_.size (); i++)
{
Grob *head = now_heads_[i];
// may happen for ambitus
continue;
}
-
-
+
+
SCM left_articulations = left_ev->get_property ("articulations");
Stream_event *tie_event = 0;
Stream_event *ev = unsmob_stream_event (scm_car (s));
if (!ev)
continue;
-
+
if (ev->in_event_class ("tie-event"))
tie_event = ev;
}
-
+
if (left_ev && (tie_event || tie_stream_event))
{
Head_event_tuple event_tup;
end += get_event_length (left_ev);
}
event_tup.end_moment_ = end;
-
+
new_heads_to_tie.push_back (event_tup);
}
}
// hmmm, how to do with copy () ?
for (vsize i = 0; i < new_heads_to_tie.size (); i++)
heads_to_tie_.push_back (new_heads_to_tie[i]);
-
+
event_ = 0;
now_heads_.clear ();
}
\defaultchild "Staff"
\accepts "Staff"
+ \accepts "RhythmicStaff"
+ \accepts "DrumStaff"
+ \accepts "TabStaff"
+ \accepts "Lyrics"
\accepts "FiguredBass"
\accepts "Dynamics"
\accepts "ChordNames"
\description "A context for printing the names of notes."
\consists "Axis_group_engraver"
- % FIXME: not sure what the default should be here.
- \override VerticalAxisGroup #'staff-affinity = #DOWN
+ \override VerticalAxisGroup #'staff-affinity = #UP
+ \override VerticalAxisGroup #'nonstaff-nonstaff-spacing =
+ #'((basic-distance . 0)
+ (minimum-distance . 2.8)
+ (padding . 0.2)
+ (stretchability . 0))
+ \override VerticalAxisGroup #'nonstaff-relatedstaff-spacing =
+ #'((basic-distance . 5.5)
+ (padding . 0.5)
+ (stretchability . 1))
+ \override VerticalAxisGroup
+ #'nonstaff-unrelatedstaff-spacing #'padding = 1.5
\consists "Tie_engraver"
\consists "Note_name_engraver"
$(outdir)/parmesan23.lisp \
$(outdir)/feta-alphabet23.lisp
$(outdir)/feta20.otf-table: $(outdir)/feta20.lisp \
- $(outdir)/feta-noteheads23.lisp \
+ $(outdir)/feta-noteheads20.lisp \
$(outdir)/parmesan20.lisp \
$(outdir)/feta-alphabet20.lisp
$(outdir)/feta18.otf-table: $(outdir)/feta18.lisp \
save flagspace, total_depth, flag_count;
flag_count = 3;
- total_depth# = 4.25 staff_space#;
+ total_depth# = 4.25 staff_space# - blot_diameter# / 2;
flare = .85 staff_space;
flagspace# = .87 staff_space#;
hip_depth_ratio = .72;
save flagspace, total_depth, flag_count;
flag_count = 4;
- total_depth# = 5.25 staff_space#;
+ total_depth# = 5.25 staff_space# - blot_diameter# / 2;
flare = .85 staff_space;
flagspace# = .9 staff_space#;
hip_depth_ratio = .72;
save flagspace, total_depth, flag_count;
flag_count = 5;
- total_depth# = 6.25 staff_space#;
+ total_depth# = 6.25 staff_space# - blot_diameter# / 2;
flare = .85 staff_space;
flagspace# = .93 staff_space#;
hip_depth_ratio = .72;
save flagspace, total_depth, flag_count;
flag_count = 1;
- total_depth# = 2.85 staff_space#;
+ total_depth# = 2.75 staff_space#;
flare = staff_space;
flagspace# = .9 staff_space#;
- hip_depth_ratio = .72;
+ hip_depth_ratio = .74;
hip_width# = downflag_width# - hip_thickness# / 2;
- foot_width_ratio = .8;
+ foot_width_ratio = .85;
(flag_count - 1) * flagspace# + foot_depth# = total_depth#;
flag_count = 2;
total_depth# = 3.0 staff_space# - blot_diameter# / 2;
- flare = .8 staff_space;
+ flare = .82 staff_space;
flagspace# = .9 staff_space#;
hip_depth_ratio = .85;
hip_width# = downflag_width# - hip_thickness# / 2;
flag_count = 3;
total_depth# = 3.75 * staff_space# - blot_diameter# / 2;
- flare = .84 staff_space;
- flagspace# = .9 staff_space#;
- hip_depth_ratio = .85;
+ flare = .82 staff_space;
+ flagspace# = .88 staff_space#;
+ hip_depth_ratio = .87;
hip_width# = downflag_width# - hip_thickness# / 2;
- foot_width_ratio = .95;
+ foot_width_ratio = .965;
(flag_count - 1) * flagspace# + foot_depth# = total_depth#;
hip_depth_ratio, foot_width_ratio,
hip_thickness, foot_thickness, 0);
- add_flag (flagspace, flare, .97, 1.00, 1.25,
+ add_flag (flagspace, flare, .98, 1.00, 1.22,
hip_thickness, foot_thickness);
- add_flag (flagspace, flare, .95, 1.05, 1.25,
+ add_flag (flagspace, flare, .95, 1.02, 1.22,
hip_thickness, foot_thickness);
draw_square_block ((-0.5 stemthickness_rounded, 0),
save flagspace, total_depth, flag_count;
flag_count = 4;
- total_depth# = 4.35 staff_space#;
+ total_depth# = 4.5 staff_space# - blot_diameter# / 2;
flare = .8 staff_space;
flagspace# = .9 staff_space#;
- hip_depth_ratio = .85;
+ hip_depth_ratio = .83;
hip_width# = downflag_width# - hip_thickness# / 2;
- foot_width_ratio = .98;
+ foot_width_ratio = .975;
(flag_count - 1) * flagspace# + foot_depth# = total_depth#;
hip_depth_ratio, foot_width_ratio,
hip_thickness, foot_thickness, 0);
- add_flag (flagspace, flare, .97, 1.20, 1.175,
+ add_flag (flagspace, flare, .98, 1.10, 1.19,
hip_thickness, foot_thickness);
- add_flag (flagspace, flare, .97, 1.10, 1.175,
+ add_flag (flagspace, flare, .98, 1.08, 1.19,
hip_thickness, foot_thickness);
- add_flag (.98 flagspace, flare, .91, 1.05, 1.2,
+ add_flag (.98 flagspace, flare, .94, 1.04, 1.21,
hip_thickness, foot_thickness);
draw_square_block ((-0.5 stemthickness_rounded, 0),
save flagspace, total_depth, flag_count;
flag_count = 5;
- total_depth# = 5.25 staff_space#;
+ total_depth# = 5.5 staff_space# - blot_diameter# / 2;
flare = .8 staff_space;
- flagspace# = .9 staff_space#;
+ flagspace# = .92 staff_space#;
hip_depth_ratio = .85;
hip_width# = downflag_width# - hip_thickness# / 2;
foot_width_ratio = .98;
hip_depth_ratio, foot_width_ratio,
hip_thickness, foot_thickness, 0);
- add_flag (flagspace, flare, .97, 1.20, 1.175,
+ add_flag (flagspace, flare, .98, 1.10, 1.185,
hip_thickness, foot_thickness);
- add_flag (flagspace, flare, .97, 1.10, 1.175,
+ add_flag (flagspace, flare, .98, 1.08, 1.185,
hip_thickness, foot_thickness);
- add_flag (.98 flagspace, flare, .91, 1.05, 1.2,
+ add_flag (.98 flagspace, flare, .97, 1.06, 1.2,
hip_thickness, foot_thickness);
- add_flag (.98 flagspace, flare, .91, 1.05, 1.2,
+ add_flag (.98 flagspace, flare, .93, 1.04, 1.22,
hip_thickness, foot_thickness);
draw_square_block ((-0.5 stemthickness_rounded, 0),
))
(gap . 0.5)
(left-bound-info . ,ly:line-spanner::calc-left-bound-info)
+ (normalized-endpoints . ,ly:spanner::calc-normalized-endpoints)
(right-bound-info . ,ly:line-spanner::calc-right-bound-info)
(stencil . ,ly:line-spanner::print)
(style . line)
;;; If an exception is specified for a given beam-type, it will apply to all
;;; beams of shorter durations that don't have an individual exception, so
;;; ((1 . 8) . (3 3 2))
-;;; will cause all primary beams to be broken at 3/8, 5/8, and 8/8.
+;;; will cause all primary beams to be broken at 3/8, 6/8, and 8/8.
;;;
;;; ((1. 32) . (16 8 4 4))
;;; will cause all 1/32, 1/64, and 1/128 beams to be broken at 1/2, 3/4,
;;; a list of (1 1 1 ...), where the number of entries is the
;;; number of base moments in a measure otherwise.
;;;
-;;; If no value is given for beatCombinations, no beats will be combined without
-;;; beamExceptions rules.
-;;;
;;; NOTE: numerator is kept in beam-type because of
;;; tuplets, e.g. (2 . 24) = (2 . 3) * (1 . 8)
;;; for eighth-note triplets.
def print_results (self, threshold):
self.write_text_result_page ('', threshold)
-def compare_trees (dir1, dir2, dest_dir, threshold):
+def compare_tree_pairs (tree_pairs, dest_dir, threshold):
data = ComparisonData ()
- data.compare_trees (dir1, dir2)
+ for dir1, dir2 in tree_pairs:
+ data.compare_trees (dir1, dir2)
data.read_sources ()
-
data.print_results (threshold)
if os.path.isdir (dest_dir):
os.environ["HOME"] + "/src/lilypond-stable/scripts/build/", '*.py')
-def test_compare_trees ():
+def test_compare_tree_pairs ():
system ('rm -rf dir1 dir2')
system ('mkdir dir1 dir2')
system ('cp 20{-*.signature,.ly,.png,.eps,.log,.profile} dir1')
system ('cp 19multipage.log dir1/log-differ.log')
system ('cp 19multipage.log dir2/log-differ.log && echo different >> dir2/log-differ.log && echo different >> dir2/log-differ.log')
- compare_trees ('dir1', 'dir2', 'compare-dir1dir2', options.threshold)
+ compare_tree_pairs (['dir1', 'dir2'], 'compare-dir1dir2', options.threshold)
def test_basic_compare ():
if do_clean:
test_basic_compare ()
- test_compare_trees ()
+ test_compare_tree_pairs ()
################################################################
#
def main ():
p = optparse.OptionParser ("output-distance - compare LilyPond formatting runs")
- p.usage = 'output-distance.py [options] tree1 tree2'
+ p.usage = 'output-distance.py [options] tree1 tree2 [tree3 tree4]...'
p.add_option ('', '--test-self',
dest="run_test",
run_tests ()
sys.exit (0)
- if len (args) != 2:
- p.print_usage()
+ if len (args) % 2:
+ p.print_usage ()
sys.exit (2)
- name = options.output_dir
- if not name:
- name = args[0].replace ('/', '')
- name = os.path.join (args[1], 'compare-' + shorten_string (name))
+ out = options.output_dir
+ if not out:
+ out = args[0].replace ('/', '')
+ out = os.path.join (args[1], 'compare-' + shorten_string (out))
- compare_trees (args[0], args[1], name, options.threshold)
+ compare_tree_pairs (zip (args[0::2], args[1::2]), out, options.threshold)
if __name__ == '__main__':
- main()
+ main ()
if not n and not vv and global_options.key:
s += global_options.key.dump ()
if average_pitch[vv+1] and voices > 1:
- s += ' \\voice' + get_voice_layout (average_pitch[1:])[vv] + '\n'
+ vl = get_voice_layout (average_pitch[1:])[vv]
+ if vl:
+ s += ' \\voice' + vl + '\n'
+ else:
+ warning (_ ('found more than 5 voices on a staff, expect bad output'))
s += ' ' + dump_voice (voice, skip)
s += '}\n\n'
v += 1
s += '\n\\score {\n <<\n'
+ control_track = False
i = 0
for i, staff in enumerate (staves):
track_name = get_track_name (i)
staff_name = track_name
context = None
if not i and not item and len (staves) > 1:
- # control track
- staff_name = get_track_name (1)
- context = 'Staff'
+ control_track = track_name
+ continue
elif (item and item.__class__ == Note):
context = 'Staff'
+ if control_track:
+ s += ' \\context %(context)s=%(staff_name)s \\%(control_track)s\n' % locals ()
elif item and item.__class__ == Text:
context = 'Lyrics'
if context: