]> git.donarmstrong.com Git - lilypond.git/commitdiff
release: 1.3.82 release/1.3.82
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 31 Aug 2000 11:11:43 +0000 (13:11 +0200)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 31 Aug 2000 11:11:43 +0000 (13:11 +0200)
======

* engraver.ly: cleanups.

* etf2ly: robustness fixes, handle mac files as well.

* Smobified Translator and Translator_group, junked
Translator_group_identifier.

* \pushproperty and \popproperty withing \translator, similar to
predefining \property, ie.

\translator { [...] \pushproperty [..] }
\translator { [...] \popproperty [..] }

(these \pushes and \pops are delayed until instantiation, so if you do

\score {
\pushproperty #'basicFooProperties #'bla #VALUE1
\context Voice { \pushproperty #'basicFooProperties #'bar #VALUE2
[..]
}
}

then the setting for basicFooProperties contains both (bla . VALUE1)
and (bar . VALUE2).

* allow \pushproperty #'symbol [..] as well as \pushproperty #'(symbol1 symbol2 ... )

1.3.81.j

68 files changed:
CHANGES
Documentation/ntweb/guile-1.3.4-gnu-windows.patch [deleted file]
Documentation/regression-test.tely
Documentation/user/mudela-book.tely
VERSION
buildscripts/pmx2ly.py [new file with mode: 0644]
configure
input/test/accidental-single-double.ly [new file with mode: 0644]
input/test/double-single-acc.ly [deleted file]
input/test/pushproperty.ly
input/trip.ly
lily/audio-element-info.cc
lily/auto-change-iterator.cc
lily/axis-group-engraver.cc
lily/axis-group-interface.cc
lily/bar-engraver.cc
lily/bar-number-engraver.cc
lily/break-align-engraver.cc
lily/change-iterator.cc
lily/clef-engraver.cc
lily/engraver-group-engraver.cc
lily/grace-engraver-group.cc
lily/grace-performer-group.cc
lily/identifier.cc
lily/include/audio-element-info.hh
lily/include/grace-engraver-group.hh
lily/include/grace-performer-group.hh
lily/include/identifier.hh
lily/include/lyric-phrasing-engraver.hh
lily/include/music-iterator.hh
lily/include/music-wrapper-iterator.hh
lily/include/sequential-music-iterator.hh
lily/include/translation-property.hh
lily/include/translator-group.hh
lily/include/translator.hh
lily/key-engraver.cc
lily/lexer.ll
lily/lyric-phrasing-engraver.cc
lily/mark-engraver.cc
lily/music-iterator.cc
lily/music-output-def.cc
lily/music-wrapper-iterator.cc
lily/parser.yy
lily/part-combine-music-iterator.cc
lily/performer-group-performer.cc
lily/performer.cc
lily/piano-pedal-engraver.cc
lily/property-engraver.cc
lily/property-iterator.cc
lily/repeat-engraver.cc
lily/score-element.cc
lily/score-performer.cc
lily/score.cc
lily/sequential-music-iterator.cc
lily/syllable-group.cc [new file with mode: 0644]
lily/translator-group-initializer.cc [new file with mode: 0644]
lily/translator-group.cc
lily/translator.cc
lily/voice-devnull-engraver.cc
ly/engraver.ly
make/out/lilypond.lsm
make/out/lilypond.spec
mutopia/Coriolan/coriolan-paper.ly
mutopia/Coriolan/coriolan-part-combine-paper.ly
scm/generic-property.scm
scripts/abc2ly.py
scripts/etf2ly.py
scripts/mudela-book.py

diff --git a/CHANGES b/CHANGES
index c40a74600459e7a482d46a9fc1e6acdebd230c4d..cb52b11d60c35ee7f6215091abbeef9c39166cc2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,19 +1,36 @@
---- ../lilypond-1.3.81/CHANGES Mon Aug 28 11:59:46 2000
-++ b/CHANGES   Sat Sep  2 23:13:32 2000
-@@ -1,3 +1,13 @@
-1.3.80.tca1
-===========
-* Added Documentation/user/mb-latex.tex, mudela-book+latex example
-  file and test case. Some work on Documentation/user/mudela-book.tely
+1.3.82
+======
+
+* engraver.ly: cleanups.
+
+* etf2ly: robustness fixes, handle mac files as well.
+
+* Smobified Translator and Translator_group, junked
+Translator_group_identifier.
+
 
-* mudela-book.py: any combination of \verb, \begin{verbatim}
-  @code and @example and mudela should work as expected. 
+* \pushproperty and \popproperty withing \translator, similar to
+predefining \property, ie.
 
-* dropped [].extend that depend on python 1.5.2 
+       \translator { [...] \pushproperty [..] }
+       \translator { [...] \popproperty [..] }
 
- 1.3.80.gp1
- ==========
- 1.3.81.jcn1
+(these \pushes and \pops are delayed until instantiation, so if you do
+
+
+       \score {
+               \pushproperty #'basicFooProperties #'bla #VALUE1
+               \context Voice { \pushproperty #'basicFooProperties #'bar #VALUE2
+                       [..]
+               }
+       }
+
+then the setting for basicFooProperties contains both (bla . VALUE1)
+and (bar . VALUE2).
+
+* allow \pushproperty #'symbol [..] as well as \pushproperty #'(symbol1 symbol2 ... )
+
+1.3.81.jcn1
 ===========
 
 * Activated regex for windows.
@@ -22,6 +39,8 @@
 
 * Added configure messages for metapost checking.
 
+1.3.81
+======
 1.3.80.gp1
 ==========
 
diff --git a/Documentation/ntweb/guile-1.3.4-gnu-windows.patch b/Documentation/ntweb/guile-1.3.4-gnu-windows.patch
deleted file mode 100644 (file)
index e69de29..0000000
index 39ae494574830da2a580e3800543d52186f4603a..c157ffa346d21e35ae86f9e3b7713d79ac78c7d9 100644 (file)
@@ -67,7 +67,7 @@ A sharp sign after a double sharp sign, as well as a flat sign
 after a double flat sign is automatically prepended with a
 natural sign.
 
-@mudelafile{double-single-acc.ly}
+@mudelafile{accidental-single-double.ly}
 
 @section Stems
 
index 5eb5410c9dcb0aee362b5d193c6f15236090fee3..6c7bdacef20468bb03c3f8429e862e5be3de4def 100644 (file)
@@ -1,7 +1,8 @@
 \input texinfo @c -*-texinfo-*-
 @setfilename mudela-book.info
 @settitle mudela-book Manual
-@afourpaper
+
+
 @titlepage
 @title mudela-book Manual
 @subtitle Integrating mudela with La@TeX{} and TeXinfo
@@ -67,21 +68,16 @@ except that this permission notice may be stated in a
 translation approved by the Free Software Foundation.
 
 @end ifinfo
-@tex
-\def\preMudelaExample{\vspace{0.5cm}}
-@end tex
 
-@contents
+
 @node Top, , , (dir)
 @top
 
 
-
 @section Introduction
 
-[TODO: THIS MANUAL IS NOT FINISHED YET. FIXME.]
+[TODO: THIS MANUAL IS OUTDATED. FIXME.]
 
-@ignore
 Mudela-book is a script that process your La@TeX{} file and with great
 help from GNU LilyPond it translates blocks of mudela code it finds
 inside @code{mudela} environments to tex or eps graphics. It then
@@ -92,194 +88,252 @@ Mudela-book will do its best to try to align the music to the left and
 right margins. Currently the most used papersizes and one- and
 twocolumn mode is supported, but if you use the geometry-package from
 La@TeX{} or change the margins things will break.
-@end ignore
-
-@file{mudela-book} is a script that helps integrating mudela and
-La@TeX{} or mudela and TeXinfo. mudela-book runs Lilypond on fragments
-of mudela in your source file, and includes the results into a
-document that can be processed with La@TeX{}, makeinfo or texi2dvi.
-The result is a text document with formatted music integrated.
 
 This document assumes you have basic knowledge of GNU LilyPond and
-La@TeX{} or texinfo.
+La@TeX{}.
 
-@ignore
-Mudela-book will do its best to try to align the music to the left and
-right margins. Currently the most used papersizes and twocolumn mode
-in La@TeX{} are supported. But if you change the margins, things will break.
-@end ignore
-
-@section Tutorial when using TeXinfo
-
-It is easies to learn by examples. A theme by Vagn Holmboe:
-
-@mudela[mbverbatim, intertext="will produce this music:"]
+So what does this look like? Well, here is an example:
+@mudela[veryverbatim, intertext="produces this music:"]
 \score{
   \notes\relative c'{
     \time 5/8;
     [e16( g b c a g][e a b d] | )e2 d,8 |
     [e16( g b c a g][e a b d] | )b2 [a16( f] |
     [e a b d] )e4 c8 | [es16( bes a as g es][d c b! )g] |
-    [f( a b d b a][f a b d] | )e2 [f16( e] | [f, a b d] )e4. |
-    [a,16 a a a a a][a a a a]
+    [f( a b d b a][f a b d] | )e2
   }
 }
 @end mudela
-
-
-You can see that mudela code is put between the @code{@@mudela}
-and @code{@@end mudela} command. Mudela-book will insert some
-code before sending your mudela code to Lilypond, to make the
-music respect the margins. So the mudela code that was actually
-sendt to Lilypond, will be something like this (removed the
-music to save space):
-
+If you are lucky, the above example show a nice feature of LilyPond
+and La@TeX{}. Since LilyPond can output the music as @TeX{} graphics,
+La@TeX{} can insert pagebreaks between the lines of music.
+
+Notice that there is no @code{\paper} statement in the example
+above. Mudela-book will insert some code for you that defines the
+linewidth and the font to use. If you don't want to change the default, 
+there is no need to put an empty @code{\paper@{@}} inside the @code{\score}.
+In the example above, something like
+this might be inserted before your code:
 @example
 \include "paper16.ly"
-\paper @{ linewidth = 455.00000 \pt; @}
-
-\score@{
- YOUR MUDELA CODE
+\paper@{ \paper_sixteen
+    linewidth = 390.\pt;
+    castingalgorithm = \Gourlay;
 @}
 @end example
+The actual values for linewidth will differ depending on papersize and
+number of columns. Also, if you use a different fontsize for the
+music, another file than @code{paper16.ly} will be included.
 
-Compare the previous examples with this short block:
+If you want to make the music not so wide, you can insert a
+@code{\paper} statement that set the linewidth:
 
-@mudela[mbverbatim, intertext="that produces this music:"]
-c' d' e'
+@mudela[veryverbatim, intertext="produces this music:"]
+\score{
+  \notes\relative c'{
+    \time 5/8;
+    [e16( g b c a g][e a b d] | )e2 d,8 |
+    [e16( g b c a g][e a b d] | )b2 [a16( f] |
+    [e a b d] )e4 c8 | [es16( bes a as g es][d c b! )g] |
+    [f( a b d b a][f a b d] | )e2
+  }
+  \paper{linewidth = 10.\cm;}
+}
 @end mudela
 
-You can see that the mudela code is
-not complete, there are no @code{\score} keyword. This made
-mudela-book threat the content of the block a little different.
-This will be fed Lilypond:
-@example
-\include "paper16.ly"
-\paper @{ linewidth = -1.00000 \pt; @}
-\score @{
-  \notes @{
- YOUR MUDELA CODE
- @}
-  \paper@{ @}
-@}
-@end example
-
-@code{linewidth = -1.00000 \pt;} tell Lilypond not to break
-the music. If you enter too much music, the music will go
-beyond the right margin.
+Very often, if you mix music and text, the music is often only a 
+few notes or at most a few bars. This music should be as short as
+possible and not stretched to be aligned to the right margin.
 
-You can set the linewidth yourself:
+If you only write voice-contents in the mudela block, mudela-book 
+will set the @code{linewidth} variable to -1, so Lilypond
+will make the music as short as possible but without breaking the
+line. Here is a well know harmonic progression:
+@mudela[veryverbatim, intertext="produce a well known harmonic progression:"]
+  <c' e g> <b d g> <c2 e g>
+@end mudela
 
-@mudela[mbverbatim, intertext="produces this music:"]
-\score{
- \notes\relative c'{c d e f | g a b c | c b a g | f e d c}
- \paper { indent = 0.0 \cm; linewidth = 4.0 \cm; }
-}
+If you want to place music examples in the text,
+@mudela[eps]
+  <c' e g> <b d g> <c2 e g>
 @end mudela
+, you can use the @code{eps} option. This will create the music as
+eps graphics and include it into the document with the 
+@code{\includegraphics} command.
 
-There is also a short version of the @code{@@mudela} command.
-The code
-@example 
-@@mudela@{ YOUR MUDELA CODE @}
+The code used look like this:
+@example
+@@mudela[eps]
+  <c' e g> <b d g> <c2 e g>
+@@end mudela
 @end example
 
-is short for
-
+You can also use the @code{eps} option if the block is a complete
+mudela source. This 5 cm long empty line, 
+@mudela[eps]
+\score{
+  \notes{s}
+  \paper{ linewidth = 5.\cm;}
+}
+@end mudela
+was created with this code:
 @example
-@@mudela
-\context Staff \context Voice @{ YOUR MUDELA CODE @}
+@@mudela[eps]
+\score@{
+  \notes@{s@}
+  \paper@{ linewidth = 5.\cm;@}
+@}
 @@end mudela
 @end example
 
+To avoid that La@TeX{} places the music on a line of its one, there should
+be no empty lines between the normal text and the mudela
+environment. 
+
+You can also use @code{mudelafile} (on a separate line, FIXME), to
+include another file.
 
-@section TeXinfo reference
+@section Fontsize options You can use all lilypond fontsizes in
+mudela-book.  The default 16pt fontsize is probably to big to be
+included in the middle of the text, 11pt or 13pt is probably better.
 
-Your code should look something like this:
+The code can look like this:
 @example
-@@mudela[options, go, here]
- YOUR MUDELA CODE
+@@mudela[13pt, eps]
+<c' e g>
 @@end mudela
 @end example
 
-or
+The following options set the fontsize:
+@itemize
+@item @code{11pt}
+@mudela[11pt, eps]
+  \relative c'{
+    r16 [c d e][f d e c] [g'8 c][b-\prall c] |
+    [d16 g, a b][c a b g][d'8 g f-\prall g]
+  }
+@end mudela
+@item @code{13pt}
+@mudela[13pt, eps]
+  \relative c'{
+    r16 [c d e][f d e c] [g'8 c][b-\prall c] |
+    [d16 g, a b][c a b g][d'8 g f-\prall g]
+  }
+@end mudela
+@item @code{16pt}
+@mudela[16pt, eps]
+  \relative c'{
+    r16 [c d e][f d e c] [g'8 c][b-\prall c] |
+    [d16 g, a b][c a b g][d'8 g f-\prall g]
+  }
+@end mudela
+@item @code{20pt}
+@mudela[20pt, eps]
+  \relative c'{
+    r16 [c d e][f d e c] [g'8 c][b-\prall c] |
+    [d16 g, a b][c a b g][d'8 g f-\prall g]
+  }
+@end mudela
+@item @code{26pt}
+@mudela[26pt, eps]
+  \relative c'{
+    r16 [c d e][f d e c] [g'8 c][b-\prall c] |
+    [d16 g, a b][c a b g][d'8 g f-\prall g]
+  }
+@end mudela
+@end itemize
 
-@example
-@@mudela[option, go, here]@{ YOUR MUDELA CODE @}
-@end example
 
-Mudelabook knows the default margins, and this papersizes:
-@itemize @bullet
-@item @code{@@afourpaper}
-@item @code{@@afourwide}
-@item @code{@@smallbook}
+@section More options
+@itemize
+@item The @code{singleline} option set @code{linewidth} to -1.0.
+@item The @code{multiline} option set @code{linewidth} to a value letting
+the music be aligned to the right margin. The music can span several
+lines. 
 @end itemize
-@code{@@pagesizes} are not supported.
 
+@section Just in case...
+The options @code{fragment} and @code{nonfragment} will override
+mudela-book when it scans the mudela code to see if it is voice
+contents or complete code. This might be useful if mudela-book choose
+wrong. 
 
-@section La@TeX{} reference
+Since there is no finder's fee which doubles every year, there is no
+need to wait for the price money to grow. So send a bug report today
+if you need this one of these options.
 
-@example
-\begin[option, go, here]@{mudela@}
- YOUR MUDELA CODE
-\end@{mudela@}
-@end example
+@section Examples
 
-@example
-\mudela@{ YOUR MUDELA CODE @}
-@end example
+This was all options to @code{\begin}. The rest of the mudela
+document will show some ways you can use mudela in
+La@TeX{} documents. It will also act as a simple test-suite for
+mudela-book. You can place @code{eps} mudela in and marginspars just
+as any other included eps graphics.
 
-The 'geometry' package is is not supported. The most popular
-papersizes should work.
+@mudela
+\score{
+  \notes\relative c'{ 
+        \time 12/8;  
+        r4-\fermata [b16-.( )b-.] [f'8-- dis16-.( )dis-. gis8--]
+        [f16-.( )f-. dis8-- gis16-.( )gis-.] cis4.-\fermata |
+        
+        r4.-\fermata [cis,16 cis g'8 f16 f b8][g16 g f8 b16 b] dis4.-\fermata
+  }
+  \paper{linewidth = 7.\cm;}
+}
+@end mudela
 
-Mudela-book know about the @code{\onecolumn} and 
-@code{\twocolumn} commands.
 
-@section Options
+To the right you can see some bars from the trumpet fanfara from the
+beginning of the fantastic street opera ``Houdini the Great'', by the
+Danish composer Andy Pape. The music is put inside a
+@code{floatingfigure} environment, and the music will be aligned by
+the right marging if you set floatingfigure width and mudela linewidth
+to the same value. The code looks like this:
 
-@table @samp
-@item eps
-    the music is created as eps graphics that can be inserted in 
-    the middle of a text line, not only as a separate paragraph.
-    (La@TeX{} only)
-@item verbatim
-    CONTENTS is copied into the TeX source enclosed in a verbatim block.
-@item 11pt, 13pt, 16pt, 20pt, 26pt
-    set the fontsize to use for the music
-@item singleline
-  linewidth = -1.
-@item multiline
-  linewidth = textwidth
-@item fragment
-@item nonfragment
-    Override mudela-book autodetection of what type of code is in the
-    mudela block, voice contents or complete code.
-@end table
+@mudela[verbatim]
+\score{
+  \notes\relative c'{ 
+    \time 12/8;  
+    r4.-\fermata [b16-.( )b-.] [f'8-- dis16-.( )dis-. gis8--]
+    [f16-.( )f-. dis8-- gis16-.( )gis-.] cis8.-\fermata |
+        
+    r4.-\fermata [cis,16 cis g'8 f16 f b8]
+    [g16 g f8 b16 b] dis4.-\fermata
+  }
+  \paper{linewidth = 7.\cm;}
+}
+@end mudela
+
+If you have a lot of small music examples like this in the middle of
+your text, you might get a nicer look by using ``double'' line
+spacing. Put the @code{\linespread@{1.6@}} command into the preamble of
+your document. Then the line spacing will not be increased between the
+lines where you have music printed with the smallest font size.
+
+Mudela-book does know about @code{\onecolumn} and @code{\twocolumn}. 
+So the music will be adjusted to the new linewith:
+
+Verbatim environments will also ignore the page margins. That is
+a feature of La@TeX{}. (But you usually put things inside a verbatim
+environment when you don't want La@TeX{} to do any linebreaking)
 
 
 @section Texinfo behavior
+
 [TODO]
 
 @section Invocation
+
 @file{mudela-book} is a script that helps integrating mudela and
 La@TeX{}.  mudela-book runs LilyPond on fragments of mudela in your
 source file, and includes the results into document that can be
 processed with La@TeX{}.  The result is a text document with formatted
 music integrated.
 
-@example
-mudela-book -M --outdir=out inputfile.tely
-@end example
-will create @code{out/inputfile.texi}, depencencies in
-@code{out/inputfile.dep} and lots of other files in @code{out/}
-
-If you are processing a latex file, the file to give to
-latex has ext @file{.latex}
+Lilypond will by default create all output files in directory @file{out}.
+The file to give to latex has ext @file{.latex}.
 
-If you are processing a texinfo file, you can use the
-@code{--no-pictures} command line optino if you are not going
-to create html output.
-
-@ignore
 @strong{About the input}
 
 If the file contains the ``block''
@@ -299,48 +353,48 @@ defined to nothing by default, and the user can redefine them
 to whatever he wants.
 
 @code{\begin} takes the following options:
-@end ignore
 
+@table @samp
+@item eps
+    the music is created as eps graphics that can be inserted in 
+    the middle of a text line, not only as a separate paragraph
+@item verbatim
+    CONTENTS is copied into the TeX source enclosed in a verbatim block.
+@item 11pt, 13pt, 16pt, 20pt, 26pt
+    set the fontsize to use for the music
+@item singleline
+  linewidth = -1.
+@item multiline
+  linewidth = textwidth
+@item fragment
+@item nonfragment
+    Override mudela-book autodetection of what type of code is in the
+    mudela block, voice contents or complete code.
+@end table
 
-@subsection Command line options
 
 @table @samp
 
-@item -f, --format=
-    Specify the document type to process, @code{latex} or @code{texi}.
-    @file{mudela-book} usually figure out this automatically.
-@item --default-music-fontsize=??pt
+@item --default-mudela-fontsize=??pt
     Set the fontsize to use for mudela if no fontsize is given
     as option.
-@item --force-music-fontsize=??pt
+@item --force-mudela-fontsize=??pt
     Force all mudela to use this fontsize, overriding options
     given to \begin@{mudela@}
-@item -I DIR, --include=DIR
-    include path
-@item -M, --dependencies
-        Write dependencies to out-www/filename.dep
-@item --dep-prefix=PREF
-       prepend PREF before each -M dependency
-@item -n, --no-lily
-       don't run lilypond
-@item --no-pictures
-       don't generate pictures
-@item --read-lys
-       don't write ly files. This way you can do
-       @example
-       mudela-book file.tely
-       convert-mudela
-       mudela-book --read-lys
-       @end example
 @item --outname=FILE
     The name of La@TeX{} file to output. If this option  is not given,
-    the output name derived from the input name.
-@item --outdir=
-       where to place generated files
-@item --version
-       print version information
+the output name derived from the input name.
+@item --out-www=DIRECTORY
+    The name of the directory to output lilypond output and input to.
+    This must be a name; the subdirectory will be created in the cwd. [FIXME]
 @item --help
        Print a short help message
+@item --dependencies
+        Write dependencies to out-www/filename.dep
+@item --force-verbatim
+       Make all mudela verbatim.
+@item --initfile=FILE
+        read command definitions from @file{FILE}
 @end table
 
 
@@ -356,16 +410,12 @@ The La@TeX{} \includeonly@{...@} command is ignored.
 
 Ignores almost all La@TeX{} commands that changes margins and linewidths.
 
-La@TeX{} comments can confuse mudela-book:
-@example
-% this music will be displayed: \mudela@{c d e@}
-@end example
-
 @section Authors
 
 @email{hanwen@@cs.uu.nl, Han-Wen Nienhuys}, @uref{http://www.cs.uu.nl/people/hanwen}
 
-@email{tca@@gnu.org, Tom Cato Amundsen}
+@email{tomato@@xoommail.com, Tom Cato Amundsen}
+
 
 @bye
 
diff --git a/VERSION b/VERSION
index a3a3c8c7a9230453b982747c025fb9bfdb20f74b..7992718877f49b3b86f3f4ba1c146faaff4c8eb8 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,8 +1,8 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
-PATCH_LEVEL=81
-MY_PATCH_LEVEL=tca1
+PATCH_LEVEL=82
+MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
diff --git a/buildscripts/pmx2ly.py b/buildscripts/pmx2ly.py
new file mode 100644 (file)
index 0000000..58d32cb
--- /dev/null
@@ -0,0 +1,25 @@
+#!@PYTHON@
+import string
+
+ls = open ('barsant.pmx').readlines ()
+def stripcomment (l):
+       return re.sub ('^%.*$', '', l)
+       
+ls = map (stripcomment, ls)
+ls = filter (lambda x: x <> '', ls)
+
+opening = ls[0]
+ls = ls[1:]
+
+opening = map (string.atoi, re.split ('[\t ]+', opening))
+(nv,noinst,mtrnuml,mtrdenl,mtrnump,mtrdenp,xmtrnum0,isig) = tuple (opening)
+
+
+opening = ls[0]
+ls = ls[1:]
+opening = map (string.atoi, re.split ('[\t ]+', opening))
+(npages,nsyst,musicsize,fracindent) = tuple (opening)
+
+for l  in ls:
+       pass
+       
index 2b07fc6941e7830228467a9e58bbec387c1613d7..9a6dc78d56684efb6ee99427057576f5d6800dd1 100755 (executable)
--- a/configure
+++ b/configure
@@ -2703,20 +2703,26 @@ echo "configure:2699: checking for working metafont mode" >&5
            break;
        fi
     done
+    echo "$ac_t""$MFMODE" 1>&6
 
+    echo $ac_n "checking for mfplain.mp""... $ac_c" 1>&6
+echo "configure:2710: checking for mfplain.mp" >&5
     #
     # For now let people define these in their environments
     #
     : ${MFPLAIN_MP=`kpsewhich mp mfplain.mp`}
+    echo "$ac_t""$MFPLAIN_MP" 1>&6
 
+    echo $ac_n "checking for inimetapost flags""... $ac_c" 1>&6
+echo "configure:2718: checking for inimetapost flags" >&5
     if test  ${INIMETAPOST} = "inimp" ; then
        : ${INIMETAPOST_FLAGS=''}
     else
        : ${INIMETAPOST_FLAGS='-interaction=nonstopmode'}
     fi
+    echo "$ac_t""$INIMETAPOST_FLAGS" 1>&6
 
     rm -f mfput.*
-    echo "$ac_t""$MFMODE" 1>&6
 
     
     
@@ -2741,7 +2747,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2745: checking for $ac_word" >&5
+echo "configure:2751: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_KPSEWHICH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2772,7 +2778,7 @@ done
 test -n "$KPSEWHICH" || KPSEWHICH="no"
 
     echo $ac_n "checking for tfm path""... $ac_c" 1>&6
-echo "configure:2776: checking for tfm path" >&5
+echo "configure:2782: checking for tfm path" >&5
 
     TFM_FONTS="cmr msam"
 
@@ -2800,13 +2806,13 @@ echo "configure:2776: checking for tfm path" >&5
 
     ## First, let's just see if we can find Guile at all.
     echo $ac_n "checking "for guile-config"""... $ac_c" 1>&6
-echo "configure:2804: checking "for guile-config"" >&5
+echo "configure:2810: checking "for guile-config"" >&5
     for guile_config in guile-config $target-guile-config $build-guile-config; do
        echo "$ac_t"""$guile_config"" 1>&6
        if ! $guile_config --version > /dev/null 2>&1 ; then
            echo "configure: warning: "cannot execute $guile_config"" 1>&2
            echo $ac_n "checking "if we are cross compiling"""... $ac_c" 1>&6
-echo "configure:2810: checking "if we are cross compiling"" >&5
+echo "configure:2816: checking "if we are cross compiling"" >&5
            guile_config=error
        else
            break
@@ -2817,7 +2823,7 @@ echo "configure:2810: checking "if we are cross compiling"" >&5
        exit 1
     fi
     echo $ac_n "checking "Guile version"""... $ac_c" 1>&6
-echo "configure:2821: checking "Guile version"" >&5
+echo "configure:2827: checking "Guile version"" >&5
     need_guile_version="1.3.4"
     guile_version=`expr "\`$guile_config --version 2>&1\`" : ".*\($need_guile_version\).*"`
     echo "$ac_t"""$guile_version"" 1>&6
@@ -2830,7 +2836,7 @@ echo "configure:2821: checking "Guile version"" >&5
     
 ## The GUILE_FLAGS macro.
   echo $ac_n "checking for Guile""... $ac_c" 1>&6
-echo "configure:2834: checking for Guile" >&5
+echo "configure:2840: checking for Guile" >&5
   if ! $guile_config link > /dev/null ; then
       echo "$ac_t"""cannot execute $guile_config"" 1>&6
       { echo "configure: error: "cannot find guile-config; is Guile installed?"" 1>&2; exit 1; }
@@ -2845,7 +2851,7 @@ echo "configure:2834: checking for Guile" >&5
     # Extract the first word of "guile", so it can be a program name with args.
 set dummy guile; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2849: checking for $ac_word" >&5
+echo "configure:2855: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GUILE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2895,17 +2901,17 @@ fi
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2899: checking for $ac_hdr" >&5
+echo "configure:2905: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2904 "configure"
+#line 2910 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2909: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2915: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2932,7 +2938,7 @@ fi
 done
 
        echo $ac_n "checking for kpse_find_file in -lkpathsea""... $ac_c" 1>&6
-echo "configure:2936: checking for kpse_find_file in -lkpathsea" >&5
+echo "configure:2942: checking for kpse_find_file in -lkpathsea" >&5
 ac_lib_var=`echo kpathsea'_'kpse_find_file | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2940,7 +2946,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lkpathsea  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2944 "configure"
+#line 2950 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
@@ -2954,7 +2960,7 @@ int main() {
 kpse_find_file()
 ; return 0; }
 EOF
-if { (eval echo configure:2958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2987,12 +2993,12 @@ fi
        for ac_func in kpse_find_file
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2991: checking for $ac_func" >&5
+echo "configure:2997: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2996 "configure"
+#line 3002 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3018,7 +3024,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3047,7 +3053,7 @@ done
 
     fi
     echo $ac_n "checking whether to use kpathsea""... $ac_c" 1>&6
-echo "configure:3051: checking whether to use kpathsea" >&5
+echo "configure:3057: checking whether to use kpathsea" >&5
     if test $kpathsea_b = yes; then
         echo "$ac_t""yes" 1>&6
        KPATHSEA=1
@@ -3065,7 +3071,7 @@ EOF
 
 
 echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:3069: checking for 8-bit clean memcmp" >&5
+echo "configure:3075: checking for 8-bit clean memcmp" >&5
 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3073,7 +3079,7 @@ else
   ac_cv_func_memcmp_clean=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 3077 "configure"
+#line 3083 "configure"
 #include "confdefs.h"
 #ifdef __cplusplus
 extern "C" void exit(int);
@@ -3086,7 +3092,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:3090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_memcmp_clean=yes
 else
@@ -3104,12 +3110,12 @@ echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
 test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
 
 echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:3108: checking for vprintf" >&5
+echo "configure:3114: checking for vprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3113 "configure"
+#line 3119 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -3135,7 +3141,7 @@ vprintf();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3139: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3145: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vprintf=yes"
 else
@@ -3159,12 +3165,12 @@ fi
 
 if test "$ac_cv_func_vprintf" != yes; then
 echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:3163: checking for _doprnt" >&5
+echo "configure:3169: checking for _doprnt" >&5
 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3168 "configure"
+#line 3174 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -3190,7 +3196,7 @@ _doprnt();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3194: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3200: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func__doprnt=yes"
 else
@@ -3217,12 +3223,12 @@ fi
 for ac_func in memmem snprintf vsnprintf gettext isinf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3221: checking for $ac_func" >&5
+echo "configure:3227: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3226 "configure"
+#line 3232 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3248,7 +3254,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3287,7 +3293,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3291: checking for $ac_word" >&5
+echo "configure:3297: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3320,7 +3326,7 @@ test -n "$MAKEINFO" || MAKEINFO="error"
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3324: checking for $ac_word" >&5
+echo "configure:3330: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
diff --git a/input/test/accidental-single-double.ly b/input/test/accidental-single-double.ly
new file mode 100644 (file)
index 0000000..c2d73e1
--- /dev/null
@@ -0,0 +1,21 @@
+
+
+thenotes = \notes \relative cis' { \time 4/4;
+gisis'4 gis gisis ges |
+geses ges geses gis |
+gisis g geses g |
+gis g ges g |
+\key a \major;
+gisis4 gis gisis ges |
+geses ges geses gis |
+gisis g geses g |
+gis g ges g |
+}
+
+\score { < \context Staff \thenotes
+       \context NoteNames  {
+               \pushproperty #'basicNoteNameProperties #'no-spacing-rods ##f 
+               \thenotes
+       }
+       >
+}
diff --git a/input/test/double-single-acc.ly b/input/test/double-single-acc.ly
deleted file mode 100644 (file)
index 923d03e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-thenotes = \notes \relative cis' { \time 4/4;
-gisis'4 gis gisis ges |
-geses ges geses gis |
-gisis g geses g |
-gis g ges g |
-\key a \major;
-gisis4 gis gisis ges |
-geses ges geses gis |
-gisis g geses g |
-gis g ges g |
-}
-
-\score { < \context Staff \thenotes
-       \context NoteNames \thenotes
-       >
-}
index 7ca018f9b96ecb48a6b878ea21d05be926d03991..0ab097c1a345368c26f8d80195c2a53da80b354a 100644 (file)
@@ -49,10 +49,6 @@ Incorrect (\popproperty costs memory):
        \popproperty #'(  ... ) #'symbolA 
        \popproperty #'(  ... ) #'symbolB 
 
-
-
-
-
 the syntax isn't likely to stay, so it is advisable to
 use identifiers, eg.
 
@@ -64,15 +60,21 @@ use identifiers, eg.
 
 \score { \notes
 \relative c' {
-       c4(
+       c4-.(
        \context Voice \pushproperty #'(basicDotsProperties basicStemProperties
        basicNoteColumnProperties basicScriptProperties basicTextProperties) #'direction #-1
-       ) c4 (
-       ) c4 (  
-       \context Voice \pushproperty #'(basicSlurProperties) #'direction #-1
-       ) c4 ( \context Voice  \popproperty #'(basicDotsProperties basicStemProperties
+       ) c4-. (
+       ) c4-. (        
+       \context Voice \pushproperty #'basicSlurProperties #'direction #-1
+       ) c4-. ( \context Voice  \popproperty #'(basicDotsProperties basicStemProperties
                basicScriptProperties basicTextProperties) #'direction
 
-        ) c4  () c4 
+        ) c4-.  () c4-. 
+}
+
+\paper {
+\translator { \VoiceContext
+       \pushproperty #'basicNoteHeadProperties #'font-size #-2
+}
 }
 }
index 750a0f6eb73cbef1fd3247cc9617aea32c595f3a..ed3e877acdf544cbab247394f4fff577e60b3dcd 100644 (file)
@@ -15,6 +15,8 @@ TODO:
 
 * tremolo
 
+* lyrics.
+
 %}
 
 \version "1.3.59";
index 5580b6f0b897f870575b7f6d9f751ca664a5d7e5..c9f99c77323f2a36be3f04540e24e398d524b337 100644 (file)
@@ -7,11 +7,12 @@
 */
 
 #include "audio-element-info.hh"
-#include "request.hh"
+#include "translator-group.hh"
 
 Audio_element_info::Audio_element_info (Audio_element*s_l, Music *r_l)
 {
   elem_l_ = s_l;
+  origin_trans_l_ =0;
   req_l_ = r_l;
 }
 
@@ -20,10 +21,19 @@ Audio_element_info::Audio_element_info()
 {
   elem_l_ = 0;
   req_l_ = 0;
+  origin_trans_l_ =0;
 }
 
+
 Link_array<Translator>
-Audio_element_info::origin_trans_l_arr (Translator*) const
+Audio_element_info::origin_trans_l_arr (Translator* end) const
 {
-  return origin_trans_l_arr_;
+  Translator * t = origin_trans_l_;
+  Link_array<Translator> r;
+  do {
+    r.push (t);
+    t = t->daddy_trans_l_;
+  } while (t && t != end->daddy_trans_l_);
+  
+  return r;
 }
index 2c9de1f71799e36533c2f65a383b59309ab401bf..0ae3021d4670172be651ba9e1abd56df4b90f4ed 100644 (file)
@@ -49,7 +49,7 @@ Auto_change_iterator::change_to (Music_iterator *it, String to_type,
        Translator_group * dest = 
          it->report_to_l ()->find_create_translator_l (to_type, to_id);
        current->remove_translator_p (last);
-       dest->add_translator (last);
+       dest->add_group_translator (last);
       }
     else
       {
index 606c93ef8b910d5e97855d5cafe015653e3dfb90..57d42f31139ac6b28104259f9499129aba885717 100644 (file)
@@ -27,8 +27,7 @@ protected:
   virtual void process_acknowledged ();
   virtual Spanner* get_spanner_p () const;
   virtual void add_element (Score_element*) ;
-public:
-  
+public:  
   VIRTUAL_COPY_CONS(Translator);
   Axis_group_engraver ();
 };
@@ -83,7 +82,7 @@ Axis_group_engraver::do_removal_processing ()
       && gh_number_p (gh_cdr (dims)))
     staffline_p_->set_elt_property ("extra-extent-Y", dims);
 
-Score_element *  it = unsmob_element (get_property ("currentCommandColumn"));
+  Score_element *  it = unsmob_element (get_property ("currentCommandColumn"));
 
   Pointer_group_interface (it, "bounded-by-me").add_element (staffline_p_);  
   staffline_p_->set_bound(RIGHT,it);
@@ -98,6 +97,10 @@ Axis_group_engraver::acknowledge_element (Score_element_info i)
   elts_.push (i.elem_l_);
 }
 
+/*
+  maybe should check if our parent_l is set, because we now get a
+  cyclic parent relationship if we have two Axis_group_engravers in
+  the context.  */
 void
 Axis_group_engraver::process_acknowledged ()
 {
@@ -120,8 +123,7 @@ Axis_group_engraver::add_element (Score_element*e)
 }
 
 ////////////////////////////////////////////////////////
-
-// maybenot sucsh a good idea after all.
+// maybenot such a good idea after all., to put classes in .cc
 
 #include "hara-kiri-group-spanner.hh"
 #include "rhythmic-head.hh"
index a156379adbdcddf7477d79072af93dbbc4f3d392..4d7db9b45210cb619abc8d113a6f95000eaf7014 100644 (file)
@@ -77,11 +77,11 @@ Axis_group_interface::set_axes (Score_element*me,Axis a1, Axis a2)
   SCM sa1= gh_int2scm (a1);
   SCM sa2 = gh_int2scm (a2);
 
-  SCM prop = me->get_elt_property ("axes");
+  SCM axes = me->get_elt_property ("axes");
   
-  if (!gh_pair_p (prop)
-      || scm_memq (sa1, prop) == SCM_BOOL_F
-      || scm_memq (sa2, prop) == SCM_BOOL_F)
+  if (!gh_pair_p (axes)
+      || scm_memq (sa1, axes) == SCM_BOOL_F
+      || scm_memq (sa2, axes) == SCM_BOOL_F)
     {
       SCM ax = gh_cons (sa1, SCM_EOL);
       if (a1 != a2)
index dfa4d906fa9dfc66cd546c9ef023315ccd44a930..bbb1af823809e0aef7203143358f96d9879621d2 100644 (file)
@@ -90,7 +90,7 @@ Bar_engraver::do_removal_processing ()
 void
 Bar_engraver::do_process_music()
 {  
-  Translator * t = daddy_grav_l  ()->get_simple_translator ("Timing_engraver");
+  Translator * t = daddy_grav_l  ()->get_simple_translator ("Timing_engraver");        // UGH.!
 
   Timing_engraver * te = dynamic_cast<Timing_engraver*>(t);
   String which = (te) ? te->which_bar () : "";
index 34a0cb2eae3228113aa22b72c3212cd03c693f43..4fe7d7172f13a6684cf52acfc673978cd75b733c 100644 (file)
 #include "item.hh"
 #include "moment.hh"
 #include "engraver.hh"
-#include "protected-scm.hh"
+#include "translator-group.hh"
+
 
 class Bar_number_engraver : public Engraver
 {
 protected:
   Item* text_p_;
 
-  Protected_scm staffs_;
-
 protected:
   virtual void do_pre_move_processing ();
   virtual void acknowledge_element (Score_element_info);
+  virtual void do_creation_processing ();
   void create_items();
   void do_process_music ();
 public:
@@ -58,9 +58,16 @@ ADD_THIS_TRANSLATOR(Bar_number_engraver);
 Bar_number_engraver::Bar_number_engraver ()
 {
   text_p_ =0;
-  staffs_ = SCM_EOL;
 }
 
+void
+Bar_number_engraver::do_creation_processing ()
+{
+  /*
+    ugh: need to share code with mark_engraver
+   */
+  daddy_trans_l_->set_property ("staffsFound", SCM_EOL); 
+}
 
 
                                               
@@ -70,7 +77,10 @@ Bar_number_engraver::acknowledge_element (Score_element_info inf)
   Score_element * s = inf.elem_l_;
   if (Staff_symbol::has_interface (s))
     {
-      staffs_ = gh_cons (inf.elem_l_->self_scm (), staffs_);
+      SCM sts = get_property ("staffsFound");
+      SCM thisstaff = inf.elem_l_->self_scm ();
+      if (scm_memq (thisstaff, sts) == SCM_BOOL_F)
+       daddy_trans_l_->set_property ("staffsFound", gh_cons (thisstaff, sts));
     }
   else if (text_p_
           && dynamic_cast<Item*> (s)
@@ -88,7 +98,7 @@ Bar_number_engraver::do_pre_move_processing ()
 {
   if (text_p_)
     {
-      text_p_->set_elt_property ("side-support-elements", staffs_);
+      text_p_->set_elt_property ("side-support-elements", get_property ("staffsFound"));
       typeset_element (text_p_);
       text_p_ =0;
     }
index b48f31b25ac870527f12041d59b552e6dda41f86..aa3bc9760cfb4cbcb10de497d3692e678efa7f2c 100644 (file)
@@ -19,6 +19,7 @@ class Break_align_engraver : public Engraver
   Item *align_l_;
   Protected_scm column_alist_;
 protected:
+  virtual void do_removal_processing ();
   virtual void acknowledge_element(Score_element_info i);
   virtual void do_pre_move_processing ();
   void add_column (SCM);
@@ -40,6 +41,12 @@ Break_align_engraver::add_column (SCM smob)
   typeset_element (e);
 }
 
+void
+Break_align_engraver::do_removal_processing ()
+{
+  column_alist_ = SCM_EOL;
+}
+
 void
 Break_align_engraver::do_pre_move_processing ()
 {
index 08fdc53271e210e0e76cd7445982bbbd397763ba..730e4adc8e3cb241ab121e0b302dabcdca7d7025 100644 (file)
@@ -66,7 +66,7 @@ Change_iterator::do_process_and_next (Moment m)
        Translator_group * dest = 
          report_to_l ()->find_create_translator_l (to_type, to_id);
        current->remove_translator_p (last);
-       dest->add_translator (last);
+       dest->add_group_translator (last);
       }
     else
       {
index df8b2eb23f843fb74452b05e021a869efad46510..d448e716483d2ad86b9846e0cc1a9296a85e5c5c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <ctype.h>
 
+#include "translator-group.hh"
 #include "key-item.hh"
 #include "local-key-item.hh"
 #include "bar.hh"
 #include "staff-symbol-referencer.hh"
 #include "debug.hh"
 #include "command-request.hh"
-#include "array.hh"
 #include "engraver.hh"
 #include "direction.hh"
 #include "side-position-interface.hh"
 #include "item.hh"
 
 /// where is c-0 in the staff?
-class Clef_engraver : public  Engraver {
+class Clef_engraver : public  Engraver
+{
   Item * clef_p_;
   Item * octavate_p_;
   Clef_change_req * clef_req_l_;
@@ -50,15 +51,11 @@ public:
   Clef_engraver();
 
   bool  first_b_;
-  
-  Protected_scm current_settings_;
 };
 
 
 Clef_engraver::Clef_engraver()
 {
-  current_settings_ = SCM_EOL;
-
   first_b_ = true;
   clef_glyph_ = SCM_EOL;
   clef_p_ = 0;
@@ -108,13 +105,14 @@ Clef_engraver::set_type (String s)
 
   c0_position_i_ -= (int) octave_dir_ * 7;
 
-  SCM basic = get_property ("basicClefItemProperties");
-  current_settings_ = gh_cons (gh_cons (ly_symbol2scm ("glyph"), clef_glyph_), basic);
-  current_settings_ =
-    gh_cons (gh_cons (ly_symbol2scm ("c0-position"),
-                     gh_int2scm (c0_position_i_)),
-            current_settings_);
-  
+  SCM basic = ly_symbol2scm ("basicClefItemProperties");
+  SCM c0 = ly_symbol2scm ("c0-position");
+  SCM gl = ly_symbol2scm ("glyph");
+  daddy_trans_l_->execute_single_pushpop_property (basic, gl, SCM_UNDEFINED);
+  daddy_trans_l_->execute_single_pushpop_property (basic, c0, SCM_UNDEFINED);  
+  daddy_trans_l_->execute_single_pushpop_property (basic, gl, clef_glyph_);
+  daddy_trans_l_->execute_single_pushpop_property (basic, c0, gh_int2scm (c0_position_i_));
+
   return true;
 }
 
@@ -178,7 +176,7 @@ Clef_engraver::create_clef()
 {
   if (!clef_p_)
     {
-      Item *c= new Item ( current_settings_);
+      Item *c= new Item (get_property ("basicClefItemProperties"));
       announce_element (c, clef_req_l_);
 
       Staff_symbol_referencer::set_interface (c);
index c12283e8e43166bd1770bc5d01c1a1efc0bc0c28..847bb5d13e36d16d6ccb16484cd612cb7c776582 100644 (file)
@@ -27,38 +27,33 @@ Engraver_group_engraver::announce_element (Score_element_info info)
 void
 Engraver_group_engraver::do_announces()
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+  for (SCM p = trans_group_list_; gh_pair_p (p); p =gh_cdr ( p))
     {
-      if (Engraver_group_engraver *trg =  dynamic_cast <Engraver_group_engraver *> (p->car_))
-       trg->do_announces ();
+      Translator * t = unsmob_translator (gh_car (p));
+      dynamic_cast<Engraver_group_engraver*> (t)->do_announces ();
     }
-
+  
   while (announce_info_arr_.size ())
     {
       for (int j =0; j < announce_info_arr_.size(); j++)
        {
          Score_element_info info = announce_info_arr_[j];
          
-         for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+         for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr (p))
            {
-             if (!dynamic_cast <Engraver_group_engraver *> (p->car_))
-               {
-                 Engraver * eng = dynamic_cast<Engraver*> (p->car_);
-                 if (eng && eng!= info.origin_trans_l_arr (this)[0])
-                   eng->acknowledge_element (info);
-               }                 
+             Translator * t = unsmob_translator (gh_car (p));
+             Engraver * eng = dynamic_cast<Engraver*> (t);
+             if (eng && eng!= info.origin_trans_l_)
+               eng->acknowledge_element (info);
            }
        }
-      
       announce_info_arr_.clear ();
-      for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+      for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr ( p))
        {
-         if (!dynamic_cast <Engraver_group_engraver *> (p->car_))
-           {
-             Engraver * eng = dynamic_cast<Engraver*> (p->car_);
-             if (eng)
-               eng->process_acknowledged ();
-           }
+         Translator * t = unsmob_translator (gh_car (p));
+         Engraver * eng = dynamic_cast<Engraver*> (t);
+         if (eng)
+           eng->process_acknowledged ();
        }
     }
 }
index f7b66a62c3f6bf30ae9f9ec5d0e77b83d0b774f3..ae3a2f5a3e1b1992a96f69d27166cd25853ec4b8 100644 (file)
@@ -85,12 +85,6 @@ Grace_engraver_group::each (Method_pointer method)
 }
 
 
-void
-Grace_engraver_group::each (Const_method_pointer method) const
-{
- if (calling_self_b_)
-    Engraver_group_engraver::each (method);
-}
 ADD_THIS_TRANSLATOR(Grace_engraver_group);
 
 
index fcfad2a3391a34021f08b0476d535fb173f33b98..4bf89fe1da896647487f99e6b7283ce1e0c120a5 100644 (file)
@@ -87,12 +87,7 @@ Grace_performer_group::each (Method_pointer method)
 }
 
 
-void
-Grace_performer_group::each (Const_method_pointer method) const
-{
- if (calling_self_b_)
-    Performer_group_performer::each (method);
-}
+
 
 /*
   don't let the commands trickle up.
index d3d0e7221b7024d83614dc6b29aaab9c783070f7..bedc2f9dfd9bfa7bea3ce2e3adf85e58da856df3 100644 (file)
   JUNKTHIS!
  */
 #include <assert.h>
+
 #include "music-output-def.hh"
 #include "score.hh"
 #include "identifier.hh"
 #include "my-lily-lexer.hh"
 #include "debug.hh"
-#include "translator-group.hh"
 #include "ly-smobs.icc"
 
 
@@ -81,8 +81,6 @@ Class ## _identifier::do_print () const { \
 }
 
 
-
-DEFAULT_PRINT(Translator_group);
 DEFAULT_PRINT(Score);
 DEFAULT_PRINT(Music_output_def);
 
@@ -93,8 +91,6 @@ Class ## _identifier::do_str () const { \
   return String (#Class); \
 }
 
-
-DUMMY_STR(Translator_group);
 DUMMY_STR(Score);
 DUMMY_STR(Music_output_def);
 DUMMY_STR(Duration);
@@ -151,10 +147,8 @@ Class ## _identifier::Class ## _identifier (Class ## _identifier const &s) \
 
 
 IMPLEMENT_ID_CLASS(Duration);
-IMPLEMENT_ID_CLASS(Translator_group);
 IMPLEMENT_ID_CLASS(Score);
 IMPLEMENT_ID_CLASS(Music_output_def);
-VIRTUAL_ACCESSOR(Translator_group);
 VIRTUAL_ACCESSOR(Music_output_def);
 DEFAULT_ACCESSOR(Duration);
 DEFAULT_ACCESSOR(Score);
index 2d09970ab4bc268546fd77d435a8d24104c13fe6..b3b805ca0763218185a737c1b0b736c216a20bf5 100644 (file)
@@ -19,7 +19,7 @@
 struct Audio_element_info {
   Audio_element * elem_l_;
   Music *req_l_;
-  Link_array<Translator> origin_trans_l_arr_;
+  Translator *  origin_trans_l_;
   Link_array<Translator> origin_trans_l_arr (Translator*) const;  
 
   Audio_element_info (Audio_element*, Music*);
index 5c63b4fd2ad371313ccfd410d8d78d68af3c64a2..2ba5768a67f5ceab74cf2addb92d3b1653d72628 100644 (file)
@@ -28,7 +28,6 @@ protected:
   virtual void finish ();
   virtual void process ();
   virtual void each (Method_pointer);
-  virtual void each (Const_method_pointer) const;
   virtual void do_removal_processing () ;
   virtual void typeset_element (Score_element*);
   virtual bool do_try_music (Music *m);
index cfeb9884a00e2fe3d1491f02770a91a5560b28cd..5b05625b09e9ebe0d47fcccadbac2226fcb7722c 100644 (file)
@@ -27,7 +27,6 @@ protected:
   virtual void finish ();
   virtual void process ();
   virtual void each (Method_pointer);
-  virtual void each (Const_method_pointer) const;
   virtual void do_removal_processing () ;
   virtual void play_element (Audio_element*);
   virtual bool do_try_music (Music *m);
index 02587ce9788138e74c767052f1a8f2c22cf8cec4..2e39b1ff47479651488f7a16cd9bdaad503b6ed2 100644 (file)
@@ -15,7 +15,6 @@
 #include "smobs.hh"
 
 
-class Translator_group_identifier;
 class Output_def_identifier;
 class Score_identifier;
 class Duration_identifier;
@@ -43,7 +42,6 @@ struct Identifier : public Input {
   
   void error (String) const;
   String str () const;
-  IDACCESSOR(Translator_group)
   IDACCESSOR(Music_output_def)
   IDACCESSOR(Score)
   IDACCESSOR(Duration)
@@ -69,7 +67,6 @@ struct Class ## _identifier : Identifier {\
 }\
 
 
-DECLARE_ID_CLASS(Translator_group);
 DECLARE_ID_CLASS(Duration);
 DECLARE_ID_CLASS(Score);
 DECLARE_ID_CLASS(Music_output_def);
index e00a1c159cb622db9121a68407b7aaac0b6e329a..cda6f6584a6e1a7408a4ef9b3f00f91efe663582 100644 (file)
@@ -66,7 +66,7 @@ protected:
   virtual void acknowledge_element(Score_element_info);
   virtual void process_acknowledged ();
   virtual void do_pre_move_processing();
-  
+  virtual void do_removal_processing ();  
 private:
   void record_notehead(const String &context_id, Score_element * notehead);
   void record_lyric(const String &context_id, Score_element * lyric);
index d1293bb4093c0745b2727b38637279ca8309671c..561e9c11eba025a2e57110a7b5cdb398854e98c1 100644 (file)
@@ -37,12 +37,12 @@ protected:
     Do the actual printing.  This should be overriden in derived classes.  It 
     is called by #print#, in the public interface
    */
-  virtual void do_print () const;
+  virtual void do_print() const;
     
   /**
     Find a bottom notation context to deliver requests to.
    */
-  virtual Translator_group* get_req_translator_l ();
+  virtual Translator_group* get_req_translator_l();
 
   /**
     Get an iterator for MUS, inheriting the translation unit from THIS.
@@ -63,32 +63,32 @@ public:
      Do the reporting.  Will try MUSIC_L_ in its own translator first,
      then its children. Returns the iterator that succeeded
   */
-  Music_iterator *try_music (Music*) const;
+  Music_iterator *  try_music (Music  *) const;
 
   /**
     The translation unit that we this iterator is reporting  to now.
    */
-  Translator_group*report_to_l () const;
+  Translator_group*report_to_l() const;
 
   void set_translator (Translator_group*);
   
   /** Get an iterator matching the type of MUS, and use TRANS to find
     an accompanying translation unit
    */
-  static Music_iterator* static_get_iterator_p (Music *);
-  void init_translator (Music *, Translator_group *); 
+  static Music_iterator* static_get_iterator_p (Music * mus);
+  void init_translator (Music  *, Translator_group *); 
 
-  Music_iterator ();
+  Music_iterator();
     
   ///  Find the next interesting point in time.
-  virtual Moment next_moment () const;
+  virtual Moment next_moment() const;
+
 
   ///Are we finished with this piece of music?
-  virtual bool ok () const;
+  virtual bool ok() const;
 
-  virtual ~Music_iterator ();
+  virtual ~Music_iterator();
 
-  virtual Music *get_next_music ();
 
   ///Report all musical information that occurs between now and UNTIL
   void process_and_next (Moment until);
@@ -97,9 +97,8 @@ public:
     Construct sub-iterators, and set the translator to 
     report to.
    */
-  virtual void construct_children ();
-
-  void print () const;
+  virtual void construct_children();
+  void print() const;
 };
 
 #endif // MUSIC_ITERATOR_HH
index a9c514382587429e7d75c1077e1d43bf7eb1632c..8200709e52f4d803b08c4c7d44b69220c85a0296 100644 (file)
@@ -27,7 +27,6 @@ public:
   virtual void construct_children  () ;
   virtual Moment next_moment () const;
   virtual bool ok () const;
-  virtual Music *get_next_music ();
 
 protected:
   virtual void do_print () const;
index 8888e462b95721051e1160afd3cfe0a978245a5e..79f493fa8724d02ba34321300383245f4e943291 100644 (file)
@@ -25,8 +25,6 @@ public:
   virtual Moment next_moment () const;
   virtual bool ok () const;
 
-  virtual Music* get_next_music ();
-
 protected:
   virtual void do_print() const;
   virtual void do_process_and_next (Moment);
index 0b887470fc4d418729cf4bec0a70fc4073f44f5a..c8a49507839f0b59a868f9582ba1e8720c46225d 100644 (file)
@@ -39,6 +39,7 @@ public:
 class Push_translation_property : public Music
 {
 public:
+  VIRTUAL_COPY_CONS(Music);
 };
 
 /**
@@ -51,7 +52,12 @@ public:
 class Pop_translation_property : public Music
 {
 public:
+  VIRTUAL_COPY_CONS(Music);
 };
 
 
+void apply_push_property (Translator_group*trans, SCM syms, SCM eprop, SCM val);
+void apply_pop_property (Translator_group*trans, SCM syms, SCM eprop);
+
+
 #endif // PROPERTY_HH
index 5bb0d08e28d5ec260f9370ec5f1efd13580df7aa..126c232c8d6ed9991f59fb386046d7b37dd395e7 100644 (file)
 #include "lily-proto.hh"
 #include "virtual-methods.hh"
 #include "translator.hh"
-#include "cons.hh"
 #include "parray.hh"
-
+#include "smobs.hh"
 
 // egcs
 typedef void (Translator::*Method_pointer)(void);
-typedef void (Translator::*Const_method_pointer)(void) const; 
+
 class Scheme_hash_table;
+
+/*
+  should make a struct out of this, and move SCM list stuff in here.
+ */
+struct Translator_group_initializer {
+  static SCM modify_definition (SCM, SCM, bool);
+
+  static void set_acceptor (Translator*,SCM accepts, bool add);
+  static void add_element (Translator*,SCM name);
+  static void remove_element (Translator*,SCM name);
+  static void add_last_element (Translator*,SCM name);
+  static void apply_pushpop_property (Translator*trans, SCM syms, SCM eprop, SCM val);
+  static void add_push_property (Translator*, SCM,SCM,SCM);
+  static void add_pop_property (Translator*, SCM,SCM);  
+  
+};
+
 /** Make some kind of Elements from Requests. Elements are made by
   hierarchically grouped Translators
   */
 class Translator_group : public virtual Translator {
-  Array<String> consists_str_arr_;
-  Array<String> accepts_str_arr_;
-  Array<String> consists_end_str_arr_;
-  Scheme_hash_table *properties_dict_;
 
+  Scheme_hash_table *properties_dict () const;
   int iterator_count_;
-  friend class Interpretation_context_handle;
 
-protected:
-  Cons_list<Translator> trans_p_list_;
 
+  friend class Interpretation_context_handle;
+protected:
+  ~Translator_group ();
 public:
+  SCM add_translator (SCM, Translator*);
+  void execute_single_pushpop_property (SCM prop, SCM sym, SCM val);
   SCM get_property (SCM name_sym) const;
   void set_property (String var_name, SCM value);
   void set_property (SCM var_sym, SCM value);  
   Translator_group *where_defined (SCM name_sym) const;
 
   String id_str_;
-  void add_last_element (String s);
 
   VIRTUAL_COPY_CONS(Translator);
-  
-  void set_acceptor (String accepts, bool add);
-  void set_element (String elt, bool add);  
-  
   Translator_group(Translator_group const &);
   Translator_group();
-  void add_translator (Translator *trans_p);
+  void add_simple_translator (Translator *trans_p);
+  void add_group_translator (Translator *trans_p);
+
   
   /// Score_register = 0, Staff_registers = 1, etc)
   Translator_group* ancestor_l (int l=1);
@@ -63,14 +75,12 @@ public:
   void terminate_translator (Translator*r_l);
   Translator *remove_translator_p (Translator*trans_l);
   void check_removal ();
-
   Translator *get_simple_translator (String) const;
   Translator_group *find_existing_translator_l (String n, String id);
   Translator_group *find_create_translator_l (String n, String id);
   Link_array<Translator_group> path_to_acceptable_translator (String alias, Music_output_def*) const;
 
   Translator_group*get_default_interpreter();
-  virtual ~Translator_group ();
   
 protected:
   bool try_music_on_nongroup_children (Music *m);
@@ -84,7 +94,7 @@ protected:
   virtual void do_creation_processing();
   virtual void do_removal_processing();
   virtual void each (Method_pointer);
-  virtual void each (Const_method_pointer) const;
+
 };
 
 #endif // TRANSLATOR_GROUP_HH
index a40fd07275e2ea4534e57c4fa9c313a157fb4a32..2cca991105ce897032fe5c027d578a31768719eb 100644 (file)
 #include "lily-guile.hh"
 #include "parray.hh"
 #include "input.hh"
-
+#include "smobs.hh"
 
 /** Make some kind of #Element#s from Requests. Elements are made by
   hierarchically grouped #Translator#s
   */
 class Translator : public Input {
+  void init ();
 public:
   Music_output_def * output_def_l_;
   String type_str_;
@@ -33,7 +34,6 @@ public:
   VIRTUAL_COPY_CONS(Translator);
   Translator (Translator const &);
   Translator ();
-  virtual ~Translator ();
   
   Translator_group * daddy_trans_l_ ;
  
@@ -65,7 +65,19 @@ public:
   
   virtual Moment now_mom () const;  
 
-protected:
+  /*
+    ugh: bubbled up from Translator_group. 
+   */
+  SCM consists_name_list_;
+  SCM end_consists_name_list_;
+  SCM accepts_name_list_;
+  SCM simple_trans_list_;
+  SCM trans_group_list_;
+  SCM properties_scm_;
+  SCM property_pushes_;
+  DECLARE_SMOBS(Translator, dummy);
+
+public:
   /*
     UGH. Clean this up.
    */
@@ -78,7 +90,8 @@ protected:
     PROCESSED_REQS,
     ACKED_REQS,
     MOVE_DONE
-  } status;
+  } status_;                   // junkme
+protected:
 
   /*    
        @see{try_request}
@@ -112,5 +125,5 @@ extern Dictionary<Translator*> *global_translator_dict_p;
 void add_translator (Translator*trans_p);
 
 Translator*get_translator_l (String s);
-
+Translator *unsmob_translator (SCM);
 #endif // TRANSLATOR_HH
index f19ddf1c1f78f34cb8d371c1c87a72ddc171008a..8fcae86fd28e78dbe8a839a5f97de08c09aaaa81 100644 (file)
@@ -22,7 +22,8 @@
 /**
   Make the key signature.
  */
-class Key_engraver : public Engraver {
+class Key_engraver : public Engraver
+{
   void create_key(bool);
   void read_req (Key_change_req const * r);
 
@@ -37,6 +38,7 @@ public:
     
 protected:
   virtual void do_creation_processing();
+  virtual void do_removal_processing ();
   virtual bool do_try_music (Music *req_l);
   virtual void do_process_music();
   virtual void do_pre_move_processing();
@@ -45,6 +47,12 @@ protected:
 };
 
 
+void
+Key_engraver::do_removal_processing ()
+{
+  old_accs_ = SCM_EOL;         // unprotect can be called from dtor.
+}
+
 Key_engraver::Key_engraver ()
 {
   keyreq_l_ = 0;
index 90f4ba43f4091e1a2a77187a8a268b5502969709..09378ba9617a98e79aa7d6eb18abb4e6700821c7 100644 (file)
@@ -39,7 +39,7 @@
 #include "identifier.hh"
 #include "version.hh"
 #include "mudela-version.hh"
-
+#include "translator-group.hh"
 void strip_trailing_white (String&);
 void strip_leading_white (String&);
 
@@ -477,6 +477,9 @@ My_lily_lexer::scan_escaped_word (String str)
        } else if (gh_number_p (sid)) {
                yylval.scm = sid;
                return NUMBER_IDENTIFIER;
+       } else if (Translator* tr = unsmob_translator (sid)) {
+               yylval.scm = sid;
+               return TRANSLATOR_IDENTIFIER;
        } else if (Music * mus =unsmob_music (sid)) {
                yylval.scm = sid;
                
index c17f9ce5154aae60111f44c158e83e4a6b0b411d..5cc40bc936503dfbb5de4efe9ae4743bc8afa697 100644 (file)
 #include "lyric-phrasing-engraver.hh"
 #include "note-head.hh"
 #include "translator-group.hh"
-#include "side-position-interface.hh"
-#include "ly-smobs.icc"
 #include "spanner.hh"
-#include "paper-def.hh"
 
 
 String get_context_id(Translator_group * ancestor, const char * type);
@@ -56,6 +53,17 @@ Lyric_phrasing_engraver::~Lyric_phrasing_engraver()
    */
 }
 
+void
+Lyric_phrasing_engraver::do_removal_processing ()
+{
+  /*
+    but do need to unprotect alist_, since Engravers are gc'd now.
+   */
+
+  voice_alist_ = SCM_EOL;
+}
+
+
 Syllable_group * 
 Lyric_phrasing_engraver::lookup_context_id(const String &context_id)
 {
@@ -275,263 +283,3 @@ Lyric_phrasing_engraver::do_pre_move_processing ()
 
 
 
-/*=========================================================================================*/
-
-/** Syllable_group is a class to be smobbed and entered as data in the association list
-    member of the Lyric_phrasing_engraver class.
-*/
-
-Syllable_group::Syllable_group()
-{
-  first_in_phrase_b_=true;
-  melisma_b_ = false;
-  clear();
-}
-
-void 
-Syllable_group::clear()
-{
-  notehead_l_=0;
-  lyric_list_.clear();
-  longest_lyric_l_=0;
-  shortest_lyric_l_=0;
-  melisma_b_ = false;
-  group_translation_f_ = 0.0;
-}
-  
-void
-Syllable_group::copy( Syllable_group *from)
-{
-  notehead_l_ = from->notehead_l_;
-  lyric_list_ = from->lyric_list_;
-  longest_lyric_l_ = from->longest_lyric_l_;
-  shortest_lyric_l_ = from->shortest_lyric_l_;
-  melisma_b_ = from->melisma_b_;
-  alignment_i_ = from->alignment_i_;
-  first_in_phrase_b_ = from->first_in_phrase_b_;
-  group_translation_f_ = from->group_translation_f_;
-}
-
-void 
-Syllable_group::set_first_in_phrase(bool f) 
-{ 
-  first_in_phrase_b_ = f; 
-}
-
-void 
-Syllable_group::set_notehead(Score_element * notehead)
-{
-  if(!notehead_l_) {
-    /* there should only be a single notehead, so silently ignore any extras */
-    notehead_l_=notehead;
-  }
-}
-
-void 
-Syllable_group::add_lyric(Score_element * lyric)
-{
-  lyric_list_.push(lyric);
-  /* record longest and shortest lyrics */
-  if( longest_lyric_l_ ) {
-    if(lyric->extent(X_AXIS).length() > (longest_lyric_l_->extent(X_AXIS)).length())
-      longest_lyric_l_ = lyric;
-    if(lyric->extent(X_AXIS).length() < (shortest_lyric_l_->extent(X_AXIS)).length())
-      shortest_lyric_l_ = lyric;
-  }
-  else
-    longest_lyric_l_ = shortest_lyric_l_ = lyric;
-}
-
-void 
-Syllable_group::add_extender(Score_element * extender)
-{
-  if(notehead_l_ && melisma_b_) {
-    dynamic_cast<Spanner*>(extender)->set_bound (RIGHT, notehead_l_);
-    // should the extender finish at the right of the last note of the melisma, or the left?
-    // Comments in lyric-extender.hh say left, but right looks better to me. GP.
-
-    // Left:
-//     extender->set_elt_property("right-trim-amount", gh_double2scm(0.0));
-
-    // Right:
-    Real ss = extender->paper_l ()->get_var ("staffspace");
-    extender->set_elt_property("right-trim-amount", 
-                              gh_double2scm(-notehead_l_->extent(X_AXIS).length()/ss));
-  }
-}
-
-bool 
-Syllable_group::set_lyric_align(const char *punc, Score_element *default_notehead_l)
-{
-  if(lyric_list_.size()==0) {
-    // No lyrics: nothing to do.
-    return true;
-  }
-
-  Score_element * lyric;
-  alignment_i_ = appropriate_alignment(punc);
-
-  // If there was no notehead in the matching voice context, use the first 
-  // notehead caught from any voice context (any port in a storm).
-  if(!notehead_l_) {
-    notehead_l_ = default_notehead_l;
-  }
-
-  group_translation_f_ = amount_to_translate();
-
-  // set the x alignment of each lyric
-  for(int l = 0; l < lyric_list_.size(); l++) {
-    lyric = lyric_list_[l];
-    lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_));
-    // centre on notehead ... if we have one. 
-    if(notehead_l_) {
-      lyric->set_parent(notehead_l_, X_AXIS);
-      lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS);
-      // reference is on the right of the notehead; move it left half way, and add translation
-      lyric->translate_axis (group_translation_f_-(notehead_l_->extent(X_AXIS)).center(), X_AXIS);
-    }
-  }
-  return (notehead_l_);
-}
-
-/** determine the distance to translate lyrics to get correct alignment
-    Rules: If alignment is centre, translate = 0
-           Otherwise,
-             If (length of longest lyric) < 2 * (length of shortest lyric),
-                - centre longest lyric on notehead
-             Otherwise
-                - move so shortest lyric just reaches notehead centre
-*/
-Real 
-Syllable_group::amount_to_translate()
-{
-  Real translate = 0.0;
-  if(alignment_i_ != CENTER) {
-    // FIXME: do we really know the lyric extent here? Some font sizing comes later?
-    if((longest_lyric_l_->extent(X_AXIS)).length() <
-       (shortest_lyric_l_->extent(X_AXIS)).length() * 2 )
-      translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2;
-    else
-      translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length();
-  }
-  return translate;
-}
-
-
-/** determine what alignment we want.
-    Rules: if first_in_phrase_b_ is set, then alignment is LEFT.
-           otherwise if each syllable ends in punctuation, then alignment is RIGHT
-          otherwise alignment is centre.
-*/
-int 
-Syllable_group::appropriate_alignment(const char *punc)
-{
-  if(first_in_phrase_b_)
-    return LEFT;
-
-  Score_element * lyric;
-  bool end_phrase = true;
-
-  for(int l = 0; l < lyric_list_.size() && end_phrase; l++) {
-    lyric = lyric_list_[l];
-    SCM lyric_scm = lyric->get_elt_property("text");
-    String lyric_str = gh_string_p(lyric_scm)?ly_scm2string(lyric_scm):"";
-    char lastchar;
-    if(lyric_str.length_i()>0) {
-      lastchar = lyric_str[lyric_str.length_i()-1];
-      /* If it doesn't end in punctuation then it ain't an end of phrase */
-      if(! strchr(punc, lastchar)) {
-       /* Special case: trailing space. Here examine the previous character and reverse the
-          sense of the test (i.e. trailing space makes a break without punctuation, or 
-          suppresses a break with punctuation).
-          This behaviour can be suppressed by including a space in the 
-          phrasingPunctuation property, in which case trailing space always means 
-          the same as punctuation.
-
-          FIXME: The extra space throws alignment out a bit.
-       */
-       if(lastchar == ' ') {
-         if(lyric_str.length_i()>1) {
-           lastchar = lyric_str[lyric_str.length_i()-2];
-           if(strchr(punc, lastchar))
-             end_phrase=false;
-         }
-       }
-       else
-         end_phrase=false;
-      }
-    }
-  }
-  if(end_phrase)
-    return RIGHT;
-
-  return CENTER;
-}
-
-/** We don't know about the melisma until after the initial alignment work is done, so go
-    back and fix the alignment when we DO know.
-*/
-void
-Syllable_group::adjust_melisma_align()
-{
-  if(notehead_l_ && lyric_list_.size()) {
-    // override any previous offset adjustments
-    Real translation = -group_translation_f_;
-    // melisma aligning:
-    switch (alignment_i_) {
-      //  case LEFT: // that's all
-    case CENTER: // move right so smallest lyric is left-aligned on notehead
-      translation += (shortest_lyric_l_->extent(X_AXIS)).length()/2;
-      break;
-    case RIGHT: // move right so smallest lyric is left-aligned on notehead
-      translation += (shortest_lyric_l_->extent(X_AXIS)).length();
-      break;
-    }
-    group_translation_f_ += translation;
-    for(int l = 0; l < lyric_list_.size(); l++) {
-      lyric_list_[l]->translate_axis (translation, X_AXIS);
-    }
-  }
-}
-
-
-bool
-Syllable_group::is_empty()
-{
-  return lyric_list_.size()==0;
-}
-
-void
-Syllable_group::next_lyric()
-{
-  first_in_phrase_b_ = (alignment_i_ == RIGHT);
-  clear();
-}
-
-/* SMOB */
-
-
-
-SCM
-Syllable_group::mark_smob (SCM)
-{
-  return SCM_EOL;
-}
-
-int
-Syllable_group::print_smob (SCM, SCM port, scm_print_state * )
-{
-  scm_puts ("#<Syllable_group>", port);
-  return 1;
-}
-
-IMPLEMENT_UNSMOB(Syllable_group, voice_entry);
-IMPLEMENT_SIMPLE_SMOBS(Syllable_group);
-IMPLEMENT_DEFAULT_EQUAL_P(Syllable_group);
-
-SCM
-Syllable_group::make_entry ()
-{
-  Syllable_group *vi = new Syllable_group;
-  return vi->smobbed_self ();
-}
index b57bafa3e28b2c280535a81553f76d31d2bf506b..9ada64765fad07f3d154e6c986bc7e5f4e5d92bc 100644 (file)
@@ -15,7 +15,7 @@
 #include "lily-guile.hh"
 #include "paper-column.hh"
 #include "paper-def.hh"
-#include "protected-scm.hh"
+
 #include "side-position-interface.hh"
 #include "staff-symbol-referencer.hh"
 #include "item.hh"
@@ -32,7 +32,6 @@ public:
   Mark_engraver ();
 protected:
   Item* text_p_;
-  Protected_scm staffs_;
   
 protected:
   virtual void do_pre_move_processing ();
@@ -41,6 +40,8 @@ protected:
   virtual bool do_try_music (Music *req_l);
   virtual void do_process_music ();
   virtual void do_post_move_processing ();
+  virtual void do_creation_processing ();
+  
 private:
   Mark_req * mark_req_l_;
 };
@@ -53,9 +54,13 @@ Mark_engraver::Mark_engraver ()
 {
   text_p_ =0;
   mark_req_l_ = 0;
-  staffs_ = SCM_EOL;
 }
 
+void
+Mark_engraver::do_creation_processing ()
+{
+  daddy_trans_l_->set_property ("staffsFound", SCM_EOL); // ugh: sharing with barnumber grav.
+}
 
 
 void
@@ -64,7 +69,10 @@ Mark_engraver::acknowledge_element (Score_element_info inf)
   Score_element * s = inf.elem_l_;
   if (Staff_symbol::has_interface (s))
     {
-      staffs_ = gh_cons (inf.elem_l_->self_scm (), staffs_);
+      SCM sts = get_property ("staffsFound");
+      SCM thisstaff = inf.elem_l_->self_scm ();
+      if (scm_memq (thisstaff, sts) == SCM_BOOL_F)
+       daddy_trans_l_->set_property ("staffsFound", gh_cons (thisstaff, sts));
     }
   else if (text_p_ && Bar::has_interface (s))
     {
@@ -81,7 +89,7 @@ Mark_engraver::do_pre_move_processing ()
 {
   if (text_p_)
     {
-      text_p_->set_elt_property("side-support-elements" , staffs_);
+      text_p_->set_elt_property("side-support-elements" , get_property ("staffsFound"));
       typeset_element (text_p_);
       text_p_ =0;
     }
index 39478c2d0594844ebc121b4c4a56ca757b05425b..bfa597527b0dd5464fdf5cd82f5bc5bc1ad27457 100644 (file)
@@ -223,8 +223,3 @@ Music_iterator::try_music_in_children (Music  *  ) const
   return 0;
 }
 
-Music*
-Music_iterator::get_next_music ()
-{
-  return 0;
-}
index 07895d86e2eec35dd5f6fd85c589c5581682d19d..a0107291a58a2ee7829c54407a9396e0c2c1b27c 100644 (file)
@@ -50,15 +50,17 @@ Music_output_def::assign_translator (Translator_group*tp)
     {
       tp->warning (_("Interpretation context with empty type"));
     }
-  translator_p_dict_p_->set (s, new Translator_group_identifier (tp, 0));
+
+  SCM tr = tp->self_scm ();
+  scm_unprotect_object (tr);
+  translator_p_dict_p_->set (s, tr);
 }
 
 Translator*
 Music_output_def::find_translator_l (String name) const
 {
   if (translator_p_dict_p_->elem_b (name))
-    return translator_p_dict_p_->elem (name)->access_content_Translator_group (false);
+    return unsmob_translator (translator_p_dict_p_->scm_elem (name));
 
   map<String, Translator*>::const_iterator ki
     =global_translator_dict_p->find (name);
@@ -77,6 +79,7 @@ Music_output_def::get_global_translator_p ()
   if (!t)
     error (_f ("can't find `%s' context", "Score"));
   t = t->clone ();
+
   t->output_def_l_ = this;
   Global_translator *g = dynamic_cast <Global_translator *> (t);
   t->add_processing ();
index 17931466a1e271822e4fe375fbd79c20f8b5c2d1..af658cf72a5905d6345810cd0925f7bc0cb12328 100644 (file)
@@ -63,10 +63,3 @@ Music_wrapper_iterator::try_music_in_children (Music *m) const
 {
   return child_iter_p_->try_music (m);
 }
-
-
-Music*
-Music_wrapper_iterator::get_next_music ()
-{
-  return child_iter_p_->get_next_music ();
-}
index bb7b882e36dc261637d8eb36c9ce13cde659a94a..84a0b042d82afc4df8aba23e0942d9cacfa40d6a 100644 (file)
@@ -198,14 +198,14 @@ yylex (YYSTYPE *s,  void * v_l)
 %token <pitch> CHORDMODIFIER_PITCH
 %token <id>    DURATION_IDENTIFIER
 %token <id>    IDENTIFIER
-%token <id>    TRANS_IDENTIFIER
+
 
 %token <id>    SCORE_IDENTIFIER
 %token <id>    MUSIC_OUTPUT_DEF_IDENTIFIER
 
 %token <scm>   NUMBER_IDENTIFIER
 %token <scm>   REQUEST_IDENTIFIER
-%token <scm>   MUSIC_IDENTIFIER
+%token <scm>   MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
 %token <scm>   STRING_IDENTIFIER SCM_IDENTIFIER 
 %token <scm>   DURATION RESTNAME
 %token <scm>   STRING 
@@ -388,7 +388,7 @@ identifier_init:
                $$ = (new Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER))->self_scm();
        }
        | translator_spec_block {
-               $$ = (new Translator_group_identifier ($1, TRANS_IDENTIFIER))->self_scm();
+               $$ = $1->self_scm ();
        }
        | Music  {
                $$ = $1->self_scm ();
@@ -418,8 +418,10 @@ translator_spec_block:
        ;
 
 translator_spec_body:
-       TRANS_IDENTIFIER        {
-               $$ = $1->access_content_Translator_group (true);
+       TRANSLATOR_IDENTIFIER   {
+               SCM trs = $1;
+               Translator*tr = unsmob_translator (trs);
+               $$ = dynamic_cast<Translator_group*> (tr->clone ());
                $$-> set_spot (THIS->here_input ());
        }
        | TYPE STRING semicolon {
@@ -449,23 +451,31 @@ translator_spec_body:
                
                tg->set_property (ly_scm2string ($2), v);
        }
+       | translator_spec_body PUSHPROPERTY
+                               embedded_scm embedded_scm embedded_scm {
+               Translator_group_initializer::add_push_property ($$, $3, $4, $5);
+       }
+       | translator_spec_body POPPROPERTY
+               embedded_scm embedded_scm  {
+               Translator_group_initializer::add_pop_property ($$, $3, $4);
+       }
        | translator_spec_body NAME STRING semicolon {
                $$->type_str_ = ly_scm2string ($3);
        }
        | translator_spec_body CONSISTS STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), true);
+               Translator_group_initializer::add_element ($$, $3);
        }
        | translator_spec_body CONSISTSEND STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), true);
+               Translator_group_initializer::add_last_element ($$, $3);
        }
        | translator_spec_body ACCEPTS STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_acceptor (ly_scm2string ($3), true);
+               Translator_group_initializer::set_acceptor ($$, $3,true);
        }
        | translator_spec_body DENIES STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_acceptor (ly_scm2string ($3), false);
+               Translator_group_initializer::set_acceptor ($$, $3,false);
        }
        | translator_spec_body REMOVE STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), false);
