From: Joe Neeman Date: Sun, 7 Jan 2007 09:25:53 +0000 (+0200) Subject: Merge branch 'master' of git+ssh://jneem@git.sv.gnu.org/srv/git/lilypond X-Git-Tag: release/2.11.11-1~45^2~7 X-Git-Url: https://git.donarmstrong.com/?p=lilypond.git;a=commitdiff_plain;h=e42585017a01fd02f6353b994cf0c87b03a7bb2e;hp=eea610885f6fb119644954939af8eb08450639f6 Merge branch 'master' of git+ssh://jneem@git.sv.gnu.org/srv/git/lilypond --- diff --git a/.gitignore b/.gitignore index 8971860688..f69a725cab 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,5 @@ out-scons out-cov tags test-output-distance +config-*.hh +config-*.make diff --git a/Documentation/topdocs/INSTALL.texi b/Documentation/topdocs/INSTALL.texi index 52d8d8cf76..616eed6010 100644 --- a/Documentation/topdocs/INSTALL.texi +++ b/Documentation/topdocs/INSTALL.texi @@ -116,7 +116,7 @@ software @item @uref{http://www.freetype.org/,FontConfig} (version 2.2). @item @uref{http://www.pango.org/,Pango} (version 1.12 or newer). @item @uref{http://www.gnu.org/software/guile/guile.html,GUILE} -(version 1.8.2 or newer), or patch 1.8.x with +(version 1.8.2 or newer), or patch 1.8.1 with @uref{http://lilypond.org/vc/gub.darcs/patches/guile-1.8-rational.patch}. @item @uref{http://www.python.org,Python} (version 2.4 or newer). @item @uref{http://www.ghostscript.com,Ghostscript} (version 8.15 or @@ -157,6 +157,45 @@ make out=www web-install @end example @end quotation +@section Testing LilyPond + +LilyPond comes with an extensive suite that excercises the entire +program. This suite can be used to automatically check the impact of a +change. This is done as follows + +@example + make test-baseline + @emph{## apply your changes, compile} + make check +@end example + +This will leave an HTML page @file{out/test-results/index.html}. This +page shows all the important differences that your change introduced, +whether in the layout, MIDI, performance or error reporting. + +To rerun tests, use + +@example + make test-redo @emph{## redo files differing from baseline} + make test-clean @emph{## remove all test results} +@end example + +@noindent +and then run @code{make check} again. + +For tracking memory usage as part of this test, you will need GUILE +CVS; especially the following patch: +@uref{http://lilypond.org/vc/gub.darcs/patches/guile-1.9-gcstats.patch}. + +For checking the coverage of the test suite, do the following + +@example + ./buildscripts/build-coverage.sh + @emph{# uncovered files, least covered first} + python ./buildscripts/coverage.py --summary out-cov/*.cc + @emph{# consecutive uncovered lines, longest first} + python ./buildscripts/coverage.py --uncovered out-cov/*.cc +@end example @section Building LilyPond diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index df38af90cc..f37f6ac496 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -67,6 +67,10 @@ which scares away people. @end ignore +@item All @code{\score}s in a lilypond-book fragment are now inserted +into the document. Also, toplevel markups don't result in an entire +page. + @item Alterations (such as a sharp and flat) may now be arbitrary fractions. This allows some forms of microtonal music. For example, Turkish makam music uses 1/9th tone alterations. diff --git a/Documentation/user/advanced-notation.itely b/Documentation/user/advanced-notation.itely index 1c19f5c0a7..2e4463ba15 100644 --- a/Documentation/user/advanced-notation.itely +++ b/Documentation/user/advanced-notation.itely @@ -1702,6 +1702,11 @@ see those sections of the documentation. @node Polymetric notation @subsection Polymetric notation +@cindex double time signatures +@cindex signatures, polymetric +@cindex polymetric signatures +@cindex meter, polymetric + Double time signatures are not supported explicitly, but they can be faked. In the next example, the markup for the time signature is created with a markup text. This markup text is inserted in the @@ -1713,7 +1718,7 @@ created with a markup text. This markup text is inserted in the tsMarkup =\markup { \override #'(baseline-skip . 2) \number { \column { "2" "4" } - \lower #1 "+" + \vcenter "+" \bracket \column { "5" "8" } } } diff --git a/Documentation/user/basic-notation.itely b/Documentation/user/basic-notation.itely index aeeb5ed9d4..1e1a59a874 100644 --- a/Documentation/user/basic-notation.itely +++ b/Documentation/user/basic-notation.itely @@ -3039,6 +3039,10 @@ declared within a @code{Voice} context. @node Repeat syntax @subsection Repeat syntax +@cindex volta +@cindex prima volta +@cindex seconda volta + LilyPond has one syntactic construct for specifying different types of repeats. The syntax is diff --git a/Documentation/user/cheatsheet.itely b/Documentation/user/cheatsheet.itely index ced3e2efd0..634026393f 100644 --- a/Documentation/user/cheatsheet.itely +++ b/Documentation/user/cheatsheet.itely @@ -115,7 +115,7 @@ c c, @tab @lilypond[fragment,relative=2] \set Score.timing = ##f -\override Staff.TimeSignature #'break-visibility = #all-invisible +\set Staff.implicitTimeSignatureVisibility = #all-invisible \set Staff.autoBeaming = ##f c( d e) @end lilypond @@ -126,7 +126,7 @@ c( d e) @tab @lilypond[fragment,relative=2] \set Score.timing = ##f -\override Staff.TimeSignature #'break-visibility = #all-invisible +\set Staff.implicitTimeSignatureVisibility = #all-invisible \set Staff.autoBeaming = ##f c\( c( d) e\) @end lilypond @@ -137,7 +137,7 @@ c\( c( d) e\) @tab @lilypond[fragment,relative=2] \set Score.timing = ##f -\override Staff.TimeSignature #'break-visibility = #all-invisible +\set Staff.implicitTimeSignatureVisibility = #all-invisible \set Staff.autoBeaming = ##f a8-[ b-] @end lilypond @@ -156,7 +156,7 @@ a8-[ b-] @tab articulations @tab @lilypond[fragment,relative=2] -\override Staff.TimeSignature #'break-visibility = #all-invisible +\set Staff.implicitTimeSignatureVisibility = #all-invisible c-> c-. @end lilypond @@ -165,7 +165,7 @@ c-> c-. @tab dynamics @tab @lilypond[fragment,relative=2] -\override Staff.TimeSignature #'break-visibility = #all-invisible +\set Staff.implicitTimeSignatureVisibility = #all-invisible c\mf c\sfz @end lilypond @@ -175,7 +175,7 @@ c\mf c\sfz @tab @lilypond[fragment,relative=2] \set Score.timing = ##f -\override Staff.TimeSignature #'break-visibility = #all-invisible +\set Staff.implicitTimeSignatureVisibility = #all-invisible \set Staff.autoBeaming = ##f a\< a a\! @end lilypond @@ -185,7 +185,7 @@ a\< a a\! @tab @lilypond[fragment,relative=2] \set Score.timing = ##f -\override Staff.TimeSignature #'break-visibility = #all-invisible +\set Staff.implicitTimeSignatureVisibility = #all-invisible \set Staff.autoBeaming = ##f a\> a a\! @end lilypond diff --git a/Documentation/user/music-glossary.tely b/Documentation/user/music-glossary.tely index 55e07d2b2a..e5967140c3 100644 --- a/Documentation/user/music-glossary.tely +++ b/Documentation/user/music-glossary.tely @@ -1348,6 +1348,7 @@ music of the baroque era, has been one of the most popular polyphonic composition methods. @lilypond[fragment,staffsize=12,line-width=13.0\cm] +\set Score.implicitTimeSignatureVisibility = #all-invisible \override Score.TimeSignature #'break-visibility = #all-invisible \context PianoStaff << \context Staff = SA \relative c' { @@ -3270,8 +3271,8 @@ subject. @lilypond[line-width=13.0\cm] \score{ \relative c'' { + \set Score.implicitTimeSignatureVisibility = #all-invisible \override Score.TimeSignature #'break-visibility = #all-invisible - %\override Score.TextScript #'font-style = #'large \time 4/4 \key g \major \partial 8 g16\startGroup fis | diff --git a/Documentation/user/non-music.itely b/Documentation/user/non-music.itely index 16ed517ad8..0743851592 100644 --- a/Documentation/user/non-music.itely +++ b/Documentation/user/non-music.itely @@ -783,9 +783,20 @@ to a score, for example, @} @end example -The tempo is specified using the @code{\tempo} command. In this -example the tempo of quarter notes is set to 72 beats per minute. +The tempo can be specified using the @code{\tempo} command within the +actual music, see @ref{Metronome marks}. An alternative, which does not +result in a metronome mark in the printed score, is shown in the example +above. In this example the tempo of quarter notes is set to 72 beats per +minute. +This kind of tempo +specification can not take dotted note lengths as an argument. In this +case, break the dotted notes into smaller units. For example, a tempo +of 90 dotted quarter notes per minute can be specified as 270 eighth +notes per minute +@example +tempoWholesPerMinute = #(ly:make-moment 270 8) +@end example If there is a @code{\midi} command in a @code{\score}, only MIDI will be produced. When notation is needed too, a @code{\layout} block must diff --git a/Documentation/user/point-and-click.itely b/Documentation/user/point-and-click.itely deleted file mode 100644 index 8d74e79a68..0000000000 --- a/Documentation/user/point-and-click.itely +++ /dev/null @@ -1,81 +0,0 @@ -@node Point and click -@appendix Point and click -@cindex point and click - - -Point and click lets you find notes in the input by clicking on them -in the PDF viewer. This makes it easier to find input that causes -some error in the sheet music. - -When this functionality is active, LilyPond adds hyperlinks to the PDF -file. These hyperlinks are sent to the web-browser, which opens a -text-editor with the cursor in the right place. - -To make this chain work, you should configure your PDF viewer to -follow hyperlinks using the @file{lilypond-invoke-editor} script -supplied with LilyPond. - -For Xpdf on Unix, the following should be present in -@file{xpdfrc}@footnote{On unix, this file is found either in -@file{/etc/xpdfrc} or as @file{.xpdfrc} in your home directory.} - -@example -urlCommand "lilypond-invoke-editor %s" -@end example - -The program @file{lilypond-invoke-editor} is a small helper -program. It will invoke an editor for the special @code{textedit} -URIs, and run a web browser for others. It tests the environment -variable @code{EDITOR} for the following patterns, - -@table @code -@item emacs - this will invoke -@example -emacsclient --no-wait +@var{line}:@var{column} @var{file} -@end example -@item vim - this will invoke -@example -gvim --remote +:@var{line}:norm@var{char} @var{file} -@end example - -@item nedit -this will invoke -@example - nc -noask +@var{line} @var{file}' -@end example -@end table - -The environment variable @code{LYEDITOR} is used to override this. It -contains the command line to start the editor, where @code{%(file)s}, -@code{%(column)s}, @code{%(line)s} is replaced with the file, column -and line respectively. The setting - -@example -emacsclient --no-wait +%(line)s:%(column)s %(file)s -@end example - -@noindent -for @code{LYEDITOR} is equivalent to the standard emacsclient -invocation. - - -@cindex file size, output - -The point and click links enlarge the output files significantly. For -reducing the size of PDF and PS files, point and click may be switched -off by issuing - -@example -#(ly:set-option 'point-and-click #f) -@end example - -@noindent -in a @file{.ly} file. Alternately, you may pass this as an command-line -option - -@example -lilypond -dno-point-and-click file.ly -@end example - diff --git a/GNUmakefile.in b/GNUmakefile.in index 37fb44abf4..4eea5f1791 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -35,7 +35,6 @@ include $(depth)/make/stepmake.make # # suggested settings # -# CHECK_SOURCE= # LILYPOND_JOBS= -djob-count=X ## for SMP/Multicore machine # include local.make @@ -101,14 +100,17 @@ local-WWW-post: rm -rf $(outdir)/offline-root $(PYTHON) $(buildscript-dir)/www_post.py $(PACKAGE_NAME) $(TOPLEVEL_VERSION) $(buildscript-dir) $(outdir) "$(WEB_TARGETS)" + tree-prefix = $(outdir) tree-bin = $(tree-prefix)/bin tree-lib = $(tree-prefix)/lib tree-share = $(tree-prefix)/share -tree-share-prefix = $(tree-share)/lilypond/$(TOPLEVEL_VERSION) -tree-share-prefix-current = $(tree-share)/lilypond/current -tree-lib-prefix = $(tree-lib)/lilypond/$(TOPLEVEL_VERSION) -tree-lib-prefix-current = $(tree-lib)/lilypond/current + +# Don't put version numbers here. During development +# they make no sense, and cause EPS files to become invalid. + +tree-share-prefix = $(tree-share)/lilypond/current +tree-lib-prefix = $(tree-lib)/lilypond/current C_DIRS = flower lily c-clean: @@ -133,9 +135,7 @@ $(tree-share-prefix)/lilypond-force link-tree: GNUmakefile $(outdir)/VERSION cd $(top-build-dir)/$(outbase) && rm -rf bin lib share mkdir -p $(tree-bin) mkdir -p $(tree-share-prefix) - ln -s $(TOPLEVEL_VERSION) $(tree-share-prefix-current) mkdir -p $(tree-lib-prefix) - ln -s $(TOPLEVEL_VERSION) $(tree-lib-prefix-current) mkdir -p $(tree-share-prefix)/elisp mkdir -p $(tree-share-prefix)/fonts mkdir -p $(tree-share-prefix)/fonts/otf @@ -206,15 +206,44 @@ $(config_h): config.hh.in @false -test-clean: - $(MAKE) -C input/regression/ out=test clean +################################################################ +# testing + +RESULT_DIR=$(top-build-dir)/out/test-results +OUT_TEST=test + test: - $(MAKE) -C input/regression/ out=test LILYPOND_BOOK_LILYPOND_FLAGS="--backend=eps --formats=ps $(LILYPOND_JOBS) -dinclude-eps-fonts -dgs-load-fonts --header=texidoc -I $(top-src-dir)/input/manual -ddump-profile -dcheck-internal-types -ddump-signatures -danti-alias-factor=1" LILYPOND_BOOK_VERBOSE= out-test/collated-files.html + rm -f input/regression/out-$(OUT_TEST)/collated-files.html + @echo -en 'For tracking crashes: use\n\n\t' + @echo 'grep sourcefilename `grep -L systems.texi input/regression/out-test/*log|sed s/log/ly/g`' + @echo + if test -d .git ; then \ + echo -e 'HEAD is:\n\n\t' ; \ + git log --max-count=1 --pretty=oneline ;\ + echo -e '\n\n\n' ; \ + git diff ; \ + fi > input/regression/out-test/tree.gittxt + $(MAKE) -C input/regression/ out=$(OUT_TEST) LILYPOND_BOOK_LILYPOND_FLAGS="--backend=eps --formats=ps $(LILYPOND_JOBS) -dseparate-log-files -dinclude-eps-fonts -dgs-load-fonts --header=texidoc -I $(top-src-dir)/input/manual -ddump-profile -dcheck-internal-types -ddump-signatures -danti-alias-factor=1" LILYPOND_BOOK_VERBOSE= out-$(OUT_TEST)/collated-files.html @find input ly -name '*.ly' -print |grep -v 'out.*/' | xargs grep '\\version' -L | grep -v "standard input" |sed 's/^/**** Missing version: /g' -RESULT_DIR=$(top-build-dir)/out/test-results/ + +test-baseline: test + rm -rf input/regression/out-test-baseline + mv input/regression/out-test input/regression/out-test-baseline + local-check: test rm -rf $(RESULT_DIR) mkdir -p $(RESULT_DIR) - $(PYTHON) $(buildscript-dir)/output-distance.py --create-images --output-dir $(RESULT_DIR) $(CHECK_SOURCE) input/regression/out-test/ + $(PYTHON) $(buildscript-dir)/output-distance.py --create-images --output-dir $(RESULT_DIR) input/regression/out-test-baseline input/regression/out-test/ + + +test-redo: + for a in `cat $(RESULT_DIR)/changed.txt` ; do \ + echo removing $$a* ; \ + rm -f $$a* ;\ + done + $(MAKE) check + +test-clean: + $(MAKE) -C input/regression/ out=$(OUT_TEST) clean diff --git a/THANKS b/THANKS index d74eb3abd7..c15d646d2b 100644 --- a/THANKS +++ b/THANKS @@ -10,6 +10,7 @@ Jan Nieuwenhuizen - Core development Joe Neeman - Core development Graham Percival - Documentation Editor and Bug Meister Mats Bengtsson - Support Guru +John Mandereau - Translation Meister CONTRIBUTORS @@ -29,6 +30,7 @@ Carl Sorensen Christian Hitz David Bobroff Eduardo Vieira +Georg Dummer Jay Anderson Jean-Marie Mouchel Kazuhiro Suzuki diff --git a/VERSION b/VERSION index 1a4814ec83..19b908e85e 100644 --- a/VERSION +++ b/VERSION @@ -1,6 +1,6 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=11 -PATCH_LEVEL=7 +PATCH_LEVEL=10 MY_PATCH_LEVEL= diff --git a/buildscripts/add_html_footer.py b/buildscripts/add_html_footer.py index 2935d456cf..a7bc7e11d9 100644 --- a/buildscripts/add_html_footer.py +++ b/buildscripts/add_html_footer.py @@ -125,9 +125,14 @@ def do_file (prefix, lang_ext, target, header, footer, pages_dict, out_root, nam # Strip .html, .png suffix for auto language selection (content # negotiation). The menu must keep the full extension, so do # this before adding the menu. - page_flavors[file_name] = re.sub ( - '''(href|src)=[\'"]([^/][.]*[^.:\'"]*)(.html|.png)(#[^"\']*|)[\'"]''', - '\\1="\\2\\4"', s) + # Don't strip .html suffix for documentation index because of + # lilypond/ vs. lilypond.html conflict + if prefix == 'Documentation/out-www/index': + page_flavors[file_name] = s + else: + page_flavors[file_name] = re.sub ( + '''(href|src)=[\'"]([^/][.]*[^.:\'"]*)(.html|.png)(#[^"\']*|)[\'"]''', + '\\1="\\2\\4"', s) elif target == 'offline': if lang_ext == '': page_flavors[file_name] = s diff --git a/buildscripts/build-coverage.sh b/buildscripts/build-coverage.sh index 13a073188b..b238202c05 100755 --- a/buildscripts/build-coverage.sh +++ b/buildscripts/build-coverage.sh @@ -10,30 +10,46 @@ fi if test "$fresh" = "yes"; then - ./configure --enable-config=cov --disable-optimising - make conf=cov -j2 clean - perl -i~ -pe 's/-pipe /-fprofile-arcs -ftest-coverage -pipe /g' config-cov.make - perl -i~ -pe 's/ -ldl / -lgcov -ldl /g' config-cov.make + ./configure --enable-config=cov --disable-optimising \ + && make conf=cov -j2 clean \ + && perl -i~ -pe 's/-pipe /-fprofile-arcs -ftest-coverage -pipe /g' config-cov.make \ + && perl -i~ -pe 's/ -ldl / -lgcov -ldl /g' config-cov.make else find -name '*.gcda' -exec rm '{}' ';' fi +mkdir -p scripts/out-cov/ +touch scripts/out-cov/midi2ly.1 +make conf=cov -j2 && \ + make conf=cov test-clean OUT_TEST=testcov LILYPOND_JOBS= && \ + make conf=cov test OUT_TEST=testcov LILYPOND_JOBS= -make conf=cov -j2 -make conf=cov test-clean LILYPOND_JOBS= -make conf=cov test LILYPOND_JOBS= >& out-cov/test-run.log +if test "$?" != "0"; then + tail -100 out-cov/test-run.log + exit 1 +fi + +depth=../.. +resultdir=out/coverage-results -rm -rf out-cov -mkdir out-cov +rm -rf $resultdir +mkdir $resultdir +cd $resultdir -cd out-cov -ln ../lily/* . -ln ../lily/out-cov/*[ch] . +ln $depth/lily/* . +ln $depth/lily/out-cov/*[ch] . mkdir include -ln ../lily/include/* include/ -for a in *[cyl] +ln $depth/lily/include/* include/ +ln $depth/flower/include/* include/ +for a in *[cl] *.yy do - gcov -o ../lily/out-cov/ -p $a > $a.gcov-summary + gcov -o $depth/lily/out-cov/ -p $a > $a.gcov-summary done -python buildscripts/coverage.py +cat <>' > long-score.ly + +rm gmon.sum + +exe=$depth/out-prof/bin/lilypond + +## todo: figure out representative sample. +files="wtk1-fugue2 wtk1-fugue2 wtk1-fugue2 wtk1-fugue2 mozart-hrn-3 mozart-hrn-3 long-score" + + + +$exe -ddump-profile --formats=ps -I $depth/input/ -I $depth/input/mutopia/J.S.Bach/ \ + -I $depth/input/mutopia/W.A.Mozart/ \ + $files + + +for a in *.profile; do + echo $a + cat $a +done + +echo 'running gprof' +gprof $exe > profile + +exit 0 + + +## gprof -s takes forever. +for a in seq 1 3; do + for f in $files ; do + $exe -ddump-profile --formats=ps -I $depth/input/ -I $depth/input/mutopia/J.S.Bach/ \ + -I $depth/input/mutopia/W.A.Mozart/ \ + $f + + echo 'running gprof' + if test -f gmon.sum ; then + gprof -s $exe gmon.out gmon.sum + else + mv gmon.out gmon.sum + fi + done +done + +gprof $exe gmon.sum > profile diff --git a/buildscripts/coverage.py b/buildscripts/coverage.py index 62a68cb0bb..380e9e3075 100644 --- a/buildscripts/coverage.py +++ b/buildscripts/coverage.py @@ -2,37 +2,192 @@ import os import glob import re - -os.chdir ('out-cov') +import sys +import optparse #File 'accidental-engraver.cc' #Lines executed:87.70% of 252 -results = [] -for f in glob.glob ('*.gcov-summary'): - str = open (f).read () - m = re.search ("File '([^']+.cc)'\s*Lines executed:([0-9.]+)% of ([0-9]+)", str) +def summary (args): + results = [] + for f in args: + str = open (f).read () + m = re.search ("File '([^']+.cc)'\s*Lines executed:([0-9.]+)% of ([0-9]+)", str) - if m and '/usr/lib' in m.group (1): - continue - - if m: - cov = float (m.group (2)) - lines = int (m.group (3)) - pain = lines * (100.0 - cov) - file = m.group (1) - tup = (pain, locals ().copy()) + if m and '/usr/lib' in m.group (1): + continue + + if m: + cov = float (m.group (2)) + lines = int (m.group (3)) + pain = lines * (100.0 - cov) + file = m.group (1) + tup = (pain, locals ().copy()) + + results.append(tup) + + results.sort () + results.reverse() + + print 'files sorted by number of untested lines (decreasing)' + print + print '%5s (%6s): %s' % ('cov %', 'lines', 'file') + print '----------------------------------------------' + + for (pain, d) in results: + print '%(cov)5.2f (%(lines)6d): %(file)s' % d + +class Chunk: + def __init__ (self, range, coverage_count, all_lines, file): + assert coverage_count >= 0 + assert type (range) == type (()) + + self.coverage_count = coverage_count + self.range = range + self.all_lines = all_lines + self.file = file + + def length (self): + return self.range[1] - self.range[0] + + def text (self): + return ''.join ([l[2] for l in self.lines()]) + + def lines (self): + return self.all_lines[self.range[0]: + self.range[1]] + def widen (self): + self.range = (min (self.range[0] -1, 0), + self.range[0] +1) + def write (self): + print 'chunk in', self.file + for (c, n, l) in self.lines (): + cov = '%d' % c + if c == 0: + cov = '#######' + elif c < 0: + cov = '' + sys.stdout.write ('%8s:%8d:%s' % (cov, n, l)) + +def read_gcov (f): + ls = [] + + in_lines = [l for l in open (f).readlines ()] + (count_len, line_num_len) = tuple (map (len, in_lines[0].split( ':')[:2])) + + for l in in_lines: + c = l[:count_len].strip () + l = l[count_len+1:] + n = int (l[:line_num_len].strip ()) + + if n == 0: + continue + + if '#' in c: + c = 0 + elif c == '-': + c = -1 + else: + c = int (c) - results.append(tup) + l = l[line_num_len+1:] -results.sort () -results.reverse() + ls.append ((c,n,l)) + + return ls + +def get_chunks (ls, file): + chunks = [] + chunk = [] + + last_c = -1 + for (c, n, l) in ls: + if not (c == last_c or c < 0 and l != '}\n'): + if chunk and last_c >= 0: + nums = [n-1 for (n, l) in chunk] + chunks.append (Chunk ((min (nums), max (nums)+1), + last_c, ls, file)) + chunk = [] + + chunk.append ((n,l)) + if c >= 0: + last_c = c + + return chunks -print 'files sorted by number of untested lines (decreasing)' -print -print '%5s (%6s): %s' % ('cov %', 'lines', 'file') -print '----------------------------------------------' +def widen_chunk (ch, ls): + a -= 1 + b += 1 -for (pain, d) in results: - print '%(cov)5.2f (%(lines)6d): %(file)s' % d + return [(n, l) for (c, n, l) in ls[a:b]] + +def extract_chunks (file): + try: + ls = read_gcov (file) + except IOError, s : + print s + return [] + + return get_chunks (ls, file) + +def filter_uncovered (chunks): + def interesting (c): + if c.coverage_count > 0: + return False + + t = c.text() + for stat in ('warning', 'error', 'print', 'scm_gc_mark'): + if stat in t: + return False + return True + + return [c for c in chunks if interesting (c)] + + +def main (): + p = optparse.OptionParser (usage="usage coverage.py [options] files", + description="") + p.add_option ("--summary", + action='store_true', + default=False, + dest="summary") + + p.add_option ("--hotspots", + default=False, + action='store_true', + dest="hotspots") + + p.add_option ("--uncovered", + default=False, + action='store_true', + dest="uncovered") + + + (options, args) = p.parse_args () + + + if options.summary: + summary (['%s.gcov-summary' % s for s in args]) + + if options.uncovered or options.hotspots: + chunks = [] + for a in args: + chunks += extract_chunks ('%s.gcov' % a) + + if options.uncovered: + chunks = filter_uncovered (chunks) + chunks = [(c.length (), c) for c in chunks] + elif options.hotspots: + chunks = [((c.coverage_count, -c.length()), c) for c in chunks] + + + chunks.sort () + chunks.reverse () + for (score, c) in chunks: + c.write () + + + +if __name__ == '__main__': + main () diff --git a/buildscripts/output-distance.py b/buildscripts/output-distance.py index ec8b5d9e10..374f7695db 100644 --- a/buildscripts/output-distance.py +++ b/buildscripts/output-distance.py @@ -2,13 +2,12 @@ import sys import optparse import os +import math ## so we can call directly as buildscripts/output-distance.py me_path = os.path.abspath (os.path.split (sys.argv[0])[0]) sys.path.insert (0, me_path + '/../python/') - - -import safeeval +sys.path.insert (0, me_path + '/../python/out/') X_AXIS = 0 @@ -19,6 +18,38 @@ OUTPUT_EXPRESSION_PENALTY = 1 ORPHAN_GROB_PENALTY = 1 options = None +################################################################ +# system interface. +temp_dir = None +class TempDirectory: + def __init__ (self): + import tempfile + self.dir = tempfile.mkdtemp () + print 'dir is', self.dir + def __del__ (self): + print 'rm -rf %s' % self.dir + os.system ('rm -rf %s' % self.dir ) + def __call__ (self): + return self.dir + + +def get_temp_dir (): + global temp_dir + if not temp_dir: + temp_dir = TempDirectory () + return temp_dir () + +def read_pipe (c): + print 'pipe' , c + return os.popen (c).read () + +def system (c): + print 'system' , c + s = os.system (c) + if s : + raise Exception ("failed") + return + def shorten_string (s): threshold = 15 if len (s) > 2*threshold: @@ -34,6 +65,38 @@ def max_distance (x1, x2): return dist +def compare_png_images (old, new, dest_dir): + def png_dims (f): + m = re.search ('([0-9]+) x ([0-9]+)', read_pipe ('file %s' % f)) + + return tuple (map (int, m.groups ())) + + dest = os.path.join (dest_dir, new.replace ('.png', '.compare.jpeg')) + try: + dims1 = png_dims (old) + dims2 = png_dims (new) + except AttributeError: + ## hmmm. what to do? + system ('touch %(dest)s' % locals ()) + return + + dims = (min (dims1[0], dims2[0]), + min (dims1[1], dims2[1])) + + dir = get_temp_dir () + system ('convert -depth 8 -crop %dx%d+0+0 %s %s/crop1.png' % (dims + (old, dir))) + system ('convert -depth 8 -crop %dx%d+0+0 %s %s/crop2.png' % (dims + (new, dir))) + + system ('compare -depth 8 %(dir)s/crop1.png %(dir)s/crop2.png %(dir)s/diff.png' % locals ()) + + system ("convert -depth 8 %(dir)s/diff.png -blur 0x3 -negate -channel alpha,blue -type TrueColorMatte -fx 'intensity' %(dir)s/matte.png" % locals ()) + + system ("composite -quality 65 %(dir)s/matte.png %(new)s %(dest)s" % locals ()) + + +################################################################ +# interval/bbox arithmetic. + empty_interval = (INFTY, -INFTY) empty_bbox = (empty_interval, empty_interval) @@ -274,107 +337,219 @@ def read_signature_file (name): ################################################################ # different systems of a .ly file. -def read_pipe (c): - print 'pipe' , c - return os.popen (c).read () - -def system (c): - print 'system' , c - s = os.system (c) - if s : - raise Exception ("failed") - return - -def compare_png_images (old, new, dir): - def png_dims (f): - m = re.search ('([0-9]+) x ([0-9]+)', read_pipe ('file %s' % f)) - - return tuple (map (int, m.groups ())) - - dest = os.path.join (dir, new.replace ('.png', '.compare.jpeg')) - try: - dims1 = png_dims (old) - dims2 = png_dims (new) - except AttributeError: - ## hmmm. what to do? - system ('touch %(dest)s' % locals ()) - return - - dims = (min (dims1[0], dims2[0]), - min (dims1[1], dims2[1])) - system ('convert -depth 8 -crop %dx%d+0+0 %s crop1.png' % (dims + (old,))) - system ('convert -depth 8 -crop %dx%d+0+0 %s crop2.png' % (dims + (new,))) - - system ('compare -depth 8 crop1.png crop2.png diff.png') - - system ("convert -depth 8 diff.png -blur 0x3 -negate -channel alpha,blue -type TrueColorMatte -fx 'intensity' matte.png") - - system ("composite -quality 65 matte.png %(new)s %(dest)s" % locals ()) +hash_to_original_name = {} class FileLink: + def __init__ (self, f1, f2): + self._distance = None + self.file_names = (f1, f2) + def text_record_string (self): return '%-30f %-20s\n' % (self.distance (), self.name ()) - def distance (self): + def calc_distance (self): return 0.0 + def distance (self): + if self._distance == None: + self._distance = self.calc_distance () + + return self._distance + + def name (self): + base = os.path.basename (self.file_names[1]) + base = os.path.splitext (base)[0] + + base = hash_to_original_name.get (base, base) + base = os.path.splitext (base)[0] + return base + + def extension (self): + return os.path.splitext (self.file_names[1])[1] + + def link_files_for_html (self, dest_dir): + for f in self.file_names: + link_file (f, os.path.join (dest_dir, f)) + + def get_distance_details (self): return '' + + def get_cell (self, oldnew): + return '' + + def get_file (self, oldnew): + return self.file_names[oldnew] - def link_files_for_html (self, old_dir, new_dir, dest_dir): - pass + def html_record_string (self, dest_dir): + self.link_files_for_html (dest_dir) + + dist = self.distance() + + details = self.get_distance_details () + if details: + details_base = os.path.splitext (self.file_names[1])[0] + details_base += '.details.html' + fn = dest_dir + '/' + details_base + open (fn, 'w').write (details) + + details = '
(details)' % locals () - def write_html_system_details (self, dir1, dir2, dest_dir): - pass + cell1 = self.get_cell (0) + cell2 = self.get_cell (1) + + name = self.name () + self.extension () + file1 = self.get_file (0) + file2 = self.get_file (1) - def html_record_string (self, old_dir, new_dir): - return '' + return ''' + +%(dist)f +%(details)s + +%(cell1)s
%(name)s +%(cell2)s
%(name)s +''' % locals () -class MidiFileLink (FileLink): - def get_midi (self, f): + +class FileCompareLink (FileLink): + def __init__ (self, f1, f2): + FileLink.__init__ (self, f1, f2) + self.contents = (self.get_content (self.file_names[0]), + self.get_content (self.file_names[1])) + + + def calc_distance (self): + ## todo: could use import MIDI to pinpoint + ## what & where changed. + + if self.contents[0] == self.contents[1]: + return 0.0 + else: + return 100.0; + + def get_content (self, f): + print 'reading', f s = open (f).read () - s = re.sub ('LilyPond [0-9.]+', '', s) return s + + +class GitFileCompareLink (FileCompareLink): + def get_cell (self, oldnew): + str = self.contents[oldnew] + + # truncate long lines + str = '\n'.join ([l[:80] for l in str.split ('\n')]) + + + str = '
%s
' % str + return str - def __init__ (self, f1, f2): - self.files = (f1, f2) + def calc_distance (self): + if self.contents[0] == self.contents[1]: + d = 0.0 + else: + d = 1.0001 *options.threshold - s1 = self.get_midi (self.files[0]) - s2 = self.get_midi (self.files[1]) + return d - self.same = (s1 == s2) +class TextFileCompareLink (FileCompareLink): + def calc_distance (self): + import difflib + diff = difflib.unified_diff (self.contents[0].strip().split ('\n'), + self.contents[1].strip().split ('\n'), + fromfiledate = self.file_names[0], + tofiledate = self.file_names[1] + ) - def name (self): - name = os.path.split (self.files[0])[1] - name = re.sub ('.midi', '', name) - return name + self.diff_lines = [l for l in diff] + self.diff_lines = self.diff_lines[2:] - def distance (self): - ## todo: could use import MIDI to pinpoint - ## what & where changed. - if self.same: - return 0 - else: - return 100; - def html_record_string (self, d1, d2): - return ''' - -%f - -%s -%s -''' % ((self.distance(),) + self.files) + return math.sqrt (float (len ([l for l in self.diff_lines if l[0] in '-+']))) + + def get_cell (self, oldnew): + str = '' + if oldnew == 1: + str = '\n'.join ([d.replace ('\n','') for d in self.diff_lines]) + str = '
%s
' % str + return str + + +class ProfileFileLink (FileCompareLink): + def __init__ (self, f1, f2): + FileCompareLink.__init__ (self, f1, f2) + self.results = [{}, {}] + + def get_cell (self, oldnew): + str = '' + for k in ('time', 'cells'): + if oldnew==0: + str += '%-8s: %d\n' % (k, int (self.results[oldnew][k])) + else: + str += '%-8s: %8d (%5.3f)\n' % (k, int (self.results[oldnew][k]), + self.get_ratio (k)) + + return '
%s
' % str + + def get_ratio (self, key): + (v1,v2) = (self.results[0].get (key, -1), + self.results[1].get (key, -1)) + + if v1 <= 0 or v2 <= 0: + return 0.0 + + return (v1 - v2) / float (v1+v2) + + def calc_distance (self): + for oldnew in (0,1): + def note_info (m): + self.results[oldnew][m.group(1)] = float (m.group (2)) + + re.sub ('([a-z]+): ([-0-9.]+)\n', + note_info, self.contents[oldnew]) + + dist = 0.0 + factor = {'time': 1.0 , + 'cells': 10.0, + } + + for k in ('time', 'cells'): + dist += math.tan (self.get_ratio (k) /(0.5* math.pi)) * factor[k] - 1 + + dist = min (dist, 100) + return dist + + +class MidiFileLink (TextFileCompareLink): + def get_content (self, oldnew): + import midi + + data = FileCompareLink.get_content (self, oldnew) + midi = midi.parse (data) + tracks = midi[1] + + str = '' + j = 0 + for t in tracks: + str += 'track %d' % j + j += 1 + + for e in t: + ev_str = repr (e) + if re.search ('LilyPond [0-9.]+', ev_str): + continue + + str += ' ev %s\n' % `e` + return str + + class SignatureFileLink (FileLink): - def __init__ (self): - self.original_name = '' - self.base_names = ('','') + def __init__ (self, f1, f2 ): + FileLink.__init__ (self, f1, f2) self.system_links = {} - self._distance = None - def name (self): - return self.original_name - + def add_system_link (self, link, number): self.system_links[number] = link @@ -388,12 +563,6 @@ class SignatureFileLink (FileLink): return d + orphan_distance - def distance (self): - if type (self._distance) != type (0.0): - return self.calc_distance () - - return self._distance - def source_file (self): for ext in ('.ly', '.ly.txt'): if os.path.exists (self.base_names[1] + ext): @@ -414,19 +583,16 @@ class SignatureFileLink (FileLink): os.path.normpath (base2)) def note_original (match): - self.original_name = match.group (1) + hash_to_original_name[os.path.basename (self.base_names[1])] = match.group (1) return '' - if not self.original_name: - self.original_name = os.path.split (base1)[1] - - ## ugh: drop the .ly.txt - for ext in ('.ly', '.ly.txt'): - try: - re.sub (r'\\sourcefilename "([^"]+)"', - note_original, open (base1 + ext).read ()) - except IOError: - pass + ## ugh: drop the .ly.txt + for ext in ('.ly', '.ly.txt'): + try: + re.sub (r'\\sourcefilename "([^"]+)"', + note_original, open (base1 + ext).read ()) + except IOError: + pass s1 = read_signature_file (f1) s2 = read_signature_file (f2) @@ -436,7 +602,7 @@ class SignatureFileLink (FileLink): self.add_system_link (link, system_index[0]) - def create_images (self, old_dir, new_dir, dest_dir): + def create_images (self, dest_dir): files_created = [[], []] for oldnew in (0, 1): @@ -457,12 +623,13 @@ class SignatureFileLink (FileLink): return files_created - def link_files_for_html (self, old_dir, new_dir, dest_dir): + def link_files_for_html (self, dest_dir): + FileLink.link_files_for_html (self, dest_dir) to_compare = [[], []] - exts = ['.ly'] + exts = [] if options.create_images: - to_compare = self.create_images (old_dir, new_dir, dest_dir) + to_compare = self.create_images (dest_dir) else: exts += ['.png', '-page*png'] @@ -479,8 +646,8 @@ class SignatureFileLink (FileLink): for (old, new) in zip (to_compare[0], to_compare[1]): compare_png_images (old, new, dest_dir) - - def html_record_string (self, old_dir, new_dir): + + def get_cell (self, oldnew): def img_cell (ly, img, name): if not name: name = 'source' @@ -488,13 +655,9 @@ class SignatureFileLink (FileLink): name = '%s' % name return ''' -

-(%(name)s) - - ''' % locals () def multi_img_cell (ly, imgs, name): if not name: @@ -509,11 +672,7 @@ class SignatureFileLink (FileLink): return ''' - %(imgs_str)s -(%(name)s) - - ''' % locals () @@ -526,32 +685,17 @@ class SignatureFileLink (FileLink): return multi_img_cell (base + '.ly', sorted (pages), name) else: return img_cell (base + '.ly', base + '.png', name) - - html_2 = self.base_names[1] + '.html' - name = self.original_name - cell_1 = cell (self.base_names[0], name) - cell_2 = cell (self.base_names[1], name) - if options.compare_images: - cell_2 = cell_2.replace ('.png', '.compare.jpeg') - - html_entry = ''' - - -%f
-(details) - - -%s -%s - -''' % (self.distance (), html_2, cell_1, cell_2) - return html_entry + str = cell (os.path.splitext (self.file_names[oldnew])[0], self.name ()) + if options.compare_images and oldnew == 1: + str = str.replace ('.png', '.compare.jpeg') + + return str - def html_system_details_string (self): + def get_distance_details (self): systems = self.system_links.items () systems.sort () @@ -575,7 +719,7 @@ class SignatureFileLink (FileLink): e = '%s' % e html += e - original = self.original_name + original = self.name () html = ''' comparison details for %(original)s @@ -597,11 +741,6 @@ class SignatureFileLink (FileLink): ''' % locals () return html - def write_html_system_details (self, dir1, dir2, dest_dir): - dest_file = os.path.join (dest_dir, self.base_names[1] + '.html') - - details = open_write_file (dest_file) - details.write (self.html_system_details_string ()) ################################################################ # Files/directories @@ -609,8 +748,6 @@ class SignatureFileLink (FileLink): import glob import re - - def compare_signature_files (f1, f2): s1 = read_signature_file (f1) s2 = read_signature_file (f2) @@ -624,20 +761,23 @@ def paired_files (dir1, dir2, pattern): Return (PAIRED, MISSING-FROM-2, MISSING-FROM-1) """ - - files1 = dict ((os.path.split (f)[1], 1) for f in glob.glob (dir1 + '/' + pattern)) - files2 = dict ((os.path.split (f)[1], 1) for f in glob.glob (dir2 + '/' + pattern)) + files = [] + for d in (dir1,dir2): + found = [os.path.split (f)[1] for f in glob.glob (d + '/' + pattern)] + found = dict ((f, 1) for f in found) + files.append (found) + pairs = [] missing = [] - for f in files1.keys (): + for f in files[0].keys (): try: - files2.pop (f) + files[1].pop (f) pairs.append (f) except KeyError: missing.append (f) - return (pairs, files2.keys (), missing) + return (pairs, files[1].keys (), missing) class ComparisonData: def __init__ (self): @@ -661,7 +801,7 @@ class ComparisonData: self.compare_trees (d1, d2) def compare_directories (self, dir1, dir2): - for ext in ['signature', 'midi']: + for ext in ['signature', 'midi', 'log', 'profile', 'gittxt']: (paired, m1, m2) = paired_files (dir1, dir2, '*.' + ext) self.missing += [(dir1, m) for m in m1] @@ -670,7 +810,6 @@ class ComparisonData: for p in paired: if (options.max_count and len (self.file_links) > options.max_count): - continue f2 = dir2 + '/' + p @@ -680,13 +819,22 @@ class ComparisonData: def compare_files (self, f1, f2): if f1.endswith ('signature'): self.compare_signature_files (f1, f2) - elif f1.endswith ('midi'): - self.compare_midi_files (f1, f2) + else: + ext = os.path.splitext (f1)[1] + klasses = { + '.midi': MidiFileLink, + '.log' : TextFileCompareLink, + '.profile': ProfileFileLink, + '.gittxt': GitFileCompareLink, + } - def compare_midi_files (self, f1, f2): + if klasses.has_key (ext): + self.compare_general_files (klasses[ext], f1, f2) + + def compare_general_files (self, klass, f1, f2): name = os.path.split (f1)[1] - file_link = MidiFileLink (f1, f2) + file_link = klass (f1, f2) self.file_links[name] = file_link def compare_signature_files (self, f1, f2): @@ -697,11 +845,35 @@ class ComparisonData: try: file_link = self.file_links[name] except KeyError: - file_link = SignatureFileLink () + generic_f1 = re.sub ('-[0-9]+.signature', '.ly', f1) + generic_f2 = re.sub ('-[0-9]+.signature', '.ly', f2) + file_link = SignatureFileLink (generic_f1, generic_f2) self.file_links[name] = file_link file_link.add_file_compare (f1, f2) + def write_changed (self, dest_dir, threshold): + (changed, below, unchanged) = self.thresholded_results (threshold) + + str = '\n'.join ([os.path.splitext (link.file_names[1])[0] + for link in changed]) + fn = dest_dir + '/changed.txt' + + open_write_file (fn).write (str) + + def thresholded_results (self, threshold): + ## todo: support more scores. + results = [(link.distance(), link) + for link in self.file_links.values ()] + results.sort () + results.reverse () + + unchanged = [r for (d,r) in results if d == 0.0] + below = [r for (d,r) in results if threshold >= d > 0.0] + changed = [r for (d,r) in results if d > threshold] + + return (changed, below, unchanged) + def write_text_result_page (self, filename, threshold): out = None if filename == '': @@ -710,21 +882,15 @@ class ComparisonData: print 'writing "%s"' % filename out = open_write_file (filename) - ## todo: support more scores. - results = [(link.distance(), link) - for link in self.file_links.values ()] - results.sort () - results.reverse () + (changed, below, unchanged) = self.thresholded_results (threshold) - for (score, link) in results: - if score > threshold: - out.write (link.text_record_string ()) + for link in changed: + out.write (link.text_record_string ()) out.write ('\n\n') - out.write ('%d below threshold\n' % len ([1 for s,l in results - if threshold >= s > 0.0])) - out.write ('%d unchanged\n' % len ([1 for (s,l) in results if s == 0.0])) + out.write ('%d below threshold\n' % len (below)) + out.write ('%d unchanged\n' % len (unchanged)) def create_text_result_page (self, dir1, dir2, dest_dir, threshold): self.write_text_result_page (dest_dir + '/index.txt', threshold) @@ -732,22 +898,14 @@ class ComparisonData: def create_html_result_page (self, dir1, dir2, dest_dir, threshold): dir1 = dir1.replace ('//', '/') dir2 = dir2.replace ('//', '/') - - results = [(link.distance(), link) - for link in self.file_links.values ()] - results.sort () - results.reverse () + + (changed, below, unchanged) = self.thresholded_results (threshold) + html = '' old_prefix = os.path.split (dir1)[1] - for (score, link) in results: - if score <= threshold: - continue - - link.link_files_for_html (dir1, dir2, dest_dir) - link.write_html_system_details (dir1, dir2, dest_dir) - - html += link.html_record_string (dir1, dir2) + for link in changed: + html += link.html_record_string (dest_dir) short_dir1 = shorten_string (dir1) @@ -764,15 +922,12 @@ class ComparisonData: ''' % locals() html += ('

') - below_count =len ([1 for s,l in results - if threshold >= s > 0.0]) + below_count = len (below) if below_count: html += ('

%d below threshold

' % below_count) - - html += ('

%d unchanged

' - % len ([1 for (s,l) in results if s == 0.0])) - + + html += ('

%d unchanged

' % len (unchanged)) dest_file = dest_dir + '/index.html' open_write_file (dest_file).write (html) @@ -788,6 +943,7 @@ def compare_trees (dir1, dir2, dest_dir, threshold): if os.path.isdir (dest_dir): system ('rm -rf %s '% dest_dir) + data.write_changed (dest_dir, threshold) data.create_html_result_page (dir1, dir2, dest_dir, threshold) data.create_text_result_page (dir1, dir2, dest_dir, threshold) @@ -802,6 +958,7 @@ def mkdir (x): def link_file (x, y): mkdir (os.path.split (y)[0]) try: + print x, '->', y os.link (x, y) except OSError, z: print 'OSError', x, y, z @@ -828,15 +985,17 @@ def test_paired_files (): def test_compare_trees (): system ('rm -rf dir1 dir2') system ('mkdir dir1 dir2') - system ('cp 20{-*.signature,.ly,.png,.eps} dir1') - system ('cp 20{-*.signature,.ly,.png,.eps} dir2') - system ('cp 20expr{-*.signature,.ly,.png,.eps} dir1') - system ('cp 19{-*.signature,.ly,.png,.eps} dir2/') - system ('cp 19{-*.signature,.ly,.png,.eps} dir1/') - system ('cp 19-1.signature 19-sub-1.signature') - system ('cp 19.ly 19-sub.ly') - system ('cp 19.png 19-sub.png') - system ('cp 19.eps 19-sub.eps') + system ('cp 20{-*.signature,.ly,.png,.eps,.log,.profile} dir1') + system ('cp 20{-*.signature,.ly,.png,.eps,.log,.profile} dir2') + system ('cp 20expr{-*.signature,.ly,.png,.eps,.log,.profile} dir1') + system ('cp 19{-*.signature,.ly,.png,.eps,.log,.profile} dir2/') + system ('cp 19{-*.signature,.ly,.png,.eps,.log,.profile} dir1/') + system ('cp 19-1.signature 19.sub-1.signature') + system ('cp 19.ly 19.sub.ly') + system ('cp 19.profile 19.sub.profile') + system ('cp 19.log 19.sub.log') + system ('cp 19.png 19.sub.png') + system ('cp 19.eps 19.sub.eps') system ('cp 20multipage* dir1') system ('cp 20multipage* dir2') @@ -844,37 +1003,41 @@ def test_compare_trees (): system ('mkdir -p dir1/subdir/ dir2/subdir/') - system ('cp 19-sub{-*.signature,.ly,.png,.eps} dir1/subdir/') - system ('cp 19-sub{-*.signature,.ly,.png,.eps} dir2/subdir/') - system ('cp 20grob{-*.signature,.ly,.png,.eps} dir2/') - system ('cp 20grob{-*.signature,.ly,.png,.eps} dir1/') + system ('cp 19.sub{-*.signature,.ly,.png,.eps,.log,.profile} dir1/subdir/') + system ('cp 19.sub{-*.signature,.ly,.png,.eps,.log,.profile} dir2/subdir/') + system ('cp 20grob{-*.signature,.ly,.png,.eps,.log,.profile} dir2/') + system ('cp 20grob{-*.signature,.ly,.png,.eps,.log,.profile} dir1/') + system ('echo HEAD is 1 > dir1/tree.gittxt') + system ('echo HEAD is 2 > dir2/tree.gittxt') ## introduce differences system ('cp 19-1.signature dir2/20-1.signature') + system ('cp 19.profile dir2/20.profile') system ('cp 19.png dir2/20.png') system ('cp 19multipage-page1.png dir2/20multipage-page1.png') - system ('cp 20-1.signature dir2/subdir/19-sub-1.signature') - system ('cp 20.png dir2/subdir/19-sub.png') + system ('cp 20-1.signature dir2/subdir/19.sub-1.signature') + system ('cp 20.png dir2/subdir/19.sub.png') + system ("sed 's/: /: 1/g' 20.profile > dir2/subdir/19.sub.profile") ## radical diffs. system ('cp 19-1.signature dir2/20grob-1.signature') system ('cp 19-1.signature dir2/20grob-2.signature') system ('cp 19multipage.midi dir1/midi-differ.midi') system ('cp 20multipage.midi dir2/midi-differ.midi') + system ('cp 19multipage.log dir1/log-differ.log') + system ('cp 19multipage.log dir2/log-differ.log && echo different >> dir2/log-differ.log && echo different >> dir2/log-differ.log') - compare_trees ('dir1', 'dir2', 'compare-dir1dir2', 0.5) + compare_trees ('dir1', 'dir2', 'compare-dir1dir2', options.threshold) def test_basic_compare (): ly_template = r""" \version "2.10.0" -#(set! toplevel-score-handler print-score-with-defaults) - #(set! toplevel-music-handler - (lambda (p m) - (if (not (eq? (ly:music-property m 'void) #t)) - (print-score-with-defaults - p (scorify-music m p))))) +#(define default-toplevel-book-handler + print-book-with-defaults-as-systems ) + +#(ly:set-option (quote no-point-and-click)) \sourcefilename "my-source.ly" @@ -916,8 +1079,8 @@ def test_basic_compare (): open (d['name'] + '.ly','w').write (ly_template % d) names = [d['name'] for d in dicts] - - system ('lilypond -ddump-signatures --png -b eps ' + ' '.join (names)) + + system ('lilypond -ddump-profile -dseparate-log-files -ddump-signatures --png -b eps ' + ' '.join (names)) multipage_str = r''' @@ -929,9 +1092,9 @@ def test_basic_compare (): } ''' - open ('20multipage', 'w').write (multipage_str.replace ('c1', 'd1')) - open ('19multipage', 'w').write ('#(set-global-staff-size 19.5)\n' + multipage_str) - system ('lilypond -ddump-signatures --png 19multipage 20multipage ') + open ('20multipage.ly', 'w').write (multipage_str.replace ('c1', 'd1')) + open ('19multipage.ly', 'w').write ('#(set-global-staff-size 19.5)\n' + multipage_str) + system ('lilypond -dseparate-log-files -ddump-signatures --png 19multipage 20multipage ') test_compare_signatures (names) diff --git a/flower/include/rational.hh b/flower/include/rational.hh index 511b8c2460..5effd3787a 100644 --- a/flower/include/rational.hh +++ b/flower/include/rational.hh @@ -45,7 +45,8 @@ public: void negate (); int to_int () const; - operator double () const; + operator double () const { return to_double (); } + double to_double () const; Rational operator - () const; /** diff --git a/flower/rational.cc b/flower/rational.cc index 6822703256..0e3ab30694 100644 --- a/flower/rational.cc +++ b/flower/rational.cc @@ -16,7 +16,8 @@ using namespace std; #include "string-convert.hh" #include "libc-extension.hh" -Rational::operator double () const +double +Rational::to_double () const { if (sign_ == -1 || sign_ == 1 || sign_ == 0) return ((double)sign_) * num_ / den_; diff --git a/input/GNUmakefile b/input/GNUmakefile index 4a45b45f4a..022f9c3f12 100644 --- a/input/GNUmakefile +++ b/input/GNUmakefile @@ -1,6 +1,6 @@ depth = .. -SUBDIRS = test regression tutorial midi no-notation mutopia manual +SUBDIRS = test regression tutorial mutopia manual examples = typography-demo les-nereides wilhelmus proportional bach-schenker cary diff --git a/input/midi/GNUmakefile b/input/midi/GNUmakefile deleted file mode 100644 index 37d97aa000..0000000000 --- a/input/midi/GNUmakefile +++ /dev/null @@ -1,8 +0,0 @@ -depth = ../.. - -STEPMAKE_TEMPLATES=documentation texinfo tex -LOCALSTEPMAKE_TEMPLATES=lilypond ly lysdoc - -include $(depth)/make/stepmake.make -TITLE=LilyPond MIDI Tests - diff --git a/input/midi/midi-drums.ly b/input/midi/midi-drums.ly deleted file mode 100644 index 2b799be25b..0000000000 --- a/input/midi/midi-drums.ly +++ /dev/null @@ -1,18 +0,0 @@ - -\version "2.10.0" - -\version "2.10.1" - -\score { - \new DrumStaff << - \drummode { - bd4 sn4 bd4 sn4 - << - {\voiceOne \repeat unfold 16 hh16 } - \new DrumVoice { \voiceTwo bd4 sn4 bd4 sn4 } - >> \oneVoice - } - >> - \layout {} - \midi {} -} diff --git a/input/midi/midi-grace.ly b/input/midi/midi-grace.ly deleted file mode 100644 index 213de79e37..0000000000 --- a/input/midi/midi-grace.ly +++ /dev/null @@ -1,22 +0,0 @@ -\version "2.10.0" -\header{ texidoc = "Tests MIDI output with grace notes. " } - -\score { - \context Voice \relative c { - \new Voice = VoiceOne - \grace { - \override Stem #'stroke-style = #"grace" - c8 - \revert Stem #'stroke-style } - d4 d d d d - \grace { - \override Stem #'stroke-style = #"grace" - e16 f e f - \revert Stem #'stroke-style } - d4 d d d d - - } - \layout { } - \midi { } -} - diff --git a/input/midi/midi-lyric-barcheck.ly b/input/midi/midi-lyric-barcheck.ly deleted file mode 100644 index 5c06916af0..0000000000 --- a/input/midi/midi-lyric-barcheck.ly +++ /dev/null @@ -1,24 +0,0 @@ -\version "2.10.0" -\header { - - texidoc = "Lyrics in MIDI are aligned to ties and beams: -this examples causes no bar checks in MIDI. -" - - - } -\score { - - <<\relative c'' \new Voice = A { - \autoBeamOff - c8[ c] c2. - c1~c4 c2. - c4 ( d e) d - c1 - - } - \lyricsto "A" \lyrics { bla bla | bla bla | bla bla | bla } - >> - \layout {} - \midi {} - } diff --git a/input/midi/midi-scales.ly b/input/midi/midi-scales.ly deleted file mode 100644 index d6e8ed91c5..0000000000 --- a/input/midi/midi-scales.ly +++ /dev/null @@ -1,159 +0,0 @@ - -\version "2.10.0" -% candidate for regression. -gp -\header { - texidoc="Converting LilyPond input to MIDI and then again back with - @code{midi2ly.py} is a reversible procedure in some simple cases, - which mean that the original @code{.ly} -file and the one converted - back from the generated @code{.midi} -file do not differ. - Here are produced some scales. - - " -} - -%{ - This means, doing: - - lilypond input/test/midi-scales.ly - midi2ly midi-scales.midi - diff -u input/test/midi-scales.ly midi-scales-midi.ly - - should show no differences at all in \key commands or notes. - - Therefore, do not reformat this file unless midi2ly changes. - - 1.7.30 reformatted, because - midi2ly now outpts 1 bar per line and adds bar checks and numbers. - -%} - -scales = \relative c { - - % [INSTRUMENT_NAME] bright acoustic - \key c \major % sharp-major - c'4 d e f | - g a b c | - - \key g \major - g a b c | - d e fis g | - - \key d \major - d, e fis g | - a b cis d | - - \key a \major - a b cis d | - e fis gis a | - - \key e \major - e, fis gis a | - b cis dis e | - - \key b \major - b cis dis e | - fis gis ais b | - - \key fis \major - fis, gis ais b | - cis dis eis fis | - - \key cis \major - cis, dis eis fis | - gis ais bis cis | - - \key a \minor % sharp-minor - a b c d | - e f gis a | - - \key e \minor - e, fis g a | - b c dis e | - - \key b \minor - b cis d e | - fis g ais b | - - \key fis \minor - fis, gis a b | - cis d eis fis | - - \key cis \minor - cis, dis e fis | - gis a bis cis | - - \key gis \minor - gis ais b cis | - dis e fisis gis | - - \key dis \minor - dis, eis fis gis | - ais b cisis dis | - - \key ais \minor - ais bis cis dis | - eis fis gisis ais | - - \key f \major % flat-major - f, g a bes | - c d e f | - - \key bes \major - bes c d ees | - f g a bes | - - \key ees \major - ees,, f g aes | - bes c d ees | - - \key aes \major - aes, bes c des | - ees f g aes | - - \key des \major - des,, ees f ges | - aes bes c des | - - \key ges \major - ges, aes bes ces | - des ees f ges | - - \key ces \major - ces,, des ees fes | - ges aes bes ces | - - \key d \minor % flat-minor - d, e f g | - a bes cis d | - - \key g \minor - g, a bes c | - d ees fis g | - - \key c \minor - c,, d ees f | - g aes b c | - - \key f \minor - f, g aes bes | - c des e f | - - \key bes \minor - bes,, c des ees | - f ges a bes | - - \key ees \minor - ees, f ges aes | - bes ces d ees | - - \key aes \minor - aes, bes ces des | - ees fes g aes | -} - -\score { - \context Voice \scales - \layout { } - \midi { } -} - diff --git a/input/midi/midi-tuplets.ly b/input/midi/midi-tuplets.ly deleted file mode 100644 index 0a0f5ef1a9..0000000000 --- a/input/midi/midi-tuplets.ly +++ /dev/null @@ -1,35 +0,0 @@ -\version "2.10.0" -\header { -texidoc = " - -Midi2ly tuplet test. - -@example - python scripts/midi2ly.py --duration-quant=32 \ - --allow-tuplet=4*2/3 \ - --allow-tuplet=8*2/3 \ - --allow-tuplet=4*3/5 \ - --allow-tuplet=8*3/5 \ - tu.midi -@end example -" -} - - -\score { - \context Voice \relative c' { - - a1 a2 a2. a4 a4. a8 a8. a16 a16. a32 a32. a64 - - \times 2/3 { b4 b4 b4 } - \times 3/5 { b4 b4 b4 b4 b4 } - - \times 2/3 { c8 c8 c8 } - \times 3/5 { c8 c8 c8 c8 c8 } - - } - \layout { } - \midi { } -} - - diff --git a/input/midi/midi-volume-equaliser.ly b/input/midi/midi-volume-equaliser.ly deleted file mode 100644 index 0ad06cb931..0000000000 --- a/input/midi/midi-volume-equaliser.ly +++ /dev/null @@ -1,161 +0,0 @@ -\version "2.10.0" -\header { - texidoc = "@cindex Midi Volume Equaliser -The full orchestra plays a notes, where groups stop one after -another. Use this to tune equalizer settings. " -} - -#(set-global-staff-size 16) - -%{ - -Override, see scm/midi.scm: - -#(set! instrument-equalizer-alist - (append - '( - ("flute" . (0 . 0.7)) - ) - instrument-equalizer-alist)) - -%} - -flauti = \relative c' { - \set Staff.midiInstrument = #"flute" - \set Staff.instrumentName = #"2 Flauti" - \set Staff.shortInstrumentName = #"Fl." - - c1\f R1*10 -} - -oboi = \relative c' { - \set Staff.midiInstrument = #"oboe" - \set Staff.instrumentName = #"2 Oboi" - \set Staff.shortInstrumentName = #"Ob." - - R1*1 c1\f R1*9 -} - -clarinetti = \relative c' { - \set Staff.midiInstrument = #"clarinet" - \set Staff.instrumentName = #"Clarinetti" - \set Staff.shortInstrumentName = #"Cl" - - R1*2 c1\f R1*8 -} - -fagotti = \relative c' { - \set Staff.midiInstrument = #"bassoon" - \set Staff.instrumentName = #"2 Fagotti" - \set Staff.shortInstrumentName = #"Fg." - - \clef bass - R1*3 c1\f R1*7 -} - -corni = \relative c' { - \set Staff.midiInstrument = #"french horn" - \set Staff.instrumentName = #"Corni" - \set Staff.shortInstrumentName = #"Cor" - - R1*4 c1\f R1*6 -} - -trombe = \relative c' { - \set Staff.midiInstrument = #"trumpet" - \set Staff.instrumentName = #"Trombe" - \set Staff.shortInstrumentName = #"Tp." - - \clef bass - R1*5 c1\f R1*5 -} - -timpani = \relative c' { - \set Staff.midiInstrument = #"timpani" - \set Staff.instrumentName = #"Timpani" - \set Staff.shortInstrumentName = #"Timp." - - R1*6 c1\f R1*4 -} - -violinoI = \relative c' { - \set Staff.midiInstrument = #"violin" - \set Staff.instrumentName = #"Violino I " - \set Staff.shortInstrumentName = #"Vl. I " - - R1*7 c1\f R1*3 -} - -violinoII = \relative c' { - \set Staff.midiInstrument = #"violin" - \set Staff.instrumentName = #"Violino II " - \set Staff.shortInstrumentName = #"Vl. II " - - R1*8 c1\f R1*2 -} - -viola = \relative c' { - \set Staff.midiInstrument = #"viola" - \set Staff.instrumentName = #"Viola" - \set Staff.shortInstrumentName = #"Vla." - - \clef alto - R1*9 c1\f R1*1 -} - -violoncello = \relative c' { - \set Staff.midiInstrument = #"cello" - %\set Staff.midiInstrument = #"contrabass" - \set Staff.instrumentName = #"Violoncello" - \set Staff.shortInstrumentName = #"Vc." - - \clef bass - R1*10 c1\f -} - - -\score { - << - \new StaffGroup = "legni" << - \new Staff = "flauti" \flauti - \new Staff = "oboi" \oboi - \new Staff = "clarinetti" \clarinetti - \new Staff = "fagotti" \fagotti - >> - \new StaffGroup = "ottoni" << - \new Staff = "corni" \corni - \new Staff = "trombe" \trombe - >> - \new StaffGroup = "timpani" << - \new Staff = "timpani" \timpani - { - \skip 1 - %% Hmm: this forces a staff-bracket, that's good! - %% However, I can't find where is decided on staff-bracket yes/no - } - >> - \new StaffGroup = "archi" << - \new GrandStaff = "violini" << - \new Staff = "violino1" \violinoI - \new Staff = "violino2" \violinoII - >> - \new Staff = "viola" \viola - \new Staff = "violoncello" \violoncello - >> - >> - - \layout { - \context { - \RemoveEmptyStaffContext - } - } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 60 1) - } - } -} - - diff --git a/input/midi/transposition.ly b/input/midi/transposition.ly deleted file mode 100644 index 2429fef5d3..0000000000 --- a/input/midi/transposition.ly +++ /dev/null @@ -1,14 +0,0 @@ -\header -{ - texidoc = "should deliver f' in MIDI" -} -\version "2.10.5" - -\score { - { - \transposition f - c'' - } - \midi{} - \layout{} -} diff --git a/input/no-notation/GNUmakefile b/input/no-notation/GNUmakefile deleted file mode 100644 index daedbb1cc4..0000000000 --- a/input/no-notation/GNUmakefile +++ /dev/null @@ -1,8 +0,0 @@ -depth = ../.. - -EXTRA_DIST_FILES=README -LOCALSTEPMAKE_TEMPLATES=ly mutopia - -include $(depth)/make/stepmake.make - - diff --git a/input/no-notation/README b/input/no-notation/README deleted file mode 100644 index d162aad83c..0000000000 --- a/input/no-notation/README +++ /dev/null @@ -1,9 +0,0 @@ -These examples test various non-typesetting things. Since they -do not generate output, they are not in test/ or regression/ - -Some (notably parse*.ly) are just error/warning generation tests -and should remain here. - -Some (notably midi-*.ly) test midi output, which does not usually -get tested in ../regression files. - diff --git a/input/no-notation/bar-check.ly b/input/no-notation/bar-check.ly deleted file mode 100644 index e9a714eae9..0000000000 --- a/input/no-notation/bar-check.ly +++ /dev/null @@ -1,13 +0,0 @@ -\version "2.10.0" - -\header { - -texidoc = "skipTypesetting doesn't affect bar checks." - -} - -\score { { - \set Score.skipTypesetting = ##t - c4 c4 - | - c4 c4 }} diff --git a/input/no-notation/beam-warn.ly b/input/no-notation/beam-warn.ly deleted file mode 100644 index 3a6586de06..0000000000 --- a/input/no-notation/beam-warn.ly +++ /dev/null @@ -1,11 +0,0 @@ -\version "2.10.0" - -\header { - -texidoc = "The first duration following a beam-open request is checked if it is short enough." - -} - -\score { - { [c4 c] } -} diff --git a/input/no-notation/die-staff.ly b/input/no-notation/die-staff.ly deleted file mode 100644 index 4f94b3bd14..0000000000 --- a/input/no-notation/die-staff.ly +++ /dev/null @@ -1,23 +0,0 @@ -\version "2.10.0" - -\header { -texidoc = "a staff should really die, if no one's referencing it." -} -\score { - { - \new Staff = "q" { - { a' b' c' d' } - } - - \break - - \context PianoStaff << - \new Staff = "i" { - { a' b' c' d' } - } - \new Staff = "ii" { - { \clef "bass" a b c d } - } - >> - } -} diff --git a/input/no-notation/display-lily-tests.ly b/input/no-notation/display-lily-tests.ly deleted file mode 100644 index 014f63ccdb..0000000000 --- a/input/no-notation/display-lily-tests.ly +++ /dev/null @@ -1,262 +0,0 @@ -\version "2.10.0" - -#(use-modules (srfi srfi-13) - (ice-9 format)) - -%%% -%%% Testing utilities -%%% - -#(define (parse-lily-and-compute-lily-string chr port) - (let ((lily-string (call-with-output-string - (lambda (out) - (do ((c (read-char port) (read-char port))) - ((and (char=? c #\#) - (char=? (peek-char port) #\])) - (read-char port)) - (display c out)))))) - `(let* ((parser-clone (ly:clone-parser parser)) - (input-str (string-trim-both ,lily-string)) - (music (car (ly:music-property (parse-string-result input-str - parser-clone) - 'elements))) - (result-str (string-trim-both (music->lily-string music parser-clone)))) - (cons input-str result-str)))) - -#(read-hash-extend #\[ parse-lily-and-compute-lily-string) %{ ] %} - -#(define (lily-string->markup str) - (make-column-markup (string-split str #\NewLine))) - -#(define test-function - (let ((test-number 0)) - (lambda (parser location result-info strings) - (let ((input (car strings)) - (output (cdr strings))) - (set! test-number (1+ test-number)) - (if (string=? input output) - (make-music 'SequentialMusic 'void #t) - (make-music 'SequentialMusic - 'elements - (list (ly:parser-lookup parser 'fatText) - (make-music 'EventChord - 'elements (list (make-music 'LineBreakEvent - 'break-permission 'force))) - (make-music 'EventChord - 'elements (list (make-music 'SkipEvent - 'duration (ly:make-duration 0 0 1 1)) - (make-music 'TextScriptEvent - 'direction -1 - 'text (markup #:column - (#:simple (format #f "Test #~a " test-number) - (if (string-null? result-info) - (markup #:bold "BUG") - (markup #:simple result-info)) - #:typewriter (lily-string->markup input) - #:typewriter (lily-string->markup output))))))))))))) - - -test = -#(define-music-function (parser location result-info strings) (string? pair?) - (test-function parser location result-info strings)) - -%%% -%%% Tests -%%% -\header { - texidoc = \markup \column { \line { \typewriter display-lily-music unit tests } - \line { Real bugs (regressions) are marked as \bold BUG. } - \line { Known bugs are marked as TODO. } } -} - -\layout { - raggedright = ##t - indent = 0\cm - \context { - \Staff - \override StaffSymbol #'line-count = #1 - \remove "Time_signature_engraver" - \remove "Clef_engraver" - } - \context { - \Score - \remove "Bar_number_engraver" - } -} - -%% Sequential music -\test "" ##[ { { a b } { c d } } #] % SequentialMusic -\test "" ##[ << { a b } { c d } >> #] % SimultaneousMusic -\test "" ##[ << { a b } \\ { c d } >> #] % VoiceSeparator - -%% Chords and Notes -\test "" ##[ { ceses ces c cis cisis } #] % NoteEvent -\test "" ##[ { deses des d dis disis } #] -\test "" ##[ { eeses ees e eis eisis } #] -\test "" ##[ { feses fes f fis fisis } #] -\test "" ##[ { geses ges g gis gisis } #] -\test "" ##[ { aeses aes a ais aisis } #] -\test "" ##[ { beses bes b bis bisis } #] -\test "" ##[ { c,, d' } #] -\test "" ##[ { c' d'=' } #] -\test "" ##[ { c! c? } #] -\test "" ##[ r1.*4/3 #] % RestEvent -\test "" ##[ c1\rest #] % RestEvent -\test "" ##[ s2..*3/4 #] % SkipEvent -\test "" ##[ R1.*2/3 #] % MultiMeasureRestMusicGroup, MultiMeasureRestEvent -\test "" ##[ \skip 2.*3/4 #] % SkipMusic -\test "" ##[ < c\1 e\3 >4.*3/4-. #] % EventChord, NoteEvent, StringNumberEvent, ArticulationEvent - -%% tags -\test "" ##[ { \tag #'foo { c4 d } } #] -\test "" ##[ c-\tag #'foo -\tag #'baz -^ -. #] - -%% Graces -\test "" ##[ { \grace c8 d2 } #] % GraceMusic -\test "" ##[ { \appoggiatura c8 d2 } #] -\test "" ##[ { \acciaccatura c8 d2 } #] -\test "" ##[ { c1 \afterGrace { b,16 c } d2 } #] - -%% Clusters -\test "" ##[ { \makeClusters { c4 g } } #] % ClusterNoteEvent - -%% Figured bass -\test "" ##[ \figures { < 6 > } #] % BassFigureEvent -\test "" ##[ \figuremode { < 1-- 3- > < 2+ 4++ > < _! 7! > } #] -\test "" ##[ \figuremode { < [6 > < 5] > } #] - -%% Lyrics -\test "" ##[ \lyrics { a b } #] -\test "" ##[ \lyricmode { a -- b } #] % HyphenEvent -\test "" ##[ \lyricmode { a __ b } #] % ExtenderEvent -\test "" ##[ \lyricmode { "a " } #] % LyricEvent -\test "" ##[ \lyricsto "foo" { bla bla } #] % LyricCombineMusic -\test "" ##[ { { c d } - \addlyrics { bla bla } } #] - -%% Drums -\test "" ##[ \drums { hihat } #] -\test "" ##[ \drummode { hihat4.*3/4 } #] - -%% Expressive marks -\test "" ##[ c4 ~ #] % TieEvent -\test "" ##[ c\noBeam #] % BeamForbidEvent -\test "" ##[ c\1 #] % StringNumberEvent -\test "" ##[ { c: c:1 } #] % TremoloEvent -\test "" ##[ { c-^ c^^ c_^ } #] % ArticulationEvent -\test "" ##[ { c-+ c^+ c_+ } #] -\test "" ##[ { c-- c^- c_- } #] -\test "" ##[ { c-| c^| c_| } #] -\test "" ##[ { c-> c^> c_> } #] -\test "" ##[ { c-. c^. c_. } #] -\test "" ##[ { c-_ c^_ c__ } #] -\test "" ##[ { c-\trill c^\trill c_\trill } #] -\test "" ##[ { c-1 c^2 c_3 } #] % FingerEvent -\test "" ##[ { c-"foo" c^"foo" c_"foo" } #] % TextScriptEvent -\test "" ##[ { R1*4-"foo" R^"foo" R_"foo" } #] % MultiMeasureTextEvent -\test "" ##[ { c4-\harmonic c^\harmonic c_\harmonic } #] % HarmonicEvent -\test "" ##[ { c-\glissando c^\glissando c_\glissando } #] % GlissandoEvent -\test "" ##[ { c-\arpeggio c^\arpeggio c_\arpeggio } #] % ArpeggioEvent -\test "" ##[ { c\p c^\ff c_\sfz } #] % AbsoluteDynamicEvent -\test "" ##[ { c[ c] c^[ c^] c_[ c_] } #] % BeamEvent -\test "" ##[ { c( c) c^( c^) c_( c_) } #] % SlurEvent -\test "" ##[ { c\< c\! c^\< c^\! c_\< c_\! } #] % CrescendoEvent -\test "" ##[ { c\> c\! c^\> c^\! c_\> c_\! } #] % DecrescendoEvent -\test "" ##[ { c\( c\) c^\( c^\) c_\( c_\) } #] % PhrasingSlurEvent -\test "" ##[ { c\sustainDown c\sustainUp } #] % SustainEvent -\test "" ##[ { c\sostenutoDown c\sostenutoUp } #] % SostenutoEvent -\test "" ##[ \melisma #] -\test "" ##[ \melismaEnd #] -\test "" ##[ { c\startTextSpan c\stopTextSpan } #] % TextSpanEvent -\test "" ##[ { c\startTrillSpan c\stopTrillSpan } #] % TrillSpanEvent -\test "" ##[ { c \startStaff c \stopStaff } #] % StaffSpanEvent -\test "" ##[ { c\startGroup c\stopGroup c^\startGroup c^\stopGroup c_\startGroup c_\stopGroup } #] % NoteGroupingEvent -\test "" ##[ { c\unaCorda c\treCorde } #] % UnaCordaEvent -\test "" ##[ \breathe #] -\test "" ##[ { c \[ c \] } #] % LigatureEvent -\test "" ##[ \~ #] % PesOrFlexaEvent - -\test "" ##[ \break #] -\test "" ##[ \noBreak #] -\test "" ##[ \pageBreak #] -\test "" ##[ \noPageBreak #] -\test "" ##[ \pageTurn #] -\test "" ##[ \noPageTurn #] - -%% Checks -\test "" ##[ \octave a' #] % RelativeOctaveCheck -\test "" ##[ | #] % BarCheck - -%% Marks -\test "" ##[ \mark \default #] % MarkEvent -\test "" ##[ \mark "Allegro" #] -\test "" ##[ \tempo 4 = 120 #] % MetronomeChangeEvent - -%% key, time, clef, bar -\test "" ##[ \key \default #] % KeyChangeEvent -\test "" ##[ \key e \minor #] -\test "" ##[ \clef "bass" #] -\test "" ##[ \clef "french^2" #] -\test "" ##[ \clef "alto_3" #] -\test "" ##[ \time 2/4 #] -\test "" ##[ #(set-time-signature 5 8 '(3 2)) #] -\test "" ##[ \bar "|." #] - -%% staff switches -\test "" ##[ \autochange { c d } #] % AutoChangeMusic -\test "" ##[ { \change Staff = "up" { c d } } #] % ContextChange - -%% Tuplets -\test "" ##[ \times 2/3 { c8 d e } #] % TimeScaledMusic -\test "" ##[ \times 4/6 { c16 d e f g a } #] -%} -%% \relative and \tranpose -\test #"NOT A BUG" ##[ \relative c' { c b } #] % RelativeOctaveMusic -\test #"NOT A BUG" ##[ \transpose c d { c d } #] % TransposedMusic -%} -%% Repeats -\test "" ##[ \repeat volta 2 { c d } #] % VoltaRepeatedMusic -\test "" ##[ \repeat unfold 2 { c d } #] % UnfoldedRepeatedMusic -\test "" ##[ \repeat fold 2 { c d } #] % FoldedRepeatedMusic -\test "" ##[ \repeat percent 2 { c d } #] % PercentRepeatedMusic -\test "" ##[ \repeat tremolo 4 { c16 d } #] % TremoloRepeatedMusic -\test "" ##[ \repeat volta 2 { c4 d } \alternative { { c d } { e f } } #] % - -%% Context creation -\test "" ##[ \new Staff { c d } #] % ContextSpeccedMusic -\test "" ##[ \new Staff = "up" { c d } #] % ContextSpeccedMusic -\test "" ##[ \context Staff { c d } #] -\test "" ##[ \context Staff = "up" { c d } #] -\test "" ##[ -\new Staff \with { - \consists "Timing_engraver" - \remove "Clef_engraver" -} { c d } #] -%% Context properties -\test "" ##[ \once \set Score . skipBars = ##t #] % PropertySet -\test "" ##[ \set autoBeaming = ##f #] -\test "" ##[ \unset Score . skipBars #] % PropertyUnset -\test "" ##[ \unset autoBeaming #] -%% Layout properties -\test "" ##[ \override Staff . Stem #'thickness = #4.0 #] % OverrideProperty -\test "" ##[ \once \override Beam #'thickness = #0.6 #] -\test "" ##[ \revert Staff . Stem #'thickness #] % RevertProperty -\test "" ##[ \revert Beam #'thickness #] - -%% \applyOutput -\test "" ##[ \applyOutput #'Foo #(lambda (arg) (list)) #] -%% \applyContext -\test "" ##[ \applyContext #(lambda (arg) (list)) #] - -%% \partial -\test "" ##[ \partial 2 #] -\test "" ##[ \partial 8. #] -\test #"TODO? exotic durations in \\partial" ##[ \partial 4*2/3 #] - -%% \partcombine -\test "" ##[ \partcombine { c e } -{ d f } #] % PartCombineMusic UnrelativableMusic - -%% Cue notes -\test "" ##[ \cueDuring #"foo" #1 { c d } #] -\test "" ##[ \quoteDuring #"foo" { c d } #] diff --git a/input/no-notation/dos-guile.ly b/input/no-notation/dos-guile.ly deleted file mode 100644 index 9858a594f1..0000000000 --- a/input/no-notation/dos-guile.ly +++ /dev/null @@ -1,14 +0,0 @@ -\version "2.10.0" - -\header{ - - texidoc = "This should not hang lilypond --safe-mode." - -} - -% DOS -#(do () (#f)) - -\score{ - c'' -} \ No newline at end of file diff --git a/input/no-notation/dos-ps.ly b/input/no-notation/dos-ps.ly deleted file mode 100644 index 31c0da1b99..0000000000 --- a/input/no-notation/dos-ps.ly +++ /dev/null @@ -1,13 +0,0 @@ -\version "2.10.0" - -\header{ - - texidoc = "This should not hang lilypond --safe-mode --no-pdf - --png run. - -} - -\score{ - % DOS - c''-"\\embeddedps{ { 0 0 moveto } loop }" -} diff --git a/input/no-notation/dos-tex.ly b/input/no-notation/dos-tex.ly deleted file mode 100644 index 859df66f83..0000000000 --- a/input/no-notation/dos-tex.ly +++ /dev/null @@ -1,12 +0,0 @@ -\version "2.10.0" - -\header{ - - texidoc = "This should not hang lilypond --safe-mode run." - -} - -\score{ - % DOS - c''-"\\loop\\iftrue\\repeat" -} diff --git a/input/no-notation/dynamic-absolute-volume.ly b/input/no-notation/dynamic-absolute-volume.ly deleted file mode 100644 index 8c3a24cd1c..0000000000 --- a/input/no-notation/dynamic-absolute-volume.ly +++ /dev/null @@ -1,34 +0,0 @@ - -\version "2.10.0" -\header { - texidoc = "@cindex Dynamic Absolute Volume -Absolute dynamics have an effect on MIDI files. -" -} - - -\score{ -\relative c''{ -%segfault in engraver -a1\ppp -a1\pp -a\p -a\mp -a\mf -a\f -a\ff -a\fff -a\sf -} -\layout{ ragged-right = ##t } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 60 1) - } - } - - -} - diff --git a/input/no-notation/embedded-scm.ly b/input/no-notation/embedded-scm.ly deleted file mode 100644 index b84dfc82d9..0000000000 --- a/input/no-notation/embedded-scm.ly +++ /dev/null @@ -1,22 +0,0 @@ -\version "2.10.0" -\header { - - texidoc = "@cindex Embedded scm - -You can embed scheme functions in your scores. While generating the -output, ``hello world'' is printed to the console. -" - % see also: --safe-mode -} - -#(begin - (newline) - (display "hello world") - (newline)) - -\score { - \relative c' { c } - \layout {ragged-right = ##t} -} - - diff --git a/input/no-notation/parse.ly b/input/no-notation/parse.ly deleted file mode 100644 index b85132308e..0000000000 --- a/input/no-notation/parse.ly +++ /dev/null @@ -1,5 +0,0 @@ -\version "2.10.0" - -% Test parser error - -\score{ diff --git a/input/no-notation/parse2.ly b/input/no-notation/parse2.ly deleted file mode 100644 index 5096c6c69a..0000000000 --- a/input/no-notation/parse2.ly +++ /dev/null @@ -1,9 +0,0 @@ -\version "2.10.0" - -% Test parser error - -foo = { - - -\score{ -} diff --git a/input/no-notation/parse3.ly b/input/no-notation/parse3.ly deleted file mode 100644 index cdf9626309..0000000000 --- a/input/no-notation/parse3.ly +++ /dev/null @@ -1,9 +0,0 @@ -\version "2.10.0" - -% Test parser error - -foo = { - - -\score{ - diff --git a/input/no-notation/parse4.ly b/input/no-notation/parse4.ly deleted file mode 100644 index cee8a6a7c5..0000000000 --- a/input/no-notation/parse4.ly +++ /dev/null @@ -1,12 +0,0 @@ -\version "2.10.0" - -% Test parser error - -foo = { -} - - -\score{ - burp -} - diff --git a/input/no-notation/parse5.ly b/input/no-notation/parse5.ly deleted file mode 100644 index 4b9756ee9f..0000000000 --- a/input/no-notation/parse5.ly +++ /dev/null @@ -1,11 +0,0 @@ -\version "2.10.0" -%If you specify two different key sigs at one point, a -%warning is printed. - -\score { -\context Voice << - { \key cis \major cis4 \key bes \major bes4 } - { \key cis \major fis4 \key es \major g4 } ->> -} - diff --git a/input/no-notation/recording.ly b/input/no-notation/recording.ly deleted file mode 100644 index 39ea07dfa3..0000000000 --- a/input/no-notation/recording.ly +++ /dev/null @@ -1,24 +0,0 @@ -\version "2.10.0" -\header { - -texidoc = "The @code{Recording_group_engraver} will record events -synchronized in time, collecting them in a list. This file also shows -how to skip the rendering and outputting step of the process, using -@code{ly:run-translator}." - -} - -theMusic = \context Staff { c4 d8-. } - -#(define (notice-the-events context lst) - (map (lambda (x) (display x) (newline)) lst)) - -listener = \layout { - \context { - \Voice - \type "Recording_group_engraver" - recordEventSequence = #notice-the-events - } -} - -#(ly:run-translator theMusic listener) diff --git a/input/no-notation/safe-guile.ly b/input/no-notation/safe-guile.ly deleted file mode 100644 index eeaf1f2efc..0000000000 --- a/input/no-notation/safe-guile.ly +++ /dev/null @@ -1,14 +0,0 @@ -\version "2.10.0" - -\header{ - - texidoc = "This should not survive lilypond --safe-mode, and - certainly not write /tmp/safe-guile.scm" - -} - -#(write "hallo" (open-file "/tmp/safe-guile.scm" "w")) - -\score{ - c'' -} \ No newline at end of file diff --git a/input/no-notation/safe-include.ly b/input/no-notation/safe-include.ly deleted file mode 100644 index aa26b22239..0000000000 --- a/input/no-notation/safe-include.ly +++ /dev/null @@ -1,13 +0,0 @@ -\version "2.10.0" - -\header{ - - texidoc = "This should not survive lilypond --safe-mode" - -} - -\include "safe-ps.ly" - -\score{ - c'' -} \ No newline at end of file diff --git a/input/no-notation/safe-ps.ly b/input/no-notation/safe-ps.ly deleted file mode 100644 index 8a0ccca602..0000000000 --- a/input/no-notation/safe-ps.ly +++ /dev/null @@ -1,10 +0,0 @@ -\version "2.10.0" - -\header{ - texidoc = "This should not survive lilypond --safe-mode - --no-pdf --png run, and certainly not write /tmp/safe-ps.ps" -} - -\score{ - c''-"\\embeddedps{ (/tmp/safe-ps.ps) (w) file (hallo) writestring }" -} diff --git a/input/no-notation/safe-tex.ly b/input/no-notation/safe-tex.ly deleted file mode 100644 index 516146ee42..0000000000 --- a/input/no-notation/safe-tex.ly +++ /dev/null @@ -1,16 +0,0 @@ -\version "2.10.0" - -\header{ - - texidoc = "This should not survive lilypond --safe-mode run, and - certainly not write /tmp/safe-tex.tex" - - % beware - % openout_any=y lilypond --keep --safe-mode -S latexoptions=']{article} - % \let\nofiles\relax%' input/no-notation/safe-tex.ly - -} - -\score{ - c''-"\\newwrite\\barf\\immediate\\openout\\barf=/tmp/safe-tex.tex\\immediate\\write\\barf{hallo}" -} diff --git a/input/no-notation/textcresc.ly b/input/no-notation/textcresc.ly deleted file mode 100644 index 08b1fde3cc..0000000000 --- a/input/no-notation/textcresc.ly +++ /dev/null @@ -1,15 +0,0 @@ -\version "2.10.0" -\header{ -texidoc="crashes lily" -} - -\score { { - \context Voice { - \set crescendoText = "cresc." - \set crescendoSpanner = #'dashed-line - c2. r8 c8 \< \break \! c1 - } -} -\layout { line-width = 5.\cm} -} - diff --git a/input/no-notation/to-xml.ly b/input/no-notation/to-xml.ly deleted file mode 100644 index 036063fbdb..0000000000 --- a/input/no-notation/to-xml.ly +++ /dev/null @@ -1,27 +0,0 @@ -\version "2.10.0" - -fooBar = { << c''4 \\ g'4 >> } - -#(ly:set-option 'parse-protect #f) -#(load-from-path "to-xml.scm") - -#(music-to-xml fooBar (current-output-port)) - -\header { - texidoc = "@cindex To XML" - texidoc = #(string-append - "The input representation is very generic. Therefore, it - should not be hard to convert it to XML or a similar format:\n\n" - - "@example\n" - (call-with-output-string - (lambda (p) (music-to-xml fooBar p)) - ) - "@end example" ) -} - - -\score { -\fooBar -} - diff --git a/input/regression/accidental-clef-change.ly b/input/regression/accidental-clef-change.ly index 59a6b64b58..fabf9546bb 100644 --- a/input/regression/accidental-clef-change.ly +++ b/input/regression/accidental-clef-change.ly @@ -2,6 +2,11 @@ texidoc = "Accidentals are reset for clef changes." } +\layout { + ragged-right = ##t +} + + \version "2.10.0" \new Staff \relative c' { \clef treble @@ -10,4 +15,3 @@ } -\layout {ragged-right = ##t} diff --git a/input/regression/apply-context.ly b/input/regression/apply-context.ly index 9024fbe8f4..abcbd30281 100644 --- a/input/regression/apply-context.ly +++ b/input/regression/apply-context.ly @@ -24,7 +24,7 @@ This example prints a bar-number during processing on stdout. \applyContext #(lambda (tr) - (format #t "\nWe were called in barnumber ~a.\n" + (ly:progress "\nWe were called in bar number ~a.\n" (ly:context-property tr 'currentBarNumber))) c1 c1 } diff --git a/input/regression/bar-line-dotted.ly b/input/regression/bar-line-dotted.ly new file mode 100644 index 0000000000..622ca7556b --- /dev/null +++ b/input/regression/bar-line-dotted.ly @@ -0,0 +1,18 @@ + +\header { + texidoc = "The dots in a dotted bar line are in spaces." + +} + +\version "2.10.0" + +\paper { ragged-right = ##t } + +\relative \new StaffGroup << + \new Staff { + c4 \bar ":" c } + \new Staff { + c c + } +>> + diff --git a/input/regression/beam-break.ly b/input/regression/beam-break.ly index ada5d68206..c2d4a2a08e 100644 --- a/input/regression/beam-break.ly +++ b/input/regression/beam-break.ly @@ -4,10 +4,10 @@ " } -\version "2.10.0" +\version "2.11.10" \layout { ragged-right= ##t } \relative c'' { - \set Score.allowBeamBreak = ##t + \override Score.Beam #'breakable = ##t \time 3/16 c16-[ d e \break f-] } diff --git a/input/regression/beam-flat-retain-direction.ly b/input/regression/beam-flat-retain-direction.ly new file mode 100644 index 0000000000..ba03734854 --- /dev/null +++ b/input/regression/beam-flat-retain-direction.ly @@ -0,0 +1,16 @@ +\header +{ + texidoc = "Even very flat but slanted patterns should give slanted beams. " +} + +\version "2.10.7" +\layout{ + line-width = 15\cm + debug-beam-scoring = ##t +} + +\relative c'''{ + \time 2/4 + \assertBeamQuant #'(0 . 1) #'(0 . 0) + fis16[ dis b ais] cis4 +} diff --git a/input/regression/bend-dot.ly b/input/regression/bend-dot.ly index 4b55de5cd4..67a354e2f9 100644 --- a/input/regression/bend-dot.ly +++ b/input/regression/bend-dot.ly @@ -3,6 +3,10 @@ texidoc = "Bends avoid dots, but only if necessary." } +\paper { + ragged-right = ##t +} + \score { << \new Staff \relative c' { @@ -13,7 +17,3 @@ } >> } - -\paper { - ragged-right = ##t -} diff --git a/input/regression/break.ly b/input/regression/break.ly index 1611f96532..b3a88c798e 100644 --- a/input/regression/break.ly +++ b/input/regression/break.ly @@ -7,13 +7,13 @@ Breaks can be encouraged and discouraged using @code{\\break} and @code{\\noBreak}." } +\layout { + indent = 0.0 + line-width = 4.0\cm +} \relative c'' \context Voice { \emptyText c1 \noBreak c1 \noBreak \mark "nobreak" c1 \noBreak c1 \break \mark "break" c1 \break \mark "break" c1 } -\layout { - indent = 0.0 - line-width = 4.0\cm -} diff --git a/input/regression/chord-tremolo-single.ly b/input/regression/chord-tremolo-single.ly new file mode 100644 index 0000000000..f4c03abcf5 --- /dev/null +++ b/input/regression/chord-tremolo-single.ly @@ -0,0 +1,13 @@ +\version "2.10.0" + +\header{ +texidoc="Chord tremolos on a single note." +} + +\context Voice \relative c' { + \time 4/4 + \repeat "tremolo" 32 { d32 } + + c4 c4 c4 c4 c4 +} + diff --git a/input/regression/completion-heads-polyphony.ly b/input/regression/completion-heads-polyphony.ly index 63c555519a..c2802689b3 100644 --- a/input/regression/completion-heads-polyphony.ly +++ b/input/regression/completion-heads-polyphony.ly @@ -8,11 +8,6 @@ Completion heads are not fooled by polyphony with a different rhythm. } -\context Staff \relative c'' << - { c2. c bes2 } \\ - { c2. a8 g4 f4. g4 f } ->> - \layout { \context{ \Voice @@ -20,3 +15,8 @@ Completion heads are not fooled by polyphony with a different rhythm. \consists "Completion_heads_engraver" } } + +\context Staff \relative c'' << + { c2. c bes2 } \\ + { c2. a8 g4 f4. g4 f } +>> diff --git a/input/regression/context-die-staff.ly b/input/regression/context-die-staff.ly new file mode 100644 index 0000000000..b36ae93cf7 --- /dev/null +++ b/input/regression/context-die-staff.ly @@ -0,0 +1,16 @@ +\version "2.10.0" + +\header { +texidoc = "a staff should die if there is reference to it." +} +\layout { + ragged-right = ##t + line-width = 2.5 \cm + indent = 0.0 +} + +{ + << \new Staff = "q" \new Voice ="V" c1 >> + %% no \break, BreakEvent causes spurious staff + \new RhythmicStaff = "R" \new Voice = "RV" c +} diff --git a/input/regression/display-lily-tests.ly b/input/regression/display-lily-tests.ly new file mode 100644 index 0000000000..516fbb4acb --- /dev/null +++ b/input/regression/display-lily-tests.ly @@ -0,0 +1,241 @@ +\version "2.11.6" +#(use-modules (srfi srfi-13) + (ice-9 format)) + +%%% +%%% Testing utilities +%%% + +#(define (parse-lily-and-compute-lily-string chr port) + (let ((lily-string (call-with-output-string + (lambda (out) + (do ((c (read-char port) (read-char port))) + ((and (char=? c #\#) + (char=? (peek-char port) #\])) + (read-char port)) + (display c out)))))) + `(let* ((parser-clone (ly:parser-clone parser)) + (input-str (string-trim-both ,lily-string)) + (music (car (ly:music-property (parse-string-result input-str + parser-clone) + 'elements))) + (result-str (string-trim-both (music->lily-string music parser-clone)))) + (cons input-str result-str)))) + +#(read-hash-extend #\[ parse-lily-and-compute-lily-string) %{ ] %} + +#(define (lily-string->markup str) + (make-column-markup (string-split str #\NewLine))) + +#(define test-function + (let ((test-number 0)) + (lambda (parser location result-info strings) + (let ((input (car strings)) + (output (cdr strings))) + (set! test-number (1+ test-number)) + (if (not (equal? input output)) + (ly:progress "Test ~a unequal: ~a. \nin = ~a\nout = ~a\n" + test-number + (if result-info + result-info "BUG") + input output)) + + + (make-music 'SequentialMusic 'void #t) + + )))) + +test = +#(define-music-function (parser location result-info strings) (string? pair?) + (test-function parser location result-info strings)) + +%%% +%%% Tests +%%% +\header { + texidoc = "This is a test of the display-lily-music unit. Problems are reported on the +stderr of this run." +} + + +%% Sequential music +\test "" ##[ { { a b } { c d } } #] % SequentialMusic +\test "" ##[ << { a b } { c d } >> #] % SimultaneousMusic +\test "" ##[ << { a b } \\ { c d } >> #] % VoiceSeparator + +%% Chords and Notes +\test "" ##[ { ceses ces c cis cisis } #] % NoteEvent +\test "" ##[ { deses des d dis disis } #] +\test "" ##[ { eeses ees e eis eisis } #] +\test "" ##[ { feses fes f fis fisis } #] +\test "" ##[ { geses ges g gis gisis } #] +\test "" ##[ { aeses aes a ais aisis } #] +\test "" ##[ { beses bes b bis bisis } #] +\test "" ##[ { c,, d' } #] +\test "" ##[ { c' d'=' } #] +\test "" ##[ { c! c? } #] +\test "" ##[ r1.*4/3 #] % RestEvent +\test "" ##[ c1\rest #] % RestEvent +\test "" ##[ s2..*3/4 #] % SkipEvent +\test "" ##[ R1.*2/3 #] % MultiMeasureRestMusicGroup, MultiMeasureRestEvent +\test "" ##[ \skip 2.*3/4 #] % SkipMusic +\test "" ##[ < c\1 e\3 >4.*3/4-. #] % EventChord, NoteEvent, StringNumberEvent, ArticulationEvent + +%% tags +\test "" ##[ { \tag #'foo { c4 d } } #] +\test "" ##[ c-\tag #'foo -\tag #'baz -^ -. #] + +%% Graces +\test "" ##[ { \grace c8 d2 } #] % GraceMusic +\test "" ##[ { \appoggiatura c8 d2 } #] +\test "" ##[ { \acciaccatura c8 d2 } #] +\test "" ##[ { c1 \afterGrace { b,16 c } d2 } #] + +%% Clusters +\test "" ##[ { \makeClusters { c4 g } } #] % ClusterNoteEvent + +%% Figured bass +\test "" ##[ \figures { < 6 > } #] % BassFigureEvent +\test "" ##[ \figuremode { < 1-- 3- > < 2+ 4++ > < _! 7! > } #] +\test "" ##[ \figuremode { < [6 > < 5] > } #] + +%% Lyrics +\test "" ##[ \lyrics { a b } #] +\test "" ##[ \lyricmode { a -- b } #] % HyphenEvent +\test "" ##[ \lyricmode { a __ b } #] % ExtenderEvent +\test "" ##[ \lyricmode { "a " } #] % LyricEvent +\test "" ##[ \lyricsto "foo" { bla bla } #] % LyricCombineMusic +\test "" ##[ { { c d } + \addlyrics { bla bla } } #] + +%% Drums +\test "" ##[ \drums { hihat } #] +\test "" ##[ \drummode { hihat4.*3/4 } #] + +%% Expressive marks +\test "" ##[ c4 ~ #] % TieEvent +\test "" ##[ c\noBeam #] % BeamForbidEvent +\test "" ##[ c\1 #] % StringNumberEvent +\test "" ##[ { c: c:1 } #] % TremoloEvent +\test "" ##[ { c-^ c^^ c_^ } #] % ArticulationEvent +\test "" ##[ { c-+ c^+ c_+ } #] +\test "" ##[ { c-- c^- c_- } #] +\test "" ##[ { c-| c^| c_| } #] +\test "" ##[ { c-> c^> c_> } #] +\test "" ##[ { c-. c^. c_. } #] +\test "" ##[ { c-_ c^_ c__ } #] +\test "" ##[ { c-\trill c^\trill c_\trill } #] +\test "" ##[ { c-1 c^2 c_3 } #] % FingerEvent +\test "" ##[ { c-"foo" c^"foo" c_"foo" } #] % TextScriptEvent +\test "" ##[ { R1*4-"foo" R^"foo" R_"foo" } #] % MultiMeasureTextEvent +\test "" ##[ { c4-\harmonic c^\harmonic c_\harmonic } #] % HarmonicEvent +\test "" ##[ { c-\glissando c^\glissando c_\glissando } #] % GlissandoEvent +\test "" ##[ { c-\arpeggio c^\arpeggio c_\arpeggio } #] % ArpeggioEvent +\test "" ##[ { c\p c^\ff c_\sfz } #] % AbsoluteDynamicEvent +\test "" ##[ { c[ c] c^[ c^] c_[ c_] } #] % BeamEvent +\test "" ##[ { c( c) c^( c^) c_( c_) } #] % SlurEvent +\test "" ##[ { c\< c\! c^\< c^\! c_\< c_\! } #] % CrescendoEvent +\test "" ##[ { c\> c\! c^\> c^\! c_\> c_\! } #] % DecrescendoEvent +\test "" ##[ { c\( c\) c^\( c^\) c_\( c_\) } #] % PhrasingSlurEvent +\test "" ##[ { c\sustainDown c\sustainUp } #] % SustainEvent +\test "" ##[ { c\sostenutoDown c\sostenutoUp } #] % SostenutoEvent +\test "" ##[ \melisma #] +\test "" ##[ \melismaEnd #] +\test "" ##[ { c\startTextSpan c\stopTextSpan } #] % TextSpanEvent +\test "" ##[ { c\startTrillSpan c\stopTrillSpan } #] % TrillSpanEvent +\test "" ##[ { c \startStaff c \stopStaff } #] % StaffSpanEvent +\test "" ##[ { c\startGroup c\stopGroup c^\startGroup c^\stopGroup c_\startGroup c_\stopGroup } #] % NoteGroupingEvent +\test "" ##[ { c\unaCorda c\treCorde } #] % UnaCordaEvent +\test "" ##[ \breathe #] +\test "" ##[ { c \[ c \] } #] % LigatureEvent +\test "" ##[ \~ #] % PesOrFlexaEvent + +\test "" ##[ \break #] +\test "" ##[ \noBreak #] +\test "" ##[ \pageBreak #] +\test "" ##[ \noPageBreak #] +\test "" ##[ \pageTurn #] +\test "" ##[ \noPageTurn #] + +%% Checks +\test "" ##[ \octave a' #] % RelativeOctaveCheck +\test "" ##[ | #] % BarCheck + +%% Marks +\test "" ##[ \mark \default #] % MarkEvent +\test "" ##[ \mark "Allegro" #] +\test "" ##[ \tempo 4 = 120 #] % MetronomeChangeEvent + +%% key, time, clef, bar +\test "" ##[ \key \default #] % KeyChangeEvent +\test "" ##[ \key e \minor #] +\test "" ##[ \clef "bass" #] +\test "" ##[ \clef "french^2" #] +\test "" ##[ \clef "alto_3" #] +\test "" ##[ \time 2/4 #] +\test "" ##[ #(set-time-signature 5 8 '(3 2)) #] +\test "" ##[ \bar "|." #] + +%% staff switches +\test "" ##[ \autochange { c d } #] % AutoChangeMusic +\test "" ##[ { \change Staff = "up" { c d } } #] % ContextChange + +%% Tuplets +\test "" ##[ \times 2/3 { c8 d e } #] % TimeScaledMusic +\test "" ##[ \times 4/6 { c16 d e f g a } #] +%} +%% \relative and \tranpose +\test #"NOT A BUG" ##[ \relative c' { c b } #] % RelativeOctaveMusic +\test #"NOT A BUG" ##[ \transpose c d { c d } #] % TransposedMusic +%} +%% Repeats +\test "" ##[ \repeat volta 2 { c d } #] % VoltaRepeatedMusic +\test "" ##[ \repeat unfold 2 { c d } #] % UnfoldedRepeatedMusic +\test "" ##[ \repeat fold 2 { c d } #] % FoldedRepeatedMusic +\test "" ##[ \repeat percent 2 { c d } #] % PercentRepeatedMusic +\test "" ##[ \repeat tremolo 4 { c16 d } #] % TremoloRepeatedMusic +\test "" ##[ \repeat volta 2 { c4 d } \alternative { { c d } { e f } } #] % + +%% Context creation +\test "" ##[ \new Staff { c d } #] % ContextSpeccedMusic +\test "" ##[ \new Staff = "up" { c d } #] % ContextSpeccedMusic +\test "" ##[ \context Staff { c d } #] +\test "" ##[ \context Staff = "up" { c d } #] +\test "" ##[ +\new Staff \with { + \consists "Timing_engraver" + \remove "Clef_engraver" +} { c d } #] +%% Context properties +\test "" ##[ \once \set Score . skipBars = ##t #] % PropertySet +\test "" ##[ \set autoBeaming = ##f #] +\test "" ##[ \unset Score . skipBars #] % PropertyUnset +\test "" ##[ \unset autoBeaming #] +%% Layout properties +\test "" ##[ \override Staff . Stem #'thickness = #4.0 #] % OverrideProperty +\test "" ##[ \once \override Beam #'thickness = #0.6 #] +\test "" ##[ \revert Staff . Stem #'thickness #] % RevertProperty +\test "" ##[ \revert Beam #'thickness #] + +%% \applyOutput +\test "" ##[ \applyOutput #'Foo #(lambda (arg) (list)) #] +%% \applyContext +\test "" ##[ \applyContext #(lambda (arg) (list)) #] + +%% \partial +\test "" ##[ \partial 2 #] +\test "" ##[ \partial 8. #] +\test #"TODO? exotic durations in \\partial" ##[ \partial 4*2/3 #] + +%% \partcombine +\test "" ##[ \partcombine { c e } +{ d f } #] % PartCombineMusic UnrelativableMusic + +%% Cue notes +\test "" ##[ \cueDuring #"foo" #1 { c d } #] +\test "" ##[ \quoteDuring #"foo" { c d } #] + + +%% end test. + +#(read-hash-extend #\[ #f) %{ ] %} diff --git a/input/regression/dynamics-broken-hairpin.ly b/input/regression/dynamics-broken-hairpin.ly index fac525db24..439e6bd01b 100644 --- a/input/regression/dynamics-broken-hairpin.ly +++ b/input/regression/dynamics-broken-hairpin.ly @@ -4,11 +4,12 @@ texidoc = "Broken crescendi should be open on one side." } -\relative c'' { - c1 \< \break c1\! \> \break c1\! -} \layout { line-width = 4.\cm } +\relative c'' { + c1 \< \break c1\! \> \break c1\! +} + diff --git a/input/regression/finger-chords-accidental.ly b/input/regression/finger-chords-accidental.ly new file mode 100644 index 0000000000..3ae06a4e62 --- /dev/null +++ b/input/regression/finger-chords-accidental.ly @@ -0,0 +1,15 @@ +\version "2.10.8" +\header +{ + texidoc = "Scripts left of a chord avoid accidentals." +} + +\paper { + ragged-right = ##t +} + +{ + r4 + \set fingeringOrientations = #'(left) + +} diff --git a/input/regression/general-scheme-bindings.ly b/input/regression/general-scheme-bindings.ly new file mode 100644 index 0000000000..ad625ff25a --- /dev/null +++ b/input/regression/general-scheme-bindings.ly @@ -0,0 +1,18 @@ +\header { + + texidoc = "This file tests various Scheme utiliity functions." + +} + + +\version "2.11.8" + +%% todo : use macro, to show the statement tested. +#(ly:progress "~a\n" (ly:expand-environment "${HOME} $HOME $$ ")) +#(ly:font-config-display-fonts) + +#(ly:progress "~A\n" (ly:duration->string (ly:make-duration 2 2 3 7))) +#(ly:parser-parse-string (ly:parser-clone parser) "foo = #1 #(ly:progress \"hello there\n\")") + +#(ly:progress "~a\n" (ly:truncate-list! (iota 5) 10)) +#(ly:progress "~a\n" (ly:truncate-list! (iota 10) 5)) diff --git a/input/regression/glissando-no-break.ly b/input/regression/glissando-no-break.ly new file mode 100644 index 0000000000..a30f4f56e4 --- /dev/null +++ b/input/regression/glissando-no-break.ly @@ -0,0 +1,17 @@ +\header { + + texidoc = "Glissandi are not broken. Here a @code{\break} is ineffective. +Use @code{breakable} grob property to override." + +} +\version "2.11.10" +\layout { + ragged-right = ##t +} +\relative c' { + c1 + c1\glissando + \break + d'1 + d1 +} diff --git a/input/regression/glissando.ly b/input/regression/glissando.ly index 407ad0b9cb..7629873bef 100644 --- a/input/regression/glissando.ly +++ b/input/regression/glissando.ly @@ -12,10 +12,17 @@ The engraver does no time-keeping, so it involves some trickery to get } +\layout{ + line-width = 50.\mm + indent = 0 +} + \new Staff \relative c''{ - % gliss non gliss and + \override Glissando #'breakable = ##t + + %% gliss non gliss and c4 \glissando d e \glissando f \glissando \break - % consecutive + %% consecutive c \glissando d, \glissando e' << { \stemUp e8 \glissando g8 } \context Voice = VB {\stemDown \repeat unfold 4 d16 } >> @@ -23,9 +30,4 @@ The engraver does no time-keeping, so it involves some trickery to get c4 \glissando c,, \glissando c' \glissando d } -\layout{ - line-width = 50.\mm - indent = 0 -} - diff --git a/input/regression/hairpin-to-rest.ly b/input/regression/hairpin-to-rest.ly new file mode 100644 index 0000000000..3ba757d520 --- /dev/null +++ b/input/regression/hairpin-to-rest.ly @@ -0,0 +1,11 @@ +\version "2.10.8" +\header { + texidoc = "Hairpins end at the left edge of a rest." +} + +\layout{ + ragged-right=##t +} +\relative c'' { + c2\p\> r4\! +} diff --git a/input/regression/identifiers.ly b/input/regression/identifiers.ly new file mode 100644 index 0000000000..682a156204 --- /dev/null +++ b/input/regression/identifiers.ly @@ -0,0 +1,31 @@ + +\header { + texidoc = "test identifiers." + } +\version "2.10.8" + +num = #3 +mus = { c'4 } +paperId = \paper { line-width = 5.0 \cm } +layoutId = \layout { ragged-right = ##t } +perfId = \midi {} +markupId = \markup { hoi } +stringId = "title" + +% headers not allowed as Id's + +scoreId = \score { + \repeat unfold \num \mus + \layout { \layoutId } + \midi { \perfId } + } + +bookId = \book { + \score { \scoreId } + \paper { \paperId } + } + + +\book { \bookId } + + diff --git a/input/regression/instrument-name-dynamic.ly b/input/regression/instrument-name-dynamic.ly index abc315f7f3..a418315dee 100644 --- a/input/regression/instrument-name-dynamic.ly +++ b/input/regression/instrument-name-dynamic.ly @@ -6,15 +6,15 @@ pedal line spanners." } +\paper { + line-width = 3\cm + indent = 0\cm +} + \relative { \set Staff.shortInstrumentName = "foo" f1 | f1 | f1 | f1\< | f1 | f1\! | } -\paper { - line-width = 3\cm - indent = 0\cm -} - % EOF diff --git a/input/regression/lyric-combine-switch-voice.ly b/input/regression/lyric-combine-switch-voice.ly new file mode 100644 index 0000000000..b0b6d1952e --- /dev/null +++ b/input/regression/lyric-combine-switch-voice.ly @@ -0,0 +1,44 @@ +\header { + + texidoc = "Switching melody to a different voice works even +the switch occurs together with context instantiation." + +} + +\version "2.10.8" + +<< + \relative \new Voice = "lahlah" { + \set Staff.autoBeaming = ##f + c4 + << + \new Voice = "alternative" { + \voiceOne + \times 2/3 { + %% show associations clearly. + \override NoteColumn #'force-hshift = #-3 + r8 f g + } + } + { + \voiceTwo + f8.[ g16] + \oneVoice + } >> + a8( b) c + } + \new Lyrics \lyricsto "lahlah" { + %% Tricky: need to set associatedVoice + %% one syllable too soon! + + \set associatedVoice = alternative % applies to "ran" + Ty -- + ran -- + \set associatedVoice = lahlah % applies to "sau" + no -- + sau -- rus Rex + } +>> + + + diff --git a/input/regression/lyric-extender-broken.ly b/input/regression/lyric-extender-broken.ly index c7db439467..36aae288b5 100644 --- a/input/regression/lyric-extender-broken.ly +++ b/input/regression/lyric-extender-broken.ly @@ -8,6 +8,9 @@ of the melisma." } +\layout { + ragged-right = ##t +} << \new Voice =A { @@ -17,7 +20,4 @@ of the melisma." } \lyricsto A \context Lyrics \lyricmode { a __ a __ ha } >> - \layout { - ragged-right = ##t - } diff --git a/input/regression/lyric-hyphen-break.ly b/input/regression/lyric-hyphen-break.ly index c78cd759c4..c48f7c8737 100644 --- a/input/regression/lyric-hyphen-break.ly +++ b/input/regression/lyric-hyphen-break.ly @@ -8,6 +8,17 @@ they go past the first note. " } +\layout { + indent = 0.0 \cm + line-width = 3.4 \cm + + \context { + \Staff \remove "Time_signature_engraver" + } +} + + + << \new Staff \relative c'' { \time 1/4 c16[ c c c] @@ -23,15 +34,5 @@ they go past the first note. " bla16 -- bla -- bla } >> - \layout { - indent = 0.0 \cm - line-width = 3.4 \cm - - \context { - \Staff \remove "Time_signature_engraver" - } - } - - diff --git a/input/regression/markup-scheme.ly b/input/regression/markup-scheme.ly index af1b4f9121..e4589d4a9b 100644 --- a/input/regression/markup-scheme.ly +++ b/input/regression/markup-scheme.ly @@ -51,7 +51,7 @@ For maintenance reasons, we don't excercise the entire markup command set. \dynamic sfzp \huge { "A" \smaller "A" \smaller \smaller "A" \smaller \smaller \smaller "A" } - \sub "alike" + \larger \sub "alike" } \break f'1-#(markup* @@ -74,5 +74,5 @@ For maintenance reasons, we don't excercise the entire markup command set. #:dynamic "sfzp" #:huge #:line ("A" #:smaller "A" #:smaller #:smaller "A" #:smaller #:smaller #:smaller "A") - #:sub "alike") + #:larger #:sub "alike") } diff --git a/input/regression/midi-drums.ly b/input/regression/midi-drums.ly new file mode 100644 index 0000000000..2b799be25b --- /dev/null +++ b/input/regression/midi-drums.ly @@ -0,0 +1,18 @@ + +\version "2.10.0" + +\version "2.10.1" + +\score { + \new DrumStaff << + \drummode { + bd4 sn4 bd4 sn4 + << + {\voiceOne \repeat unfold 16 hh16 } + \new DrumVoice { \voiceTwo bd4 sn4 bd4 sn4 } + >> \oneVoice + } + >> + \layout {} + \midi {} +} diff --git a/input/regression/midi-dynamics.ly b/input/regression/midi-dynamics.ly new file mode 100644 index 0000000000..edff9c2f7a --- /dev/null +++ b/input/regression/midi-dynamics.ly @@ -0,0 +1,24 @@ +\header { + + texidoc = "Midi also handles crescendo and decrescendo, either + starting and ending from specified or unspecified sound level." + +} + +\version "2.11.10" + +\score { + \relative { + + \set midiMinimumVolume = #0.0 + \set midiMaximumVolume = #1.0 + c\ff c\pppp + c\ff\> c c c c\!\pppp + + c\< c c c c\! \ff + + c\> c c c \! + } + \midi {} + \layout{} +} diff --git a/input/regression/midi-grace.ly b/input/regression/midi-grace.ly new file mode 100644 index 0000000000..213de79e37 --- /dev/null +++ b/input/regression/midi-grace.ly @@ -0,0 +1,22 @@ +\version "2.10.0" +\header{ texidoc = "Tests MIDI output with grace notes. " } + +\score { + \context Voice \relative c { + \new Voice = VoiceOne + \grace { + \override Stem #'stroke-style = #"grace" + c8 + \revert Stem #'stroke-style } + d4 d d d d + \grace { + \override Stem #'stroke-style = #"grace" + e16 f e f + \revert Stem #'stroke-style } + d4 d d d d + + } + \layout { } + \midi { } +} + diff --git a/input/regression/midi-lyric-barcheck.ly b/input/regression/midi-lyric-barcheck.ly new file mode 100644 index 0000000000..5c06916af0 --- /dev/null +++ b/input/regression/midi-lyric-barcheck.ly @@ -0,0 +1,24 @@ +\version "2.10.0" +\header { + + texidoc = "Lyrics in MIDI are aligned to ties and beams: +this examples causes no bar checks in MIDI. +" + + + } +\score { + + <<\relative c'' \new Voice = A { + \autoBeamOff + c8[ c] c2. + c1~c4 c2. + c4 ( d e) d + c1 + + } + \lyricsto "A" \lyrics { bla bla | bla bla | bla bla | bla } + >> + \layout {} + \midi {} + } diff --git a/input/regression/midi-microtone.ly b/input/regression/midi-microtone.ly new file mode 100644 index 0000000000..cf1f9f1e32 --- /dev/null +++ b/input/regression/midi-microtone.ly @@ -0,0 +1,10 @@ +\version "2.10.8" +\header { + texidoc = "The pitch wheel is used for microtones." + } + +\score { + { c4 cih cis cisih d } + \midi { } + } + diff --git a/input/regression/midi-pedal.ly b/input/regression/midi-pedal.ly new file mode 100644 index 0000000000..0c4ecabcab --- /dev/null +++ b/input/regression/midi-pedal.ly @@ -0,0 +1,22 @@ +\header { + + texidoc = "Pedals. Run @code{timidity -idvvv file.midi |grep Midi} + to see midi events." + +} + +\version "2.11.10" + +\score { + \relative { + { + { c16 e g c } + + { c,16\sustainDown e g c\sustainUp } + { c,16\unaCorda e g c\treCorde } + { c,16\sostenutoDown e g c\sostenutoUp } + } + } + \midi {} + \layout{} +} diff --git a/input/regression/midi-scales.ly b/input/regression/midi-scales.ly new file mode 100644 index 0000000000..d6e8ed91c5 --- /dev/null +++ b/input/regression/midi-scales.ly @@ -0,0 +1,159 @@ + +\version "2.10.0" +% candidate for regression. -gp +\header { + texidoc="Converting LilyPond input to MIDI and then again back with + @code{midi2ly.py} is a reversible procedure in some simple cases, + which mean that the original @code{.ly} -file and the one converted + back from the generated @code{.midi} -file do not differ. + Here are produced some scales. + + " +} + +%{ + This means, doing: + + lilypond input/test/midi-scales.ly + midi2ly midi-scales.midi + diff -u input/test/midi-scales.ly midi-scales-midi.ly + + should show no differences at all in \key commands or notes. + + Therefore, do not reformat this file unless midi2ly changes. + + 1.7.30 reformatted, because + midi2ly now outpts 1 bar per line and adds bar checks and numbers. + +%} + +scales = \relative c { + + % [INSTRUMENT_NAME] bright acoustic + \key c \major % sharp-major + c'4 d e f | + g a b c | + + \key g \major + g a b c | + d e fis g | + + \key d \major + d, e fis g | + a b cis d | + + \key a \major + a b cis d | + e fis gis a | + + \key e \major + e, fis gis a | + b cis dis e | + + \key b \major + b cis dis e | + fis gis ais b | + + \key fis \major + fis, gis ais b | + cis dis eis fis | + + \key cis \major + cis, dis eis fis | + gis ais bis cis | + + \key a \minor % sharp-minor + a b c d | + e f gis a | + + \key e \minor + e, fis g a | + b c dis e | + + \key b \minor + b cis d e | + fis g ais b | + + \key fis \minor + fis, gis a b | + cis d eis fis | + + \key cis \minor + cis, dis e fis | + gis a bis cis | + + \key gis \minor + gis ais b cis | + dis e fisis gis | + + \key dis \minor + dis, eis fis gis | + ais b cisis dis | + + \key ais \minor + ais bis cis dis | + eis fis gisis ais | + + \key f \major % flat-major + f, g a bes | + c d e f | + + \key bes \major + bes c d ees | + f g a bes | + + \key ees \major + ees,, f g aes | + bes c d ees | + + \key aes \major + aes, bes c des | + ees f g aes | + + \key des \major + des,, ees f ges | + aes bes c des | + + \key ges \major + ges, aes bes ces | + des ees f ges | + + \key ces \major + ces,, des ees fes | + ges aes bes ces | + + \key d \minor % flat-minor + d, e f g | + a bes cis d | + + \key g \minor + g, a bes c | + d ees fis g | + + \key c \minor + c,, d ees f | + g aes b c | + + \key f \minor + f, g aes bes | + c des e f | + + \key bes \minor + bes,, c des ees | + f ges a bes | + + \key ees \minor + ees, f ges aes | + bes ces d ees | + + \key aes \minor + aes, bes ces des | + ees fes g aes | +} + +\score { + \context Voice \scales + \layout { } + \midi { } +} + diff --git a/input/regression/midi-transposition.ly b/input/regression/midi-transposition.ly new file mode 100644 index 0000000000..2429fef5d3 --- /dev/null +++ b/input/regression/midi-transposition.ly @@ -0,0 +1,14 @@ +\header +{ + texidoc = "should deliver f' in MIDI" +} +\version "2.10.5" + +\score { + { + \transposition f + c'' + } + \midi{} + \layout{} +} diff --git a/input/regression/midi-tuplets.ly b/input/regression/midi-tuplets.ly new file mode 100644 index 0000000000..0a0f5ef1a9 --- /dev/null +++ b/input/regression/midi-tuplets.ly @@ -0,0 +1,35 @@ +\version "2.10.0" +\header { +texidoc = " + +Midi2ly tuplet test. + +@example + python scripts/midi2ly.py --duration-quant=32 \ + --allow-tuplet=4*2/3 \ + --allow-tuplet=8*2/3 \ + --allow-tuplet=4*3/5 \ + --allow-tuplet=8*3/5 \ + tu.midi +@end example +" +} + + +\score { + \context Voice \relative c' { + + a1 a2 a2. a4 a4. a8 a8. a16 a16. a32 a32. a64 + + \times 2/3 { b4 b4 b4 } + \times 3/5 { b4 b4 b4 b4 b4 } + + \times 2/3 { c8 c8 c8 } + \times 3/5 { c8 c8 c8 c8 c8 } + + } + \layout { } + \midi { } +} + + diff --git a/input/regression/midi-volume-equaliser.ly b/input/regression/midi-volume-equaliser.ly new file mode 100644 index 0000000000..0ad06cb931 --- /dev/null +++ b/input/regression/midi-volume-equaliser.ly @@ -0,0 +1,161 @@ +\version "2.10.0" +\header { + texidoc = "@cindex Midi Volume Equaliser +The full orchestra plays a notes, where groups stop one after +another. Use this to tune equalizer settings. " +} + +#(set-global-staff-size 16) + +%{ + +Override, see scm/midi.scm: + +#(set! instrument-equalizer-alist + (append + '( + ("flute" . (0 . 0.7)) + ) + instrument-equalizer-alist)) + +%} + +flauti = \relative c' { + \set Staff.midiInstrument = #"flute" + \set Staff.instrumentName = #"2 Flauti" + \set Staff.shortInstrumentName = #"Fl." + + c1\f R1*10 +} + +oboi = \relative c' { + \set Staff.midiInstrument = #"oboe" + \set Staff.instrumentName = #"2 Oboi" + \set Staff.shortInstrumentName = #"Ob." + + R1*1 c1\f R1*9 +} + +clarinetti = \relative c' { + \set Staff.midiInstrument = #"clarinet" + \set Staff.instrumentName = #"Clarinetti" + \set Staff.shortInstrumentName = #"Cl" + + R1*2 c1\f R1*8 +} + +fagotti = \relative c' { + \set Staff.midiInstrument = #"bassoon" + \set Staff.instrumentName = #"2 Fagotti" + \set Staff.shortInstrumentName = #"Fg." + + \clef bass + R1*3 c1\f R1*7 +} + +corni = \relative c' { + \set Staff.midiInstrument = #"french horn" + \set Staff.instrumentName = #"Corni" + \set Staff.shortInstrumentName = #"Cor" + + R1*4 c1\f R1*6 +} + +trombe = \relative c' { + \set Staff.midiInstrument = #"trumpet" + \set Staff.instrumentName = #"Trombe" + \set Staff.shortInstrumentName = #"Tp." + + \clef bass + R1*5 c1\f R1*5 +} + +timpani = \relative c' { + \set Staff.midiInstrument = #"timpani" + \set Staff.instrumentName = #"Timpani" + \set Staff.shortInstrumentName = #"Timp." + + R1*6 c1\f R1*4 +} + +violinoI = \relative c' { + \set Staff.midiInstrument = #"violin" + \set Staff.instrumentName = #"Violino I " + \set Staff.shortInstrumentName = #"Vl. I " + + R1*7 c1\f R1*3 +} + +violinoII = \relative c' { + \set Staff.midiInstrument = #"violin" + \set Staff.instrumentName = #"Violino II " + \set Staff.shortInstrumentName = #"Vl. II " + + R1*8 c1\f R1*2 +} + +viola = \relative c' { + \set Staff.midiInstrument = #"viola" + \set Staff.instrumentName = #"Viola" + \set Staff.shortInstrumentName = #"Vla." + + \clef alto + R1*9 c1\f R1*1 +} + +violoncello = \relative c' { + \set Staff.midiInstrument = #"cello" + %\set Staff.midiInstrument = #"contrabass" + \set Staff.instrumentName = #"Violoncello" + \set Staff.shortInstrumentName = #"Vc." + + \clef bass + R1*10 c1\f +} + + +\score { + << + \new StaffGroup = "legni" << + \new Staff = "flauti" \flauti + \new Staff = "oboi" \oboi + \new Staff = "clarinetti" \clarinetti + \new Staff = "fagotti" \fagotti + >> + \new StaffGroup = "ottoni" << + \new Staff = "corni" \corni + \new Staff = "trombe" \trombe + >> + \new StaffGroup = "timpani" << + \new Staff = "timpani" \timpani + { + \skip 1 + %% Hmm: this forces a staff-bracket, that's good! + %% However, I can't find where is decided on staff-bracket yes/no + } + >> + \new StaffGroup = "archi" << + \new GrandStaff = "violini" << + \new Staff = "violino1" \violinoI + \new Staff = "violino2" \violinoII + >> + \new Staff = "viola" \viola + \new Staff = "violoncello" \violoncello + >> + >> + + \layout { + \context { + \RemoveEmptyStaffContext + } + } + + \midi { + \context { + \Score + tempoWholesPerMinute = #(ly:make-moment 60 1) + } + } +} + + diff --git a/input/regression/multi-measure-rest-usebreve.ly b/input/regression/multi-measure-rest-usebreve.ly new file mode 100644 index 0000000000..444becef4d --- /dev/null +++ b/input/regression/multi-measure-rest-usebreve.ly @@ -0,0 +1,24 @@ +\version "2.10.0" +\header{ + + texidoc="For longer measure lengths, the breve rest is used." + +} + +\layout { + \context { + \Score + skipBars = ##t + } + ragged-right = ##t +} + + +{ + \time 8/4 + R1*12 + \time 4/4 + R1*6 +} + + diff --git a/input/regression/multi-measure-rest.ly b/input/regression/multi-measure-rest.ly index 5fb5344018..8ea6f3155c 100644 --- a/input/regression/multi-measure-rest.ly +++ b/input/regression/multi-measure-rest.ly @@ -27,8 +27,7 @@ are used then a different symbol is used. \time 3/4 \key cis \major R2.*15 - R2. - R2.*3 + R2.*7 R2.*9 R2.*11 diff --git a/input/regression/non-empty-text.ly b/input/regression/non-empty-text.ly index efd1fa5d89..82256aac18 100644 --- a/input/regression/non-empty-text.ly +++ b/input/regression/non-empty-text.ly @@ -6,6 +6,9 @@ The boolean property @code{no-spacing-rods} in @code{TextScript} is used to control the horizontal size of text. " } +\layout { + line-width = 3.0\cm +} \relative c''{ %% \emptyText @@ -15,8 +18,5 @@ to control the horizontal size of text. " } \fatText c_"very wide and long text" c } -\layout { - line-width = 3.0\cm -} diff --git a/input/regression/note-line.ly b/input/regression/note-line.ly index f6e1a55507..392dbf0c8b 100644 --- a/input/regression/note-line.ly +++ b/input/regression/note-line.ly @@ -9,9 +9,15 @@ su = { \change Staff = up} sd = { \change Staff = down} +\layout { + line-width = 8.0 \cm +} + + \context PianoStaff << \new Staff = "up" { + \override Glissando #'breakable = ##t \set PianoStaff.connectArpeggios = ##t \showStaffSwitch \clef F @@ -21,9 +27,4 @@ sd = { \change Staff = down} \clef F s1*4 } >> - \layout { - line-width = 8.0 \cm - } - - diff --git a/input/regression/page-layout-twopass.ly b/input/regression/page-layout-twopass.ly index cf0337ef29..a046efce87 100644 --- a/input/regression/page-layout-twopass.ly +++ b/input/regression/page-layout-twopass.ly @@ -15,6 +15,7 @@ bla = \new Staff { \repeat unfold 5 \relative { c1 c1 c1 } } + \book { \score { \bla @@ -28,19 +29,4 @@ tweakFileName = #(format "~a-page-layout.ly" (ly:parser-output-name parser)) #(newline) -%% unfortunately: the following doesn't show up in lp-book output - -%% if the following is there, the tweak file will be overwritten. - -%{ - -#(ly:progress "Including file: '~a'" tweakFileName) - -\markup { - \column { - \line { contents of \typewriter tweakFileName: } - \smaller \verbatim-file #tweakFileName - } -} - -%} +#(ly:progress "Contents of: '~a'" (ly:gulp-file tweakFileName)) diff --git a/input/regression/part-combine-tuplet.ly b/input/regression/part-combine-tuplet.ly new file mode 100644 index 0000000000..b6bf5978d1 --- /dev/null +++ b/input/regression/part-combine-tuplet.ly @@ -0,0 +1,19 @@ +\header { + + texidoc = "End tuplets events are sent to the starting context, so +even after a switch, a tuplet ends correctly." + +} + +\version "2.10.8" + +\new Staff << + \partcombine + \relative c'' { + r2 + \times 2/3 { g8[ g g] } + \times 2/3 { g[ g g] } g1 + } + \relative c'' { R1 g1 } +>> + diff --git a/input/regression/profile-property-access.ly b/input/regression/profile-property-access.ly new file mode 100644 index 0000000000..39a41510d4 --- /dev/null +++ b/input/regression/profile-property-access.ly @@ -0,0 +1,47 @@ +% -*- Scheme -*- + +\header { + texidoc = "This file profiles property accesses; the log file shows the top properties examined." +} + + +#(ly:set-option 'profile-property-accesses #t) + +\version "2.10.8" + +\include "../../input/typography-demo.ly" +%\book { \score { {c4 } } } + +#(define (prop-stats>? x y) + (cond + ((> (cdr x) (cdr y)) #t) + ((= (cdr x) (cdr y)) + (symbolexact (round (/ x rnd)))))) + (alist (map (lambda (entry) (cons (car entry) (round-to (cdr entry)))) (hash-table->alist (ly:property-lookup-stats what)))) + (total (apply + (map cdr alist))) + ) + + (set! alist (acons 'TOTAL total alist)) + + (ly:progress "\n\n~A properties, top ~a rounded to ~a\n\n~a" + what count rnd + (string-join + (map (lambda (x) (format "~30a: ~6@a" (car x) (cdr x))) + (ly:truncate-list! + (sort alist prop-stats>?) count)) + "\n")))) + + + +#(display-stats 'prob) +#(display-stats 'context) +#(display-stats 'grob) + + diff --git a/input/regression/quote-cue-during.ly b/input/regression/quote-cue-during.ly index 42045c5f73..347838151f 100644 --- a/input/regression/quote-cue-during.ly +++ b/input/regression/quote-cue-during.ly @@ -11,14 +11,14 @@ last note." } -\version "2.10.0" +\version "2.11.10" \layout { ragged-right = ##t } quoteMe = \relative c' { fis4 r16 a8.-> b4(-\ff~ b16 c8. b) } -\addquote quoteMe \quoteMe +\addQuote quoteMe \quoteMe original = \relative c'' { c8 d diff --git a/input/regression/quote-cyclic.ly b/input/regression/quote-cyclic.ly index 26332e3ebe..9cc47d370a 100644 --- a/input/regression/quote-cyclic.ly +++ b/input/regression/quote-cyclic.ly @@ -6,13 +6,13 @@ example, there are notes with each full-bar rest." } -\version "2.10.0" +\version "2.11.10" A = \relative c' { c4 d e f | \cueDuring #"qB" #1 { R1 } | } B = \relative c' { \cueDuring #"qA" #1 { R1 } | f4 e d c | } -\addquote "qA" \A -\addquote "qB" \B +\addQuote "qA" \A +\addQuote "qB" \B \layout { ragged-right = ##t } diff --git a/input/regression/quote-during.ly b/input/regression/quote-during.ly index 4b2549ba00..d17d80d4c5 100644 --- a/input/regression/quote-during.ly +++ b/input/regression/quote-during.ly @@ -8,7 +8,7 @@ quoted. In this example, a 16th rests is not quoted, since @code{rest-event} is not in @code{quotedEventTypes}." } -\version "2.10.0" +\version "2.11.10" \layout { ragged-right = ##t } @@ -16,7 +16,7 @@ quoted. In this example, a 16th rests is not quoted, since quoteMe = \relative c' { fis4 r16 a8.-> b4-\ff c } -\addquote quoteMe \quoteMe +\addQuote quoteMe \quoteMe original = \relative c'' { c8 d s2 es8 gis8 } << diff --git a/input/regression/quote-grace.ly b/input/regression/quote-grace.ly index 718134d611..e612aeac3c 100644 --- a/input/regression/quote-grace.ly +++ b/input/regression/quote-grace.ly @@ -7,13 +7,13 @@ } \paper { ragged-right= ##t } -\version "2.10.0" +\version "2.11.10" quoted = \relative c'' { R1 \grace g16 f4 \grace a16 bes4 \grace b16 c4 c4 } -\addquote quoted \quoted +\addQuote quoted \quoted << diff --git a/input/regression/quote-tie.ly b/input/regression/quote-tie.ly index e9584de114..50cb66e275 100644 --- a/input/regression/quote-tie.ly +++ b/input/regression/quote-tie.ly @@ -1,4 +1,4 @@ -\version "2.10.0" +\version "2.11.10" \header { @@ -15,12 +15,12 @@ to the 2nd note. " cueI = \relative c'' { a1 ~ | a | a | } -\addquote "cueI" { \cueI } +\addQuote "cueI" { \cueI } cueII = \relative c' { R1 | e | a | } -\addquote "cueII" { \cueII } +\addQuote "cueII" { \cueII } \new Staff { \cueDuring "cueI" #UP { R1 } | diff --git a/input/regression/quote-transposition.ly b/input/regression/quote-transposition.ly index ef700dd871..ceecc579d4 100644 --- a/input/regression/quote-transposition.ly +++ b/input/regression/quote-transposition.ly @@ -10,12 +10,12 @@ quoted ones) will transposed as well. " } -\version "2.10.0" +\version "2.11.10" \layout { ragged-right = ##t } -\addquote clarinet { +\addQuote clarinet { \transposition bes d'16 d'16 d'8 d'16 d'16 d'8 @@ -23,7 +23,7 @@ quoted ones) will transposed as well. " d'16 d'16 d'8 } -\addquote sax { +\addQuote sax { \transposition es' a8 a a a a a a a } diff --git a/input/regression/quote-tuplet.ly b/input/regression/quote-tuplet.ly index 0579d4fde6..a96249540f 100644 --- a/input/regression/quote-tuplet.ly +++ b/input/regression/quote-tuplet.ly @@ -1,5 +1,5 @@ -\version "2.10.0" +\version "2.11.10" \header { @@ -12,7 +12,7 @@ foo = \relative { \times 2/3 { c4 c c } \times 2/3 { c4 c c } } -\addquote "foo" { \foo } +\addQuote "foo" { \foo } \paper { ragged-right = ##t diff --git a/input/regression/quote.ly b/input/regression/quote.ly index 4d61ee608b..1f29585f3c 100644 --- a/input/regression/quote.ly +++ b/input/regression/quote.ly @@ -7,7 +7,7 @@ things are quoted. In this example, a 16th rests is not quoted, since @code{rest-event} is not in @code{quotedEventTypes}." } -\version "2.10.0" +\version "2.11.10" \layout { ragged-right = ##t } @@ -15,7 +15,7 @@ things are quoted. In this example, a 16th rests is not quoted, since quoteMe = \relative c' { fis4 r16 a8.-> b4-\ff c } -\addquote quoteMe \quoteMe +\addQuote quoteMe \quoteMe original = \relative c'' { c8 d s2 es8 gis8 } << diff --git a/input/regression/relative-repeat.ly b/input/regression/relative-repeat.ly new file mode 100644 index 0000000000..5f0c613b41 --- /dev/null +++ b/input/regression/relative-repeat.ly @@ -0,0 +1,10 @@ +\header { + texidoc = "Relative mode for repeats uses order of entry." + } +\version "2.10.8" + +\relative { + \repeat "unfold" 3 + { f2 bes2 } + \alternative { a1 e b } +} diff --git a/input/regression/safe.ly b/input/regression/safe.ly new file mode 100644 index 0000000000..760d60faaf --- /dev/null +++ b/input/regression/safe.ly @@ -0,0 +1,21 @@ +\version "2.10.0" + +"expect-error" = ##t + +% Ugh - this affects other files too. +#(ly:set-option 'protected-scheme-parsing #t) +#(ly:set-option 'safe #t) + +"force-finish" = ##t + +\header{ + texidoc = "This should not survive lilypond --safe-mode" + + #(open-file "w") +} + + +#(open-file "/tmp/safe-guile.scm") + +\include "this-should-fail.ly" + diff --git a/input/regression/skiptypesetting-bar-check.ly b/input/regression/skiptypesetting-bar-check.ly new file mode 100644 index 0000000000..e4181833e4 --- /dev/null +++ b/input/regression/skiptypesetting-bar-check.ly @@ -0,0 +1,17 @@ +\version "2.10.0" + +\header { + +texidoc = "skipTypesetting doesn't affect bar checks." + +} + +\relative { + c4 + \set Score.skipTypesetting = ##t + c4 c4 + | + c4 c4 + \set Score.skipTypesetting = ##f + d +} diff --git a/input/regression/skyline-debug.ly b/input/regression/skyline-debug.ly new file mode 100644 index 0000000000..0180d0473e --- /dev/null +++ b/input/regression/skyline-debug.ly @@ -0,0 +1,20 @@ +\header { + texidoc = "@code{-ddebug-skyline} draws the outline of the skyline used." + } +\version "2.11.10" + +#(set-default-paper-size "a6" ) + +\header { + tagline = ##f +} + +#(ly:set-option 'debug-skylines #t) +\book { + \score { + { + a,,1 | a'4 b' c'' d'' \break + \repeat unfold 2 {a' b' c'' d''} | b''''1 + } + } +} diff --git a/input/regression/slur-nice.ly b/input/regression/slur-nice.ly index bb35666906..8399155a52 100644 --- a/input/regression/slur-nice.ly +++ b/input/regression/slur-nice.ly @@ -8,6 +8,9 @@ run through noteheads or stems. " } +\layout{ + line-width = 120.\mm +} \relative c''{ \time 3/4 @@ -19,8 +22,3 @@ run through noteheads or stems. \stemNeutral c ( \stemUp c \stemNeutral c) c ( a c) c( d, c') c( f, c') \stemDown c( f, c') } -\layout{ - line-width = 120.\mm -} - - diff --git a/input/regression/spanner-break-overshoot.ly b/input/regression/spanner-break-overshoot.ly index 7408bd11ae..6926256fdd 100644 --- a/input/regression/spanner-break-overshoot.ly +++ b/input/regression/spanner-break-overshoot.ly @@ -8,13 +8,13 @@ prefatory matter." } -\version "2.10.0" +\version "2.11.10" \paper { ragged-right = ##t } \relative c'' { \override Beam #'break-overshoot = #'(1.0 . 2.0) \override TupletBracket #'break-overshoot = #'(1.0 . 2.0) - \set allowBeamBreak = ##t + \override Beam #'breakable = ##t c2.. \times 2/3 { c8.[ \break c8.] } } diff --git a/input/regression/tie-broken-minimum-length.ly b/input/regression/tie-broken-minimum-length.ly index 51f9708a3c..2d3739e5ec 100644 --- a/input/regression/tie-broken-minimum-length.ly +++ b/input/regression/tie-broken-minimum-length.ly @@ -8,13 +8,13 @@ has a @code{minimum-length} of 5." } +\paper { + indent = 0.0\mm + line-width = 40.0\mm +} + \relative { \override Tie #'minimum-length = #5 f2. f16 f f f ~ | \break f1 } - -\paper { - indent = 0.0\mm - line-width = 40.0\mm -} diff --git a/input/regression/to-xml.ly b/input/regression/to-xml.ly new file mode 100644 index 0000000000..0a3cc4a35d --- /dev/null +++ b/input/regression/to-xml.ly @@ -0,0 +1,16 @@ +\version "2.10.0" + +testMusic = { << c''4 \\ g'4 >> } + +#(use-modules (scm to-xml)) + +#(ly:progress "\nXML:\n\n~A\n" (call-with-output-string (lambda (p) (music-to-xml testMusic p)))) + + +\header { + texidoc = + "The input representation is generic, and may be translated to XML. " +} + + +{ \testMusic } diff --git a/input/regression/tuplet-full-length.ly b/input/regression/tuplet-full-length.ly index 60da5995fc..110da8a63b 100644 --- a/input/regression/tuplet-full-length.ly +++ b/input/regression/tuplet-full-length.ly @@ -5,14 +5,14 @@ start of the next non-tuplet note. " } -\version "2.10.0" +\version "2.11.10" \paper { ragged-right = ##t indent = 0.0 } \relative c'' \new Voice \with { \remove Forbid_line_break_engraver - allowBeamBreak = ##t + \override Beam #'breakable = ##t } { \set tupletFullLength = ##t diff --git a/input/regression/tuplet-nest-beam.ly b/input/regression/tuplet-nest-beam.ly new file mode 100644 index 0000000000..d7dc560bb2 --- /dev/null +++ b/input/regression/tuplet-nest-beam.ly @@ -0,0 +1,17 @@ +\header { + + texidoc = "Nested tuplets do collision resolution, also when they + span beams." + +} + +\version "2.10.8" +\paper{ + ragged-right=##t +} + +{ + \times 4/7 { + \times 4/5 { c'8 d' e' f' g' } a' b' c'' + } +} diff --git a/input/regression/warn-conflicting-key-signatures.ly b/input/regression/warn-conflicting-key-signatures.ly new file mode 100644 index 0000000000..4b9756ee9f --- /dev/null +++ b/input/regression/warn-conflicting-key-signatures.ly @@ -0,0 +1,11 @@ +\version "2.10.0" +%If you specify two different key sigs at one point, a +%warning is printed. + +\score { +\context Voice << + { \key cis \major cis4 \key bes \major bes4 } + { \key cis \major fis4 \key es \major g4 } +>> +} + diff --git a/input/test/compound-time.ly b/input/test/compound-time.ly index 525c5a776b..a74b0baa8b 100644 --- a/input/test/compound-time.ly +++ b/input/test/compound-time.ly @@ -12,20 +12,16 @@ compound time. \layout{ragged-right = ##t} -#(define (compound-time grob one two num) - (interpret-markup - (ly:grob-layout grob) - '(((baseline-skip . 2) - (word-space . 2) - (font-family . number))) - (markup - #:line ( #:column (one num) #:lower 1 "+" #:column (two num))))) +#(define (compound-time one two num) + (markup #:override '(baseline-skip . 0) #:number + (#:line ((#:column (one num)) #:vcenter "+" (#:column (two num)))))) + \relative { %% compound time signature hack \time 5/8 - \override Staff.TimeSignature #'stencil - = #(lambda (grob) (compound-time grob "2" "3" "8")) + \override Staff.TimeSignature #'stencil = #ly:text-interface::print + \override Staff.TimeSignature #'text = #(compound-time "2" "3" "8" ) #(override-auto-beam-setting '(end 1 8 5 8) 1 4) c8 c c8 c c } diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 89d2648ae2..23b9527d29 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -146,8 +146,17 @@ get_skylines (Grob *me, vector child_refpoints; for (vsize i = 0; i < elements->size (); i++) { - extract_grob_set ((*elements)[i], "elements", child_elts); - Grob *child_common = common_refpoint_of_array (child_elts, (*elements)[i], other_axis (a)); + Grob *elt = (*elements)[i]; + Grob *child_common = unsmob_grob ((a == Y_AXIS) + ? elt->get_object ("X-common") + : elt->get_object ("Y-common")); + + if (!child_common) + { + extract_grob_set (elt, "elements", child_elts); + child_common = common_refpoint_of_array (child_elts, elt, other_axis (a)); + } + child_refpoints.push_back (child_common); } Grob *common_refpoint = common_refpoint_of_array (child_refpoints, me, other_axis (a)); diff --git a/lily/all-font-metrics.cc b/lily/all-font-metrics.cc index 61b0a60e6f..bc100e77bc 100644 --- a/lily/all-font-metrics.cc +++ b/lily/all-font-metrics.cc @@ -104,37 +104,12 @@ All_font_metrics::find_pango_font (PangoFontDescription *description, #endif -string -kpathsea_find_file (string name, string ext) -{ - name += "." + ext; - string path = global_path.find (name); - if (path.length () > 0) - return path; - - static SCM proc; - if (!proc) - { - SCM module = scm_c_resolve_module ("scm kpathsea"); - proc = scm_c_module_lookup (module, "ly:kpathsea-find-file"); - proc = scm_variable_ref (proc); - } - - if (ly_is_procedure (proc)) - { - SCM kp_result = scm_call_1 (proc, scm_makfrom0str (name.c_str ())); - if (scm_is_string (kp_result)) - return ly_scm2string (kp_result); - } - - return ""; -} Open_type_font * All_font_metrics::find_otf (string name) { SCM sname = ly_symbol2scm (name.c_str ()); - SCM name_string = scm_makfrom0str (name.c_str ()); + SCM name_string = ly_string2scm (name); SCM val; if (!otf_dict_->try_retrieve (sname, &val)) { diff --git a/lily/ambitus.cc b/lily/ambitus.cc index 1e6da083bc..b733ef615e 100644 --- a/lily/ambitus.cc +++ b/lily/ambitus.cc @@ -24,7 +24,7 @@ Ambitus::print (SCM smob) Item *me = (Item *) unsmob_grob (smob); Stencil stencil; - // join heads + // FIXME : should be Ambitus_line join heads extract_grob_set (me, "note-heads", heads); if (to_boolean (me->get_property ("join-heads")) && heads.size () > 1) diff --git a/lily/audio-column.cc b/lily/audio-column.cc index d0a36518a5..6365305675 100644 --- a/lily/audio-column.cc +++ b/lily/audio-column.cc @@ -11,9 +11,9 @@ #include "audio-item.hh" #include "performance.hh" -Audio_column::Audio_column (Moment at_mom) +Audio_column::Audio_column (Moment when) { - at_mom_ = at_mom; + when_ = when; } void @@ -24,14 +24,14 @@ Audio_column::add_audio_item (Audio_item *l) } Moment -Audio_column::at_mom () const +Audio_column::when () const { - return at_mom_; + return when_; } void -Audio_column::offset_at_mom (Moment m) +Audio_column::offset_when (Moment m) { - at_mom_ += m; + when_ += m; } diff --git a/lily/audio-item.cc b/lily/audio-item.cc index 4a3b9d4a41..3913527ea1 100644 --- a/lily/audio-item.cc +++ b/lily/audio-item.cc @@ -16,6 +16,17 @@ Audio_instrument::Audio_instrument (string instrument_string) str_ = instrument_string; } +void +Audio_item::render () +{ +} + +Audio_column * +Audio_item::get_column () const +{ + return audio_column_; +} + Audio_item::Audio_item () { audio_column_ = 0; @@ -47,11 +58,75 @@ Audio_key::Audio_key (int acc, bool major) major_ = major; } -Audio_dynamic::Audio_dynamic (Real volume) +Audio_dynamic::Audio_dynamic () +{ + volume_ = -1; +} + +Audio_span_dynamic::Audio_span_dynamic () +{ + grow_dir_ = CENTER; +} + +void +Audio_span_dynamic::add_absolute (Audio_dynamic *d) +{ + assert (d); + dynamics_.push_back (d); +} + +static Real +moment2real (Moment m) +{ + return m.main_part_.to_double () + + 0.1 * m.grace_part_.to_double (); +} + +void +Audio_span_dynamic::render () { - volume_ = volume; + if (dynamics_.size () <= 1) + return ; + + assert (dynamics_[0]->volume_ >= 0); + + if (dynamics_.back ()->volume_ > 0 + && sign (dynamics_.back ()->volume_ - dynamics_[0]->volume_) != grow_dir_) + { + dynamics_.erase (dynamics_.end () - 1); + assert (dynamics_.back ()->volume_ < 0); + } + + if (dynamics_.size () <= 1) + return ; + + Real delta_v = grow_dir_ * 0.1; + + Real start_v = dynamics_[0]->volume_; + if (dynamics_.back ()->volume_ < 0) + dynamics_.back ()->volume_ = max (min (start_v + grow_dir_ * 0.25, 1.0), 0.0); + + delta_v = dynamics_.back ()->volume_ - dynamics_[0]->volume_; + + Moment start = dynamics_[0]->get_column ()->when (); + + Real total_t = moment2real (dynamics_.back ()->get_column ()->when () - start); + + for (vsize i = 1; i < dynamics_.size(); i ++) + { + Moment dt_moment = dynamics_[i]->get_column ()->when () + - start; + + Real dt = moment2real (dt_moment); + + Real v = start_v + delta_v * (dt / total_t); + + dynamics_[i]->volume_ = v; + } } + + Audio_tempo::Audio_tempo (int per_minute_4) { per_minute_4_ = per_minute_4; diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 48766e7e52..ac413b3350 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -238,8 +238,12 @@ Auto_beam_engraver::end_beam () else { finished_beam_ = create_beam (); + if (finished_beam_) - finished_grouping_ = grouping_; + { + announce_end_grob (finished_beam_, SCM_EOL); + finished_grouping_ = grouping_; + } delete stems_; stems_ = 0; grouping_ = 0; @@ -427,5 +431,11 @@ ADD_TRANSLATOR (Auto_beam_engraver, "@ref{Stem_engraver} properties @code{stemLeftBeamCount} and " "@code{stemRightBeamCount}. ", /* create */ "Beam", - /* read */ "autoBeaming autoBeamSettings beatLength subdivideBeams", + + /* read */ + "autoBeaming " + "autoBeamSettings " + "beatLength " + "subdivideBeams ", + /* write */ ""); diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 4319bb8b92..6cebbce598 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -68,6 +68,14 @@ Axis_group_interface::relative_group_extent (vector const &elts, return r; } + +/* + FIXME: pure extent handling has a lot of ad-hoc caching. + This should be done with grob property callbacks. + + --hwn +*/ + Interval Axis_group_interface::cached_pure_height (Grob *me, vector const &elts, @@ -235,44 +243,73 @@ Axis_group_interface::generic_group_extent (Grob *me, Axis a) return ly_interval2scm (r - my_coord); } -SCM -Axis_group_interface::pure_group_height (Grob *me, int start, int end) + +Grob * +Axis_group_interface::calc_pure_elts_and_common (Grob *me) { - Grob *common = unsmob_grob (me->get_object ("common-refpoint-of-elements")); + if (Grob *c = unsmob_grob (me->get_object ("pure-Y-common"))) + return c; + + extract_grob_set (me, "elements", elts); + + vector relevant_elts; + SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?"); - if (!common) + for (vsize i = 0; i < elts.size (); i++) { - extract_grob_set (me, "elements", elts); + if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL))) + relevant_elts.push_back (elts[i]); - vector relevant_elts; - SCM is_relevant = ly_lily_module_constant ("pure-relevant"); + Item *it = dynamic_cast (elts[i]); + Direction d = LEFT; + if (it) + do + { + Item *piece = it->find_prebroken_piece (d); + if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL))) + relevant_elts.push_back (piece); + } + while (flip (&d) != LEFT); + } - for (vsize i = 0; i < elts.size (); i++) - { - if (to_boolean (scm_apply_1 (is_relevant, elts[i]->self_scm (), SCM_EOL))) - relevant_elts.push_back (elts[i]); - - Item *it = dynamic_cast (elts[i]); - Direction d = LEFT; - if (it) - do - { - Item *piece = it->find_prebroken_piece (d); - if (piece && to_boolean (scm_apply_1 (is_relevant, piece->self_scm (), SCM_EOL))) - relevant_elts.push_back (piece); - } - while (flip (&d) != LEFT); - } + Grob *common = common_refpoint_of_array (relevant_elts, me, Y_AXIS); + me->set_object ("pure-Y-common", common->self_scm ()); + + SCM ga_scm = Grob_array::make_array (); + Grob_array *ga = unsmob_grob_array (ga_scm); + ga->set_array (relevant_elts); + me->set_object ("pure-relevant-elements", ga_scm); - common = common_refpoint_of_array (relevant_elts, me, Y_AXIS); - me->set_object ("common-refpoint-of-elements", common->self_scm ()); + return common; +} - SCM ga_scm = Grob_array::make_array (); - Grob_array *ga = unsmob_grob_array (ga_scm); - ga->set_array (relevant_elts); - me->set_object ("pure-relevant-elements", ga_scm); - } +MAKE_SCHEME_CALLBACK(Axis_group_interface,calc_x_common, 1); +SCM +Axis_group_interface::calc_x_common (SCM grob) +{ + Grob *me = unsmob_grob (grob); + extract_grob_set (me, "elements", elts); + Grob *common = common_refpoint_of_array (elts, me, X_AXIS); + return common->self_scm (); +} + +MAKE_SCHEME_CALLBACK(Axis_group_interface,calc_y_common, 1); +SCM +Axis_group_interface::calc_y_common (SCM grob) +{ + Grob *me = unsmob_grob (grob); + + extract_grob_set (me, "elements", elts); + Grob *common = common_refpoint_of_array (elts, me, Y_AXIS); + return common->self_scm (); +} + +SCM +Axis_group_interface::pure_group_height (Grob *me, int start, int end) +{ + Grob *common = calc_pure_elts_and_common (me); + extract_grob_set (me, "pure-relevant-elements", elts); Real my_coord = me->relative_coordinate (common, Y_AXIS); Interval r (relative_pure_height (me, elts, common, start, end, true)); @@ -398,6 +435,10 @@ add_grobs_of_one_priority (Skyline_pair *const skylines, elements[i]->set_property ("outside-staff-priority", SCM_BOOL_F); last_affected_position[dir] = b[X_AXIS][RIGHT]; } + + /* + Ugh: quadratic. --hwn + */ elements.erase (elements.begin () + i); } } @@ -439,9 +480,11 @@ ADD_INTERFACE (Axis_group_interface, "An object that groups other layout objects.", /* properties */ + "X-common " + "Y-common " "axes " "elements " - "common-refpoint-of-elements " + "pure-Y-common " "pure-relevant-elements " "skylines " "cached-pure-extents " diff --git a/lily/beam-concave.cc b/lily/beam-concave.cc index a37005c17c..2b88e0807a 100644 --- a/lily/beam-concave.cc +++ b/lily/beam-concave.cc @@ -106,7 +106,7 @@ Beam::calc_concaveness (SCM smob) } if (stems.size () <= 2) - return SCM_UNSPECIFIED; + return scm_from_int (0); vector close_positions; vector far_positions; diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index b0d640a62b..0432218ce2 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -35,7 +35,7 @@ protected: Spanner *beam_; Stream_event *prev_start_ev_; - Stream_event *now_stop_ev_; + Stream_event *stop_ev_; Beaming_pattern *beam_info_; Beaming_pattern *finished_beam_info_; @@ -91,7 +91,7 @@ Beam_engraver::Beam_engraver () finished_beam_ = 0; finished_beam_info_ = 0; beam_info_ = 0; - now_stop_ev_ = 0; + stop_ev_ = 0; start_ev_ = 0; prev_start_ev_ = 0; } @@ -105,7 +105,7 @@ Beam_engraver::listen_beam (Stream_event *ev) if (d == START && valid_start_point ()) ASSIGN_EVENT_ONCE (start_ev_, ev); else if (d == STOP && valid_end_point ()) - ASSIGN_EVENT_ONCE (now_stop_ev_, ev); + ASSIGN_EVENT_ONCE (stop_ev_, ev); } void @@ -119,9 +119,6 @@ Beam_engraver::set_melisma (bool ml) void Beam_engraver::process_music () { - if (beam_ && !to_boolean (get_property ("allowBeamBreak"))) - context ()->get_score_context ()->set_property ("forbidBreak", SCM_BOOL_T); - if (start_ev_) { if (beam_) @@ -141,6 +138,10 @@ Beam_engraver::process_music () beam_info_ = new Beaming_pattern; /* urg, must copy to Auto_beam_engraver too */ } + + typeset_beam (); + if (stop_ev_ && beam_) + announce_end_grob (beam_, stop_ev_->self_scm ()); } void @@ -174,13 +175,12 @@ Beam_engraver::start_translation_timestep () void Beam_engraver::stop_translation_timestep () { - typeset_beam (); - if (now_stop_ev_) + if (stop_ev_) { finished_beam_ = beam_; finished_beam_info_ = beam_info_; - now_stop_ev_ = 0; + stop_ev_ = 0; beam_ = 0; beam_info_ = 0; typeset_beam (); @@ -322,7 +322,7 @@ Grace_beam_engraver::listen_beam (Stream_event *ev) if (d == START && valid_start_point ()) start_ev_ = ev; else if (d == STOP && valid_end_point ()) - now_stop_ev_ = ev; + stop_ev_ = ev; } @@ -341,7 +341,6 @@ ADD_TRANSLATOR (Grace_beam_engraver, /* read */ "beamMelismaBusy " "beatLength " - "allowBeamBreak " "subdivideBeams " , /* write */ ""); diff --git a/lily/beam-quanting.cc b/lily/beam-quanting.cc index e150a51594..0338ecd7ec 100644 --- a/lily/beam-quanting.cc +++ b/lily/beam-quanting.cc @@ -37,15 +37,17 @@ Beam_quant_parameters::fill (Grob *him) { SCM details = him->get_property ("details"); + /* + TODO: put in define-grobs.scm + */ INTER_QUANT_PENALTY = get_detail (details, ly_symbol2scm ("inter-quant-penalty"), 1000.0); SECONDARY_BEAM_DEMERIT = get_detail (details, ly_symbol2scm ("secondary-beam-demerit"), 10.0); STEM_LENGTH_DEMERIT_FACTOR = get_detail (details, ly_symbol2scm ("stem-length-demerit-factor"), 5); REGION_SIZE = get_detail (details, ly_symbol2scm ("region-size"), 2); BEAM_EPS = get_detail (details, ly_symbol2scm ("beam-eps"), 1e-3); - - // possibly ridiculous, but too short stems just won't do STEM_LENGTH_LIMIT_PENALTY = get_detail (details, ly_symbol2scm ("stem-length-limit-penalty"), 5000); DAMPING_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("damping-direction-penalty"), 800); + HINT_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("hint-direction-penalty"), 20); MUSICAL_DIRECTION_FACTOR = get_detail (details, ly_symbol2scm ("musical-direction-factor"), 400); IDEAL_SLOPE_FACTOR = get_detail (details, ly_symbol2scm ("ideal-slope-factor"), 10); ROUND_TO_ZERO_SLOPE = get_detail (details, ly_symbol2scm ("round-to-zero-slope"), 0.02); @@ -152,8 +154,8 @@ Beam::quanting (SCM smob, SCM posns) for (int a = 2; a--;) common[a] = common_refpoint_of_array (stems, me, Axis (a)); - Grob *fvs = first_visible_stem (me); - Grob *lvs = last_visible_stem (me); + Grob *fvs = first_normal_stem (me); + Grob *lvs = last_normal_stem (me); Real xl = fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; Real xr = fvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; @@ -321,7 +323,7 @@ Beam::quanting (SCM smob, SCM posns) // debug quanting me->set_property ("quant-score", - scm_makfrom0str (qscores[best_idx].score_card_.c_str ())); + ly_string2scm (qscores[best_idx].score_card_)); } #endif @@ -401,10 +403,19 @@ Beam::score_slopes_dy (Real yl, Real yr, TODO: find a way to incorporate the complexity of the beam in this penalty. */ - if (fabs (dy / dx) > parameters->ROUND_TO_ZERO_SLOPE - && sign (dy_damp) != sign (dy)) - dem += parameters->DAMPING_DIRECTION_PENALTY; - + if (sign (dy_damp) != sign (dy)) + { + if (!dy) + { + if (fabs (dy_damp / dx) > parameters->ROUND_TO_ZERO_SLOPE) + dem += parameters->DAMPING_DIRECTION_PENALTY; + else + dem += parameters->HINT_DIRECTION_PENALTY; + } + else + dem += parameters->DAMPING_DIRECTION_PENALTY; + } + dem += parameters->MUSICAL_DIRECTION_FACTOR * max (0.0, (fabs (dy) - fabs (dy_mus))); diff --git a/lily/beam.cc b/lily/beam.cc index a2e7a3cb92..ba6dc277e9 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -41,6 +41,7 @@ #include "staff-symbol-referencer.hh" #include "stem.hh" #include "warn.hh" +#include "grob-array.hh" #if DEBUG_BEAM_SCORING #include "text-interface.hh" // debug output. @@ -119,6 +120,21 @@ Beam::get_beam_count (Grob *me) return m; } +MAKE_SCHEME_CALLBACK (Beam, calc_normal_stems, 1); +SCM +Beam::calc_normal_stems (SCM smob) +{ + Grob *me = unsmob_grob (smob); + + extract_grob_set (me, "stems", stems); + SCM val = Grob_array::make_array (); + Grob_array *ga = unsmob_grob_array (val); + for (vsize i = 0; i < stems.size (); i++) + if (Stem::is_normal_stem (stems[i])) + ga->add (stems[i]); + + return val; +} MAKE_SCHEME_CALLBACK (Beam, calc_direction, 1); SCM @@ -135,7 +151,7 @@ Beam::calc_direction (SCM smob) Direction dir = CENTER; - int count = visible_stem_count (me); + int count = normal_stem_count (me); if (count < 2) { extract_grob_set (me, "stems", stems); @@ -148,7 +164,7 @@ Beam::calc_direction (SCM smob) } else { - Grob *stem = first_visible_stem (me); + Grob *stem = first_normal_stem (me); /* ugh: stems[0] case happens for chord tremolo. @@ -265,6 +281,9 @@ Beam::calc_beaming (SCM smob) } else { + /* + FIXME: what's this for? + */ SCM s = scm_cdr (this_beaming); for (; scm_is_pair (s); s = scm_cdr (s)) { @@ -460,10 +479,10 @@ Beam::print (SCM grob) vector segments = get_beam_segments (me, &commonx); Interval span; - if (visible_stem_count (me)) + if (normal_stem_count (me)) { - span[LEFT] = first_visible_stem (me)->relative_coordinate (commonx, X_AXIS); - span[RIGHT] = last_visible_stem (me)->relative_coordinate (commonx, X_AXIS); + span[LEFT] = first_normal_stem (me)->relative_coordinate (commonx, X_AXIS); + span[RIGHT] = last_normal_stem (me)->relative_coordinate (commonx, X_AXIS); } else { @@ -654,7 +673,7 @@ Beam::consider_auto_knees (Grob *me) gaps.set_full (); - extract_grob_set (me, "stems", stems); + extract_grob_set (me, "normal-stems", stems); Grob *common = common_refpoint_of_array (stems, me, Y_AXIS); Real staff_space = Staff_symbol_referencer::staff_space (me); @@ -663,8 +682,6 @@ Beam::consider_auto_knees (Grob *me) for (vsize i = 0; i < stems.size (); i++) { Grob *stem = stems[i]; - if (Stem::is_invisible (stem)) - continue; Interval head_extents = Stem::head_positions (stem); if (!head_extents.is_empty ()) @@ -724,9 +741,6 @@ Beam::consider_auto_knees (Grob *me) for (vsize i = 0; i < stems.size (); i++) { Grob *stem = stems[i]; - if (Stem::is_invisible (stem)) - continue; - Interval head_extents = head_extents_array[j++]; Direction d = (head_extents.center () < max_gap.center ()) @@ -789,7 +803,7 @@ Beam::calc_stem_shorten (SCM smob) return scm_from_int (0); Real forced_fraction = 1.0 * forced_stem_count (me) - / visible_stem_count (me); + / normal_stem_count (me); int beam_count = get_beam_count (me); @@ -825,27 +839,27 @@ Beam::calc_least_squares_positions (SCM smob, SCM posns) Grob *me = unsmob_grob (smob); - int count = visible_stem_count (me); + int count = normal_stem_count (me); Interval pos (0,0); if (count < 1) return ly_interval2scm (pos); vector x_posns; - extract_grob_set (me, "stems", stems); + extract_grob_set (me, "normal-stems", stems); Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); Grob *commony = common_refpoint_of_array (stems, me, Y_AXIS); Real my_y = me->relative_coordinate (commony, Y_AXIS); - Grob *fvs = first_visible_stem (me); - Grob *lvs = last_visible_stem (me); + Grob *fvs = first_normal_stem (me); + Grob *lvs = last_normal_stem (me); Interval ideal (Stem::get_stem_info (fvs).ideal_y_ + fvs->relative_coordinate (commony, Y_AXIS) - my_y, Stem::get_stem_info (lvs).ideal_y_ + lvs->relative_coordinate (commony, Y_AXIS) - my_y); - Real x0 = first_visible_stem (me)->relative_coordinate (commonx, X_AXIS); + Real x0 = first_normal_stem (me)->relative_coordinate (commonx, X_AXIS); for (vsize i = 0; i < stems.size (); i++) { Grob *s = stems[i]; @@ -853,7 +867,7 @@ Beam::calc_least_squares_positions (SCM smob, SCM posns) Real x = s->relative_coordinate (commonx, X_AXIS) - x0; x_posns.push_back (x); } - Real dx = last_visible_stem (me)->relative_coordinate (commonx, X_AXIS) - x0; + Real dx = last_normal_stem (me)->relative_coordinate (commonx, X_AXIS) - x0; Real y = 0; Real slope = 0; @@ -861,8 +875,8 @@ Beam::calc_least_squares_positions (SCM smob, SCM posns) Real ldy = 0.0; if (!ideal.delta ()) { - Interval chord (Stem::chord_start_y (first_visible_stem (me)), - Stem::chord_start_y (last_visible_stem (me))); + Interval chord (Stem::chord_start_y (stems[0]), + Stem::chord_start_y (stems.back ())); /* Simple beams (2 stems) on middle line should be allowed to be slightly sloped. @@ -894,9 +908,6 @@ Beam::calc_least_squares_positions (SCM smob, SCM posns) for (vsize i = 0; i < stems.size (); i++) { Grob *s = stems[i]; - if (!Stem::is_normal_stem (s)) - continue; - ideals.push_back (Offset (x_posns[i], Stem::get_stem_info (s).ideal_y_ + s->relative_coordinate (commony, Y_AXIS) @@ -942,7 +953,7 @@ Beam::shift_region_to_valid (SCM grob, SCM posns) Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); Grob *commony = common_refpoint_of_array (stems, me, Y_AXIS); - Grob *fvs = first_visible_stem (me); + Grob *fvs = first_normal_stem (me); if (!fvs) return posns; @@ -956,7 +967,7 @@ Beam::shift_region_to_valid (SCM grob, SCM posns) x_posns.push_back (x); } - Grob *lvs = last_visible_stem (me); + Grob *lvs = last_normal_stem (me); if (!lvs) return posns; @@ -1033,7 +1044,7 @@ Beam::slope_damping (SCM smob, SCM posns) Grob *me = unsmob_grob (smob); Drul_array pos = ly_scm2interval (posns); - if (visible_stem_count (me) <= 1) + if (normal_stem_count (me) <= 1) return posns; @@ -1053,13 +1064,13 @@ Beam::slope_damping (SCM smob, SCM posns) Real dy = pos[RIGHT] - pos[LEFT]; - Grob *fvs = first_visible_stem (me); - Grob *lvs = last_visible_stem (me); + Grob *fvs = first_normal_stem (me); + Grob *lvs = last_normal_stem (me); Grob *commonx = fvs->common_refpoint (lvs, X_AXIS); - Real dx = last_visible_stem (me)->relative_coordinate (commonx, X_AXIS) - - first_visible_stem (me)->relative_coordinate (commonx, X_AXIS); + Real dx = last_normal_stem (me)->relative_coordinate (commonx, X_AXIS) + - first_normal_stem (me)->relative_coordinate (commonx, X_AXIS); Real slope = dy && dx ? dy / dx : 0; @@ -1173,8 +1184,8 @@ Beam::set_stem_lengths (SCM smob) thick = get_thickness (me); } - Grob *fvs = first_visible_stem (me); - Grob *lvs = last_visible_stem (me); + Grob *fvs = first_normal_stem (me); + Grob *lvs = last_normal_stem (me); Real xl = fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; Real xr = lvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; @@ -1246,16 +1257,13 @@ Beam::set_beaming (Grob *me, Beaming_pattern const *beaming) int Beam::forced_stem_count (Grob *me) { - extract_grob_set (me, "stems", stems); + extract_grob_set (me, "normal-stems", stems); int f = 0; for (vsize i = 0; i < stems.size (); i++) { Grob *s = stems[i]; - if (Stem::is_invisible (s)) - continue; - /* I can imagine counting those boundaries as a half forced stem, but let's count them full for now. */ Direction defdir = to_dir (s->get_property ("default-direction")); @@ -1269,42 +1277,24 @@ Beam::forced_stem_count (Grob *me) } int -Beam::visible_stem_count (Grob *me) +Beam::normal_stem_count (Grob *me) { - extract_grob_set (me, "stems", stems); - int c = 0; - for (vsize i = stems.size (); i--;) - { - if (!Stem::is_invisible (stems[i])) - c++; - } - return c; + extract_grob_set (me, "normal-stems", stems); + return stems.size (); } Grob * -Beam::first_visible_stem (Grob *me) +Beam::first_normal_stem (Grob *me) { - extract_grob_set (me, "stems", stems); - - for (vsize i = 0; i < stems.size (); i++) - { - if (Stem::is_normal_stem (stems[i])) - return stems[i]; - } - return 0; + extract_grob_set (me, "normal-stems", stems); + return stems.size () ? stems[0] : 0; } Grob * -Beam::last_visible_stem (Grob *me) +Beam::last_normal_stem (Grob *me) { - extract_grob_set (me, "stems", stems); - - for (vsize i = stems.size (); i--;) - { - if (Stem::is_normal_stem (stems[i])) - return stems[i]; - } - return 0; + extract_grob_set (me, "normal-stems", stems); + return stems.size () ? stems.back () : 0; } /* @@ -1334,7 +1324,7 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset) Grob *beam = unsmob_grob (stem->get_object ("beam")); if (!beam || !Beam::has_interface (beam) - || !Beam::visible_stem_count (beam)) + || !Beam::normal_stem_count (beam)) return scm_from_double (0.0); Drul_array pos (robust_scm2drul (beam->get_property ("positions"), @@ -1346,8 +1336,8 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset) Real dy = pos[RIGHT] - pos[LEFT]; - Drul_array visible_stems (first_visible_stem (beam), - last_visible_stem (beam)); + Drul_array visible_stems (first_normal_stem (beam), + last_normal_stem (beam)); extract_grob_set (beam, "stems", stems); Grob *common = common_refpoint_of_array (stems, beam, X_AXIS); @@ -1477,6 +1467,7 @@ ADD_INTERFACE (Beam, "length-fraction " "least-squares-dy " "neutral-direction " + "normal-stems " "positions " "quant-score " "quantized-positions " diff --git a/lily/bezier.cc b/lily/bezier.cc index 77f3949992..3da46abe0f 100644 --- a/lily/bezier.cc +++ b/lily/bezier.cc @@ -14,21 +14,6 @@ Real binomial_coefficient_3[] = { 1, 3, 3, 1 }; -Real -binomial_coefficient (Real over, int under) -{ - Real x = 1.0; - - while (under) - { - x *= over / Real (under); - - over -= 1.0; - under--; - } - return x; -} - void scale (vector *array, Real x, Real y) { diff --git a/lily/book-scheme.cc b/lily/book-scheme.cc index 750917187f..23d728edf2 100644 --- a/lily/book-scheme.cc +++ b/lily/book-scheme.cc @@ -64,3 +64,33 @@ LY_DEFINE (ly_parser_print_book, "ly:book-process", return SCM_UNSPECIFIED; } + +LY_DEFINE (ly_parser_print_book_to_systems, "ly:book-process-to-systems", + 4, 0, 0, (SCM book_smob, + SCM default_paper, + SCM default_layout, + SCM output), + "Print book. @var{output} is passed to the backend unchanged. " + "Eg. it may be " + "a string (for file based outputs) or a socket (for network based " + "output).") +{ + Book *book = unsmob_book (book_smob); + + SCM_ASSERT_TYPE (book, book_smob, SCM_ARG1, __FUNCTION__, "Book"); + SCM_ASSERT_TYPE (unsmob_output_def (default_paper), + default_layout, SCM_ARG2, __FUNCTION__, "\\paper block"); + SCM_ASSERT_TYPE (unsmob_output_def (default_layout), + default_layout, SCM_ARG3, __FUNCTION__, "\\layout block"); + + Paper_book *pb = book->process (unsmob_output_def (default_paper), + unsmob_output_def (default_layout)); + if (pb) + { + pb->classic_output (output); + pb->unprotect (); + } + + return SCM_UNSPECIFIED; +} + diff --git a/lily/book.cc b/lily/book.cc index 44f7ee4ef9..2bf7b58575 100644 --- a/lily/book.cc +++ b/lily/book.cc @@ -44,13 +44,17 @@ Book::Book (Book const &s) smobify_self (); if (s.paper_) - paper_ = s.paper_->clone (); + { + paper_ = s.paper_->clone (); + paper_->unprotect (); + } input_location_ = make_input (*s.origin ()); + header_ = ly_make_anonymous_module (false); if (ly_is_module (s.header_)) ly_module_copy (header_, s.header_); - + SCM *t = &scores_; for (SCM p = s.scores_; scm_is_pair (p); p = scm_cdr (p)) { diff --git a/lily/break-alignment-interface.cc b/lily/break-alignment-interface.cc index 37eae38297..893653041e 100644 --- a/lily/break-alignment-interface.cc +++ b/lily/break-alignment-interface.cc @@ -21,22 +21,6 @@ #include "warn.hh" -MAKE_SCHEME_CALLBACK (Break_alignment_interface, self_align_callback, 1); -SCM -Break_alignment_interface::self_align_callback (SCM smob) -{ - Grob *me = unsmob_grob (smob); - - Item *item = dynamic_cast (me); - Direction bsd = item->break_status_dir (); - if (bsd == LEFT) - me->set_property ("self-alignment-X", scm_from_int (RIGHT)); - - /* - Force break alignment itself to be done first, in the case - */ - return Self_alignment_interface::aligned_on_self (me, X_AXIS); -} /* This is tricky: we cannot modify 'elements, since callers are diff --git a/lily/chord-tremolo-engraver.cc b/lily/chord-tremolo-engraver.cc index bd380facc7..1198a99dac 100644 --- a/lily/chord-tremolo-engraver.cc +++ b/lily/chord-tremolo-engraver.cc @@ -108,6 +108,7 @@ Chord_tremolo_engraver::finalize () if (beam_) { repeat_->origin ()->warning (_ ("unterminated chord tremolo")); + announce_end_grob (beam_, SCM_EOL); beam_->suicide (); } } @@ -125,8 +126,11 @@ Chord_tremolo_engraver::acknowledge_stem (Grob_info info) beam_->set_property ("gap-count", scm_from_int (flags_ - expected_beam_count_)); if (beam_dir_ == RIGHT) - beam_dir_ = LEFT; - + { + beam_dir_ = LEFT; + announce_end_grob (beam_, s->self_scm ()); + } + if (info.ultimate_event_cause ()->in_event_class ("rhythmic-event")) Beam::add_stem (beam_, s); else diff --git a/lily/chord-tremolo-iterator.cc b/lily/chord-tremolo-iterator.cc index 45ddbc443d..1a785b9c4d 100644 --- a/lily/chord-tremolo-iterator.cc +++ b/lily/chord-tremolo-iterator.cc @@ -29,7 +29,9 @@ Chord_tremolo_iterator::get_music_list () const int elt_count = body_is_sequential ? scm_ilength (body->get_property ("elements")) : 1; - if (body_is_sequential && elt_count != 2) + if (body_is_sequential && + (elt_count != 2 + && elt_count != 1)) mus->origin ()->warning (_f ("expect 2 elements for chord tremolo, found %d", elt_count)); if (elt_count <= 0) diff --git a/lily/clef.cc b/lily/clef.cc index 36427055f5..5cd041bfae 100644 --- a/lily/clef.cc +++ b/lily/clef.cc @@ -31,7 +31,7 @@ Clef::calc_glyph_name (SCM smob) str += "_change"; } - return scm_makfrom0str (str.c_str ()); + return ly_string2scm (str); } s->suicide (); diff --git a/lily/cluster.cc b/lily/cluster.cc index 8fe55dc69a..2c41b9a174 100644 --- a/lily/cluster.cc +++ b/lily/cluster.cc @@ -193,9 +193,12 @@ ADD_INTERFACE (Cluster, "The property @code{style} controls the shape of cluster segments. Valid values " "include @code{leftsided-stairs}, @code{rightsided-stairs}, @code{centered-stairs}, " "and @code{ramp}.\n", + + /* props */ "style " "padding " - "columns "); + "columns " + ); struct Cluster_beacon { diff --git a/lily/context-scheme.cc b/lily/context-scheme.cc index 9827c8bd41..825a77112e 100644 --- a/lily/context-scheme.cc +++ b/lily/context-scheme.cc @@ -20,7 +20,7 @@ LY_DEFINE (ly_context_id, "ly:context-id", Context *tr = unsmob_context (context); SCM_ASSERT_TYPE (tr, context, SCM_ARG1, __FUNCTION__, "Context"); - return scm_makfrom0str (tr->id_string ().c_str ()); + return ly_string2scm (tr->id_string ()); } LY_DEFINE (ly_context_name, "ly:context-name", diff --git a/lily/context.cc b/lily/context.cc index 45a1562b1f..9d10d5378f 100644 --- a/lily/context.cc +++ b/lily/context.cc @@ -337,7 +337,7 @@ Context::create_context (Context_def *cdef, send_stream_event (this, "CreateContext", 0, ly_symbol2scm ("ops"), ops, ly_symbol2scm ("type"), cdef->get_context_name (), - ly_symbol2scm ("id"), scm_makfrom0str (id.c_str ())); + ly_symbol2scm ("id"), ly_string2scm (id)); event_source_-> remove_listener (GET_LISTENER (acknowledge_infant), ly_symbol2scm ("AnnounceNewContext")); diff --git a/lily/dot-column-engraver.cc b/lily/dot-column-engraver.cc index ede002049f..620328ed33 100644 --- a/lily/dot-column-engraver.cc +++ b/lily/dot-column-engraver.cc @@ -16,7 +16,6 @@ class Dot_column_engraver : public Engraver { Grob *dotcol_; - vector heads_; public: TRANSLATOR_DECLARATIONS (Dot_column_engraver); @@ -36,7 +35,6 @@ void Dot_column_engraver::stop_translation_timestep () { dotcol_ = 0; - heads_.clear (); } void diff --git a/lily/dot-column.cc b/lily/dot-column.cc index a07dfcde11..6e967f3489 100644 --- a/lily/dot-column.cc +++ b/lily/dot-column.cc @@ -256,6 +256,10 @@ Dot_column::calc_positioning_done (SCM smob) } int p = Staff_symbol_referencer::get_rounded_position (dp.dot_); + + /* icky, since this should go via a Staff_symbol_referencer + offset callback but adding a dot overwrites Y-offset. */ + p += (int) robust_scm2double (dp.dot_->get_property ("staff-position"), 0.0); dp.pos_ = p; if (dp.extremal_head_) diff --git a/lily/dots.cc b/lily/dots.cc index afa82868a8..ed2d8d5636 100644 --- a/lily/dots.cc +++ b/lily/dots.cc @@ -13,7 +13,6 @@ #include "font-interface.hh" #include "lookup.hh" #include "staff-symbol-referencer.hh" -#include "directional-element-interface.hh" #include "international.hh" MAKE_SCHEME_CALLBACK (Dots, print, 1); diff --git a/lily/duration-scheme.cc b/lily/duration-scheme.cc index 361036256d..de8646e858 100644 --- a/lily/duration-scheme.cc +++ b/lily/duration-scheme.cc @@ -121,6 +121,14 @@ LY_DEFINE (ly_duration_length, "ly:duration-length", return Moment (unsmob_duration (dur)->get_length ()).smobbed_copy (); } +LY_DEFINE (ly_duration2string, "ly:duration->string", + 1, 0, 0, (SCM dur), + "Convert @var{dur} to string.") +{ + SCM_ASSERT_TYPE (unsmob_duration (dur), dur, SCM_ARG1, __FUNCTION__, "duration"); + return ly_string2scm (unsmob_duration (dur)->to_string ()); +} + LY_DEFINE (ly_duration_factor, "ly:duration-factor", 1, 0, 0, (SCM dur), "Extract the compression factor from @var{dur}. Return as a pair.") diff --git a/lily/duration.cc b/lily/duration.cc index 413ac889ec..8020cd42d4 100644 --- a/lily/duration.cc +++ b/lily/duration.cc @@ -91,7 +91,7 @@ Duration::print_smob (SCM s, SCM port, scm_print_state *) Duration *r = (Duration *) SCM_CELL_WORD_1 (s); scm_puts ("#to_string ().c_str ()), port); + scm_display (ly_string2scm (r->to_string ()), port); scm_puts (" >", port); return 1; diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index 6882939d88..e3d4f09581 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -261,7 +261,7 @@ Dynamic_engraver::process_music () if (scm_is_string (s) || scm_is_pair (s)) { cresc_->set_property ("edge-text", - scm_cons (s, scm_makfrom0str (""))); + scm_cons (s, scm_from_locale_string (""))); context ()->set_property ((start_type + "Text").c_str (), SCM_EOL); } @@ -390,7 +390,6 @@ Dynamic_engraver::typeset_all () } } - void Dynamic_engraver::acknowledge_accidental (Grob_info info) { @@ -398,7 +397,6 @@ Dynamic_engraver::acknowledge_accidental (Grob_info info) Side_position_interface::add_support (line_spanner_, info.grob ()); } - void Dynamic_engraver::acknowledge_stem_tremolo (Grob_info info) { @@ -406,7 +404,6 @@ Dynamic_engraver::acknowledge_stem_tremolo (Grob_info info) Side_position_interface::add_support (line_spanner_, info.grob ()); } - void Dynamic_engraver::acknowledge_slur (Grob_info info) { @@ -414,7 +411,6 @@ Dynamic_engraver::acknowledge_slur (Grob_info info) Side_position_interface::add_support (line_spanner_, info.grob ()); } - void Dynamic_engraver::acknowledge_note_column (Grob_info info) { diff --git a/lily/dynamic-performer.cc b/lily/dynamic-performer.cc deleted file mode 100644 index 0dd4556060..0000000000 --- a/lily/dynamic-performer.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - dynamic-performer.cc -- implement Dynamic_performer - - source file of the GNU LilyPond music typesetter - - (c) 2000--2006 Jan Nieuwenhuizen -*/ - -#include "performer.hh" - -#include "audio-item.hh" -#include "stream-event.hh" -#include "translator.icc" - -/* - TODO: - - handle multiple events - - perform absolute (text) dynamics -*/ -class Dynamic_performer : public Performer -{ -public: - TRANSLATOR_DECLARATIONS (Dynamic_performer); -protected: - void stop_translation_timestep (); - void process_music (); - - DECLARE_TRANSLATOR_LISTENER (absolute_dynamic); -private: - Stream_event *script_event_; - Audio_dynamic *audio_; -}; - -Dynamic_performer::Dynamic_performer () -{ - script_event_ = 0; - audio_ = 0; -} - -void -Dynamic_performer::process_music () -{ - if (script_event_) - { - SCM proc = get_property ("dynamicAbsoluteVolumeFunction"); - - SCM svolume = SCM_EOL; - if (ly_is_procedure (proc)) - { - // urg - svolume = scm_call_1 (proc, script_event_->get_property ("text")); - } - - Real volume = robust_scm2double (svolume, 0.5); - - /* - properties override default equaliser setting - */ - SCM min = get_property ("midiMinimumVolume"); - SCM max = get_property ("midiMaximumVolume"); - if (scm_is_number (min) || scm_is_number (max)) - { - Interval iv (0, 1); - if (scm_is_number (min)) - iv[MIN] = scm_to_double (min); - if (scm_is_number (max)) - iv[MAX] = scm_to_double (max); - volume = iv[MIN] + iv.length () * volume; - } - else - { - /* - urg, code duplication:: staff_performer - */ - SCM s = get_property ("midiInstrument"); - - if (!scm_is_string (s)) - s = get_property ("instrumentName"); - - if (!scm_is_string (s)) - s = scm_makfrom0str ("piano"); - - SCM eq = get_property ("instrumentEqualizer"); - if (ly_is_procedure (eq)) - s = scm_call_1 (eq, s); - - if (is_number_pair (s)) - { - Interval iv = ly_scm2interval (s); - volume = iv[MIN] + iv.length () * volume; - } - } - - audio_ = new Audio_dynamic (volume); - Audio_element_info info (audio_, script_event_); - announce_element (info); - script_event_ = 0; - } -} - -void -Dynamic_performer::stop_translation_timestep () -{ - if (audio_) - { - audio_ = 0; - } -} - -IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_performer, absolute_dynamic); -void -Dynamic_performer::listen_absolute_dynamic (Stream_event *r) -{ - if (!script_event_) - script_event_ = r; -} - -ADD_TRANSLATOR (Dynamic_performer, - /* doc */ "", - /* create */ "", - - /* read */ - "dynamicAbsoluteVolumeFunction " - "instrumentEqualizer " - "midiMaximumVolume " - "midiMinimumVolume " - "midiInstrument " - , - /*writes*/""); diff --git a/lily/easy-notation.cc b/lily/easy-notation.cc index c6ecb0e20f..7931d08e48 100644 --- a/lily/easy-notation.cc +++ b/lily/easy-notation.cc @@ -47,7 +47,7 @@ Note_head::brew_ez_stencil (SCM smob) char s[2] = "a"; s[0] = (pit->get_notename () + 2) % 7 + 'a'; s[0] = toupper (s[0]); - charstr = scm_makfrom0str (s); + charstr = scm_from_locale_string (s); } SCM letter diff --git a/lily/engraver.cc b/lily/engraver.cc index c8eb805638..544309138d 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -134,8 +134,8 @@ Engraver::internal_make_grob (SCM symbol, SCM cause, char const *name, char cons #ifndef NDEBUG if (ly_is_procedure (creation_callback)) scm_apply_0 (creation_callback, - scm_list_n (grob->self_scm (), scm_makfrom0str (file), - scm_from_int (line), scm_makfrom0str (fun), SCM_UNDEFINED)); + scm_list_n (grob->self_scm (), scm_from_locale_string (file), + scm_from_int (line), scm_from_locale_string (fun), SCM_UNDEFINED)); #endif return grob; diff --git a/lily/figured-bass-engraver.cc b/lily/figured-bass-engraver.cc index 025f7de6ed..d058f78059 100644 --- a/lily/figured-bass-engraver.cc +++ b/lily/figured-bass-engraver.cc @@ -286,7 +286,7 @@ Figured_bass_engraver::add_brackets () void Figured_bass_engraver::process_music () { - if (!to_boolean (get_property ("useBassFigureExtenders"))) + if (alignment_ && !to_boolean (get_property ("useBassFigureExtenders"))) clear_spanners (); if (rest_event_) diff --git a/lily/font-config-scheme.cc b/lily/font-config-scheme.cc index 482a240c9f..351319c662 100644 --- a/lily/font-config-scheme.cc +++ b/lily/font-config-scheme.cc @@ -8,13 +8,16 @@ */ #include "lily-guile.hh" -#include "std-string.hh" +#include "string-convert.hh" +#include "warn.hh" #include -void +string display_fontset (FcFontSet *fs) { + string retval; + int j; for (j = 0; j < fs->nfont; j++) { @@ -23,36 +26,42 @@ display_fontset (FcFontSet *fs) font = FcNameUnparse (fs->fonts[j]); if (FcPatternGetString (fs->fonts[j], FC_FILE, 0, &str) == FcResultMatch) - printf ("FILE %s\n", str); + retval += String_convert::form_string ("FILE %s\n", str); if (FcPatternGetString (fs->fonts[j], FC_FAMILY, 0, &str) == FcResultMatch) - printf ("family %s\n ", str); + retval += String_convert::form_string ("family %s\n ", str); if (FcPatternGetString (fs->fonts[j], "designsize", 0, &str) == FcResultMatch) - printf ("designsize %s\n ", str); + retval += String_convert::form_string ("designsize %s\n ", str); - printf ("%s\n", (const char*) font); + retval += String_convert::form_string ("%s\n", (const char*) font); free (font); } + + return retval; } -void +string display_strlist (char const*what, FcStrList *slist) { + string retval; while (FcChar8 *dir = FcStrListNext (slist)) { - printf("%s: %s\n", what, dir); + retval += String_convert::form_string ("%s: %s\n", what, dir); } + return retval; } -void +string display_config (FcConfig *fcc) { - display_strlist ("Config files", FcConfigGetConfigFiles(fcc)); - display_strlist ("Config dir", FcConfigGetConfigDirs(fcc)); - display_strlist ("Font dir", FcConfigGetFontDirs(fcc)); + string retval; + retval += display_strlist ("Config files", FcConfigGetConfigFiles(fcc)); + retval += display_strlist ("Config dir", FcConfigGetConfigDirs(fcc)); + retval += display_strlist ("Font dir", FcConfigGetFontDirs(fcc)); + return retval; } -void +string display_list (FcConfig *fcc) { FcPattern*pat = FcPatternCreate (); @@ -66,11 +75,13 @@ display_list (FcConfig *fcc) if (pat) FcPatternDestroy (pat); + string retval; if (fs) { - display_fontset (fs); + retval = display_fontset (fs); FcFontSetDestroy (fs); } + return retval; } @@ -98,7 +109,7 @@ LY_DEFINE (ly_font_config_get_font_file, "ly:font-config-get-font-file", 1, 0, 0 pat = FcFontMatch(NULL, pat, &result); FcChar8 *str = 0; if (FcPatternGetString (pat, FC_FILE, 0, &str) == FcResultMatch) - scm_result = scm_makfrom0str ((char const*) str); + scm_result = scm_from_locale_string ((char const*) str); FcPatternDestroy (pat); @@ -109,8 +120,10 @@ LY_DEFINE (ly_font_config_display_fonts, "ly:font-config-display-fonts", 0, 0, 0 (), "Dump a list of all fonts visible to FontConfig.") { - display_list (NULL); - display_config (NULL); + string str = display_list (NULL); + str += display_config (NULL); + + progress_indication (str); return SCM_UNSPECIFIED; } diff --git a/lily/font-metric-scheme.cc b/lily/font-metric-scheme.cc index d04d1eab8a..319ef80fe8 100644 --- a/lily/font-metric-scheme.cc +++ b/lily/font-metric-scheme.cc @@ -122,7 +122,7 @@ LY_DEFINE (ly_font_name, "ly:font-name", Font_metric *fm = unsmob_metrics (font); SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric"); - return scm_makfrom0str (fm->font_name ().c_str ()); + return ly_string2scm (fm->font_name ()); } LY_DEFINE (ly_font_magnification, "ly:font-magnification", 1, 0, 0, diff --git a/lily/font-metric.cc b/lily/font-metric.cc index 03625cc946..17c7796ded 100644 --- a/lily/font-metric.cc +++ b/lily/font-metric.cc @@ -40,7 +40,7 @@ Font_metric::find_by_name (string s) const { expr = scm_list_3 (ly_symbol2scm ("named-glyph"), self_scm (), - scm_makfrom0str (s.c_str ())); + ly_string2scm (s)); b = get_indexed_char (idx); } @@ -187,12 +187,9 @@ Font_metric::word_stencil (string str) const Stencil Font_metric::text_stencil (string str) const { - SCM lst = scm_list_3 (ly_symbol2scm ("text"), - this->self_scm (), - scm_makfrom0str (str.c_str ())); - - Box b = text_dimension (str); - return Stencil (b, lst); + (void) str; + assert (false); + return Stencil (Box (), SCM_EOL); } Box diff --git a/lily/function-documentation.cc b/lily/function-documentation.cc index 5081d7eb58..11b655497f 100644 --- a/lily/function-documentation.cc +++ b/lily/function-documentation.cc @@ -29,8 +29,8 @@ void ly_add_function_documentation (SCM func, + "\n" + doc; scm_set_procedure_property_x (func, ly_symbol2scm ("documentation"), - scm_makfrom0str (s.c_str ())); - SCM entry = scm_cons (scm_makfrom0str (varlist), scm_makfrom0str (doc)); + ly_string2scm (s)); + SCM entry = scm_cons (scm_from_locale_string (varlist), scm_from_locale_string (doc)); scm_hashq_set_x (doc_hash_table, ly_symbol2scm (fname), entry); } diff --git a/lily/general-scheme.cc b/lily/general-scheme.cc index 5e161474dc..dc236aa34f 100644 --- a/lily/general-scheme.cc +++ b/lily/general-scheme.cc @@ -22,6 +22,7 @@ using namespace std; #include "dimensions.hh" #include "main.hh" #include "file-path.hh" +#include "relocate.hh" LY_DEFINE (ly_find_file, "ly:find-file", 1, 0, 0, (SCM name), @@ -35,7 +36,7 @@ LY_DEFINE (ly_find_file, "ly:find-file", if (file_name.empty ()) return SCM_BOOL_F; - return scm_makfrom0str (file_name.c_str ()); + return ly_string2scm (file_name); } /* @@ -168,7 +169,7 @@ LY_DEFINE (ly_number2string, "ly:number->string", else snprintf (str, sizeof (str), "%d", int (scm_to_int (s))); - return scm_makfrom0str (str); + return scm_from_locale_string (str); } LY_DEFINE (ly_version, "ly:version", 0, 0, 0, (), @@ -182,7 +183,7 @@ LY_DEFINE (ly_version, "ly:version", 0, 0, 0, (), LY_DEFINE (ly_unit, "ly:unit", 0, 0, 0, (), "Return the unit used for lengths as a string.") { - return scm_makfrom0str (INTERNAL_UNIT); + return scm_from_locale_string (INTERNAL_UNIT); } LY_DEFINE (ly_dimension_p, "ly:dimension?", 1, 0, 0, (SCM d), @@ -208,14 +209,14 @@ LY_DEFINE (ly_gettext, "ly:gettext", { SCM_ASSERT_TYPE (scm_is_string (string), string, SCM_ARG1, __FUNCTION__, "string"); - return scm_makfrom0str (_ (scm_i_string_chars (string)).c_str ()); + return ly_string2scm (_ (scm_i_string_chars (string))); } LY_DEFINE (ly_output_backend, "ly:output-backend", 0, 0, 0, (), "Return name of output backend.") { - return scm_makfrom0str (output_backend_global.c_str ()); + return ly_string2scm (output_backend_global); } LY_DEFINE (ly_output_formats, "ly:output-formats", @@ -228,7 +229,7 @@ LY_DEFINE (ly_output_formats, "ly:output-formats", SCM lst = SCM_EOL; int output_formats_count = output_formats.size (); for (int i = 0; i < output_formats_count; i++) - lst = scm_cons (scm_makfrom0str (output_formats[i].c_str ()), lst); + lst = scm_cons (ly_string2scm (output_formats[i]), lst); return lst; } @@ -265,14 +266,14 @@ LY_DEFINE (ly_wchar_to_utf_8, "ly:wide-char->utf-8", } *p = 0; - return scm_makfrom0str (buf); + return scm_from_locale_string (buf); } LY_DEFINE (ly_effective_prefix, "ly:effective-prefix", 0, 0, 0, (), "Return effective prefix.") { - return scm_makfrom0str (prefix_directory.c_str ()); + return ly_string2scm (prefix_directory); } LY_DEFINE (ly_chain_assoc_get, "ly:chain-assoc-get", @@ -303,6 +304,7 @@ LY_DEFINE (ly_stderr_redirect, "ly:stderr-redirect", m = ly_scm2newstr (mode, 0); /* dup2 and (fileno (current-error-port)) do not work with mingw'c gcc -mwindows. */ + fflush (stderr); freopen (ly_scm2newstr (file_name, 0), m, stderr); return SCM_UNSPECIFIED; } @@ -339,3 +341,38 @@ LY_DEFINE (ly_camel_case_to_lisp_identifier, "ly:camel-case->lisp-identifier", return ly_symbol2scm (result.c_str ()); } + +LY_DEFINE (ly_expand_environment, "ly:expand-environment", + 1, 0, 0, (SCM str), + "Expand $VAR and $@{VAR@} in @var{str}.") +{ + SCM_ASSERT_TYPE(scm_is_string (str), str, + SCM_ARG1, __FUNCTION__, "string"); + + return ly_string2scm (expand_environment_variables (ly_scm2string (str))); +} + + +LY_DEFINE (ly_truncate_list_x, "ly:truncate-list!", + 2, 0, 0, (SCM lst, SCM i), + "Take at most the first @var{i} of list @var{lst}") +{ + SCM_ASSERT_TYPE(scm_is_integer (i), i, + SCM_ARG1, __FUNCTION__, "integer"); + + int k = scm_to_int (i); + if (k == 0) + lst = SCM_EOL; + else + { + SCM s = lst; + k--; + for (; scm_is_pair (s) && k--; s = scm_cdr (s)) + ; + + if (scm_is_pair (s)) + scm_set_cdr_x (s, SCM_EOL); + } + return lst; +} + diff --git a/lily/glissando-engraver.cc b/lily/glissando-engraver.cc index 4c506df38d..a6888b827c 100644 --- a/lily/glissando-engraver.cc +++ b/lily/glissando-engraver.cc @@ -7,11 +7,13 @@ */ #include "engraver.hh" + #include "international.hh" #include "rhythmic-head.hh" #include "spanner.hh" #include "stream-event.hh" #include "warn.hh" +#include "item.hh" #include "translator.icc" @@ -65,15 +67,19 @@ Glissando_engraver::acknowledge_rhythmic_head (Grob_info info) line_->set_bound (LEFT, g); if (last_line_) - last_line_->set_bound (RIGHT, g); + { + last_line_->set_bound (RIGHT, g); + announce_end_grob (last_line_, g->self_scm ()); + } } void Glissando_engraver::stop_translation_timestep () { if (last_line_ && last_line_->get_bound (RIGHT)) - last_line_ = 0; - + { + last_line_ = 0; + } if (line_) { if (last_line_) diff --git a/lily/grob-info.cc b/lily/grob-info.cc index 62af8f3256..aa6583f927 100644 --- a/lily/grob-info.cc +++ b/lily/grob-info.cc @@ -19,6 +19,11 @@ Grob_info::Grob_info (Translator *t, Grob *g) origin_trans_ = t; grob_ = g; start_end_ = START; + + /* + assert here, because this is easier to debug. + */ + assert (g); } Grob_info::Grob_info () diff --git a/lily/grob-interface.cc b/lily/grob-interface.cc index c47937db0f..278afa84e6 100644 --- a/lily/grob-interface.cc +++ b/lily/grob-interface.cc @@ -26,7 +26,7 @@ SCM add_interface (char const *cxx_name, lispy_name += suffix; SCM s = ly_symbol2scm (lispy_name.c_str ()); - SCM d = scm_makfrom0str (descr); + SCM d = scm_from_locale_string (descr); SCM l = parse_symbol_list (vars); ly_add_interface (s, d, l); diff --git a/lily/grob-pitch-tuple.cc b/lily/grob-pitch-tuple.cc deleted file mode 100644 index eb72a367e1..0000000000 --- a/lily/grob-pitch-tuple.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - grob-pitch-tuple.cc -- implement Grob_pitch_tuple - - source file of the GNU LilyPond music typesetter - - (c) 2001--2006 Han-Wen Nienhuys -*/ - -#include "grob-pitch-tuple.hh" - -#include "music.hh" - -int compare (Grob_pitch_tuple const &a, Grob_pitch_tuple const &b) -{ - return Grob_pitch_tuple::time_compare (a, b); -} - -Grob_pitch_tuple::Grob_pitch_tuple () -{ - head_ = 0; - end_ = 0; -} - -Grob_pitch_tuple::Grob_pitch_tuple (Grob *h, Music *m, Moment mom) -{ - head_ = h; - pitch_ = *unsmob_pitch (m->get_property ("pitch")); - end_ = mom; -} - -/* - signed compare, should use pitchtry_callback (sym, val); + Grob *me = ((Grob*)this); + val = me->try_callback_on_alist (&me->mutable_property_alist_, sym, val); } return val; @@ -151,15 +162,14 @@ bool debug_property_callbacks = 0; #endif SCM -Grob::try_callback (SCM sym, SCM proc) +Grob::try_callback_on_alist (SCM *alist, SCM sym, SCM proc) { SCM marker = ly_symbol2scm ("calculation-in-progress"); /* need to put a value in SYM to ensure that we don't get a cyclic call chain. */ - mutable_property_alist_ - = scm_assq_set_x (mutable_property_alist_, sym, marker); + *alist = scm_assq_set_x (*alist, sym, marker); #ifndef NDEBUG if (debug_property_callbacks) @@ -175,6 +185,7 @@ Grob::try_callback (SCM sym, SCM proc) simple_closure_expression (proc), false, 0, 0); } + #ifndef NDEBUG if (debug_property_callbacks) grob_property_callback_stack = scm_cdr (grob_property_callback_stack); @@ -188,12 +199,13 @@ Grob::try_callback (SCM sym, SCM proc) if (value == SCM_UNSPECIFIED) { value = internal_get_property (sym); + assert (value == SCM_EOL || value == marker); if (value == marker) - mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, marker); + *alist = scm_assq_remove_x (*alist, marker); } else - set_property (sym, value); - + internal_set_value_on_alist (alist, sym, value); + return value; } @@ -216,13 +228,25 @@ Grob::internal_del_property (SCM sym) SCM Grob::internal_get_object (SCM sym) const { -#ifdef PROFILE_PROPERTY_ACCESSES - note_property_access (&grob_property_lookup_table, sym); -#endif + if (profile_property_accesses) + note_property_access (&grob_property_lookup_table, sym); SCM s = scm_sloppy_assq (sym, object_alist_); + + if (s != SCM_BOOL_F) + { + SCM val = scm_cdr (s); + if (ly_is_procedure (val) + || is_simple_closure (val)) + { + Grob *me = ((Grob*)this); + val = me->try_callback_on_alist (&me->object_alist_, sym, val); + } + + return val; + } - return (s == SCM_BOOL_F) ? SCM_EOL : scm_cdr (s); + return SCM_EOL; } bool diff --git a/lily/grob.cc b/lily/grob.cc index 91f8ce5016..0738e80869 100644 --- a/lily/grob.cc +++ b/lily/grob.cc @@ -59,7 +59,16 @@ Grob::Grob (SCM basicprops, SCM meta = get_property ("meta"); if (scm_is_pair (meta)) - interfaces_ = scm_cdr (scm_assq (ly_symbol2scm ("interfaces"), meta)); + { + interfaces_ = scm_cdr (scm_assq (ly_symbol2scm ("interfaces"), meta)); + + SCM object_cbs = scm_assq (ly_symbol2scm ("object-callbacks"), meta); + if (scm_is_pair (object_cbs)) + { + for (SCM s = scm_cdr (object_cbs); scm_is_pair (s); s = scm_cdr (s)) + set_object (scm_caar (s), scm_cdar (s)); + } + } if (get_property_data ("X-extent") == SCM_EOL) set_property ("X-extent", Grob::stencil_width_proc); @@ -644,15 +653,10 @@ ADD_INTERFACE (Grob, "transparent " ); - - - - /**************************************************************** CALLBACKS ****************************************************************/ - static SCM grob_stencil_extent (Grob *me, Axis a) { diff --git a/lily/guile-init.cc b/lily/guile-init.cc index 77fd7c59f3..e891fc7699 100644 --- a/lily/guile-init.cc +++ b/lily/guile-init.cc @@ -41,7 +41,7 @@ ly_init_ly_module (void *) progress_indication ("]\n"); } - scm_primitive_load_path (scm_makfrom0str ("lily.scm")); + scm_primitive_load_path (scm_from_locale_string ("lily.scm")); } SCM global_lily_module; diff --git a/lily/hairpin.cc b/lily/hairpin.cc index e0916cd99d..6bb83b16a6 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -9,16 +9,15 @@ #include "hairpin.hh" #include "dimensions.hh" -#include "font-interface.hh" #include "international.hh" #include "line-interface.hh" -#include "lookup.hh" #include "output-def.hh" #include "paper-column.hh" #include "pointer-group-interface.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" #include "text-interface.hh" +#include "note-column.hh" #include "warn.hh" MAKE_SCHEME_CALLBACK (Hairpin, after_line_breaking, 1); @@ -167,7 +166,12 @@ Hairpin::print (SCM smob) } else { - x_points[d] = e[d]; + if (Note_column::has_interface (b) + && Note_column::has_rests (b)) + x_points[d] = e[-d]; + else + x_points[d] = e[d]; + Item *bound = me->get_bound (d); if (bound->is_non_musical (bound)) x_points[d] -= d * padding; diff --git a/lily/hara-kiri-group-spanner.cc b/lily/hara-kiri-group-spanner.cc index 90a06f145a..061b472126 100644 --- a/lily/hara-kiri-group-spanner.cc +++ b/lily/hara-kiri-group-spanner.cc @@ -119,15 +119,6 @@ Hara_kiri_group_spanner::consider_suicide (Grob *me) We can't rely on offsets and dimensions of elements in a hara-kiri group. Use a callback to make sure that hara-kiri has been done before asking for offsets. */ -MAKE_SCHEME_CALLBACK (Hara_kiri_group_spanner, after_line_breaking, 1); -SCM -Hara_kiri_group_spanner::after_line_breaking (SCM smob) -{ - Grob *me = unsmob_grob (smob); - consider_suicide (me); - return SCM_UNSPECIFIED; -} - MAKE_SCHEME_CALLBACK (Hara_kiri_group_spanner, force_hara_kiri_callback, 1); SCM Hara_kiri_group_spanner::force_hara_kiri_callback (SCM smob) diff --git a/lily/includable-lexer.cc b/lily/includable-lexer.cc index 65bea4d00b..29b7d9e5f3 100644 --- a/lily/includable-lexer.cc +++ b/lily/includable-lexer.cc @@ -41,19 +41,12 @@ Includable_lexer::Includable_lexer () #if HAVE_FLEXLEXER_YY_CURRENT_BUFFER yy_current_buffer = 0; #endif - allow_includes_b_ = true; } /** Set the new input file to NAME, remember old file. */ void Includable_lexer::new_input (string name, Sources *sources) { - if (!allow_includes_b_) - { - LexerError (_ ("include files are not allowed in safe mode").c_str ()); - return; - } - Source_file *file = sources->get_file (&name); if (!file) { diff --git a/lily/include/audio-column.hh b/lily/include/audio-column.hh index 1cc827a276..1d0fb5ca18 100644 --- a/lily/include/audio-column.hh +++ b/lily/include/audio-column.hh @@ -19,21 +19,21 @@ class Audio_column : public Audio_element { public: - Audio_column (Moment at_mom); + Audio_column (Moment when); void add_audio_item (Audio_item *i); - Moment at_mom () const; + Moment when () const; vector audio_items_; protected: - void offset_at_mom (Moment m); + void offset_when (Moment m); friend class Score_performer; private: Audio_column (Audio_column const &); - Moment at_mom_; + Moment when_; }; #endif // AUDIO_COLUMN_HH diff --git a/lily/include/audio-item.hh b/lily/include/audio-item.hh index e6f0c9ad91..d450582feb 100644 --- a/lily/include/audio-item.hh +++ b/lily/include/audio-item.hh @@ -21,7 +21,10 @@ class Audio_item : public Audio_element public: Audio_item (); Audio_column *audio_column_; + Audio_column *get_column () const; + virtual void render (); + private: Audio_item (Audio_item const &); Audio_item &operator = (Audio_item const &); @@ -30,11 +33,24 @@ private: class Audio_dynamic : public Audio_item { public: - Audio_dynamic (Real volume); + Audio_dynamic (); Real volume_; }; +class Audio_span_dynamic : public Audio_element +{ +public: + Direction grow_dir_; + vector dynamics_; + + + virtual void render (); + void add_absolute (Audio_dynamic*); + Audio_span_dynamic (); +}; + + class Audio_key : public Audio_item { public: diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh index 4272b1a890..a4201d006c 100644 --- a/lily/include/axis-group-interface.hh +++ b/lily/include/axis-group-interface.hh @@ -19,6 +19,8 @@ struct Axis_group_interface static SCM generic_group_extent (Grob *me, Axis a); static SCM pure_group_height (Grob *me, int start, int end); DECLARE_SCHEME_CALLBACK (width, (SCM smob)); + DECLARE_SCHEME_CALLBACK (calc_x_common, (SCM smob)); + DECLARE_SCHEME_CALLBACK (calc_y_common, (SCM smob)); DECLARE_SCHEME_CALLBACK (height, (SCM smob)); DECLARE_SCHEME_CALLBACK (pure_height, (SCM smob, SCM start, SCM end)); DECLARE_SCHEME_CALLBACK (calc_skylines, (SCM smob)); @@ -31,6 +33,7 @@ struct Axis_group_interface static Interval cached_pure_height (Grob *me, vector const &list, Grob *common, int, int); + static Grob *calc_pure_elts_and_common (Grob*); static Skyline_pair skyline_spacing (Grob *me, vector elements); static void add_element (Grob *me, Grob *); static void set_axes (Grob *, Axis, Axis); diff --git a/lily/include/beam.hh b/lily/include/beam.hh index 67daab8de8..f521f180c2 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -34,6 +34,7 @@ struct Beam_quant_parameters Real STEM_LENGTH_LIMIT_PENALTY; Real DAMPING_DIRECTION_PENALTY; Real MUSICAL_DIRECTION_FACTOR; + Real HINT_DIRECTION_PENALTY; Real IDEAL_SLOPE_FACTOR; Real ROUND_TO_ZERO_SLOPE; @@ -68,9 +69,9 @@ bool operator <(Beam_stem_segment const &a, Beam_stem_segment const &b); class Beam { public: - static int visible_stem_count (Grob *); - static Grob *first_visible_stem (Grob *); - static Grob *last_visible_stem (Grob *); + static int normal_stem_count (Grob *); + static Grob *first_normal_stem (Grob *); + static Grob *last_normal_stem (Grob *); DECLARE_GROB_INTERFACE(); static void add_stem (Grob *, Grob *); static bool is_knee (Grob *); @@ -89,6 +90,7 @@ public: DECLARE_SCHEME_CALLBACK (calc_direction, (SCM)); DECLARE_SCHEME_CALLBACK (calc_positions, (SCM)); DECLARE_SCHEME_CALLBACK (calc_least_squares_positions, (SCM, SCM)); + DECLARE_SCHEME_CALLBACK (calc_normal_stems, (SCM)); DECLARE_SCHEME_CALLBACK (calc_concaveness, (SCM)); DECLARE_SCHEME_CALLBACK (set_stem_lengths, (SCM)); diff --git a/lily/include/context-handle.hh b/lily/include/context-handle.hh index e32bc29cb7..2eaeaca852 100644 --- a/lily/include/context-handle.hh +++ b/lily/include/context-handle.hh @@ -6,13 +6,11 @@ (c) 1999--2006 Han-Wen Nienhuys */ -#ifndef INTERPRETATION_CONTEXT_HANDLE_HH -#define INTERPRETATION_CONTEXT_HANDLE_HH +#ifndef CONTEXT_HANDLE_HH +#define CONTEXT_HANDLE_HH + #include "lily-proto.hh" -/* - Rename me to Context_handle. -*/ class Context_handle { @@ -32,5 +30,5 @@ private: void up (Context *); }; -#endif /* INTERPRETATION_CONTEXT_HANDLE_HH */ +#endif /* CONTEXT_HANDLE_HH */ diff --git a/lily/include/grob-pitch-tuple.hh b/lily/include/grob-pitch-tuple.hh index 325e3fa0a4..e69de29bb2 100644 --- a/lily/include/grob-pitch-tuple.hh +++ b/lily/include/grob-pitch-tuple.hh @@ -1,30 +0,0 @@ -/* - grob-pitch-tuple.hh -- declare Grob_pitch_tuple - - source file of the GNU LilyPond music typesetter - - (c) 2001--2006 Han-Wen Nienhuys -*/ - -#ifndef GROB_PITCH_TUPLE_HH -#define GROB_PITCH_TUPLE_HH - -#include "pitch.hh" -#include "moment.hh" - -struct Grob_pitch_tuple -{ - Pitch pitch_; - Grob *head_; - Moment end_; - - Grob_pitch_tuple (); - Grob_pitch_tuple (Grob *, Music *, Moment); - static int pitch_compare (Grob_pitch_tuple const &, Grob_pitch_tuple const &); - static int time_compare (Grob_pitch_tuple const &, Grob_pitch_tuple const &); -}; - -int compare (Grob_pitch_tuple const &, Grob_pitch_tuple const &); - -#endif /* GROB_PITCH_TUPLE_HH */ - diff --git a/lily/include/grob.hh b/lily/include/grob.hh index 3a06afda20..08ad8c7835 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -44,6 +44,9 @@ protected: void substitute_object_links (SCM, SCM); Real get_offset (Axis a) const; SCM try_callback (SCM, SCM); + SCM try_callback_on_alist (SCM *, SCM, SCM); + void internal_set_value_on_alist (SCM *alist, SCM sym, SCM val); + public: /* friends */ diff --git a/lily/include/includable-lexer.hh b/lily/include/includable-lexer.hh index 5f03e97854..c103ba97f5 100644 --- a/lily/include/includable-lexer.hh +++ b/lily/include/includable-lexer.hh @@ -33,7 +33,6 @@ protected: vector char_count_stack_; public: - bool allow_includes_b_; Includable_lexer (); ~Includable_lexer (); @@ -42,9 +41,10 @@ public: vector file_name_strings_; Source_file *get_source_file () const; - void new_input (string s, Sources *); + virtual void new_input (string s, Sources *); + void new_input (string name, string data, Sources *); - + char const *here_str0 () const; }; diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index e94d8ef557..c0621d2639 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -43,6 +43,7 @@ extern SCM global_lily_module; string gulp_file_to_string (string fn, bool must_exist, int size); +SCM ly_string2scm (string const &s); string ly_scm2string (SCM s); string ly_symbol2string (SCM); Rational ly_scm2rational (SCM); diff --git a/lily/include/lily-lexer.hh b/lily/include/lily-lexer.hh index 994d185f6f..5609f53f4d 100644 --- a/lily/include/lily-lexer.hh +++ b/lily/include/lily-lexer.hh @@ -55,7 +55,7 @@ public: Lily_lexer (Sources *, Lily_parser *); Lily_lexer (Lily_lexer const &, Lily_parser *); int yylex (); - + void add_lexed_char (int); void prepare_for_next_token (); @@ -69,6 +69,9 @@ public: void start_main_input (); + virtual void new_input (string s, Sources *); + virtual void new_input (string s, string d, Sources *); + SCM keyword_list () const; SCM lookup_identifier (string s); SCM lookup_identifier_symbol (SCM s); diff --git a/lily/include/lily-parser.hh b/lily/include/lily-parser.hh index b07734769a..3acfd8a596 100644 --- a/lily/include/lily-parser.hh +++ b/lily/include/lily-parser.hh @@ -57,6 +57,8 @@ public: void parser_error (string); void parser_error (Input const &, string); void set_yydebug (bool); + + SCM make_scope () const; }; DECLARE_UNSMOB (Lily_parser, lily_parser); diff --git a/lily/include/lookup.hh b/lily/include/lookup.hh index db5f2d9cc7..cbd10549b0 100644 --- a/lily/include/lookup.hh +++ b/lily/include/lookup.hh @@ -31,6 +31,7 @@ struct Lookup static Stencil repeat_slash (Real w, Real slope, Real th); static Stencil horizontal_line (Interval w, Real th); static Stencil triangle (Interval, Real, Real); + static Stencil points_to_line_stencil (Real thick, vector const &points); }; #endif // LOOKUP_HH diff --git a/lily/include/music.hh b/lily/include/music.hh index f7e4407f3b..7b290482fa 100644 --- a/lily/include/music.hh +++ b/lily/include/music.hh @@ -66,6 +66,6 @@ SCM ly_camel_case_to_lisp_identifier (SCM name_sym); extern SCM ly_music_p_proc; /* common transposition function for music and event */ -SCM transpose_mutable (SCM alist, Pitch delta); +void transpose_mutable (SCM alist, Pitch delta); #endif /* MUSIC_HH */ diff --git a/lily/include/output-def.hh b/lily/include/output-def.hh index 6a6165037e..5d024c7b66 100644 --- a/lily/include/output-def.hh +++ b/lily/include/output-def.hh @@ -49,9 +49,6 @@ public: Input input_origin_; string user_key_; - Lily_parser *parser_; - Lily_parser *get_parser () const; - Output_def (Output_def const&); Output_def (); diff --git a/lily/include/profile.hh b/lily/include/profile.hh index fff7fa225c..d8d4eff957 100644 --- a/lily/include/profile.hh +++ b/lily/include/profile.hh @@ -14,5 +14,7 @@ void note_property_access (SCM *table, SCM sym); extern SCM context_property_lookup_table; extern SCM grob_property_lookup_table; +extern SCM prob_property_lookup_table; +extern bool profile_property_accesses; #endif /* PROFILE_HH */ diff --git a/lily/include/program-option.hh b/lily/include/program-option.hh index 55971a1fa1..bf5e253d59 100644 --- a/lily/include/program-option.hh +++ b/lily/include/program-option.hh @@ -15,7 +15,6 @@ extern bool do_midi_debugging_global; extern int testing_level_global; extern bool lily_1_8_relative; extern bool lily_1_8_compatibility_used; -extern bool profile_property_accesses; SCM ly_get_option (SCM); SCM ly_set_option (SCM, SCM); diff --git a/lily/include/relocate.hh b/lily/include/relocate.hh index e3af270a88..df541f9d20 100644 --- a/lily/include/relocate.hh +++ b/lily/include/relocate.hh @@ -1,5 +1,5 @@ /* - relocate.hh -- declare + relocate.hh -- declare relocation functions source file of the GNU LilyPond music typesetter diff --git a/lily/include/rest.hh b/lily/include/rest.hh index 20107120b7..5399c203fd 100644 --- a/lily/include/rest.hh +++ b/lily/include/rest.hh @@ -25,5 +25,6 @@ public: DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (width, (SCM)); DECLARE_SCHEME_CALLBACK (height, (SCM)); + DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM)); }; #endif // REST_HH diff --git a/lily/include/skyline.hh b/lily/include/skyline.hh index 36fd9d23e4..ab8fe30c65 100644 --- a/lily/include/skyline.hh +++ b/lily/include/skyline.hh @@ -32,7 +32,7 @@ struct Building void print () const; Real height (Real x) const; - Real intersection (Building const &other) const; + Real intersection_x (Building const &other) const; void leading_part (Real chop); bool conceals_beginning (Building const &other) const; bool conceals (Building const &other) const; diff --git a/lily/include/spaceable-grob.hh b/lily/include/spaceable-grob.hh index cb1217bf6f..b7e54875b6 100644 --- a/lily/include/spaceable-grob.hh +++ b/lily/include/spaceable-grob.hh @@ -20,7 +20,6 @@ struct Spaceable_grob static void get_spring (Grob *me, Grob *other, Real *dist, Real *inv_strength); DECLARE_GROB_INTERFACE(); - static void remove_interface (Grob *); static SCM get_minimum_distances (Grob *); static SCM get_ideal_distances (Grob *); }; diff --git a/lily/include/stencil.hh b/lily/include/stencil.hh index b80bcc1c3d..807ea6d110 100644 --- a/lily/include/stencil.hh +++ b/lily/include/stencil.hh @@ -95,6 +95,5 @@ void register_stencil_head (SCM symbol); bool is_stencil_head (SCM symbol); SCM all_stencil_heads (); -Stencil points_to_line_stencil (vector points); #endif /* STENCIL_HH */ diff --git a/lily/include/tie.hh b/lily/include/tie.hh index 35d3d9596c..b68d73d24b 100644 --- a/lily/include/tie.hh +++ b/lily/include/tie.hh @@ -25,10 +25,10 @@ public: static int get_column_rank (Grob *, Direction); static int get_position (Grob *); static Direction get_default_dir (Grob *); - static void set_control_points (Grob *, Grob *, - Tie_configuration const&, - Tie_details const&); - static void set_default_control_points (Grob *); + static SCM get_control_points (Grob *, Grob *, + Tie_configuration const&, + Tie_details const&); + static SCM get_default_control_points (Grob *); DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM)); DECLARE_SCHEME_CALLBACK (calc_direction, (SCM)); diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh index 72481b5da3..eef11560ac 100644 --- a/lily/include/translator-group.hh +++ b/lily/include/translator-group.hh @@ -57,7 +57,6 @@ public: public: virtual void connect_to_context (Context *c); virtual void disconnect_from_context (); - virtual Translator_group *get_daddy_translator ()const; virtual SCM get_simple_trans_list (); virtual void initialize (); virtual void finalize (); diff --git a/lily/input-scheme.cc b/lily/input-scheme.cc index c24d2ed1b0..97c82de82c 100644 --- a/lily/input-scheme.cc +++ b/lily/input-scheme.cc @@ -47,7 +47,7 @@ LY_DEFINE (ly_input_file_line_column, int ch = 0; int col = 0; ip->get_counts (&l, &ch, &col); - return scm_list_4 (scm_makfrom0str (ip->file_string ().c_str ()), + return scm_list_4 (ly_string2scm (ip->file_string ()), scm_from_int (l), scm_from_int (ch), scm_from_int (col)); @@ -61,7 +61,7 @@ LY_DEFINE (ly_input_both_locations, { Input *ip = unsmob_input (sip); SCM_ASSERT_TYPE (ip, sip, SCM_ARG1, __FUNCTION__, "input location"); - return scm_list_5 (scm_makfrom0str (ip->file_string ().c_str ()), + return scm_list_5 (ly_string2scm (ip->file_string ()), scm_from_int (ip->line_number ()), scm_from_int (ip->column_number ()), scm_from_int (ip->end_line_number ()), diff --git a/lily/instrument-switch-engraver.cc b/lily/instrument-switch-engraver.cc index fe30a0423c..c9dce0aafb 100644 --- a/lily/instrument-switch-engraver.cc +++ b/lily/instrument-switch-engraver.cc @@ -31,6 +31,9 @@ Instrument_switch_engraver::Instrument_switch_engraver () text_ = 0; } +/* + TODO: should use an event. + */ void Instrument_switch_engraver::process_music () { diff --git a/lily/lexer.ll b/lily/lexer.ll index 9cb2cac0c6..9ce0da012d 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -236,7 +236,7 @@ BOM_UTF8 \357\273\277 progress_indication ("\n"); scm_module_define (scm_car (scopes_), ly_symbol2scm ("input-file-name"), - scm_makfrom0str (s.c_str ())); + ly_string2scm (s)); } @@ -271,7 +271,7 @@ BOM_UTF8 \357\273\277 } <> { LexerError (_ ("EOF found inside a comment").c_str ()); - is_main_input_ = false; + is_main_input_ = false; // should be safe , can't have \include in --safe. if (! close_input ()) yyterminate (); // can't move this, since it actually rets a YY_NULL } @@ -323,7 +323,7 @@ BOM_UTF8 \357\273\277 } {RESTNAME} { char const *s = YYText (); - yylval.scm = scm_makfrom0str (s); + yylval.scm = scm_from_locale_string (s); return RESTNAME; } R { @@ -427,7 +427,7 @@ BOM_UTF8 \357\273\277 /* yylval is union. Must remember STRING before setting SCM*/ string *sp = yylval.string; - yylval.scm = scm_makfrom0str (sp->c_str ()); + yylval.scm = ly_string2scm (*sp); delete sp; return is_lyric_state () ? LYRICS_STRING : STRING; } @@ -464,7 +464,7 @@ BOM_UTF8 \357\273\277 if (c == '{' || c == '}') // brace open is for not confusing dumb tools. here_input ().warning ( _ ("Brace found at end of lyric. Did you forget a space?")); - yylval.scm = scm_makfrom0str (s.c_str ()); + yylval.scm = ly_string2scm (s); return LYRICS_STRING; @@ -557,7 +557,7 @@ BOM_UTF8 \357\273\277 if (c == '{' || c == '}') here_input ().warning ( _ ("Brace found at end of markup. Did you forget a space?")); - yylval.scm = scm_makfrom0str (s.c_str ()); + yylval.scm = ly_string2scm (s); return STRING; @@ -570,7 +570,11 @@ BOM_UTF8 \357\273\277 <*><> { if (is_main_input_) { - is_main_input_ = false; + /* 2 = init.ly + current file. + > because we're before closing, but is_main_input_ should + reflect after. + */ + is_main_input_ = include_stack_.size () > 2; if (!close_input ()) /* Returns YY_NULL */ yyterminate (); @@ -774,7 +778,7 @@ Lily_lexer::scan_escaped_word (string str) string msg (_f ("unknown escaped string: `\\%s'", str)); LexerError (msg.c_str ()); - yylval.scm = scm_makfrom0str (str.c_str ()); + yylval.scm = ly_string2scm (str); return STRING; } @@ -802,7 +806,7 @@ Lily_lexer::scan_bare_word (string str) } } - yylval.scm = scm_makfrom0str (str.c_str ()); + yylval.scm = ly_string2scm (str); return STRING; } @@ -937,7 +941,7 @@ SCM lookup_markup_command (string s) { SCM proc = ly_lily_module_constant ("lookup-markup-command"); - return scm_call_1 (proc, scm_makfrom0str (s.c_str ())); + return scm_call_1 (proc, ly_string2scm (s)); } /* Shut up lexer warnings. */ diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index 8ba98a4a69..85628e64f8 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -45,7 +45,7 @@ ly_to_string (SCM scm) { return scm_call_3 (ly_lily_module_constant ("format"), SCM_BOOL_F, - scm_makfrom0str ("~S"), scm); + scm_from_locale_string ("~S"), scm); } SCM @@ -129,6 +129,14 @@ ly_scm2string (SCM str) (int) scm_i_string_length (str)); } +SCM +ly_string2scm (string const &str) +{ + return scm_from_locale_stringn (str.c_str(), + str.length ()); +} + + char * ly_scm2newstr (SCM str, size_t *lenp) { @@ -335,37 +343,6 @@ ly_scm2offsets (SCM s) ALIST */ -/* looks the key up in the cdrs of the alist-keys - - ignoring the car and ignoring non-pair keys. - Returns first match found, i.e. - - alist = ((1 . 10) - ((1 . 2) . 11) - ((2 . 1) . 12) - ((3 . 0) . 13) - ((4 . 1) . 14) ) - - I would like (ly_assoc_cdr 1) to return 12 - because it's the first - element with the cdr of the key = 1. In other words (alloc_cdr key) - corresponds to call - - (alloc (anything . key)) -*/ -SCM -ly_assoc_cdr (SCM key, SCM alist) -{ - if (scm_is_pair (alist)) - { - SCM trykey = scm_caar (alist); - if (scm_is_pair (trykey) - && to_boolean (scm_equal_p (key, scm_cdr (trykey)))) - return scm_car (alist); - return ly_assoc_cdr (key, scm_cdr (alist)); - } - return SCM_BOOL_F; -} - - bool alist_equal_p (SCM a, SCM b) { @@ -429,25 +406,6 @@ ly_deep_copy (SCM src) } -SCM -ly_truncate_list (int k, SCM lst) -{ - if (k == 0) - lst = SCM_EOL; - else - { - SCM s = lst; - k--; - for (; scm_is_pair (s) && k--; s = scm_cdr (s)) - ; - - if (scm_is_pair (s)) - scm_set_cdr_x (s, SCM_EOL); - } - return lst; -} - - diff --git a/lily/lily-lexer-scheme.cc b/lily/lily-lexer-scheme.cc index 66e47d3d6b..7cb6d53691 100644 --- a/lily/lily-lexer-scheme.cc +++ b/lily/lily-lexer-scheme.cc @@ -10,11 +10,10 @@ #include "lily-lexer.hh" LY_DEFINE(ly_lexer_keywords, "ly:lexer-keywords", - 1,0,0, (SCM lexer), + 1, 0, 0, (SCM lexer), "Return a list of (KEY . CODE) pairs, signifying the lilypond reserved words list.") { Lily_lexer * lex = Lily_lexer::unsmob (lexer); SCM_ASSERT_TYPE(lex, lexer, SCM_ARG1, __FUNCTION__, "lily lexer"); return lex->keyword_list (); } - diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc index 8d70783cb5..97d515aaaa 100644 --- a/lily/lily-lexer.cc +++ b/lily/lily-lexer.cc @@ -193,7 +193,7 @@ Lily_lexer::keyword_list () const SCM *tail = &l; for (vsize i = 0; i < keytable_->table_.size (); i++) { - *tail = scm_acons (scm_makfrom0str (keytable_->table_[i].name_), + *tail = scm_acons (scm_from_locale_string (keytable_->table_[i].name_), scm_from_int (keytable_->table_[i].tokcode_), SCM_EOL); @@ -231,12 +231,27 @@ Lily_lexer::start_main_input () new_input (main_input_name_, sources_); - /* Do not allow \include in --safe-mode */ - allow_includes_b_ = allow_includes_b_ && !be_safe_global; - scm_module_define (scm_car (scopes_), ly_symbol2scm ("input-file-name"), - scm_makfrom0str (main_input_name_.c_str ())); + ly_string2scm (main_input_name_)); +} + +void +Lily_lexer::new_input (string str, string d, Sources *ss) +{ + Includable_lexer::new_input (str, d, ss); +} + +void +Lily_lexer::new_input (string str, Sources *ss) +{ + if (is_main_input_ && be_safe_global) + { + LexerError (_ ("include files are not allowed in safe mode").c_str ()); + return; + } + + Includable_lexer::new_input (str, ss); } void diff --git a/lily/lily-parser-scheme.cc b/lily/lily-parser-scheme.cc index 305359c3f5..47a0095a44 100644 --- a/lily/lily-parser-scheme.cc +++ b/lily/lily-parser-scheme.cc @@ -142,27 +142,11 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", if (error) /* TODO: pass renamed input file too. */ scm_throw (ly_symbol2scm ("ly-file-failed"), - scm_list_1 (scm_makfrom0str (file_name.c_str ()))); + scm_list_1 (ly_string2scm (file_name))); return SCM_UNSPECIFIED; } -LY_DEFINE (ly_parse_string, "ly:parse-string", - 1, 0, 0, (SCM ly_code), - "Parse the string LY_CODE. " - "Upon failure, throw @code{ly-file-failed} key.") -{ - SCM_ASSERT_TYPE (scm_is_string (ly_code), ly_code, SCM_ARG1, __FUNCTION__, "string"); - - Sources sources; - sources.set_path (&global_path); - Lily_parser *parser = new Lily_parser (&sources); - parser->parse_string (ly_scm2string (ly_code)); - parser->unprotect (); - parser = 0; - - return SCM_UNSPECIFIED; -} LY_DEFINE (ly_parser_lexer, "ly:parser-lexer", 1, 0, 0, (SCM parser_smob), @@ -251,7 +235,7 @@ LY_DEFINE (ly_parser_output_name, "ly:parser-output-name", Lily_parser *p = unsmob_lily_parser (parser); SCM_ASSERT_TYPE (p, parser, SCM_ARG1, __FUNCTION__, "Lilypond parser"); - return scm_makfrom0str (p->output_basename_.c_str ()); + return ly_string2scm (p->output_basename_); } LY_DEFINE (ly_parser_error, "ly:parser-error", @@ -271,3 +255,26 @@ LY_DEFINE (ly_parser_error, "ly:parser-error", return parser; } + +LY_DEFINE (ly_parser_clear_error, "ly:parser-clear-error", + 1, 0, 0, (SCM parser), + "Clear the error flag for the parser.") +{ + Lily_parser *p = unsmob_lily_parser (parser); + SCM_ASSERT_TYPE (p, parser, SCM_ARG1, __FUNCTION__, "Lilypond parser"); + + p->error_level_ = 0; + p->lexer_->error_level_ = 0; + + return SCM_UNSPECIFIED; +} + +LY_DEFINE (ly_parser_has_error_p, "ly:parser-has-error?", + 1, 0, 0, (SCM parser), + "Does @var{parser} have an error flag?") +{ + Lily_parser *p = unsmob_lily_parser (parser); + SCM_ASSERT_TYPE (p, parser, SCM_ARG1, __FUNCTION__, "Lilypond parser"); + + return scm_from_bool (p->error_level_ || p->lexer_->error_level_); +} diff --git a/lily/lily-parser.cc b/lily/lily-parser.cc index ae3943dbdb..04b15622bf 100644 --- a/lily/lily-parser.cc +++ b/lily/lily-parser.cc @@ -105,7 +105,7 @@ Lily_parser::parse_file (string init, string name, string out_name) File_name f (name); string s = global_path.find (f.base_ + ".twy"); s = gulp_file_to_string (s, false, -1); - scm_eval_string (scm_makfrom0str (s.c_str ())); + scm_eval_string (ly_string2scm (s)); /* Read .ly IN_FILE, lex, parse, write \score blocks from IN_FILE to OUT_FILE (unless IN_FILE redefines output file name). */ @@ -140,8 +140,7 @@ Lily_parser::parse_string (string ly_code) self_scm ()); lexer_->main_input_name_ = ""; - lexer_->is_main_input_ = true; - + lexer_->is_main_input_ = true; lexer_->new_input (lexer_->main_input_name_, ly_code, sources_); SCM mod = lexer_->set_current_scope (); @@ -208,7 +207,6 @@ get_layout (Lily_parser *parser) Output_def *layout = unsmob_output_def (id); layout = layout ? layout->clone () : new Output_def; layout->set_variable (ly_symbol2scm ("is-layout"), SCM_BOOL_T); - layout->parser_ = parser; return layout; } @@ -220,7 +218,6 @@ get_midi (Lily_parser *parser) Output_def *layout = unsmob_output_def (id); layout = layout ? layout->clone () : new Output_def; layout->set_variable (ly_symbol2scm ("is-midi"), SCM_BOOL_T); - layout->parser_ = parser; return layout; } @@ -232,7 +229,6 @@ get_paper (Lily_parser *parser) layout = layout ? dynamic_cast (layout->clone ()) : new Output_def; layout->set_variable (ly_symbol2scm ("is-paper"), SCM_BOOL_T); - layout->parser_ = parser; return layout; } @@ -241,13 +237,19 @@ get_header (Lily_parser *parser) { SCM id = parser->lexer_->lookup_identifier ("$defaultheader"); if (!ly_is_module (id)) - id = ly_make_anonymous_module (be_safe_global); + id = parser->make_scope (); else { - SCM nid = ly_make_anonymous_module (false); - ly_module_copy(nid,id); + SCM nid = parser->make_scope (); + ly_module_copy (nid, id); id = nid; } return id; } + +SCM +Lily_parser::make_scope () const +{ + return ly_make_anonymous_module (be_safe_global); +} diff --git a/lily/lilypond-key.cc b/lily/lilypond-key.cc index 99b190bcc4..b75d872699 100644 --- a/lily/lilypond-key.cc +++ b/lily/lilypond-key.cc @@ -63,7 +63,7 @@ Lilypond_grob_key::as_scheme () const { return scm_list_4 (context_ ? context_->self_scm () : SCM_BOOL_F, creation_moment_.smobbed_copy (), - scm_makfrom0str (grob_name_.c_str ()), + ly_string2scm (grob_name_), scm_from_int (disambiguation_count_)); } @@ -146,8 +146,8 @@ Lilypond_context_key::as_scheme () const { return scm_list_5 (parent_context_ ? parent_context_->self_scm () : SCM_BOOL_F, start_moment_.smobbed_copy (), - scm_makfrom0str (context_name_.c_str ()), - scm_makfrom0str (id_.c_str ()), + ly_string2scm (context_name_), + ly_string2scm (id_), scm_from_int (disambiguation_count_)); } @@ -213,7 +213,7 @@ SCM Lilypond_general_key::as_scheme () const { return scm_list_3 (parent_ ? parent_->self_scm () : SCM_BOOL_F, - scm_makfrom0str (name_.c_str ()), + ly_string2scm (name_), scm_from_int (disambiguation_count_)); } diff --git a/lily/line-interface.cc b/lily/line-interface.cc index f65dc946f2..c765ffcd4c 100644 --- a/lily/line-interface.cc +++ b/lily/line-interface.cc @@ -156,21 +156,3 @@ ADD_INTERFACE (Line_interface, "arrow-length " "arrow-width") - - -/* todo: move this somewhere else? */ -Stencil -points_to_line_stencil (vector points) -{ - Stencil ret; - for (vsize i = 1; i < points.size (); i++) - { - if (points[i-1].is_sane () && points[i].is_sane ()) - { - Stencil line - = Line_interface::make_line (0.1, points[i-1], points[i]); - ret.add_stencil (line); - } - } - return ret; -} diff --git a/lily/lookup.cc b/lily/lookup.cc index d8c20c044f..1a34881d80 100644 --- a/lily/lookup.cc +++ b/lily/lookup.cc @@ -147,7 +147,7 @@ Lookup::horizontal_line (Interval w, Real th) Stencil Lookup::blank (Box b) { - return Stencil (b, scm_makfrom0str ("")); + return Stencil (b, scm_from_locale_string ("")); } Stencil @@ -714,17 +714,29 @@ Lookup::triangle (Interval iv, Real thick, Real protude) b[X_AXIS] = Interval (0, iv.length ()); b[Y_AXIS] = Interval (min (0., protude), max (0.0, protude)); - Offset z1 (iv[LEFT], 0); - Offset z2 (iv[RIGHT], 0); - Offset z3 ((z1 + z2)[X_AXIS] / 2, protude); + vector points; + points.push_back (Offset (iv[LEFT], 0)); + points.push_back (Offset (iv[RIGHT], 0)); + points.push_back (Offset (iv.center (), protude)); - /* - TODO: move Triangle to Line_interface ? - */ - Stencil tri = Line_interface::make_line (thick, z1, z2); - tri.add_stencil (Line_interface::make_line (thick, z2, z3)); - tri.add_stencil (Line_interface::make_line (thick, z3, z1)); + return points_to_line_stencil (thick, points); - return tri; } + + +Stencil +Lookup::points_to_line_stencil (Real thick, vector const &points) +{ + Stencil ret; + for (vsize i = 1; i < points.size (); i++) + { + if (points[i-1].is_sane () && points[i].is_sane ()) + { + Stencil line + = Line_interface::make_line (thick, points[i-1], points[i]); + ret.add_stencil (line); + } + } + return ret; +} diff --git a/lily/lyric-combine-music-iterator.cc b/lily/lyric-combine-music-iterator.cc index 85e72d3197..88ef1d18e6 100644 --- a/lily/lyric-combine-music-iterator.cc +++ b/lily/lyric-combine-music-iterator.cc @@ -15,6 +15,20 @@ #include "music-iterator.hh" #include "music.hh" +/* + This iterator is hairy. It tracks both lyric and melody contexts, + and has a complicated communication route, reading/writing + properties in both. + + In the future, this should rather be done with + + \interpretAsMelodyFor { MUSIC } { LYRICS LYRICS LYRICS } + + This can run an interpret step on MUSIC, generating a stream. Then + the stream can be perused at leisure to apply durations to all of + the LYRICS. +*/ + class Lyric_combine_music_iterator : public Music_iterator { public: @@ -32,7 +46,7 @@ protected: virtual void derived_substitute (Context *, Context *); void set_music_context (Context *to); private: - bool start_new_syllable (); + bool start_new_syllable () const; Context *find_voice (); DECLARE_LISTENER (set_busy); DECLARE_LISTENER (check_new_context); @@ -75,6 +89,7 @@ Lyric_combine_music_iterator::set_music_context (Context *to) music_context_->event_source()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("music-event")); lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext")); } + music_context_ = to; if (to) { @@ -85,13 +100,11 @@ Lyric_combine_music_iterator::set_music_context (Context *to) } bool -Lyric_combine_music_iterator::start_new_syllable () +Lyric_combine_music_iterator::start_new_syllable () const { if (!busy_) return false; - busy_ = false; - if (!lyrics_context_) return false; @@ -169,15 +182,13 @@ Lyric_combine_music_iterator::construct_children () Context *voice = find_voice (); if (voice) set_music_context (voice); - else - { - /* - Wait for a Create_context event. If this isn't done, lyrics can be - delayed when voices are created implicitly. - */ - Global_context *g = get_outlet ()->get_global_context (); - g->events_below ()->add_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext")); - } + + /* + Wait for a Create_context event. If this isn't done, lyrics can be + delayed when voices are created implicitly. + */ + Global_context *g = get_outlet ()->get_global_context (); + g->events_below ()->add_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext")); /* We do not create a Lyrics context, because the user might @@ -191,15 +202,15 @@ void Lyric_combine_music_iterator::check_new_context (SCM sev) { // TODO: Check first if type=Voice and if id matches - (void)sev; - + Stream_event * ev = unsmob_stream_event (sev); + if (ev->get_property ("type") != ly_symbol2scm ("Voice")) + return ; + Context *voice = find_voice (); + if (voice) { set_music_context (voice); - - Global_context *g = voice->get_global_context (); - g->events_below ()->remove_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext")); } } @@ -258,6 +269,7 @@ Lyric_combine_music_iterator::process (Moment) set_music_context (0); } + if (music_context_ && (start_new_syllable () || pending_grace_lyric_) && lyric_iter_->ok ()) @@ -275,6 +287,8 @@ Lyric_combine_music_iterator::process (Moment) music_found_ = true; } + + busy_ = false; } void diff --git a/lily/lyric-engraver.cc b/lily/lyric-engraver.cc index 06ffce0d50..3005760765 100644 --- a/lily/lyric-engraver.cc +++ b/lily/lyric-engraver.cc @@ -59,7 +59,7 @@ Lyric_engraver::process_music () { SCM text = event_->get_property ("text"); - if (ly_is_equal (text, scm_makfrom0str (" "))) + if (ly_is_equal (text, scm_from_locale_string (" "))) { if (last_text_) last_text_->set_property ("self-alignment-X", scm_from_int (LEFT)); diff --git a/lily/main.cc b/lily/main.cc index 5aba63d78d..bf8132477b 100644 --- a/lily/main.cc +++ b/lily/main.cc @@ -424,7 +424,7 @@ main_with_guile (void *, int, char **) SCM *tail = &files; while (char const *arg = option_parser->get_next_arg ()) { - *tail = scm_cons (scm_makfrom0str (arg), SCM_EOL); + *tail = scm_cons (scm_from_locale_string (arg), SCM_EOL); tail = SCM_CDRLOC (*tail); } @@ -566,10 +566,8 @@ parse_argv (int argc, char **argv) be_verbose_global = true; break; case 's': - be_safe_global = true; init_scheme_variables += "(cons \'safe #t)\n"; - break; case 'p': make_preview = true; diff --git a/lily/melody-spanner.cc b/lily/melody-spanner.cc index d4901f2c9b..103a5c6427 100644 --- a/lily/melody-spanner.cc +++ b/lily/melody-spanner.cc @@ -27,7 +27,7 @@ Melody_spanner::calc_neutral_stem_direction (SCM smob) Grob *stem = unsmob_grob (smob); Grob *me = unsmob_grob (stem->get_object ("melody-spanner")); if (!me || !me->is_live ()) - return SCM_UNSPECIFIED; + return scm_from_int (DOWN); extract_grob_set (me, "stems", stems); @@ -41,6 +41,7 @@ Melody_spanner::calc_neutral_stem_direction (SCM smob) && !dirs[next_nonneutral]) next_nonneutral++; + SCM retval = SCM_EOL; while (last_nonneutral == VPOS || last_nonneutral < dirs.size () - 1) { Direction d1 = CENTER; @@ -61,8 +62,12 @@ Melody_spanner::calc_neutral_stem_direction (SCM smob) total = to_dir (me->get_property ("neutral-direction")); for (vsize i = last_nonneutral + 1; i < next_nonneutral; i++) - stems[i]->set_property ("neutral-direction", scm_from_int (total)); - + { + if (stems[i] == stem) + retval = scm_from_int (total); + else + stems[i]->set_property ("neutral-direction", scm_from_int (total)); + } last_nonneutral = next_nonneutral; while (last_nonneutral < dirs.size () @@ -76,8 +81,7 @@ Melody_spanner::calc_neutral_stem_direction (SCM smob) next_nonneutral++; } - me->suicide (); - return SCM_UNSPECIFIED; + return retval; } void diff --git a/lily/midi-item.cc b/lily/midi-item.cc index 3fcdb4ca22..82283201eb 100644 --- a/lily/midi-item.cc +++ b/lily/midi-item.cc @@ -140,9 +140,6 @@ Midi_instrument::to_string () const Byte program_byte = 0; bool found = false; - /* - UGH. don't use eval. - */ SCM proc = ly_lily_module_constant ("midi-program"); SCM program = scm_call_1 (proc, ly_symbol2scm (audio_->str_.c_str ())); found = (program != SCM_BOOL_F); diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc index c2aaa085b1..8a315d6f2c 100644 --- a/lily/midi-walker.cc +++ b/lily/midi-walker.cc @@ -57,7 +57,7 @@ void Midi_walker::do_start_note (Midi_note *note) { Audio_item *ptr = (*items_)[index_]; - Moment stop_mom = note->get_length () + ptr->audio_column_->at_mom (); + Moment stop_mom = note->get_length () + ptr->audio_column_->when (); bool play_start = true; for (vsize i = 0; i < stop_note_queue.size (); i++) @@ -93,7 +93,7 @@ Midi_walker::do_start_note (Midi_note *note) stop_note_queue.insert (e); if (play_start) - output_event (ptr->audio_column_->at_mom (), note); + output_event (ptr->audio_column_->when (), note); } } @@ -142,7 +142,7 @@ void Midi_walker::process () { Audio_item *audio = (*items_)[index_]; - do_stop_notes (audio->audio_column_->at_mom ()); + do_stop_notes (audio->audio_column_->when ()); if (Midi_item *midi = Midi_item::get_midi (audio)) { @@ -156,7 +156,7 @@ Midi_walker::process () do_start_note (note); } else - output_event (audio->audio_column_->at_mom (), midi); + output_event (audio->audio_column_->when (), midi); } } diff --git a/lily/modified-font-metric.cc b/lily/modified-font-metric.cc index e0fb13044d..91e9698032 100644 --- a/lily/modified-font-metric.cc +++ b/lily/modified-font-metric.cc @@ -178,7 +178,7 @@ Modified_font_metric::text_stencil (string text) const Box Modified_font_metric::text_dimension (string text) const { - SCM stext = scm_makfrom0str (text.c_str ()); + SCM stext = ly_string2scm (text); Box b; if (output_backend_global == "tex") diff --git a/lily/multi-measure-rest.cc b/lily/multi-measure-rest.cc index 44d699b7ce..bc6f7927bc 100644 --- a/lily/multi-measure-rest.cc +++ b/lily/multi-measure-rest.cc @@ -205,11 +205,11 @@ Multi_measure_rest::church_rest (Grob *me, Font_metric *musfont, int measures, int count = 0; Real symbols_width = 0.0; - SCM sml = me->get_property ("use-breve-rest"); + bool use_breve = to_boolean (me->get_property ("use-breve-rest")); while (l) { - if (sml == SCM_BOOL_T) + if (use_breve) { int k; if (l >= 2) diff --git a/lily/music.cc b/lily/music.cc index 83f88fbcd9..3dbbe123e5 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -184,29 +184,28 @@ Music::compress (Moment factor) } /* - This mutates alist. Hence, make sure that it is not changed + This mutates alist. Hence, make sure that it is not shared */ -SCM +void transpose_mutable (SCM alist, Pitch delta) { - SCM retval = SCM_EOL; - for (SCM s = alist; scm_is_pair (s); s = scm_cdr (s)) { SCM entry = scm_car (s); SCM prop = scm_car (entry); SCM val = scm_cdr (entry); - + SCM new_val = val; + if (Pitch *p = unsmob_pitch (val)) { Pitch transposed = p->transposed (delta); - scm_set_cdr_x (entry, transposed.smobbed_copy ()); - if (transposed.get_alteration ().abs () > Rational (1,1)) { warning (_f ("transposition by %s makes alteration larger than double", delta.to_string ())); } + + new_val = transposed.smobbed_copy (); } else if (prop == ly_symbol2scm ("element")) { @@ -217,12 +216,11 @@ transpose_mutable (SCM alist, Pitch delta) transpose_music_list (val, delta); else if (prop == ly_symbol2scm ("pitch-alist") && scm_is_pair (val)) - entry = scm_cons (prop, - ly_transpose_key_alist (val, delta.smobbed_copy ())); - retval = scm_cons (entry, retval); - } + new_val = ly_transpose_key_alist (val, delta.smobbed_copy ()); - return scm_reverse_x (retval, SCM_EOL); + if (val != new_val) + scm_set_cdr_x (entry , new_val); + } } void @@ -231,7 +229,7 @@ Music::transpose (Pitch delta) if (to_boolean (get_property ("untransposable"))) return; - mutable_property_alist_ = transpose_mutable (mutable_property_alist_, delta); + transpose_mutable (mutable_property_alist_, delta); } void diff --git a/lily/new-dynamic-performer.cc b/lily/new-dynamic-performer.cc new file mode 100644 index 0000000000..7afc555c7a --- /dev/null +++ b/lily/new-dynamic-performer.cc @@ -0,0 +1,213 @@ +/* + dynamic-performer.cc -- implement New_dynamic_performer + + source file of the GNU LilyPond music typesetter + + (c) 2000--2006 Jan Nieuwenhuizen +*/ + +#include "performer.hh" +#include "audio-item.hh" +#include "stream-event.hh" + +#include "translator.icc" + +/* + TODO: + + handle multiple events + + perform absolute (text) dynamics +*/ +class New_dynamic_performer : public Performer +{ +public: + TRANSLATOR_DECLARATIONS (New_dynamic_performer); +protected: + void stop_translation_timestep (); + void process_music (); + Real equalize_volume (Real); + + DECLARE_TRANSLATOR_LISTENER (decrescendo); + DECLARE_TRANSLATOR_LISTENER (crescendo); + DECLARE_TRANSLATOR_LISTENER (absolute_dynamic); +private: + Stream_event *script_event_; + Drul_array span_events_; + Drul_array grow_dir_; + Real last_volume_; + Audio_dynamic *absolute_; + Audio_span_dynamic *span_dynamic_; + Audio_span_dynamic *finished_span_dynamic_; +}; + +New_dynamic_performer::New_dynamic_performer () +{ + last_volume_ = 0.5; + script_event_ = 0; + absolute_ = 0; + span_events_[LEFT] = + span_events_[RIGHT] = 0; + span_dynamic_ = 0; + finished_span_dynamic_ = 0; +} + +Real +New_dynamic_performer::equalize_volume (Real volume) +{ + /* + properties override default equaliser setting + */ + SCM min = get_property ("midiMinimumVolume"); + SCM max = get_property ("midiMaximumVolume"); + if (scm_is_number (min) || scm_is_number (max)) + { + Interval iv (0, 1); + if (scm_is_number (min)) + iv[MIN] = scm_to_double (min); + if (scm_is_number (max)) + iv[MAX] = scm_to_double (max); + volume = iv[MIN] + iv.length () * volume; + } + else + { + /* + urg, code duplication:: staff_performer + */ + SCM s = get_property ("midiInstrument"); + + if (!scm_is_string (s)) + s = get_property ("instrumentName"); + + if (!scm_is_string (s)) + s = scm_from_locale_string ("piano"); + + SCM eq = get_property ("instrumentEqualizer"); + if (ly_is_procedure (eq)) + s = scm_call_1 (eq, s); + + if (is_number_pair (s)) + { + Interval iv = ly_scm2interval (s); + volume = iv[MIN] + iv.length () * volume; + } + } + return volume; +} + + +void +New_dynamic_performer::process_music () +{ + if (span_events_[STOP] || script_event_) + { + finished_span_dynamic_ = span_dynamic_; + span_dynamic_ = 0; + } + + if (span_events_[START]) + { + span_dynamic_ = new Audio_span_dynamic(); + announce_element (Audio_element_info (span_dynamic_, span_events_[START])); + + span_dynamic_->grow_dir_ = grow_dir_[START]; + } + + if (script_event_ + || span_dynamic_ + || finished_span_dynamic_) + { + absolute_ = new Audio_dynamic (); + + if (script_event_) + { + SCM proc = get_property ("dynamicAbsoluteVolumeFunction"); + + SCM svolume = SCM_EOL; + if (ly_is_procedure (proc)) + { + // urg + svolume = scm_call_1 (proc, script_event_->get_property ("text")); + } + + Real volume = robust_scm2double (svolume, 0.5); + + last_volume_ + = absolute_->volume_ = equalize_volume (volume); + } + + Audio_element_info info (absolute_, script_event_); + announce_element (info); + } + + + if (span_dynamic_) + span_dynamic_->add_absolute (absolute_); + + if (finished_span_dynamic_) + finished_span_dynamic_->add_absolute (absolute_); +} + +void +New_dynamic_performer::stop_translation_timestep () +{ + if (finished_span_dynamic_) + { + finished_span_dynamic_->render (); + finished_span_dynamic_ = 0; + } + + + if (absolute_ && absolute_->volume_ < 0) + { + absolute_->volume_ = last_volume_; + } + else if (absolute_) + { + last_volume_ = absolute_->volume_; + } + + absolute_ = 0; + script_event_ = 0; + span_events_[LEFT] = + span_events_[RIGHT] = 0; +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_performer, decrescendo); +void +New_dynamic_performer::listen_decrescendo (Stream_event *r) +{ + Direction d = to_dir (r->get_property ("span-direction")); + span_events_[d] = r; + grow_dir_[d] = SMALLER; +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_performer, crescendo); +void +New_dynamic_performer::listen_crescendo (Stream_event *r) +{ + Direction d = to_dir (r->get_property ("span-direction")); + span_events_[d] = r; + grow_dir_[d] = BIGGER; +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_performer, absolute_dynamic); +void +New_dynamic_performer::listen_absolute_dynamic (Stream_event *r) +{ + if (!script_event_) + script_event_ = r; +} + +ADD_TRANSLATOR (New_dynamic_performer, + /* doc */ "", + /* create */ "", + + /* read */ + "dynamicAbsoluteVolumeFunction " + "instrumentEqualizer " + "midiMaximumVolume " + "midiMinimumVolume " + "midiInstrument " + , + /*writes*/""); diff --git a/lily/new-fingering-engraver.cc b/lily/new-fingering-engraver.cc index 1ae7794393..cd2d0487c0 100644 --- a/lily/new-fingering-engraver.cc +++ b/lily/new-fingering-engraver.cc @@ -250,6 +250,11 @@ New_fingering_engraver::position_scripts (SCM orientations, f->set_parent (ft.head_, X_AXIS); f->set_parent (ft.head_, Y_AXIS); + if (hordir == LEFT + && unsmob_grob (ft.head_->get_object ("accidental-grob"))) + Side_position_interface::add_support (f, + unsmob_grob (ft.head_->get_object ("accidental-grob"))); + Self_alignment_interface::set_align_self (f, Y_AXIS); Self_alignment_interface::set_center_parent (f, Y_AXIS); Side_position_interface::set_axis (f, X_AXIS); diff --git a/lily/note-name-engraver.cc b/lily/note-name-engraver.cc index f3c081f039..dfff746e27 100644 --- a/lily/note-name-engraver.cc +++ b/lily/note-name-engraver.cc @@ -50,7 +50,7 @@ Note_name_engraver::process_music () if (s.length ()) { Item *t = make_item ("NoteName", events_[0]->self_scm ()); - t->set_property ("text", scm_makfrom0str (s.c_str ())); + t->set_property ("text", ly_string2scm (s)); texts_.push_back (t); } } diff --git a/lily/open-type-font.cc b/lily/open-type-font.cc index 2f2e5fdaad..7e025bc5b2 100644 --- a/lily/open-type-font.cc +++ b/lily/open-type-font.cc @@ -296,7 +296,7 @@ Open_type_font::glyph_list () const if (code) warning (_f ("FT_Get_Glyph_Name() returned error: %u", unsigned (code))); - *tail = scm_cons (scm_makfrom0str (name), SCM_EOL); + *tail = scm_cons (scm_from_locale_string (name), SCM_EOL); tail = SCM_CDRLOC (*tail); } diff --git a/lily/output-def-scheme.cc b/lily/output-def-scheme.cc index 4bf03f2e13..9ab1ba64eb 100644 --- a/lily/output-def-scheme.cc +++ b/lily/output-def-scheme.cc @@ -98,21 +98,6 @@ LY_DEFINE (ly_paper_outputscale, "ly:paper-outputscale", return scm_from_double (output_scale (b)); } -/* - Cannot put in scope, but need a separate function, since we don't - want to allow this in --safe. - */ -LY_DEFINE (ly_output_def_parser, "ly:output-def-parser", - 1, 0, 0, (SCM odef), - "Return the parser where @var{odef} is coming from.") -{ - Output_def *b = unsmob_output_def (odef); - SCM_ASSERT_TYPE (b, odef, SCM_ARG1, __FUNCTION__, "paper"); - - return b->get_parser()->self_scm (); -} - - LY_DEFINE (ly_make_output_def, "ly:make-output-def", 0, 0, 0, (), "Make a output def.") diff --git a/lily/output-def.cc b/lily/output-def.cc index 739b4b9e7b..aade16df6e 100644 --- a/lily/output-def.cc +++ b/lily/output-def.cc @@ -26,7 +26,6 @@ Output_def::Output_def () { scope_ = SCM_EOL; - parser_ = 0; parent_ = 0; smobify_self (); @@ -38,7 +37,6 @@ Output_def::Output_def (Output_def const &s) { scope_ = SCM_EOL; parent_ = 0; - parser_ = s.parser_; smobify_self (); input_origin_ = s.input_origin_; @@ -54,12 +52,6 @@ Output_def::~Output_def () IMPLEMENT_SMOBS (Output_def); IMPLEMENT_DEFAULT_EQUAL_P (Output_def); -Lily_parser * -Output_def::get_parser () const -{ - return parent_ ? parent_->get_parser () : parser_; -} - SCM Output_def::mark_smob (SCM m) { diff --git a/lily/pango-font.cc b/lily/pango-font.cc index 3d58e0dd0e..77d279ab90 100644 --- a/lily/pango-font.cc +++ b/lily/pango-font.cc @@ -69,8 +69,8 @@ void Pango_font::register_font_file (string filename, string ps_name) { scm_hash_set_x (physical_font_tab_, - scm_makfrom0str (ps_name.c_str ()), - scm_makfrom0str (filename.c_str ())); + ly_string2scm (ps_name), + ly_string2scm (filename)); } void @@ -204,7 +204,7 @@ Pango_font::pango_item_string_stencil (PangoItem const *item, string str, char_id = scm_from_uint32 (pg); } else - char_id = scm_makfrom0str (glyph_name); + char_id = scm_from_locale_string (glyph_name); *tail = scm_cons (scm_list_4 (scm_from_double (ggeo.width * scale_), scm_from_double (ggeo.x_offset * scale_), @@ -261,7 +261,7 @@ Pango_font::pango_item_string_stencil (PangoItem const *item, string str, pango_fc_font_unlock_face (fcfont); SCM expr = scm_list_5 (ly_symbol2scm ("glyph-string"), - scm_makfrom0str (ps_name.c_str ()), + ly_string2scm (ps_name), scm_from_double (size), scm_from_bool (cid_keyed), ly_quote_scm (glyph_exprs)); @@ -355,8 +355,8 @@ Pango_font::text_stencil (string str, bool tight) const */ SCM exp = scm_list_3 (ly_symbol2scm ("utf-8-string"), - scm_makfrom0str (description_string ().c_str ()), - scm_makfrom0str (str.c_str ())); + ly_string2scm (description_string ()), + ly_string2scm (str)); Box b (Interval (0, 0), Interval (0, 0)); b.unite (dest.extent_box ()); diff --git a/lily/pango-select-scheme.cc b/lily/pango-select-scheme.cc index 89330c842a..7a48daf535 100644 --- a/lily/pango-select-scheme.cc +++ b/lily/pango-select-scheme.cc @@ -19,7 +19,7 @@ LY_DEFINE (ly_make_pango_description_string, "ly:make-pango-description-string", PangoFontDescription *pfd = properties_to_pango_description (chain, scm_to_double (size)); char *str = pango_font_description_to_string (pfd); - SCM scm_str = scm_makfrom0str (str); + SCM scm_str = scm_from_locale_string (str); g_free (str); pango_font_description_free (pfd); return scm_str; diff --git a/lily/pango-select.cc b/lily/pango-select.cc index bd684b92f8..5d032f252b 100644 --- a/lily/pango-select.cc +++ b/lily/pango-select.cc @@ -56,7 +56,7 @@ select_pango_font (Output_def *layout, SCM chain) * layout->get_dimension (ly_symbol2scm ("text-font-size"))); char *str = pango_font_description_to_string (pfd); - SCM scm_str = scm_makfrom0str (str); + SCM scm_str = scm_from_locale_string (str); g_free (str); return find_pango_font (layout, scm_str, 1.0); diff --git a/lily/paper-book.cc b/lily/paper-book.cc index c66d1d6ae9..e53e2564a5 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -136,6 +136,13 @@ Paper_book::output (SCM output_channel) void Paper_book::classic_output (SCM output) { + if (scm_is_pair (performances_)) + { + SCM proc = ly_lily_module_constant ("write-performances-midis"); + + scm_call_2 (proc, performances (), output); + } + /* Generate all stencils to trigger font loads. */ systems (); diff --git a/lily/paper-column.cc b/lily/paper-column.cc index 2636b20fe4..4f97c81afb 100644 --- a/lily/paper-column.cc +++ b/lily/paper-column.cc @@ -19,6 +19,9 @@ #include "output-def.hh" #include "pointer-group-interface.hh" #include "grob-array.hh" +#include "system.hh" +#include "spring.hh" +#include "lookup.hh" Grob * Paper_column::clone (int count) const @@ -29,7 +32,6 @@ Paper_column::clone (int count) const void Paper_column::do_break_processing () { - Spaceable_grob::remove_interface (this); Item::do_break_processing (); } @@ -136,26 +138,26 @@ Paper_column::is_breakable (Grob *me) /* Print a vertical line and the rank number, to aid debugging. */ - MAKE_SCHEME_CALLBACK (Paper_column, print, 1); SCM Paper_column::print (SCM p) { - Grob *me = unsmob_grob (p); + Paper_column *me = dynamic_cast (unsmob_grob (p)); string r = to_string (Paper_column::get_rank (me)); Moment *mom = unsmob_moment (me->get_property ("when")); string when = mom ? mom->to_string () : "?/?"; + Font_metric *musfont = Font_interface::get_default_font (me); SCM properties = Font_interface::text_font_alist_chain (me); SCM scm_mol = Text_interface::interpret_markup (me->layout ()->self_scm (), properties, - scm_makfrom0str (r.c_str ())); + ly_string2scm (r)); SCM when_mol = Text_interface::interpret_markup (me->layout ()->self_scm (), properties, - scm_makfrom0str (when.c_str ())); + ly_string2scm (when)); Stencil t = *unsmob_stencil (scm_mol); t.add_at_edge (Y_AXIS, DOWN, *unsmob_stencil (when_mol), 0.1, 0.1); t.align_to (X_AXIS, CENTER); @@ -164,6 +166,55 @@ Paper_column::print (SCM p) Stencil l = Lookup::filled_box (Box (Interval (-0.01, 0.01), Interval (-2, -1))); + + + System * my_system = me->get_system (); + int drank = + me->get_rank () + - my_system->get_bound (LEFT)->get_column ()->get_rank (); + int j = 0; + for (SCM s = me->get_object ("ideal-distances"); + scm_is_pair (s); s = scm_cdr (s)) + { + Spring_smob *sp = unsmob_spring (scm_car (s)); + + Real y = -j * 0.1 -3; + vector pts; + pts.push_back (Offset (0, y)); + + Offset p2 (sp->distance_, y); + pts.push_back (p2); + + Stencil id_stencil = Lookup::points_to_line_stencil (0.1, pts); + Stencil head (musfont->find_by_name ("arrowheads.open.01")); + head.translate (p2); + id_stencil.add_stencil (head); + id_stencil = id_stencil.in_color (0,0,1); + l.add_stencil (id_stencil) ; + + } + + for (SCM s = me->get_object ("minimum-distances"); + scm_is_pair (s); s = scm_cdr (s)) + { + Grob *other = unsmob_grob (scm_caar (s)); + Real dist = scm_to_double (scm_cdar (s)); + + Real y = -j * 0.1 -3.5; + vector pts; + pts.push_back (Offset (0, y)); + + Offset p2 (dist, y); + pts.push_back (p2); + + Stencil id_stencil = Lookup::points_to_line_stencil (0.1, pts); + Stencil head (musfont->find_by_name ("arrowheads.open.0M1")); + head.translate_axis (y, Y_AXIS); + id_stencil.add_stencil (head); + + id_stencil = id_stencil.in_color (1,0,0); + l.add_stencil (id_stencil); + } t.add_stencil (l); return t.smobbed_copy (); } diff --git a/lily/parser.yy b/lily/parser.yy index 7ea90f93da..0d42a60a18 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -503,7 +503,7 @@ embedded_scm: lilypond_header_body: { - $$ = get_header(PARSER); + $$ = get_header (PARSER); PARSER->lexer_->add_scope ($$); } | lilypond_header_body assignment { @@ -1701,25 +1701,25 @@ gen_text_def: script_abbreviation: '^' { - $$ = scm_makfrom0str ("Hat"); + $$ = scm_from_locale_string ("Hat"); } | '+' { - $$ = scm_makfrom0str ("Plus"); + $$ = scm_from_locale_string ("Plus"); } | '-' { - $$ = scm_makfrom0str ("Dash"); + $$ = scm_from_locale_string ("Dash"); } | '|' { - $$ = scm_makfrom0str ("Bar"); + $$ = scm_from_locale_string ("Bar"); } | ANGLE_CLOSE { - $$ = scm_makfrom0str ("Larger"); + $$ = scm_from_locale_string ("Larger"); } | '.' { - $$ = scm_makfrom0str ("Dot"); + $$ = scm_from_locale_string ("Dot"); } | '_' { - $$ = scm_makfrom0str ("Underscore"); + $$ = scm_from_locale_string ("Underscore"); } ; @@ -2384,7 +2384,7 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) SCM get_next_unique_context_id () { - return scm_makfrom0str ("$uniqueContextId"); + return scm_from_locale_string ("$uniqueContextId"); } @@ -2394,7 +2394,7 @@ get_next_unique_lyrics_context_id () static int new_context_count; char s[128]; snprintf (s, sizeof (s)-1, "uniqueContext%d", new_context_count++); - return scm_makfrom0str (s); + return scm_from_locale_string (s); } diff --git a/lily/part-combine-engraver.cc b/lily/part-combine-engraver.cc index 121ad3fbd2..831d4fb12e 100644 --- a/lily/part-combine-engraver.cc +++ b/lily/part-combine-engraver.cc @@ -104,6 +104,9 @@ ADD_TRANSLATOR (Part_combine_engraver, /* doc */ "Part combine engraver for orchestral scores: " "Print markings a2, Solo, Solo II, and unisono ", /* create */ "CombineTextScript", - /* read */ "printPartCombineTexts soloText soloIIText " + /* read */ + "printPartCombineTexts " + "soloText " + "soloIIText " "aDueText", /* write */ ""); diff --git a/lily/pfb.cc b/lily/pfb.cc index a96aac7761..11ee5d90c5 100644 --- a/lily/pfb.cc +++ b/lily/pfb.cc @@ -85,7 +85,7 @@ LY_DEFINE (ly_pfb_to_pfa, "ly:pfb->pfa", vector pfb_string = gulp_file (file_name, 0); char *pfa = pfb2pfa ((Byte *) &pfb_string[0], pfb_string.size ()); - SCM pfa_scm = scm_makfrom0str (pfa); + SCM pfa_scm = scm_from_locale_string (pfa); free (pfa); if (be_verbose_global) diff --git a/lily/pitch.cc b/lily/pitch.cc index da3a8a01dd..c0a24f47b2 100644 --- a/lily/pitch.cc +++ b/lily/pitch.cc @@ -245,7 +245,7 @@ Pitch::print_smob (SCM s, SCM port, scm_print_state *) { Pitch *r = (Pitch *) SCM_CELL_WORD_1 (s); scm_puts ("#to_string ().c_str ()), port); + scm_display (ly_string2scm (r->to_string ()), port); scm_puts (" >", port); return 1; } diff --git a/lily/prob.cc b/lily/prob.cc index a45e089a08..9c3b40d712 100644 --- a/lily/prob.cc +++ b/lily/prob.cc @@ -10,6 +10,7 @@ #include "main.hh" #include "item.hh" #include "input.hh" +#include "profile.hh" #include "ly-smobs.icc" @@ -140,6 +141,11 @@ Prob::print_smob (SCM smob, SCM port, scm_print_state*) SCM Prob::internal_get_property (SCM sym) const { +#ifndef NDEBUG + if (profile_property_accesses) + note_property_access (&prob_property_lookup_table, sym); +#endif + /* TODO: type checking */ diff --git a/lily/profile.cc b/lily/profile.cc index 6531a3f330..e1862c7236 100644 --- a/lily/profile.cc +++ b/lily/profile.cc @@ -12,22 +12,25 @@ void note_property_access (SCM *table, SCM sym); SCM context_property_lookup_table; SCM grob_property_lookup_table; +SCM prob_property_lookup_table; -LY_DEFINE (ly_context_property_lookup_stats, "ly:context-property-lookup-stats", - 0, 0, 0, (), - "") +LY_DEFINE (ly_property_lookup_stats, "ly:property-lookup-stats", + 1, 0, 0, (SCM sym), + "Return hash table with a property access corresponding to @var{sym}. " + "Choices are prob, grob and context.") { - return context_property_lookup_table ? context_property_lookup_table - : scm_c_make_hash_table (1); + if (sym == ly_symbol2scm ("context")) + return context_property_lookup_table ? context_property_lookup_table + : scm_c_make_hash_table (1); + if (sym == ly_symbol2scm ("prob")) + return prob_property_lookup_table ? prob_property_lookup_table + : scm_c_make_hash_table (1); + if (sym == ly_symbol2scm ("grob")) + return grob_property_lookup_table ? grob_property_lookup_table + : scm_c_make_hash_table (1); + return scm_c_make_hash_table (1); } -LY_DEFINE (ly_property_lookup_stats, "ly:grob-property-lookup-stats", - 0, 0, 0, (), - "") -{ - return grob_property_lookup_table ? grob_property_lookup_table - : scm_c_make_hash_table (1); -} void note_property_access (SCM *table, SCM sym) diff --git a/lily/program-option.cc b/lily/program-option.cc index 02213e4c71..0c87be9dc8 100644 --- a/lily/program-option.cc +++ b/lily/program-option.cc @@ -7,6 +7,7 @@ */ #include "program-option.hh" +#include "profile.hh" #include #include @@ -73,6 +74,11 @@ void internal_set_option (SCM var, SCM val) parsed_objects_should_be_dead = to_boolean (val); val = scm_from_bool (parsed_objects_should_be_dead); } + else if (var == ly_symbol2scm ("safe")) + { + be_safe_global = to_boolean (val); + val = scm_from_bool (be_safe_global); + } else if (var == ly_symbol2scm ("old-relative")) { lily_1_8_relative = to_boolean (val); @@ -216,6 +222,13 @@ LY_DEFINE (ly_command_line_verbose_p, "ly:command-line-verbose?", 0, 0, 0, (), +LY_DEFINE (ly_all_option, "ly:all-options", + 0, 0, 0, (), + "Get all option settings in an alist.") +{ + return ly_hash2alist (option_hash); +} + LY_DEFINE (ly_get_option, "ly:get-option", 1, 0, 0, (SCM var), "Get a global option setting.") @@ -226,6 +239,7 @@ LY_DEFINE (ly_get_option, "ly:get-option", 1, 0, 0, (SCM var), } + bool get_program_option (const char *s) { diff --git a/lily/quote-iterator.cc b/lily/quote-iterator.cc index c55aae3428..09e91e6e38 100644 --- a/lily/quote-iterator.cc +++ b/lily/quote-iterator.cc @@ -246,8 +246,7 @@ Quote_iterator::process (Moment m) Pitch diff = pitch_interval (qp, mp); ev = ev->clone (); - SCM props = transpose_mutable (ev->get_property_alist (true), diff); - ev = new Stream_event (ev->get_property ("class"), props); + transpose_mutable (ev->get_property_alist (true), diff); transposed_musics_ = scm_cons (ev->unprotect (), transposed_musics_); } quote_outlet_.get_outlet ()->event_source ()->broadcast (ev); diff --git a/lily/repeat-acknowledge-engraver.cc b/lily/repeat-acknowledge-engraver.cc index 56301cd2a3..0f94383838 100644 --- a/lily/repeat-acknowledge-engraver.cc +++ b/lily/repeat-acknowledge-engraver.cc @@ -102,7 +102,7 @@ Repeat_acknowledge_engraver::process_music () if (!scm_is_string (wb) || ly_is_equal (db, wb)) { if (s != "" || (volta_found && !scm_is_string (wb))) - context ()->set_property ("whichBar", scm_makfrom0str (s.c_str ())); + context ()->set_property ("whichBar", ly_string2scm (s)); } } diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index 5825671a17..588df93abe 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -117,7 +117,7 @@ Rest_collision::calc_positioning_done (SCM smob) no partners to collide with */ if (rests.size () + notes.size () < 2) - return SCM_UNSPECIFIED; + return SCM_BOOL_T; Real staff_space = Staff_symbol_referencer::staff_space (me); /* @@ -155,7 +155,7 @@ Rest_collision::calc_positioning_done (SCM smob) if (ordered_rests[-d].size () > 1) ordered_rests[-d][0]->warning (_ ("too many colliding rests")); - return SCM_UNSPECIFIED; + return SCM_BOOL_T; } } while (flip (&d) != LEFT); @@ -210,14 +210,14 @@ Rest_collision::calc_positioning_done (SCM smob) } if (!rcol) - return SCM_UNSPECIFIED; + return SCM_BOOL_T; Grob *rest = Note_column::get_rest (rcol); Grob *common = common_refpoint_of_array (notes, rcol, Y_AXIS); Interval restdim = rcol->extent (common, Y_AXIS); if (restdim.is_empty ()) - return SCM_UNSPECIFIED; + return SCM_BOOL_T; Real staff_space = Staff_symbol_referencer::staff_space (rcol); Real minimum_dist = robust_scm2double (me->get_property ("minimum-distance"), 1.0) * staff_space; @@ -249,7 +249,7 @@ Rest_collision::calc_positioning_done (SCM smob) Note_column::translate_rests (rcol, discrete_y); } - return SCM_UNSPECIFIED; + return SCM_BOOL_T; } ADD_INTERFACE (Rest_collision, diff --git a/lily/rest.cc b/lily/rest.cc index e3543e4cb9..61dd18b6c7 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -40,18 +40,6 @@ Rest::y_offset_callback (SCM smob) else amount += ss / 2; - Grob *dot = unsmob_grob (me->get_object ("dot")); - if (dot && duration_log > 4) // UGH. - { - dot->set_property ("staff-position", - scm_from_int ((duration_log == 7) ? 4 : 3)); - } - if (dot && duration_log >= -1 && duration_log <= 1) // UGH again. - { - dot->set_property ("staff-position", - scm_from_int ((duration_log == 0) ? -1 : 1)); - } - if (!position_override) amount += 2 * ss * get_grob_direction (me);; @@ -187,12 +175,25 @@ Rest::generic_extent_callback (Grob *me, Axis a) return ly_interval2scm (unsmob_stencil (m)->extent (a)); } +MAKE_SCHEME_CALLBACK (Rest, pure_height, 3); +SCM +Rest::pure_height (SCM smob, SCM start, SCM end) +{ + (void) start; + (void) end; + + Grob *me = unsmob_grob (smob); + SCM m = brew_internal_stencil (me, false); + return ly_interval2scm (unsmob_stencil (m)->extent (Y_AXIS)); +} + ADD_INTERFACE (Rest, "A rest symbol.", /* properties */ - "style " "direction " - "minimum-distance"); + "minimum-distance " + "style " + ); diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 91cca081e7..b70ead4349 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -99,6 +99,20 @@ Score_engraver::connect_to_context (Context *c) d->add_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish")); } +/* + uncovered: + + check_removal always returns false for Score contexts, it has been that way +since I joined the project. There is a reason for this: The typeset score is +stored in the Score_engraver, which in turn is accessed through the +Global_context returned by ly:run-translator. So the score-translator must be +connected to the score-context after run-translator finishes. + +I plan to change this: we should junk run-translator, and instead keep track +of both context and translator in the SCM code, and access the typeset score +directly via the created global-translator. Then it would be possible to +disconnect score-translators at iteration time. -es + */ void Score_engraver::disconnect_from_context () { diff --git a/lily/score-performer.cc b/lily/score-performer.cc index 73f79add86..0dfea54c6e 100644 --- a/lily/score-performer.cc +++ b/lily/score-performer.cc @@ -113,7 +113,7 @@ Score_performer::one_time_step (SCM) { if (!skipping_) { - skip_start_mom_ = audio_column_->at_mom (); + skip_start_mom_ = audio_column_->when (); skipping_ = true; } } @@ -121,11 +121,11 @@ Score_performer::one_time_step (SCM) { if (skipping_) { - offset_mom_ -= audio_column_->at_mom () - skip_start_mom_; + offset_mom_ -= audio_column_->when () - skip_start_mom_; skipping_ = false; } - audio_column_->offset_at_mom (offset_mom_); + audio_column_->offset_when (offset_mom_); precomputed_recurse_over_translators (context (), PROCESS_MUSIC, UP); do_announces (); } diff --git a/lily/score-scheme.cc b/lily/score-scheme.cc index b48219ad44..3b256b01f4 100644 --- a/lily/score-scheme.cc +++ b/lily/score-scheme.cc @@ -114,67 +114,3 @@ LY_DEFINE (ly_score_embedded_format, "ly:score-embedded-format", scm_remember_upto_here_1 (prot); return output; } - -LY_DEFINE (ly_score_process, "ly:render-music-as-systems", - 5, 0, 0, (SCM music, - SCM outdef, - SCM book_outputdef, - SCM header, - SCM outname), - "Create output using a default \\book block. ") -{ - SCM_ASSERT_TYPE(unsmob_music(music), music, - SCM_ARG1, __FUNCTION__, "music"); - SCM_ASSERT_TYPE(unsmob_output_def (outdef), outdef, - SCM_ARG2, __FUNCTION__, "output def"); - SCM_ASSERT_TYPE(unsmob_output_def (book_outputdef), book_outputdef, - SCM_ARG3, __FUNCTION__, "output def"); - SCM_ASSERT_TYPE(scm_is_string (outname), outname, - SCM_ARG5, __FUNCTION__, "string"); - - - SCM scaled_def = outdef; - SCM scaled_bookdef = book_outputdef; - - Output_def *bpd = unsmob_output_def (book_outputdef); - - /* ugh . */ - assert (bpd->c_variable ("is-paper") == SCM_BOOL_T); - - Real scale = scm_to_double (bpd->c_variable ("output-scale")); - - Output_def *def = scale_output_def (unsmob_output_def (outdef), scale); - Output_def *bdef = scale_output_def (bpd, scale); - def->parent_ = bdef; - - scaled_def = def->self_scm (); - scaled_bookdef = bdef->self_scm (); - - def->unprotect (); - bdef->unprotect (); - - SCM context = ly_run_translator (music, scaled_def, SCM_BOOL_F); - SCM output_as_scm = ly_format_output (context); - Music_output *output = unsmob_music_output (output_as_scm); - - Paper_score *pscore = dynamic_cast (output); - assert (pscore); - - /* ugh, this is strange, Paper_book without a Book object. */ - Paper_book *paper_book = new Paper_book (); - paper_book->header_ = header; - paper_book->paper_ = unsmob_output_def (scaled_bookdef); - - if (ly_is_module (header)) - paper_book->add_score (header); - - paper_book->add_score (pscore->self_scm ()); - paper_book->classic_output (outname); - paper_book->unprotect (); - - scm_remember_upto_here_1 (scaled_def); - scm_remember_upto_here_1 (scaled_bookdef); - - return SCM_UNSPECIFIED; -} - diff --git a/lily/semi-tie-column.cc b/lily/semi-tie-column.cc index 7a02ac578b..7b3ff58f89 100644 --- a/lily/semi-tie-column.cc +++ b/lily/semi-tie-column.cc @@ -58,8 +58,10 @@ Semi_tie_column::calc_positioning_done (SCM smob) Ties_configuration base = problem.generate_optimal_chord_configuration (); for (vsize i = 0; i < lv_ties.size(); i++) { - Tie::set_control_points (lv_ties[i], problem.common_x_refpoint (), base[i], - problem.details_); + SCM cp = Tie::get_control_points (lv_ties[i], problem.common_x_refpoint (), base[i], + problem.details_); + + lv_ties[i]->set_property ("control-points", cp); set_grob_direction (lv_ties[i], base[i].dir_); } diff --git a/lily/semi-tie.cc b/lily/semi-tie.cc index 77b266e6c4..80a56e4c74 100644 --- a/lily/semi-tie.cc +++ b/lily/semi-tie.cc @@ -23,6 +23,7 @@ ADD_INTERFACE(Semi_tie, "control-points " "direction " "details " + "head-direction " "note-head " "thickness " ); @@ -43,8 +44,8 @@ Semi_tie::calc_control_points (SCM smob) programming_error ("lv tie without Semi_tie_column. Killing lv tie."); me->suicide (); } - - return SCM_UNSPECIFIED; + + return me->get_property_data ("control-points"); } int diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index ffc4bfcbfc..9c71e6c448 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -356,29 +356,6 @@ next_spaceable_column (vector const &list, vsize starting) return 0; } -static void -get_column_spring (Grob *this_col, Grob *next_col, Real *ideal, Real *inv_hooke) -{ - Spring_smob *spring = 0; - - for (SCM s = this_col->get_object ("ideal-distances"); - !spring && scm_is_pair (s); - s = scm_cdr (s)) - { - Spring_smob *sp = unsmob_spring (scm_car (s)); - - if (sp->other_ == next_col) - spring = sp; - } - - if (!spring) - programming_error (_f ("No spring between column %d and next one", - Paper_column::get_rank (this_col))); - - *ideal = (spring) ? spring->distance_ : 5.0; - *inv_hooke = (spring) ? spring->inverse_strength_ : 1.0; -} - static Column_description get_column_description (vector const &cols, vsize col_index, bool line_starter) { @@ -389,10 +366,10 @@ get_column_description (vector const &cols, vsize col_index, bool line_st Column_description description; Grob *next_col = next_spaceable_column (cols, col_index); if (next_col) - get_column_spring (col, next_col, &description.ideal_, &description.inverse_hooke_); + Spaceable_grob::get_spring (col, next_col, &description.ideal_, &description.inverse_hooke_); Grob *end_col = dynamic_cast (cols[col_index+1])->find_prebroken_piece (LEFT); if (end_col) - get_column_spring (col, end_col, &description.end_ideal_, &description.end_inverse_hooke_); + Spaceable_grob::get_spring (col, end_col, &description.end_ideal_, &description.end_inverse_hooke_); for (SCM s = Spaceable_grob::get_minimum_distances (col); scm_is_pair (s); s = scm_cdr (s)) diff --git a/lily/skyline.cc b/lily/skyline.cc index 6b53a62ef8..e61abbaea6 100644 --- a/lily/skyline.cc +++ b/lily/skyline.cc @@ -41,6 +41,31 @@ but the distance routine does. */ +/* + FIXME: + + * Consider to use + + typedef list Skyline; + struct Skyline_point + { + Real x; + Drul_array ys; + }; + + this is a cleaner representation, as it doesn't duplicate the X, and + doesn't need bogus buildings at infinity --hwn. + + + * All the messing around with EPS is very fishy. There are no + complicated numerical algorithms involved, so EPS should not be + necessary. + + --hwn + + + */ + #define EPS 1e-10 static inline bool @@ -159,7 +184,7 @@ Building::print () const } Real -Building::intersection (Building const &other) const +Building::intersection_x (Building const &other) const { return (y_intercept_ - other.y_intercept_) / (other.slope_ - slope_); } @@ -213,9 +238,16 @@ skyline_trailing_part (list *sky, Real x) bool Building::conceals_beginning (Building const &other) const { - if (approx_equal (intersection (other), iv_[LEFT]) || approx_equal (height_[LEFT], other.height_[LEFT])) - return slope_ > other.slope_; - return height_[LEFT] > other.height_[LEFT]; + bool w = false; + Real h = other.height (iv_[LEFT]); + if (approx_equal (height_[LEFT], h)) + w = slope_ > other.slope_; + else if (height_[LEFT] > h) + w = true; + else + w = false; + + return w; } bool @@ -254,7 +286,7 @@ Skyline::internal_merge_skyline (list *s1, list *s2, if (approx_greater_than (s2_start_height, s1_start_height)) end = s2->front ().iv_[LEFT]; else if (approx_greater_than (s2_end_height, s1_end_height)) - end = b.intersection (s2->front ()); + end = b.intersection_x (s2->front ()); end = min (end, b.iv_[RIGHT]); b.leading_part (end); diff --git a/lily/slur-scoring.cc b/lily/slur-scoring.cc index bccee086c5..ef252da5dd 100644 --- a/lily/slur-scoring.cc +++ b/lily/slur-scoring.cc @@ -362,7 +362,7 @@ Slur_score_state::get_best_curve () } slur_->set_property ("quant-score", - scm_makfrom0str (total.c_str ())); + ly_string2scm (total)); } #endif diff --git a/lily/source-file.cc b/lily/source-file.cc index 4415e8dad7..e6aae1ceae 100644 --- a/lily/source-file.cc +++ b/lily/source-file.cc @@ -138,9 +138,9 @@ Source_file::Source_file (string filename_string) void Source_file::init_port () { - SCM str = scm_makfrom0str (c_str ()); + SCM str = scm_from_locale_string (c_str ()); str_port_ = scm_mkstrport (SCM_INUM0, str, SCM_OPN | SCM_RDNG, __FUNCTION__); - scm_set_port_filename_x (str_port_, scm_makfrom0str (name_.c_str ())); + scm_set_port_filename_x (str_port_, ly_string2scm (name_)); } diff --git a/lily/spaceable-grob.cc b/lily/spaceable-grob.cc index 7d86ebf919..d2326b6afb 100644 --- a/lily/spaceable-grob.cc +++ b/lily/spaceable-grob.cc @@ -15,6 +15,7 @@ #include "pointer-group-interface.hh" #include "grob.hh" #include "paper-column.hh" +#include "international.hh" SCM Spaceable_grob::get_minimum_distances (Grob *me) @@ -98,28 +99,30 @@ Spaceable_grob::add_spring (Grob *me, Grob *other, } void -Spaceable_grob::get_spring (Grob *me, Grob *other, Real *dist, Real *inv_strength) +Spaceable_grob::get_spring (Grob *this_col, Grob *next_col, Real *dist, Real *inv_strength) { - for (SCM s = me->get_object ("ideal-distances"); - scm_is_pair (s); s = scm_cdr (s)) + Spring_smob *spring = 0; + + for (SCM s = this_col->get_object ("ideal-distances"); + !spring && scm_is_pair (s); + s = scm_cdr (s)) { - Spring_smob *spring = unsmob_spring (scm_car (s)); - if (spring && spring->other_ == other) - { - *dist = spring->distance_; - *inv_strength = spring->inverse_strength_; - } + Spring_smob *sp = unsmob_spring (scm_car (s)); + + if (sp && sp->other_ == next_col) + spring = sp; } -} -void -Spaceable_grob::remove_interface (Grob *me) -{ - me->set_object ("minimum-distances", SCM_EOL); - me->set_object ("spacing-wishes", SCM_EOL); - me->set_object ("ideal-distances", SCM_EOL); + if (!spring) + programming_error (_f ("No spring between column %d and next one", + Paper_column::get_rank (this_col))); + + *dist = (spring) ? spring->distance_ : 5.0; + *inv_strength = (spring) ? spring->inverse_strength_ : 1.0; } + + ADD_INTERFACE (Spaceable_grob, "A layout object that takes part in the spacing problem. ", diff --git a/lily/span-bar.cc b/lily/span-bar.cc index 4566d73f77..bd10b1c671 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -185,7 +185,7 @@ Span_bar::calc_glyph_name (SCM smob) else if (type == ":|:") type = ".|."; - return scm_makfrom0str (type.c_str ()); + return ly_string2scm (type); } Interval diff --git a/lily/span-dynamic-performer.cc b/lily/span-dynamic-performer.cc deleted file mode 100644 index e5938f0852..0000000000 --- a/lily/span-dynamic-performer.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - span-dynamic-performer.cc -- implement Span_dynamic_performer - - source file of the GNU LilyPond music typesetter - - (c) 2000--2006 Jan Nieuwenhuizen -*/ - -#include "performer.hh" - -#include "audio-item.hh" -#include "international.hh" -#include "stream-event.hh" - -#include "translator.icc" - -/* - TODO: fold this into 1 engraver: \< and \> should also stop when - absdyn is encountered. -*/ -struct Audio_dynamic_tuple -{ - Audio_dynamic *audio_; - Moment mom_; -}; - -/** - perform span-dynamics -*/ -class Span_dynamic_performer : public Performer -{ -public: - TRANSLATOR_DECLARATIONS (Span_dynamic_performer); - -protected: - virtual void acknowledge_audio_element (Audio_element_info); - void process_music (); - void stop_translation_timestep (); - - DECLARE_TRANSLATOR_LISTENER (decrescendo); - DECLARE_TRANSLATOR_LISTENER (crescendo); -private: - Audio_dynamic *audio_; - Real last_volume_; - Stream_event *span_start_event_; - Drul_array span_events_; - vector dynamic_tuples_; - vector finished_dynamic_tuples_; - Direction dir_; - Direction finished_dir_; -}; - -Span_dynamic_performer::Span_dynamic_performer () -{ - span_events_[START] = 0; - span_events_[STOP] = 0; - span_start_event_ = 0; - audio_ = 0; - last_volume_ = 0; -} - -void -Span_dynamic_performer::acknowledge_audio_element (Audio_element_info i) -{ - if (Audio_dynamic *d = dynamic_cast (i.elem_)) - last_volume_ = d->volume_; -} - -void -Span_dynamic_performer::process_music () -{ - if (span_start_event_ || span_events_[START]) - { - audio_ = new Audio_dynamic (0); - Audio_element_info info (audio_, span_events_[START] - ? span_events_[START] - : span_events_[STOP]); - announce_element (info); - Audio_dynamic_tuple a = { audio_, now_mom () }; - dynamic_tuples_.push_back (a); - } - - if (span_events_[STOP]) - { - if (!span_start_event_) - { - span_events_[STOP]->origin ()->warning (_ ("cannot find start of (de)crescendo")); - span_events_[STOP] = 0; - } - else - { - finished_dir_ = dir_; - finished_dynamic_tuples_ = dynamic_tuples_; - } - dynamic_tuples_.clear (); - span_start_event_ = 0; - } - - if (span_events_[START]) - { - dir_ = (span_events_[START]->in_event_class ("crescendo-event")) - ? RIGHT : LEFT; - span_start_event_ = span_events_[START]; - - dynamic_tuples_.clear (); - Audio_dynamic_tuple a = { audio_, now_mom () }; - dynamic_tuples_.push_back (a); - } - - if (span_events_[STOP]) - finished_dynamic_tuples_.back ().audio_->volume_ = last_volume_; - - if (span_events_[START]) - dynamic_tuples_[0].audio_->volume_ = last_volume_; - - span_events_[START] = 0; - span_events_[STOP] = 0; -} - -void -Span_dynamic_performer::stop_translation_timestep () -{ - if (finished_dynamic_tuples_.size () > 1) - { - Real start_volume = finished_dynamic_tuples_[0].audio_->volume_; - Real dv = finished_dynamic_tuples_.back ().audio_->volume_ - - start_volume; - /* - urg. - Catch and fix the case of: - - | | - x| x| - f cresc. -- -- -- -- -- pp - - Actually, we should provide a non-displayed dynamic/volume setting, - to set volume to 'ff' just before the pp. - */ - if (!dv || sign (dv) != finished_dir_) - { - // urg. 20%: about two volume steps - dv = (Real)finished_dir_ * 0.2; - if (!start_volume) - start_volume = finished_dynamic_tuples_.back ().audio_->volume_ - - dv; - } - Moment start_mom = finished_dynamic_tuples_[0].mom_; - Moment dt = finished_dynamic_tuples_.back ().mom_ - start_mom; - for (vsize i = 0; i < finished_dynamic_tuples_.size (); i++) - { - Audio_dynamic_tuple *a = &finished_dynamic_tuples_[i]; - Real volume = start_volume + dv * (Real) (a->mom_ - start_mom).main_part_ - / (Real)dt.main_part_; - a->audio_->volume_ = volume; - } - finished_dynamic_tuples_.clear (); - } - - if (audio_) - { - audio_ = 0; - } - - span_events_[STOP] = 0; - span_events_[START] = 0; -} - -IMPLEMENT_TRANSLATOR_LISTENER (Span_dynamic_performer, decrescendo); -void -Span_dynamic_performer::listen_decrescendo (Stream_event *r) -{ - Direction d = to_dir (r->get_property ("span-direction")); - span_events_[d] = r; -} - -IMPLEMENT_TRANSLATOR_LISTENER (Span_dynamic_performer, crescendo); -void -Span_dynamic_performer::listen_crescendo (Stream_event *r) -{ - Direction d = to_dir (r->get_property ("span-direction")); - span_events_[d] = r; -} - -ADD_TRANSLATOR (Span_dynamic_performer, - "", "", - "", ""); diff --git a/lily/spanner-break-forbid-engraver.cc b/lily/spanner-break-forbid-engraver.cc new file mode 100644 index 0000000000..41d061c058 --- /dev/null +++ b/lily/spanner-break-forbid-engraver.cc @@ -0,0 +1,68 @@ +/* + spanner-break-forbid-engraver.cc -- implement Spanner_break_forbid_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2007 Han-Wen Nienhuys +*/ + + + +#include "engraver.hh" +#include "international.hh" +#include "spanner.hh" +#include "stream-event.hh" +#include "warn.hh" +#include "context.hh" + +#include "translator.icc" + +class Spanner_break_forbid_engraver : public Engraver +{ + TRANSLATOR_DECLARATIONS (Spanner_break_forbid_engraver); + vector running_spanners_; +protected: + DECLARE_ACKNOWLEDGER (unbreakable_spanner); + DECLARE_END_ACKNOWLEDGER (unbreakable_spanner); + + void process_music (); +}; + + +void +Spanner_break_forbid_engraver::process_music () +{ + if (running_spanners_.size ()) + { + context ()->get_score_context ()->set_property ("forbidBreak", SCM_BOOL_T); + } +} + +void +Spanner_break_forbid_engraver::acknowledge_end_unbreakable_spanner (Grob_info gi) +{ + vector::iterator i = find (running_spanners_.begin (), running_spanners_.end (), + gi.spanner ()); + if (i != running_spanners_.end ()) + running_spanners_.erase (i); +} + +void +Spanner_break_forbid_engraver::acknowledge_unbreakable_spanner (Grob_info gi) +{ + if (!to_boolean (gi.grob ()->get_property ("breakable"))) + running_spanners_.push_back (gi.spanner ()); +} + +Spanner_break_forbid_engraver::Spanner_break_forbid_engraver () +{ +} + + +ADD_END_ACKNOWLEDGER (Spanner_break_forbid_engraver, unbreakable_spanner); +ADD_ACKNOWLEDGER (Spanner_break_forbid_engraver, unbreakable_spanner); +ADD_TRANSLATOR (Spanner_break_forbid_engraver, + /* doc */ "Forbid breaks in certain spanners", + /* create */ "", + /* read */ "", + /* write */ ""); diff --git a/lily/staff-spacing.cc b/lily/staff-spacing.cc index f89113187e..0f1ec15de1 100644 --- a/lily/staff-spacing.cc +++ b/lily/staff-spacing.cc @@ -107,7 +107,7 @@ Staff_spacing::bar_y_positions (Grob *bar_grob) || glyph_string.substr (0, 1) == ".") { Grob *common = bar_grob->common_refpoint (staff_sym, Y_AXIS); - Interval bar_size = bar_grob->extent (common, Y_AXIS); + bar_size = bar_grob->extent (common, Y_AXIS); bar_size *= 1.0 / Staff_symbol_referencer::staff_space (bar_grob); } } @@ -138,28 +138,33 @@ Staff_spacing::next_notes_correction (Grob *me, Grob *last_grob, { Grob *g = right_items[i]; - Real space = 0.0; - Real fixed = 0.0; - next_note_correction (me, g, bar_size, &space, &fixed); - - *compound_space += space; - *compound_fixed += fixed; - wish_count ++; - - extract_grob_set (g, "elements", elts); - for (vsize j = elts.size (); j--;) + if (Note_column::has_interface (g)) { Real space = 0.0; Real fixed = 0.0; - next_note_correction (me, elts[j], bar_size, &space, &fixed); - *compound_fixed += fixed; + + next_note_correction (me, g, bar_size, &space, &fixed); + *compound_space += space; + *compound_fixed += fixed; wish_count ++; } + else + { + extract_grob_set (g, "elements", elts); + for (vsize j = elts.size (); j--;) + { + Real space = 0.0; + Real fixed = 0.0; + next_note_correction (me, elts[j], bar_size, &space, &fixed); + *compound_fixed += fixed; + *compound_space += space; + wish_count ++; + } + } } - - if (wish_count) + if (wish_count > 1) { *compound_space /= wish_count; *compound_fixed /= wish_count; diff --git a/lily/stem-tremolo.cc b/lily/stem-tremolo.cc index cf927a5e51..60cde74744 100644 --- a/lily/stem-tremolo.cc +++ b/lily/stem-tremolo.cc @@ -33,8 +33,8 @@ Stem_tremolo::calc_slope (SCM smob) if (is_number_pair (s)) dy = - scm_to_double (scm_car (s)) + scm_to_double (scm_cdr (s)); - Grob *s2 = Beam::last_visible_stem (beam); - Grob *s1 = Beam::first_visible_stem (beam); + Grob *s2 = Beam::last_normal_stem (beam); + Grob *s1 = Beam::first_normal_stem (beam); Grob *common = s1->common_refpoint (s2, X_AXIS); Real dx = s2->relative_coordinate (common, X_AXIS) - diff --git a/lily/stem.cc b/lily/stem.cc index 6757582869..e155a0611e 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -214,12 +214,9 @@ Stem::add_head (Grob *me, Grob *n) bool Stem::is_invisible (Grob *me) { - Real stemlet_length = robust_scm2double (me->get_property ("stemlet-length"), - 0.0); - - return !((head_count (me) - || stemlet_length > 0.0) - && scm_to_int (me->get_property ("duration-log")) >= 1); + return !is_normal_stem (me) + && (robust_scm2double (me->get_property ("stemlet-length"), + 0.0) == 0.0); } @@ -236,14 +233,17 @@ Stem::pure_height (SCM smob, SCM start, SCM end) { (void) start; (void) end; - - + Grob *me = unsmob_grob (smob); + Interval iv; + + if (!is_normal_stem (me)) + return ly_interval2scm (iv); + Real ss = Staff_symbol_referencer::staff_space (me); Real len = scm_to_double (calc_length (smob)) * ss / 2; Direction dir = get_grob_direction (me); - Interval iv; Interval hp = head_positions (me); if (dir == UP) iv = Interval (0, len); diff --git a/lily/system.cc b/lily/system.cc index 8fee382572..5070f9426c 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -23,6 +23,7 @@ #include "staff-symbol-referencer.hh" #include "tweak-registration.hh" #include "warn.hh" +#include "lookup.hh" extern bool debug_skylines; @@ -399,8 +400,8 @@ System::get_paper_system () exprs)); if (debug_skylines) { - sys_stencil.add_stencil (points_to_line_stencil (skylines_[UP].to_points ()).in_color (255, 0, 0)); - sys_stencil.add_stencil (points_to_line_stencil (skylines_[DOWN].to_points ()).in_color (0, 255, 0)); + sys_stencil.add_stencil (Lookup::points_to_line_stencil (0.1, skylines_[UP].to_points ()).in_color (255, 0, 0)); + sys_stencil.add_stencil (Lookup::points_to_line_stencil (0.1, skylines_[DOWN].to_points ()).in_color (0, 255, 0)); } Grob *left_bound = this->get_bound (LEFT); @@ -445,9 +446,7 @@ System::broken_col_range (Item const *left, Item const *right) const extract_grob_set (this, "columns", cols); - vsize i = binary_search (cols, (Grob *) left, - Paper_column::less_than); - + vsize i = Paper_column::get_rank (left); int end_rank = Paper_column::get_rank (right); if (i < cols.size ()) i++; @@ -494,11 +493,7 @@ Grob* System::column (int which) const { extract_grob_set (this, "columns", columns); - for (vsize i = 0; i < columns.size (); i++) - if (dynamic_cast (columns[i])->get_rank () == which) - return columns[i]; - programming_error ("couldn't find the column of the requested index"); - return columns[0]; + return columns[which]; } Paper_score* diff --git a/lily/text-metrics.cc b/lily/text-metrics.cc index 164d0062ff..fcab0495f8 100644 --- a/lily/text-metrics.cc +++ b/lily/text-metrics.cc @@ -31,7 +31,7 @@ lookup_tex_text_dimension (Font_metric *font, SCM text) if (text_dimension_hash_tab) { scm_hash_ref (text_dimension_hash_tab, - scm_makfrom0str (key_str.c_str ()), + ly_string2scm (key_str), SCM_BOOL_F); } if (scm_is_pair (val)) diff --git a/lily/tie-column.cc b/lily/tie-column.cc index dd54530e81..2121d318ce 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -100,9 +100,11 @@ Tie_column::calc_positioning_done (SCM smob) for (vsize i = 0; i < base.size(); i++) { - Tie::set_control_points (ties[i], problem.common_x_refpoint (), - base[i], - problem.details_); + SCM cp = Tie::get_control_points (ties[i], problem.common_x_refpoint (), + base[i], + problem.details_); + + ties[i]->set_property ("control-points", cp); set_grob_direction (ties[i], base[i].dir_); @@ -120,7 +122,7 @@ Tie_column::calc_positioning_done (SCM smob) card += to_string ("TOTAL=%.2f", base.score ()); ties[i]->set_property ("quant-score", - scm_makfrom0str (card.c_str ())); + ly_string2scm (card)); } #endif diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index 243b14b43f..9efe4784dc 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -9,7 +9,6 @@ #include "engraver.hh" #include "context.hh" -#include "grob-pitch-tuple.hh" #include "international.hh" #include "item.hh" #include "note-head.hh" @@ -160,8 +159,8 @@ Tie_engraver::start_translation_timestep () { context ()->set_property ("tieMelismaBusy", ly_bool2scm (heads_to_tie_.size ())); - - if (!to_boolean (get_property ("tieWaitForNote"))) + + if (heads_to_tie_.size () && !to_boolean (get_property ("tieWaitForNote"))) { Moment now = now_mom (); for (vsize i = heads_to_tie_.size (); i--; ) diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index d9d58cec70..7a751e14d2 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -294,8 +294,7 @@ Tie_formatting_problem::from_ties (vector const &ties) do { spec.note_head_drul_[d] = Tie::head (ties[i], d); - spec.column_ranks_[d] = - dynamic_cast (ties[i])->get_bound (d)->get_column ()->get_rank (); + spec.column_ranks_[d] = Tie::get_column_rank (ties[i], d); } while (flip (&d) != LEFT); specifications_.push_back (spec); @@ -328,7 +327,7 @@ Tie_formatting_problem::from_semi_ties (vector const &semi_ties, Directio spec.get_tie_manual_settings (semi_ties[i]); spec.note_head_drul_[head_dir] = head; - column_rank = dynamic_cast (head)->get_column ()->get_rank (); + column_rank = Tie::get_column_rank (semi_ties[i], head_dir); spec.column_ranks_ = Drul_array (column_rank, column_rank); heads.push_back (head); specifications_.push_back (spec); diff --git a/lily/tie.cc b/lily/tie.cc index 50519bc4f5..1e94638f39 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -152,16 +152,16 @@ Tie::calc_direction (SCM smob) { /* trigger positioning. */ (void) yparent->get_property ("positioning-done"); + + return me->get_property_data ("direction"); } else - set_grob_direction (me, Tie::get_default_dir (me)); - - return SCM_UNSPECIFIED; + return scm_from_int (Tie::get_default_dir (me)); } -void -Tie::set_default_control_points (Grob *me_grob) +SCM +Tie::get_default_control_points (Grob *me_grob) { Spanner *me = dynamic_cast (me_grob); Grob *common = me; @@ -174,17 +174,18 @@ Tie::set_default_control_points (Grob *me_grob) spec.has_manual_dir_ = true; spec.manual_dir_ = get_grob_direction (me); - if (me->is_live ()) - { - Tie_configuration conf - = problem.find_optimal_tie_configuration (spec); + if (!me->is_live ()) + return SCM_EOL; + + Tie_configuration conf + = problem.find_optimal_tie_configuration (spec); - set_control_points (me, problem.common_x_refpoint (), - conf, problem.details_); - } + return get_control_points (me, problem.common_x_refpoint (), + conf, problem.details_); } -void -Tie::set_control_points (Grob *me, + +SCM +Tie::get_control_points (Grob *me, Grob *common, Tie_configuration const &conf, Tie_details const &details @@ -200,9 +201,10 @@ Tie::set_control_points (Grob *me, programming_error ("Insane offset"); controls = scm_cons (ly_offset2scm (b.control_[i]), controls); } - me->set_property ("control-points", controls); + return controls; } + MAKE_SCHEME_CALLBACK(Tie, calc_control_points, 1); SCM Tie::calc_control_points (SCM smob) @@ -222,12 +224,13 @@ Tie::calc_control_points (SCM smob) (void) yparent->get_property ("positioning-done"); } - if (!scm_is_pair (me->get_property_data ("control-points"))) + SCM cp = me->get_property_data ("control-points"); + if (!scm_is_pair (cp)) { - set_default_control_points (me); + cp = get_default_control_points (me); } - return SCM_UNSPECIFIED; + return cp; } /* diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index 9ab2673eeb..973a1d8c5e 100644 --- a/lily/time-scaled-music-iterator.cc +++ b/lily/time-scaled-music-iterator.cc @@ -11,14 +11,14 @@ #include "input.hh" #include "international.hh" #include "music.hh" -#include "sequential-iterator.hh" +#include "music-wrapper-iterator.hh" /* Iterates \times, by sending TupletSpanEvents at the start/end of each tuplet bracket. Extra stop/start events are sent at regular intervals if tupletSpannerDuration is set. */ -class Time_scaled_music_iterator : public Sequential_iterator +class Time_scaled_music_iterator : public Music_wrapper_iterator { public: DECLARE_SCHEME_CALLBACK (constructor, ()); @@ -26,7 +26,6 @@ public: DECLARE_CLASSNAME(Time_scaled_music_iterator); Time_scaled_music_iterator (); protected: - virtual SCM get_music_list () const; virtual void process (Moment m); virtual void construct_children (); virtual void derived_mark () const; @@ -42,18 +41,26 @@ private: /* Recycle start/stop events if tupletSpannerDuration is set. */ Music *start_; Music *stop_; + + bool done_first_; + + Context_handle tuplet_handler_; }; Time_scaled_music_iterator::Time_scaled_music_iterator () { spanner_duration_ = next_split_mom_ = 0; + done_first_ = 0; } Moment Time_scaled_music_iterator::pending_moment () const { - Moment next_mom = Sequential_iterator::pending_moment (); + if (!done_first_) + return Moment (0); + + Moment next_mom = Music_wrapper_iterator::pending_moment (); if (spanner_duration_.to_bool () && next_mom.main_part_ > next_split_mom_) @@ -68,10 +75,21 @@ Time_scaled_music_iterator::pending_moment () const void Time_scaled_music_iterator::process (Moment m) { + if (!done_first_) + { + done_first_ = true; + descend_to_bottom_context (); + report_event (start_); + tuplet_handler_.set_context (get_outlet()); + } + if (spanner_duration_.to_bool () && m.main_part_ == next_split_mom_) { - report_event (stop_); + descend_to_bottom_context (); + stop_->send_to_context (tuplet_handler_.get_outlet ()); + + tuplet_handler_.set_context (get_outlet ()); report_event (start_); next_split_mom_ += spanner_duration_; @@ -79,7 +97,16 @@ Time_scaled_music_iterator::process (Moment m) if (next_split_mom_ == get_music ()->get_length ().main_part_) next_split_mom_.set_infinite (1); } - Sequential_iterator::process(m); + + Music_wrapper_iterator::process(m); + if (child_iter_ && child_iter_->ok ()) + descend_to_child (child_iter_->get_outlet ()); + + if (m.main_part_ == music_get_length ().main_part_) + { + stop_->send_to_context (tuplet_handler_.get_outlet ()); + tuplet_handler_.set_context (0); + } } void @@ -117,16 +144,10 @@ Time_scaled_music_iterator::construct_children () next_split_mom_ = spanner_duration_; } - Sequential_iterator::construct_children (); -} - -SCM -Time_scaled_music_iterator::get_music_list () const -{ - Music *mus = get_music (); - SCM child = mus->get_property ("element"); + Music_wrapper_iterator::construct_children (); - return scm_list_3 (start_->self_scm (), child, stop_->self_scm ()); + if (child_iter_ && child_iter_->ok ()) + descend_to_child (child_iter_->get_outlet ()); } void @@ -137,7 +158,7 @@ Time_scaled_music_iterator::derived_mark () const if (stop_) scm_gc_mark (stop_->self_scm ()); - Sequential_iterator::derived_mark (); + Music_wrapper_iterator::derived_mark (); } IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator); diff --git a/lily/time-signature-engraver.cc b/lily/time-signature-engraver.cc index 68a7e178b0..5cf3ebdc61 100644 --- a/lily/time-signature-engraver.cc +++ b/lily/time-signature-engraver.cc @@ -66,9 +66,14 @@ Time_signature_engraver::process_music () int (scm_to_int (scm_car (fr))))); } - last_time_fraction_ = fr; time_signature_ = make_item ("TimeSignature", SCM_EOL); time_signature_->set_property ("fraction", fr); + + if (last_time_fraction_ == SCM_BOOL_F) + time_signature_->set_property ("break-visibility", + get_property ("implicitTimeSignatureVisibility")); + + last_time_fraction_ = fr; } } @@ -81,7 +86,13 @@ Time_signature_engraver::stop_translation_timestep () #include "translator.icc" ADD_TRANSLATOR (Time_signature_engraver, - /* doc */ "Create a TimeSignature whenever @code{timeSignatureFraction} changes", - /* create */ "TimeSignature", - /* read */ "", + /* doc */ "Create a @ref{TimeSignature} whenever @code{timeSignatureFraction} changes", + /* create */ + "TimeSignature ", + + /* read */ + "implicitTimeSignatureVisibility " + "timeSignatureFraction " + + , /* write */ ""); diff --git a/lily/time-signature.cc b/lily/time-signature.cc index ced6468e8d..fa1bfadbd6 100644 --- a/lily/time-signature.cc +++ b/lily/time-signature.cc @@ -94,9 +94,9 @@ Time_signature::numbered_time_signature (Grob *me, int num, int den) chain); SCM sn = Text_interface::interpret_markup (me->layout ()->self_scm (), chain, - scm_makfrom0str (to_string (num).c_str ())); + ly_string2scm (to_string (num))); SCM sd = Text_interface::interpret_markup (me->layout ()->self_scm (), chain, - scm_makfrom0str (to_string (den).c_str ())); + ly_string2scm (to_string (den))); Stencil n = *unsmob_stencil (sn); Stencil d = *unsmob_stencil (sd); diff --git a/lily/translator-group-ctors.cc b/lily/translator-group-ctors.cc index 83feef1634..bca809281b 100644 --- a/lily/translator-group-ctors.cc +++ b/lily/translator-group-ctors.cc @@ -9,6 +9,7 @@ #include "score-engraver.hh" #include "score-performer.hh" #include "warn.hh" +#include "international.hh" /* Quick & dirty. @@ -25,11 +26,13 @@ get_translator_group (SCM sym) else if (sym == ly_symbol2scm ("Score_performer")) return new Score_performer (); - programming_error ("Couldn't find type"); + error (_f ("fatal error. Couldn't find type: %s", + ly_symbol2string (sym).c_str ())); scm_flush (scm_current_error_port ()); scm_display (sym, scm_current_error_port ()); scm_flush (scm_current_error_port ()); - assert (0); + exit (2); + return 0; } diff --git a/lily/translator-group.cc b/lily/translator-group.cc index 0fa39c662a..5445b9bd5b 100644 --- a/lily/translator-group.cc +++ b/lily/translator-group.cc @@ -21,11 +21,6 @@ #include "scm-hash.hh" #include "warn.hh" -Translator_group * -Translator_group::get_daddy_translator () const -{ - return context ()->get_parent_context ()->implementation (); -} void translator_each (SCM list, Translator_method method) diff --git a/lily/translator.cc b/lily/translator.cc index b7a46d29b6..8820879e01 100644 --- a/lily/translator.cc +++ b/lily/translator.cc @@ -199,7 +199,7 @@ Translator::static_translator_description (const char *grobs, parse_symbol_list (grobs), static_properties); static_properties = scm_acons (ly_symbol2scm ("description"), - scm_makfrom0str (desc), static_properties); + scm_from_locale_string (desc), static_properties); SCM list = SCM_EOL; for (; listener_list; listener_list = listener_list->next_) diff --git a/lily/ttf.cc b/lily/ttf.cc index 2e5eb8865d..1cb6fdc83c 100644 --- a/lily/ttf.cc +++ b/lily/ttf.cc @@ -231,7 +231,7 @@ LY_DEFINE (ly_ttf_ps_name, "ly:ttf-ps-name", FT_Face face = open_ft_face (file_name); char const *ps_name_str0 = FT_Get_Postscript_Name (face); - SCM ps_name = scm_makfrom0str (ps_name_str0 ? ps_name_str0 : ""); + SCM ps_name = scm_from_locale_string (ps_name_str0 ? ps_name_str0 : ""); FT_Done_Face (face); diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index d13cf1c613..4d4fbe9acb 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -511,37 +511,10 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy) Direction dir = get_grob_direction (me); - /* - Use outer non-rest columns to determine slope - */ - Grob *left_col = 0; - Grob *right_col = 0; - get_bounds (me, &left_col, &right_col); - if (left_col && right_col) - { - Interval rv = right_col->extent (commony, Y_AXIS); - Interval lv = left_col->extent (commony, Y_AXIS); - rv.unite (staff); - lv.unite (staff); - Real graphical_dy = rv[dir] - lv[dir]; - - Slice ls = Note_column::head_positions_interval (left_col); - Slice rs = Note_column::head_positions_interval (right_col); - - Interval musical_dy; - musical_dy[UP] = rs[UP] - ls[UP]; - musical_dy[DOWN] = rs[DOWN] - ls[DOWN]; - if (sign (musical_dy[UP]) != sign (musical_dy[DOWN])) - *dy = 0.0; - else if (sign (graphical_dy) != sign (musical_dy[DOWN])) - *dy = 0.0; - else - *dy = graphical_dy; - } - else - *dy = 0; + bool equally_long = false; + Grob *par_beam = parallel_beam (me, columns, &equally_long); + - *offset = -dir * infinity_f; Item *lgr = get_x_bound_item (me, LEFT, dir); Item *rgr = get_x_bound_item (me, RIGHT, dir); @@ -549,18 +522,82 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy) Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT]; vector points; - points.push_back (Offset (x0 - x0, staff[dir])); - points.push_back (Offset (x1 - x0, staff[dir])); - for (vsize i = 0; i < columns.size (); i++) + if (columns.size () + && par_beam + && get_grob_direction (par_beam) == dir + && Note_column::get_stem (columns[0]) + && Note_column::get_stem (columns.back ())) + { + /* + trigger set_stem_ends + */ + (void) par_beam->get_property ("quantized-positions"); + + + Drul_array stems (Note_column::get_stem (columns[0]), + Note_column::get_stem (columns.back ())); + + + + + Real ss = 0.5 * Staff_symbol_referencer::staff_space (me); + Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0); + Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0); + + *dy = rp - lp; + points.push_back (Offset (stems[LEFT]->relative_coordinate (commonx, X_AXIS) - x0, lp)); + points.push_back (Offset (stems[RIGHT]->relative_coordinate (commonx, X_AXIS) - x0, rp)); + } + else { - Interval note_ext = columns[i]->extent (commony, Y_AXIS); - Real notey = note_ext[dir] - me->relative_coordinate (commony, Y_AXIS); + /* + Use outer non-rest columns to determine slope + */ + Grob *left_col = 0; + Grob *right_col = 0; + get_bounds (me, &left_col, &right_col); + if (left_col && right_col) + { + Interval rv = right_col->extent (commony, Y_AXIS); + Interval lv = left_col->extent (commony, Y_AXIS); + rv.unite (staff); + lv.unite (staff); + Real graphical_dy = rv[dir] - lv[dir]; + + Slice ls = Note_column::head_positions_interval (left_col); + Slice rs = Note_column::head_positions_interval (right_col); + + Interval musical_dy; + musical_dy[UP] = rs[UP] - ls[UP]; + musical_dy[DOWN] = rs[DOWN] - ls[DOWN]; + if (sign (musical_dy[UP]) != sign (musical_dy[DOWN])) + *dy = 0.0; + else if (sign (graphical_dy) != sign (musical_dy[DOWN])) + *dy = 0.0; + else + *dy = graphical_dy; + } + else + *dy = 0; - Real x = columns[i]->relative_coordinate (commonx, X_AXIS) - x0; - points.push_back (Offset (x, notey)); + *offset = -dir * infinity_f; + for (vsize i = 0; i < columns.size (); i++) + { + Interval note_ext = columns[i]->extent (commony, Y_AXIS); + Real notey = note_ext[dir] - me->relative_coordinate (commony, Y_AXIS); + + Real x = columns[i]->relative_coordinate (commonx, X_AXIS) - x0; + points.push_back (Offset (x, notey)); + } } + if (!(par_beam && get_grob_direction (par_beam) == dir)) + { + points.push_back (Offset (x0 - x0, staff[dir])); + points.push_back (Offset (x1 - x0, staff[dir])); + } + /* This is a slight hack. We compute two encompass points from the bbox of the smaller tuplets. @@ -647,7 +684,6 @@ SCM Tuplet_bracket::calc_positions (SCM smob) { Spanner *me = unsmob_spanner (smob); - extract_grob_set (me, "note-columns", columns); /* Don't print if it doesn't span time. @@ -659,44 +695,9 @@ Tuplet_bracket::calc_positions (SCM smob) return SCM_EOL; } - - Direction dir = get_grob_direction (me); - bool equally_long = false; - Grob *par_beam = parallel_beam (me, columns, &equally_long); - - /* - We follow the beam only if there is one, and we are next to it. - */ Real dy = 0.0; Real offset = 0.0; - if (!par_beam - || get_grob_direction (par_beam) != dir) - calc_position_and_height (me, &offset, &dy); - else if (columns.size () - && Note_column::get_stem (columns[0]) - && Note_column::get_stem (columns.back ())) - { - /* - trigger set_stem_ends - */ - (void) par_beam->get_property ("quantized-positions"); - - - Drul_array stems (Note_column::get_stem (columns[0]), - Note_column::get_stem (columns.back ())); - - - - - Real ss = 0.5 * Staff_symbol_referencer::staff_space (me); - Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0); - Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0); - - - offset = lp + dir * (0.5 + scm_to_double (me->get_property ("padding"))); - dy = (rp - lp); - } - + calc_position_and_height (me, &offset, &dy); SCM x = scm_cons (scm_from_double (offset), scm_from_double (offset + dy)); diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index 66930ce6bd..fd280e127e 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -81,7 +81,9 @@ Tuplet_engraver::process_music () { for (vsize i = 0; i < stopped_tuplets_.size (); i++) { - if (stopped_tuplets_[i].bracket_) + Spanner *bracket = stopped_tuplets_[i].bracket_; + Spanner *number = stopped_tuplets_[i].number_; + if (bracket) { if (stopped_tuplets_[i].full_length_) { @@ -90,20 +92,20 @@ Tuplet_engraver::process_music () ? get_property ("currentMusicalColumn") : get_property ("currentCommandColumn")); - stopped_tuplets_[i].bracket_->set_bound (RIGHT, col); - stopped_tuplets_[i].number_->set_bound (RIGHT, col); + bracket->set_bound (RIGHT, col); + number->set_bound (RIGHT, col); } - else if (!stopped_tuplets_[i].bracket_->get_bound (RIGHT)) + else if (!bracket->get_bound (RIGHT)) { - stopped_tuplets_[i].bracket_->set_bound (RIGHT, - stopped_tuplets_[i].bracket_->get_bound (LEFT)); - stopped_tuplets_[i].number_->set_bound (RIGHT, + bracket->set_bound (RIGHT, + bracket->get_bound (LEFT)); + number->set_bound (RIGHT, stopped_tuplets_[i].bracket_->get_bound (LEFT)); } // todo: scrap last_tuplets_, use stopped_tuplets_ only. // clear stopped_tuplets_ at start_translation_timestep - last_tuplets_.push_back (tuplets_[i].bracket_); - last_tuplets_.push_back (tuplets_[i].number_); + last_tuplets_.push_back (bracket); + last_tuplets_.push_back (number); } } stopped_tuplets_.clear (); diff --git a/lily/vaticana-ligature-engraver.cc b/lily/vaticana-ligature-engraver.cc index 608cb16c66..6cd3c0bdac 100644 --- a/lily/vaticana-ligature-engraver.cc +++ b/lily/vaticana-ligature-engraver.cc @@ -681,7 +681,7 @@ Vaticana_ligature_engraver::transform_heads (Spanner *ligature, if (prev_primitive) prev_primitive->set_property ("glyph-name", - scm_makfrom0str (prev_glyph_name.c_str ())); + ly_string2scm (prev_glyph_name)); /* * In the backend, flexa shapes and joins need to know about line @@ -699,7 +699,7 @@ Vaticana_ligature_engraver::transform_heads (Spanner *ligature, } prev_primitive->set_property ("glyph-name", - scm_makfrom0str (prev_glyph_name.c_str ())); + ly_string2scm (prev_glyph_name)); align_heads (primitives, flexa_width, thickness); diff --git a/lily/vertical-align-engraver.cc b/lily/vertical-align-engraver.cc index 830aa78fd7..e1685077c1 100644 --- a/lily/vertical-align-engraver.cc +++ b/lily/vertical-align-engraver.cc @@ -102,7 +102,7 @@ Vertical_align_engraver::acknowledge_axis_group (Grob_info i) { string id = i.context ()->id_string (); - scm_hash_set_x (id_to_group_hashtab_, scm_makfrom0str (id.c_str ()), + scm_hash_set_x (id_to_group_hashtab_, ly_string2scm (id), i.grob ()->self_scm ()); SCM before_id = i.context ()->get_property ("alignAboveContext"); diff --git a/lily/volta-repeat-iterator.cc b/lily/volta-repeat-iterator.cc index 1828dfdbca..7e803b81c8 100644 --- a/lily/volta-repeat-iterator.cc +++ b/lily/volta-repeat-iterator.cc @@ -98,7 +98,7 @@ Volta_repeat_iterator::next_element (bool side_effect) if (done_count_ <= alt_count_) add_repeat_command (scm_list_n (ly_symbol2scm ("volta"), - scm_makfrom0str (repstr.c_str ()), SCM_UNDEFINED)); + ly_string2scm (repstr), SCM_UNDEFINED)); } else add_repeat_command (ly_symbol2scm ("end-repeat")); diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly index 210b81daf3..17329521a0 100644 --- a/ly/declarations-init.ly +++ b/ly/declarations-init.ly @@ -8,6 +8,7 @@ breve = #(ly:make-duration -1 0) longa = #(ly:make-duration -2 0) maxima = #(ly:make-duration -3 0) +\include "markup-init.ly" \include "music-functions-init.ly" %% default note names are dutch diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 063b9b44f9..759ef96fa6 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -233,6 +233,7 @@ contained staves are not connected vertically." \consists "Script_column_engraver" \consists "Rhythmic_column_engraver" \consists "Note_spacing_engraver" + \consists "Spanner_break_forbid_engraver" \consists "Phrasing_slur_engraver" \consists "Cluster_spanner_engraver" \consists "Slur_engraver" @@ -521,6 +522,8 @@ AncientRemoveEmptyStaffContext = \context { explicitClefVisibility = #all-visible explicitKeySignatureVisibility = #all-visible + implicitTimeSignatureVisibility = #end-of-line-invisible + autoBeamSettings = #default-auto-beam-settings autoBeaming = ##t autoBeamCheck = #default-auto-beam-check diff --git a/ly/init.ly b/ly/init.ly index eab90ef3d5..c3db3b3717 100644 --- a/ly/init.ly +++ b/ly/init.ly @@ -4,11 +4,6 @@ #(if (and #t (defined? 'set-debug-cell-accesses!)) (set-debug-cell-accesses! 5000)) -#(define-public midi-debug #f) - - - - \version "2.10.0" \include "declarations-init.ly" @@ -19,7 +14,8 @@ #(define output-count 0) #(define $defaultheader #f) #(define version-seen #f) - +#(define expect-error #f) +#(define output-empty-score-list #f) #(use-modules (scm clip-region)) \maininput @@ -38,7 +34,15 @@ (defined? 'input-file-name)) (version-not-seen-message input-file-name)) -#(if (pair? toplevel-scores) - (toplevel-book-handler +#(if (or (pair? toplevel-scores) output-empty-score-list) + ((if (defined? 'default-toplevel-book-handler) + default-toplevel-book-handler + toplevel-book-handler) parser (apply ly:make-book $defaultpaper $defaultheader toplevel-scores))) + + +#(if (eq? expect-error (ly:parser-has-error? parser)) + (ly:parser-clear-error parser) + (if expect-error + (ly:parser-error parser (_ "expected error, but none found")))) diff --git a/ly/lilypond-book-preamble.ly b/ly/lilypond-book-preamble.ly index aa82b7330c..a7bea92f15 100644 --- a/ly/lilypond-book-preamble.ly +++ b/ly/lilypond-book-preamble.ly @@ -1,12 +1,30 @@ \version "2.10.0" -#(set! toplevel-score-handler print-score-with-defaults) -#(set! toplevel-music-handler - (lambda (p m) - (if (not (eq? (ly:music-property m 'void) #t)) - (print-score-with-defaults - p (scorify-music m p))))) +%% toplevel \book gets output per page, +%% everything else gets output per system/title +#(define default-toplevel-book-handler + print-book-with-defaults-as-systems ) + +#(define toplevel-book-handler + (lambda ( . rest) + (set! output-empty-score-list #f) + (apply print-book-with-defaults rest))) + +#(define toplevel-music-handler + (lambda ( . rest) + (apply collect-music-for-book rest))) + +#(define toplevel-score-handler + (lambda ( . rest) + (apply collect-scores-for-book rest))) + +#(define toplevel-text-handler + (lambda ( . rest) + (apply collect-scores-for-book rest))) + +#(set! output-empty-score-list #t) + #(ly:set-option (quote no-point-and-click)) #(define inside-lilypond-book #t) diff --git a/ly/markup-init.ly b/ly/markup-init.ly new file mode 100644 index 0000000000..c40bd88ad4 --- /dev/null +++ b/ly/markup-init.ly @@ -0,0 +1,87 @@ +%% -*- Mode: Scheme -*- + +\version "2.11.9" + +%%;; to be define later, in a closure +#(define-public toplevel-module-define-public! #f) +#(define-public toplevel-module-ref #f) +#(let ((toplevel-module (current-module))) + (set! toplevel-module-define-public! + (lambda (symbol value) + (module-define! toplevel-module symbol value) + (module-export! toplevel-module (list symbol)))) + (set! toplevel-module-ref + (lambda (symbol) + (module-ref toplevel-module symbol)))) + +#(defmacro-public define-public-toplevel + (first-arg . rest) + "Define a public variable or function in the toplevel module: + (define-public-toplevel variable-name value) +or: + (define-public-toplevel (function-name . args) + ..body..)" + (if (symbol? first-arg) + ;; (define-public-toplevel symbol value) + (let ((symbol first-arg) + (value (car rest))) + `(toplevel-module-define-public! ',symbol ,value)) + ;; (define-public-toplevel (function-name . args) . body) + (let ((function-name (car first-arg)) + (arg-list (cdr first-arg)) + (body rest)) + `(toplevel-module-define-public! + ',function-name + (let ((proc (lambda ,arg-list + ,@body))) + (set-procedure-property! proc + 'name + ',function-name) + proc))))) + +#(defmacro-public define-markup-command (command-and-args signature . body) + " +* Define a COMMAND-markup function after command-and-args and body, +register COMMAND-markup and its signature, + +* add COMMAND-markup to markup-function-list, + +* sets COMMAND-markup markup-signature and markup-keyword object properties, + +* define a make-COMMAND-markup function. + +Syntax: + (define-markup-command (COMMAND layout props arg1 arg2 ...) + (arg1-type? arg2-type? ...) + \"documentation string\" + ...command body...) +or: + (define-markup-command COMMAND (arg1-type? arg2-type? ...) function) +" + (let* ((command (if (pair? command-and-args) + (car command-and-args) + command-and-args)) + (command-name (string->symbol (format #f "~a-markup" command))) + (make-markup-name (string->symbol (format #f "make-~a-markup" command)))) + `(begin + ;; define the COMMAND-markup procedure in toplevel module + ,(if (pair? command-and-args) + ;; 1/ (define (COMMAND-markup layout props arg1 arg2 ...) + ;; ..command body)) + `(define-public-toplevel (,command-name ,@(cdr command-and-args)) + ,@body) + ;; 2/ (define (COMMAND-markup . args) (apply function args)) + (let ((args (gensym "args")) + (command (car body))) + `(define-public-toplevel (,command-name . ,args) + (apply ,command ,args)))) + (let ((command-proc (toplevel-module-ref ',command-name))) + ;; register its command signature + (set! (markup-command-signature command-proc) + (list ,@signature)) + ;; define the make-COMMAND-markup procedure in the toplevel module + (define-public-toplevel (,make-markup-name . args) + (make-markup command-proc + ,(symbol->string make-markup-name) + (list ,@signature) + args)))))) diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index 725ba480a5..2f4876b044 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -14,7 +14,7 @@ acciaccatura = #(def-grace-function startAcciaccaturaMusic stopAcciaccaturaMusic) -addquote = +addQuote = #(define-music-function (parser location name music) (string? ly:music?) (_i "Add a piece of music to be quoted ") (add-quotable parser name music) diff --git a/ly/performer-init.ly b/ly/performer-init.ly index 24f0da2b81..23e96dae3c 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -30,9 +30,7 @@ \context { \type "Performer_group" \name Voice - % The order of the dynamic performers is significant: absolute dynamic events must override crescendo events in midi. - \consists "Span_dynamic_performer" - \consists "Dynamic_performer" + \consists "New_dynamic_performer" \consists "Tie_performer" \consists "Piano_pedal_performer" \consists "Note_performer" diff --git a/make/ly-rules.make b/make/ly-rules.make index 8b59dc9619..2e9e5ff022 100644 --- a/make/ly-rules.make +++ b/make/ly-rules.make @@ -7,12 +7,10 @@ $(outdir)/%.latex: %.doc # don't do ``cd $(outdir)'', and assume that $(outdir)/.. is the src dir. # it is not, for --srcdir builds $(outdir)/%.texi: %.tely - rm -f $$(grep -LF '% eof' $(outdir)/lily-*systems.*tex 2>/dev/null) $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BINARY) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) $(LILYPOND_BOOK_FLAGS) $< $(outdir)/%.texi: $(outdir)/%.tely - rm -f $$(grep -LF '% eof' $(outdir)/lily-*systems.*tex 2>/dev/null) $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BINARY) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) $(LILYPOND_BOOK_FLAGS) $< # # DON'T REMOVE SOURCE FILES, otherwise the .TEXI ALWAYS OUT OF DATE. diff --git a/python/convertrules.py b/python/convertrules.py index d6b89e777d..cd08dab83e 100644 --- a/python/convertrules.py +++ b/python/convertrules.py @@ -2927,3 +2927,17 @@ def conv (str): return str conversions.append (((2, 11, 6), conv, """Rename accidental glyphs, use glyph-name-alist.""")) + + +def conv (str): + str = re.sub (r'(\\set\s+)?([A-Z][a-zA-Z]+\s*\.\s*)allowBeamBreak', + r"\override \2Beam #'breakable", str) + str = re.sub (r'(\\set\s+)?allowBeamBreak', + r"\override Beam #'breakable", str) + str = re.sub (r'addquote' , 'addQuote', str) + return str + +conversions.append (((2, 11, 10), conv, """allowBeamBreak -> Beam #'breakable = ##t +addquote -> addQuote + +""")) diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 43a738d6ae..5debc1d10d 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -38,7 +38,6 @@ (alignBassFigureAccidentals ,boolean? "If true, then the accidentals are aligned in bass figure context.") - (allowBeamBreak ,boolean? "If true allow line breaks for beams over bar lines.") (associatedVoice ,string? "Name of the @code{Voice} that has the melody for this @code{Lyrics} line.") (autoBeamSettings ,list? "Specifies @@ -249,6 +248,8 @@ selector for tab notation.") (ignoreBarChecks ,boolean? "Ignore bar checks") (ignoreMelismata ,boolean? "Ignore melismata for this @internalsref{Lyrics} line.") + (implicitTimeSignatureVisibility ,vector? "break visibility for the default timesignature.") + (implicitBassFigures ,list? "List of bass figures that are not printed as numbers, but only as extender lines.") diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index 4936710172..e141103e05 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -176,6 +176,13 @@ interesting enough to maintain a hara-kiri staff." "An interface for any notes set in a tablature staff" '()) +(ly:add-interface + 'unbreakable-spanner-interface + "A spanner that should not be broken across line breaks. Override +with @code{breakable=##t}. " + + '(breakable)) + (ly:add-interface 'vertically-spaceable-interface "Objects that should be kept at constant vertical distances. Typically: diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 918fe5d11f..d2c49e6278 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -68,6 +68,7 @@ beaming patterns from stem to stem inside a beam.") (bracket-flare ,number-pair? "A pair of numbers specifying how much edges of brackets should slant outward. Value 0.0 means straight edges") + (breakable ,boolean? "Allow breaks here.") (break-align-symbol ,symbol? "This key is used for aligning and spacing breakable items.") (break-align-orders ,vector? " Defines the order in which @@ -451,9 +452,9 @@ glissando line can be constructed from a whole number of squiggles.") ;;;;;;;;;;;;;;;; ;; grobs & grob arrays. (alphabetical) - + (Y-common ,ly:grob? "See X-common") + (X-common ,ly:grob? "Common refpoint for axis group.") (cached-pure-extents ,vector? "Used by a VerticalAxisGroup to cache the Y-extents of different column ranges.") - (common-refpoint-of-elements ,ly:grob? "Caches the common_refpoint_of_array of the elements grob-set") (axis-group-parent-X ,ly:grob? "Containing X axis group") (axis-group-parent-Y ,ly:grob? "Containing Y axis group") (accidental-grobs ,list? "Alist with (NOTENAME . GROBLIST) entries") @@ -482,6 +483,7 @@ columns. (left-items ,ly:grob-array? "") (pedal-text ,ly:grob? "Pointer to the text of a mixed-style piano pedal.") + (pure-Y-common ,ly:grob? "Caches the common_refpoint_of_array of the elements grob-set") (pure-relevant-elements ,ly:grob-array? "The subset of elements that are relevant for finding the pure-Y-extent.") (stem ,ly:grob? "pointer to Stem object.") (tremolo-flag ,ly:grob? "The tremolo object on a stem.") @@ -508,6 +510,7 @@ where this is set in.") (note-columns ,pair? "list of NoteColumn grobs.") + (normal-stems ,ly:grob-array? "Array of visible stems.") (note-heads ,ly:grob-array? "List of note head grobs") (note-head ,ly:grob? "A single note head") (right-items ,ly:grob-array? "") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 33493aabdf..d3270748bb 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -127,7 +127,7 @@ (after-line-breaking . ,ly:accidental-interface::after-line-breaking) (side-axis . ,X) (meta . ((class . Item) - (interfaces . (item-interface + (interfaces . ( accidental-interface break-aligned-interface side-position-interface @@ -325,7 +325,8 @@ (beaming . ,ly:beam::calc-beaming) (stencil . ,ly:beam::print) (clip-edges . #t) - + + (details . ((hint-direction-penalty . 20))) ;; TODO: should be in SLT. (thickness . 0.48) ; in staff-space (neutral-direction . ,DOWN) @@ -351,7 +352,9 @@ ;; only for debugging. (font-family . roman) (meta . ((class . Spanner) + (object-callbacks . ((normal-stems . ,ly:beam::calc-normal-stems))) (interfaces . (staff-symbol-referencer-interface + unbreakable-spanner-interface beam-interface)))))) (BendAfter @@ -492,7 +495,7 @@ rhythmic-grob-interface text-interface chord-name-interface - item-interface)))))) + )))))) (CombineTextScript . ( @@ -548,6 +551,7 @@ . ( (stencil . ,ly:dots::print) (dot-count . ,dots::calc-dot-count) + (staff-position . ,dots::calc-staff-position) (meta . ((class . Item) (interfaces . (font-interface staff-symbol-referencer-interface @@ -667,7 +671,6 @@ (self-alignment-X . 0) (self-alignment-Y . 0) (script-priority . 100) - (stencil . ,ly:text-interface::print) (direction . ,ly:script-interface::calc-direction) (text . ,fingering::calc-text) @@ -680,7 +683,7 @@ text-interface side-position-interface self-alignment-interface - item-interface)))))) + )))))) (FretBoard . ((stencil . ,fret-board::calc-stencil) (finger-code . below-string) @@ -700,6 +703,7 @@ (after-line-breaking . ,ly:line-spanner::after-line-breaking) (meta . ((class . Spanner) (interfaces . (line-interface + unbreakable-spanner-interface line-spanner-interface)))))) (GraceSpacing @@ -1375,7 +1379,6 @@ ;; padding set in script definitions. (staff-padding . 0.25) - ;; (script-priority . 0) priorities for scripts, see script.scm (X-offset . ,ly:self-alignment-interface::centered-on-x-parent) (Y-offset . ,ly:side-position-interface::y-aligned-side) (side-axis . ,Y) @@ -1618,7 +1621,7 @@ text-interface side-position-interface self-alignment-interface - item-interface)))))) + )))))) (StrokeFinger . ( @@ -1639,7 +1642,7 @@ text-interface side-position-interface self-alignment-interface - item-interface)))))) + )))))) (SustainPedal @@ -1890,8 +1893,8 @@ (stencil . ,ly:accidental-interface::print) (glyph-name-alist . ,standard-alteration-glyph-name-alist) (meta . ((class . Item) - (interfaces . (item-interface - trill-pitch-accidental-interface + (interfaces . (trill-pitch-accidental-interface + accidental-interface side-position-interface font-interface)))))) @@ -1906,6 +1909,7 @@ (padding . 0.3) (meta . ((class . Item) (interfaces . (side-position-interface + parentheses-interface note-head-interface rhythmic-head-interface font-interface @@ -1918,8 +1922,7 @@ (Y-offset . ,ly:staff-symbol-referencer::callback) (font-size . -4) (meta . ((class . Item) - (interfaces . (item-interface - rhythmic-head-interface + (interfaces . (rhythmic-head-interface font-interface pitched-trill-interface ledgered-interface @@ -2003,6 +2006,7 @@ (padding . 0.5) (skylines . ,ly:axis-group-interface::combine-skylines) (meta . ((class . Spanner) + (object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common))) (interfaces . (align-interface axis-group-interface)))))) (VerticalAxisGroup @@ -2013,6 +2017,7 @@ (X-extent . ,ly:axis-group-interface::width) (skylines . ,ly:axis-group-interface::calc-skylines); (meta . ((class . Spanner) + (object-callbacks . ((X-common . ,ly:axis-group-interface::calc-x-common))) (interfaces . (axis-group-interface hara-kiri-group-spanner-interface vertically-spaceable-interface)))))) @@ -2082,6 +2087,8 @@ (cons 'spanner-interface ifaces-entry)))) (else (ly:warning "Unknown class ~a" class))) + + (set! ifaces-entry (uniq-list (sort ifaces-entry symbolstencil axis size file-name) )) -(define-markup-command (postscript layout props str) (string?) +(define-builtin-markup-command (postscript layout props str) (string?) "This inserts @var{str} directly into the output as a PostScript command string. Due to technicalities of the output backends, different scales should be used for the @TeX{} and PostScript backend, @@ -244,7 +244,7 @@ grestore '(0 . 0) '(0 . 0))) -(define-markup-command (score layout props score) (ly:score?) +(define-builtin-markup-command (score layout props score) (ly:score?) "Inline an image of music." (let* ((output (ly:score-embedded-format score layout))) @@ -255,7 +255,7 @@ grestore (ly:warning (_"no systems found in \\score markup, does it have a \\layout block?")) empty-stencil)))) -(define-markup-command (null layout props) () +(define-builtin-markup-command (null layout props) () "An empty markup with extents of a single point" point-stencil) @@ -266,12 +266,12 @@ grestore -(define-markup-command (simple layout props str) (string?) +(define-builtin-markup-command (simple layout props str) (string?) "A simple text string; @code{\\markup @{ foo @}} is equivalent with @code{\\markup @{ \\simple #\"foo\" @}}." (interpret-markup layout props str)) -(define-markup-command (tied-lyric layout props str) (string?) +(define-builtin-markup-command (tied-lyric layout props str) (string?) "Like simple-markup, but use tie characters for ~ tilde symbols." @@ -329,7 +329,7 @@ grestore (/ (+ (car text-widths) (car (cdr text-widths))) 2)) (get-fill-space word-count line-width (cdr text-widths)))))) -(define-markup-command (fill-line layout props markups) +(define-builtin-markup-command (fill-line layout props markups) (markup-list?) "Put @var{markups} in a horizontal line of width @var{line-width}. The markups are spaced/flushed to fill the entire line. @@ -389,7 +389,7 @@ grestore (stack-stencils-padding-list X RIGHT fill-space-normal line-stencils)))) -(define-markup-command (line layout props args) (markup-list?) +(define-builtin-markup-command (line layout props args) (markup-list?) "Put @var{args} in a horizontal line. The property @code{word-space} determines the space between each markup in @var{args}." (let* @@ -406,7 +406,7 @@ determines the space between each markup in @var{args}." space (remove ly:stencil-empty? stencils)))) -(define-markup-command (concat layout props args) (markup-list?) +(define-builtin-markup-command (concat layout props args) (markup-list?) "Concatenate @var{args} in a horizontal line, without spaces inbetween. Strings and simple markups are concatenated on the input level, allowing ligatures. For example, @code{\\concat @{ \"f\" \\simple #\"i\" @}} is @@ -524,14 +524,14 @@ equivalent to @code{\"fi\"}." (stack-lines DOWN 0.0 baseline-skip lines))) -(define-markup-command (justify layout props args) (markup-list?) +(define-builtin-markup-command (justify layout props args) (markup-list?) "Like wordwrap, but with lines stretched to justify the margins. Use @code{\\override #'(line-width . X)} to set line-width, where X is the number of staff spaces." (wordwrap-markups layout props args #t)) -(define-markup-command (wordwrap layout props args) (markup-list?) +(define-builtin-markup-command (wordwrap layout props args) (markup-list?) "Simple wordwrap. Use @code{\\override #'(line-width . X)} to set line-width, where X is the number of staff spaces." @@ -572,23 +572,23 @@ line-width, where X is the number of staff spaces." (stack-lines DOWN 0.0 baseline-skip (apply append para-lines)))) -(define-markup-command (wordwrap-string layout props arg) (string?) +(define-builtin-markup-command (wordwrap-string layout props arg) (string?) "Wordwrap a string. Paragraphs may be separated with double newlines" (wordwrap-string layout props #f arg)) -(define-markup-command (justify-string layout props arg) (string?) +(define-builtin-markup-command (justify-string layout props arg) (string?) "Justify a string. Paragraphs may be separated with double newlines" (wordwrap-string layout props #t arg)) -(define-markup-command (wordwrap-field layout props symbol) (symbol?) +(define-builtin-markup-command (wordwrap-field layout props symbol) (symbol?) (let* ((m (chain-assoc-get symbol props))) (if (string? m) (interpret-markup layout props (list wordwrap-string-markup m)) (ly:make-stencil '() '(1 . -1) '(1 . -1))))) -(define-markup-command (justify-field layout props symbol) (symbol?) +(define-builtin-markup-command (justify-field layout props symbol) (symbol?) (let* ((m (chain-assoc-get symbol props))) (if (string? m) (interpret-markup layout props @@ -597,7 +597,7 @@ line-width, where X is the number of staff spaces." -(define-markup-command (combine layout props m1 m2) (markup? markup?) +(define-builtin-markup-command (combine layout props m1 m2) (markup? markup?) "Print two markups on top of each other." (let* ((s1 (interpret-markup layout props m1)) (s2 (interpret-markup layout props m2))) @@ -606,7 +606,7 @@ line-width, where X is the number of staff spaces." ;; ;; TODO: should extract baseline-skip from each argument somehow.. ;; -(define-markup-command (column layout props args) (markup-list?) +(define-builtin-markup-command (column layout props args) (markup-list?) "Stack the markups in @var{args} vertically. The property @code{baseline-skip} determines the space between each markup in @var{args}." @@ -620,7 +620,7 @@ line-width, where X is the number of staff spaces." (remove ly:stencil-empty? arg-stencils)))) -(define-markup-command (dir-column layout props args) (markup-list?) +(define-builtin-markup-command (dir-column layout props args) (markup-list?) "Make a column of args, going up or down, depending on the setting of the @code{#'direction} layout property." (let* ((dir (chain-assoc-get 'direction props))) @@ -630,39 +630,39 @@ of the @code{#'direction} layout property." (chain-assoc-get 'baseline-skip props) (map (lambda (x) (interpret-markup layout props x)) args)))) -(define-markup-command (center-align layout props args) (markup-list?) +(define-builtin-markup-command (center-align layout props args) (markup-list?) "Put @code{args} in a centered column. " (let* ((mols (map (lambda (x) (interpret-markup layout props x)) args)) (cmols (map (lambda (x) (ly:stencil-aligned-to x X CENTER)) mols))) (stack-lines -1 0.0 (chain-assoc-get 'baseline-skip props) cmols))) -(define-markup-command (vcenter layout props arg) (markup?) +(define-builtin-markup-command (vcenter layout props arg) (markup?) "Align @code{arg} to its Y center. " (let* ((mol (interpret-markup layout props arg))) (ly:stencil-aligned-to mol Y CENTER))) -(define-markup-command (hcenter layout props arg) (markup?) +(define-builtin-markup-command (hcenter layout props arg) (markup?) "Align @code{arg} to its X center. " (let* ((mol (interpret-markup layout props arg))) (ly:stencil-aligned-to mol X CENTER))) -(define-markup-command (right-align layout props arg) (markup?) +(define-builtin-markup-command (right-align layout props arg) (markup?) "Align @var{arg} on its right edge. " (let* ((m (interpret-markup layout props arg))) (ly:stencil-aligned-to m X RIGHT))) -(define-markup-command (left-align layout props arg) (markup?) +(define-builtin-markup-command (left-align layout props arg) (markup?) "Align @var{arg} on its left edge. " (let* ((m (interpret-markup layout props arg))) (ly:stencil-aligned-to m X LEFT))) -(define-markup-command (general-align layout props axis dir arg) (integer? number? markup?) +(define-builtin-markup-command (general-align layout props axis dir arg) (integer? number? markup?) "Align @var{arg} in @var{axis} direction to the @var{dir} side." (let* ((m (interpret-markup layout props arg))) (ly:stencil-aligned-to m axis dir))) -(define-markup-command (halign layout props dir arg) (number? markup?) +(define-builtin-markup-command (halign layout props dir arg) (number? markup?) "Set horizontal alignment. If @var{dir} is @code{-1}, then it is left-aligned, while @code{+1} is right. Values in between interpolate alignment accordingly." @@ -671,14 +671,14 @@ alignment accordingly." -(define-markup-command (with-dimensions layout props x y arg) (number-pair? number-pair? markup?) +(define-builtin-markup-command (with-dimensions layout props x y arg) (number-pair? number-pair? markup?) "Set the dimensions of @var{arg} to @var{x} and @var{y}." (let* ((m (interpret-markup layout props arg))) (ly:make-stencil (ly:stencil-expr m) x y))) -(define-markup-command (pad-around layout props amount arg) (number? markup?) +(define-builtin-markup-command (pad-around layout props amount arg) (number? markup?) "Add padding @var{amount} all around @var{arg}. " @@ -694,7 +694,7 @@ alignment accordingly." )) -(define-markup-command (pad-x layout props amount arg) (number? markup?) +(define-builtin-markup-command (pad-x layout props amount arg) (number? markup?) "Add padding @var{amount} around @var{arg} in the X-direction. " (let* @@ -709,7 +709,7 @@ alignment accordingly." )) -(define-markup-command (put-adjacent layout props arg1 axis dir arg2) (markup? integer? ly:dir? markup?) +(define-builtin-markup-command (put-adjacent layout props arg1 axis dir arg2) (markup? integer? ly:dir? markup?) "Put @var{arg2} next to @var{arg1}, without moving @var{arg1}. " @@ -719,7 +719,7 @@ alignment accordingly." (ly:stencil-combine-at-edge m1 axis dir m2 0.0 0.0) )) -(define-markup-command (transparent layout props arg) (markup?) +(define-builtin-markup-command (transparent layout props arg) (markup?) "Make the argument transparent" (let* ((m (interpret-markup layout props arg)) @@ -732,7 +732,7 @@ alignment accordingly." x y))) -(define-markup-command (pad-to-box layout props x-ext y-ext arg) +(define-builtin-markup-command (pad-to-box layout props x-ext y-ext arg) (number-pair? number-pair? markup?) "Make @var{arg} take at least @var{x-ext}, @var{y-ext} space" @@ -746,7 +746,7 @@ alignment accordingly." (interval-union y-ext y)))) -(define-markup-command (hcenter-in layout props length arg) +(define-builtin-markup-command (hcenter-in layout props length arg) (number? markup?) "Center @var{arg} horizontally within a box of extending @var{length}/2 to the left and right." @@ -762,7 +762,7 @@ alignment accordingly." ;; property ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-markup-command (fromproperty layout props symbol) (symbol?) +(define-builtin-markup-command (fromproperty layout props symbol) (symbol?) "Read the @var{symbol} from property settings, and produce a stencil from the markup contained within. If @var{symbol} is not defined, it returns an empty markup" @@ -772,7 +772,7 @@ alignment accordingly." (ly:make-stencil '() '(1 . -1) '(1 . -1))))) -(define-markup-command (on-the-fly layout props procedure arg) (symbol? markup?) +(define-builtin-markup-command (on-the-fly layout props procedure arg) (symbol? markup?) "Apply the @var{procedure} markup command to @var{arg}. @var{procedure} should take a single argument." (let* ((anonymous-with-signature (lambda (layout props arg) (procedure layout props arg)))) @@ -783,7 +783,7 @@ alignment accordingly." -(define-markup-command (override layout props new-prop arg) (pair? markup?) +(define-builtin-markup-command (override layout props new-prop arg) (pair? markup?) "Add the first argument in to the property list. Properties may be any sort of property supported by @internalsref{font-interface} and @internalsref{text-interface}, for example @@ -799,7 +799,7 @@ any sort of property supported by @internalsref{font-interface} and ;; files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-markup-command (verbatim-file layout props name) (string?) +(define-builtin-markup-command (verbatim-file layout props name) (string?) "Read the contents of a file, and include verbatimly" (interpret-markup @@ -819,26 +819,26 @@ any sort of property supported by @internalsref{font-interface} and ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-markup-command (bigger layout props arg) (markup?) +(define-builtin-markup-command (bigger layout props arg) (markup?) "Increase the font size relative to current setting" (interpret-markup layout props `(,fontsize-markup 1 ,arg))) -(define-markup-command (smaller layout props arg) (markup?) +(define-builtin-markup-command (smaller layout props arg) (markup?) "Decrease the font size relative to current setting" (interpret-markup layout props `(,fontsize-markup -1 ,arg))) -(define-markup-command larger (markup?) bigger-markup) +(define-builtin-markup-command larger (markup?) bigger-markup) -(define-markup-command (finger layout props arg) (markup?) +(define-builtin-markup-command (finger layout props arg) (markup?) "Set the argument as small numbers." (interpret-markup layout (cons '((font-size . -5) (font-encoding . fetaNumber)) props) arg)) -(define-markup-command (fontsize layout props increment arg) (number? markup?) +(define-builtin-markup-command (fontsize layout props increment arg) (number? markup?) "Add @var{increment} to the font-size. Adjust baseline skip accordingly." (let* ((fs (chain-assoc-get 'font-size props 0)) @@ -852,7 +852,7 @@ any sort of property supported by @internalsref{font-interface} and ;; FIXME -> should convert to font-size. -(define-markup-command (magnify layout props sz arg) (number? markup?) +(define-builtin-markup-command (magnify layout props sz arg) (number? markup?) "Set the font magnification for the its argument. In the following example, the middle A will be 10% larger: @example @@ -866,54 +866,54 @@ Use @code{\\fontsize} otherwise." (prepend-alist-chain 'font-magnification sz props) arg)) -(define-markup-command (bold layout props arg) (markup?) +(define-builtin-markup-command (bold layout props arg) (markup?) "Switch to bold font-series" (interpret-markup layout (prepend-alist-chain 'font-series 'bold props) arg)) -(define-markup-command (sans layout props arg) (markup?) +(define-builtin-markup-command (sans layout props arg) (markup?) "Switch to the sans serif family" (interpret-markup layout (prepend-alist-chain 'font-family 'sans props) arg)) -(define-markup-command (number layout props arg) (markup?) +(define-builtin-markup-command (number layout props arg) (markup?) "Set font family to @code{number}, which yields the font used for time signatures and fingerings. This font only contains numbers and some punctuation. It doesn't have any letters. " (interpret-markup layout (prepend-alist-chain 'font-encoding 'fetaNumber props) arg)) -(define-markup-command (roman layout props arg) (markup?) +(define-builtin-markup-command (roman layout props arg) (markup?) "Set font family to @code{roman}." (interpret-markup layout (prepend-alist-chain 'font-family 'roman props) arg)) -(define-markup-command (huge layout props arg) (markup?) +(define-builtin-markup-command (huge layout props arg) (markup?) "Set font size to +2." (interpret-markup layout (prepend-alist-chain 'font-size 2 props) arg)) -(define-markup-command (large layout props arg) (markup?) +(define-builtin-markup-command (large layout props arg) (markup?) "Set font size to +1." (interpret-markup layout (prepend-alist-chain 'font-size 1 props) arg)) -(define-markup-command (normalsize layout props arg) (markup?) +(define-builtin-markup-command (normalsize layout props arg) (markup?) "Set font size to default." (interpret-markup layout (prepend-alist-chain 'font-size 0 props) arg)) -(define-markup-command (small layout props arg) (markup?) +(define-builtin-markup-command (small layout props arg) (markup?) "Set font size to -1." (interpret-markup layout (prepend-alist-chain 'font-size -1 props) arg)) -(define-markup-command (tiny layout props arg) (markup?) +(define-builtin-markup-command (tiny layout props arg) (markup?) "Set font size to -2." (interpret-markup layout (prepend-alist-chain 'font-size -2 props) arg)) -(define-markup-command (teeny layout props arg) (markup?) +(define-builtin-markup-command (teeny layout props arg) (markup?) "Set font size to -3." (interpret-markup layout (prepend-alist-chain 'font-size -3 props) arg)) -(define-markup-command (fontCaps layout props arg) (markup?) +(define-builtin-markup-command (fontCaps layout props arg) (markup?) "Set @code{font-shape} to @code{caps}." (interpret-markup layout (prepend-alist-chain 'font-shape 'caps props) arg)) ;; Poor man's caps -(define-markup-command (smallCaps layout props text) (markup?) +(define-builtin-markup-command (smallCaps layout props text) (markup?) "Turn @code{text}, which should be a string, to small caps. @example \\markup \\smallCaps \"Text between double quotes\" @@ -978,10 +978,10 @@ some punctuation. It doesn't have any letters. " #f #f))) -(define-markup-command (caps layout props arg) (markup?) +(define-builtin-markup-command (caps layout props arg) (markup?) (interpret-markup layout props (make-smallCaps-markup arg))) -(define-markup-command (dynamic layout props arg) (markup?) +(define-builtin-markup-command (dynamic layout props arg) (markup?) "Use the dynamic font. This font only contains @b{s}, @b{f}, @b{m}, @b{z}, @b{p}, and @b{r}. When producing phrases, like ``pi@`{u} @b{f}'', the normal words (like ``pi@`{u}'') should be done in a different font. The @@ -989,7 +989,7 @@ recommend font for this is bold and italic" (interpret-markup layout (prepend-alist-chain 'font-encoding 'fetaDynamic props) arg)) -(define-markup-command (text layout props arg) (markup?) +(define-builtin-markup-command (text layout props arg) (markup?) "Use a text font instead of music symbol or music alphabet font." ;; ugh - latin1 @@ -997,26 +997,26 @@ recommend font for this is bold and italic" arg)) -(define-markup-command (italic layout props arg) (markup?) +(define-builtin-markup-command (italic layout props arg) (markup?) "Use italic @code{font-shape} for @var{arg}. " (interpret-markup layout (prepend-alist-chain 'font-shape 'italic props) arg)) -(define-markup-command (typewriter layout props arg) (markup?) +(define-builtin-markup-command (typewriter layout props arg) (markup?) "Use @code{font-family} typewriter for @var{arg}." (interpret-markup layout (prepend-alist-chain 'font-family 'typewriter props) arg)) -(define-markup-command (upright layout props arg) (markup?) +(define-builtin-markup-command (upright layout props arg) (markup?) "Set font shape to @code{upright}. This is the opposite of @code{italic}." (interpret-markup layout (prepend-alist-chain 'font-shape 'upright props) arg)) -(define-markup-command (medium layout props arg) (markup?) +(define-builtin-markup-command (medium layout props arg) (markup?) "Switch to medium font-series (in contrast to bold)." (interpret-markup layout (prepend-alist-chain 'font-series 'medium props) arg)) -(define-markup-command (normal-text layout props arg) (markup?) +(define-builtin-markup-command (normal-text layout props arg) (markup?) "Set all font related properties (except the size) to get the default normal text font, no matter what font was used earlier." ;; ugh - latin1 (interpret-markup layout @@ -1029,45 +1029,45 @@ recommend font for this is bold and italic" ;; symbols. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-markup-command (doublesharp layout props) () +(define-builtin-markup-command (doublesharp layout props) () "Draw a double sharp symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get 1 standard-alteration-glyph-name-alist "")))) -(define-markup-command (sesquisharp layout props) () +(define-builtin-markup-command (sesquisharp layout props) () "Draw a 3/2 sharp symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get 3/4 standard-alteration-glyph-name-alist "")))) -(define-markup-command (sharp layout props) () +(define-builtin-markup-command (sharp layout props) () "Draw a sharp symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get 1/2 standard-alteration-glyph-name-alist "")))) -(define-markup-command (semisharp layout props) () +(define-builtin-markup-command (semisharp layout props) () "Draw a semi sharp symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get 1/4 standard-alteration-glyph-name-alist "")))) -(define-markup-command (natural layout props) () +(define-builtin-markup-command (natural layout props) () "Draw a natural symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get 0 standard-alteration-glyph-name-alist "")))) -(define-markup-command (semiflat layout props) () +(define-builtin-markup-command (semiflat layout props) () "Draw a semiflat." (interpret-markup layout props (markup #:musicglyph (assoc-get -1/4 standard-alteration-glyph-name-alist "")))) -(define-markup-command (flat layout props) () +(define-builtin-markup-command (flat layout props) () "Draw a flat symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get -1/2 standard-alteration-glyph-name-alist "")))) -(define-markup-command (sesquiflat layout props) () +(define-builtin-markup-command (sesquiflat layout props) () "Draw a 3/2 flat symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get -3/4 standard-alteration-glyph-name-alist "")))) -(define-markup-command (doubleflat layout props) () +(define-builtin-markup-command (doubleflat layout props) () "Draw a double flat symbol." (interpret-markup layout props (markup #:musicglyph (assoc-get -1 standard-alteration-glyph-name-alist "")))) -(define-markup-command (with-color layout props color arg) (color? markup?) +(define-builtin-markup-command (with-color layout props color arg) (color? markup?) "Draw @var{arg} in color specified by @var{color}" (let* ((stil (interpret-markup layout props arg))) @@ -1082,7 +1082,7 @@ recommend font for this is bold and italic" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-markup-command (arrow-head layout props axis direction filled) +(define-builtin-markup-command (arrow-head layout props axis direction filled) (integer? ly:dir? boolean?) "produce an arrow head in specified direction and axis. Use the filled head if @var{filled} is specified." (let* @@ -1097,7 +1097,7 @@ recommend font for this is bold and italic" props)) name))) -(define-markup-command (musicglyph layout props glyph-name) (string?) +(define-builtin-markup-command (musicglyph layout props glyph-name) (string?) "This is converted to a musical symbol, e.g. @code{\\musicglyph #\"accidentals.natural\"} will select the natural sign from the music font. See @usermanref{The Feta font} for a complete listing of the possible glyphs." @@ -1106,12 +1106,12 @@ See @usermanref{The Feta font} for a complete listing of the possible glyphs." props)) glyph-name)) -(define-markup-command (lookup layout props glyph-name) (string?) +(define-builtin-markup-command (lookup layout props glyph-name) (string?) "Lookup a glyph by name." (ly:font-get-glyph (ly:paper-get-font layout props) glyph-name)) -(define-markup-command (char layout props num) (integer?) +(define-builtin-markup-command (char layout props num) (integer?) "Produce a single character, e.g. @code{\\char #65} produces the letter 'A'." @@ -1139,13 +1139,13 @@ letter 'A'." (number->markletter-string vec (remainder n lst))) (make-string 1 (vector-ref vec n))))) -(define-markup-command (markletter layout props num) (integer?) +(define-builtin-markup-command (markletter layout props num) (integer?) "Make a markup letter for @var{num}. The letters start with A to Z (skipping I), and continues with double letters." (ly:text-interface::interpret-markup layout props (number->markletter-string number->mark-letter-vector num))) -(define-markup-command (markalphabet layout props num) (integer?) +(define-builtin-markup-command (markalphabet layout props num) (integer?) "Make a markup letter for @var{num}. The letters start with A to Z and continues with double letters." (ly:text-interface::interpret-markup layout props @@ -1153,7 +1153,7 @@ letter 'A'." -(define-markup-command (slashed-digit layout props num) (integer?) +(define-builtin-markup-command (slashed-digit layout props num) (integer?) "A feta number, with slash. This is for use in the context of figured bass notation" (let* @@ -1212,7 +1212,7 @@ figured bass notation" ;; TODO: better syntax. -(define-markup-command (note-by-number layout props log dot-count dir) (number? number? number?) +(define-builtin-markup-command (note-by-number layout props log dot-count dir) (number? number? number?) "Construct a note symbol, with stem. By using fractional values for @var{dir}, you can obtain longer or shorter stems." @@ -1309,7 +1309,7 @@ figured bass notation" (if dots (string-length dots) 0))) (ly:error (_ "not a valid duration string: ~a") duration-string)))) -(define-markup-command (note layout props duration dir) (string? number?) +(define-builtin-markup-command (note layout props duration dir) (string? number?) "This produces a note with a stem pointing in @var{dir} direction, with the @var{duration} for the note head type and augmentation dots. For example, @code{\\note #\"4.\" #-0.75} creates a dotted quarter note, with @@ -1322,7 +1322,7 @@ a shortened down stem." ;; translating. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-markup-command (lower layout props amount arg) (number? markup?) +(define-builtin-markup-command (lower layout props amount arg) (number? markup?) " Lower @var{arg}, by the distance @var{amount}. A negative @var{amount} indicates raising, see also @code{\\raise}. @@ -1331,7 +1331,7 @@ A negative @var{amount} indicates raising, see also @code{\\raise}. (- amount) Y)) -(define-markup-command (translate-scaled layout props offset arg) (number-pair? markup?) +(define-builtin-markup-command (translate-scaled layout props offset arg) (number-pair? markup?) "Translate @var{arg} by @var{offset}, scaling the offset by the @code{font-size}." (let* @@ -1342,7 +1342,7 @@ A negative @var{amount} indicates raising, see also @code{\\raise}. (ly:stencil-translate (interpret-markup layout props arg) scaled))) -(define-markup-command (raise layout props amount arg) (number? markup?) +(define-builtin-markup-command (raise layout props amount arg) (number? markup?) " Raise @var{arg}, by the distance @var{amount}. A negative @var{amount} indicates lowering, see also @code{\\lower}. @@ -1361,7 +1361,7 @@ positions it next to the staff cancels any shift made with and/or @code{extra-offset} properties. " (ly:stencil-translate-axis (interpret-markup layout props arg) amount Y)) -(define-markup-command (fraction layout props arg1 arg2) (markup? markup?) +(define-builtin-markup-command (fraction layout props arg1 arg2) (markup? markup?) "Make a fraction of two markups." (let* ((m1 (interpret-markup layout props arg1)) (m2 (interpret-markup layout props arg2)) @@ -1389,13 +1389,13 @@ and/or @code{extra-offset} properties. " -(define-markup-command (normal-size-super layout props arg) (markup?) +(define-builtin-markup-command (normal-size-super layout props arg) (markup?) "Set @var{arg} in superscript with a normal font size." (ly:stencil-translate-axis (interpret-markup layout props arg) (* 0.5 (chain-assoc-get 'baseline-skip props)) Y)) -(define-markup-command (super layout props arg) (markup?) +(define-builtin-markup-command (super layout props arg) (markup?) " @cindex raising text @cindex lowering text @@ -1421,7 +1421,7 @@ Raising and lowering texts can be done with @code{\\super} and (* 0.5 (chain-assoc-get 'baseline-skip props)) Y)) -(define-markup-command (translate layout props offset arg) (number-pair? markup?) +(define-builtin-markup-command (translate layout props offset arg) (number-pair? markup?) "This translates an object. Its first argument is a cons of numbers @example A \\translate #(cons 2 -3) @{ B C @} D @@ -1435,7 +1435,7 @@ that. (ly:stencil-translate (interpret-markup layout props arg) offset)) -(define-markup-command (sub layout props arg) (markup?) +(define-builtin-markup-command (sub layout props arg) (markup?) "Set @var{arg} in subscript." (ly:stencil-translate-axis (interpret-markup @@ -1445,7 +1445,7 @@ that. (* -0.5 (chain-assoc-get 'baseline-skip props)) Y)) -(define-markup-command (normal-size-sub layout props arg) (markup?) +(define-builtin-markup-command (normal-size-sub layout props arg) (markup?) "Set @var{arg} in subscript, in a normal font size." (ly:stencil-translate-axis (interpret-markup layout props arg) @@ -1456,19 +1456,19 @@ that. ;; brackets. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define-markup-command (hbracket layout props arg) (markup?) +(define-builtin-markup-command (hbracket layout props arg) (markup?) "Draw horizontal brackets around @var{arg}." (let ((th 0.1) ;; todo: take from GROB. (m (interpret-markup layout props arg))) (bracketify-stencil m X th (* 2.5 th) th))) -(define-markup-command (bracket layout props arg) (markup?) +(define-builtin-markup-command (bracket layout props arg) (markup?) "Draw vertical brackets around @var{arg}." (let ((th 0.1) ;; todo: take from GROB. (m (interpret-markup layout props arg))) (bracketify-stencil m Y th (* 2.5 th) th))) -(define-markup-command (bracketed-y-column layout props indices args) +(define-builtin-markup-command (bracketed-y-column layout props indices args) (list? markup-list?) "Make a column of the markups in @var{args}, putting brackets around the elements marked in @var{indices}, which is a list of numbers. diff --git a/scm/document-markup.scm b/scm/document-markup.scm index 9a5e51eb19..27d1229dde 100644 --- a/scm/document-markup.scm +++ b/scm/document-markup.scm @@ -10,10 +10,10 @@ (f-name (symbol->string (procedure-name func))) (c-name (regexp-substitute/global #f "-markup$" f-name 'pre "" 'post)) (sig (object-property func 'markup-signature)) - (arg-names - (map symbol->string - (cddr (cadr (procedure-source func))))) - + (arg-names (let ((arg-list (cadr (procedure-source func)))) + (if (list? arg-list) + (map symbol->string (cddr arg-list)) + (make-list (length sig) "arg")))) (sig-type-names (map type-name sig)) (signature-str (string-join diff --git a/scm/framework-eps.scm b/scm/framework-eps.scm index e2215ede41..cf9bec54b3 100644 --- a/scm/framework-eps.scm +++ b/scm/framework-eps.scm @@ -28,11 +28,14 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." (define left - (apply min - (map (lambda (stc) - (interval-start (ly:stencil-extent stc X))) - stencils))) + (if (pair? stencils) + (apply min + (map (lambda (stc) + (interval-start (ly:stencil-extent stc X))) + stencils)) + 0.0)) + (map (lambda (stil) (ly:make-stencil @@ -79,18 +82,22 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." (dump-stencils-as-separate-EPS rest (1+ count))))) ;; main body - (let* ((tex-system-name (format "~a-systems.tex" basename)) - (texi-system-name (format "~a-systems.texi" basename)) - (tex-system-port (open-output-file tex-system-name)) - (texi-system-port (open-output-file texi-system-name)) + (let* ((write-file (lambda (str-port ext) + (let* + ((name (format "~a-systems.~a" basename ext)) + (port (open-output-file name))) + (ly:message (_ "Writing ~a...") name) + (display (get-output-string str-port) port) + (close-output-port port) + ))) + + (tex-system-port (open-output-string)) + (texi-system-port (open-output-string)) (widened-stencils (widen-left-stencil-edges stencils)) (counted-systems (count-list widened-stencils)) (eps-files (map dump-counted-stencil counted-systems)) ) - (ly:message (_ "Writing ~a...") tex-system-name) - (ly:message (_ "Writing ~a...") texi-system-name) - (if do-pdf ;; par-for-each: a bit faster ... @@ -113,15 +120,16 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." basename (1+ c)) texi-system-port)) (iota (length stencils))) - (display "@c eof - 'eof' is a Makefile marker; do not remove. " texi-system-port) - (display "% eof - 'eof' is Makefile marker; do not remove. " tex-system-port) - - (close-output-port texi-system-port) - (close-output-port tex-system-port) + (display "@c eof." texi-system-port) + (display "% eof. " tex-system-port) (dump-infinite-stack-EPS stencils) (postprocess-output book framework-eps-module - (format "~a.eps" basename) (ly:output-formats)))) + (format "~a.eps" basename) (ly:output-formats)) + + (write-file texi-system-port "texi") + (write-file tex-system-port "tex") + )) diff --git a/scm/fret-diagrams.scm b/scm/fret-diagrams.scm index 2792ef7956..a682a824be 100644 --- a/scm/fret-diagrams.scm +++ b/scm/fret-diagrams.scm @@ -295,7 +295,7 @@ Line thickness is given by @var{th}, fret & string spacing by (sans-serif-stencil layout props (* size label-font-mag) label-text) (* size (+ fret-count label-vertical-offset)) Y))) -(define-markup-command (fret-diagram-verbose layout props marking-list) +(define-builtin-markup-command (fret-diagram-verbose layout props marking-list) (list?) "Make a fret diagram containing the symbols indicated in @var{marking-list} @@ -391,7 +391,7 @@ indications per string. (ly:stencil-aligned-to fret-diagram-stencil X alignment) )) -(define-markup-command (fret-diagram layout props definition-string) +(define-builtin-markup-command (fret-diagram layout props definition-string) (string?) " Example @@ -522,7 +522,7 @@ Note: There is no limit to the number of fret indications per string. (cons* numeric-value (numerify (cdr mylist))) (cons* (car (string->list (car mylist))) (numerify (cdr mylist))))))) -(define-markup-command (fret-diagram-terse layout props definition-string) +(define-builtin-markup-command (fret-diagram-terse layout props definition-string) (string?) "Make a fret diagram markup using terse string-based syntax. diff --git a/scm/layout-beam.scm b/scm/layout-beam.scm index d946890049..1ee840aa0b 100644 --- a/scm/layout-beam.scm +++ b/scm/layout-beam.scm @@ -59,7 +59,7 @@ ly:beam::quanting (check-beam-quant l r) )) - + (define-public (check-slope-callbacks comparison) (list ly:beam::calc-least-squares-positions diff --git a/scm/layout-page-dump.scm b/scm/layout-page-dump.scm index 50815ac2ef..8237106f06 100644 --- a/scm/layout-page-dump.scm +++ b/scm/layout-page-dump.scm @@ -70,12 +70,11 @@ (format out-port "~a\n~a\n" skip base) (dump-tweaks out-port (cdr tweak-list) (graceless-moment now))))) -(define (dump-all-tweaks pages tweaks) - (let* ((paper (ly:paper-book-paper (page-property (car pages) 'paper-book))) - (parser (ly:output-def-parser paper)) - (name (format "~a-page-layout.ly" - (ly:parser-output-name parser))) +(define (dump-all-tweaks pages tweaks output-name) + (let* ((paper (ly:paper-book-paper (page-property (car pages) 'paper-book))) + (name (format "~a-page-layout.ly" output-name)) (out-port (open-output-file name))) + (ly:message "Writing page layout to ~a" name) (hash-for-each (lambda (key val) @@ -85,7 +84,7 @@ tweaks) (close-port out-port))) -(define (write-page-breaks pages) +(define (write-page-breaks pages output-name) "Dump page breaks and tweaks" (let ((tweaks (make-hash-table 60))) (define (handle-page page) @@ -145,4 +144,4 @@ (record-line-tweak (cdr lines) #f (1+ index))))))) ;; Compute tweaks for each page, then dump them to the page-layout file (for-each handle-page pages) - (dump-all-tweaks pages tweaks))) + (dump-all-tweaks pages tweaks output-name))) diff --git a/scm/layout-page-layout.scm b/scm/layout-page-layout.scm index f7853b01bb..9e8971ac7e 100644 --- a/scm/layout-page-layout.scm +++ b/scm/layout-page-layout.scm @@ -35,8 +35,14 @@ (define (post-process-pages layout pages) "If the write-page-layout paper variable is true, dumps page breaks and tweaks." - (if (ly:output-def-lookup layout 'write-page-layout #f) - (write-page-breaks pages))) + + (let* + ((parser (ly:modules-lookup (list (current-module)) 'parser)) + (output-name (ly:parser-output-name parser)) + ) + + (if (ly:output-def-lookup layout 'write-page-layout #f) + (write-page-breaks pages output-name)))) ;;; ;;; Utilities for computing line distances and positions diff --git a/scm/lily-library.scm b/scm/lily-library.scm index 1e8fe97e47..e3a59a6439 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -49,46 +49,28 @@ (define-public (moment-min a b) (if (ly:moment output hooks. -;; parser stuff. -(define-public (print-music-as-book parser music) - (let* ((head (ly:parser-lookup parser '$defaultheader)) - (book (ly:make-book (ly:parser-lookup parser '$defaultpaper) - head (scorify-music music parser)))) - (print-book-with-defaults parser book))) - -(define-public (print-score-as-book parser score) - (let* ((head (ly:parser-lookup parser '$defaultheader)) - (book (ly:make-book (ly:parser-lookup parser '$defaultpaper) - head score))) - (print-book-with-defaults parser book))) - -(define-public (print-score parser score) - (let* ((head (ly:parser-lookup parser '$defaultheader)) - (book (ly:make-book (ly:parser-lookup parser '$defaultpaper) - head score))) - (ly:parser-print-score parser book))) (define-public (collect-scores-for-book parser score) (ly:parser-define! parser 'toplevel-scores (cons score (ly:parser-lookup parser 'toplevel-scores)))) +(define-public (collect-music-for-book parser music) + ;; discard music if its 'void property is true. + (let ((void-music (ly:music-property music 'void))) + (if (or (null? void-music) (not void-music)) + (collect-scores-for-book parser (scorify-music music parser))))) + (define-public (scorify-music music parser) + "Preprocess MUSIC." (for-each (lambda (func) (set! music (func music parser))) @@ -96,36 +78,15 @@ (ly:make-score music)) -(define-public (collect-music-for-book parser music) - ;; discard music if its 'void property is true. - (let ((void-music (ly:music-property music 'void))) - (if (or (null? void-music) (not void-music)) - (collect-scores-for-book parser (scorify-music music parser))))) - - -(define-public (print-book-with-defaults parser book) +(define (print-book-with parser book process-procedure) (let* ((paper (ly:parser-lookup parser '$defaultpaper)) (layout (ly:parser-lookup parser '$defaultlayout)) - (count (ly:parser-lookup parser 'output-count)) - (base (ly:parser-output-name parser))) - - (if (not (integer? count)) - (set! count 0)) - - (if (> count 0) - (set! base (format #f "~a-~a" base count))) - - (ly:parser-define! parser 'output-count (1+ count)) - (ly:book-process book paper layout base) - )) -(define-public (print-score-with-defaults parser score) - (let* - ((paper (ly:parser-lookup parser '$defaultpaper)) (count (ly:parser-lookup parser 'output-count)) (base (ly:parser-output-name parser))) + ;; must be careful: output-count is under user control. (if (not (integer? count)) (set! count 0)) @@ -133,36 +94,14 @@ (set! base (format #f "~a-~a" base count))) (ly:parser-define! parser 'output-count (1+ count)) + (process-procedure book paper layout base) + )) - (if (not (ly:score-error? score)) - (let* - ((header (ly:score-header score)) - (output-defs (ly:score-output-defs score)) - (layout-defs (filter (lambda (d) (eq? #t (ly:output-def-lookup d 'is-layout))) - output-defs)) - (midi-defs (filter (lambda (d) (eq? #t (ly:output-def-lookup d 'is-midi))) - output-defs)) - (music (ly:score-music score)) - (layout-def (if (null? layout-defs) - (ly:parser-lookup parser '$defaultlayout) - (car layout-defs)))) - - (if (not (module? header)) - (set! header (ly:parser-lookup parser '$defaultheader))) - - (ly:render-music-as-systems - music layout-def paper header base) - - (if (pair? midi-defs) - (ly:performance-write (ly:format-output (ly:run-translator music (car midi-defs))) - (format #f "~a.midi" base) - )) - - )))) - - - +(define-public (print-book-with-defaults parser book) + (print-book-with parser book ly:book-process)) +(define-public (print-book-with-defaults-as-systems parser book) + (print-book-with parser book ly:book-process-to-systems)) ;;;;;;;;;;;;;;;; ;; alist @@ -647,14 +586,16 @@ possibly turned off." (define-public (version-not-seen-message input-file-name) (ly:message - (string-append - input-file-name ": 0: " (_ "warning: ") - (format #f - (_ "no \\version statement found, please add~afor future compatibility") - (format #f "\n\n\\version ~s\n\n" (lilypond-version)))))) + "~a:0: ~a: ~a" + input-file-name + (_ "warning: ") + (format #f + (_ "no \\version statement found, please add~afor future compatibility") + (format #f "\n\n\\version ~s\n\n" (lilypond-version))))) (define-public (old-relative-not-used-message input-file-name) (ly:message - (string-append - input-file-name ": 0: " (_ "warning: ") - (_ "old relative compatibility not used")))) + "~a:0: ~a: ~a" + input-file-name + (_ "warning: ") + (_ "old relative compatibility not used"))) diff --git a/scm/lily.scm b/scm/lily.scm index 401017181c..5daa01c53d 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -39,10 +39,9 @@ ensure that all refs to parsed objects are dead. This is an internal option, an "delete unusable PostScript files") (dump-profile #f "dump timing information for each file") (dump-tweaks #f "dump page layout and tweaks for each score having the tweak-key layout property set.") - (dump-signatures #f "dump output signatures of each system") + (dump-signatures #f "dump output signatures of each system. Used for regression testing.") - (eps-box-padding #f "Pad EPS bounding box left edge by this much to guarantee alignment between systems") - + (eps-box-padding #f "Pad EPS bounding box left edge. Guarantee alignment between systems in LaTeX.") (gs-load-fonts #f "load fonts via Ghostscript.") (gui #f "running from gui; redirect stderr to log file") @@ -69,14 +68,12 @@ on errors, and print a stack trace.") (read-file-list #f "Read files to be processed from command line arguments") (safe #f "Run safely") - (strict-infinity-checking #f "If yes, crash on encountering Inf/NaN") - + (strict-infinity-checking #f "If yes, crash on encountering Inf/NaN.") + (separate-log-files #f "Output to FILE.log per file.") (ttf-verbosity 0 "how much verbosity for TTF font embedding?") - (show-available-fonts #f - "List font names available.") - + "List font names available.") (verbose ,(ly:command-line-verbose?) "value for the --verbose flag") ))) @@ -101,12 +98,11 @@ on errors, and print a stack trace.") (srfi srfi-13) (srfi srfi-14) (scm clip-region) - ) - ;; my display -(define-public (myd k v) (display k) (display ": ") (display v) (display ", ")) +(define-public (myd k v) (display k) (display ": ") (display v) (display ", ") + v) (define-public (print . args) (apply format (cons (current-output-port) args))) @@ -365,24 +361,26 @@ The syntax is the same as `define*-public'." (define (profile-measurements) (let* ((t (times)) (stats (gc-stats))) - + (list - (- (tms:utime t) + (- (+ (tms:cutime t) + (tms:utime t)) (ly:assoc-get 'gc-time-taken stats)) - - ;; difficult to put memory amount stats into here. + (ly:assoc-get 'total-cells-allocated stats 0) ))) -(define (dump-profile name last this) +(define (dump-profile base last this) (let* - ((outname (format "~a.profile" (basename name ".ly"))) + ((outname (format "~a.profile" (basename base ".ly"))) (diff (map (lambda (y) (apply - y)) (zip this last)))) (ly:progress "\nWriting timing to ~a..." outname) (format (open-file outname "w") - "time: ~a" - (car diff)))) + "time: ~a\ncells: ~a\n" + (car diff) + (cadr diff) + ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -508,7 +506,7 @@ The syntax is the same as `define*-public'." )) (if (and (number? (ly:get-option 'job-count)) - (> (length files) (ly:get-option 'job-count))) + (>= (length files) (ly:get-option 'job-count))) (let* ((count (ly:get-option 'job-count)) @@ -530,25 +528,36 @@ The syntax is the same as `define*-public'." (for-each (lambda (pid) (let* ((stat (cdr (waitpid pid)))) - + (if (not (= stat 0)) - (set! errors (cons (list-element-index joblist pid) errors))))) + (set! errors (acons (list-element-index joblist pid) stat errors))))) joblist) (for-each (lambda (x) - (let* ((logfile (format "~a-~a.log" - (ly:get-option 'log-file) x)) + (let* ((job (car x)) + (state (cdr x)) + (logfile (format "~a-~a.log" + (ly:get-option 'log-file) job)) (log (ly:gulp-file logfile)) (len (string-length log)) (tail (substring log (max 0 (- len 1024))))) - (display (format "\n\nlogfile ~a:\n\n ~a" logfile tail)))) + (if (status:term-sig state) + (ly:message "\n\n~a\n" + (format (_ "job ~a terminated with signal: ~a") + job + (status:term-sig state))) + (ly:message (_ "logfile ~a (exit ~a):\n~a") logfile (status:exit-val state) tail)))) errors) (if (pair? errors) - (ly:error "Children ~a exited with errors." errors)) + (ly:error "Children ~a exited with errors." (map car errors))) + + ;; must overwrite individual entries + (if (ly:get-option 'dump-profile) + (dump-profile "lily-run-total" '(0 0) (profile-measurements))) (exit (if (null? errors) 0 1)))))) @@ -576,27 +585,56 @@ The syntax is the same as `define*-public'." )) (let* ((failed '()) - (start-measurements #f) + (separate-logs (ly:get-option 'separate-log-files)) + (do-measurements (ly:get-option 'dump-profile)) (handler (lambda (key failed-file) (set! failed (append (list failed-file) failed))))) + (gc) (for-each (lambda (x) - - (gc) - (set! start-measurements (profile-measurements)) - (lilypond-file handler x) - (if (ly:get-option 'dump-profile) - (dump-profile x start-measurements (profile-measurements))) + (let* + ((start-measurements (if do-measurements + (profile-measurements) + #f)) + (base (basename x ".ly")) + (all-settings (ly:all-options))) + + (if separate-logs + (ly:stderr-redirect (format "~a.log" base) "w")) + (lilypond-file handler x) + (if start-measurements + (dump-profile x start-measurements (profile-measurements))) - (ly:clear-anonymous-modules) - (if (ly:get-option 'debug-gc) - (dump-gc-protects) - (if (= (random 40) 1) - (ly:reset-all-fonts)))) + (for-each + (lambda (s) + (ly:set-option (car s) (cdr s))) + all-settings) + + (ly:clear-anonymous-modules) + (ly:set-option 'debug-gc-assert-parsed-dead #t) + (gc) + (ly:set-option 'debug-gc-assert-parsed-dead #f) + + + (if (ly:get-option 'debug-gc) + (dump-gc-protects) + (if (= (random 40) 1) + (ly:reset-all-fonts))))) files) + + ;; we want the failed-files notice in the aggregrate logfile. + (if (ly:get-option 'separate-logs) + (ly:stderr-redirect + (if (string-or-symbol? (ly:get-option 'log-file)) + (format "~a.log" (ly:get-option 'log-file)) + "/dev/tty") "a")) + + (if (ly:get-option 'dump-profile) + (dump-profile "lily-run-total" '(0 0) (profile-measurements))) + failed)) (define (lilypond-file handler file-name) diff --git a/scm/markup.scm b/scm/markup.scm index bd20798e91..c786c16890 100644 --- a/scm/markup.scm +++ b/scm/markup.scm @@ -20,7 +20,9 @@ The function should return a stencil (i.e. a formatted, ready to print object). -To add a function, use the define-markup-command utility. +To add a builtin markup command, use the define-builtin-markup-command +utility. In a user file, the define-markup-command macro shall be used +(see ly/markup-init.ly). (define-markup-command (mycommand layout prop arg1 ...) (arg1-type? ...) \"my command usage and description\" @@ -28,7 +30,6 @@ To add a function, use the define-markup-command utility. The command is now available in markup mode, e.g. - \\markup { .... \\MYCOMMAND #1 argument ... } " ; " @@ -36,34 +37,8 @@ The command is now available in markup mode, e.g. ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; markup definer utilities -(defmacro-public in-module-define-variable (module-name symbol value) - "Define a variable in a module and export its name. - (in-module-define-variable (some module) symbol value)" - (let ((gmodule (gensym "module"))) - `(let ((,gmodule (resolve-module ',module-name))) - (module-define! ,gmodule ',symbol ,value) - (module-export! ,gmodule '(,symbol))))) - -(defmacro-public in-module-define-function - (module-name function-name+arg-list . body) - "Define a public function in a module: - (in-module-define-function (some module) (function-name . args) - ..body..)" - `(in-module-define-variable - ,module-name - ,(car function-name+arg-list) - (let ((proc (lambda ,(cdr function-name+arg-list) - ,@body))) - (set-procedure-property! proc - 'name - ',(car function-name+arg-list)) - proc))) - -;;; `define-markup-command' can be used both for built-in markup -;;; definitions and user defined markups. -(defmacro-public define-markup-command (command-and-args signature . body) +(define-macro (define-builtin-markup-command command-and-args signature . body) " - * Define a COMMAND-markup function after command-and-args and body, register COMMAND-markup and its signature, @@ -74,40 +49,36 @@ register COMMAND-markup and its signature, * define a make-COMMAND-markup function. Syntax: - (define-markup-command (COMMAND layout props arg1 arg2 ...) (arg1-type? arg2-type? ...) + (define-builtin-markup-command (COMMAND layout props arg1 arg2 ...) + (arg1-type? arg2-type? ...) \"documentation string\" ...command body...) -or: - (define-markup-command COMMAND (arg1-type? arg2-type? ...) function) + or: + (define-builtin-markup-command COMMAND (arg1-type? arg2-type? ...) + function) " - (let* ((command (if (pair? command-and-args) - (car command-and-args) - command-and-args)) + (let* ((command (if (pair? command-and-args) (car command-and-args) command-and-args)) + (args (if (pair? command-and-args) (cdr command-and-args) '())) (command-name (string->symbol (format #f "~a-markup" command))) (make-markup-name (string->symbol (format #f "make-~a-markup" command)))) - `(let ((lily-module (resolve-module '(lily)))) - ;; define the COMMAND-markup procedure in (lily) module - ,(if (pair? command-and-args) - ;; two cases: - ;; 1/ (define (COMMAND-markup layout props arg1 arg2 ...) - ;; ..command body)) - `(in-module-define-function (lily) (,command-name ,@(cdr command-and-args)) + `(begin + ;; define the COMMAND-markup function + ,(if (pair? args) + `(define-public (,command-name ,@args) ,@body) - ;; 2/ (define COMMAND-markup function) - `(in-module-define-variable (lily) ,command-name ,(car body))) - (let ((command-proc (module-ref lily-module ',command-name))) - ;; register its command signature - (set! (markup-command-signature command-proc) - (list ,@signature)) - ;; add the COMMAND-markup procedure to the list of markup functions - (if (not (member command-proc markup-function-list)) - (set! markup-function-list (cons command-proc markup-function-list))) - ;; define the make-COMMAND-markup procedure in (lily) module - (in-module-define-function (lily) (,make-markup-name . args) - (make-markup command-proc - ,(symbol->string make-markup-name) - (list ,@signature) - args)))))) + (let ((args (gensym "args")) + (markup-command (car body))) + `(define-public (,command-name . ,args) + ,(format #f "Copy of the ~a command" markup-command) + (apply ,markup-command ,args)))) + (set! (markup-command-signature ,command-name) (list ,@signature)) + ;; add the command to markup-function-list, for markup documentation + (if (not (member ,command-name markup-function-list)) + (set! markup-function-list (cons ,command-name markup-function-list))) + ;; define the make-COMMAND-markup function + (define-public (,make-markup-name . args) + (let ((sig (list ,@signature))) + (make-markup ,command-name ,(symbol->string make-markup-name) sig args)))))) (define-public (make-markup markup-function make-name signature args) " Construct a markup object from MARKUP-FUNCTION and ARGS. Typecheck @@ -141,22 +112,21 @@ against SIGNATURE, reporting MAKE-NAME as the user-invoked function. "The `markup' macro provides a lilypond-like syntax for building markups. - #:COMMAND is used instead of \\COMMAND - - #:lines ( ... ) is used instead of { ... } - - #:center-align ( ... ) is used instead of \\center-align < ... > + - #:line ( ... ) is used instead of \\line { ... } - etc. Example: \\markup { foo \\raise #0.2 \\hbracket \\bold bar \\override #'(baseline-skip . 4) - \\bracket \\column < baz bazr bla > + \\bracket \\column { baz bazr bla } } <==> (markup \"foo\" #:raise 0.2 #:hbracket #:bold \"bar\" #:override '(baseline-skip . 4) #:bracket #:column (\"baz\" \"bazr\" \"bla\")) -Use `markup*' in a \\notes block." +Use `markup*' in a \\notemode context." (car (compile-all-markup-expressions `(#:line ,body)))) @@ -269,44 +239,28 @@ Use `markup*' in a \\notes block." ;;; (markup-command-keyword raise-markup) ==> "scheme0-markup1" ;;; -(define markup-command-signatures (make-hash-table 50)) +(define-public (markup-command-keyword markup-command) + "Return markup-command's argument keyword, ie a string describing the command + arguments, eg. \"scheme0markup1\"" + (object-property markup-command 'markup-keyword)) -(define (markup-command-signature-ref markup-command) - "Return markup-command's signature, e.g. (number? markup?). -markup-command may be a procedure." - (let ((sig-key (hashq-ref markup-command-signatures - markup-command))) - (if sig-key (car sig-key) #f))) +(define-public (markup-command-signature-ref markup-command) + "Return markup-command's signature (the 'markup-signature object property)" + (object-property markup-command 'markup-signature)) -(define-public (markup-command-keyword markup-command) - "Return markup-command's keyword, e.g. \"scheme0markup1\". -markup-command may be a procedure." - (let ((sig-key (hashq-ref markup-command-signatures - markup-command))) - (if sig-key (cdr sig-key) #f))) - -(define (markup-command-signatureset! markup-command signature) - "Set markup-command's signature. markup-command must be a named procedure. -Also set markup-signature and markup-keyword object properties." - (hashq-set! markup-command-signatures - markup-command - (cons signature (markup-signature-to-keyword signature))) - ;; these object properties are still in use somewhere +(define-public (markup-command-signature-set! markup-command signature) + "Set markup-command's signature and keyword (as object properties)" (set-object-property! markup-command 'markup-signature signature) - (set-object-property! markup-command 'markup-keyword (markup-signature-to-keyword signature))) - -(define-public markup-command-signature - (make-procedure-with-setter markup-command-signature-ref markup-command-signatureset!)) + (set-object-property! markup-command 'markup-keyword + (markup-signature-to-keyword signature)) + signature) -(define (markup-symbol-to-proc markup-sym) - "Return the markup command procedure which name is `markup-sym', if any." - (hash-fold (lambda (key val prev) - (or prev - (if (eqv? (procedure-name key) markup-sym) key #f))) - #f - markup-command-signatures)) +(define-public markup-command-signature + (make-procedure-with-setter markup-command-signature-ref + markup-command-signature-set!)) -(define-public markup-function-list '()) +;; For documentation purposes +(define-public markup-function-list (list)) (define-public (markup-signature-to-keyword sig) " (A B C) -> a0-b1-c2 " @@ -329,8 +283,13 @@ Also set markup-signature and markup-keyword object properties." "-")))) (define-public (lookup-markup-command code) - (let ((proc (markup-symbol-to-proc (string->symbol (string-append code "-markup"))))) - (and proc (cons proc (markup-command-keyword proc))))) + (let ((proc (catch 'misc-error + (lambda () + (module-ref (current-module) + (string->symbol (format #f "~a-markup" code)))) + (lambda (key . args) #f)))) + (and (procedure? proc) + (cons proc (markup-command-keyword proc))))) ;;;;;;;;;;;;;;;;;;;;;; ;;; used in parser.yy to map a list of markup commands on markup arguments diff --git a/scm/music-functions.scm b/scm/music-functions.scm index 189f960ff6..54b363bdd9 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -228,10 +228,15 @@ Returns `obj'. (if (memq 'sequential-music (ly:music-property main 'types)) ;; \repeat "tremolo" { c4 d4 } (let ((children (length (ly:music-property main 'elements)))) - (if (not (= children 2)) + + ;; fixme: should be more generic. + (if (and (not (= children 2)) + (not (= children 1))) (ly:warning (_ "expecting 2 elements for chord tremolo, found ~a") children)) (ly:music-compress r (ly:make-moment 1 children)) - (shift-duration-log r (1- shift) dots)) + (shift-duration-log r + (if (= children 2) (1- shift) shift) + dots)) ;; \repeat "tremolo" c4 (shift-duration-log r shift dots))) r))) @@ -745,7 +750,7 @@ Syntax: (set! (ly:music-property music 'quoted-events) quoted-vector) (set! (ly:music-property music 'iterator-ctor) ly:quote-iterator::constructor)) - (ly:warning (_ "cannot find quoted music: `~S'" quoted-name)))) + (ly:warning (_ "cannot find quoted music: `~S'") quoted-name))) music)) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 19f3c61345..f66a78bcbc 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -135,6 +135,21 @@ (ly:duration-dot-count (ly:event-property (event-cause grob) 'duration))) +(define-public (dots::calc-staff-position grob) + (let* + ((head (ly:grob-parent grob Y)) + (log (ly:grob-property head 'duration-log))) + + (cond + ((or (not (grob::has-interface head 'rest-interface)) + (not (integer? log))) 0) + ((= log 7) 4) + ((> log 4) 3) + ((= log 0) -1) + ((= log 1) 1) + ((= log -1) 1) + (else 0)))) + (define (note-head::calc-tablature-stem-attachment grob) (cons 0.0 1.35)) diff --git a/scm/output-ps.scm b/scm/output-ps.scm index 9a65b0c5e5..42aecc1dbc 100644 --- a/scm/output-ps.scm +++ b/scm/output-ps.scm @@ -68,6 +68,8 @@ (if (or (nan? num) (inf? num)) (begin (ly:warning (_ "Found infinity or nan in output. Substituting 0.0")) + (if (ly:get-option 'strict-infinity-checking) + (exit 1)) "0.0") (format #f "~f" (round4 num)))) diff --git a/scm/safe-lily.scm b/scm/safe-lily.scm index ac89b1e279..65c5bfa6dd 100644 --- a/scm/safe-lily.scm +++ b/scm/safe-lily.scm @@ -102,7 +102,6 @@ ly:paper-get-number ly:paper-system? ly:output-def-lookup - ly:parse-string ly:parser-parse-string ly:pitch-alteration ly:pitch-diff diff --git a/scm/script.scm b/scm/script.scm index 6044f61a18..e12cdd07dd 100644 --- a/scm/script.scm +++ b/scm/script.scm @@ -4,230 +4,227 @@ ;;;; ;;;; (c) 2000--2006 Han-Wen Nienhuys -(set! default-script-alist - (append - '(("thumb" . - ((script-stencil . (feta . ("thumb" . "thumb"))) - (avoid-slur . inside) - (padding . 0.20) - (direction . 1))) - ("accent" . - ((avoid-slur . around) - (padding . 0.20) - (quantize-position . #t) - (script-stencil . (feta . ("sforzato" . "sforzato"))) - (side-relative-direction . -1))) - ("espressivo" . - ((avoid-slur . around) - (padding . 0.20) - (quantize-position . #t) - (script-stencil . (feta . ("espr" . "espr"))) - (side-relative-direction . -1))) - ("marcato" . - ((script-stencil . (feta . ("dmarcato" . "umarcato"))) - (padding . 0.20) - (avoid-slur . inside) -; (staff-padding . ()) - (quantize-position . #t) - (side-relative-direction . -1))) - ("staccatissimo" . - ((avoid-slur . inside) - (script-stencil . (feta . ("dstaccatissimo" . "ustaccatissimo"))) - (padding . 0.20) - (side-relative-direction . -1))) - - ("portato" . - ((script-stencil . (feta . ("uportato" . "dportato"))) - (avoid-slur . around) - (slur-padding . 0.3) - (padding . 0.45) - (side-relative-direction . -1))) +(define-public default-script-alist + '(("thumb" . + ((script-stencil . (feta . ("thumb" . "thumb"))) + (avoid-slur . inside) + (padding . 0.20) + (direction . 1))) + ("accent" . + ((avoid-slur . around) + (padding . 0.20) + (quantize-position . #t) + (script-stencil . (feta . ("sforzato" . "sforzato"))) + (side-relative-direction . -1))) + ("espressivo" . + ((avoid-slur . around) + (padding . 0.20) + (quantize-position . #t) + (script-stencil . (feta . ("espr" . "espr"))) + (side-relative-direction . -1))) + ("marcato" . + ((script-stencil . (feta . ("dmarcato" . "umarcato"))) + (padding . 0.20) + (avoid-slur . inside) + ; (staff-padding . ()) + (quantize-position . #t) + (side-relative-direction . -1))) + ("staccatissimo" . + ((avoid-slur . inside) + (script-stencil . (feta . ("dstaccatissimo" . "ustaccatissimo"))) + (padding . 0.20) + (side-relative-direction . -1))) + + ("portato" . + ((script-stencil . (feta . ("uportato" . "dportato"))) + (avoid-slur . around) + (slur-padding . 0.3) + (padding . 0.45) + (side-relative-direction . -1))) - ("accentus" . - ((script-stencil . (feta . ("uaccentus" . "uaccentus"))) - (side-relative-direction . -1) - (padding . 0.20) - (quantize-position . #t) - (script-priority . -100) - (direction . 1))) - ("ictus" . - ((script-stencil . (feta . ("ictus" . "ictus"))) - (side-relative-direction . -1) - (quantize-position . #t) - (padding . 0.20) - (script-priority . -100) - (direction . -1))) - ("semicirculus" . - ((script-stencil . (feta . ("dsemicirculus" . "dsemicirculus"))) - (side-relative-direction . -1) - (quantize-position . #t) - (padding . 0.20) - (script-priority . -100) - (direction . 1))) - ("circulus" . - ((script-stencil . (feta . ("circulus" . "circulus"))) - (side-relative-direction . -1) - (padding . 0.20) - (quantize-position . #t) - (script-priority . -100) - (direction . 1))) + ("accentus" . + ((script-stencil . (feta . ("uaccentus" . "uaccentus"))) + (side-relative-direction . -1) + (padding . 0.20) + (quantize-position . #t) + (script-priority . -100) + (direction . 1))) + ("ictus" . + ((script-stencil . (feta . ("ictus" . "ictus"))) + (side-relative-direction . -1) + (quantize-position . #t) + (padding . 0.20) + (script-priority . -100) + (direction . -1))) + ("semicirculus" . + ((script-stencil . (feta . ("dsemicirculus" . "dsemicirculus"))) + (side-relative-direction . -1) + (quantize-position . #t) + (padding . 0.20) + (script-priority . -100) + (direction . 1))) + ("circulus" . + ((script-stencil . (feta . ("circulus" . "circulus"))) + (side-relative-direction . -1) + (padding . 0.20) + (quantize-position . #t) + (script-priority . -100) + (direction . 1))) - ("signumcongruentiae" . - ((script-stencil . (feta . ("dsignumcongruentiae" . "usignumcongruentiae"))) - (padding . 0.20) - (direction . 1))) - ("fermata" . - ((script-stencil . (feta . ("dfermata" . "ufermata"))) - (padding . 0.20) - (avoid-slur . around) - (script-priority . 4000) - (direction . 1))) - ("shortfermata" . - ((script-stencil . (feta . ("dshortfermata" . "ushortfermata"))) - (padding . 0.20) - (direction . 1))) - ("longfermata" . - ((script-stencil . (feta . ("dlongfermata" . "ulongfermata"))) - (padding . 0.20) - (direction . 1))) - ("verylongfermata" . - ((script-stencil . (feta . ("dverylongfermata" . "uverylongfermata"))) - (padding . 0.20) - (direction . 1))) - ("stopped" . - ((script-stencil . (feta . ("stopped" . "stopped"))) - (avoid-slur . inside) - (padding . 0.20) - (direction . 1))) - ("staccato" . - ((script-stencil . (feta . ("staccato" . "staccato"))) - (side-relative-direction . -1) - (quantize-position . #t) - (avoid-slur . inside) - (padding . 0.20) - (script-priority . -100))) - ("tenuto" . - ((script-stencil . (feta . ("tenuto" . "tenuto"))) - (quantize-position . #t) - (avoid-slur . inside) - (padding . 0.20) - (side-relative-direction . -1))) - ("comma" . - ((script-stencil . (feta . ("lcomma" . "rcomma"))) - (quantize-position . #t) - (padding . 0.20) - (direction . 1))) - ("varcomma" . - ((script-stencil . (feta . ("lvarcomma" . "rvarcomma"))) - (quantize-position . #t) - (padding . 0.20) - (direction . 1))) - ("upbow" . - ((script-stencil . (feta . ("upbow" . "upbow"))) - (avoid-slur . around) - (padding . 0.20) - (direction . 1))) - ("downbow" . - ((script-stencil . (feta . ("downbow" . "downbow"))) - (padding . 0.20) - (avoid-slur . around) - (direction . 1))) - ("lheel" . - ((script-stencil . (feta . ("upedalheel" . "upedalheel"))) - (padding . 0.20) - (direction . -1)) - ) - ("rheel" . - ((script-stencil . (feta . ("dpedalheel" . "dpedalheel"))) - (padding . 0.20) - (direction . 1))) - ("ltoe" . - ((script-stencil . (feta . ("upedaltoe" . "upedaltoe"))) - (padding . 0.20) - (direction . -1))) - ("rtoe" . - ((script-stencil . (feta . ("dpedaltoe" . "dpedaltoe"))) - (padding . 0.20) - (direction . 1))) - ("turn" . - ((script-stencil . (feta . ("turn" . "turn"))) - (avoid-slur . inside) - (padding . 0.20) - (direction . 1))) - ("open" . - ((avoid-slur . outside) - (padding . 0.20) - (script-stencil . (feta . ("open" . "open"))) - (direction . 1))) - ("flageolet" . - ((script-stencil . (feta . ("flageolet" . "flageolet"))) - (padding . 0.20) - (direction . 1))) - ("reverseturn" . - ((script-stencil . (feta . ("reverseturn" . "reverseturn"))) - (padding . 0.20) - (direction . 1))) - ("trill" . - ((script-stencil . (feta . ("trill" . "trill"))) - (direction . 1) - (padding . 0.20) - (avoid-slur . outside) - (script-priority . 2000))) - ("prall" . - ((script-stencil . (feta . ("prall" . "prall"))) - (padding . 0.20) - (direction . 1))) - ("mordent" . - ((script-stencil . (feta . ("mordent" . "mordent"))) - (padding . 0.20) - (direction . 1))) - ("prallprall" . - ((script-stencil . (feta . ("prallprall" . "prallprall"))) - (padding . 0.20) - (direction . 1))) - ("prallmordent" . - ((script-stencil . (feta . ("prallmordent" . "prallmordent"))) - (padding . 0.20) - (direction . 1))) - ("upprall" . - ((script-stencil . (feta . ("upprall" . "upprall"))) - (padding . 0.20) - (direction . 1))) - ("downprall" . - ((script-stencil . (feta . ("downprall" . "downprall"))) - (padding . 0.20) - (direction . 1))) - ("upmordent" . - ((script-stencil . (feta . ("upmordent" . "upmordent"))) - (padding . 0.20) - (direction . 1))) - ("downmordent" . - ((script-stencil . (feta . ("downmordent" . "downmordent"))) - (padding . 0.20) - (direction . 1))) - ("lineprall" . - ((script-stencil . (feta . ("lineprall" . "lineprall"))) - (padding . 0.20) - (direction . 1))) - ("pralldown" . - ((script-stencil . (feta . ("pralldown" . "pralldown"))) - (padding . 0.20) - (direction . 1))) - ("prallup" . - ((script-stencil . (feta . ("prallup" . "prallup"))) - (padding . 0.20) - (direction . 1))) - ("segno" . - ((script-stencil . (feta . ("segno" . "segno"))) - (padding . 0.20) - (direction . 1))) - ("coda" . - ((script-stencil . (feta . ("coda" . "coda"))) - (padding . 0.20) - (direction . 1))) - ("varcoda" . - ((script-stencil . (feta . ("varcoda" . "varcoda"))) - (padding . 0.20) - (direction . 1)))) - default-script-alist) - ) + ("signumcongruentiae" . + ((script-stencil . (feta . ("dsignumcongruentiae" . "usignumcongruentiae"))) + (padding . 0.20) + (direction . 1))) + ("fermata" . + ((script-stencil . (feta . ("dfermata" . "ufermata"))) + (padding . 0.20) + (avoid-slur . around) + (script-priority . 4000) + (direction . 1))) + ("shortfermata" . + ((script-stencil . (feta . ("dshortfermata" . "ushortfermata"))) + (padding . 0.20) + (direction . 1))) + ("longfermata" . + ((script-stencil . (feta . ("dlongfermata" . "ulongfermata"))) + (padding . 0.20) + (direction . 1))) + ("verylongfermata" . + ((script-stencil . (feta . ("dverylongfermata" . "uverylongfermata"))) + (padding . 0.20) + (direction . 1))) + ("stopped" . + ((script-stencil . (feta . ("stopped" . "stopped"))) + (avoid-slur . inside) + (padding . 0.20) + (direction . 1))) + ("staccato" . + ((script-stencil . (feta . ("staccato" . "staccato"))) + (side-relative-direction . -1) + (quantize-position . #t) + (avoid-slur . inside) + (padding . 0.20) + (script-priority . -100))) + ("tenuto" . + ((script-stencil . (feta . ("tenuto" . "tenuto"))) + (quantize-position . #t) + (avoid-slur . inside) + (padding . 0.20) + (side-relative-direction . -1))) + ("comma" . + ((script-stencil . (feta . ("lcomma" . "rcomma"))) + (quantize-position . #t) + (padding . 0.20) + (direction . 1))) + ("varcomma" . + ((script-stencil . (feta . ("lvarcomma" . "rvarcomma"))) + (quantize-position . #t) + (padding . 0.20) + (direction . 1))) + ("upbow" . + ((script-stencil . (feta . ("upbow" . "upbow"))) + (avoid-slur . around) + (padding . 0.20) + (direction . 1))) + ("downbow" . + ((script-stencil . (feta . ("downbow" . "downbow"))) + (padding . 0.20) + (avoid-slur . around) + (direction . 1))) + ("lheel" . + ((script-stencil . (feta . ("upedalheel" . "upedalheel"))) + (padding . 0.20) + (direction . -1)) + ) + ("rheel" . + ((script-stencil . (feta . ("dpedalheel" . "dpedalheel"))) + (padding . 0.20) + (direction . 1))) + ("ltoe" . + ((script-stencil . (feta . ("upedaltoe" . "upedaltoe"))) + (padding . 0.20) + (direction . -1))) + ("rtoe" . + ((script-stencil . (feta . ("dpedaltoe" . "dpedaltoe"))) + (padding . 0.20) + (direction . 1))) + ("turn" . + ((script-stencil . (feta . ("turn" . "turn"))) + (avoid-slur . inside) + (padding . 0.20) + (direction . 1))) + ("open" . + ((avoid-slur . outside) + (padding . 0.20) + (script-stencil . (feta . ("open" . "open"))) + (direction . 1))) + ("flageolet" . + ((script-stencil . (feta . ("flageolet" . "flageolet"))) + (padding . 0.20) + (direction . 1))) + ("reverseturn" . + ((script-stencil . (feta . ("reverseturn" . "reverseturn"))) + (padding . 0.20) + (direction . 1))) + ("trill" . + ((script-stencil . (feta . ("trill" . "trill"))) + (direction . 1) + (padding . 0.20) + (avoid-slur . outside) + (script-priority . 2000))) + ("prall" . + ((script-stencil . (feta . ("prall" . "prall"))) + (padding . 0.20) + (direction . 1))) + ("mordent" . + ((script-stencil . (feta . ("mordent" . "mordent"))) + (padding . 0.20) + (direction . 1))) + ("prallprall" . + ((script-stencil . (feta . ("prallprall" . "prallprall"))) + (padding . 0.20) + (direction . 1))) + ("prallmordent" . + ((script-stencil . (feta . ("prallmordent" . "prallmordent"))) + (padding . 0.20) + (direction . 1))) + ("upprall" . + ((script-stencil . (feta . ("upprall" . "upprall"))) + (padding . 0.20) + (direction . 1))) + ("downprall" . + ((script-stencil . (feta . ("downprall" . "downprall"))) + (padding . 0.20) + (direction . 1))) + ("upmordent" . + ((script-stencil . (feta . ("upmordent" . "upmordent"))) + (padding . 0.20) + (direction . 1))) + ("downmordent" . + ((script-stencil . (feta . ("downmordent" . "downmordent"))) + (padding . 0.20) + (direction . 1))) + ("lineprall" . + ((script-stencil . (feta . ("lineprall" . "lineprall"))) + (padding . 0.20) + (direction . 1))) + ("pralldown" . + ((script-stencil . (feta . ("pralldown" . "pralldown"))) + (padding . 0.20) + (direction . 1))) + ("prallup" . + ((script-stencil . (feta . ("prallup" . "prallup"))) + (padding . 0.20) + (direction . 1))) + ("segno" . + ((script-stencil . (feta . ("segno" . "segno"))) + (padding . 0.20) + (direction . 1))) + ("coda" . + ((script-stencil . (feta . ("coda" . "coda"))) + (padding . 0.20) + (direction . 1))) + ("varcoda" . + ((script-stencil . (feta . ("varcoda" . "varcoda"))) + (padding . 0.20) + (direction . 1))))) diff --git a/scm/to-xml.scm b/scm/to-xml.scm index b1b2ed79a6..409247d0a5 100644 --- a/scm/to-xml.scm +++ b/scm/to-xml.scm @@ -5,8 +5,11 @@ ;;;; (c) 2003--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen +(define-module (scm to-xml)) + (use-modules (ice-9 regex) (srfi srfi-1) + (lily) (oop goops)) " diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index 6a8fcc1963..dd495fc750 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -1109,8 +1109,7 @@ class Lilypond_snippet (Snippet): and (self.relevant_contents (self.full_ly ()) == self.relevant_contents (open (ly_file).read ()))): return None - if global_options.verbose: - print 'OUT OF DATE: ', ly_file + return self def png_is_outdated (self): @@ -1565,6 +1564,7 @@ def write_file_map (lys, name): snippet_map = open ('snippet-map.ly', 'w') snippet_map.write (""" #(define version-seen #t) +#(define output-empty-score-list #f) #(ly:add-file-name-alist '( """) for ly in lys: @@ -1577,7 +1577,7 @@ def write_file_map (lys, name): def do_process_cmd (chunks, input_name): all_lys = filter (lambda x: is_derived_class (x.__class__, Lilypond_snippet), - chunks) + chunks) write_file_map (all_lys, input_name) ly_outdated = filter (lambda x: is_derived_class (x.__class__, diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index 6c2691c30c..66774fa672 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -313,7 +313,12 @@ def musicxml_voice_to_lily_voice (voice): if isinstance (n, musicxml.Attributes): if n.is_first () and n._measure_position == Rational (0): - voice_builder.add_bar_check (int (n.get_parent ().number)) + try: + number = int (n.get_parent ().number) + except ValueError: + number = 0 + + voice_builder.add_bar_check (number) for a in musicxml_attributes_to_lily (n): voice_builder.add_music (a, Rational (0)) continue @@ -330,7 +335,10 @@ def musicxml_voice_to_lily_voice (voice): continue if n.is_first () and n._measure_position == Rational (0): - num = int (n.get_parent ().number) + try: + num = int (n.get_parent ().number) + except ValueError: + num = 0 voice_builder.add_bar_check (num) main_event = musicxml_note_to_lily_main_event (n)