---- ../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.
* Added configure messages for metapost checking.
+1.3.81
+======
1.3.80.gp1
==========
after a double flat sign is automatically prepended with a
natural sign.
-@mudelafile{double-single-acc.ly}
+@mudelafile{accidental-single-double.ly}
@section Stems
\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
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
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''
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
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
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.
--- /dev/null
+#!@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
+
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
# 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
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"
## 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
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
## 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; }
# 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
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*
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
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
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
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. */
; 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
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
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
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);
}
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
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. */
; 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
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. */
; 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
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. */
; 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
# 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
# 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
--- /dev/null
+
+
+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
+ }
+ >
+}
+++ /dev/null
-
-
-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
- >
-}
\popproperty #'( ... ) #'symbolA
\popproperty #'( ... ) #'symbolB
-
-
-
-
the syntax isn't likely to stay, so it is advisable to
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
+}
}
}
* tremolo
+* lyrics.
+
%}
\version "1.3.59";
*/
#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;
}
{
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;
}
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
{
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 ();
};
&& 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);
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 ()
{
}
////////////////////////////////////////////////////////
-
-// 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"
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)
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 () : "";
#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:
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);
+}
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)
{
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;
}
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);
typeset_element (e);
}
+void
+Break_align_engraver::do_removal_processing ()
+{
+ column_alist_ = SCM_EOL;
+}
+
void
Break_align_engraver::do_pre_move_processing ()
{
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
{
#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_;
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;
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;
}
{
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);
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 ();
}
}
}
}
-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);
}
-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.
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"
}
-
-DEFAULT_PRINT(Translator_group);
DEFAULT_PRINT(Score);
DEFAULT_PRINT(Music_output_def);
return String (#Class); \
}
-
-DUMMY_STR(Translator_group);
DUMMY_STR(Score);
DUMMY_STR(Music_output_def);
DUMMY_STR(Duration);
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);
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*);
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);
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);
#include "smobs.hh"
-class Translator_group_identifier;
class Output_def_identifier;
class Score_identifier;
class Duration_identifier;
void error (String) const;
String str () const;
- IDACCESSOR(Translator_group)
IDACCESSOR(Music_output_def)
IDACCESSOR(Score)
IDACCESSOR(Duration)
}\
-DECLARE_ID_CLASS(Translator_group);
DECLARE_ID_CLASS(Duration);
DECLARE_ID_CLASS(Score);
DECLARE_ID_CLASS(Music_output_def);
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);
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.
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);
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
virtual void construct_children () ;
virtual Moment next_moment () const;
virtual bool ok () const;
- virtual Music *get_next_music ();
protected:
virtual void do_print () const;
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);
class Push_translation_property : public Music
{
public:
+ VIRTUAL_COPY_CONS(Music);
};
/**
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
#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);
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);
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
#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_;
VIRTUAL_COPY_CONS(Translator);
Translator (Translator const &);
Translator ();
- virtual ~Translator ();
Translator_group * daddy_trans_l_ ;
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.
*/
PROCESSED_REQS,
ACKED_REQS,
MOVE_DONE
- } status;
+ } status_; // junkme
+protected:
/*
@see{try_request}
void add_translator (Translator*trans_p);
Translator*get_translator_l (String s);
-
+Translator *unsmob_translator (SCM);
#endif // TRANSLATOR_HH
/**
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);
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();
};
+void
+Key_engraver::do_removal_processing ()
+{
+ old_accs_ = SCM_EOL; // unprotect can be called from dtor.
+}
+
Key_engraver::Key_engraver ()
{
keyreq_l_ = 0;
#include "identifier.hh"
#include "version.hh"
#include "mudela-version.hh"
-
+#include "translator-group.hh"
void strip_trailing_white (String&);
void strip_leading_white (String&);
} 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;
#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);
*/
}
+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)
{
-/*=========================================================================================*/
-
-/** 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 ();
-}
#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"
Mark_engraver ();
protected:
Item* text_p_;
- Protected_scm staffs_;
protected:
virtual void do_pre_move_processing ();
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_;
};
{
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
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))
{
{
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;
}
return 0;
}
-Music*
-Music_iterator::get_next_music ()
-{
- return 0;
-}
{
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);
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 ();
{
return child_iter_p_->try_music (m);
}
-
-
-Music*
-Music_wrapper_iterator::get_next_music ()
-{
- return child_iter_p_->get_next_music ();
-}
%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
$$ = (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 ();
;
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 {
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);
}
;
#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"
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
{
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)
{
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);
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 ())
{
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 ();
+ }
}
}
+
+
+
+
+
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);
}
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
#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
{
/*
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))
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);
}
{
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);
}
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.
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;
Score_performer::announce_element (Audio_element_info info)
{
announce_info_arr_.push (info);
- info.origin_trans_l_arr_.push (this);
+
/*
huh?
}
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 ()));
{
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;
-}
--- /dev/null
+#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 ();
+}
--- /dev/null
+ /*
+ 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);
+}
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 *
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;
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));
{
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;
{
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;
}
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.
+ */
}
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);
bool
Translator_group::is_bottom_translator_b () const
{
- return !accepts_str_arr_.size ();
+ return accepts_name_list_ == SCM_EOL;
}
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 ();
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;
}
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_)
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);
+}
#include "translator-group.hh"
#include "moment.hh"
+#include "ly-smobs.icc"
char const*
Translator::name() const
{
}
+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
void
Translator::add_processing ()
{
- if (status > ORPHAN)
+ if (status_ > ORPHAN)
return;
do_add_processing ();
- status = VIRGIN;
+ status_ = VIRGIN;
}
void
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);
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 ();
}
Translator::pre_move_processing ()
{
do_pre_move_processing ();
- status = CREATION_INITED;
+ status_ = CREATION_INITED;
}
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);
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;
}
- }
}
\type "Engraver_group_engraver";
\name Staff ;
\consists "Output_property_engraver";
- barAuto = ##t
- voltaVisibility = ##t
Generic_property_list = #generic-staff-properties
\consists "Property_engraver";
% 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";
\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 }
\consists "System_start_delimiter_engraver";
systemStartDelimiterGlyph = #'bracket
-
-
\accepts "Staff";
\accepts "RhythmicStaff";
\accepts "GrandStaff";
\accepts "PianoStaff";
-
-
\accepts "Lyrics";
\accepts "ChordNames";
}
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";
\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.
\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";
\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;
};
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,
(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)
(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)
(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))
(breakable . #t)
(interfaces . (mark-interface))
(visibility-lambda . ,end-of-line-invisible)
+ (padding . 4.0)
)
basicMultiMeasureRestProperties = #`(
(spacing-procedure . ,Multi_measure_rest::set_spacing_rods)
(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))
(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)
)
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)
(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))
)
(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 }
OrchestralScoreContext= \translator {
\ScoreContext
- barScriptPadding = #2.0 % dimension \pt
- markScriptPadding = #4.0
-
- \consists "Mark_engraver";
};
\translator {
\name NoteNames;
\consistsend "Axis_group_engraver";
\consists "Note_name_engraver";
+ \consists "Separating_line_group_engraver";
}
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
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
\consists "Script_engraver";
\consists "Script_column_engraver";
\consists "Rhythmic_column_engraver";
-%% \consists "Slur_engraver";
+ \consists "Slur_engraver";
\consists "Tie_engraver";
}
\translator {
\consists "Script_engraver";
\consists "Script_column_engraver";
\consists "Rhythmic_column_engraver";
-%% \consists "Slur_engraver";
+ \consists "Slur_engraver";
\consists "Tie_engraver";
}
\translator {
(define generic-All-properties
(cons 'all
- (list (list 'fontSize number? 'fontsize))))
+ (list (list 'fontSize number? 'font-size))))
(define generic-notehead-properties
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 ():
#
# 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@'
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):
self.finale = []
+ def __str__ (self):
+ return `self.finale `
+
def set_timesig (self, finale):
(beats, fdur) = finale
(log, dots) = EDU_to_duration (fdur)
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])
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
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):
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:
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
= 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
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
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:
continue
mno = 1
for m in st.measures[1:]:
+ if not m:
+ continue
+
m.global_measure = self.measures[mno]
m.calculate()
def __str__ (self):
- return self.dump ()
+ return 'ETF FILE %s %s' % (self.measures, self.entries)
def unthread_entries (self):
self.chords = [None]
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')
#!@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
import __main__
+initfile = ''
+
+
program_version = '@TOPLEVEL_VERSION@'
+if program_version == '@' + 'TOPLEVEL_VERSION' + '@':
+ program_version = '1.3.69-very-unstable'
include_path = [os.getcwd()]
g_num_cols = 1
format = ''
g_run_lilypond = 1
+g_use_hash = 1
no_match = 'a\ba'
default_music_fontsize = 16
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
'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)",
},
'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,
}
}
return ''
def do_ignore(match_object):
- return [('ignore', match_object.group('code'))]
+ return []
def make_verbatim(match_object):
return [('verbatim', match_object.group('code'))]
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)
# 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
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
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')
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)
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.
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:
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:
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)
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':
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?