+               Translator_group_initializer::remove_element ($$, $3);
        }
        ;
 
index 17e79b2423913442ea07c6ade2e3d30bd0326bda..3a72a587a959865256883b60abb0acd86d56ad94 100644 (file)
@@ -8,7 +8,6 @@
 
 #include "part-combine-music.hh"
 #include "part-combine-music-iterator.hh"
-#include "sequential-music-iterator.hh"
 #include "translator-group.hh"
 #include "musical-request.hh"
 #include "warn.hh"
@@ -102,7 +101,7 @@ Part_combine_music_iterator::change_to (Music_iterator *it, String to_type,
        Translator_group * dest = 
          it->report_to_l ()->find_create_translator_l (to_type, to_id);
        current->remove_translator_p (last);
-       dest->add_translator (last);
+       dest->add_group_translator (last);
       }
     else
       {
@@ -124,8 +123,6 @@ Pitch_interrogate_req* second_spanish_inquisition; // won't strike twice
 Rhythm_interrogate_req* first_rhythmic_inquisition;
 Rhythm_interrogate_req* second_rhythmic_inquisition;
 
-#include <iostream.h>
-
 void
 Part_combine_music_iterator::do_process_and_next (Moment m)
 {
@@ -133,23 +130,14 @@ Part_combine_music_iterator::do_process_and_next (Moment m)
 
   now_ = next_moment ();
 
-  Music* first_music = 0;
-  Music* second_music = 0;
-
   /*
     Hmm, shouldn't we check per iterator if next_moment < m?
    */
   if (first_iter_p_->ok ())
-    {
-      first_music = first_iter_p_->get_next_music ();
-      first_iter_p_->process_and_next (m);
-    }
+    first_iter_p_->process_and_next (m);
   
   if (second_iter_p_->ok ())
-    {
-      second_music = second_iter_p_->get_next_music ();
-      second_iter_p_->process_and_next (m);
-    }
+    second_iter_p_->process_and_next (m);
 
   Music_iterator::do_process_and_next (m);
 
@@ -199,13 +187,6 @@ Part_combine_music_iterator::do_process_and_next (Moment m)
   Array<Duration>* first_durations = &first_rhythmic_inquisition->duration_arr_;
   Array<Duration>* second_durations = &second_rhythmic_inquisition->duration_arr_;
 
-  if (!first_durations->empty ())
-    cout << "first_durations: " << first_durations->top ().length_mom ().str () << endl;
-  
-  //  if (Rhythmic_req *r = dynamic_cast<Rhythmic_req*> (first_music))
-  if (first_music)
-    cout << "first_music: " << first_music->length_mom ().str ();
-
   SCM interval = SCM_BOOL_F;
   if (first_pitches->size () && second_pitches->size ())
     {
index 7a38830b530ebbe381491b634e1409f750f05510..0c07bf694f8af4b7f1ac7d43bab1076dc39ca5f7 100644 (file)
@@ -22,48 +22,44 @@ Performer_group_performer::announce_element (Audio_element_info info)
   Performer::announce_element (info);
 }
 
+
+
 void
 Performer_group_performer::do_announces()
 {
-   for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+  for (SCM p = trans_group_list_; gh_pair_p (p); p =gh_cdr ( p))
     {
-      if (Performer_group_performer *trg =  dynamic_cast <Performer_group_performer *> (p->car_))
-       trg->do_announces ();
+      Translator * t = unsmob_translator (gh_car (p));
+      dynamic_cast<Performer_group_performer*> (t)->do_announces ();
     }
-
   
-
-
   while (announce_info_arr_.size ())
     {
       for (int j =0; j < announce_info_arr_.size(); j++)
        {
          Audio_element_info info = announce_info_arr_[j];
-         for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-           {
-             if (!dynamic_cast <Performer_group_performer *> (p->car_))
-               {
-                 Performer * eng = dynamic_cast<Performer*> (p->car_);
-                 // urg, huh? core dump?
-                 //if (eng && eng!= info.origin_trans_l_arr ()[0])
-                 if (eng && info.origin_trans_l_arr (this).size ()
-                     && eng!= info.origin_trans_l_arr (this)[0])
-                   eng->acknowledge_element (info);
-               }
-           }
-         announce_info_arr_.clear ();
-      
-      
-         for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+         
+         for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr (p))
            {
-             if (!dynamic_cast <Performer_group_performer *> (p->car_))
-               {
-                 Performer * eng = dynamic_cast<Performer*> (p->car_);
-                 if (eng)
-                   eng->process_acknowledged ();
-               }
+             Translator * t = unsmob_translator (gh_car (p));
+             Performer * eng = dynamic_cast<Performer*> (t);
+             if (eng && eng!= info.origin_trans_l_)
+               eng->acknowledge_element (info);
            }
        }
+      announce_info_arr_.clear ();
+      for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr ( p))
+       {
+         Translator * t = unsmob_translator (gh_car (p));
+         Performer * eng = dynamic_cast<Performer*> (t);
+         if (eng)
+           eng->process_acknowledged ();
+       }
     }
 }
 
