-1.3.123.hwn1
+1.3.124.jcn1
============
+* Bugfix: automatic interstaff knees.
+
+1.3.124.hwn1
+============
+
+* Auto change music bugfix; removed Auto_change_music type
+
+* Bugfix: add copy ctors to all relevant iterators, this fixes various
+combinations with auto-change and part-combine.
+
+* Bugfix: glissandi with smaller rhythms parallel.
+
+* Add printfilename option to @lilypondfile
+
+1.3.124
+=======
+
* Tutorial fragment on ly2dvi.
* Bugfix: also print path of mismatched .TFM file.
Officially BugFree (tm). This document is intended for finding bugs,
and documenting bugfixes.
-[TODO: revise and completize this. ]
-
-
-
@section Notes and rests
-@lilypondfile{rest.ly}
+@lilypondfile[printfilename]{rest.ly}
-@lilypondfile{noteheadstyle.ly}
+@lilypondfile[printfilename]{noteheadstyle.ly}
-@lilypondfile{dots.ly}
+@lilypondfile[printfilename]{dots.ly}
-@lilypondfile{accidental.ly}
+@lilypondfile[printfilename]{accidental.ly}
-@lilypondfile{multi-measure-rest.ly}
+@lilypondfile[printfilename]{multi-measure-rest.ly}
-@lilypondfile{mm-rests2.ly}
+@lilypondfile[printfilename]{mm-rests2.ly}
-@lilypondfile{accidental-single-double.ly}
+@lilypondfile[printfilename]{accidental-single-double.ly}
@section Stems
-@lilypondfile{stem-tremolo.ly}
+@lilypondfile[printfilename]{stem-tremolo.ly}
-@lilypondfile{chord-tremolo.ly}
+@lilypondfile[printfilename]{chord-tremolo.ly}
-@lilypondfile{stem-direction.ly}
+@lilypondfile[printfilename]{stem-direction.ly}
-@lilypondfile{stem-direction-down.ly}
+@lilypondfile[printfilename]{stem-direction-down.ly}
@section Scripts
-@lilypondfile{staccato-pos.ly}
+@lilypondfile[printfilename]{staccato-pos.ly}
-@lilypondfile{dyn-line.ly}
+@lilypondfile[printfilename]{dyn-line.ly}
-@lilypondfile{arpeggio.ly}
+@lilypondfile[printfilename]{arpeggio.ly}
-@lilypondfile{glissando.ly}
+@lilypondfile[printfilename]{glissando.ly}
-@lilypondfile{follow-thread.ly}
+@lilypondfile[printfilename]{follow-thread.ly}
@section Chord names
-@lilypondfile{chord-names.ly}
+@lilypondfile[printfilename]{chord-names.ly}
@section Grace notes
-@lilypondfile{grace.ly}
+@lilypondfile[printfilename]{grace.ly}
@section Beams, slurs and other spanners
-@lilypondfile{beaming.ly}
+@lilypondfile[printfilename]{beaming.ly}
+
+@lilypondfile[printfilename]{beam-extreme.ly}
+
+@lilypondfile[printfilename]{beam-position.ly}
-@lilypondfile{beam-extreme.ly}
+@lilypondfile[printfilename]{auto-beam-bar.ly}
-@lilypondfile{beam-position.ly}
+@lilypondfile[printfilename]{beam-rest.ly}
-@lilypondfile{auto-beam-bar.ly}
+@lilypondfile[printfilename]{beam-length.ly}
-@lilypondfile{beam-rest.ly}
+@lilypondfile[printfilename]{beam-dir-function.ly}
-@lilypondfile{beam-length.ly}
+@lilypondfile[printfilename]{auto-knee.ly}
-@lilypondfile{beam-dir-function.ly}
+@lilypondfile[printfilename]{auto-isknee.ly}
-@lilypondfile{triplets.ly}
+@lilypondfile[printfilename]{triplets.ly}
-@lilypondfile{slur-nice.ly}
-@lilypondfile{slur-symmetry.ly}
-@lilypondfile{slur-symmetry-1.ly}
+@lilypondfile[printfilename]{slur-nice.ly}
+@lilypondfile[printfilename]{slur-symmetry.ly}
+@lilypondfile[printfilename]{slur-symmetry-1.ly}
-@lilypondfile{slur-broken-trend.ly}
+@lilypondfile[printfilename]{slur-broken-trend.ly}
-@lilypondfile{slur-attachment.ly}
+@lilypondfile[printfilename]{slur-attachment.ly}
-@lilypondfile{slur-attachment-override.ly}
+@lilypondfile[printfilename]{slur-attachment-override.ly}
-@lilypondfile{ophee-slurs.ly}
+@lilypondfile[printfilename]{ophee-slurs.ly}
-@lilypondfile{tie.ly}
+@lilypondfile[printfilename]{tie.ly}
-@lilypondfile{tie-chord.ly}
+@lilypondfile[printfilename]{tie-chord.ly}
-@lilypondfile{tie-accidental.ly}
+@lilypondfile[printfilename]{tie-accidental.ly}
-@lilypondfile{beam-cross-staff.ly}
+@lilypondfile[printfilename]{beam-cross-staff.ly}
-@lilypondfile{slur-cross-staff.ly}
+@lilypondfile[printfilename]{slur-cross-staff.ly}
-@lilypondfile{tup.ly}
+@lilypondfile[printfilename]{tup.ly}
@section Property details
-@lilypondfile{generic-property-override.ly}
+@lilypondfile[printfilename]{generic-property-override.ly}
@section Repeats
-@lilypondfile{repeat-unfold.ly}
+@lilypondfile[printfilename]{repeat-unfold.ly}
-@lilypondfile{repeat-volta.ly}
+@lilypondfile[printfilename]{repeat-volta.ly}
-@lilypondfile{repeat-fold.ly}
+@lilypondfile[printfilename]{repeat-fold.ly}
-@lilypondfile{repeat-line-break.ly}
+@lilypondfile[printfilename]{repeat-line-break.ly}
-@lilypondfile{auto-change.ly}
+@lilypondfile[printfilename]{auto-change.ly}
@section Lyrics
-@lilypondfile{lyric-combine.ly}
+@lilypondfile[printfilename]{lyric-combine.ly}
-@lilypondfile{lyrics-multi-stanza.ly}
+@lilypondfile[printfilename]{lyrics-multi-stanza.ly}
@section Multiple notes
-@lilypondfile{rest-collision.ly}
+@lilypondfile[printfilename]{rest-collision.ly}
-@lilypondfile{collisions.ly}
+@lilypondfile[printfilename]{collisions.ly}
-@lilypondfile{number-staff-lines.ly}
+@lilypondfile[printfilename]{number-staff-lines.ly}
@section Spacing
-@lilypondfile{stem-spacing.ly}
+@lilypondfile[printfilename]{stem-spacing.ly}
-@lilypondfile{spacing-tight.ly}
+@lilypondfile[printfilename]{spacing-tight.ly}
-@lilypondfile{spacing-natural.ly}
+@lilypondfile[printfilename]{spacing-natural.ly}
-@lilypondfile{spacing-loose.ly}
+@lilypondfile[printfilename]{spacing-loose.ly}
-@lilypondfile{lyrics-bar.ly}
+@lilypondfile[printfilename]{lyrics-bar.ly}
-@lilypondfile{non-empty-text.ly}
+@lilypondfile[printfilename]{non-empty-text.ly}
@section Global stuff
-@lilypondfile{break.ly}
+@lilypondfile[printfilename]{break.ly}
-@lilypondfile{bar-scripts.ly}
+@lilypondfile[printfilename]{bar-scripts.ly}
-@lilypondfile{staff-margin.ly}
+@lilypondfile[printfilename]{staff-margin.ly}
-@lilypondfile{breathing-sign.ly}
+@lilypondfile[printfilename]{breathing-sign.ly}
-@lilypondfile{hara-kiri-short.ly}
+@lilypondfile[printfilename]{hara-kiri-short.ly}
-@lilypondfile{part-combine.ly}
+@lilypondfile[printfilename]{part-combine.ly}
-@lilypondfile[nonfragment]{size11.ly}
+@lilypondfile[printfilename,nonfragment]{size11.ly}
-@lilypondfile[nonfragment]{size13.ly}
+@lilypondfile[printfilename,nonfragment]{size13.ly}
-@lilypondfile[nonfragment]{size16.ly}
+@lilypondfile[printfilename,nonfragment]{size16.ly}
-@lilypondfile[nonfragment]{size20.ly}
+@lilypondfile[printfilename,nonfragment]{size20.ly}
-@lilypondfile[nonfragment]{size23.ly}
+@lilypondfile[printfilename,nonfragment]{size23.ly}
-@lilypondfile[nonfragment]{size26.ly}
+@lilypondfile[printfilename,nonfragment]{size26.ly}
@section Clefs and Time Signatures
-@lilypondfile{clefs.ly}
+@lilypondfile[printfilename]{clefs.ly}
-@lilypondfile{keys.ly}
+@lilypondfile[printfilename]{keys.ly}
@ignore
@section Hacks and Features
-@lilypondfile{generic-output-property.ly}
+@lilypondfile[printfilename]{generic-output-property.ly}
-@lilypondfile{between-systems.ly}
+@lilypondfile[printfilename]{between-systems.ly}
@bye
LilyPond uses a versioning scheme similar to the Linux kernel. In a
version "x.y.z", an even second number 'y' denotes a stable version.
-For development versions 'y' is odd. Sh, in theory, version 1.2 is stable,
+For development versions 'y' is odd. So, in theory, version 1.2 is stable,
which means that there are no glaring errors in it. In practice 1.2.x is also
unmaintained.
@email{gnu-music-discuss@@gnu.org}. Please consult the FAQ and
installation instructions before mailing your problems.
-@section CDROM distributions
-
-If you have received LilyPond on a cdrom, chances are that development
-has moved some patchlevels up. Please check the latest version of
-LilyPond before reporting bugs.
@bye
cd $(outdir) && rm -f lilypond && ln -s . lilypond
cd $(outdir) && rm -f lilypond-internals && ln -s . lilypond-internals
cd $(outdir) && $(foreach i, $(LILYPOND_LINKS),\
- rm -f $(i) && ln -s $(i) lilypond.html &&) true
+ rm -f $(i) && ln -s lilypond.html $(i) &&) true
endif
@itemize @bullet
-@item @strong{important:} a sample input which causes the error.
+@item a sample input which causes the error. This is @strong{important
+} to determine the cause of the problem.
(and you will do us a favor if send a @strong{small} sample file)
-@item @strong{important:} which LilyPond version you use.
+@item which LilyPond version you use. This is @strong{important information}
+
This information tells us if you've found a new bug, or an old one.
@c -*-texinfo-*-
-@node Convert-ly
-@section Convert-ly
+@node convert-ly
+@section convert-ly
Convert-ly sequentially applies different
@menu
* Conversion stages:: Lilypond is a multi-pass program.
+* Moment::
* Grobs:: Graphical object
* Engraver::
* Music_iterator::
* Music::
* Molecules:: Molecules are stand-alone descriptions of output
+* Font metrics:: Font metrics
@end menu
@node Conversion stages
@end table
+@node Moment
+@section Moment
+
+Moment is a rational number. Since GUILE doesn't support them natively,
+so we created our own rational data type.
+
+@defun moment?
+@end defun
+
+@defun make-moment num den
+create the rational number @var{num}/@var{den}.
+@end defun
@node Grobs
@section Grobs
* Setting grob properties::
* Items and Spanners::
* Pointer substitution::
+* Grob Scheme functions::
@end menu
@node What is a grob?
the grob is made. A substitution process redirects all grob-reference
so that spanner grob will only reference other grobs in the same line.
+@node Grob Scheme functions
+@unnumberedsubsec Grob Scheme functions
+
+
+@defun ly-get-grob-property g sym
+ Get the value of a value in grob @var{g} of property @var{sym}. It
+will return @code{'()} (end-of-list) if not true.
+@end defun
+
+@defun ly-set-grob-property g sym val
+@end defun
+
+@defun ly-get-spanner-bound spanner dir
+@end defun
+
+@defun ly-grob? g
+@end defun
+
+
+
@node Engraver
@section Engraver
be a Scheme function taking one argument (the grob) and returning a
Molecule.
+@defun molecule? m
+@end defun
+
+@defun ly-combine-molecule-at-edge mol1 axis dir mol2 padding
+@end defun
+
+@defun molecule? m
+@end defun
+
+@defun ly-get-molecule-extent! mol axis
+@end defun
+
+@defun ly-set-molecule-extent! mol axis extent
+@end defun
+
+@node Font metrics
+@section Font metrics
+
+The font object represents the metric information of a font. Every font
+that is loaded into LilyPond can be accessed via Scheme.
+
+[tfm vs. afm]
+
+
+@defun ly-get-default-font gr
+This returns the default font for grob @var{gr}.
+@end defun
+
+@defun ly-find-glyph-by-name font name
+This function retrieves a Molecule for the glyph named @var{name} in
+@var{font}. The font must be available as a afm file.
+@cindex afm file
+
+@end defun
@node Development
* Bug reports:: Where to report bugs.
* Reference Manual:: Reference Manual.
* Features:: Features, tips and tricks.
-* Internals:(lilypond-internals). Auto generated detailed documentation.
-* Programs:: External programs.
+* Utility programs:: External programs.
* Internals:: How it all works.
* Development:: On developing code for LilyPond.
-* Index:: Unified index.
+* Index of internals:(lilypond-internals). Auto generated detailed documentation.
+* Index:: Unified index.
+* Function Index:: Function index.
@end menu
@contents
@printindex cp
+@node Function Index
+@unnumbered Function Index
+
+@printindex fn
+
+
+
@bye
@c -*-texinfo-*-
-@node Ly2dvi
-@section Ly2dvi
+@node ly2dvi
+@section ly2dvi
Ly2dvi is a Python script which creates input file for La@TeX{},
based on information from the output files from LilyPond.
@c -*-texinfo-*-
-@node Midi2ly
-@section Midi2ly
+@node midi2ly
+@section midi2ly
Midi2ly translates a MIDI input file to a LilyPond source file.
Midi2ly is part of the GNU LilyPond music typesetting package.
@c -*-texinfo-*-
-@node Programs
-@chapter Programs
+@node Utility programs
+@chapter Utility programs
@menu
-* Ly2dvi:: Generating nice output with titles.
-* Convert-ly:: Upgrading input files.
-* Midi2ly:: Converting from MIDI input.
+* ly2dvi:: Generating nice output with titles.
+* convert-ly:: Upgrading input files.
+* midi2ly:: Converting from MIDI input.
@end menu
@mbinclude ly2dvi.itexi
@item Molecule: device-independent page output object,
including dimensions. Produced by some Grob functions
See @ref{Molecules}
- @item Translator: object that produces audio objects or Grobs.
- @item Font_metric: object representing a font. (Not yet user
-accessible.)
-
+ @item Translator: object that produces audio objects or Grobs. This is
+not yet user accessible.
+ @item Font_metric: object representing a font. (See @ref{Font metrics})
@c @item Audio_element: (todo, smobme)
@end itemize
@file{layout.ly},
@example
+ \version "1.3.124";
\header @{ title = "Two miniatures"; @}
- #(set point-and-click #t)
+ #(set! point-and-click #t)
\paper @{
linewidth = -1.0; @}
@end example
@file{ly2dvi} runs it through LaTeX. LaTeX is a text-formatting system
-built on top of @TeX. It's very popular in the academic world. If LaTeX
+built on top of @TeX{}. It's very popular in the academic world. If LaTeX
is successful, this will produce a @file{.dvi} file, containing both the
titling and notes. @code{ly2dvi} completes its task by deleting the two
temporary files, leaving only @file{layout.dvi}.
+Next, now we'll look at the examples line by line to explain new things.
+
+@example
+\version "1.3.124";
+@end example
+Lilypond and its language are still under development, and occasionally,
+details of the syntax are changed. This fragment indicates for which
+version the input file was written. When you compile this file, the
+version number will be checked, and you will get a warning when the file
+is too old.
+
+This version number is also used by the @code{convert-ly} program (See
+@ref{convert-ly}), which uses it update the file to the latest lily
+version.
+
@example
- #(set point-and-click #t)
+ \header @{ title = "Two miniatures"; @}
+@end example
+This sets the titling information for the entire file.
+
+@example
+ #(set! point-and-click #t)
@end example
Editing input files can be quite complicated if you're working with
Sammartini. It was composed around 1740.
@lilypond[verbatim]
-
-\version "1.3.60";
\include "paper16.ly";
+stemdown = \property Voice.Stem \override #'direction = #-1
+stemup = \property Voice.Stem \override #'direction = #1
+stemboth = \property Voice.Stem \revert #'direction
+
viola = \notes \relative c' \context Voice = viola {
- <c4-\f g' c>
- \stemDown g'8. b,16
- s1 s2. r4
- g
+ <c4-\f g' c>
+ \stemdown g'8. b,16
+ s1 s2. r4
+ g
}
oboes = \notes \relative c'' \context Voice = oboe {
- \stemUp s4 g8. b,16 c8 r <e'8.-\p g> <f16 a>
- \grace <e8( g> <d4 f> <c2 e> \times 2/3 { <d8 \< f> <e g> <f a> }
- <
- { \times 2/3 { a8 g c } \! c2 }
- \context Voice = oboeTwo {
- \stemDown
- \grace {
- \property Grace.Stem \override #'direction = #-1
- [f,16 g] }
- f8 e e2
- } >
- \stemBoth
- \grace <c,8( e> <)b8. d8.-\trill> <c16 e> |
- [<d ( f> < )f8. a>] <)b,8 d> r [<d16( f> <f8. )a>] <b,8 d> r |
- [<c16( e> < )e8. g>] <c8 e,>
+ \stemup s4 g8. b,16 c8 r <e'8.-\p g> <f16 a>
+ \grace <e8( g> <d4 f> <c2 e> \times 2/3 { <d8 \< f> <e g> <f a> }
+ <
+ { \times 2/3 { a8 g c } \! c2 }
+ \context Voice = oboeTwo {
+ \stemdown
+ \grace {
+ \property Grace.Stem \override #'direction = #-1
+ [f,16 g] }
+ f8 e e2
+ } >
+ \stemboth
+ \grace <c,8( e> <)b8. d8.-\trill> <c16 e> |
+ [<d ( f> < )f8. a>] <)b,8 d> r [<d16( f> <f8. )a>] <b,8 d> r |
+ [<c16( e> < )e8. g>] <c8 e,>
}
-hoomPah = \notes \transpose c' {
- c8 \translator Staff = top \stemDown
- c'8 \translator Staff = bottom \stemUp }
-
-hoomPahHoomPah = { [\hoomPah \hoomPah] }
+hoomPah = \notes \repeat unfold 8 \transpose c' { c8 \stemdown c'8 \stemup }
bassvoices = \notes \relative c' {
- c4 g8. b,16
- \repeat unfold 4 {\hoomPahHoomPah}
- \stemDown [c8 c'8] r4
- <g d'> r4
- < {\stemUp r2 <e4 c'> <c8 g'> }
- \context Voice = reallyLow {\stemDown g2 ~ | g4 c8 } >
+ c4 g8. b,16
+ \autochange Staff \hoomPah o
+ \translator Staff = down
+ \stemdown [c8 c'8] r4
+ <g d'> r4
+ < {\stemup r2 <e4 c'> <c8 g'> }
+ \context Voice = reallyLow {\stemdown g2 ~ | g4 c8 } >
}
\score {
- \context PianoStaff \notes <
- \context Staff = top < \time 2/2;
- \viola
- \oboes
- >
- \context Staff = bottom < \time 2/2; \clef bass;
- \bassvoices
- >
- >
- \midi { }
- \paper {
- indent = 0.0;
- linewidth = 15.0 \cm; }
+ \context PianoStaff \notes <
+ \context Staff = up < \time 2/2;
+ \viola
+ \oboes
+ >
+ \context Staff = down < \time 2/2; \clef bass;
+ \bassvoices
+ >
+ >
+ \midi { }
+ \paper {
+ indent = 0.0;
+ linewidth = 15.0 \cm; }
}
@end lilypond
-If it looks like incomprehensible gibberish to you@dots{} Then you are
-right. The author has doctored this example to have as many quirks in
-one system as possible.
-@example
-\version "1.3.61";
-@end example
-Lilypond and the Lilypond language is still under development, therefore
-it is useful to indicate the Lilypond version of the file. Lilypond
-will check the version number and warn you when the syntax has
-changed. Also, the @code{convert-ly} program will be able to
-update most of the syntax changes automatically.
+If it looks like incomprehensible gibberish to you, then you are right.
+This example has been doctored this example to have as many quirks as
+possible.
+
+@example
+stemdown = \property Voice.Stem \override #'direction = #-1
+stemup = \property Voice.Stem \override #'direction = #1
+stemboth = \property Voice.Stem \revert #'direction
+@end example
+
+[explain grob push/pop]
+
@example
viola = \notes \relative c' \context Voice = viola @{
@end example
@code{<} and @code{>} are short hands for @code{\simultaneous @{} and
@code{@}}. So the expression enclosed in @code{<} and @code{>} is a
chord. @code{\f} places a forte symbol under the chord.
-[FIXME]
@example
- \property Voice.verticalDirection = \down
+ \stemdown
@end example
-@code{verticalDirection} is a property of the voice context. It
-controls the directions of stems, articulations marks and other
-symbols.
-If @code{verticalDirection} is set to @code{\down}
-(identifier for the integer -1) the stems go down,
-@code{\up} (identifier for the integer 1) makes the stems go up.
+
@example
g'8. b,16
@end example
\stemUp s4 g8. b,16 c8 r <e'8.-\p g> <f16 a>
@end example
@code{\stemUp} is an identifier reference. It is shorthand for
-@code{\property Voice.verticalDirection = \up}. If possible, you
+@code{\property Voice.Stem \override #'direction = #1}. If possible, you
should use predefined identifiers like these for setting properties.
Your input will be less dependent upon the implementation of LilyPond.
@example
@code{\grace} is sequential music.
@example
-\property Grace.verticalDirection = \down
+\property Grace.Stem \override #'direction = #-1
[f,16 g] @}
- [FIXME]
@end example
+
Normally, grace notes are always stem up, but in this case, the upper
voice interferes. We set the stems down here.
positioned as if it were single part music.
The bass has a little hoom-pah melody to demonstrate parts switching
-between staffs. Since it is repetitive, we use identifiers:
+between staffs. Since it is repetitive, we use repeats:
@example
-hoomPah = \notes \transpose c' @{
-@end example
+hoomPah = \notes \repeat unfold 8
+@end example
+
+@example
+\transpose c' @{
+@end example
Transposing can be done with @code{\transpose}. It takes two
arguments; the first specifies what central C should be transposed to.
The second is the to-be-transposed music. As you can see, in this
-case, the transposition is a no-op. Central C is transposed to
+case, the transposition is a no-op, as central C would be transposed to
central C.
-The purpose of this no-op is circumventing relative mode. Relative
-mode can not be used in conjunction with transposition, so relative
-mode will leave the contents of @code{\hoomPah} alone. We can use it
-without having to worry about getting the motive in a wrong
-octave@footnote{@code{hoomPah = \relative @dots{}} would be more
-intuitive to use, but that would not let me plug @code{\transpose}
-:-).}.
-@example
-c8 \translator Staff = top \stemDown
-@end example
-We assume that the first note will be put in the lower staff. After
-that note we switch to the upper staff with @code{\translator}. To be
-precise, this @code{\translator} entry switches the current voice to a
-@code{Staff} named @code{top}. So we have to name the upper staff
-`@code{top}'. Stem directions are set to avoid interfering with the
-oboe voices.
-@example
-c'8 \translator Staff = bottom \stemUp @}
-@end example
-Then a note is put on the upper staff, and we switch again. We have
-to name the lower staff `@code{bottom}'.
+The purpose of this no-op is circumventing relative mode. Relative mode
+can not be used in conjunction with transposition, so relative mode will
+leave the contents of @code{\hoomPah} alone. We can use it without
+having to worry about getting the motive in a wrong octave.
@example
-hoomPahHoomPah = @{ [\hoomPah \hoomPah] @}
-@end example
-Put two of these fragments in sequence, and beam them.@example
bassvoices = \notes \relative c' @{
c4 g8. b,16
-\repeat unfold 4 @{\hoomPahHoomPah @}
+\autochange Staff \hoomPah
@end example
Entering the bass part is easy: the hoomPahHoomPah variable is
repeated four times; @code{unfold} means that all four repetitions
should be written out.
+
+@example
+ \translator Staff = down
+@end example
+
@example
\context Voice = reallyLow @{\stemDown g2 ~ | g4 c8 @} >
@end example
@end example
To make some more room on the line, the first (in this case the only)
line is not indented. The line still looks very cramped, but that is due
-to the format of this tutorial.
+to the page layout of this document.
+
+[TODO:
+
+Split piano in 2
+
+* Piano I: autochange, simple chords, arpeggio, glissando, tuplets
+unfolded repeat, space rests.
+
+* Piano II: property push/pop, grace notes, multiple voices,
+dynamics, stem up/stem down,
-This example shows a lot of features, but the organisation isn't
-perfect. For example, it would be less confusing to use a chord
-containing sequential music than a sequence of chords for the oboe
-parts.
+* Orchestral: demonstrate Hara-Kiri, part combining, part extraction,
+scores, transposition, instrument names,
-[TODO: demonstrate Hara-Kiri with scores and part extraction.]
+]
@node end of tutorial
@section The end
MAJOR_VERSION=1
MINOR_VERSION=3
PATCH_LEVEL=124
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=jcn1
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
--- /dev/null
+
+% y-pos of f is wrong
+
+\score {
+ \notes \relative c' \context Voice = viola {
+ <c4-\f g' c>
+ \stemDown g'8. b,16
+ s1 s2. r4
+ g }
+}
-\version "1.3.117";
+\header{
+texidoc="Two automatic knees";
+}
+
\score {
- \notes \context PianoStaff <
- \context Staff = "up" {
- \autochange Staff \relative c' {
- [c8 e'] [c' c,,]
- \stemDown
- c'8 c c g,
- g8 d' d d
- \stemUp
- b8 c d e
- }
- }
- \context Staff = "down" {
- \clef bass;
- s1*2
- }
- >
- \paper{
- \translator{
- \StaffContext
- autoKneeGap = #13.0
- autoInterstaffKneeGap = #4.0
- }
- }
+ \notes \context PianoStaff <
+ \context Staff = "up" \notes\relative c''{
+ [ b8 \translator Staff="down" d,, ]
+ [ c \translator Staff="up" c'' ]
+ [ b, \translator Staff="down" d ]
+ }
+ \context Staff = "down" {
+ \clef bass;
+ s2.
+ }
+ >
+ \paper{
+ linewidth = 40*\staffspace;
+ \translator{
+ \VoiceContext
+ Beam \override #'auto-interstaff-knee-gap = #4.0
+ }
+ }
}
+\header{
+texidoc="One automatic knee";
+}
\score {
- \context Staff \notes\relative c'{
-% \property Voice.autoKneeGap = #13
- [c8 e'] [c' c,,]
- }
- \paper{
- \translator{
- \StaffContext
- autoKneeGap = #13
- }
- }
+ \context Staff \notes\relative c''{
+ [c'8 c,,] [c8 e']
+ }
+ \paper{
+ linewidth = 40*\staffspace;
+ \translator {
+ \VoiceContext
+ Beam \override #'auto-knee-gap = #13
+ }
+ }
}
-\score
-{
- \context StaffGroup = a <
- \context PianoStaff = b <
- \context Staff = "c" \notes\relative c'' { b4 b \bar "empty"; \break b b }
- \context Staff = "d" \notes\relative c'' { b4 b b b }
- >
- >
- \paper {
- indent=100.0\mm;
- linewidth=150.0\mm;
- \translator {
- \StaffContext
- \consists "Instrument_name_engraver";
- numberOfStaffLines = #1
- marginScriptPadding = #30 % urg: this is in PT
- instrument = #"Foo"
- instr = #"Bar"
- }
- \translator {
- \StaffGroupContext
- \consists "Instrument_name_engraver";
- marginScriptPadding = #10 % urg: this is in PT
- instrument = #"Piano in het midden"
- }
- }
-}
\header{
texidoc="
-As a last resort, the placement of items can be adjusted manually, by
-setting the @code{extra-offset} of an output object.
+As a last resort, the placement of grobs can be adjusted manually, by
+setting the @code{extra-offset} of a grob.
";
}
}
\paper{
linewidth=-1.0;
- \translator {
- \ScoreContext
- \consists "Mark_engraver";
- }
}
}
\header{
-texidoc="
-Simple glissando lines between notes are supported. The first two glissandi are not consecutive.
+
+texidoc=" Simple glissando lines between notes are supported.
+The first two glissandi are not consecutive.
+
+The engraver does no time-keeping, so it involves some trickery to get
+< @{ s8 s8 s4 @} @{ c4 \\gliss d4 @} > working correctly.
+
";
}
\score{
\context Staff=one \notes\relative c''{
- % gliss non gliss and
- c \glissando d e \glissando f\break
+ % gliss non gliss and
+ c4 \glissando d e \glissando f \glissando \break
% consecutive
- c \glissando d \glissando e f
+ c \glissando d \glissando e
+ < { \stemUp e8 \glissando g8 }
+ \context Voice = VB {\stemDown \repeat unfold 4 d16 } >
+
}
\paper{
linewidth = 70.\mm;
% \remove Clef_engraver;
}
}
-}
\ No newline at end of file
+}
-% :-(
x = {
-\outputproperty #(make-type-checker 'Note_head) #'extra-offset = #'(-1 . 0)
+\outputproperty #(make-type-checker 'note-head-interface) #'extra-offset = #'(-1 . 0)
}
\score{
linewidth=-1.0\mm;
\translator{
\VoiceContext
-slurVerticalDirection = #1
-stemVerticalDirection = #-1
+Slur \override #'direction = #1
+Stem \override #'direction = #-1
}
}
}
\version "1.3.117";
\score{
\context Voice\notes \relative c''{
- %%?
- \property Voice.textVerticalDirection = #1
- %% burp, is this in staff or half spaces, or what?
- \property Voice.textScriptPadding = #15
+ \property Voice.Text \set #'direction = #1
+ \property Voice.TextScript \set #'padding = #5
a1:4^":4" a:8^":8" c:16^":16" a:32^":32" a^"x" a:^":"
a4:4 c:8 a:16 c:32 a a: a2:
\break
\include "paper16.ly";
+stemdown = \property Voice.Stem \override #'direction = #-1
+stemup = \property Voice.Stem \override #'direction = #1
+stemboth = \property Voice.Stem \revert #'direction
+
viola = \notes \relative c' \context Voice = viola {
<c4-\f g' c>
- \property Voice.verticalDirection = \down g'8. b,16
+ \stemdown g'8. b,16
s1 s2. r4
g
}
\context Voice = oboeTwo {
\stemdown
\grace {
- \property Grace.verticalDirection = \down
+ \property Grace.Stem \override #'direction = #-1
[f,16 g] }
f8 e e2
} >
[<c16( e> < )e8. g>] <c8 e,>
}
-hoomPah = \notes \transpose c' {
- c8 \translator Staff = top \stemdown
- c'8 \translator Staff = bottom \stemup }
-
-hoomPahHoomPah = { [\hoomPah \hoomPah] }
+hoomPah = \notes \repeat unfold 8 \transpose c' { c8 \stemdown c'8 \stemup }
bassvoices = \notes \relative c' {
c4 g8. b,16
- \hoomPahHoomPah \hoomPahHoomPah \hoomPahHoomPah \hoomPahHoomPah
+ \autochange Staff \hoomPah o
+ \translator Staff = down
\stemdown [c8 c'8] r4
<g d'> r4
< {\stemup r2 <e4 c'> <c8 g'> }
\score {
\context PianoStaff \notes <
- \context Staff = top < \time 2/2;
- \context Voice = viola \viola
+ \context Staff = up < \time 2/2;
+ \viola
\oboes
>
- \context Staff = bottom < \time 2/2; \clef bass;
+ \context Staff = down < \time 2/2; \clef bass;
\bassvoices
>
>
indent = 0.0;
linewidth = 15.0 \cm; }
}
-
-
-
--- /dev/null
+
+accompMotif = \notes \relative c {
+ \times 2/3 { c8 g' es' }
+ \times 2/3 { c' es, g, }
+}
+
+accomp = \notes \relative c' \autochange Staff {
+ \autoBeamOff
+ <c2-\arpeggio es g>
+ r8 d-.
+ \showStaffSwitch
+ f, b,
+ \hideStaffSwitch
+ \autoBeamOn
+ \repeat unfold 2 \accompMotif
+}
+piano = \context PianoStaff \notes <
+ \context Staff = up <
+ s1*2
+ \accomp
+ >
+ \context Staff = down { \clef bass; s1*2 }
+>
+
+saw = \context Staff \notes {
+ \property Staff.clefOctavation = #7
+ r1 b'''2 - \glissando ais'''2
+}
+
+\score {
+ < \saw \piano >
+}
+
--- /dev/null
+
+\score {
+
+\notes {\notes \reletive c' {
+ \times 2/3 { [fis8 fis8 fis8] }
+ \times 2/3 { [b b b] }
+ bes4
+}
*/
-#include "auto-change-music.hh"
+#include "music.hh"
#include "auto-change-iterator.hh"
#include "translator-group.hh"
#include "musical-request.hh"
{
where_dir_ = s;
String to_id = (s >= 0) ? "up" : "down";
- Auto_change_music const * auto_mus = dynamic_cast<Auto_change_music const* > (music_l_);
-
- String wh = ly_scm2string (auto_mus->get_mus_property ("what"));
+ String wh = ly_scm2string (music_l_->get_mus_property ("what"));
change_to (child_iter_p_, wh, to_id);
}
}
-/*
- auto-switch-music.cc -- implement Auto_change_music
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#include "auto-change-music.hh"
-#include "auto-change-iterator.hh"
-
-Auto_change_music::Auto_change_music (SCM m)
- : Music_wrapper (m)
-{
- set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_cxx_function);
-
-}
{
bool is_b = (bool)(calc_interstaff_dist (stems[i], sp)
- calc_interstaff_dist (stems[i-1], sp));
- int l_y = (int)(Stem::head_positions(stems[i-1])[d])
- + (int)calc_interstaff_dist (stems[i-1], sp);
- int r_y = (int)(Stem::head_positions(stems[i])[d])
- + (int)calc_interstaff_dist (stems[i], sp);
+ int l_y = (int)(Stem::head_positions(stems[i-1])[d]);
+ int l_i = (int)calc_interstaff_dist (stems[i-1], sp);
+ l_y -= l_i;
+ int r_y = (int)(Stem::head_positions(stems[i])[d]);
+ int r_i = (int)calc_interstaff_dist (stems[i], sp);
+ r_y -= r_i;
int gap_i = r_y - l_y;
if ((abs (gap_i) >= auto_gap_i) && (!interstaff_b || is_b))
for (int i=0; i < stems.size (); i++)
{
Item *s = stems[i];
- int y = (int)(Stem::head_positions(s)[d])
- + (int)calc_interstaff_dist (s, dynamic_cast<Spanner*> (me));
+ int y = (int)(Stem::head_positions(s)[d]);
+ int y_i = (int)calc_interstaff_dist (s, dynamic_cast<Spanner*> (me));
+ y -= y_i;
Directional_element_interface::set (s,y < knee_y ? UP : DOWN);
s->set_grob_property ("dir-forced", SCM_BOOL_T);
child_iter_p_ = 0;
}
+Chord_tremolo_iterator::Chord_tremolo_iterator (Chord_tremolo_iterator const &src)
+ : Music_iterator (src)
+{
+ child_iter_p_ = src.child_iter_p_? src.child_iter_p_->clone () : 0;
+}
+
void
Chord_tremolo_iterator::process (Moment m)
{
delete alternative_iter_p_;
}
+Folded_repeat_iterator::Folded_repeat_iterator (Folded_repeat_iterator const &src)
+ : Music_iterator (src)
+{
+ main_iter_p_ = src.main_iter_p_ ? src.main_iter_p_->clone () : 0;
+ alternative_iter_p_ = src.alternative_iter_p_ ? src.alternative_iter_p_->clone () : 0;
+ main_length_mom_ = src.main_length_mom_;
+}
+
Moment
Folded_repeat_iterator::pending_moment () const
{
main_iter_p_ = get_iterator_p (mus->body ());
if (!main_iter_p_->ok())
{
- leave_body ();
+ leave_body ();
enter_alternative ();
}
}
-/*
- auto-change-music.hh -- declare Auto_change_music
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#ifndef AUTO_CHANGE_MUSIC_HH
-#define AUTO_CHANGE_MUSIC_HH
-
-#include "music-wrapper.hh"
-
-
-class Auto_change_music : public Music_wrapper
-{
-public:
- Auto_change_music (SCM);
-
-};
-
-
-#endif /* AUTO_CHANGE_MUSIC_HH */
-
+#error
VIRTUAL_COPY_CONS (Music_iterator);
static SCM constructor_cxx_function;
Chord_tremolo_iterator ();
-
+ Chord_tremolo_iterator (Chord_tremolo_iterator const & );
protected:
virtual ~Chord_tremolo_iterator ();
virtual Moment pending_moment () const;
public:
VIRTUAL_COPY_CONS (Music_iterator);
static SCM constructor_cxx_function;
-
+
+ Folded_repeat_iterator (Folded_repeat_iterator const &src);
Folded_repeat_iterator ();
~Folded_repeat_iterator ();
private:
Music_iterator * main_iter_p_;
Music_iterator * alternative_iter_p_;
- int count_;
+
Moment main_length_mom_;
};
#endif /* FOLDED_REPEAT_ITERATOR_HH */
public:
VIRTUAL_COPY_CONS (Music_iterator);
Lyric_combine_music_iterator ();
+ Lyric_combine_music_iterator (Lyric_combine_music_iterator const&src);
static SCM constructor_cxx_function;
protected:
virtual void construct_children ();
class Glissando_req : public Request
{
+public:
VIRTUAL_COPY_CONS (Music);
};
static SCM constructor_cxx_function;
protected:
virtual ~Part_combine_music_iterator ();
-
+ Part_combine_music_iterator (Part_combine_music_iterator const &);
virtual void construct_children ();
virtual Moment pending_moment () const;
virtual void process (Moment);
SCM alternative_cons_;
~Unfolded_repeat_iterator();
Unfolded_repeat_iterator ();
-
+ Unfolded_repeat_iterator (Unfolded_repeat_iterator const &);
protected:
virtual void construct_children ();
virtual Moment pending_moment () const;
delete music_iter_p_;
}
+Lyric_combine_music_iterator::Lyric_combine_music_iterator (Lyric_combine_music_iterator const & src)
+ : Music_iterator (src)
+{
+
+ lyric_iter_p_ = src.lyric_iter_p_ ? src.lyric_iter_p_->clone () : 0;
+ music_iter_p_ = src.music_iter_p_ ? src.music_iter_p_->clone () : 0;
+}
Music_iterator*
Lyric_combine_music_iterator::try_music_in_children (Music *m) const
{
init_moments ()
{
scm_make_gsubr ("make-moment", 2 , 0, 0, (Scheme_function_unknown) make_rational);
- scm_make_gsubr ("make-moment", 2 , 0, 0, (Scheme_function_unknown) make_rational);
}
ADD_SCM_INIT_FUNC(moms,init_moments);
Music_iterator::Music_iterator ()
{
- // clone_i_ = 0;
}
Music_iterator::Music_iterator (Music_iterator const& src)
{
- // clone_i_ = src.clone_i_ + 1;
handle_ = *src.handle_.clone ();
music_l_ = src.music_l_;
music_length_ = src.music_length_;
/**
Create line-spanner grobs for glissandi (and possibly other) lines
that connect note heads.
- */
+
+ TODO: have the line commit suicide if the notes are connected with
+ either slur or beam.
+
+*/
class Note_head_line_engraver : public Engraver
{
public:
{
if (Rhythmic_head::has_interface (info.elem_l_))
{
- last_head_ = head_;
head_ = info.elem_l_;
if (to_boolean (get_property ("followThread")))
{
- Translator* staff = daddy_trans_l_ && daddy_trans_l_->daddy_trans_l_
- ? daddy_trans_l_->daddy_trans_l_->daddy_trans_l_ : 0;
- if (staff != last_staff_)
+ Translator_group * tr = daddy_trans_l_;
+ while (tr && tr->type_str_ != "Staff")
+ tr = tr->daddy_trans_l_ ;
+
+ if (tr && tr->type_str_ == "Staff" && tr != last_staff_)
{
if (last_head_)
follow_ = true;
- last_staff_ = staff;
+ last_staff_ = tr;
}
}
}
}
-static Grob*
-beam_l (Grob *h)
-{
- if (Grob *s = Rhythmic_head::stem_l (h))
- return Stem::beam_l (s);
- return 0;
-}
void
Note_head_line_engraver::create_grobs ()
if (!line_ && (follow_ || last_req_) && last_head_ && head_
&& (last_head_ != head_))
{
- /* Don't follow if there's a beam.
+ /* TODO: Don't follow if there's a beam.
- Hmm, this doesn't work, as head_ does not yet have a beam.
+ We can't do beam-stuff here, since beam doesn't exist yet.
Should probably store follow_ in line_, and suicide at some
later point */
- if (!(follow_
- && beam_l (last_head_) && beam_l (last_head_) == beam_l (head_)))
- {
- if (follow_)
- line_ = new Spanner (get_property ("FollowThread"));
- else
- line_ = new Spanner (get_property ("Glissando"));
+ if (follow_)
+ line_ = new Spanner (get_property ("FollowThread"));
+ else
+ line_ = new Spanner (get_property ("Glissando"));
- line_->set_bound (LEFT, last_head_);
- line_->set_bound (RIGHT, head_);
+ line_->set_bound (LEFT, last_head_);
+ line_->set_bound (RIGHT, head_);
/* Note, mustn't set y-parent of breakable symbol to simple item:
one of the two broken parts won't have an y-parent! */
/* X parent is set by set_bound */
- line_->set_parent (Staff_symbol_referencer::staff_symbol_l (last_head_),
- Y_AXIS);
+ line_->set_parent (Staff_symbol_referencer::staff_symbol_l (last_head_),
+ Y_AXIS);
- announce_grob (line_, last_req_);
- }
+ announce_grob (line_, last_req_);
+ last_req_ = 0;
- last_head_ = 0;
- if (!follow_ && !req_)
- head_ = 0;
-
- last_req_ = 0;
follow_ = false;
}
}
typeset_grob (line_);
line_ = 0;
}
- last_req_ = req_;
- req_ = 0;
+ if (head_)
+ last_head_ = head_;
+ head_ = 0;
+
+ if (req_)
+ {
+ last_req_ = req_;
+ req_ =0;
+ }
}
#include "repeated-music.hh"
#include "lilypond-input-version.hh"
#include "grace-music.hh"
-#include "auto-change-music.hh"
#include "part-combine-music.hh"
#include "scm-hash.hh"
+#include "auto-change-iterator.hh"
#include "chord.hh"
$$ = csm;
}
| AUTOCHANGE STRING Music {
- Auto_change_music * chm = new Auto_change_music (SCM_EOL);
+ Music * chm = new Music_wrapper (SCM_EOL);
chm->set_mus_property ("element", $3->self_scm ());
+ chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_cxx_function);
scm_unprotect_object ($3->self_scm ());
chm->set_mus_property ("what", $2);
a->set_spot (THIS->here_input ());
$$ = a;
}
+ /*
+duh, junk this syntax from the parser, if possible.
+ */
| ARPEGGIO {
Arpeggio_req *a = new Arpeggio_req;
a->set_spot (THIS->here_input ());
delete first_iter_p_;
}
+Part_combine_music_iterator::Part_combine_music_iterator (Part_combine_music_iterator const &src)
+ : Music_iterator (src)
+{
+ second_iter_p_ = src.second_iter_p_ ? src.second_iter_p_->clone () : 0;
+ first_iter_p_ = src.first_iter_p_ ? src.first_iter_p_->clone () : 0;
+
+ first_until_ = src.first_until_;
+ second_until_ = src.second_until_;
+ state_ = src.state_;
+ suffix_ = src.suffix_;
+}
+
Moment
Part_combine_music_iterator::pending_moment () const
{
score_global_array.clear();
inclusion_global_array.clear ();
- scm_unprotect_object (global_header_p ->self_scm ());
+ if (global_header_p)
+ scm_unprotect_object (global_header_p ->self_scm ());
global_header_p =0;
}
delete current_iter_p_;
}
+Unfolded_repeat_iterator::Unfolded_repeat_iterator (Unfolded_repeat_iterator const &src)
+ : Music_iterator (src)
+{
+ done_count_ = src.done_count_;
+ current_iter_p_ = (src.current_iter_p_)? src.current_iter_p_->clone () : 0;
+ do_main_b_ = src.do_main_b_;
+ volta_b_ = src.volta_b_;
+ alternative_count_i_ = src.alternative_count_i_;
+ alternative_cons_ = src.alternative_cons_;
+}
+
Unfolded_repeat_iterator::Unfolded_repeat_iterator ()
{
done_count_ =0;
volta_b_ = false;
do_main_b_ = false;
alternative_count_i_ =0;
+ alternative_cons_ = SCM_EOL;
}
/**
\name Grace;
\consists "Note_performer";
\consists "Tie_performer";
- weAreGraceContext = "1";
+ \consists "Swallow_performer";
+
+ weAreGraceContext = #t
}
\translator
autoBeamOff = \property Voice.noAutoBeaming = ##t
autoBeamOn = \property Voice.noAutoBeaming = ##f
-
emptyText = \property Voice.textNonEmpty = ##f
fatText = \property Voice.textNonEmpty = ##t
+showStaffSwitch = \property Thread.followThread = ##t
+hideStaffSwitch = \property Thread.followThread = ##f
+
+
% To remove a Volta bracet or some other graphical object,
-% set it to turnOff. Example: \property Staff.VoltaBracket = turnOff
+% set it to turnOff. Example: \property Staff.VoltaBracket = \turnOff
turnOff = #'((meta . ((interfaces . ()))))
(cons (string-append "@code{" name "} "
"(" typename ")"
- ":" )
+ ": "
+
+; index gets too messy
+; "@vindex " name "\n"
+
+
+ )
desc)))
-(define (document-grob-property sym grob-description only-doc-if-set)
+(define (document-grob-property sym grob-description )
(let* ((handle (assoc sym grob-description))
(defval (if (eq? handle #f)
""
(scm->texi (cdr handle))))
(propdoc (backend-property->texi sym)))
- (if (and only-doc-if-set (eq? handle #f))
- '("" . "")
- (cons (car propdoc) (string-append (cdr propdoc)
+ (cons (car propdoc) (string-append (cdr propdoc)
"\nDefault value: "
- defval)))))
+ defval))))
(define (document-interface where interface grob-description)
(let* ((level (if (eq? where 'grob) 3 2))
(props (caddr interface))
(docfunc (lambda (x)
(document-grob-property
- x grob-description (eq? where 'grob))))
+ x grob-description )))
(docs (map docfunc props)))
(string-append
(eval-string (ly-gulp-file "engraver-documentation-lib.scm"))
(eval-string (ly-gulp-file "backend-documentation-lib.scm"))
-
-
;;(define no-copies #t) ; from 490 to 410K, but doesn't look nice yet
;;
;; Also, copies of interfaces use up lots more space, but that's
("LilyPond context properties" . "context properties")
("LilyPond backend" . "Detailed description of all Grobs")
("LilyPond interfaces" . "Grob Interfaces")
- ("LilyPond backend properties" . "Grob properties")))
+ ("LilyPond backend properties" . "Grob properties")
+ ("Index" . "index")
+ ))
doc
+
+ "@node Index
+@unnumbered Concept index
+
+@printindex cp
+
+@unnumbered Variable index
+
+@printindex vr
+
+@unnumbered Function index
+
+@printindex fn
+
+"
+
+
"\n@bye")
out))
'(LEFT-offset . RIGHT-offset). This offset is added to the
attachments to prevent ugly slurs. [fixme: we need more documentation here].
")
+(grob-property-description 'auto-interstaff-knee-gap number? "")
+(grob-property-description 'auto-knee-gap number? "")
(grob-property-description 'axes list? "list of axis numbers.
'Note_head_line_engraver
(engraver-description
"Note_head_line_engraver"
- "Engrave a line between two note heads."
- '(Glissando FollowThread)
- '(
- )))
+ "Engrave a line between two note heads, for example a glissando.
+If followThread is set, staff switches also generate a line."
+ '(Glissando)
+ '(followThread)))
(cons
'Note_name_engraver
(translator-property-description 'drarnChords boolean? "")
(translator-property-description 'explicitClefVisibility procedure? "visibility-lambda function for clef changes.")
(translator-property-description 'explicitKeySignatureVisibility procedure? "visibility-lambda function for explicit Key changes.")
+(translator-property-description 'followThread boolean?
+ "if set, note heads are tracked across staff switches by a thin line")
(translator-property-description 'forceClef boolean? "Show clef symbol, even if it hasn't changed.")
(translator-property-description 'forgetAccidentals boolean? "do
not set localKeySignature when a note alterated differently from
%s
}
>
-\end{lilypond}""",
- 'output-lilypond':r"""\begin[%s]{lilypond}
+\end{lilypond}""",
+ 'output-filename' : r'''
+
+\verb+%s+:''',
+ 'output-lilypond': r"""\begin[%s]{lilypond}
%s
\end{lilypond}""",
'output-verbatim': "\\begin{verbatim}%s\\end{verbatim}",
%s
@end lilypond
""",
+ 'output-filename' : r'''
+
+@file{%s}:''',
'output-lilypond-fragment': """@lilypond[%s]
\context Staff\context Voice{ %s }
@end lilypond """,
read_files = []
def find_file (name):
"""
- Search the include path for NAME. If found, return the contents of teh file.
+ Search the include path for NAME. If found, return the (CONTENTS, PATH) of the file.
"""
+
f = None
+ nm = ''
for a in include_path:
try:
nm = os.path.join (a, name)
pass
if f:
sys.stderr.write ("Reading `%s'\n" % nm)
- return f.read ()
+ return (f.read (), nm)
else:
error ("File not found `%s'\n" % name)
- return ''
+ return ('', '')
def do_ignore(match_object):
return [('ignore', match_object.group('code'))]
(options, m.group('code')))]
def make_lilypond_file(m):
+ """
+
+ Find @lilypondfile{bla.ly} occurences and substitute bla.ly
+ into a @lilypond .. @end lilypond block.
+
+ """
+
if m.group('options'):
options = m.group('options')
else:
options = ''
+ (content, nm) = find_file(m.group('filename'))
+ options = "filename=%s," % nm + options
+
return [('input', get_output('output-lilypond') %
- (options, find_file(m.group('filename'))))]
+ (options, content))]
def make_lilypond_block(m):
if m.group('options'):
def read_doc_file (filename):
"""Read the input file, find verbatim chunks and do \input and \include
"""
- str = find_file(filename)
+ (str, path) = find_file(filename)
determine_format (str)
chunks = [('input', str)]
if 'png' in needed_filetypes and f(pathbase, '.eps', '.png'):
todo.append('png')
newbody = ''
+
+ if 'printfilename' in opts:
+ for o in opts:
+ m= re.match ("filename=(.*)", o)
+ if m:
+ newbody = newbody + get_output ("output-filename") % m.group(1)
+ break
+
+
if 'verbatim' in opts:
newbody = output_verbatim (body)
(type, body, opts, todo, basename) = c;
pathbase = os.path.join (g_outdir, basename)
if os.path.isfile (pathbase + '.texidoc'):
- body = '\n@include %s.texidoc' % basename + body
+ body = '\n@include %s.texidoc\n' % basename + body
c = (type, body, opts, todo, basename)
n.append (c)
return n