out-cov
tags
test-output-distance
+config-*.hh
+config-*.make
@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
@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
@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.
@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
tsMarkup =\markup {
\override #'(baseline-skip . 2) \number {
\column { "2" "4" }
- \lower #1 "+"
+ \vcenter "+"
\bracket \column { "5" "8" }
}
}
@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
@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
@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
@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
@tab articulations
@tab
@lilypond[fragment,relative=2]
-\override Staff.TimeSignature #'break-visibility = #all-invisible
+\set Staff.implicitTimeSignatureVisibility = #all-invisible
c-> c-.
@end lilypond
@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
@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
@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
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' {
@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 |
@}
@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
+++ /dev/null
-@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
-
#
# suggested settings
#
-# CHECK_SOURCE=<input/regression/ reference dir>
# LILYPOND_JOBS= -djob-count=X ## for SMP/Multicore machine
#
include local.make
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:
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
@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
Joe Neeman - Core development
Graham Percival - Documentation Editor and Bug Meister
Mats Bengtsson - Support Guru
+John Mandereau - Translation Meister
CONTRIBUTORS
Christian Hitz
David Bobroff
Eduardo Vieira
+Georg Dummer
Jay Anderson
Jean-Marie Mouchel
Kazuhiro Suzuki
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=11
-PATCH_LEVEL=7
+PATCH_LEVEL=10
MY_PATCH_LEVEL=
# 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
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 <<EOF
+
+now run
+
+ python buildscripts/coverage.py --uncovered $resultdir/*.cc
+
+EOF
--- /dev/null
+#!/bin/sh
+
+if test "$1" == "--fresh"; then
+ fresh=yes
+fi
+
+if test ! -f config-prof.make; then
+ fresh=yes
+fi
+
+if test "$fresh" = "yes";
+then
+ ./configure --enable-config=prof --enable-optimising \
+ && perl -i~ -pe 's/-pipe /-pg -pipe /g' config-prof.make \
+ && perl -i~ -pe 's/ -ldl / -pg -ldl /g' config-prof.make
+fi
+
+make conf=prof -j2
+
+if test "$?" != "0"; then
+ exit 2
+fi
+
+depth=../..
+resultdir=out/profile-results
+
+rm -rf $resultdir
+mkdir $resultdir
+cd $resultdir
+
+
+echo 'foo = \new Staff \new Voice \repeat unfold 50 \relative { c4 d8[ d16( e]~ e16[ e e) f] g8 }
+\new ChoirStaff <<
+ \foo \foo \foo \foo
+ \foo \foo \foo \foo
+
+>>' > 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
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 ()
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
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:
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)
################################################################
# 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 = '<br>(<a href="%(details_base)s">details</a>)' % 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 '''<tr>
+<td>
+%(dist)f
+%(details)s
+</td>
+<td>%(cell1)s<br><font size=-2><a href="%(file1)s"><tt>%(name)s</tt></font></td>
+<td>%(cell2)s<br><font size=-2><a href="%(file2)s"><tt>%(name)s</tt></font></td>
+</tr>''' % 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 = '<font size="-2"><pre>%s</pre></font>' % 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 '''<tr>
-<td>
-%f
-</td>
-<td><tt>%s</tt></td>
-<td><tt>%s</tt></td>
-</tr>''' % ((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 = '<font size="-2"><pre>%s</pre></font>' % 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 '<pre>%s</pre>' % 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
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):
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)
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):
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']
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'
name = '<tt>%s</tt>' % name
return '''
-<td align="center">
<a href="%(img)s">
<img src="%(img)s" style="border-style: none; max-width: 500px;">
</a><br>
-<font size="-2">(<a href="%(ly)s">%(name)s</a>)
-</font>
-</td>
''' % locals ()
def multi_img_cell (ly, imgs, name):
if not name:
return '''
-<td align="center">
%(imgs_str)s
-<font size="-2">(<a href="%(ly)s">%(name)s</a>)
-</font>
-</td>
''' % locals ()
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 = '''
-<tr>
-<td>
-%f<br>
-(<a href="%s">details</a>)
-</td>
-
-%s
-%s
-</tr>
-''' % (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 ()
e = '<tr>%s</tr>' % e
html += e
- original = self.original_name
+ original = self.name ()
html = '''<html>
<head>
<title>comparison details for %(original)s</title>
''' % 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
import glob
import re
-
-
def compare_signature_files (f1, f2):
s1 = read_signature_file (f1)
s2 = read_signature_file (f2)
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):
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]
for p in paired:
if (options.max_count
and len (self.file_links) > options.max_count):
-
continue
f2 = dir2 + '/' + p
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):
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 == '':
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)
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)
</html>''' % locals()
html += ('<p>')
- below_count =len ([1 for s,l in results
- if threshold >= s > 0.0])
+ below_count = len (below)
if below_count:
html += ('<p>%d below threshold</p>' % below_count)
-
- html += ('<p>%d unchanged</p>'
- % len ([1 for (s,l) in results if s == 0.0]))
-
+
+ html += ('<p>%d unchanged</p>' % len (unchanged))
dest_file = dest_dir + '/index.html'
open_write_file (dest_file).write (html)
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)
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
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')
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"
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'''
}
'''
- 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)
void negate ();
int to_int () const;
- operator double () const;
+ operator double () const { return to_double (); }
+ double to_double () const;
Rational operator - () const;
/**
#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_;
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
+++ /dev/null
-depth = ../..
-
-STEPMAKE_TEMPLATES=documentation texinfo tex
-LOCALSTEPMAKE_TEMPLATES=lilypond ly lysdoc
-
-include $(depth)/make/stepmake.make
-TITLE=LilyPond MIDI Tests
-
+++ /dev/null
-
-\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 {}
-}
+++ /dev/null
-\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 { }
-}
-
+++ /dev/null
-\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 {}
- }
+++ /dev/null
-
-\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 { }
-}
-
+++ /dev/null
-\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 { }
-}
-
-
+++ /dev/null
-\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)
- }
- }
-}
-
-
+++ /dev/null
-\header
-{
- texidoc = "should deliver f' in MIDI"
-}
-\version "2.10.5"
-
-\score {
- {
- \transposition f
- c''
- }
- \midi{}
- \layout{}
-}
+++ /dev/null
-depth = ../..
-
-EXTRA_DIST_FILES=README
-LOCALSTEPMAKE_TEMPLATES=ly mutopia
-
-include $(depth)/make/stepmake.make
-
-
+++ /dev/null
-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.
-
+++ /dev/null
-\version "2.10.0"
-
-\header {
-
-texidoc = "skipTypesetting doesn't affect bar checks."
-
-}
-
-\score { {
- \set Score.skipTypesetting = ##t
- c4 c4
- |
- c4 c4 }}
+++ /dev/null
-\version "2.10.0"
-
-\header {
-
-texidoc = "The first duration following a beam-open request is checked if it is short enough."
-
-}
-
-\score {
- { [c4 c] }
-}
+++ /dev/null
-\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 }
- }
- >>
- }
-}
+++ /dev/null
-\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 } #]
+++ /dev/null
-\version "2.10.0"
-
-\header{
-
- texidoc = "This should not hang lilypond --safe-mode."
-
-}
-
-% DOS
-#(do () (#f))
-
-\score{
- c''
-}
\ No newline at end of file
+++ /dev/null
-\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 }"
-}
+++ /dev/null
-\version "2.10.0"
-
-\header{
-
- texidoc = "This should not hang lilypond --safe-mode run."
-
-}
-
-\score{
- % DOS
- c''-"\\loop\\iftrue\\repeat"
-}
+++ /dev/null
-
-\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)
- }
- }
-
-
-}
-
+++ /dev/null
-\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}
-}
-
-
+++ /dev/null
-\version "2.10.0"
-
-% Test parser error
-
-\score{
+++ /dev/null
-\version "2.10.0"
-
-% Test parser error
-
-foo = {
-
-
-\score{
-}
+++ /dev/null
-\version "2.10.0"
-
-% Test parser error
-
-foo = {
-
-
-\score{
-
+++ /dev/null
-\version "2.10.0"
-
-% Test parser error
-
-foo = {
-}
-
-
-\score{
- burp
-}
-
+++ /dev/null
-\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 }
->>
-}
-
+++ /dev/null
-\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)
+++ /dev/null
-\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
+++ /dev/null
-\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
+++ /dev/null
-\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 }"
-}
+++ /dev/null
-\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}"
-}
+++ /dev/null
-\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}
-}
-
+++ /dev/null
-\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
-}
-
texidoc = "Accidentals are reset for clef changes."
}
+\layout {
+ ragged-right = ##t
+}
+
+
\version "2.10.0"
\new Staff \relative c' {
\clef treble
<cis dis fis gis>
}
-\layout {ragged-right = ##t}
\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
}
--- /dev/null
+
+\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
+ }
+>>
+
"
}
-\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-]
}
--- /dev/null
+\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
+}
texidoc = "Bends avoid dots, but only if necessary."
}
+\paper {
+ ragged-right = ##t
+}
+
\score {
<<
\new Staff \relative c' {
}
>>
}
-
-\paper {
- ragged-right = ##t
-}
@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
-}
--- /dev/null
+\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
+}
+
}
-\context Staff \relative c'' <<
- { c2. c bes2 } \\
- { c2. a8 g4 f4. g4 f }
->>
-
\layout {
\context{
\Voice
\consists "Completion_heads_engraver"
}
}
+
+\context Staff \relative c'' <<
+ { c2. c bes2 } \\
+ { c2. a8 g4 f4. g4 f }
+>>
--- /dev/null
+\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
+}
--- /dev/null
+\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) %{ ] %}
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\!
+}
+
--- /dev/null
+\version "2.10.8"
+\header
+{
+ texidoc = "Scripts left of a chord avoid accidentals."
+}
+
+\paper {
+ ragged-right = ##t
+}
+
+{
+ r4
+ \set fingeringOrientations = #'(left)
+ <cis''-3 >
+}
--- /dev/null
+\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))
--- /dev/null
+\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
+}
}
+\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 } >>
c4 \glissando c,, \glissando c' \glissando d
}
-\layout{
- line-width = 50.\mm
- indent = 0
-}
-
--- /dev/null
+\version "2.10.8"
+\header {
+ texidoc = "Hairpins end at the left edge of a rest."
+}
+
+\layout{
+ ragged-right=##t
+}
+\relative c'' {
+ c2\p\> r4\!
+}
--- /dev/null
+
+\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 }
+
+
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
--- /dev/null
+\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
+ }
+>>
+
+
+
}
+\layout {
+ ragged-right = ##t
+}
<<
\new Voice =A {
}
\lyricsto A \context Lyrics \lyricmode { a __ a __ ha }
>>
- \layout {
- ragged-right = ##t
- }
}
+\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]
bla16 -- bla -- bla
}
>>
- \layout {
- indent = 0.0 \cm
- line-width = 3.4 \cm
-
- \context {
- \Staff \remove "Time_signature_engraver"
- }
- }
-
-
\dynamic sfzp
\huge { "A" \smaller "A" \smaller \smaller "A"
\smaller \smaller \smaller "A" }
- \sub "alike"
+ \larger \sub "alike"
}
\break
f'1-#(markup*
#:dynamic "sfzp"
#:huge #:line ("A" #:smaller "A" #:smaller #:smaller "A"
#:smaller #:smaller #:smaller "A")
- #:sub "alike")
+ #:larger #:sub "alike")
}
--- /dev/null
+
+\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 {}
+}
--- /dev/null
+\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{}
+}
--- /dev/null
+\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 { }
+}
+
--- /dev/null
+\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 {}
+ }
--- /dev/null
+\version "2.10.8"
+\header {
+ texidoc = "The pitch wheel is used for microtones."
+ }
+
+\score {
+ { c4 cih cis cisih d }
+ \midi { }
+ }
+
--- /dev/null
+\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{}
+}
--- /dev/null
+
+\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 { }
+}
+
--- /dev/null
+\header
+{
+ texidoc = "should deliver f' in MIDI"
+}
+\version "2.10.5"
+
+\score {
+ {
+ \transposition f
+ c''
+ }
+ \midi{}
+ \layout{}
+}
--- /dev/null
+\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 { }
+}
+
+
--- /dev/null
+\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)
+ }
+ }
+}
+
+
--- /dev/null
+\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
+}
+
+
\time 3/4 \key cis \major
R2.*15
- R2.
- R2.*3
+ R2.*7
R2.*9
R2.*11
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
\fatText
c_"very wide and long text" c
}
-\layout {
- line-width = 3.0\cm
-}
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
\clef F s1*4
}
>>
- \layout {
- line-width = 8.0 \cm
- }
-
-
\repeat unfold 5 \relative { c1 c1 c1 }
}
+
\book {
\score {
\bla
#(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))
--- /dev/null
+\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 }
+>>
+
--- /dev/null
+% -*- 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))
+ (symbol<? (car x) (car y)))
+ (else #f)))
+
+#(define (display-stats what)
+ (let*
+ ((count 50)
+ (rnd 10)
+ (round-to (lambda (x) (* rnd (inexact->exact (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)
+
+
}
-\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
}
-\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 }
@code{rest-event} is not in @code{quotedEventTypes}."
}
-\version "2.10.0"
+\version "2.11.10"
\layout {
ragged-right = ##t
}
quoteMe = \relative c' { fis4 r16 a8.-> b4-\ff c }
-\addquote quoteMe \quoteMe
+\addQuote quoteMe \quoteMe
original = \relative c'' { c8 d s2 es8 gis8 }
<<
}
\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
<<
-\version "2.10.0"
+\version "2.11.10"
\header {
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 } |
}
-\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
d'16 d'16 d'8
}
-\addquote sax {
+\addQuote sax {
\transposition es'
a8 a a a a a a a
}
-\version "2.10.0"
+\version "2.11.10"
\header {
\times 2/3 { c4 c c } \times 2/3 { c4 c c }
}
-\addquote "foo" { \foo }
+\addQuote "foo" { \foo }
\paper {
ragged-right = ##t
@code{rest-event} is not in @code{quotedEventTypes}."
}
-\version "2.10.0"
+\version "2.11.10"
\layout {
ragged-right = ##t
}
quoteMe = \relative c' { fis4 r16 a8.-> b4-\ff c }
-\addquote quoteMe \quoteMe
+\addQuote quoteMe \quoteMe
original = \relative c'' { c8 d s2 es8 gis8 }
<<
--- /dev/null
+\header {
+ texidoc = "Relative mode for repeats uses order of entry."
+ }
+\version "2.10.8"
+
+\relative {
+ \repeat "unfold" 3
+ { f2 bes2 }
+ \alternative { a1 e b }
+}
--- /dev/null
+\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"
+
--- /dev/null
+\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
+}
--- /dev/null
+\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
+ }
+ }
+}
"
}
+\layout{
+ line-width = 120.\mm
+}
\relative c''{
\time 3/4
\stemNeutral c ( \stemUp c \stemNeutral c) c ( a c) c( d, c') c( f, c')
\stemDown c( f, c')
}
-\layout{
- line-width = 120.\mm
-}
-
-
}
-\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.] }
}
}
+\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
-}
--- /dev/null
+\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 }
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
--- /dev/null
+\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''
+ }
+}
--- /dev/null
+\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 }
+>>
+}
+
\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
}
vector<Grob*> 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));
#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))
{
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)
#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
}
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;
}
str_ = instrument_string;
}
+void
+Audio_item::render ()
+{
+}
+
+Audio_column *
+Audio_item::get_column () const
+{
+ return audio_column_;
+}
+
Audio_item::Audio_item ()
{
audio_column_ = 0;
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;
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;
"@ref{Stem_engraver} properties @code{stemLeftBeamCount} and "
"@code{stemRightBeamCount}. ",
/* create */ "Beam",
- /* read */ "autoBeaming autoBeamSettings beatLength subdivideBeams",
+
+ /* read */
+ "autoBeaming "
+ "autoBeamSettings "
+ "beatLength "
+ "subdivideBeams ",
+
/* write */ "");
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<Grob*> const &elts,
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<Grob*> 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<Grob*> relevant_elts;
- SCM is_relevant = ly_lily_module_constant ("pure-relevant");
+ Item *it = dynamic_cast<Item*> (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<Item*> (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));
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);
}
}
"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 "
}
if (stems.size () <= 2)
- return SCM_UNSPECIFIED;
+ return scm_from_int (0);
vector<int> close_positions;
vector<int> far_positions;
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_;
finished_beam_ = 0;
finished_beam_info_ = 0;
beam_info_ = 0;
- now_stop_ev_ = 0;
+ stop_ev_ = 0;
start_ev_ = 0;
prev_start_ev_ = 0;
}
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
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_)
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
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 ();
if (d == START && valid_start_point ())
start_ev_ = ev;
else if (d == STOP && valid_end_point ())
- now_stop_ev_ = ev;
+ stop_ev_ = ev;
}
/* read */
"beamMelismaBusy "
"beatLength "
- "allowBeamBreak "
"subdivideBeams "
,
/* write */ "");
{
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);
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;
// debug quanting
me->set_property ("quant-score",
- scm_makfrom0str (qscores[best_idx].score_card_.c_str ()));
+ ly_string2scm (qscores[best_idx].score_card_));
}
#endif
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)));
#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.
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
Direction dir = CENTER;
- int count = visible_stem_count (me);
+ int count = normal_stem_count (me);
if (count < 2)
{
extract_grob_set (me, "stems", stems);
}
else
{
- Grob *stem = first_visible_stem (me);
+ Grob *stem = first_normal_stem (me);
/*
ugh: stems[0] case happens for chord tremolo.
}
else
{
+ /*
+ FIXME: what's this for?
+ */
SCM s = scm_cdr (this_beaming);
for (; scm_is_pair (s); s = scm_cdr (s))
{
vector<Beam_segment> 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
{
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);
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 ())
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 ())
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);
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<Real> 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];
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;
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.
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)
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;
x_posns.push_back (x);
}
- Grob *lvs = last_visible_stem (me);
+ Grob *lvs = last_normal_stem (me);
if (!lvs)
return posns;
Grob *me = unsmob_grob (smob);
Drul_array<Real> pos = ly_scm2interval (posns);
- if (visible_stem_count (me) <= 1)
+ if (normal_stem_count (me) <= 1)
return 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;
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;
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"));
}
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;
}
/*
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<Real> pos (robust_scm2drul (beam->get_property ("positions"),
Real dy = pos[RIGHT] - pos[LEFT];
- Drul_array<Grob*> visible_stems (first_visible_stem (beam),
- last_visible_stem (beam));
+ Drul_array<Grob*> 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);
"length-fraction "
"least-squares-dy "
"neutral-direction "
+ "normal-stems "
"positions "
"quant-score "
"quantized-positions "
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<Offset> *array, Real x, Real y)
{
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;
+}
+
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))
{
#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<Item *> (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
if (beam_)
{
repeat_->origin ()->warning (_ ("unterminated chord tremolo"));
+ announce_end_grob (beam_, SCM_EOL);
beam_->suicide ();
}
}
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
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)
str += "_change";
}
- return scm_makfrom0str (str.c_str ());
+ return ly_string2scm (str);
}
s->suicide ();
"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
{
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",
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"));
class Dot_column_engraver : public Engraver
{
Grob *dotcol_;
- vector<Item*> heads_;
public:
TRANSLATOR_DECLARATIONS (Dot_column_engraver);
Dot_column_engraver::stop_translation_timestep ()
{
dotcol_ = 0;
- heads_.clear ();
}
void
}
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_)
#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);
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.")
Duration *r = (Duration *) SCM_CELL_WORD_1 (s);
scm_puts ("#<Duration ", port);
- scm_display (scm_makfrom0str (r->to_string ().c_str ()), port);
+ scm_display (ly_string2scm (r->to_string ()), port);
scm_puts (" >", port);
return 1;
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);
}
}
}
-
void
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)
{
Side_position_interface::add_support (line_spanner_, info.grob ());
}
-
void
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)
{
+++ /dev/null
-/*
- dynamic-performer.cc -- implement Dynamic_performer
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-#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*/"");
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
#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;
void
Figured_bass_engraver::process_music ()
{
- if (!to_boolean (get_property ("useBassFigureExtenders")))
+ if (alignment_ && !to_boolean (get_property ("useBassFigureExtenders")))
clear_spanners ();
if (rest_event_)
*/
#include "lily-guile.hh"
-#include "std-string.hh"
+#include "string-convert.hh"
+#include "warn.hh"
#include <fontconfig/fontconfig.h>
-void
+string
display_fontset (FcFontSet *fs)
{
+ string retval;
+
int j;
for (j = 0; j < fs->nfont; j++)
{
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 ();
if (pat)
FcPatternDestroy (pat);
+ string retval;
if (fs)
{
- display_fontset (fs);
+ retval = display_fontset (fs);
FcFontSetDestroy (fs);
}
+ return retval;
}
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);
(),
"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;
}
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,
{
expr = scm_list_3 (ly_symbol2scm ("named-glyph"),
self_scm (),
- scm_makfrom0str (s.c_str ()));
+ ly_string2scm (s));
b = get_indexed_char (idx);
}
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
+ "\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);
}
#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),
if (file_name.empty ())
return SCM_BOOL_F;
- return scm_makfrom0str (file_name.c_str ());
+ return ly_string2scm (file_name);
}
/*
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, (),
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),
{
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",
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;
}
}
*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",
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;
}
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;
+}
+
*/
#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"
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_)
origin_trans_ = t;
grob_ = g;
start_end_ = START;
+
+ /*
+ assert here, because this is easier to debug.
+ */
+ assert (g);
}
Grob_info::Grob_info ()
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);
+++ /dev/null
-/*
- grob-pitch-tuple.cc -- implement Grob_pitch_tuple
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2001--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
-*/
-
-#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 pitch<?
-*/
-int
-Grob_pitch_tuple::pitch_compare (Grob_pitch_tuple const &h1,
- Grob_pitch_tuple const &h2)
-{
- return Pitch::compare (h1.pitch_, h2.pitch_);
-}
-
-int
-Grob_pitch_tuple::time_compare (Grob_pitch_tuple const &h1,
- Grob_pitch_tuple const &h2)
-{
- return Moment::compare (h1.end_, h2.end_);
-}
extern void check_interfaces_for_property (Grob const *me, SCM sym);
-void
#ifndef NDEBUG
+void
Grob::internal_set_property (SCM sym, SCM v, char const *file, int line, char const *fun)
{
SCM grob_p = ly_lily_module_constant ("ly:grob?");
scm_display (scm_list_2 (sym, type), scm_current_output_port ());
assert (0);
}
+
+ internal_set_value_on_alist (&mutable_property_alist_,
+ sym, v);
+
+
+ if (ly_is_procedure (modification_callback))
+ scm_apply_0 (modification_callback,
+ scm_list_n (self_scm (),
+ scm_from_locale_string (file),
+ scm_from_int (line),
+ scm_from_locale_string (fun),
+ sym, v, SCM_UNDEFINED));
+}
#else
+void
Grob::internal_set_property (SCM sym, SCM v)
{
+ internal_set_value_on_alist (&mutable_property_alist_,
+ sym, v);
+
+}
#endif
+void
+Grob::internal_set_value_on_alist (SCM *alist, SCM sym, SCM v)
+{
/* Perhaps we simply do the assq_set, but what the heck. */
if (!is_live ())
return;
check_interfaces_for_property (this, sym);
}
-#ifndef NDEBUG
- if (ly_is_procedure (modification_callback))
- scm_apply_0 (modification_callback,
- scm_list_n (self_scm (),
- scm_makfrom0str (file),
- scm_from_int (line),
- scm_makfrom0str (fun),
- sym, v, SCM_UNDEFINED));
-#endif
-
- mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, sym, v);
+ *alist = scm_assq_set_x (*alist, sym, v);
}
-//#define PROFILE_PROPERTY_ACCESSES
SCM
Grob::internal_get_property_data (SCM sym) const
{
if (ly_is_procedure (val)
|| is_simple_closure (val))
{
- val = ((Grob*)this)->try_callback (sym, val);
+ Grob *me = ((Grob*)this);
+ val = me->try_callback_on_alist (&me->mutable_property_alist_, sym, val);
}
return val;
#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)
simple_closure_expression (proc),
false, 0, 0);
}
+
#ifndef NDEBUG
if (debug_property_callbacks)
grob_property_callback_stack = scm_cdr (grob_property_callback_stack);
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;
}
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
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);
"transparent "
);
-
-
-
-
/****************************************************************
CALLBACKS
****************************************************************/
-
static SCM
grob_stencil_extent (Grob *me, Axis a)
{
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;
#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);
}
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;
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)
#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)
{
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_item*> 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
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 &);
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<Audio_dynamic*> dynamics_;
+
+
+ virtual void render ();
+ void add_absolute (Audio_dynamic*);
+ Audio_span_dynamic ();
+};
+
+
class Audio_key : public Audio_item
{
public:
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));
static Interval cached_pure_height (Grob *me, vector<Grob*> const &list,
Grob *common, int, int);
+ static Grob *calc_pure_elts_and_common (Grob*);
static Skyline_pair skyline_spacing (Grob *me, vector<Grob*> elements);
static void add_element (Grob *me, Grob *);
static void set_axes (Grob *, Axis, Axis);
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;
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 *);
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));
(c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#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
{
void up (Context *);
};
-#endif /* INTERPRETATION_CONTEXT_HANDLE_HH */
+#endif /* CONTEXT_HANDLE_HH */
-/*
- grob-pitch-tuple.hh -- declare Grob_pitch_tuple
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2001--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
-*/
-
-#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 */
-
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 */
vector<int> char_count_stack_;
public:
- bool allow_includes_b_;
Includable_lexer ();
~Includable_lexer ();
vector<string> 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;
};
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);
Lily_lexer (Sources *, Lily_parser *);
Lily_lexer (Lily_lexer const &, Lily_parser *);
int yylex ();
-
+
void add_lexed_char (int);
void prepare_for_next_token ();
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);
void parser_error (string);
void parser_error (Input const &, string);
void set_yydebug (bool);
+
+ SCM make_scope () const;
};
DECLARE_UNSMOB (Lily_parser, lily_parser);
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<Offset> const &points);
};
#endif // LOOKUP_HH
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 */
Input input_origin_;
string user_key_;
- Lily_parser *parser_;
- Lily_parser *get_parser () const;
-
Output_def (Output_def const&);
Output_def ();
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 */
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);
/*
- relocate.hh -- declare
+ relocate.hh -- declare relocation functions
source file of the GNU LilyPond music typesetter
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
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;
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 *);
};
bool is_stencil_head (SCM symbol);
SCM all_stencil_heads ();
-Stencil points_to_line_stencil (vector<Offset> points);
#endif /* STENCIL_HH */
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));
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 ();
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));
{
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 ()),
text_ = 0;
}
+/*
+ TODO: should use an event.
+ */
void
Instrument_switch_engraver::process_music ()
{
progress_indication ("\n");
scm_module_define (scm_car (scopes_),
ly_symbol2scm ("input-file-name"),
- scm_makfrom0str (s.c_str ()));
+ ly_string2scm (s));
}
}
<<EOF>> {
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
}
}
<chords,notes,figures>{RESTNAME} {
char const *s = YYText ();
- yylval.scm = scm_makfrom0str (s);
+ yylval.scm = scm_from_locale_string (s);
return RESTNAME;
}
<chords,notes,figures>R {
/* 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;
}
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;
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;
<*><<EOF>> {
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 ();
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;
}
}
}
- yylval.scm = scm_makfrom0str (str.c_str ());
+ yylval.scm = ly_string2scm (str);
return STRING;
}
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. */
{
return scm_call_3 (ly_lily_module_constant ("format"), SCM_BOOL_F,
- scm_makfrom0str ("~S"), scm);
+ scm_from_locale_string ("~S"), scm);
}
SCM
(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)
{
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)
{
}
-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;
-}
-
-
#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 ();
}
-
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);
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
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),
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",
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_);
+}
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). */
self_scm ());
lexer_->main_input_name_ = "<string>";
- 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 ();
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;
}
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;
}
layout = layout ? dynamic_cast<Output_def *> (layout->clone ()) : new Output_def;
layout->set_variable (ly_symbol2scm ("is-paper"), SCM_BOOL_T);
- layout->parser_ = parser;
return layout;
}
{
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);
+}
{
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_));
}
{
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_));
}
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_));
}
"arrow-length "
"arrow-width")
-
-
-/* todo: move this somewhere else? */
-Stencil
-points_to_line_stencil (vector<Offset> 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;
-}
Stencil
Lookup::blank (Box b)
{
- return Stencil (b, scm_makfrom0str (""));
+ return Stencil (b, scm_from_locale_string (""));
}
Stencil
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<Offset> 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<Offset> 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;
+}
#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:
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);
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)
{
}
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;
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
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"));
}
}
set_music_context (0);
}
+
if (music_context_
&& (start_new_syllable () || pending_grace_lyric_)
&& lyric_iter_->ok ())
music_found_ = true;
}
+
+ busy_ = false;
}
void
{
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));
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);
}
be_verbose_global = true;
break;
case 's':
- be_safe_global = true;
init_scheme_variables
+= "(cons \'safe #t)\n";
-
break;
case 'p':
make_preview = true;
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);
&& !dirs[next_nonneutral])
next_nonneutral++;
+ SCM retval = SCM_EOL;
while (last_nonneutral == VPOS || last_nonneutral < dirs.size () - 1)
{
Direction d1 = CENTER;
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 ()
next_nonneutral++;
}
- me->suicide ();
- return SCM_UNSPECIFIED;
+ return retval;
}
void
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);
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++)
stop_note_queue.insert (e);
if (play_start)
- output_event (ptr->audio_column_->at_mom (), note);
+ output_event (ptr->audio_column_->when (), note);
}
}
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))
{
do_start_note (note);
}
else
- output_event (audio->audio_column_->at_mom (), midi);
+ output_event (audio->audio_column_->when (), midi);
}
}
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")
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)
}
/*
- 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"))
{
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
if (to_boolean (get_property ("untransposable")))
return;
- mutable_property_alist_ = transpose_mutable (mutable_property_alist_, delta);
+ transpose_mutable (mutable_property_alist_, delta);
}
void
--- /dev/null
+/*
+ dynamic-performer.cc -- implement New_dynamic_performer
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#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<Stream_event*> span_events_;
+ Drul_array<Direction> 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*/"");
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);
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);
}
}
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);
}
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.")
Output_def::Output_def ()
{
scope_ = SCM_EOL;
- parser_ = 0;
parent_ = 0;
smobify_self ();
{
scope_ = SCM_EOL;
parent_ = 0;
- parser_ = s.parser_;
smobify_self ();
input_origin_ = s.input_origin_;
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)
{
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
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_),
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));
*/
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 ());
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;
* 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);
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 ();
#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
void
Paper_column::do_break_processing ()
{
- Spaceable_grob::remove_interface (this);
Item::do_break_processing ();
}
/*
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<Paper_column*> (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);
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<Offset> 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<Offset> 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 ();
}
lilypond_header_body:
{
- $$ = get_header(PARSER);
+ $$ = get_header (PARSER);
PARSER->lexer_->add_scope ($$);
}
| lilypond_header_body assignment {
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");
}
;
SCM
get_next_unique_context_id ()
{
- return scm_makfrom0str ("$uniqueContextId");
+ return scm_from_locale_string ("$uniqueContextId");
}
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);
}
/* 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 */ "");
vector<char> 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)
{
Pitch *r = (Pitch *) SCM_CELL_WORD_1 (s);
scm_puts ("#<Pitch ", port);
- scm_display (scm_makfrom0str (r->to_string ().c_str ()), port);
+ scm_display (ly_string2scm (r->to_string ()), port);
scm_puts (" >", port);
return 1;
}
#include "main.hh"
#include "item.hh"
#include "input.hh"
+#include "profile.hh"
#include "ly-smobs.icc"
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
*/
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)
*/
#include "program-option.hh"
+#include "profile.hh"
#include <cstdio>
#include <cstring>
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);
+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.")
}
+
bool
get_program_option (const char *s)
{
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);
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));
}
}
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);
/*
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);
}
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;
Note_column::translate_rests (rcol, discrete_y);
}
- return SCM_UNSPECIFIED;
+ return SCM_BOOL_T;
}
ADD_INTERFACE (Rest_collision,
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);;
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 "
+ );
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 ()
{
{
if (!skipping_)
{
- skip_start_mom_ = audio_column_->at_mom ();
+ skip_start_mom_ = audio_column_->when ();
skipping_ = true;
}
}
{
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 ();
}
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<Paper_score *> (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;
-}
-
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_);
}
"control-points "
"direction "
"details "
+ "head-direction "
"note-head "
"thickness "
);
programming_error ("lv tie without Semi_tie_column. Killing lv tie.");
me->suicide ();
}
-
- return SCM_UNSPECIFIED;
+
+ return me->get_property_data ("control-points");
}
int
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<Grob*> const &cols, vsize col_index, bool line_starter)
{
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<Item*> (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))
but the distance routine does.
*/
+/*
+ FIXME:
+
+ * Consider to use
+
+ typedef list<Skyline_point> Skyline;
+ struct Skyline_point
+ {
+ Real x;
+ Drul_array<Real> 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
}
Real
-Building::intersection (Building const &other) const
+Building::intersection_x (Building const &other) const
{
return (y_intercept_ - other.y_intercept_) / (other.slope_ - slope_);
}
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
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);
}
slur_->set_property ("quant-score",
- scm_makfrom0str (total.c_str ()));
+ ly_string2scm (total));
}
#endif
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_));
}
#include "pointer-group-interface.hh"
#include "grob.hh"
#include "paper-column.hh"
+#include "international.hh"
SCM
Spaceable_grob::get_minimum_distances (Grob *me)
}
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. ",
else if (type == ":|:")
type = ".|.";
- return scm_makfrom0str (type.c_str ());
+ return ly_string2scm (type);
}
Interval
+++ /dev/null
-/*
- span-dynamic-performer.cc -- implement Span_dynamic_performer
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-#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<Stream_event *> span_events_;
- vector<Audio_dynamic_tuple> dynamic_tuples_;
- vector<Audio_dynamic_tuple> 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<Audio_dynamic *> (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,
- "", "",
- "", "");
--- /dev/null
+/*
+ spanner-break-forbid-engraver.cc -- implement Spanner_break_forbid_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2007 Han-Wen Nienhuys <hanwen@lilypond.org>
+*/
+
+
+
+#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<Spanner*> 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<Spanner*>::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 */ "");
|| 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);
}
}
{
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;
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) -
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);
}
{
(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);
#include "staff-symbol-referencer.hh"
#include "tweak-registration.hh"
#include "warn.hh"
+#include "lookup.hh"
extern bool debug_skylines;
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);
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++;
System::column (int which) const
{
extract_grob_set (this, "columns", columns);
- for (vsize i = 0; i < columns.size (); i++)
- if (dynamic_cast<Paper_column*> (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*
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))
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_);
card += to_string ("TOTAL=%.2f", base.score ());
ties[i]->set_property ("quant-score",
- scm_makfrom0str (card.c_str ()));
+ ly_string2scm (card));
}
#endif
#include "engraver.hh"
#include "context.hh"
-#include "grob-pitch-tuple.hh"
#include "international.hh"
#include "item.hh"
#include "note-head.hh"
{
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--; )
do
{
spec.note_head_drul_[d] = Tie::head (ties[i], d);
- spec.column_ranks_[d] =
- dynamic_cast<Spanner*> (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);
spec.get_tie_manual_settings (semi_ties[i]);
spec.note_head_drul_[head_dir] = head;
- column_rank = dynamic_cast<Item*> (head)->get_column ()->get_rank ();
+ column_rank = Tie::get_column_rank (semi_ties[i], head_dir);
spec.column_ranks_ = Drul_array<int> (column_rank, column_rank);
heads.push_back (head);
specifications_.push_back (spec);
{
/* 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<Spanner*> (me_grob);
Grob *common = me;
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
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)
(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;
}
/*
#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, ());
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;
/* 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_)
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_;
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
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
if (stop_)
scm_gc_mark (stop_->self_scm ());
- Sequential_iterator::derived_mark ();
+ Music_wrapper_iterator::derived_mark ();
}
IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);
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;
}
}
#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 */ "");
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);
#include "score-engraver.hh"
#include "score-performer.hh"
#include "warn.hh"
+#include "international.hh"
/*
Quick & dirty.
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;
}
#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)
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_)
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);
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);
Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT];
vector<Offset> 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<Grob *> 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.
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.
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<Grob *> 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));
{
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_)
{
? 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 ();
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
}
prev_primitive->set_property ("glyph-name",
- scm_makfrom0str (prev_glyph_name.c_str ()));
+ ly_string2scm (prev_glyph_name));
align_heads (primitives, flexa_width, thickness);
{
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");
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"));
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
\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"
explicitClefVisibility = #all-visible
explicitKeySignatureVisibility = #all-visible
+ implicitTimeSignatureVisibility = #end-of-line-invisible
+
autoBeamSettings = #default-auto-beam-settings
autoBeaming = ##t
autoBeamCheck = #default-auto-beam-check
#(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"
#(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
(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"))))
\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)
--- /dev/null
+%% -*- 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))))))
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)
\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"
# 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.
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
+
+"""))
(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
(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.")
"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:
(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
;;;;;;;;;;;;;;;;
;; 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")
(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.")
(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? "")
(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
(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)
;; 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
rhythmic-grob-interface
text-interface
chord-name-interface
- item-interface))))))
+ ))))))
(CombineTextScript
. (
. (
(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
(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)
text-interface
side-position-interface
self-alignment-interface
- item-interface))))))
+ ))))))
(FretBoard
. ((stencil . ,fret-board::calc-stencil)
(finger-code . below-string)
(after-line-breaking . ,ly:line-spanner::after-line-breaking)
(meta . ((class . Spanner)
(interfaces . (line-interface
+ unbreakable-spanner-interface
line-spanner-interface))))))
(GraceSpacing
;; 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)
text-interface
side-position-interface
self-alignment-interface
- item-interface))))))
+ ))))))
(StrokeFinger
. (
text-interface
side-position-interface
self-alignment-interface
- item-interface))))))
+ ))))))
(SustainPedal
(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))))))
(padding . 0.3)
(meta . ((class . Item)
(interfaces . (side-position-interface
+ parentheses-interface
note-head-interface
rhythmic-head-interface
font-interface
(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
(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
(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))))))
(cons 'spanner-interface ifaces-entry))))
(else
(ly:warning "Unknown class ~a" class)))
+
+ (set! ifaces-entry (uniq-list (sort ifaces-entry symbol<?)))
(set! ifaces-entry (cons 'grob-interface ifaces-entry))
(set! meta-entry (assoc-set! meta-entry 'name name-sym))
(list
`(,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback)
`(,ly:stem::height . ,ly:stem::pure-height)
+ `(,ly:rest::height . ,ly:rest::pure-height)
`(,ly:grob::stencil-height . ,pure-stencil-height)
`(,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)
`(,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height)
ly:staff-symbol-referencer::callback
ly:staff-symbol::height))
-(define-public (pure-relevant grob)
+(define-public (pure-relevant? grob)
(let ((extent-callback (ly:grob-property-data grob 'Y-extent)))
(not (eq? #f
(or
(or
(not (eq? extent-callback ly:grob::stencil-height))
(memq (ly:grob-property-data grob 'stencil) pure-print-callbacks)
- (ly:stencil? (ly:grob-property-data grob 'stencil))))))))))
+ (ly:stencil? (ly:grob-property-data grob 'stencil))
+
+ ))))))))
(define-public (call-pure-function unpure args start end)
(if (ly:simple-closure? unpure)
;; geometric shapes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define-markup-command (draw-circle layout props radius thickness fill)
+(define-builtin-markup-command (draw-circle layout props radius thickness fill)
(number? number? boolean?)
"A circle of radius @var{radius}, thickness @var{thickness} and
optionally filled."
(make-circle-stencil radius thickness fill))
-(define-markup-command (triangle layout props filled) (boolean?)
+(define-builtin-markup-command (triangle layout props filled) (boolean?)
"A triangle, filled or not"
(let*
((th (chain-assoc-get 'thickness props 0.1))
(cons 0 (* .86 ex))
)))
-(define-markup-command (circle layout props arg) (markup?)
+(define-builtin-markup-command (circle layout props arg) (markup?)
"Draw a circle around @var{arg}. Use @code{thickness},
@code{circle-padding} and @code{font-size} properties to determine line
thickness and padding around the markup."
(m (interpret-markup layout props arg)))
(circle-stencil m th pad)))
-(define-markup-command (with-url layout props url arg) (string? markup?)
+(define-builtin-markup-command (with-url layout props url arg) (string? markup?)
"Add a link to URL @var{url} around @var{arg}. This only works in
the PDF backend."
(let* ((stil (interpret-markup layout props arg))
(ly:stencil-add (ly:make-stencil url-expr xextent yextent) stil)))
-(define-markup-command (beam layout props width slope thickness)
+(define-builtin-markup-command (beam layout props width slope thickness)
(number? number? number?)
"Create a beam with the specified parameters."
(let* ((y (* slope width))
(cons (+ (- half) (car yext))
(+ half (cdr yext))))))
-(define-markup-command (box layout props arg) (markup?)
+(define-builtin-markup-command (box layout props arg) (markup?)
"Draw a box round @var{arg}. Looks at @code{thickness},
@code{box-padding} and @code{font-size} properties to determine line
thickness and padding around the markup."
(m (interpret-markup layout props arg)))
(box-stencil m th pad)))
-(define-markup-command (filled-box layout props xext yext blot)
+(define-builtin-markup-command (filled-box layout props xext yext blot)
(number-pair? number-pair? number?)
"Draw a box with rounded corners of dimensions @var{xext} and
@var{yext}. For example,
(ly:round-filled-box
xext yext blot))
-(define-markup-command (rotate layout props ang arg) (number? markup?)
+(define-builtin-markup-command (rotate layout props ang arg) (number? markup?)
"Rotate object with @var{ang} degrees around its center."
(let* ((stil (interpret-markup layout props arg)))
(ly:stencil-rotate stil ang 0 0)))
-(define-markup-command (whiteout layout props arg) (markup?)
+(define-builtin-markup-command (whiteout layout props arg) (markup?)
"Provide a white underground for @var{arg}"
(stencil-whiteout (interpret-markup layout props arg)))
-(define-markup-command (pad-markup layout props padding arg) (number? markup?)
+(define-builtin-markup-command (pad-markup layout props padding arg) (number? markup?)
"Add space around a markup object."
(let*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;FIXME: is this working?
-(define-markup-command (strut layout props) ()
+(define-builtin-markup-command (strut layout props) ()
"Create a box of the same height as the space in the current font."
(let ((m (ly:text-interface::interpret-markup layout props " ")))
(ly:make-stencil (ly:stencil-expr m)
;; todo: fix negative space
-(define-markup-command (hspace layout props amount) (number?)
+(define-builtin-markup-command (hspace layout props amount) (number?)
"This produces a invisible object taking horizontal space.
@example
\\markup @{ A \\hspace #2.0 B @}
;; importing graphics.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define-markup-command (stencil layout props stil) (ly:stencil?)
+(define-builtin-markup-command (stencil layout props stil) (ly:stencil?)
"Stencil as markup"
stil)
#f)))
-(define-markup-command (epsfile layout props axis size file-name) (number? number? string?)
+(define-builtin-markup-command (epsfile layout props axis size file-name) (number? number? string?)
"Inline an EPS image. The image is scaled along @var{axis} to
@var{size}."
(eps-file->stencil 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,
'(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)))
(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)
-(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."
(/ (+ (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.
(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*
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
(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."
(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
-(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)))
;;
;; 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}."
(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)))
(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."
-(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}. "
))
-(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*
))
-(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}. "
(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))
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"
(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."
;; 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"
(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))))
-(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
;; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(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))
;; 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
(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\"
#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
(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
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
;; 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)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(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*
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."
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'."
(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
-(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*
;; 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."
(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
;; 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}.
(- 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*
(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}.
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))
-(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
(* 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
(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
(* -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)
;; 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.
(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
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
(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 ...
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")
+ ))
(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}
(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
(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.
ly:beam::quanting
(check-beam-quant l r)
))
-
+
(define-public (check-slope-callbacks comparison)
(list ly:beam::calc-least-squares-positions
(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)
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)
(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)))
(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
(define-public (moment-min a b)
(if (ly:moment<? a b) a b))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; arithmetic
(define-public (average x . lst)
(/ (+ x (apply + lst)) (1+ (length lst))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; lily specific variables.
-
-(define-public default-script-alist '())
-
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; parser <-> 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)))
(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))
(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
(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")))
"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")
(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")
)))
(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)))
(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)
+ )))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
))
(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))
(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))))))
))
(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)
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\"
The command is now available in markup mode, e.g.
-
\\markup { .... \\MYCOMMAND #1 argument ... }
" ; "
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 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,
* 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
"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))))
;;; (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 "
"-"))))
(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
(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)))
(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))
(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))
(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))))
ly:paper-get-number
ly:paper-system?
ly:output-def-lookup
- ly:parse-string
ly:parser-parse-string
ly:pitch-alteration
ly:pitch-diff
;;;;
;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
-(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)))))
;;;; (c) 2003--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
+(define-module (scm to-xml))
+
(use-modules (ice-9 regex)
(srfi srfi-1)
+ (lily)
(oop goops))
"
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):
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:
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__,
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
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)