+
+
+
+
+
index fe706b01f9528740a5a02b68085f3e3ad34590e8..8cf1c972f7118ae5b16d350cb4c5a26580688f9d 100644 (file)
@@ -45,6 +45,7 @@ Performer::process_acknowledged ()
 void
 Performer::announce_element (Audio_element_info i)
 {
-  i.origin_trans_l_arr_.push (this);
+  if (!i.origin_trans_l_)
+    i.origin_trans_l_= this;
   daddy_perf_l()->announce_element (i);
 }
index 6b1fd8f7c1d707de9aabd20c8ff4b16d034ad8ce..b9688e5de717c89b1c8581c2f6fc604d5328ba1c 100644 (file)
@@ -182,15 +182,8 @@ Piano_pedal_engraver::do_process_music ()
 
       if (gh_string_p (s))
        {
-         if (p->name_ == String ("Sustain"))
-           {
-             // fixme: Item should be sufficient.
-             p->item_p_ = new Item (get_property ("basicSustainPedalProperties"));
-           }
-         else
-           {
-             p->item_p_ = new Item (get_property ("basicPedalProperties"));
-           }
+         String propname = String ("basic")+  p->name_ + "PedalProperties";
+         p->item_p_ = new Item (get_property (propname.ch_C()));
          p->item_p_->set_elt_property ("text", s);
          // guh
 
index e7baf2ec253d21434c3669b373fc1c21c0d39fb4..1e5a16b931ae2e849ee3e21873a86ad3fb325130 100644 (file)
@@ -9,11 +9,14 @@
 
 #include "lily-guile.hh"
 #include "engraver.hh"
-#include "protected-scm.hh"
 #include "dictionary.hh"
 #include "score-element.hh"
 #include "scm-hash.hh"
 
+/*
+  JUNKME: should use pushproperty everywhere.
+  
+ */
 class Property_engraver : public Engraver
 {
   /*
@@ -99,12 +102,12 @@ Property_engraver::apply_properties (SCM p, Score_element *e)
       SCM type_p   = gh_cadr (entry);
       SCM elt_prop_sym = gh_caddr (entry);
 
-      SCM preset = e->get_elt_property (elt_prop_sym); // scm_assq(elt_prop_sym, e->property_alist_);
-      if (preset != SCM_EOL)
+      SCM preset = scm_assq(elt_prop_sym, e->mutable_property_alist_);
+      if (preset != SCM_BOOL_F)
        continue;
   
       SCM val = get_property (prop_sym);
-     
+
       if (val == SCM_UNDEFINED)
        ;                       // Not defined in context.
       else if (gh_apply (type_p, scm_listify (val, SCM_UNDEFINED))
index 0e50832e64a7d55013b491b3366e171c7cab123d..41b0ed5406edbebe6c74e440a5c98f587e59c754 100644 (file)
@@ -28,20 +28,11 @@ void
 Push_property_iterator::do_process_and_next (Moment m)
 {
   SCM syms = music_l_->get_mus_property ("symbols");
-  SCM  eprop = music_l_->get_mus_property ("element-property");
+  SCM eprop = music_l_->get_mus_property ("element-property");
   SCM val = music_l_->get_mus_property ("element-value");
 
-  for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s))
-    {
-      SCM sym = gh_car (s);
-      if (gh_symbol_p(sym))
-      {
-       SCM prev = report_to_l ()->get_property (sym);
-
-       prev = gh_cons (gh_cons (eprop, val), prev);
-       report_to_l ()->set_property (gh_car (s), prev);
-      }
-    }
+  Translator_group_initializer::apply_pushpop_property (report_to_l (), syms,eprop, val);
+  
   Music_iterator::do_process_and_next (m);
 }
 
@@ -50,23 +41,7 @@ Pop_property_iterator::do_process_and_next (Moment m)
 {
   SCM syms = music_l_->get_mus_property ("symbols");
   SCM eprop = music_l_->get_mus_property ("element-property");
-  for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s)) 
-    {
-    SCM sym = gh_car (s);
-    if (gh_symbol_p(sym))
-      {
-       SCM prev = report_to_l ()->get_property (sym);
-
-       SCM newprops= SCM_EOL ;
-       while (gh_pair_p (prev) && gh_caar (prev) != eprop)
-         {
-           newprops = gh_cons (gh_car (prev), newprops);
-           prev = gh_cdr (prev);
-         }
-
-       newprops = scm_reverse_x (newprops, gh_cdr (prev));
-       report_to_l ()->set_property (sym, newprops);
-      }
-    }
+  Translator_group_initializer::apply_pushpop_property (report_to_l (), syms, eprop, SCM_UNDEFINED);
+  
   Music_iterator::do_process_and_next (m);
 }
index 98747444146aadb78410bcc6f2bf974f46d1c5bf..2cae99cb0928efa7c90261d7decb198cc91bc921 100644 (file)
@@ -208,7 +208,7 @@ Repeat_engraver::do_process_music ()
     return;
 
   Bar_engraver* bar_engraver_l = dynamic_cast <Bar_engraver*>
-    (daddy_grav_l ()->get_simple_translator ("Bar_engraver"));
+    (daddy_grav_l ()->get_simple_translator ("Bar_engraver")); // UGH
 
   /*
     Do all the events that need to be done now.
index 49493167f39e3d8e7704bc06f9b3c583d53298f0..26a62293fcec8cf03c43014bc331b8a6876d3323 100644 (file)
@@ -189,10 +189,13 @@ Score_element::paper_l ()  const
 Lookup const *
 Score_element::lookup_l () const
 {
+  /*
+    URG junkthis, caching is clumsy.
+   */
   if (!lookup_l_)
     {
       Score_element * urg = (Score_element*)this;
-      SCM sz = urg->remove_elt_property ("fontsize");
+      SCM sz = urg->remove_elt_property ("font-size");
       int i = (gh_number_p (sz))
        ? gh_scm2int  (sz)
        : 0;
index ad868ae9e3af77df8cd93ac8e467c67f3fa30c9c..1908644904f4ba32ce95e0b1131f8eb54ac25a66 100644 (file)
@@ -47,7 +47,7 @@ void
 Score_performer::announce_element (Audio_element_info info)
 {
   announce_info_arr_.push (info);
-  info.origin_trans_l_arr_.push (this);
+
 
   /*
     huh?
index 75e397aab8a9686fdedfe48f88944e3b264a0a1a..4f33c853f1a37edded37c8a7bd8cc60374478e0f 100644 (file)
@@ -95,7 +95,8 @@ Score::run_translator (Music_output_def *odef_l)
     }
 
   Music_output * output = trans_p->get_output_p();
-  delete trans_p;
+  scm_unprotect_object (trans_p->self_scm ());
+  
   if(verbose_global_b)
     progress_indication (_f ("elapsed time: %.2f seconds",  timer.read ()));
 
index d98dc5738f564b6fe134dc94c4c00d47839f9d95..d99381cf5415a8645039c6251cf44388c58e6575 100644 (file)
@@ -139,11 +139,3 @@ Sequential_music_iterator::try_music_in_children (Music *m) const
 { 
   return iter_p_ ? iter_p_->try_music (m) : 0;
 }
-
-Music*
-Sequential_music_iterator::get_next_music ()
-{
-  if (cursor_ && gh_pair_p (cursor_))
-    return unsmob_music (gh_car (cursor_));
-  return 0;
-}
diff --git a/lily/syllable-group.cc b/lily/syllable-group.cc
new file mode 100644 (file)
index 0000000..a0cf73d
--- /dev/null
@@ -0,0 +1,268 @@
+#include <string.h>
+
+#include "lyric-phrasing-engraver.hh"
+#include "note-head.hh"
+#include "translator-group.hh"
+#include "side-position-interface.hh"
+#include "ly-smobs.icc"
+#include "spanner.hh"
+#include "paper-def.hh"
+
+
+/*=========================================================================================*/
+
+/** Syllable_group is a class to be smobbed and entered as data in the association list
+    member of the Lyric_phrasing_engraver class.
+*/
+
+Syllable_group::Syllable_group()
+{
+  first_in_phrase_b_=true;
+  melisma_b_ = false;
+  clear();
+}
+
+void 
+Syllable_group::clear()
+{
+  notehead_l_=0;
+  lyric_list_.clear();
+  longest_lyric_l_=0;
+  shortest_lyric_l_=0;
+  melisma_b_ = false;
+  group_translation_f_ = 0.0;
+}
+  
+void
+Syllable_group::copy( Syllable_group *from)
+{
+  notehead_l_ = from->notehead_l_;
+  lyric_list_ = from->lyric_list_;
+  longest_lyric_l_ = from->longest_lyric_l_;
+  shortest_lyric_l_ = from->shortest_lyric_l_;
+  melisma_b_ = from->melisma_b_;
+  alignment_i_ = from->alignment_i_;
+  first_in_phrase_b_ = from->first_in_phrase_b_;
+  group_translation_f_ = from->group_translation_f_;
+}
+
+void 
+Syllable_group::set_first_in_phrase(bool f) 
+{ 
+  first_in_phrase_b_ = f; 
+}
+
+void 
+Syllable_group::set_notehead(Score_element * notehead)
+{
+  if(!notehead_l_) {
+    /* there should only be a single notehead, so silently ignore any extras */
+    notehead_l_=notehead;
+  }
+}
+
+void 
+Syllable_group::add_lyric(Score_element * lyric)
+{
+  lyric_list_.push(lyric);
+  /* record longest and shortest lyrics */
+  if( longest_lyric_l_ ) {
+    if(lyric->extent(X_AXIS).length() > (longest_lyric_l_->extent(X_AXIS)).length())
+      longest_lyric_l_ = lyric;
+    if(lyric->extent(X_AXIS).length() < (shortest_lyric_l_->extent(X_AXIS)).length())
+      shortest_lyric_l_ = lyric;
+  }
+  else
+    longest_lyric_l_ = shortest_lyric_l_ = lyric;
+}
+
+void 
+Syllable_group::add_extender(Score_element * extender)
+{
+  if(notehead_l_ && melisma_b_) {
+    dynamic_cast<Spanner*>(extender)->set_bound (RIGHT, notehead_l_);
+    // should the extender finish at the right of the last note of the melisma, or the left?
+    // Comments in lyric-extender.hh say left, but right looks better to me. GP.
+
+    // Left:
+//     extender->set_elt_property("right-trim-amount", gh_double2scm(0.0));
+
+    // Right:
+    Real ss = extender->paper_l ()->get_var ("staffspace");
+    extender->set_elt_property("right-trim-amount", 
+                              gh_double2scm(-notehead_l_->extent(X_AXIS).length()/ss));
+  }
+}
+
+bool 
+Syllable_group::set_lyric_align(const char *punc, Score_element *default_notehead_l)
+{
+  if(lyric_list_.size()==0) {
+    // No lyrics: nothing to do.
+    return true;
+  }
+
+  Score_element * lyric;
+  alignment_i_ = appropriate_alignment(punc);
+
+  // If there was no notehead in the matching voice context, use the first 
+  // notehead caught from any voice context (any port in a storm).
+  if(!notehead_l_) {
+    notehead_l_ = default_notehead_l;
+  }
+
+  group_translation_f_ = amount_to_translate();
+
+  // set the x alignment of each lyric
+  for(int l = 0; l < lyric_list_.size(); l++) {
+    lyric = lyric_list_[l];
+    lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_));
+    // centre on notehead ... if we have one. 
+    if(notehead_l_) {
+      lyric->set_parent(notehead_l_, X_AXIS);
+      lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS);
+      // reference is on the right of the notehead; move it left half way, and add translation
+      lyric->translate_axis (group_translation_f_-(notehead_l_->extent(X_AXIS)).center(), X_AXIS);
+    }
+  }
+  return (notehead_l_);
+}
+
+/** determine the distance to translate lyrics to get correct alignment
+    Rules: If alignment is centre, translate = 0
+           Otherwise,
+             If (length of longest lyric) < 2 * (length of shortest lyric),
+                - centre longest lyric on notehead
+             Otherwise
+                - move so shortest lyric just reaches notehead centre
+*/
+Real 
+Syllable_group::amount_to_translate()
+{
+  Real translate = 0.0;
+  if(alignment_i_ != CENTER) {
+    // FIXME: do we really know the lyric extent here? Some font sizing comes later?
+    if((longest_lyric_l_->extent(X_AXIS)).length() <
+       (shortest_lyric_l_->extent(X_AXIS)).length() * 2 )
+      translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2;
+    else
+      translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length();
+  }
+  return translate;
+}
+
+
+/** determine what alignment we want.
+    Rules: if first_in_phrase_b_ is set, then alignment is LEFT.
+           otherwise if each syllable ends in punctuation, then alignment is RIGHT
+          otherwise alignment is centre.
+*/
+int 
+Syllable_group::appropriate_alignment(const char *punc)
+{
+  if(first_in_phrase_b_)
+    return LEFT;
+
+  Score_element * lyric;
+  bool end_phrase = true;
+
+  for(int l = 0; l < lyric_list_.size() && end_phrase; l++) {
+    lyric = lyric_list_[l];
+    SCM lyric_scm = lyric->get_elt_property("text");
+    String lyric_str = gh_string_p(lyric_scm)?ly_scm2string(lyric_scm):"";
+    char lastchar;
+    if(lyric_str.length_i()>0) {
+      lastchar = lyric_str[lyric_str.length_i()-1];
+      /* If it doesn't end in punctuation then it ain't an end of phrase */
+      if(! strchr(punc, lastchar)) {
+       /* Special case: trailing space. Here examine the previous character and reverse the
+          sense of the test (i.e. trailing space makes a break without punctuation, or 
+          suppresses a break with punctuation).
+          This behaviour can be suppressed by including a space in the 
+          phrasingPunctuation property, in which case trailing space always means 
+          the same as punctuation.
+
+          FIXME: The extra space throws alignment out a bit.
+       */
+       if(lastchar == ' ') {
+         if(lyric_str.length_i()>1) {
+           lastchar = lyric_str[lyric_str.length_i()-2];
+           if(strchr(punc, lastchar))
+             end_phrase=false;
+         }
+       }
+       else
+         end_phrase=false;
+      }
+    }
+  }
+  if(end_phrase)
+    return RIGHT;
+
+  return CENTER;
+}
+
+/** We don't know about the melisma until after the initial alignment work is done, so go
+    back and fix the alignment when we DO know.
+*/
+void
+Syllable_group::adjust_melisma_align()
+{
+  if(notehead_l_ && lyric_list_.size()) {
+    // override any previous offset adjustments
+    Real translation = -group_translation_f_;
+    // melisma aligning:
+    switch (alignment_i_) {
+      //  case LEFT: // that's all
+    case CENTER: // move right so smallest lyric is left-aligned on notehead
+      translation += (shortest_lyric_l_->extent(X_AXIS)).length()/2;
+      break;
+    case RIGHT: // move right so smallest lyric is left-aligned on notehead
+      translation += (shortest_lyric_l_->extent(X_AXIS)).length();
+      break;
+    }
+    group_translation_f_ += translation;
+    for(int l = 0; l < lyric_list_.size(); l++) {
+      lyric_list_[l]->translate_axis (translation, X_AXIS);
+    }
+  }
+}
+
+
+bool
+Syllable_group::is_empty()
+{
+  return lyric_list_.size()==0;
+}
+
+void
+Syllable_group::next_lyric()
+{
+  first_in_phrase_b_ = (alignment_i_ == RIGHT);
+  clear();
+}
+
+/* SMOB */
+SCM
+Syllable_group::mark_smob (SCM)
+{
+  return SCM_EOL;
+}
+
+int
+Syllable_group::print_smob (SCM, SCM port, scm_print_state * )
+{
+  scm_puts ("#<Syllable_group>", port);
+  return 1;
+}
+
+IMPLEMENT_UNSMOB(Syllable_group, voice_entry);
+IMPLEMENT_SIMPLE_SMOBS(Syllable_group);
+IMPLEMENT_DEFAULT_EQUAL_P(Syllable_group);
+
+SCM
+Syllable_group::make_entry ()
+{
+  Syllable_group *vi = new Syllable_group;
+  return vi->smobbed_self ();
+}
diff --git a/lily/translator-group-initializer.cc b/lily/translator-group-initializer.cc
new file mode 100644 (file)
index 0000000..b7a5aec
--- /dev/null
@@ -0,0 +1,95 @@
+       /*   
+  translator-group-initializer.cc --  implement Translator_group_initializer
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "translator-group.hh"
+#include "warn.hh"
+
+
+void
+Translator_group_initializer::set_acceptor (Translator *me,SCM name, bool add)
+{
+  if (add)
+    me->accepts_name_list_ = gh_append2 (me->accepts_name_list_, gh_cons (name, SCM_EOL));
+  else
+    me->accepts_name_list_ = scm_delete_x (name, me->accepts_name_list_);
+}
+
+
+SCM
+Translator_group_initializer::modify_definition (SCM list, SCM str, bool add)
+{
+  String s = ly_scm2string (str);
+  if (!get_translator_l (s))
+    error (_ ("Program has no such type"));
+
+  if (add)
+    {
+      if (scm_memq (str, list) != SCM_BOOL_F)
+       {
+         warning (_f("Already contains: `%s'", s));
+         warning (_f("Not adding translator: `%s'", s));
+       }
+      else
+       list= gh_cons (str, list);
+    }
+  else
+    {
+      list = scm_delete_x (str, list);
+    }
+  return list;
+}
+
+
+
+void
+Translator_group_initializer::remove_element (Translator *me,SCM s)
+{
+  me->end_consists_name_list_ = modify_definition (me->end_consists_name_list_, s, false);
+  me->consists_name_list_ = modify_definition (me->consists_name_list_, s, false);
+}
+
+void
+Translator_group_initializer::add_element (Translator *me,SCM s)
+{
+  me->consists_name_list_ = modify_definition (me->consists_name_list_, s, true);
+}
+
+void
+Translator_group_initializer::add_last_element (Translator *me,SCM s)
+{
+  me->end_consists_name_list_ = modify_definition (me->end_consists_name_list_, s, true);
+}
+void
+Translator_group_initializer::add_push_property (Translator * me,
+                                                SCM props, SCM syms,  SCM vals)
+{
+  me->property_pushes_ = gh_cons (gh_list (props, syms, vals, SCM_UNDEFINED),
+                                 me->property_pushes_);
+}
+
+void
+Translator_group_initializer::add_pop_property (Translator * me,
+                                                SCM props, SCM syms)
+{
+  me->property_pushes_ = gh_cons (gh_list (props, syms, SCM_UNDEFINED),
+                                 me->property_pushes_);
+}
+
+/*
+  Do it. SYMS maybe a symbol or a list of symbols. VAL is
+  SCM_UNDEFINED in case of a pop
+*/
+void
+Translator_group_initializer::apply_pushpop_property (Translator *trans, SCM syms, SCM eprop, SCM val)
+{
+  if (gh_symbol_p (syms))
+    dynamic_cast<Translator_group*>(trans)->execute_single_pushpop_property (syms, eprop, val);
+  else for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s))
+    dynamic_cast<Translator_group*>(trans)->execute_single_pushpop_property (gh_car (s), eprop, val);
+}
index 8d92fb8ac15b9d7d528923ffe7b695cec7751f1b..d2b7c83a04dbcd637bdf31ac8ab7759d81a9ed23 100644 (file)
 Translator_group::Translator_group (Translator_group const&s)
   : Translator(s)
 {
-  consists_str_arr_ = s.consists_str_arr_;
-  consists_end_str_arr_ = s.consists_end_str_arr_;
-  accepts_str_arr_ = s.accepts_str_arr_;
   iterator_count_ =0;
-  properties_dict_ = new Scheme_hash_table (*s.properties_dict_);
+  
+  Scheme_hash_table * tab =  new Scheme_hash_table (*s.properties_dict ());
+  properties_scm_ = tab->self_scm ();
+  scm_unprotect_object (tab->self_scm( ));
+}
+
+Scheme_hash_table*
+Translator_group::properties_dict () const
+{
+  return Scheme_hash_table::unsmob (properties_scm_);
 }
 
 Translator_group::~Translator_group ()
 {
   assert (removable_b());
-  trans_p_list_.junk ();
-  scm_unprotect_object (properties_dict_->self_scm ());
 }
 
 
 Translator_group::Translator_group()
 {
   iterator_count_  = 0;
-  properties_dict_ = new Scheme_hash_table ;
+  Scheme_hash_table *tab = new Scheme_hash_table ;
+  properties_scm_ = tab->self_scm ();
+
+  scm_unprotect_object (tab->self_scm ());
 }
 
 void
 Translator_group::check_removal()
 {
-  Cons<Translator> *next =0;
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = next)
+  SCM next = SCM_EOL; 
+  for (SCM p = trans_group_list_; gh_pair_p (p); p = next)
     {
-      next = p->next_;
-      if (Translator_group *trg =  dynamic_cast <Translator_group *> (p->car_))
-       {
-         trg->check_removal ();
-         if (trg->removable_b())
-           terminate_translator (trg);
-       }
+      next = gh_cdr (p);
+
+      Translator_group *trg =  dynamic_cast<Translator_group*> (unsmob_translator (gh_car (p)));
+
+      trg->check_removal ();
+      if (trg->removable_b())
+       terminate_translator (trg);
     }
 }
 
-void
-Translator_group::add_translator (Translator *trans_p)
+
+SCM
+Translator_group::add_translator (SCM list, Translator *t)
 {
-  trans_p_list_.append (new Killing_cons<Translator> (trans_p,0));
+  list = gh_append2 (list, gh_cons (t->self_scm (), SCM_EOL));
+  t->daddy_trans_l_ = this;
+  t->output_def_l_ = output_def_l_;
+  t->add_processing ();
 
-  trans_p->daddy_trans_l_ = this;
-  trans_p->output_def_l_ = output_def_l_;
-  trans_p->add_processing ();
+  return list;
 }
-
 void
-Translator_group::set_acceptor (String accepts, bool add)
+Translator_group::add_simple_translator (Translator*t)
 {
-  if (add)
-    accepts_str_arr_.push (accepts);
-  else
-    for (int i=accepts_str_arr_.size (); i--; )
-      if (accepts_str_arr_[i] == accepts)
-       accepts_str_arr_.del (i);
+  simple_trans_list_ = add_translator (simple_trans_list_, t);
 }
-
 void
-Translator_group::add_last_element (String s)
+Translator_group::add_group_translator (Translator *t)
 {
-  if (!get_translator_l (s))
-    error (_ ("Program has no such type"));
-
-  for (int i=consists_end_str_arr_.size (); i--; )
-    if (consists_end_str_arr_[i] == s)
-      warning (_f ("Already contains: `%s'", s));
-      
-  consists_end_str_arr_.push (s);
+  trans_group_list_ = add_translator (trans_group_list_,t);
 }
 
-void
-Translator_group::set_element (String s, bool add)
-{
-  if (!get_translator_l (s))
-    error (_ ("Program has no such type"));
 
-  if (add)
-    {
-      for (int i=consists_str_arr_.size (); i--; )
-       if (consists_str_arr_[i] == s)
-         warning (_f("Already contains: `%s'", s));
-      
-      consists_str_arr_.push (s);
-    }
-  else
-    {
-      for (int i=consists_str_arr_.size (); i--; )
-       if (consists_str_arr_[i] == s)
-         consists_str_arr_.del (i);
-      for (int i=consists_end_str_arr_.size (); i--; )
-       if (consists_end_str_arr_[i] == s)
-         consists_end_str_arr_.del (i);
-    }
-}
+
 bool
 Translator_group::removable_b() const
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-    {
-      if (dynamic_cast <Translator_group *> (p->car_))
-       return false;
-    }
-
-  return !iterator_count_;
+  return trans_group_list_ == SCM_EOL && ! iterator_count_;
 }
 
 Translator_group *
@@ -131,10 +98,11 @@ Translator_group::find_existing_translator_l (String n, String id)
     return this;
 
   Translator_group* r = 0;
-  for (Cons<Translator> *p = trans_p_list_.head_; !r && p; p = p->next_)
+  for (SCM p = trans_group_list_; !r && gh_pair_p (p); p = gh_cdr (p))
     {
-      if (Translator_group *trg =  dynamic_cast <Translator_group *> (p->car_))
-       r = trg->find_existing_translator_l (n, id);
+      Translator *  t = unsmob_translator (gh_car (p));
+      
+      r = dynamic_cast<Translator_group*> (t)->find_existing_translator_l (n, id);
     }
 
   return r;
@@ -143,10 +111,11 @@ Translator_group::find_existing_translator_l (String n, String id)
 Link_array<Translator_group>
 Translator_group::path_to_acceptable_translator (String type, Music_output_def* odef) const
 {
- Link_array<Translator_group> accepted_arr;
-  for (int i=0; i < accepts_str_arr_.size (); i++)
 Link_array<Translator_group> accepted_arr;
+  for (SCM s = accepts_name_list_; gh_pair_p (s); s = gh_cdr (s))
     {
-      Translator *t = odef->find_translator_l (accepts_str_arr_[i]);
+      
+      Translator *t = odef->find_translator_l (ly_scm2string (gh_car (s)));
       if (!t || !dynamic_cast <Translator_group *> (t))
        continue;
       accepted_arr.push (dynamic_cast <Translator_group *> (t));
@@ -198,7 +167,7 @@ Translator_group::find_create_translator_l (String n, String id)
        {
          Translator_group * new_group = dynamic_cast<Translator_group*>(path[i]->clone ());
 
-         current->add_translator (new_group);
+         current->add_group_translator (new_group);
          current = new_group;
        }
       current->id_str_ = id;
@@ -221,12 +190,10 @@ Translator_group::try_music_on_nongroup_children (Music *m)
 {
   bool hebbes_b =false;
 
-  for (Cons<Translator> *p = trans_p_list_.head_; !hebbes_b && p; p = p->next_)
+  
+  for (SCM p = simple_trans_list_; !hebbes_b && gh_pair_p (p); p = gh_cdr (p))
     {
-      if (!dynamic_cast <Translator_group *> (p->car_))
-       {
-         hebbes_b = p->car_->try_music (m);
-       }
+      hebbes_b = unsmob_translator (gh_car (p))->try_music (m);
     }
   return hebbes_b;
 }
@@ -256,17 +223,14 @@ Translator_group::ancestor_l (int level)
   return daddy_trans_l_->ancestor_l (level-1);
 }
 
-
-
-
-
 void
 Translator_group::terminate_translator (Translator*r_l)
 {
   r_l->removal_processing();
   Translator * trans_p =remove_translator_p (r_l);
-
-  delete trans_p;
+  /*
+    forget trans_p, GC does the rest.
+   */
 }
 
 
@@ -277,28 +241,20 @@ Translator *
 Translator_group::remove_translator_p (Translator*trans_l)
 {
   assert (trans_l);
-  
-  for (Cons<Translator> **pp = &trans_p_list_.head_; *pp; pp = &(*pp)->next_)
-    if ((*pp)->car_ == trans_l)
-      {
-       Cons<Translator> *r = trans_p_list_.remove_cons (pp);
-       r->car_ =0;
-       trans_l->daddy_trans_l_ =0;
-       delete r;
-       return trans_l;
-      }
 
-  return 0;
+  trans_group_list_ = scm_delq_x (trans_l->self_scm (), trans_group_list_);
+  trans_l->daddy_trans_l_ = 0;
+  return trans_l;
 }
 
 
 Translator*
 Translator_group::get_simple_translator (String type) const
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+  for (SCM p = simple_trans_list_;  gh_pair_p (p); p =gh_cdr (p))
     {
-      if (classname (p->car_) == type)
-       return p->car_;
+      if (classname (unsmob_translator (gh_car (p))) == type)
+       return unsmob_translator (gh_car (p));
     }
   if (daddy_trans_l_)
     return daddy_trans_l_->get_simple_translator (type);
@@ -309,7 +265,7 @@ Translator_group::get_simple_translator (String type) const
 bool
 Translator_group::is_bottom_translator_b () const
 {
-  return !accepts_str_arr_.size ();
+  return accepts_name_list_ == SCM_EOL;
 }
 
 
@@ -317,16 +273,17 @@ Translator_group::is_bottom_translator_b () const
 Translator_group*
 Translator_group::get_default_interpreter()
 {
-  if (accepts_str_arr_.size())
+  if (gh_pair_p (accepts_name_list_))
     {
-      Translator*t = output_def_l ()->find_translator_l (accepts_str_arr_[0]);
+      String str = ly_scm2string (gh_car (accepts_name_list_));
+      Translator*t = output_def_l ()->find_translator_l (str);
       if (!t)
        {
-         warning (_f ("can't find or create: `%s'", accepts_str_arr_[0]));
+         warning (_f ("can't find or create: `%s'", str));
          t = this;
        }
       Translator_group * g= dynamic_cast <Translator_group*>(t->clone ());
-      add_translator (g);
+      add_group_translator (g);
 
       if (!g->is_bottom_translator_b ())
        return g->get_default_interpreter ();
@@ -336,105 +293,90 @@ Translator_group::get_default_interpreter()
   return this;
 }
 
-void
-Translator_group::each (Method_pointer method)
+static void
+static_each (SCM list, Method_pointer method)
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-    (p->car_->*method) ();
+  for (SCM p = list; gh_pair_p (p); p = gh_cdr(p))
+    (unsmob_translator (gh_car (p))->*method) ();
+  
 }
 
-
 void
-Translator_group::each (Const_method_pointer method) const
+Translator_group::each (Method_pointer method) 
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-    (p->car_->*method) ();
+  static_each (simple_trans_list_, method);
+  static_each (trans_group_list_, method);
 }
 
 void
 Translator_group::do_print() const
 {
 #ifndef NPRINT
-  if (!flower_dstream)
-    return ;
-
-  gh_display (properties_dict_->self_scm ());
-  if (status == ORPHAN)
-    {
-      DEBUG_OUT << "consists of: ";
-      for (int i=0; i < consists_str_arr_.size (); i++)
-       DEBUG_OUT << consists_str_arr_[i] << ", ";
-      DEBUG_OUT << "\naccepts: ";
-      for (int i=0; i < accepts_str_arr_.size (); i++)
-       DEBUG_OUT << accepts_str_arr_[i] << ", ";
-    }
-  else
-    {
-      if (id_str_.length_i ())
-       DEBUG_OUT << "ID: " << id_str_ ;
-      DEBUG_OUT << " iterators: " << iterator_count_<< '\n';
-    }
-  each (&Translator::print);
 #endif
 }
 
-void
-Translator_group::do_pre_move_processing ()
+static SCM
+trans_list (SCM namelist, Music_output_def *mdef)
 {
-  each (&Translator::pre_move_processing);
-}
-
-void
-Translator_group::do_post_move_processing ()
-{
-  each (&Translator::post_move_processing);
-}
-
-void
-Translator_group::do_process_music ()
-{
-  each (&Translator::process_music);
-}
-
-void
-Translator_group::do_creation_processing ()
-{
-  each (&Translator::creation_processing);
+  SCM l = SCM_EOL;
+  for (SCM s = namelist; gh_pair_p (s) ; s = gh_cdr (s))
+    {
+      Translator * t = mdef->find_translator_l (ly_scm2string (gh_car (s)));
+      if (!t)
+       warning (_f ("can't find: `%s'", s));
+      else
+       {
+         Translator * tr = t->clone ();
+         SCM str = tr->self_scm ();
+         l = gh_cons (str, l);
+         scm_unprotect_object (str);
+       }
+    }
+  return l; 
 }
 
-void
-Translator_group::do_removal_processing ()
-{
-  each (&Translator::removal_processing);
-}
 
 void
 Translator_group::do_add_processing ()
 {
-   for (int i=0; i < consists_str_arr_.size(); i++)
+  assert (simple_trans_list_== SCM_EOL);
+
+  SCM correct_order = scm_reverse (property_pushes_); // pity of the mem.
+  for (SCM s = correct_order; gh_pair_p (s); s = gh_cdr (s))
     {
-      String s = consists_str_arr_[i];
-      Translator * t = output_def_l ()->find_translator_l (s);
-      if (!t)
-       warning (_f ("can't find: `%s'", s));
-      else
-       add_translator (t->clone ());
+      SCM entry = gh_car (s);
+      SCM val = gh_cddr (entry);
+      val = gh_pair_p (val) ? gh_car (val) : SCM_UNDEFINED;
+      
+      Translator_group_initializer::apply_pushpop_property (this, gh_car (entry),
+                                                           gh_cadr (entry),
+                                                           val);
     }
-   for (int i=0; i-- < consists_end_str_arr_.size (); i++)
-     {
-       String s = consists_end_str_arr_[i];
-       Translator * t = output_def_l ()->find_translator_l (s);
-       if (!t)
-        warning (_f ("can't find: `%s'", s));
-       else
-        add_translator (t->clone ());
+
+  SCM l1 = trans_list (consists_name_list_, output_def_l ());
+  SCM l2 =trans_list (end_consists_name_list_, output_def_l ());
+  l1 = scm_reverse_x (l1, l2);
+  
+  simple_trans_list_ = l1;
+  for (SCM s = l1; gh_pair_p (s) ; s = gh_cdr (s))
+    {
+      Translator * t = unsmob_translator (gh_car (s));
+
+      t->daddy_trans_l_ = this;
+      t->output_def_l_ = output_def_l_;
+      t->add_processing ();
     }
+
+  
 }
 
+/*
+  PROPERTIES
+ */
 Translator_group*
 Translator_group::where_defined (SCM sym) const
 {
-  if (properties_dict_->elem_b (sym))
+  if (properties_dict ()->elem_b (sym))
     {
       return (Translator_group*)this;
     }
@@ -445,9 +387,9 @@ Translator_group::where_defined (SCM sym) const
 SCM
 Translator_group::get_property (SCM sym) const
 {
-  if (properties_dict_->elem_b (sym))
+  if (properties_dict ()->elem_b (sym))
     {
-      return properties_dict_->get (sym);
+      return properties_dict ()->get (sym);
     }
 
   if (daddy_trans_l_)
@@ -465,7 +407,78 @@ Translator_group::set_property (String id, SCM val)
 void
 Translator_group::set_property (SCM sym, SCM val)
 {
-  properties_dict_->set (sym, val);
+  properties_dict ()->set (sym, val);
 }
 
+/*
+  Push or pop (depending on value of VAL) a single entry (ELTPROP . VAL)
+  entry from a translator property list by name of PROP
+*/
+void
+Translator_group::execute_single_pushpop_property (SCM prop, SCM eltprop, SCM val)
+{
+  if (gh_symbol_p(prop))
+    {
+      if (val != SCM_UNDEFINED)
+       {
+         SCM prev = get_property (prop);
 
+         prev = gh_cons (gh_cons (eltprop, val), prev);
+         set_property (prop, prev);
+       }
+      else
+       {
+         SCM prev = get_property (prop);
+
+         SCM newprops= SCM_EOL ;
+         while (gh_pair_p (prev) && gh_caar (prev) != eltprop)
+           {
+             newprops = gh_cons (gh_car (prev), newprops);
+             prev = gh_cdr (prev);
+           }
+         
+         if (gh_pair_p (prev))
+           {
+             newprops = scm_reverse_x (newprops, gh_cdr (prev));
+             set_property (prop, newprops);
+           }
+       }
+    }
+}
+
+
+
+
+
+/*
+  STUBS
+*/
+void
+Translator_group::do_pre_move_processing ()
+{
+  each (&Translator::pre_move_processing);
+}
+
+void
+Translator_group::do_post_move_processing ()
+{
+  each (&Translator::post_move_processing);
+}
+
+void
+Translator_group::do_process_music ()
+{
+  each (&Translator::process_music);
+}
+
+void
+Translator_group::do_creation_processing ()
+{
+  each (&Translator::creation_processing);
+}
+
+void
+Translator_group::do_removal_processing ()
+{
+  each (&Translator::removal_processing);
+}
index 68db603831d8396abbec3acb0d4955e63980b68c..6605eaae0ca1ae2ababd353a41ede4b9fa856f95 100644 (file)
@@ -12,6 +12,7 @@
 #include "translator-group.hh"
 
 #include "moment.hh"
+#include "ly-smobs.icc"
 
 char const*
 Translator::name() const
@@ -23,20 +24,42 @@ Translator::~Translator ()
 {
 }
 
+void
+Translator::init ()
+{
+  status_ = ORPHAN;
+  simple_trans_list_ = SCM_EOL;
+  trans_group_list_ = SCM_EOL;
+  properties_scm_ = SCM_EOL;
+  accepts_name_list_ = SCM_EOL;   
+  consists_name_list_ = SCM_EOL;
+  end_consists_name_list_ = SCM_EOL;
+  property_pushes_ = SCM_EOL;
+  daddy_trans_l_ =0;
+}
+
 Translator::Translator ()
 {
-  status = ORPHAN;
-  daddy_trans_l_ = 0;
+  init ();
   output_def_l_ = 0;
+  smobify_self ();
+
 }
 
 Translator::Translator (Translator const &s)
   : Input (s)
 {
-  status = ORPHAN;
-  daddy_trans_l_ =0;
+  init ();
+  
+  consists_name_list_ = scm_list_copy (s.consists_name_list_);
+  end_consists_name_list_ = scm_list_copy (s.end_consists_name_list_);
+  accepts_name_list_ = scm_list_copy (s.accepts_name_list_);
+  property_pushes_ = scm_list_copy (s.property_pushes_);
+  
   output_def_l_ = s.output_def_l_;
   type_str_ = s.type_str_;
+
+  smobify_self ();
 }
 
 bool
@@ -62,11 +85,11 @@ Translator::now_mom () const
 void
 Translator::add_processing ()
 {
-  if (status > ORPHAN)
+  if (status_ > ORPHAN)
     return;
   
   do_add_processing ();
-  status = VIRGIN;
+  status_ = VIRGIN;
 }
 
 void
@@ -97,40 +120,40 @@ Translator::do_print () const
 void
 Translator::creation_processing ()
 {
-  if (status >= CREATION_INITED)
+  if (status_ >= CREATION_INITED)
     return ;
   
   do_creation_processing ();
-  status = CREATION_INITED;
+  status_ = CREATION_INITED;
 }
 
 void
 Translator::post_move_processing ()
 {
-  if (status >= MOVE_INITED)
+  if (status_ >= MOVE_INITED)
     return;
 
   creation_processing ();
   do_post_move_processing ();
-  status = MOVE_INITED;
+  status_ = MOVE_INITED;
 }
 
 void
 Translator::removal_processing ()
 {
-  if (status == ORPHAN)
+  if (status_ == ORPHAN)
     return;
   creation_processing ();
   do_removal_processing ();
   // elegancy ...
-  // status = ORPHAN;
+  // status_ = ORPHAN;
 }
 
 
 bool
 Translator::try_music (Music * r)
 {
-  if (status < MOVE_INITED)
+  if (status_ < MOVE_INITED)
     post_move_processing ();
 
   return do_try_music (r);
@@ -139,12 +162,12 @@ Translator::try_music (Music * r)
 void
 Translator::process_music ()
 {
-  if (status < PROCESSED_REQS)
+  if (status_ < PROCESSED_REQS)
     post_move_processing ();
-  else if (status >= PROCESSED_REQS)
+  else if (status_ >= PROCESSED_REQS)
     return; 
   
-  status = PROCESSED_REQS;
+  status_ = PROCESSED_REQS;
   do_process_music ();
 }
 
@@ -152,7 +175,7 @@ void
 Translator::pre_move_processing ()
 {
   do_pre_move_processing ();
-  status = CREATION_INITED;
+  status_ = CREATION_INITED;
 }
 
 
@@ -199,3 +222,47 @@ void
 Translator::do_removal_processing ()
 {
 }
+
+
+/*
+
+  SMOBS
+
+*/
+SCM
+Translator::mark_smob (SCM sm)
+{
+  Translator * me = (Translator*) SCM_CELL_WORD_1(sm);
+  scm_gc_mark (me->consists_name_list_);
+  scm_gc_mark (me->accepts_name_list_);
+  scm_gc_mark (me->end_consists_name_list_);
+  scm_gc_mark (me->simple_trans_list_);
+  scm_gc_mark (me->trans_group_list_);
+  scm_gc_mark (me->property_pushes_);
+  return me->properties_scm_;
+}
+
+
+int
+Translator::print_smob (SCM s, SCM port, scm_print_state *)
+{
+  Translator *sc = (Translator *) gh_cdr (s);
+     
+  scm_puts ("#<Translator ", port);
+  scm_puts ((char *)sc->name (), port);
+  scm_display (sc->simple_trans_list_, port);
+  /*
+    don't try to print properties, that is too much hassle.
+   */
+  scm_puts (" >", port);
+
+  
+  
+  return 1;
+}
+
+
+
+IMPLEMENT_UNSMOB(Translator, translator);
+IMPLEMENT_SMOBS(Translator);
+IMPLEMENT_DEFAULT_EQUAL_P(Translator);
index ed5e782706b56c44820057833212bcfccff4ec24..a6684ed45416fa1fccf517d3f06eba82daa19e81 100644 (file)
@@ -22,30 +22,27 @@ protected:
 
 ADD_THIS_TRANSLATOR (Voice_devnull_engraver);
 
+static char const *junk_interfaces[] = {
+  //   "beam-interface",
+  "slur-interface",
+  "tie-interface",
+  "text-item-interface",
+  "text-script-interface",
+  "dynamic-interface",
+  "crescendo-interface",
+  0
+};
+
 void
 Voice_devnull_engraver::acknowledge_element (Score_element_info i)
 {
   if (daddy_trans_l_->id_str_ == "two"
       && (to_boolean (get_property ("unison"))
          || to_boolean (get_property ("unisilence"))))
-    {
-      static char const *junk[] = {
-       //      "beam-interface",
-       "slur-interface",
-       "tie-interface",
-       "text-item-interface",
-       "text-script-interface",
-       "dynamic-interface",
-       "crescendo-interface",
-       0
-      };
-      for (char const **p = junk; *p; *p++)
+    for (char const **p = junk_interfaces; *p; p++)
+      if (i.elem_l_->has_interface (ly_symbol2scm (*p)))
        {
-         if (i.elem_l_->has_interface (ly_symbol2scm (*p)))
-           {
-             i.elem_l_->suicide ();
-             return;
-           }
+         i.elem_l_->suicide ();
+         return;
        }
-    }
 }
index 0d1408d4c1856f8430bd01bb8bd0205f5c623a99..3671d3c46c09050396ba52e29047b721324f848c 100644 (file)
@@ -6,8 +6,6 @@ StaffContext=\translator {
        \type "Engraver_group_engraver";
        \name Staff ;
        \consists "Output_property_engraver";   
-       barAuto = ##t
-       voltaVisibility = ##t
        Generic_property_list = #generic-staff-properties
        \consists "Property_engraver";
        
@@ -16,36 +14,11 @@ StaffContext=\translator {
  % Bar_engraver must be first so default bars aren't overwritten
 % with empty ones.
 
-       voltaPadding = #5  % urg, in \pt
-       voltaMinimumSpace = #25  % urg, in \pt
-
-       StaffMinimumVerticalExtent = #(cons -4.0 4.0)
 
        \consists "Repeat_engraver";
 
 
-       %  name, glyph id, c0 position
-       supportedClefTypes = #'(
-         ("treble" . ("clefs-G" -2))
-         ("violin" . ("clefs-G" -2))
-         ("G" . ("clefs-G" -2))
-         ("G2" . ("clefs-G" -2))
-         ("french" . ("clefs-G" -4 ))
-         ("soprano" . ("clefs-C" -4 ))
-         ("mezzosoprano" . ("clefs-C" -2 ))
-         ("alto" . ("clefs-C" 0 ))
-         ("tenor" . ("clefs-C" 2 ))
-         ("baritone" . ("clefs-C" 4 ))
-         ("varbaritone"  . ("clefs-F" 0))
-         ("bass" . ("clefs-F" 2 ))
-         ("F" . ( "clefs-F" 2))
-         ("subbass" . ("clefs-F" 4))
-       )
-       % where is c0 in this clef?
-       clefPitches = #'(("clefs-G" . -4)
-         ("clefs-C" . 0)
-         ("clefs-F" . 4))
-         
+
        \consists "Clef_engraver";
        \consists "Key_engraver";
        \consists "Time_signature_engraver";
@@ -56,23 +29,19 @@ StaffContext=\translator {
 
        \consistsend "Axis_group_engraver";
 
-
-
 %{
        The Instrument_name_engraver puts the name of the instrument
        (\property Staff.instrument; Staff.instr for subsequent lines)
        to the left of a staff.
-       Usually, you only want this in the full score, not in the parts.
 
+       This is commented out, so you don't get funny things on the
+       PianoStaff      
        \consists "Instrument_name_engraver";
 %}
 
-       defaultClef = #"treble"
 
-       \consists "Separating_line_group_engraver";
          
        \accepts "Voice";
-       dynamicStyle = #"dynamic"
 };
 
 \translator{\StaffContext }
@@ -83,14 +52,10 @@ StaffContext=\translator {
        \consists "System_start_delimiter_engraver";
        systemStartDelimiterGlyph = #'bracket
 
-
-
        \accepts "Staff";
        \accepts "RhythmicStaff";
        \accepts "GrandStaff";
        \accepts "PianoStaff";
-
-               
        \accepts "Lyrics";
        \accepts "ChordNames";
 }
@@ -104,13 +69,17 @@ RhythmicStaffContext=\translator{
 
        Generic_property_list = #generic-staff-properties
        
-       barSize =   4.0 * \staffspace ; 
+       barSize =   4.0 * \staffspace ; % urg: pt
+
        \consists "Pitch_squash_engraver";
        \consists "Separating_line_group_engraver";     
        \name RhythmicStaff;
 
-       voltaPadding = #5  % urg, in \pt
-       voltaMinimumSpace = #15  % urg, in \pt
+       \pushproperty #'basicVoltaSpannerProperties #'minimum-space #15  % urg, in \pt
+       \pushproperty #'basicVoltaSpannerProperties #'padding #5  % urg, in \pt
+
+
+
        \consists "Repeat_engraver";
        \consists "Bar_engraver";
        \consists "Time_signature_engraver";
@@ -124,10 +93,8 @@ VoiceContext = \translator {
        \type "Engraver_group_engraver";
        \name Voice;
 
-       dynamicPadding = #3  % urg, in \pt
-       dynamicMinimumSpace = #6  % urg, in \pt
-
        Generic_property_list = #generic-voice-properties
+       
        \consists "Output_property_engraver";   
 
        \consists "Dynamic_engraver";   % must come before text_engraver.
@@ -143,24 +110,18 @@ VoiceContext = \translator {
 
        \consists "Chord_tremolo_engraver";
        \consists "Melisma_engraver";
-       textScriptPadding = #3.0
        \consists "Text_engraver";
        \consists "A2_engraver";
        \consists "Voice_devnull_engraver";
 
-       % ugh :  set these in Score context, please.
+
        startSustain = #"Ped."
        stopSustain = #"*"
        stopStartSustain = #"*Ped."
        startUnaChorda = #"una chorda"
        stopUnaChorda = #"tre chorde"
-
-       soloText = #"Solo"
-       soloIIText = #"Solo II"
-       aDueText = #"\\`a2"
-       soloADue = ##t
-       splitInterval = #'(0 . 1)
-
+       % should make separate lists for stopsustain and startsustain 
+       
        \consists "Piano_pedal_engraver";
        \consists "Script_engraver";
        \consists "Script_column_engraver";
@@ -192,18 +153,19 @@ GraceContext=\translator {
        \consists "Align_note_column_engraver";
 
        \consists "Rhythmic_column_engraver";
-       \consists "Dynamic_engraver";
-       \consists "Text_engraver";
+
+       \consists "Dynamic_engraver";% in Grace ???
+       \consists "Text_engraver"; % in Grace ???
 
        \consists "Property_engraver";
 
-       stemStyle = #"grace"
-       flagStyle = #"grace" 
+       \pushproperty #'basicStemProperties #'style #"grace"
+       \pushproperty #'basicStemProperties #'flag-style #"grace"
+       \pushproperty #'basicStemProperties #'stem-length #6.0
+       \pushproperty #'basicStemProperties #'direction #1
+       \pushproperty #'(basicNoteHeadProperties basicStemProperties basicBeamProperties basicTextScriptProperties basicSlurProperties basicLocalKeyProperties) #'font-size #-1
+               
        weAreGraceContext = ##t 
-       fontSize = #-1
-       
-       stemLength = #6.0
-       verticalDirection = \up ;
        graceAccidentalSpace= 1.5 * \staffspace;
 };
 
@@ -365,40 +327,71 @@ OrchestralPartStaffContext = \translator {
 ScoreContext = \translator {
        \type Score_engraver;
        \name Score;
-
-       marginScriptPadding = #10  % urg, in \pt
+       
 
        \consists "Timing_engraver";
        \consists "Output_property_engraver";   
-
-       %bracketCollapseHeight = #10  % \pt
        \consists "System_start_delimiter_engraver";
-       
-%      \consists "Score_priority_engraver";
+       \consists "Mark_engraver";      
        \consists "Break_align_engraver";
-       breakAlignOrder = #'(
-         Instrument_name
-         Left_edge_item
-         Span_bar
-         Breathing_sign
-         Clef_item
-         Key_item
-         Staff_bar
-         Time_signature
-         Stanza_number
-       )
        \consists "Spacing_engraver";
 
        \consists "Vertical_align_engraver";
 
        \consists "Lyric_phrasing_engraver";
-        automaticPhrasing = ##t;
-
        \consists "Bar_number_engraver";
+
+       
+       \accepts "Staff";
+       \accepts "StaffGroup";
+       \accepts "RhythmicStaff";       
+       \accepts "Lyrics";
+       \accepts "ChordNames";
+       \accepts "GrandStaff";
+       \accepts "ChoirStaff";
+       \accepts "PianoStaff";
+       \accepts "NoteNames";
+
+       soloText = #"Solo"
+       soloIIText = #"Solo II"
+       aDueText = #"\\`a2"
+       soloADue = ##t
+       splitInterval = #'(0 . 1)
+
+       defaultClef = #"treble"
+
+       StaffMinimumVerticalExtent = #(cons -4.0 4.0)
+
+       barAuto = ##t
+       voltaVisibility = ##t
+       %  name, glyph id, c0 position
+       supportedClefTypes = #'(
+         ("treble" . ("clefs-G" -2))
+         ("violin" . ("clefs-G" -2))
+         ("G" . ("clefs-G" -2))
+         ("G2" . ("clefs-G" -2))
+         ("french" . ("clefs-G" -4 ))
+         ("soprano" . ("clefs-C" -4 ))
+         ("mezzosoprano" . ("clefs-C" -2 ))
+         ("alto" . ("clefs-C" 0 ))
+         ("tenor" . ("clefs-C" 2 ))
+         ("baritone" . ("clefs-C" 4 ))
+         ("varbaritone"  . ("clefs-F" 0))
+         ("bass" . ("clefs-F" 2 ))
+         ("F" . ( "clefs-F" 2))
+         ("subbass" . ("clefs-F" 4))
+       )
+       % where is c0 in this clef?
+       clefPitches = #'(("clefs-G" . -4)
+         ("clefs-C" . 0)
+         ("clefs-F" . 4))
+               
+
+        automaticPhrasing = ##t;
        alignmentReference = \down;
        defaultClef = #"treble"
        defaultBarType = #"|"
-       systemStartDelimiterGlyph = #'bar-line
+       systemStartDelimiterGlyph = #'bar-line
 
        %
        % what order to print accs.  We could compute this, 
@@ -409,17 +402,27 @@ ScoreContext = \translator {
          (6 . -1) (2  . -1) (5 . -1 ) (1  . -1) (4  . -1) (0  . -1) (3  . -1)
         (3  . 1) (0 . 1) (4 . 1) (1 . 1) (5 . 1) (2 . 1) (6 . 1)
        )
+       breakAlignOrder = #'(
+         Instrument_name
+         Left_edge_item
+         Span_bar
+         Breathing_sign
+         Clef_item
+         Key_item
+         Staff_bar
+         Time_signature
+         Stanza_number
+       )
+       
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-       % default settings, mainly for breakable items
-       % in alphabetical order
        % TODO: uniform naming.;  
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+
        %
-       % distances are given in stafflinethickness (thicknesses) and staffspace (distances)
+       % distances are given in stafflinethickness (thicknesses) and
+       % staffspace (distances)
        %
-       
-       
        basicBarProperties = #`(
                (break-align-symbol . Staff_bar)
                (barsize-procedure . ,Bar::get_staff_bar_size)
@@ -501,17 +504,20 @@ ScoreContext = \translator {
                (dot-count . 1)
                (interfaces . (dot-interface))
        )
-       basicDynamicLineSpannerProperties = #`(
-               (interfaces . (dynamic-interface axis-group-interface))
-               (axes . ( 1))
-       )
-       basicDynamicTextProperties       = # `(
+       basicDynamicTextProperties = # `(
                (style . "dynamic")
                (interfaces . (dynamic-interface))
                (molecule-callback . ,Text_item::brew_molecule)
                (script-priority . 100)
                (self-alignment-Y . 0)
        )
+       
+       basicDynamicLineSpannerProperties = #`(
+               (interfaces . (dynamic-interface axis-group-interface))
+               (axes . ( 1))
+               (padding . 3)
+               (minimum-space . 6)
+       )
        leftEdgeBasicProperties = #`(
                (break-align-symbol . Left_edge_item)
                (breakable . #t)
@@ -531,6 +537,13 @@ ScoreContext = \translator {
                (minimum-length .  0.5) 
                (molecule-callback . ,Hyphen_spanner::brew_molecule)
        )
+       
+       basicInstrumentNameProperties = #`(
+               (breakable . #t)
+               (molecule-callback . ,Text_item::brew_molecule)         
+               (break-align-symbol . Instrument_name)
+               (visibility-lambda . ,begin-of-line-visible)
+       )
        basicKeyProperties = #`(
          (molecule-callback . ,Key_item::brew_molecule)
          (interfaces . (key-item-interface))
@@ -565,6 +578,7 @@ ScoreContext = \translator {
          (breakable . #t)
          (interfaces . (mark-interface))
          (visibility-lambda . ,end-of-line-invisible)
+         (padding . 4.0)
        )
        basicMultiMeasureRestProperties = #`(
                (spacing-procedure . ,Multi_measure_rest::set_spacing_rods)             
@@ -594,13 +608,6 @@ ScoreContext = \translator {
                (axes 0)
                (rank . -1)
        )
-       basicPedalProperties = #`(
-               (molecule-callback . ,Text_item::brew_molecule)
-               (style . "italic")
-               (no-spacing-rods . #t)
-               (self-alignment-X . 0)
-                               
-       )
        basicTextProperties = #`( )
        basicRestProperties = #`(
                (interfaces . (rest-interface rhythmic-head-interface))
@@ -658,20 +665,6 @@ ScoreContext = \translator {
                (break-align-symbol . Clef_item)
                (visibility-lambda . ,begin-of-line-visible)
        )
-       basicStemProperties = #`(
-               (before-line-breaking-callback . ,Stem::before_line_breaking)
-               (molecule-callback . ,Stem::brew_molecule)
-
-               ; if stem is on middle line, choose this direction.
-               (default-neutral-direction . 1)
-               (interfaces . (stem-interface))
-       )
-       basicSustainPedalProperties = #`(
-               (no-spacing-rods . #t)
-               (molecule-callback . ,Sustain_pedal::brew_molecule)
-               (self-alignment-X . 0)
-               (interfaces . (sustain-pedal-interface))
-       )       
        staffSymbolBasicProperties = #`(
                (molecule-callback . ,Staff_symbol::brew_molecule)
                (staff-space . 1.0)
@@ -692,10 +685,9 @@ ScoreContext = \translator {
        )
        basicTextScriptProperties = #`(
                (molecule-callback . ,Text_item::brew_molecule)
-
-: -- don't set, because property-engraver will not override it.  
-;              (no-spacing-rods . #t)
+               (no-spacing-rods . #t)
                (interfaces . (text-script-interface text-item-interface))
+               (padding .      3.0)            
        )
        basicTieProperties = #`(
                (molecule-callback . ,Tie::brew_molecule)
@@ -723,12 +715,26 @@ ScoreContext = \translator {
                (molecule-callback . ,Tuplet_spanner::brew_molecule)
                (interfaces . (tuplet-spanner-interface))
        )       
+       basicSostenutoPedalProperties = #`(
+               (molecule-callback . ,Text_item::brew_molecule)
+               (style . "italic")
+               (no-spacing-rods . #t)
+               (self-alignment-X . 0)
+                               
+       )
        basicStemTremoloProperties = #`(
                (molecule-callback . ,Stem_tremolo::brew_molecule)
                (beam-width . 2.0) ; staff-space
                (beam-thickness . 0.42) ; staff-space
        )
+       basicStemProperties = #`(
+               (before-line-breaking-callback . ,Stem::before_line_breaking)
+               (molecule-callback . ,Stem::brew_molecule)
 
+               ; if stem is on middle line, choose this direction.
+               (default-neutral-direction . 1)
+               (interfaces . (stem-interface))
+       )
        basicSeparationItemProperties = #`(
                (interfaces . (separation-item-interface))
        )
@@ -736,33 +742,29 @@ ScoreContext = \translator {
                (interfaces . (separation-spanner-interface))
                (spacing-procedure . ,Separating_group_spanner::set_spacing_rods)
        )
-       basicInstrumentNameProperties = #`(
-               (breakable . #t)
-               (molecule-callback . ,Text_item::brew_molecule)         
-               (break-align-symbol . Instrument_name)
-               (visibility-lambda . ,begin-of-line-visible)
-       )
-       basicVerticalAxisGroupProperties = #`(
-               (axes 1)
-               (interfaces . (axis-group-interface))
+       basicSustainPedalProperties = #`(
+               (no-spacing-rods . #t)
+               (molecule-callback . ,Sustain_pedal::brew_molecule)
+               (self-alignment-X . 0)
+               (interfaces . (sustain-pedal-interface))
+       )       
+       basicUnaChordaPdealProperties = #`(
+               (molecule-callback . ,Text_item::brew_molecule)
+               (style . "italic")
+               (no-spacing-rods . #t)
+               (self-alignment-X . 0)
        )
+       
        basicVoltaSpannerProperties = #`(
                (molecule-callback . ,Volta_spanner::brew_molecule)
                (interfaces . (volta-spanner-interface))
+               (padding . 5)
+               (minimum-space . 25)
+       )       
+       basicVerticalAxisGroupProperties = #`(
+               (axes 1)
+               (interfaces . (axis-group-interface))
        )
-       
-       \accepts "Staff";
-       \accepts "StaffGroup";
-       \accepts "RhythmicStaff";       
-       \accepts "Lyrics";
-       \accepts "ChordNames";
-       \accepts "GrandStaff";
-       \accepts "ChoirStaff";
-       \accepts "PianoStaff";
-       \accepts "NoteNames";
-
-
-       markVisibilityFunction = #end-of-line-invisible
 };
 
 \translator { \ScoreContext }
@@ -770,10 +772,6 @@ ScoreContext = \translator {
 OrchestralScoreContext= \translator {
        \ScoreContext
 
-       barScriptPadding = #2.0         % dimension \pt
-       markScriptPadding = #4.0
-
-       \consists "Mark_engraver";
 };
 
 \translator {
@@ -781,4 +779,5 @@ OrchestralScoreContext= \translator {
        \name NoteNames;
        \consistsend "Axis_group_engraver";
        \consists "Note_name_engraver";
+       \consists "Separating_line_group_engraver";
 }
index 4281407c2221e41346961168eb2cccacd034b0cd..951fe62c358089cbea4cd91e33b3b57859a5e59c 100644 (file)
@@ -1,15 +1,15 @@
 Begin3
 Title: LilyPond
-Version: 1.3.81
-Entered-date: 28AUG00
+Version: 1.3.82
+Entered-date: 31AUG00
 Description: 
 Keywords: music notation typesetting midi fonts engraving
 Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
        janneke@gnu.org (Jan Nieuwenhuizen)
 Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
 Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
-       1000k lilypond-1.3.81.tar.gz 
+       1000k lilypond-1.3.82.tar.gz 
 Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
-       1000k lilypond-1.3.81.tar.gz 
+       1000k lilypond-1.3.82.tar.gz 
 Copying-policy: GPL
 End
index 6741ab896e5b039647d77d40f4d1ad2564a8461d..d6ee4e016145a62a97e5bc0b2796b326b197b207 100644 (file)
@@ -1,9 +1,9 @@
 Name: lilypond
-Version: 1.3.81
+Version: 1.3.82
 Release: 1
 Copyright: GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.81.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.82.tar.gz
 Summary: A program for printing sheet music.
 URL: http://www.cs.uu.nl/~hanwen/lilypond
 # Icon: lilypond-icon.gif
index 9a277e310c95d8e986cb4b5f24c662e4d912dc11..9d33209b23b0b54fd18df07569e497abcc87441f 100644 (file)
@@ -94,7 +94,7 @@
                \consists "Script_engraver";
                \consists "Script_column_engraver";
                \consists "Rhythmic_column_engraver";
-%%             \consists "Slur_engraver";
+               \consists "Slur_engraver";
                \consists "Tie_engraver";
        }
        \translator {
index dd045ff0e41f7d54cd937a8a8b4818c7c42326ae..c23c88937a4cd08d8b54131ee29fd3e23d7e677b 100644 (file)
@@ -94,7 +94,7 @@
                \consists "Script_engraver";
                \consists "Script_column_engraver";
                \consists "Rhythmic_column_engraver";
-%%             \consists "Slur_engraver";
+               \consists "Slur_engraver";
                \consists "Tie_engraver";
        }
        \translator {
index a786acd0a18c9bc158b30f4c1d5daa6f793336ac..befcda71bce6c7355f507973609a3fe5f7d884c8 100644 (file)
 
 (define generic-All-properties
   (cons 'all
-       (list (list 'fontSize number? 'fontsize))))
+       (list (list 'fontSize number? 'font-size))))
 
 
 (define generic-notehead-properties
index e592f9f38fa5756dd878f11216be5d63d047cf2e..cc0d03c07ef07e94ba710aad9f4c351d55a5679f 100644 (file)
@@ -1049,12 +1049,15 @@ def help ():
        print r"""
 Convert ABC to Mudela.
 
-Usage: abc2ly [OPTION]... ABC-FILE
+Usage: abc2ly [OPTIONS]... ABC-FILE
 
 Options:
   -h, --help          this help
   -o, --output=FILE   set output filename to FILE
   -v, --version       version information
+
+This program converts ABC music files (see
+http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) To LilyPond input.
 """
 
 def print_version ():
index 292e983fb823bde772234d2070bffe81848b3439..b194f285614f32fc5446ae567a6e5e5473550f00 100644 (file)
 # 
 
 # todo:
+#  * automatic PC/mac/unix conversion
 #  * slur/stem directions
 #  * voices (2nd half of frame?)
 #  * more intelligent lyrics
 #  * beams (better use autobeam?)
+#  * more robust: try entertainer.etf (freenote), schubert ave maria (gmd)
 
 program_name = 'etf2ly'
 version = '@TOPLEVEL_VERSION@'
@@ -151,11 +153,19 @@ class Slur:
        def calculate (self, chords):
                startnote = self.finale[0][5]
                endnote = self.finale[3][2]
+               try:
+                       cs = chords[startnote]
+                       ce = chords[endnote]
 
-               cs = chords[startnote]
-               cs.note_suffix = '(' + cs.note_suffix 
-               ce = chords[endnote]
-               ce.prefix = ce.prefix + ')'
+                       if not cs or not ce:
+                               raise IndexError
+                       
+                       cs.note_suffix = '(' + cs.note_suffix 
+                       ce.note_prefix = ce.note_prefix + ')'
+               except IndexError:
+                       sys.stderr.write ("""\nHuh? Incorrect slur start/endpoint
+len(list) is %d, start/end is (%d,%d)\n""" % (len (chords), startnote, endnote))
+                                        
                
 class Global_measure:
        def __init__ (self, number):
@@ -166,6 +176,9 @@ class Global_measure:
 
                self.finale = []
 
+       def __str__ (self):
+               return `self.finale `
+       
        def set_timesig (self, finale):
                (beats, fdur) = finale
                (log, dots) = EDU_to_duration (fdur)
@@ -248,17 +261,23 @@ class Verse:
 class Measure:
        def __init__(self, no):
                self.number = no
-               self.frames = []
+               self.frames = [0] * 4
                self.flags = 0
                self.clef = 0
                self.finale = []
                self.global_measure = None
+               self.staff = None
                
        def add_finale_entry (self, entry):
                self.finale.append (entry)
 
        def calculate (self):
-               f0  = self.finale[0]
+               if len (self.finale) < 2:
+                       sys.stderr.write ("Measure %d in staff %d  has incomplete information.\n" % (self.number, self.staff.number))
+                       
+                       return 
+                       
+               f0 = self.finale[0]
                f1 = self.finale[1]
                
                self.clef = string.atoi (f0[0])
@@ -286,11 +305,12 @@ class Frame:
                for c in self.chords:
                        str = str + c.ly_string () + ' '
                        left = rat_subtract (left, c.length ())
+                       
                if left[0] < 0:
-                       print self.number
-                       print self.start, self.end
-                       print left
-                       raise 'bla'
+                       sys.stderr.write ("""Huh? Going backwards.
+Frame no %d, start/end (%d,%d)
+""" % (self.number, self.start, self.end))
+                       left = (0,1)
                if left[0]:
                        str = str + 's*%d/%d' % left
                        
@@ -310,7 +330,10 @@ class Staff:
                        self.measures = self.measures + [None]* (1 + no - len (self.measures))
 
                if self.measures[no] == None:
-                       self.measures [no] = Measure (no)
+                       m = Measure (no)
+                       self.measures [no] =m
+                       m.staff = self
+
 
                return self.measures[no]
        def staffid (self):
@@ -325,6 +348,9 @@ class Staff:
                last_clef = None
                gap = (0,1)
                for m in self.measures[1:]:
+                       if not m :
+                               continue # ugh.
+                       
                        g = m.global_measure
                        e = ''
                        if last_key <> g.keysignature:
@@ -359,6 +385,10 @@ class Staff:
                        first_frame = None
                        gap = (0,1)
                        for m in self.measures[1:]:
+                               if not m:
+                                       continue
+                               
+                               
                                fr = m.frames[x]
                                if fr:
                                        first_frame = fr
@@ -596,7 +626,12 @@ class Etf_file:
                          = tuple (map (string.atoi, [no,prev,next,dur,pos,extended,follow]))
 
                        entryflag = string.atol (entryflag,16)
-                       assert (no==len (self.entries))
+                       if no > len (self.entries):
+                               sys.stderr.write ("Huh? Entry number to large,\nexpected %d got %d. Filling with void entries.\n" % (len(self.entries), no  ))
+                               while len (self.entries) <> no:
+                                       c = ((len (self.entries), 0, 0, 0, 0, 0L, 0, 0), [])
+                                       self.entries.append (c)
+                                       
                        current_entry = ((no, prev, next, dur, pos, entryflag, extended, follow), [])
                        self.entries.append (current_entry)
                return m
@@ -632,6 +667,11 @@ class Etf_file:
                if m:
                        (frameno, startnote, endnote, foo, bar) = m.groups ()
                        (frameno, startnote, endnote)  = tuple (map (string.atoi, [frameno, startnote, endnote]))
+                       if frameno > len (self.frames):
+                               sys.stderr.write ("Frame no %d missing, filling up to %d\n" % (len(self.frames), frameno))
+                               while frameno <> len (self.frames):
+                                       self.frames.append (Frame ((len (self.frames), 0,0) ))
+                       
                        self.frames.append (Frame ((frameno, startnote, endnote)))
                        
                return m
@@ -660,8 +700,12 @@ class Etf_file:
        def parse (self, name):
                sys.stderr.write ('parsing ...')
                sys.stderr.flush ()
+
+               gulp = open (name).read ()
+
+               gulp = re.sub ('[\n\r]+', '\n',  gulp)
+               ls = string.split (gulp, '\n')
                
-               ls = open (name).readlines ()
                for l in ls:
                        m = None
                        if not m: 
@@ -691,6 +735,9 @@ class Etf_file:
                                continue
                        mno = 1
                        for m in st.measures[1:]:
+                               if not m:
+                                       continue
+                               
                                m.global_measure = self.measures[mno]
                                m.calculate()
 
@@ -756,7 +803,7 @@ class Etf_file:
 
 
        def __str__ (self):
-               return self.dump ()
+               return 'ETF FILE %s %s' % (self.measures,  self.entries)
        
        def unthread_entries (self):
                self.chords = [None]
@@ -827,7 +874,7 @@ for f in files:
        sys.stderr.write ('Processing `%s\'\n' % f)
        e = Etf_file(f)
        if not out_filename:
-               out_filename = os.path.basename (re.sub ('.etf$', '.ly', f))
+               out_filename = os.path.basename (re.sub ('(?i).etf$', '.ly', f))
                
        if out_filename == f:
                out_filename = os.path.basename (f + '.ly')
index 03b479bfb260c54ada2d9fb9b76e7e30c916004d..610c29e7099b7bfd207364aa617c696f15c7b86f 100644 (file)
@@ -1,7 +1,43 @@
 #!@PYTHON@
 # vim: set noexpandtab:
+import time
+t1 = time.clock()
+
+# support bruk av convert-mudela
+#
+# option:
+# 11pt, 13pt, 16pt, 20pt, 26pt
+# singleline
+# multiline
+# fragment  (used when a comment containg \score confuses mudela-book)
+# nonfragment (probably not needed)
+# verbatim
+
+# latex only options:
+# eps
+# 
+
+# command line options
+# --defalt-mudela-fontsize
+# --force-mudela-fontsize
+# --outname
+# --force-verbatim make all mudela verbatim. Maybe not that useful
+# --dependencies
+# --dep-prefix
+# --no-pictures
+# --no-lily
 # TODO: Figure out clean set of options.
-# add support for .lilyrc
+
+# BUG: does not handle \verb|\begin{verbatim}\end{verbatim}| correctly.
+# Should make a joint RE for \verb and \begin, \end{verbatim}
+
+# TODO: add an option to read the .ly files from a previous run and dump
+# the .tex file, so you can do
+#
+# * mudela-book file.tex
+# * convert-mudela *.ly
+# * mudela-book --read-lys *.ly
+#
 
 import os
 import stat
@@ -12,7 +48,12 @@ import sys
 import __main__
 
 
+initfile = ''
+
+
 program_version = '@TOPLEVEL_VERSION@'
+if program_version == '@' + 'TOPLEVEL_VERSION' + '@':
+       program_version = '1.3.69-very-unstable'        
 
 include_path = [os.getcwd()]
 
@@ -24,6 +65,7 @@ g_do_pictures = 1
 g_num_cols = 1
 format = ''
 g_run_lilypond = 1
+g_use_hash = 1
 no_match = 'a\ba'
 
 default_music_fontsize = 16
@@ -62,20 +104,22 @@ def get_linewidth(cols, paper, fontsize):
 
 option_definitions = [
   ('EXT', 'f', 'format', 'set format.  EXT is one of texi and latex.'),
-  ('DIM',  '', 'default-music-fontsize', 'default fontsize for music.  DIM is assumed to be in points'),
+  ('DIM',  '', 'default-music-fontsize', 'default fontsize for music.  DIM is assumed to in points'),
   ('DIM',  '', 'default-mudela-fontsize', 'deprecated, use --default-music-fontsize'),
-  ('DIM', '', 'force-music-fontsize', 'force fontsize for all inline mudela. DIM is assumed be to in points'),
-  ('DIM', '', 'force-mudela-fontsize', 'deprecated, use --force-music-fontsize'),
+  ('', 'h', 'help', 'print help'),
   ('DIR', 'I', 'include', 'include path'),
+  ('', '', 'init', 'mudela-book initfile'),
+  ('DIM', '', 'force-music-fontsize', 'force fontsize for all inline mudela. DIM is assumed to in points'),
+  ('DIM', '', 'force-mudela-fontsize', 'deprecated, use --force-music-fontsize'),
+  ('', '', 'force-verbatim', 'make all mudela verbatim'),
   ('', 'M', 'dependencies', 'write dependencies'),
-  ('PREF', '',  'dep-prefix', 'prepend PREF before each -M dependency'),
   ('', 'n', 'no-lily', 'don\'t run lilypond'),
   ('', '', 'no-pictures', "don\'t generate pictures"),
   ('', '', 'read-lys', "don't write ly files."),
-  ('FILE', 'o', 'outname', 'filename main output file'),
-  ('FILE', '', 'outdir', "where to place generated files"),
+  ('FILE', 'o', 'outname', 'prefix for filenames'),
   ('', 'v', 'version', 'print version information' ),
-  ('', 'h', 'help', 'print help'),
+  ('PREF', '',  'dep-prefix', 'prepend PREF before each -M dependency'),
+  ('FILE', '', 'outdir', "where to place generated files"),
   ]
 
 # format specific strings, ie. regex-es for input, and % strings for output
@@ -150,16 +194,16 @@ re_dict = {
                  'option-sep' : ', *',
                  'header': r"""\\documentclass(\[.*?\])?""",
                  'preamble-end': '\\\\begin{document}',
-                 'verbatim': r"""(?s)(?P<code>\\begin{verbatim}.*?\\end{verbatim})""",
-                 'verb': r"""(?P<code>\\verb(?P<del>.).*?(?P=del))""",
+                 'verbatim': r"""(?s)\\begin{verbatim}(?P<code>.*?)\\end{verbatim}""",
+                 'verb': r"""\\verb(.)(?P<code>.*?)\1""",
                  'mudela-file': r'\\mudelafile(\[(?P<options>.*?)\])?\{(?P<filename>.+)}',
-                 'mudela' : '(?m)\\\\mudela(\[(?P<options>.*?)\])?{(?P<code>.*?)}',
-                 #'mudela-block': r"""(?m)^[^%]*?\\begin(\[(?P<options>.*?)\])?{mudela}(?P<code>.*?)\\end{mudela}""",
+                 'mudela' : '\\\\mudela(\[(?P<options>.*?)\])?{(?P<code>.*?)}',
                  'mudela-block': r"""(?s)\\begin(\[(?P<options>.*?)\])?{mudela}(?P<code>.*?)\\end{mudela}""",
+                 'interesting-cs': '\\\\(chapter|section|twocolumn|onecolumn)',
                  'def-post-re': r"""\\def\\postMudelaExample""",
                  'def-pre-re': r"""\\def\\preMudelaExample""",           
                  'intertext': r',?\s*intertext=\".*?\"',
-                 'ignore': r"(?m)(?P<code>%.*?^)",
+                 'ignore': no_match,
                  'numcols': r"(?P<code>\\(?P<num>one|two)column)",
                  },
        
@@ -169,13 +213,14 @@ re_dict = {
                 'header': no_match,
                 'preamble-end': no_match,
                 'verbatim': r"""(?s)(?P<code>@example\s.*?@end example\s)""",
-                'verb': r"""(?P<code>@code{.*?})""",
+                'verb': r"""@code{(?P<code>.*?)}""",
                 'mudela-file': '@mudelafile(\[(?P<options>.*?)\])?{(?P<filename>[^}]+)}',
                 'mudela' : '@mudela(\[(?P<options>.*?)\])?{(?P<code>.*?)}',
                 'mudela-block': r"""(?s)@mudela(\[(?P<options>.*?)\])?\s(?P<code>.*?)@end mudela\s""",
+                'interesting-cs': r"""[\\@](chapter|section)""",
                  'option-sep' : ', *',
                  'intertext': r',?\s*intertext=\".*?\"',
-                 'ignore': r"(?s)(?P<code>@ignore\s.*?@end ignore)\s",
+                 'ignore': r"(?s)@ignore\s(.*?)@end ignore\s",
                  'numcols': no_match,
                 }
        }
@@ -351,7 +396,7 @@ def find_file (name):
                return ''
 
 def do_ignore(match_object):
-       return [('ignore', match_object.group('code'))]
+       return []
 
 def make_verbatim(match_object):
        return [('verbatim', match_object.group('code'))]
@@ -423,9 +468,7 @@ def chop_chunks(chunks, re_name, func):
                     str = ''
                 else:
                     newchunks.append (('input', str[:m.start (0)]))
-                    #newchunks.extend(func(m))
-                   # python 1.5 compatible:
-                   newchunks = newchunks + func(m)
+                    newchunks.extend(func(m))
                     str = str [m.end(0):]
         else:
             newchunks.append(c)
@@ -450,6 +493,7 @@ def read_doc_file (filename):
        # we have to check for verbatim before doing include,
        # because we don't want to include files that are mentioned
        # inside a verbatim environment
+       chunks = chop_chunks(chunks, 'ignore', do_ignore)
        chunks = chop_chunks(chunks, 'verbatim', make_verbatim)
        chunks = chop_chunks(chunks, 'verb', make_verb)
        #ugh fix input
@@ -458,8 +502,25 @@ def read_doc_file (filename):
        return chunks
 
 
-taken_file_names = {}
-def schedule_mudela_block (chunk, extra_opts):
+def advance_counters (counter, str):
+       """Advance chap/sect counters,
+       Return the new counter tuple
+       """
+       (chapter, section, count) = counter
+       while str:
+               m = get_re ('interesting-cs').search(str)
+               if not m:
+                       break
+               str = str[m.end(0):]
+               g = m.group (1)
+               if g == 'chapter':#ugh use dict
+                       (chapter, section, count)  = (chapter + 1, 0, 0)
+               elif g == 'section':
+                       (section, count)  = (section + 1, 0)
+       return (chapter, section, count)
+
+taken_file_names = []
+def schedule_mudela_block (basename, chunk, extra_opts):
        """Take the body and options from CHUNK, figure out how the
        real .ly should look, and what should be left MAIN_STR (meant
        for the main file).  The .ly is written, and scheduled in
@@ -478,16 +539,15 @@ def schedule_mudela_block (chunk, extra_opts):
        assert type == 'mudela'
        opts = opts +  extra_opts
        file_body = compose_full_body (body, opts)
-       basename = `abs(hash (file_body))`
+       if __main__.g_use_hash:
+               basename = `abs(hash (file_body))`
        for o in opts:
                m = re.search ('filename="(.*?)"', o)
                if m:
-                       basename = m.group (1)
-                       if not taken_file_names.has_key(basename):
-                           taken_file_names[basename] = 0
-                       else:
-                           taken_file_names[basename] = taken_file_names[basename] + 1
-                           basename = basename + "-%i" % taken_file_names[basename]
+                       basename = m.group (1)#ugh add check if more than
+                       #one file has the same name
+                       assert basename not in taken_file_names
+                       taken_file_names.append(basename)
        # writes the file if necessary, returns true if it was written
        if not g_read_lys:
                update_file(file_body, os.path.join(g_outdir, basename) + '.ly')
@@ -527,11 +587,16 @@ def schedule_mudela_block (chunk, extra_opts):
        return ('mudela', newbody, opts, todo, basename)
 
 def process_mudela_blocks(outname, chunks, global_options):#ugh rename
+       (chap,sect,count) = (0,0,0)
        newchunks = []
        # Count sections/chapters.
        for c in chunks:
-               if c[0] == 'mudela':
-                       c = schedule_mudela_block (c, global_options)
+               if c[0] == 'input':
+                       (chap,sect,count) = advance_counters((chap,sect,count), c[1])
+               elif c[0] == 'mudela':
+                       base = '%s-%d.%d.%d' % (outname, chap, sect, count)
+                       count = count + 1
+                       c = schedule_mudela_block (base, c, global_options)
                elif c[0] == 'numcols':
                        __main__.g_num_cols = c[2]
                newchunks.append (c)
@@ -716,9 +781,8 @@ def do_file(input_filename):
        chunks = chop_chunks(chunks, 'mudela', make_mudela)
        chunks = chop_chunks(chunks, 'mudela-file', make_mudela_file)
        chunks = chop_chunks(chunks, 'mudela-block', make_mudela_block)
-       #for c in chunks: print c, "\n"
-       chunks = chop_chunks(chunks, 'ignore', do_ignore)
        chunks = chop_chunks(chunks, 'numcols', do_columns)
+       #for c in chunks: print c, "\n"
        global_options = scan_preamble(chunks[0][1])
        chunks = process_mudela_blocks(my_outname, chunks, global_options)
        # Do It.
@@ -741,7 +805,8 @@ def do_file(input_filename):
        sys.stderr.write ("Writing `%s'\n" % foutn)
        fout = open (foutn, 'w')
        for c in chunks:
-               fout.write (c[1])
+               #if c[1] is not None:
+                       fout.write (c[1])
        fout.close ()
 
        if do_deps:
@@ -763,10 +828,11 @@ for opt in options:
 
        if o == '--include' or o == '-I':
                include_path.append (a)
-       elif o == '--version' or o == '-v':
+       elif o == '--version':
                print_version ()
                sys.exit  (0)
-       elif o == '--format' or o == '-f':
+
+       elif o == '--format' or o == '-o':
                __main__.format = a
        elif o == '--outname' or o == '-o':
                if len(files) > 1:
@@ -778,7 +844,7 @@ for opt in options:
                help ()
        elif o == '--no-lily' or o == '-n':
                __main__.g_run_lilypond = 0
-       elif o == '--dependencies' or o == '-M':
+       elif o == '--dependencies':
                do_deps = 1
        elif o == '--default-music-fontsize':
                default_music_fontsize = string.atoi (a)
@@ -790,6 +856,9 @@ for opt in options:
        elif o == '--force-mudela-fontsize':
                print "--force-mudela-fontsize is deprecated, use --default-mudela-fontsize"
                g_force_mudela_fontsize = string.atoi(a)
+
+       elif o == '--init':
+               initfile =  a
        elif o == '--dep-prefix':
                g_dep_prefix = a
        elif o == '--no-pictures':
@@ -808,6 +877,10 @@ if g_outdir:
 for input_filename in files:
        do_file(input_filename)
        
+
+
+t2 = time.clock()
+print "Time:", t2-t1
 #
 # Petr, ik zou willen dat ik iets zinvoller deed,
 # maar wat ik kan ik doen, het verandert toch niets?