]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' into translation
authorJean-Charles Malahieude <lilyfan@orange.fr>
Sat, 24 Oct 2015 15:10:28 +0000 (17:10 +0200)
committerJean-Charles Malahieude <lilyfan@orange.fr>
Sat, 24 Oct 2015 15:10:28 +0000 (17:10 +0200)
70 files changed:
.gitignore
Documentation/changes.tely
Documentation/contributor/doc-work.itexi
Documentation/contributor/quick-start.itexi
Documentation/de/learning/templates.itely
Documentation/de/notation/simultaneous.itely
Documentation/es/notation/simultaneous.itely
Documentation/fr/notation/simultaneous.itely
Documentation/included/compile.itexi
Documentation/it/notation/simultaneous.itely
Documentation/ja/notation/simultaneous.itely
Documentation/learning/common-notation.itely
Documentation/notation/editorial.itely
Documentation/notation/expressive.itely
Documentation/notation/input.itely
Documentation/notation/notation-appendices.itely
Documentation/notation/simultaneous.itely
Documentation/web/news-front.itexi
Documentation/web/news.itexi
VERSION
elisp/lilypond-mode.el
input/regression/part-combine-force-once.ly
input/regression/part-combine-force.ly
input/regression/phrasing-slur-multiple.ly
input/regression/slur-multiple.ly
lily/all-font-metrics.cc
lily/context-property.cc
lily/context.cc
lily/grob-closure.cc
lily/grob-property.cc
lily/grob-scheme.cc
lily/include/context.hh
lily/include/lily-imports.hh
lily/include/lookup.hh
lily/include/scm-hash.hh
lily/include/simple-closure.hh [deleted file]
lily/include/slur-proto-engraver.hh
lily/lily-imports.cc
lily/lookup.cc
lily/midi-stream.cc
lily/parenthesis-engraver.cc
lily/parser.yy
lily/phrasing-slur-engraver.cc
lily/scm-hash.cc
lily/simple-closure.cc [deleted file]
lily/slur-engraver.cc
lily/slur-proto-engraver.cc
lily/slur-scoring.cc
lily/stencil-scheme.cc
lily/translator-ctors.cc
lily/unpure-pure-container.cc
ly/Welcome-to-LilyPond-MacOS.ly
ly/Welcome_to_LilyPond.ly
ly/music-functions-init.ly
ly/property-init.ly
ly/spanners-init.ly
po/lilypond.pot
po/nl.po
python/convertrules.py
scm/chord-entry.scm
scm/define-context-properties.scm
scm/define-event-classes.scm
scm/define-music-properties.scm
scm/define-music-types.scm
scm/fret-diagrams.scm
scm/lily-library.scm
scm/lily.scm
scm/output-lib.scm
scm/part-combiner.scm
scm/stencil.scm

index 7096f9b3b68a3c83869f865148a26ee82a22d276..96f90af558da99f42dbeffda712fc7f2f95a7c74 100644 (file)
@@ -77,5 +77,5 @@ RELEASE-COMMIT
 Documentation/lilypond
 semantic.cache
 .lock-wscript
-build/
+/build/
 .gitfilelist
index 7ba1fa281bee1eff0d4d02ce6a4079250b596efd..f6af535df5f58c030c7eb33ea2c025524098c123 100644 (file)
@@ -287,7 +287,7 @@ For Example:
 declares a list of @q{tags} that belong to a single @q{tag group}.
 
 @example
-\keepwithTag#'violinI
+\keepWithTag #'violinI
 @end example
 
 Is now only concerned with @q{tags} from @q{violinI}’s tag group.
index 87fb7955b943a1ca400ac8b30a9a0c6011f8485b..70fd22660d1253c438754287d95c7d84e480038e 100644 (file)
@@ -1290,15 +1290,6 @@ Note that you have to find yourself the source files to fix
 cross-references in the generated documentation such as the
 Internals Reference; e.g. you can grep scm/ and lily/.
 
-@c temporary?  how long will kainhofer be used?  -gp
-Also of interest may be the linkdoc checks on kainhofer.com.  Be
-warned that these docs are not completely rebuilt every day, so it
-might not accurately reflect the current state of the docs.
-
-@example
-@uref{http://kainhofer.com/~lilypond/linkdoc/}
-@end example
-
 
 @node General writing
 @subsection General writing
index ce6fa2b0f96444b09d42e4afc67005cfb8e9bd07..6d6dec3e7c87538a2b9960288d6751b4b63c91f2 100644 (file)
@@ -17,64 +17,54 @@ for you and will help you do this as quickly and easily as possible.
 @node LilyDev
 @section LilyDev
 
-There is a disk image of a @q{remix} of Debian GNU/Linux available for
-download which includes all the necessary software and tools to compile
-both LilyPond and the documentation.  Called the
-@qq{Debian LilyPond Developer Remix}, but known simply as @qq{LilyDev}
-for short.  Although it is not possible to compile LilyPond on Windows
-and extremely difficult on MacOS, LilyDev can be installed and run
-inside a @q{virtual machine} on any of these operating systems without
-disturbing your main operating system.  The LilyDev disk image can also
-be burnt to a DVD or copied to a USB stick and installed like any
-other GNU/Linux distribution.
-
-Most virtualization software can be used but we recommend VirtualBox as
-it is available for all major operating systems and is easy to install
-& configure.
+@c This text was written based on LilyDev 4.0 - JL
 
-If you are not familiar with GNU/Linux, it may be beneficial to read a
-couple of @qq{introduction to Linux} web pages.
+There is a @q{remix} of Debian GNU/Linux -- known as @qq{LilyDev} for
+short -- which includes all the necessary software and tools to compile
+LilyPond, the documentation and the website (also see
+@ref{Website work}).
+
+@warning{LilyDev does not include the software for the Grand Unified
+Builder -- also see @ref{Grand Unified Builder (GUB)}.}
+
+While compiling LilyPond on MacOs and Windows is possible, both
+environments are complex to set up.  LilyDev can be easily installed
+and run inside a @q{virtual machine} on either of these operating
+systems relatively easily using readily available virtualization
+software.  We recommend using VirtualBox as it is available for all
+major operating systems and is very easy to install & configure.
 
-For those interested, the LilyDev remix is currently based on a 32bit
-version of Debian 7 (Wheezy).  The image is generated using Debian
-@uref{http://live.debian.net/, live-build} and the configuration
-files are hosted on GitHub:
+The LilyDev disk image can also be written to a USB device or @q{burnt}
+to a DVD -- it is approximately 900 GB in size -- and installed just
+like any standard GNU/Linux distribution.
 
-@smallexample
-@uref{https://github.com/fedelibre/LilyDev}
-@end smallexample
+The current image is based on a 32bit version of Debian 8 (@q{Jessie})
+and the Disk image was generated using Debian
+@uref{http://live.debian.net/, live-build 4}.
+
+@noindent
+Download the LilyDev disk image file from here:
+
+@example
+@uref{https://github.com/fedelibre/LilyDev/releases/latest}
+@end example
 
 @warning{Apart from installing and configuring LilyDev in VirtualBox,
 the rest of the chapter assumes that you are comfortable using the
-command-line.  While this chapter is intended for users who may have
-never created a patch or compiled software before, experienced
-developers (who prefer to use their own development environment) may
-still find it instructive to skim over this section.}
+command-line and is intended for users who may have never created a
+patch or compiled software before.  More experienced developers (who
+prefer to use their own development environment) may still find it
+instructive to skim over the following information.}
+
+If you are not familiar with GNU/Linux, it may be beneficial to read a
+a few @qq{introduction to Linux} type web pages.
 
 @menu
-* Where to get LilyDev::
 * Installing LilyDev in VirtualBox::
 * Configuring LilyDev in VirtualBox::
 @end menu
 
 
-@node Where to get LilyDev
-@unnumberedsubsec Where to get LilyDev
-
-Download the LilyDev image file (approximately 850 MB) from here:
-
-@smallexample
-@uref{http://www.et.byu.edu/~sorensen/lilydev-3.0.iso}
-@end smallexample
-
-Some advanced users might want this file too:
-@smallexample
-@uref{http://www.et.byu.edu/~sorensen/lilydev-3.0.iso.md5}
-@end smallexample
-(If you don't recognize what this file is, then you don't need it.)
-
-
-
 @node Installing LilyDev in VirtualBox
 @unnumberedsubsec Installing LilyDev in VirtualBox
 
@@ -89,7 +79,7 @@ you can skip this section and go straight to @ref{lily-git}.}
 Download Virtualbox from here:
 
 @example
-@uref{http://@/www.virtualbox.org/@/wiki/@/Downloads}
+@uref{http://www.virtualbox.org/wiki/Downloads}
 @end example
 
 @warning{In virtualization terminology, the operating system where
@@ -116,62 +106,51 @@ even if you are able to assign more.
 
 @item
 For your @q{Virtual Hard Disk}, leave the @q{Create new hard disk}
-option checked, use the default @q{VDI} and
-@qq{Dynamically allocated} options for the virtual hard drive.  A
-complete compile of everything (code, docs, regression tests) can reach
-10 GB so size your virtual disk and its location accordingly.
+option checked, use the default @q{VDI} and @qq{Dynamically allocated}
+options for the virtual hard drive.  A complete compile of everything
+(code, docs, regression tests) can reach 10 GB so size your virtual disk
+and its location accordingly.
 
 @item
 Verify the summary details and click @q{Create}, when you are satisfied.
 Your new guest will be displayed in the Virtualbox window.
-@warning{The image contains a 686-pae kernel, so you must enable PAE
-in the virtual machine settings: click on @clicksequence{System @click{} Processor}
-and select @q{Extended features: Enable PAE/NX}.}
+
+@warning{The image contains a @q{686-pae} kernel, so you must enable
+@code{PAE} within the virtual machine's settings -- click on
+@clicksequence{System @click{} Processor} and select
+@q{Extended features: Enable PAE/NX}.}
 
 @item
-Click the @q{Start} button and the @q{First Run Wizard} will prompt you for
-the installation media.  Click the browse icon and locate the LilyDev
-disk image and click through the wizard to start the installation
+Click the @q{Start} button and the @q{First Run Wizard} will prompt you
+for the installation media.  Click the browse icon, locate the LilyDev
+disk image and click through the wizard to begin the installation
 process.
 
 @item
-When the LilyDev disk image boots, you should choose the @q{Install} or
-the @q{Graphical install} menu item to begin the installation of
-LilyDev on your virtual hard disk.  The installer will walk you
-through the complete installation process.
-
-@warning{If the root password is left blank when prompted, the configured user
-account will be be given root privileges automatically.  This means that only
-one password needs to be remembered.}
+When the LilyDev disk image boots for the first time, choose either the
+@q{Install} or the @q{Graphical install} menu item.  The installer will
+then walk you through the complete installation process.
 
 @item
 At the @qq{Partition disks} stage, do not be afraid to select
 @qq{Guided - use entire disk}, since this refers to your
-@strong{@emph{virtual disk}}, not your machine's actual hard
-disk.
+@strong{@emph{virtual disk}}, not your computer's own hard disk.
 
 @item
-Click through the rest of the wizard, filling in any appropriate details
-when asked and wait for the install to complete.
-This will take about 10 minutes in a recent computer.
+Continue to click through the rest of the wizard, filling in any
+appropriate details when asked, and wait for the install to complete.
+This will take about 10 minutes or so on a reasonably modern computer.
 
 @item
-When the installation is completed, just click on Continue (you
-don't have to remove any media since you installed from a file
-on your host filesystem).  The installer will reboot the virtual
-machine: LilyDev is now installed and running!
-
+When the installation is completed, just click on @q{Continue} (you
+do not have to remove any media since you installed LilyDev from a Disk
+image, which is just a file on your computer).  The installer will
+reboot the virtual machine.
 
 @end enumerate
 
-@knownissues
-Not all hardware is supported in all virtualization tools.  In
-particular, some contributors have reported problems with USB network
-adapters.  If you have problems with network connection (for example
-Internet connection in the host system is lost when you launch virtual
-system), try installing and running LilyDev with your computer's
-built-in network adapter used to connect to the network.  Refer to the
-help documentation that comes with your virtualization software.
+@noindent
+LilyDev should now be installed and running!
 
 
 @node Configuring LilyDev in VirtualBox
@@ -199,9 +178,9 @@ with LilyDev as the client.
 @item
 Restart LilyDev to complete the installation of the guest additions.
 
-@advanced{If you do any kernel upgrades, you may need to reinstall
-the additional software.  Just follow the step above again and reboot
-when the reinstallation is complete.}
+@advanced{If you do any kernel upgrades, you may need to reinstall the
+additional software.  Just follow the step above again and reboot when
+the reinstallation is complete.}
 
 @end enumerate
 
@@ -218,8 +197,8 @@ hosts.
 @item
 Set up any additional features, such as @q{Shared Folders} between
 your main operating system and LilyDev.  This is distinct from the
-networked share folders in Windows.  Consult the external
-documentation for this.
+networked share folders in Windows.  Consult the external documentation
+for this.
 
 Some longtime contributors have reported that @q{shared folders}
 are rarely useful and not worth the fuss, particularly since files
@@ -232,24 +211,17 @@ Pasting into a terminal is done with @code{Ctrl+Shift+v}.
 Right-click allows you to edit a file with the text editor (default
 is Leafpad).
 
-@item
-One particular change from Windows and MacOS X is that most
-software should be installed with your @qq{package manager}; this
-vastly simplifies the process of installing and configuring
-software.  If you use LilyDev 3.0 and you need a graphical
-package manager type this command in a terminal:
-
-@c synaptic will be added in the next version of LilyDev
-
-@example
-sudo apt-get install synaptic
-@end example
-
-Go to the menu at the bottom left and click on
-@clicksequence{Preferences @click{} Synaptic Package Manager}.
-
 @end itemize
 
+@knownissues
+Not all hardware is supported in all virtualization tools.  In
+particular, some contributors have reported problems with USB network
+adapters.  If you have problems with network connection (for example
+Internet connection in the host system is lost when you launch virtual
+system), try installing and running LilyDev with your computer's
+built-in network adapter used to connect to the network.  Refer to the
+help documentation that comes with your virtualization software.
+
 
 @node lily-git
 @section lily-git
index bf9b8194a62d7abb9c3a32cfcce2cb3164bca478..9d521b173649c0ecebe54ef89ce28fcaa446364b 100644 (file)
@@ -588,7 +588,7 @@ violin concerto as TchaikovskyPI, whereas perhaps you wish to print
 
 @ The `line-width' is for \header.
 @li lypond[quote,verbatim,ragged-right,line-width]
-\version "2.19.2"
+\version "2.19.25"
 \header {
   dedication = "dedication"
   title = "Title"
index 7791aa6b05191d02e081534c1dc6b8f7984e957e..28e60c0964ffcd6628ed006ae332e454ca7eafc2 100644 (file)
@@ -7,7 +7,7 @@
     Guide, node Updating translation committishes.
 @end ignore
 
-@c \version "2.19.21"
+@c \version "2.19.29"
 
 @c Translators: Till Paala
 
@@ -1050,28 +1050,28 @@ Note eines musikalischen Ausdrucks.
 
 @itemize
 @item
-@code{\partcombineApart} und @code{\partcombineApartOnce}
+@code{\partcombineApart} und @code{\once \partcombineApart}
 erhalten die Noten als zwei unterschiedliche Stimmen, auch wenn sie als Akkord
 oder Unisono kombiniert werden könnten.
 
 @item
-@code{\partcombineChords} und @code{\partcombineChordsOnce}
+@code{\partcombineChords} und @code{\once \partcombineChords}
 kombinieren die Noten als Akkord.
 
 @item
-@code{\partcombineUnisono} und @code{\partcombineUnisonoOnce}
+@code{\partcombineUnisono} und @code{\once \partcombineUnisono}
 kombinieren beide Stimmen als Unisono.
 
 @item
-@code{\partcombineSoloI} und @code{\partcombineSoloIOnce}
+@code{\partcombineSoloI} und @code{\once \partcombineSoloI}
 setzen nur Stimme eins und markieren sie als @qq{Solo}.
 
 @item
-@code{\partcombineSoloII} und @code{\partcombineSoloIIOnce}
+@code{\partcombineSoloII} und @code{\once \partcombineSoloII}
 setzen nur Stimme zwei und markieren sie als @qq{Solo}.
 
 @item
-@code{\partcombineAutomatic} und @code{\partcombineAutomaticOnce}
+@code{\partcombineAutomatic} und @code{\once \partcombineAutomatic}
 beenden die Wirkung der Befehle oben und stellt das
 normale Verhalten des Kombinationsmechanismus wieder her.
 
@@ -1083,7 +1083,7 @@ instrumentOne = \relative c' {
   \partcombineAutomatic e2^"auto" e |
   \partcombineChords e'2^"chord" e |
   \partcombineAutomatic c2^"auto" c |
-  \partcombineApart c2^"apart" \partcombineChordsOnce e^"chord once" |
+  \partcombineApart c2^"apart" \once \partcombineChords e^"chord once" |
   c2 c |
 }
 instrumentTwo = \relative {
index 423889445fbf9500f73f166483fa9eddf3a8337e..cc63e375147ef87160c3405b809851533bc5ac9a 100644 (file)
@@ -7,7 +7,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.19.21"
+@c \version "2.19.29"
 
 @c Translation status: post-GDP
 
@@ -1036,29 +1036,29 @@ exclusivamente a la nota siguiente dentro de la expresión musical.
 
 @itemize
 @item
-@code{\partcombineApart} y @code{\partcombineApartOnce}
+@code{\partcombineApart} y @code{\once \partcombineApart}
 mantienen las notas como dos voces separadas incluso si se pueden
 combinar en un acorde o unísono.
 
 @item
-@code{\partcombineChords} y @code{\partcombineChordsOnce}
+@code{\partcombineChords} y @code{\once \partcombineChords}
 combinan las notas en un acorde.
 
 @item
-@code{\partcombineUnisono} y @code{\partcombineUnisonoOnce}
+@code{\partcombineUnisono} y @code{\once \partcombineUnisono}
 combinan las dos voces como unísono y marcan el resultado
 como @qq{unison}.
 
 @item
-@code{\partcombineSoloI} y @code{\partcombineSoloIOnce}
+@code{\partcombineSoloI} y @code{\once \partcombineSoloI}
 muestran solo la voz uno y la marcan como @qq{Solo}.
 
 @item
-@code{\partcombineSoloII} o @code{\partcombineSoloIIOnce}
+@code{\partcombineSoloII} o @code{\once \partcombineSoloII}
 imprimen solo la voz dos y la marcan como @qq{Solo}.
 
 @item
-@code{\partcombineAutomatic} y @code{\partcombineAutomaticOnce}
+@code{\partcombineAutomatic} y @code{\once \partcombineAutomatic}
 terminan el efecto de las instrucciones anteriores y retornan a la
 funcionalidad estándar de @code{\partcombine}.
 
@@ -1070,7 +1070,7 @@ instrumentOne = \relative c' {
   \partcombineAutomatic e2^"auto" e |
   \partcombineChords e'2^"chord" e |
   \partcombineAutomatic c2^"auto" c |
-  \partcombineApart c2^"apart" \partcombineChordsOnce e^"chord once" |
+  \partcombineApart c2^"apart" \once \partcombineChords e^"chord once" |
   c2 c |
 }
 instrumentTwo = \relative {
index 51996fa2b6919f5c3b8df693a023ec0cb2da7f7c..a5685adf1e6808949312920e225dc59170d3a614 100644 (file)
@@ -7,7 +7,7 @@
    Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.19.21"
+@c \version "2.19.29"
 
 @c Translators: Frédéric Chiasson, Valentin Villenave, Jean-Charles Malahieude
 @c Translation checkers: Jean-Charles Malahieude, John Mandereau
@@ -1082,28 +1082,28 @@ note qui les suit directement dans l'expression musicale.
 
 @itemize
 @item
-@code{\partcombineApart} et @code{\partcombineApartOnce} maintiennent
+@code{\partcombineApart} et @code{\once \partcombineApart} maintiennent
 les notes dans des voix séparées même si elles peuvent se combiner en
 accord ou en unisson.
 
 @item
-@code{\partcombineChords} et @code{\partcombineChordsOnce} combinent les
+@code{\partcombineChords} et @code{\once \partcombineChords} combinent les
 notes en accords.
 
 @item
-@code{\partcombineUnisono} et @code{\partcombineUnisonoOnce} combinent
+@code{\partcombineUnisono} et @code{\once \partcombineUnisono} combinent
 les voix en un « unisson ».
 
 @item
-@code{\partcombineSoloI} et @code{\partcombineSoloIOnce} affichent
+@code{\partcombineSoloI} et @code{\once \partcombineSoloI} affichent
 exclusivement la première voix et l'affublent d'un « Solo ».
 
 @item
-@code{\partcombineSoloII} et @code{\partcombineSoloIIOnce} affichent
+@code{\partcombineSoloII} et @code{\once \partcombineSoloII} affichent
 exclusivement la deuxième voix et l'affublent d'un « Solo ».
 
 @item
-@code{\partcombineAutomatic} et @code{\partcombineAutomaticOnce}
+@code{\partcombineAutomatic} et @code{\once \partcombineAutomatic}
 annulent les effets des dérogations précédentes et activent le
 comportement standard de la fonction @code{\partcombine}.
 @end itemize
@@ -1114,7 +1114,7 @@ instrumentOne = \relative c' {
   \partcombineAutomatic e2^"auto" e |
   \partcombineChords e'2^"chord" e |
   \partcombineAutomatic c2^"auto" c |
-  \partcombineApart c2^"apart" \partcombineChordsOnce e^"chord once" |
+  \partcombineApart c2^"apart" \once \partcombineChords e^"chord once" |
   c2 c |
 }
 instrumentTwo = \relative {
index bdee2dba58ab96aa6ccbf35cf677aa0c5280fbc6..7253087c70ef2588492cb7155dc6c0aa25abc1d1 100644 (file)
@@ -60,168 +60,519 @@ unsuccessful, though a workaround is available (see
 @node Requirements for running LilyPond
 @subsection Requirements for running LilyPond
 
-Running LilyPond requires proper installation of the following
-software:
+This section contains the list of separate software packages that are
+required to run LilyPond.
 
 @itemize
-@item @uref{http://www.dejavu-fonts.org/, DejaVu fonts} (normally
-installed by default)
 
-@item @uref{http://www.fontconfig.org/, FontConfig} (2.4.0 or newer)
+@item @uref{http://www.dejavu-fonts.org/, DejaVu fonts}
+These are normally installed by default.
 
-@item @uref{http://www.freetype.org/, Freetype} (2.1.10 or newer)
+@item
+@uref{http://www.fontconfig.org/, FontConfig}
+Use version 2.4.0 or newer.
+
+@item
+@uref{http://www.freetype.org/, Freetype}
+Use version 2.1.10 or newer.
 
-@item @uref{http://www.ghostscript.com, Ghostscript} (8.60 or
-newer)
+@item
+@uref{http://www.ghostscript.com, Ghostscript}
+Use version 8.60 or newer.
 
-@item @uref{http://www.gnu.org/software/guile/guile.html, Guile}
-(1.8.8 - version 2.x is not currently supported)
+@item
+@uref{http://www.gnu.org/software/guile/guile.html, Guile}
+Use version 1.8.8. Version 2.x of Guile is not currently supported.
 
-@item @uref{http://www.pango.org/, Pango} (1.12 or newer)
+@item
+@uref{http://www.pango.org/, Pango}
+User version 1.12 or newer.
 
-@item @uref{http://www.python.org, Python} (2.4 or newer)
-@end itemize
+@item
+@uref{http://www.python.org, Python}
+Use version 2.4 or newer.
+
+@item
+International fonts.  For example:
+
+Fedora:
+
+@example
+fonts-arabic
+fonts-hebrew
+fonts-ja
+fonts-xorg-truetype
+taipeifonts
+ttfonts-ja
+ttfonts-zh_CN
+@end example
 
-International fonts are required to create music with
-international text or lyrics.
+Debian based distributions:
+
+@example
+emacs-intl-fonts
+fonts-ipafont-gothic
+fonts-ipafont-mincho
+xfonts-bolkhov-75dpi
+xfonts-cronyx-75dpi
+xfonts-cronyx-100dpi
+xfonts-intl-.*
+@end example
+
+These are normally installed by default and are required only to create
+music with international text or lyrics.
+
+@end itemize
 
 
 @node Requirements for compiling LilyPond
 @subsection Requirements for compiling LilyPond
 
-Below is a full list of packages needed to build LilyPond.
-However, for most common distributions there is an easy way of
-installing most all build dependencies in one go:
+This section contains instructions on how to quickly and easily get all
+the software packages required to build LilyPond.
+
+Most of the more popular Linux distributions only require a few simple
+commands to download all the software needed.  For others, there is an
+explicit list of all the individual packages (as well as where to get
+them from) for those that are not already included in your
+distributions' own repositories.
+
+@ignore
+I have tested all of the following four Linux Distributions listed here
+Using a simple virtual machine and the appropriate ISO image file
+downloaded from each distribution's own website.  The instructions
+documented were run immediately after the initial installation
+(without any further additional configuration to the OS) and I made sure
+that I was able to run the full set of make, make test-baseline, make
+check and a full make doc. - James
+@end ignore
+
+@menu
+* Fedora::
+* Linux Mint::
+* OpenSUSE::
+* Ubuntu::
+* Other::
+@end menu
+
+
+@node Fedora
+@unnumberedsubsubsec Fedora
+
+The following instructions were tested on @q{Fedora 22} and include all
+the software to both compile LilyPond and build the documenation.
+
+@itemize
+
+@item
+Download and install all the LilyPond build-dependencies (approximately
+700MB);
+
+@example
+sudo dnf builddep lilypond --nogpgcheck
+@end example
+
+@item
+Download and install additional @q{build} tools required for compiling;
+
+@example
+sudo dnf install autoconf gcc-c++
+@end example
+
+@item
+Download @code{texi2html 1.82} directly from:
+@uref{http://download.savannah.gnu.org/releases/texi2html/texi2html-1.82.tar.gz};
+
+@code{texi2html} is only required if you intend to compile LilyPond's
+own documentation (e.g. to help with any document writing).  The version
+available in the Fedora repositories is too new and will not work.
+Extract the files into an appropriate location and then run the
+commands;
+
+@example
+./configure
+make
+sudo make install
+@end example
+
+This should install @code{texi2html 1.82} into @code{/usr/local/bin},
+which will normally take priority over @code{/usr/bin} where the
+later, pre-installed versions gets put.  Now verify that your operating
+system is able to see the correct version of @code{texi2html}.
+
+@example
+texi2html --version
+@end example
+
+@item
+Although not @q{required} to compile LilyPond, if you intend to
+contribute to LilyPond (codebase or help improve the documentation) then
+it is recommended that you also need to install @code{git}.
+
+@example
+sudo dnf install git
+@end example
+
+Also see @ruser{Starting with Git}.
+
+@item
+To use the @code{lily-git.tcl} GUI;
+
+@example
+sudo dnf install tk
+@end example
+
+See @ruser{lily-git}.
+
+@end itemize
 
-@multitable @columnfractions .5 .5
-@headitem Distribution @tab Command
-@item Debian, Ubuntu
-@tab @code{sudo apt-get build-dep lilypond}
 
-@item Fedora, RHEL
-@tab @code{sudo yum-builddep lilypond}
 
-@item openSUSE, SLED
-@c sorry for the idiosyncratic command, I really asked and argued
-@c for "zypper build-dep" :-(
-@tab @code{sudo zypper --build-deps-only source-install lilypond}
-@end multitable
+@node Linux Mint
+@unnumberedsubsubsec Linux Mint
+
+The following instructions were tested on @q{Linux Mint 17.1} and
+@q{LMDE - Betsy} and include all the software to both compile LilyPond
+and build the documenation.
 
 @itemize
-@item Everything listed in @ref{Requirements for running
-LilyPond}
 
-@item Development packages for the above items (which should
-include header files and libraries).
+@item
+Enable the @emph{sources} repository;
+
+@enumerate
+
+@item
+Using the @emph{Software Sources} GUI (located under
+@emph{Administration}).
 
-Red Hat Fedora:
+@item
+Select @emph{Official Repositories}.
+
+@item
+Check the @emph{Enable source code repositories} box under the
+@emph{Source Code} section.
+
+@item
+Click the @emph{Update the cache} button and when it has completed,
+close the @emph{Software Sources} GUI.
+
+@end enumerate
+
+@item
+Download and install all the LilyPond build-dependencies (approximately
+200MB);
 
-@c ghostscript-devel-[version] isn't needed
 @example
-guile-devel-@var{version}
-fontconfig-devel-@var{version}
-freetype-devel-@var{version}
-pango-devel-@var{version}
-python-devel-@var{version}
+sudo apt-get build-dep lilypond
 @end example
 
-Debian GNU/Linux:
+@item
+Download and install additional @q{build} tools required for compiling;
 
-@c libgs-dev isn't needed
 @example
-guile-@var{version}-dev
-libfontconfig1-dev
-libfreetype6-dev
-libpango1.0-dev
-python@var{version}-dev
+sudo apt-get install autoconf fonts-texgyre texlive-lang-cyrillic
 @end example
 
-@item @uref{http://flex.sourceforge.net/, Flex}
+@item
+Although not @q{required} to compile LilyPond, if you intend to
+contribute to LilyPond (codebase or help improve the documentation) then
+it is recommended that you also need to install @code{git}.
+
+@example
+sudo apt-get install git
+@end example
 
-@item @uref{http://fontforge.sf.net/, FontForge} (20060125 or
-newer; 20100501 or newer is recommended; must be compiled
-with @option{--enable-double}.  Failure to do so can lead to
-poor intersection calculations and poorly-rendered glyphs.)
+Also see @ruser{Starting with Git}.
 
-@item @uref{http://www.gnu.org/software/bison/, GNU Bison}
+@item
+To use the @code{lily-git.tcl} GUI;
 
-@item @uref{http://gcc.gnu.org/, GNU Compiler Collection} (3.4 or
-newer, 4.@var{x} recommended)
+@example
+sudo apt-get install tk
+@end example
 
-@item @uref{http://www.gnu.org/software/gettext/gettext.html, GNU
-gettext} (0.17 or newer)
+Also see @ruser{lily-git}.
+
+@end itemize
+
+
+@node OpenSUSE
+@unnumberedsubsubsec OpenSUSE
+
+The following instructions were tested on @q{OpenSUSE 13.2} and include
+all the software to both compile LilyPond and build the documenation.
+
+@itemize
 
-@item @uref{http://www.gnu.org/software/make/, GNU Make} (3.78 or
-newer)
+@item
+Add the @emph{sources} repository;
+
+@smallexample
+sudo zypper addrepo -f \
+"http://download.opensuse.org/source/distribution/13.2/repo/oss/" sources
+@end smallexample
+
+@item
+Download and install all the LilyPond build-dependencies (approximately
+680MB);
+
+@example
+sudo zypper source-install lilypond
+@end example
+
+@item
+Download and install additional @q{build} tools required for compiling;
+
+@example
+sudo zypper install make
+@end example
+
+@item
+Although not @q{required} to compile LilyPond, if you intend to
+contribute to LilyPond (codebase or help improve the documentation) then
+it is recommended that you also need to install @code{git}.
 
-@item @uref{http://metafont.tutorial.free.fr/, MetaFont}
-(mf-nowin, mf, mfw or mfont binaries), usually packaged with
+@example
+sudo apt-get install git
+@end example
+
+Also see @ruser{Starting with Git}.
+
+@item
+To use the @code{lily-git.tcl} GUI;
+
+@example
+sudo zypper install tk
+@end example
+
+Also see @ruser{lily-git}.
+
+@end itemize
+
+
+
+@node Ubuntu
+@unnumberedsubsubsec Ubuntu
+
+The following commands were tested on Ubuntu versions @code{14.04 LTS},
+@code{14.10} and @code{15.04} and include all the software to both
+compile LilyPond and build the documenation.
+
+@itemize
+
+@item
+Download and install all the LilyPond build-dependencies (approximately
+200MB);
+
+@example
+sudo apt-get build-dep lilypond
+@end example
+
+@item
+Download and install additional @q{build} tools required for compiling;
+
+@example
+sudo apt-get install autoconf fonts-texgyre texlive-land-cyrillic
+@end example
+
+@item
+Although not @q{required} to compile LilyPond, if you intend to
+contribute to LilyPond (codebase or help improve the documentation) then
+it is recommended that you also need to install @code{git}.
+
+@example
+sudo apt-get install git
+@end example
+
+Also see @ruser{Starting with Git}.
+
+@item
+To use the @code{lily-git.tcl} GUI;
+
+@example
+sudo apt-get install tk
+@end example
+
+Also see @ruser{lily-git}.
+
+@end itemize
+
+
+@node Other
+@unnumberedsubsubsec Other
+
+The following individual software packages are required just to compile
+LilyPond.
+
+@itemize
+
+@item
+@uref{http://www.gnu.org/software/autoconf, GNU Autoconf}
+
+@item
+@uref{http://www.gnu.org/software/bison/, GNU Bison}
+
+Use version @code{2.0} or newer.
+
+@item
+@uref{http://gcc.gnu.org/, GNU Compiler Collection}
+
+Use version @code{3.4} or newer (@code{4.x} recommended).
+
+@item
+@uref{http://flex.sourceforge.net/, Flex}
+
+@item
+@uref{http://fontforge.sf.net/, FontForge}
+
+Use version @code{20060125} or newer (we recommend using at least
+@code{20100501}); it must also be compiled with the
+@option{--enable-double} switch, else this can lead to inaccurate
+intersection calculations which end up with poorly-rendered glyphs in
+the output.
+
+@item
+@uref{http://www.gnu.org/software/gettext/gettext.html, GNU gettext}
+
+Use version @code{0.17} or newer.
+
+@item
+@uref{http://www.gnu.org/software/make/, GNU Make}
+
+Use version @code{3.78} or newer.
+
+@item
+@uref{http://metafont.tutorial.free.fr/, MetaFont}
+
+The @code{mf-nowin}, @code{mf}, @code{mfw} or @code{mfont} binaries are
+usually packaged along with
 @uref{http://www.latex-project.org/ftp.html, @TeX{}}.
 
-@item @uref{http://cm.bell-labs.com/who/hobby/MetaPost.html,
-MetaPost} (mpost binary), usually packaged with
+@item
+@uref{http://cm.bell-labs.com/who/hobby/MetaPost.html, MetaPost}
+
+The @code{mpost} binary is also usually packaged with
 @uref{http://www.latex-project.org/ftp.html, @TeX{}}.
 
-@item @uref{http://www.perl.org/, Perl}
+@item
+@uref{http://www.perl.org/, Perl}
 
-@item @uref{http://www.gnu.org/software/texinfo/, Texinfo} (4.11
-or newer)
+@item
+@uref{http://www.gnu.org/software/texinfo/, Texinfo}
+
+Use version @code{4.11} or newer.
+
+@item
+@uref{http://www.lcdf.org/~eddietwo/type/#t1utils, Type 1 utilities}
+
+Use version @code{1.33} or newer.
+
+@item
+@uref{https://www.ctan.org/pkg/cyrillic?lang=en, Cyrillic fonts}
+
+Often packaged in repositories as @code{texlive-lang-cyrillic}.
+
+@item
+TeX Gyre @q{OTF} font packages.  As of LilyPond version @code{2.19.26},
+the previous default serif, san serif and monospace fonts now use Tex
+Gyre's @emph{Schola}, @emph{Heros} and @emph{Cursor} fonts respectively.
+Also See @ruser{Fonts}.
+
+Some distributions do not always provide @q{OTF} font files in the Tex
+Gyre packages from their repositories.  Use the command
+@code{fc-list | grep texgyre} to list the fonts available to your system
+and check that the appropriate @code{*.otf} files are reported.  If they
+are not then download and manually extract the @q{OTF} files to either
+your local  @code{~/.fonts/} directory or use the
+@code{configure} command and the
+@code{--with-texgyre-dir=/path_to_otf_files/} option.
+
+The following font families are required:
+
+@uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/schola, Schola},
+@uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/heros, Heros}
+and
+@uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/cursor, Cursor}.
 
-@item @uref{http://www.lcdf.org/~eddietwo/type/#t1utils, Type 1
-utilities} (1.33 or newer recommended)
 @end itemize
 
 
+
 @node Requirements for building documentation
 @subsection Requirements for building documentation
 
-You can view the documentation online at
-@uref{http://www.lilypond.org/doc/}, but you can also build it
-locally.  This process requires some additional tools and
-packages:
+The entire set of documentation for the most current build of LilyPond
+is available online at
+@uref{http://lilypond.org/doc/v2.19/Documentation/web/development}, but
+you can also build them locally from the source code.  This process
+requires some additional tools and packages.
+
+@warning{If you have used the instructions for one of the Linux
+distributions explicitly listed in the previous section
+(@rcontrib{Requirements for compiling LilyPond}) then the following can
+be ignored as the software should already be installed.}
 
 @itemize
-@item Everything listed in @ref{Requirements for compiling
-LilyPond}
 
-@item @uref{http://www.imagemagick.org/, ImageMagick}
+@item
+Everything listed in @ref{Requirements for compiling LilyPond}
+
+@item
+@uref{http://www.imagemagick.org/, ImageMagick}
+
+@item
+@uref{http://netpbm.sourceforge.net/, Netpbm}
+
+@item
+@uref{http://gzip.org/, gzip}
 
-@item @uref{http://netpbm.sourceforge.net/, Netpbm}
+@item
+@uref{http://rsync.samba.org/, rsync}
 
-@item @uref{http://gzip.org/, gzip}
+@item
+@uref{http://www.nongnu.org/texi2html/, Texi2HTML}
 
-@item @uref{http://rsync.samba.org/, rsync}
+Use version @code{1.82}.  Later versions will not work.
 
-@item @uref{http://www.nongnu.org/texi2html/, Texi2HTML} (1.82)
+Download @code{texi2html 1.82} directly from:
+@uref{http://download.savannah.gnu.org/releases/texi2html/texi2html-1.82.tar.gz};
 
-@item International fonts
+Extract the files into an appropriate location and then run the
+commands;
 
-Red Hat Fedora:
+@example
+./configure
+make
+sudo make install
+@end example
+
+Now verify that your operating system is able to see the correct version
+of @code{texi2html}.
 
 @example
-fonts-arabic
-fonts-hebrew
-fonts-ja
-fonts-xorg-truetype
-taipeifonts
-ttfonts-ja
-ttfonts-zh_CN
+texi2html --version
 @end example
 
-Debian GNU/Linux:
+@item
+Fonts required to build the documentation in addition to those required
+to run LilyPond:
 
 @example
-emacs-intl-fonts
-ttf-kochi-gothic
-ttf-kochi-mincho
-xfonts-bolkhov-75dpi
-xfonts-cronyx-75dpi
-xfonts-cronyx-100dpi
-xfonts-intl-.*
+gsfonts
+fonts-linuxlibertine
+fonts-liberation
+fonts-dejavu
+fonts-freefont-otf
+ttf-bitstream-vera
+texlive-fonts-recommended
+ttf-xfree86-nonfree
 @end example
+
 @end itemize
 
 
+
 @node Getting the source code
 @section Getting the source code
 
@@ -922,20 +1273,6 @@ bug reports to @email{bug-lilypond@@gnu.org}.
 
 Bugs that are not fault of LilyPond are documented here.
 
-@unnumberedsubsec Bison 1.875
-
-There is a bug in bison-1.875: compilation fails with "parse error
-before `goto'" in line 4922 due to a bug in bison.  To fix, please
-recompile bison 1.875 with the following fix
-
-@example
-$ cd lily; make out/parser.cc
-$ vi +4919 out/parser.cc
-# append a semicolon to the line containing "__attribute__ ((__unused__))
-# save
-$ make
-@end example
-
 
 @unnumberedsubsec Compiling on MacOS@tie{}X
 
@@ -1044,7 +1381,7 @@ Red Hat Fedora
 Debian GNU/Linux
 
    apt-get install emacs-intl-fonts xfonts-intl-.* \
-        ttf-kochi-gothic ttf-kochi-mincho \
+        fonts-ipafont-gothic  fonts-ipafont-mincho \
         xfonts-bolkhov-75dpi xfonts-cronyx-100dpi xfonts-cronyx-75dpi
 @end verbatim
 
index 14646088e34547efb7ce089b4ebd42519aa7d0c9..e751b4244329c391a8cf0467ed60666f467cfa36 100644 (file)
@@ -7,7 +7,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.19.21"
+@c \version "2.19.29"
 
 @c Translators: Federico Bruni
 @c Translation checkers: Luca Rossetto Casel
@@ -1012,28 +1012,28 @@ nota successiva dell'espressione musicale.
 
 @itemize
 @item
-@code{\partcombineApart} e @code{\partcombineApartOnce} mantengono le
+@code{\partcombineApart} e @code{\once \partcombineApart} mantengono le
 note su due voci distinte, anche se potrebbero essere combinate in un
 accordo o in un unisono.
 
 @item
-@code{\partcombineChords} e @code{\partcombineChordsOnce} uniscono le
+@code{\partcombineChords} e @code{\once \partcombineChords} uniscono le
 note in un accordo.
 
 @item
-@code{\partcombineUnisono} e @code{\partcombineUnisonoOnce} uniscono
+@code{\partcombineUnisono} e @code{\once \partcombineUnisono} uniscono
 entrambe le voci come @qq{unisono}.
 
 @item
-@code{\partcombineSoloI} e @code{\partcombineSoloIOnce} stampano soltanto
+@code{\partcombineSoloI} e @code{\once \partcombineSoloI} stampano soltanto
 la prima voce e la contrassegnano come un @qq{Solo}.
 
 @item
-@code{\partcombineSoloII} o @code{\partcombineSoloIIOnce} stampano soltanto
+@code{\partcombineSoloII} o @code{\once \partcombineSoloII} stampano soltanto
 la seconda voce e la contrassegnano come un @qq{Solo}.
 
 @item
-@code{\partcombineAutomatic} e @code{\partcombineAutomaticOnce} terminano
+@code{\partcombineAutomatic} e @code{\once \partcombineAutomatic} terminano
 le funzioni dei comandi precedenti e ripristinano il funzionamento
 predefinito di @code{\partcombine}.
 @end itemize
@@ -1044,7 +1044,7 @@ instrumentOne = \relative c' {
   \partcombineAutomatic e2^"automatico" e |
   \partcombineChords e'2^"accordo" e |
   \partcombineAutomatic c2^"automatico" c |
-  \partcombineApart c2^"separato" \partcombineChordsOnce e^"accordo una volta sola" |
+  \partcombineApart c2^"separato" \once \partcombineChords e^"accordo una volta sola" |
   c2 c |
 }
 instrumentTwo = \relative {
index daf15086fc151e874c1984057c29168fff95bfa7..b15c17a18ed1d9b7b5f3c77e20cb06f959bb279b 100644 (file)
@@ -6,7 +6,7 @@
     version that you are working on.  See TRANSLATION for details.
 @end ignore
 
-@c \version "2.19.21"
+@c \version "2.19.29"
 
 
 @c Translators: Yoshiki Sawada
@@ -1032,28 +1032,28 @@ instrumentTwo = \relative {
 
 @itemize
 @item
-@code{\partcombineApart} と @code{\partcombineApartOnce} は@c
+@code{\partcombineApart} と @code{\once \partcombineApart} は@c
 音符を 2 つの別個のボイスとして譜刻します
 -- たとえ和音やユニゾンにできる場合であっても分けて譜刻します。
 
 @item
-@code{\partcombineChords} と @code{\partcombineChordsOnce} は@c
+@code{\partcombineChords} と @code{\once \partcombineChords} は@c
 音符を組み合わせて、和音として譜刻します。
 
 @item
-@code{\partcombineUnisono} と @code{\partcombineUnisonoOnce} は@c
+@code{\partcombineUnisono} と @code{\once \partcombineUnisono} は@c
 音符を組み合わせて、@qq{ユニゾン} として譜刻します。
 
 @item
-@code{\partcombineSoloI} と @code{\partcombineSoloIOnce} は@c
+@code{\partcombineSoloI} と @code{\once \partcombineSoloI} は@c
 ボイス 1 だけを譜刻して、@qq{Solo} のマークを付けます。
 
 @item
-@code{\partcombineSoloII} と @code{\partcombineSoloIIOnce} は@c
+@code{\partcombineSoloII} と @code{\once \partcombineSoloII} は@c
 ボイス 2 だけを譜刻して、@qq{Solo} のマークを付けます。
 
 @item
-@code{\partcombineAutomatic} と @code{\partcombineAutomaticOnce}は@c
+@code{\partcombineAutomatic} と @code{\once \partcombineAutomatic}は@c
 上記のコマンドの効果を終わらせ、標準の @code{\partcombine} に戻します。
 @end itemize
 
@@ -1063,7 +1063,7 @@ instrumentOne = \relative c' {
   \partcombineAutomatic e2^"auto" e |
   \partcombineChords e'2^"chord" e |
   \partcombineAutomatic c2^"auto" c |
-  \partcombineApart c2^"apart" \partcombineChordsOnce e^"chord once" |
+  \partcombineApart c2^"apart" \once \partcombineChords e^"chord once" |
   c2 c |
 }
 instrumentTwo = \relative {
index e5b3a652a34487e14ddc15a0afc78f35ef5b9f8c..9ce651fc02c13e40cff9363c6f5ab49317c934d8 100644 (file)
@@ -334,9 +334,8 @@ starting note and ending note are marked with @code{(} and
 Music Glossary: @rglos{slur}, @rglos{phrasing}.
 
 Slurs to indicate longer @notation{phrasing} can be entered with
-@code{\(} and @code{\)}.  You can have both @notation{slurs}
-and phrasing slurs at the same time, but you cannot have
-simultaneous slurs or simultaneous phrasing slurs.
+@code{\(} and @code{\)}.  You can have both @notation{slurs} and
+phrasing slurs at the same time.
 
 @lilypond[verbatim,quote]
 \relative { g'4\( g8( a) b( c) b4\) }
index 0588a3fa480861ce3032986c17ac924aa31f73bf..96d0a75356e6867eb2f175004b369bed00664501 100644 (file)
@@ -316,7 +316,7 @@ and @code{\revert} commands:
 \magnifyMusic @var{mag} @{
   \newSpacingSection
   \override Score.SpacingSpanner.spacing-increment = #(* 1.2 @var{mag})
-  @var{[music]}
+  [@var{music}]
   \newSpacingSection
   \revert Score.SpacingSpanner.spacing-increment
 @}
index 52259c6c95abf2e223d03929e0b07fc828f5cf52..f999363cb4d69e9da17b000f7d2b135164addd13 100644 (file)
@@ -714,10 +714,20 @@ Slurs may be manually placed above or below the staff; see
 @cindex slur, phrasing
 @cindex slurs, multiple
 @cindex slurs, simultaneous
+@funindex \=
 
-Simultaneous or overlapping slurs are not permitted, but a phrasing
-slur can overlap a slur.  This permits two slurs to be printed at
-once.  For details, see @ref{Phrasing slurs}.
+Simultaneous or overlapping slurs require special attention.  Most
+occurences of outer slurs actually indicate phrasing, and phrasing
+slurs may overlap a regular slur, see @ref{Phrasing slurs}.  When
+multiple regular slurs are needed in a single @code{Voice},
+matching slur starts and ends need to be labelled by preceding
+them with @code{\=} followed by an identifying number or string.
+
+@lilypond[verbatim,quote]
+\fixed c' {
+  <c~ f\=1( g\=2( >2 <c e\=1) a\=2) >
+}
+@end lilypond
 
 @cindex slur style
 @cindex slur, solid
@@ -878,7 +888,8 @@ may be manually placed above or below the staff; see
 @cindex phrasing slur, simultaneous
 @cindex phrasing slur, multiple
 
-Simultaneous or overlapping phrasing slurs are not permitted.
+Simultaneous or overlapping phrasing slurs are entered using
+@code{\=} as with regular slurs, see @ref{Slurs}.
 
 @funindex phrasingSlurDashed
 @funindex \phrasingSlurDashed
index a5b04b4b2414171179a2ab7b155a8c894a6ab906..485a75212d0dbad1881d8317e366e9647be943cc 100644 (file)
@@ -521,12 +521,17 @@ Notation Reference:
 @node Titles and headers
 @section Titles and headers
 
+@cindex titles
+@cindex headers
+@cindex footers
+
 Almost all printed music includes a title and the composer's name;
 some pieces include a lot more information.
 
 @menu
 * Creating titles headers and footers::
 * Custom titles headers and footers::
+* Creating PDF metadata::
 * Creating footnotes::
 * Reference to page numbers::
 * Table of contents::
@@ -723,7 +728,7 @@ Notation Reference:
 @node Default layout of bookpart and score titles
 @unnumberedsubsubsec Default layout of bookpart and score titles
 
-This example demonstrates all @code{\header} variables:
+This example demonstrates all printed @code{\header} variables:
 
 @lilypond[papersize=a6landscape,quote,verbatim,noragged-right]
 \book {
@@ -1194,6 +1199,44 @@ Notation Reference:
 Installed Files:
 @file{../ly/titling-init.ly}.
 
+@node Creating PDF metadata
+@subsection Creating PDF metadata
+
+@cindex PDF metadata
+
+In addition to being shown in the printed output, @code{\header} variables
+are also used to set PDF metadata (the information displayed by PDF readers
+as the @code{properties} of the PDF file).  For example, setting the
+@code{title} property of the @code{header} block @q{Symphony I} will also give
+this title to the PDF document.
+
+@example
+  @code{\header@{}
+    @code{title = "Symphony I"}
+  @code{@}}
+@end example
+
+If you want to set the title of the printed output to one value, but have the
+title property of the PDF to have a different value, you can use
+@code{pdftitle}, as below.
+
+@example
+  @code{\header@{}
+    @code{title = "Symphony I"}
+    @code{pdftitle = "Symphony I by Beethoven"}
+  @code{@}}
+@end example
+
+The variables @code{title}, @code{subject}, @code{keywords},
+@code{subtitle}, @code{composer}, @code{arranger}, @code{poet}, @code{author}
+and @code{copyright} all set PDF properties and can all be prefixed with
+@q{pdf} to set a PDF property to a value different from the printed output.
+
+The PDF property @code{Creator} is automatically set to @q{LilyPond} plus
+the current LilyPond version, and @code{CreationDate} and @code{ModDate} are
+both set to the current date and time.  @code{ModDate} can be overridden by
+setting the header variable @code{moddate} (or @code{pdfmoddate}) to a
+valid PDF date string.
 
 @node Creating footnotes
 @subsection Creating footnotes
index 68f5cb717967868e317e9a87f9d2dcc47f2859a0..241daf752fafcd6a0ec6e8aaa068190a9d077f49 100644 (file)
@@ -2352,7 +2352,6 @@ or in the source code.
 * parser::
 * parser variable::
 * prob::
-* simple closure::
 * smob::
 * stencil::
 @end menu
@@ -2389,7 +2388,6 @@ performed.
 @unnumberedsubsec closure
 
 @cindex closure
-@cindex simple closure
 
 In Scheme, a @strong{closure} is created when a function, usually
 a lambda expression, is passed as a variable.  The closure contains
@@ -2402,13 +2400,6 @@ variables to be used in the calculation.  One useful property of
 closures is the retention of internal variable values between
 invocations, so permitting state to be maintained.
 
-A @strong{simple closure} is a closure whose expression has no free
-variables and hence no free variable bindings.
-
-A simple closure is represented in LilyPond by a smob containing
-the expression and a method to apply the expression to a passed
-list of arguments.
-
 
 @node glyph
 @unnumberedsubsec glyph
@@ -2629,12 +2620,6 @@ to hold the formatted content of system grobs and titling blocks
 during page layout.
 
 
-@node simple closure
-@unnumberedsubsec simple closure
-
-See @ref{closure}.
-
-
 @node smob
 @unnumberedsubsec smob
 
index 8caaaff7e17e67fd8d03b52c38ad0af13cab257a..c96837e5224cb5593e6f6ef281bf8ebe44d10a3d 100644 (file)
@@ -7,7 +7,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.19.21"
+@c \version "2.19.29"
 
 
 @node Simultaneous notes
@@ -77,9 +77,11 @@ and ornamentation.
 }
 @end lilypond
 
-However some notation, such as dynamics, hairpins and slurs must be
-attached to the chord, rather than notes within the chord, otherwise
-they will not print.
+However some notation, such as dynamics and hairpins must be
+attached to the chord rather than to notes within the chord,
+otherwise they will not print.  Other notation like fingerings and
+slurs will get placed markedly different when attached to notes
+within a chord rather than to whole chords or single notes.
 
 @lilypond[verbatim,quote]
 \relative {
@@ -1033,28 +1035,28 @@ music expression.
 
 @itemize
 @item
-@code{\partcombineApart} and @code{\partcombineApartOnce} keep the
+@code{\partcombineApart} and @code{\once \partcombineApart} keep the
 notes as two separate voices, even if they can be combined into a chord
 or unison.
 
 @item
-@code{\partcombineChords} and @code{\partcombineChordsOnce} combine the
+@code{\partcombineChords} and @code{\once \partcombineChords} combine the
 notes into a chord.
 
 @item
-@code{\partcombineUnisono} and @code{\partcombineUnisonoOnce} combine
+@code{\partcombineUnisono} and @code{\once \partcombineUnisono} combine
 both voices as @qq{unison}.
 
 @item
-@code{\partcombineSoloI} and @code{\partcombineSoloIOnce} print only
+@code{\partcombineSoloI} and @code{\once \partcombineSoloI} print only
 voice one, and mark it as a @qq{Solo}.
 
 @item
-@code{\partcombineSoloII} or @code{\partcombineSoloIIOnce} print only
+@code{\partcombineSoloII} or @code{\once \partcombineSoloII} print only
 voice two and mark it as a @qq{Solo}.
 
 @item
-@code{\partcombineAutomatic} and @code{\partcombineAutomaticOnce} end
+@code{\partcombineAutomatic} and @code{\once \partcombineAutomatic} end
 the functions of the commands above, and revert back to the standard
 @code{\partcombine} functionality.
 @end itemize
@@ -1065,7 +1067,7 @@ instrumentOne = \relative c' {
   \partcombineAutomatic e2^"auto" e |
   \partcombineChords e'2^"chord" e |
   \partcombineAutomatic c2^"auto" c |
-  \partcombineApart c2^"apart" \partcombineChordsOnce e^"chord once" |
+  \partcombineApart c2^"apart" \once \partcombineChords e^"chord once" |
   c2 c |
 }
 instrumentTwo = \relative {
index 4cbd84bc389e00a07c9f9716dd021b1cfa16a961..ee9ada70d3de7e96df0db4e37a0fea79676fff41 100644 (file)
@@ -9,10 +9,10 @@
 @c used for news about the upcoming release; see CG 10.2
 
 @newsItem
-@subheading LilyPond 2.19.27 released  @emph{September 12, 2015}
+@subheading LilyPond 2.19.29 released  @emph{October 18, 2015}
 
 We are happy to announce the release of LilyPond
-2.19.27.  This release includes a number of enhancements, and contains some
+2.19.29.  This release includes a number of enhancements, and contains some
 work in progress.  You will have access to the very latest features, but
 some may be incomplete, and you may encounter bugs and crashes.  If you
 require a stable version of Lilypond, we recommend using the 2.18
index 048ebc78dbb360d9fb3130101240156b53e05784..92c7373a6288cd7c2500ac2b91c80bdd5957ed9d 100644 (file)
@@ -26,6 +26,30 @@ NOTE:
   * don't duplicate entries from news-front.itexi
 @end ignore
 
+@newsItem
+@subheading LilyPond 2.19.28 released  @emph{September 27, 2015}
+
+We are happy to announce the release of LilyPond
+2.19.28.  This release includes a number of enhancements, and contains some
+work in progress.  You will have access to the very latest features, but
+some may be incomplete, and you may encounter bugs and crashes.  If you
+require a stable version of Lilypond, we recommend using the 2.18
+version.
+
+@newsEnd
+
+@newsItem
+@subheading LilyPond 2.19.27 released  @emph{September 12, 2015}
+
+We are happy to announce the release of LilyPond
+2.19.27.  This release includes a number of enhancements, and contains some
+work in progress.  You will have access to the very latest features, but
+some may be incomplete, and you may encounter bugs and crashes.  If you
+require a stable version of Lilypond, we recommend using the 2.18
+version.
+
+@newsEnd
+
 @newsItem
 @subheading LilyPond 2.19.26 released  @emph{August 27, 2015}
 
diff --git a/VERSION b/VERSION
index fa6df29e42320131ed9ac83f20a0d0a5f9058da7..37842d14c81ce2f06593891f3f92153956d34f9c 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
 MINOR_VERSION=19
-PATCH_LEVEL=28
+PATCH_LEVEL=30
 MY_PATCH_LEVEL=
 VERSION_STABLE=2.18.2
-VERSION_DEVEL=2.19.27
+VERSION_DEVEL=2.19.29
index 98b9401150d01844c71b405f42f8cc627ae5a29a..0bf05408e2075240253a54efb23876dc2d3ff236 100644 (file)
@@ -432,16 +432,16 @@ in LilyPond-include-path."
 (defcustom LilyPond-command-alist
   ;; Should expand this to include possible keyboard shortcuts which
   ;; could then be mapped to define-key and menu.
-  `(
-    ("LilyPond" . (,(concat LilyPond-lilypond-command " %s") "%s" "%l" "View"))
-    ("2PS" . (,(concat LilyPond-lilypond-command " -f ps %s") "%s" "%p" "ViewPS"))
+  '(
+    ("LilyPond" . ((LilyPond-lilypond-command " %s") "%s" "%l" "View"))
+    ("2PS" . ((LilyPond-lilypond-command " -f ps %s") "%s" "%p" "ViewPS"))
     ("Book" . ("lilypond-book %x" "%x" "%l" "LaTeX"))
     ("LaTeX" . ("latex '\\nonstopmode\\input %l'" "%l" "%d" "ViewDVI"))
 
     ;; refreshes when kicked USR1
-    ("View" . (,(concat LilyPond-pdf-command " %f")))
-    ("ViewPDF" . (,(concat LilyPond-pdf-command " %f")))
-    ("ViewPS" . (,(concat LilyPond-ps-command " %p")))
+    ("View" . ((LilyPond-pdf-command " %f")))
+    ("ViewPDF" . ((LilyPond-pdf-command " %f")))
+    ("ViewPS" . ((LilyPond-ps-command " %p")))
 
     ;; The following are refreshed in LilyPond-command:
     ;; - current-midi depends on cursor position and
@@ -616,24 +616,35 @@ Must be the car of an entry in `LilyPond-command-alist'."
   (LilyPond-command-select-buffer)
   (LilyPond-command-region (point-min) (point-max)))
 
-(defun LilyPond-command-expand (string file)
-  (let ((case-fold-search nil))
-    (if (string-match "%" string)
-       (let* ((b (match-beginning 0))
-              (e (+ b 2))
-              (l (split-file-name file))
-              (dir (car l))
-              (base (cadr l)))
-         (concat (substring string 0 b)
-                 (shell-quote-argument (concat dir base))
-                 (LilyPond-command-expand
-                  (concat
-                   (let ((entry (assoc (substring string b e)
-                                       LilyPond-expand-alist)))
-                     (if entry (cdr entry) ""))
-                   (substring string e))
-                  file)))
-      string)))
+(defun LilyPond-command-expand (arg file)
+  (cond
+   ((listp arg)
+    (mapconcat (lambda (arg) (LilyPond-command-expand arg file))
+              arg
+              ""))
+   ((and (symbolp arg) (boundp arg)
+        ;; Avoid self-quoting symbols
+        (not (eq (symbol-value arg) arg)))
+    (LilyPond-command-expand (symbol-value arg) file))
+   ((stringp arg)
+    (let ((case-fold-search nil))
+      (if (string-match "%" arg)
+         (let* ((b (match-beginning 0))
+                (e (+ b 2))
+                (l (split-file-name file))
+                (dir (car l))
+                (base (cadr l)))
+           (concat (substring arg 0 b)
+                   (shell-quote-argument (concat dir base))
+                   (LilyPond-command-expand
+                    (concat
+                     (let ((entry (assoc (substring arg b e)
+                                         LilyPond-expand-alist)))
+                       (if entry (cdr entry) ""))
+                     (substring arg e))
+                    file)))
+       arg)))
+   (t (error "Bad expansion `%S'" arg))))
 
 (defun LilyPond-shell-process (name buffer command)
   (let ((old (current-buffer)))
index ab59c20888b19a1428d2a7816069318fd6b97d4a..465042786d441222825413f69fe0a076dbd661f6 100644 (file)
@@ -8,19 +8,19 @@
 
 \layout { ragged-right = ##t }
 
-\version "2.19.21"
+\version "2.19.29"
 
 mI = \relative {
-       e'4 e \partcombineApartOnce c c |
-       \partcombineApart c \partcombineChordsOnce e e e |
-       c \partcombineUnisonoOnce c c c |
-       \partcombineAutomatic \partcombineSoloIOnce r2 c4 c |
-       \partcombineSoloIIOnce R1 |
-       d'2 \partcombineChordsOnce d4^"1 chord" d|
+       e'4 e \once \partcombineApart c c |
+       \partcombineApart c \once \partcombineChords e e e |
+       c \once \partcombineUnisono c c c |
+       \partcombineAutomatic \once \partcombineSoloI r2 c4 c |
+       \once \partcombineSoloII R1 |
+       d'2 \once \partcombineChords d4^"1 chord" d|
 }
 mII = \relative {
-       c'4 \partcombineApartOnce c c c |
-       c c \partcombineAutomaticOnce e e |
+       c'4 \once \partcombineApart c c c |
+       c c \once \partcombineAutomatic e e |
        c c c c |
        R1 |
        r2 c4 c |
index fda6838ce690207dfcb2e291dabeb6861218353c..4a41ae3104741ba48247e38a29da9b0d3a74dd34 100644 (file)
@@ -1,14 +1,14 @@
 
 \header {
   texidoc ="Overrides for the part-combiner. All functions like
-  @code{\\partcombineApart} and @code{\\partcombineApartOnce} are internally implemented
-  using a dedicated @code{PartCombineForceEvent}.
-"
+  @code{\\partcombineApart} and @code{\\once \partcombineApart} are
+  internally implemented using a dedicated @code{partCombineForced}
+  context property."
 }
 
 \layout { ragged-right = ##t }
 
-\version "2.19.21"
+\version "2.19.29"
 
 mI = \relative {
        e'4 e c2 |
index 08487af5d9386df8b3381b87d4ed34d10f65235f..adf8221845b9a8077eca0c446bb161607f51aee3 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.19.22"
+\version "2.19.29"
 
 #(ly:set-option 'warning-as-error #f)
 #(ly:expect-warning (_ "already have phrasing slur"))
@@ -12,14 +12,10 @@ slur will not be generated.  However, one can can create a second slur with
 a different spanner-id."
 }
 
-sp=#(define-event-function (n e) (index? ly:event?)
-     (set! (ly:music-property e 'spanner-id) (format "sp~a" n))
-     e)
-
 \relative { 
   % This will give warnings ("Already have phrasing slur" and "Cannot end phrasing slur")
-  c''4\(\(\sp1\( d4\)\(\sp1\( e4\) f\) |
+  c''4\(\(\=1\( d4\)\(\=1\( e4\) f\) |
   % This will give two overlapping slurs and "unterminated phrasing slur" from above
-  d\(  d\sp2\( e\) f\sp2\) |
+  d\(  d\=2\( e\) f\=2\) |
   
 }
index a5e8b38c6061885d878f8fa49eb7a222b1adef94..007b69773ec293a7d30af9d6043bda472b3fde3b 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.19.22"
+\version "2.19.29"
 
 #(ly:set-option 'warning-as-error #f)
 #(ly:expect-warning (_ "already have slur"))
@@ -12,14 +12,10 @@ slur will not be generated.  However, one can can create a second slur with
 a different spanner-id."
 }
 
-sp=#(define-event-function (n e) (index? ly:event?)
-     (set! (ly:music-property e 'spanner-id) (format "sp~a" n))
-     e)
-
 \relative { 
   % This will give warnings ("Already have slur" and "Cannot end slur")
-  c''4((\sp1( d4)(\sp1( e4) f) |
+  c''4((\=1( d4)(\=1( e4) f) |
   % This will give two overlapping slurs and "unterminated slur" from above
-  d(  d\sp2( e) f\sp2) |
+  d(  d\=2( e) f\=2) |
   
 }
index ca3703369a98ab091a242765ec2b7c5e0a055208..ab4f2a4ce4e3a09651b674a8f9598e2cdd6699f5 100644 (file)
@@ -43,15 +43,15 @@ All_font_metrics::get_index_to_charcode_map (const string &filename,
 All_font_metrics::All_font_metrics (const string &path)
 {
 #if HAVE_PANGO_FT2
-  pango_dict_ = new Scheme_hash_table;
+  pango_dict_ = 0;
 #endif
 
-  otf_dict_ = new Scheme_hash_table;
+  otf_dict_ = 0;
   smobify_self ();
-  otf_dict_->unprotect ();
+  otf_dict_ = unsmob<Scheme_hash_table> (Scheme_hash_table::make_smob ());
 
 #if HAVE_PANGO_FT2
-  pango_dict_->unprotect ();
+  pango_dict_ = unsmob<Scheme_hash_table> (Scheme_hash_table::make_smob ());
   PangoFontMap *pfm = pango_ft2_font_map_new ();
 
   pango_ft2_fontmap_ = PANGO_FT2_FONT_MAP (pfm);
index 87bfbc5b9d842d9fe0771da958b0054c85e4a4d4..534fced49aacc813db06a76a0d63c4768516fc14 100644 (file)
@@ -24,7 +24,6 @@
 #include "international.hh"
 #include "item.hh"
 #include "main.hh"
-#include "simple-closure.hh"
 #include "smobs.hh"
 #include "spanner.hh"
 #include "unpure-pure-container.hh"
@@ -59,7 +58,6 @@ typecheck_grob (SCM symbol, SCM value)
     return typecheck_grob (symbol, upc->unpure_part ())
       && typecheck_grob (symbol, upc->pure_part ());
   return ly_is_procedure (value)
-    || unsmob<Simple_closure> (value)
     || type_check_assignment (symbol, value, ly_symbol2scm ("backend-type?"));
 }
 
index ef6fecf4b1aa123e566d858c4a576f2c3f45951e..a6b1da6a3609787625c7546905cf61a2935d6bf2 100644 (file)
@@ -90,8 +90,7 @@ Context::Context ()
 
   smobify_self ();
 
-  Scheme_hash_table *tab = new Scheme_hash_table;
-  properties_scm_ = tab->unprotect ();
+  properties_scm_ = Scheme_hash_table::make_smob ();
   event_source_ = new Dispatcher ();
   event_source_->unprotect ();
   events_below_ = new Dispatcher ();
index 978cbeb76cdd471ef973bfa2a016994aa7f3a2a5..bfafd4c9822e3a7c3f459bfd3c6f9a1ca54d246a 100644 (file)
@@ -1,5 +1,4 @@
 #include "grob.hh"
-#include "simple-closure.hh"
 #include "unpure-pure-container.hh"
 #include "lily-imports.hh"
 
@@ -31,25 +30,9 @@ axis_parent_positioning (Axis a)
 void
 add_offset_callback (Grob *g, SCM proc, Axis a)
 {
-  SCM data = g->get_property_data (axis_offset_symbol (a));
-  if (!scm_is_number (data)
-      && !ly_is_procedure (data)
-      && !unsmob<Simple_closure> (data))
-    {
-      g->set_property (axis_offset_symbol (a), proc);
-      return;
-    }
-
-  if (ly_is_procedure (data) || unsmob<Unpure_pure_container> (data))
-    data = Simple_closure::make_smob (scm_list_1 (data));
-  else if (Simple_closure *sc = unsmob<Simple_closure> (data))
-    data = sc->expression ();
-
-  if (ly_is_procedure (proc))
-    proc = Simple_closure::make_smob (scm_list_1 (proc));
-
-  SCM expr = scm_list_3 (Guile_user::plus, proc, data);
-  g->set_property (axis_offset_symbol (a), Simple_closure::make_smob (expr));
+  SCM sym = axis_offset_symbol (a);
+  SCM data = g->get_property_data (sym);
+  g->set_property (sym, Lily::grob_offset_function (proc, data));
 }
 
 /*
@@ -65,25 +48,7 @@ void
 chain_callback (Grob *g, SCM proc, SCM sym)
 {
   SCM data = g->get_property_data (sym);
-
-  if (ly_is_procedure (data) || unsmob<Unpure_pure_container> (data))
-    data = Simple_closure::make_smob (scm_list_1 (data));
-  else if (Simple_closure *sc = unsmob<Simple_closure> (data))
-    data = sc->expression ();
-  else
-    /*
-      Data may be nonnumber. In that case, it is assumed to be
-      undefined.
-    */
-
-    data = SCM_UNDEFINED;
-
-  SCM expr = scm_list_2 (proc, data);
-  g->set_property (sym,
-
-                   // twice: one as a wrapper for grob property routines,
-                   // once for the actual delayed binding.
-                   Simple_closure::make_smob (Simple_closure::make_smob (expr)));
+  g->set_property (sym, Lily::grob_compose_function (proc, data));
 }
 
 void
index e21ccf479d32e5f337cd37abd6a6fd0ed1771a47..5842662757b4650bba19c7fd5f68f5fd8f0dbe97 100644 (file)
@@ -15,7 +15,6 @@
 #include "item.hh"
 #include "program-option.hh"
 #include "profile.hh"
-#include "simple-closure.hh"
 #include "unpure-pure-container.hh"
 #include "warn.hh"
 #include "protected-scm.hh"
@@ -121,7 +120,6 @@ Grob::internal_set_value_on_alist (SCM *alist, SCM sym, SCM v)
   if (do_internal_type_checking_global)
     {
       if (!ly_is_procedure (v)
-          && !unsmob<Simple_closure> (v)
           && !unsmob<Unpure_pure_container> (v)
           && !scm_is_eq (v, ly_symbol2scm ("calculation-in-progress")))
         type_check_assignment (sym, v, ly_symbol2scm ("backend-type?"));
@@ -149,7 +147,7 @@ Grob::internal_get_property_data (SCM sym) const
   if (do_internal_type_checking_global && scm_is_pair (handle))
     {
       SCM val = scm_cdr (handle);
-      if (!ly_is_procedure (val) && !unsmob<Simple_closure> (val)
+      if (!ly_is_procedure (val)
           && !unsmob<Unpure_pure_container> (val))
         type_check_assignment (sym, val, ly_symbol2scm ("backend-type?"));
 
@@ -181,8 +179,7 @@ Grob::internal_get_property (SCM sym) const
   if (Unpure_pure_container *upc = unsmob<Unpure_pure_container> (val))
     val = upc->unpure_part ();
 
-  if (ly_is_procedure (val)
-      || unsmob<Simple_closure> (val))
+  if (ly_is_procedure (val))
     {
       Grob *me = ((Grob *)this);
       val = me->try_callback_on_alist (&me->mutable_property_alist_, sym, val);
@@ -207,10 +204,6 @@ Grob::internal_get_pure_property (SCM sym, int start, int end) const
       return call_pure_function (val, scm_list_1 (self_scm ()), start, end);
   }
 
-  if (Simple_closure *sc = unsmob<Simple_closure> (val))
-    return evaluate_with_simple_closure (self_scm (),
-                                         sc->expression (),
-                                         true, start, end);
   return val;
 }
 
@@ -238,12 +231,6 @@ Grob::try_callback_on_alist (SCM *alist, SCM sym, SCM proc)
   SCM value = SCM_EOL;
   if (ly_is_procedure (proc))
     value = scm_call_1 (proc, self_scm ());
-  else if (Simple_closure *sc = unsmob<Simple_closure> (proc))
-    {
-      value = evaluate_with_simple_closure (self_scm (),
-                                            sc->expression (),
-                                            false, 0, 0);
-    }
 
 #ifdef DEBUG
   if (debug_property_callbacks)
@@ -302,7 +289,6 @@ Grob::internal_get_object (SCM sym) const
     {
       SCM val = scm_cdr (s);
       if (ly_is_procedure (val)
-          || unsmob<Simple_closure> (val)
           || unsmob<Unpure_pure_container> (val))
         {
           Grob *me = ((Grob *)this);
@@ -328,37 +314,34 @@ Grob::internal_has_interface (SCM k)
 }
 
 SCM
-call_pure_function (SCM unpure, SCM args, int start, int end)
+call_pure_function (SCM value, SCM args, int start, int end)
 {
-  if (Unpure_pure_container *upc = unsmob<Unpure_pure_container> (unpure))
+  if (Unpure_pure_container *upc = unsmob<Unpure_pure_container> (value))
     {
-      SCM pure = upc->pure_part ();
-
-      if (Simple_closure *sc = unsmob<Simple_closure> (pure))
+      if (upc->is_unchanging ())
         {
-          SCM expr = sc->expression ();
-          return evaluate_with_simple_closure (scm_car (args), expr, true, start, end);
+          // Don't bother forming an Unpure_pure_call here.
+          value = upc->unpure_part ();
+
+          if (ly_is_procedure (value))
+            return scm_apply_0 (value, args);
+          return value;
         }
 
-      if (ly_is_procedure (pure))
-        return scm_apply_0 (pure,
-                            scm_append (scm_list_2 (scm_list_3 (scm_car (args),
-                                                                scm_from_int (start),
-                                                                scm_from_int (end)),
-                                                    scm_cdr (args))));
+      value = upc->pure_part ();
 
-      return pure;
-    }
+      if (ly_is_procedure (value))
+        return scm_apply_3 (value,
+                            scm_car (args),
+                            scm_from_int (start),
+                            scm_from_int (end),
+                            scm_cdr (args));
 
-  if (Simple_closure *sc = unsmob<Simple_closure> (unpure))
-    {
-      SCM expr = sc->expression ();
-      return evaluate_with_simple_closure (scm_car (args), expr, true, start, end);
+      return value;
     }
 
-  if (!ly_is_procedure (unpure))
-    return unpure;
+  if (!ly_is_procedure (value))
+    return value;
 
   return SCM_BOOL_F;
 }
-
index 0924b0a58dab8699abde6cc5b2c87b104f86a6a5..1a316b7ae1e3a49a41e80a6bc15bc740e693c68f 100644 (file)
@@ -23,7 +23,6 @@
 #include "item.hh"
 #include "output-def.hh"
 #include "paper-score.hh"
-#include "simple-closure.hh"
 #include "system.hh"
 #include "unpure-pure-container.hh"
 #include "warn.hh"              // error ()
@@ -51,7 +50,6 @@ LY_DEFINE (ly_grob_set_property_x, "ly:grob-set-property!",
   LY_ASSERT_TYPE (ly_is_symbol, sym, 2);
 
   if (!ly_is_procedure (val)
-      && !unsmob<Simple_closure> (val)
       && !type_check_assignment (sym, val, ly_symbol2scm ("backend-type?")))
     error ("typecheck failed");
 
index b9aa6292b67736e07150b18c04d0c8d18e385c33..c4af7bce0579255dea4919f034065a00b3640bf8 100644 (file)
@@ -186,11 +186,11 @@ bool check_repeat_count_visibility (Context const *context, SCM count);
 void set_context_property_on_children (Context *trans, SCM sym, SCM val);
 
 /* Shorthand for creating and broadcasting stream events. */
-#define send_stream_event(ctx, type, origin, ...)                               \
-{                                                                       \
-  SCM props[] = { __VA_ARGS__, 0 };                                     \
-  ctx->internal_send_stream_event (ly_symbol2scm (type), origin, props);        \
-}
+#define send_stream_event(ctx, type, origin, ...)                       \
+  do {                                                                  \
+    SCM props[] = { __VA_ARGS__, 0 };                                   \
+    ctx->internal_send_stream_event (ly_symbol2scm (type), origin, props); \
+  } while (0)
 
 SCM nested_property_alist (SCM alist, SCM prop_path, SCM value);
 SCM nested_create_alist (SCM prop_path, SCM value);
index 638aa132a9e79a9e070f111c7431912314eb40ad..28f6e935622ff2bb37adb470fc162602beead3fa 100644 (file)
@@ -60,6 +60,8 @@ namespace Lily {
   extern Variable car_less;
   extern Variable construct_chord_elements;
   extern Variable default_time_signature_settings;
+  extern Variable grob_compose_function;
+  extern Variable grob_offset_function;
   extern Variable hash_table_to_alist;
   extern Variable interpret_markup_list;
   extern Variable invalidate_alterations;
index 5b7614531625c0bb02099c3618bcdf8b3d054409..5fe740482593e6f93365d63aa31086a1709ce7da 100644 (file)
@@ -29,7 +29,7 @@ namespace Lookup
   Stencil bracket (Axis a, Interval iv, Real thick, Real protrude, Real blot);
   Stencil circle (Real rad, Real thick, bool filled);
   Stencil rotated_box (Real slope, Real width, Real thick, Real blot);
-  Stencil round_filled_polygon (vector<Offset> const &points, Real blotdiameter);
+  Stencil round_filled_polygon (vector<Offset> const &points, Real blotdiameter, Real extroversion = -1.0);
   Stencil frame (Box b, Real thick, Real blot);
   Stencil slur (Bezier controls, Real cthick, Real thick,
                        SCM dash_definition);
index f77ba50635a4227d40847e56da2f743cf71eb0f5..3453904f7152cf3c8cfe60b652fca9892803637a 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef SCM_HASH_HH
 #define SCM_HASH_HH
 
-#include "smobs.hh"
+#include "small-smobs.hh"
 
 /*
   hash table.
   scm_gc_unprotect_object (tab->self_scm_);
 */
 
-class Scheme_hash_table : public Smob<Scheme_hash_table>
+class Scheme_hash_table : public Smob1<Scheme_hash_table>
 {
 public:
   int print_smob (SCM, scm_print_state *) const;
-  SCM mark_smob () const;
-  virtual ~Scheme_hash_table ();
   bool try_retrieve (SCM key, SCM *val);
   bool contains (SCM key) const;
   void set (SCM k, SCM v);
   SCM get (SCM k) const;
   void remove (SCM k);
-  Scheme_hash_table ();
   void operator = (Scheme_hash_table const &);
-  Scheme_hash_table (Scheme_hash_table const &);
   SCM to_alist () const;
+  static SCM make_smob ();
 
 private:
-  SCM hash_tab_;
-  void copy (Scheme_hash_table const &src);
+  SCM &hash_tab () const { return scm1 (); }
 };
 
 #endif /* SCM_HASH_HH */
diff --git a/lily/include/simple-closure.hh b/lily/include/simple-closure.hh
deleted file mode 100644 (file)
index 49e501c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-  This file is part of LilyPond, the GNU music typesetter.
-
-  Copyright (C) 2005--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
-
-  LilyPond is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  LilyPond is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SIMPLE_CLOSURE_HH
-#define SIMPLE_CLOSURE_HH
-
-#include "lily-guile.hh"
-#include "small-smobs.hh"
-
-class Simple_closure : public Smob1<Simple_closure>
-{
-public:
-  SCM expression() const { return scm1 (); }
-  int print_smob (SCM, scm_print_state *) const;
-  static const char type_p_name_[];
-};
-
-SCM evaluate_with_simple_closure (SCM delayed_argument, SCM expr, bool pure, int start, int end);
-
-#endif /* SIMPLE_CLOSURE_HH */
index 5bae1647f1664930ba4c4283695346753e85449b..c11926b21a9bc8841b4b6e9ba5cdc115cdbbd412 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "engraver.hh"
 #include "moment.hh"
+#include <map>
 
 class Slur_proto_engraver : public Engraver
 {
@@ -32,9 +33,18 @@ protected:
       grob_name_ (grob_name), object_name_ (object_name),
       event_name_ (event_name) {}
 
+  struct Event_info {
+    Stream_event *slur_, *note_;
+    Event_info (Stream_event *slur, Stream_event *note)
+      : slur_ (slur), note_ (note)
+    { }
+  };
   // protected so that subclasses can see them
-  vector<Stream_event *> start_events_;
-  vector<Stream_event *> stop_events_;
+  vector<Event_info> start_events_;
+  vector<Event_info> stop_events_;
+
+  typedef std::multimap<Stream_event *, Spanner *> Note_slurs;
+  Drul_array<Note_slurs> note_slurs_;
   vector<Grob *> slurs_;
   vector<Grob *> end_slurs_;
   vector<Grob_info> objects_to_acknowledge_;
@@ -42,6 +52,7 @@ protected:
   const char* grob_name_;
   const char* object_name_;
   const char* event_name_;
+  virtual SCM event_symbol () = 0;
 
   DECLARE_ACKNOWLEDGER (inline_accidental);
   DECLARE_ACKNOWLEDGER (fingering);
@@ -52,14 +63,15 @@ protected:
   DECLARE_END_ACKNOWLEDGER (tie);
   DECLARE_ACKNOWLEDGER (tuplet_number);
 
-  void internal_listen_slur (Stream_event *ev);
+  void listen_note (Stream_event *ev);
+  void listen_slur (Stream_event *ev, Stream_event *note = 0);
   void acknowledge_extra_object (Grob_info);
   void stop_translation_timestep ();
   void process_music ();
 
   bool can_create_slur (const string&, vsize, vsize *, Stream_event *);
-  void create_slur (const string &spanner_id, Stream_event *ev_cause, Grob *g_cause, Direction dir, bool left_broken);
-  bool try_to_end (Stream_event *ev);
+  void create_slur (const string &spanner_id, Event_info evi, Grob *g_cause, Direction dir, bool left_broken);
+  bool try_to_end (Event_info evi);
 
   virtual void set_melisma (bool);
   virtual void finalize ();
index 27ca05924ea78692f2321726384ca6f2d6ec6fa2..04f0f7e57fbf732a9248dc1e13ff09fd05848ec2 100644 (file)
@@ -54,6 +54,8 @@ namespace Lily {
   Variable car_less ("car<");
   Variable construct_chord_elements ("construct-chord-elements");
   Variable default_time_signature_settings ("default-time-signature-settings");
+  Variable grob_compose_function ("grob::compose-function");
+  Variable grob_offset_function ("grob::offset-function");
   Variable hash_table_to_alist ("hash-table->alist");
   Variable interpret_markup_list ("interpret-markup-list");
   Variable invalidate_alterations ("invalidate-alterations");
index 4f9d0bbbdefaa78d1766c4fea4345dbe8d80964b..bad54405eb0b4d73b039493f6c8eeacc902b049e 100644 (file)
@@ -230,10 +230,18 @@ Lookup::round_filled_box (Box b, Real blotdiameter)
  * blotdiameter along all edges of the polygon (which is what the
  * postscript routine in the backend effectively does, but on the
  * shrinked polygon). --jr
+ *
+ * An extra parameter "extroversion" has been added since staying just
+ * inside of a polygon will reduce its visual size when tracing a
+ * rounded path.  If extroversion is zero, the polygon is just traced
+ * as-is.  If it is -1 (the default) the drawing will stay just within
+ * the given polygon.  If it is 1, the traced line will stay just
+ * outside of the given polygon.
  */
 Stencil
 Lookup::round_filled_polygon (vector<Offset> const &points,
-                              Real blotdiameter)
+                              Real blotdiameter,
+                              Real extroversion)
 {
   /* TODO: Maybe print a warning if one of the above limitations
      applies to the given polygon.  However, this is quite complicated
@@ -257,101 +265,114 @@ Lookup::round_filled_polygon (vector<Offset> const &points,
     return Stencil ();
   if (points.size () == 1)
     {
-      Stencil circ = circle (0.5 * blotdiameter, 0, true);
+      Stencil circ = circle (0.5 * (1.0 + extroversion) * blotdiameter, 0, true);
       circ.translate (points[0]);
       return circ;
     }
   if (points.size () == 2)
-    return Line_interface::make_line (blotdiameter, points[0], points[1]);
-
-  /* shrink polygon in size by 0.5 * blotdiameter */
-
-  // first we need to determine the orientation of the polygon in
-  // order to decide whether shrinking means moving the polygon to the
-  // left or to the right of the outline.  We do that by calculating
-  // (double) the oriented area of the polygon.  We first determine the
-  // center and do the area calculations relative to it.
-  // Mathematically, the result is not affected by this shift, but
-  // numerically a lot of cancellation is going on and this keeps its
-  // effects in check.
-
-  Offset center;
-  for (vsize i = 0; i < points.size (); i++)
-    center += points[i];
-  center /= points.size ();
+    return Line_interface::make_line ((1.0 + extroversion) * blotdiameter, points[0], points[1]);
 
-  Real area = 0.0;
-  Offset last = points.back () - center;
+  vector<Offset> shrunk_points;
 
-  for (vsize i = 0; i < points.size (); i++)
+  if (extroversion == 0.0)
     {
-      Offset here = points[i] - center;
-      area += cross_product (last, here);
-      last = here;
+      shrunk_points = points;
     }
-
-  bool ccw = area >= 0.0;  // true if whole shape is counterclockwise oriented
-
-  vector<Offset> shrunk_points;
-  shrunk_points.resize (points.size ());
-
-  for (vsize i = 0; i < points.size (); i++)
+  else
     {
-      int i0 = i;
-      int i1 = (i + 1) % points.size ();
-      int i2 = (i + 2) % points.size ();
-      Offset p0 = points[i0];
-      Offset p1 = points[i1];
-      Offset p2 = points[i2];
-      Offset p01 = p1 - p0;
-      Offset p12 = p2 - p1;
-      Offset inward0 = Offset(-p01[Y_AXIS], p01[X_AXIS]).direction ();
-      Offset inward2 = Offset(-p12[Y_AXIS], p12[X_AXIS]).direction ();
-
-      if (!ccw)
+      /* shrink polygon in size by 0.5 * blotdiameter */
+
+      // first we need to determine the orientation of the polygon in
+      // order to decide whether shrinking means moving the polygon to the
+      // left or to the right of the outline.  We do that by calculating
+      // (double) the oriented area of the polygon.  We first determine the
+      // center and do the area calculations relative to it.
+      // Mathematically, the result is not affected by this shift, but
+      // numerically a lot of cancellation is going on and this keeps its
+      // effects in check.
+
+      Offset center;
+      for (vsize i = 0; i < points.size (); i++)
+        center += points[i];
+      center /= points.size ();
+
+      Real area = 0.0;
+      Offset last = points.back () - center;
+
+      for (vsize i = 0; i < points.size (); i++)
         {
-          inward0 = -inward0;
-          inward2 = -inward2;
+          Offset here = points[i] - center;
+          area += cross_product (last, here);
+          last = here;
         }
 
-      Offset middle = 0.5*(inward0 + inward2);
-
-      // "middle" now is a vector in the right direction for the
-      // shrinkage.  Its size needs to be large enough that the
-      // projection on either of the inward vectors has a size of 1.
-
-      Real proj = dot_product (middle, inward0);
+      bool ccw = area >= 0.0;  // true if whole shape is counterclockwise oriented
 
-      // What's the size of proj?  Assuming that we have a corner
-      // angle of phi where 0 corresponds to a continuing line, the
-      // length of middle is 0.5 |(1+cos phi, sin phi)| = cos (phi/2),
-      // so its projection has length
-      // cos^2 (phi/2) = 0.5 + 0.5 cos (phi).
-      // We don't really want to move inwards more than 3 blob
-      // diameters corresponding to 6 blob radii.  So
-      // cos (phi/2) = 1/6 gives phi ~ 161, meaning that a 20 degree
-      // corner necessitates moving 3 blob diameters from the corner
-      // in order to stay inside the lines.  Ruler and circle agree.
-      // 0.03 is close enough to 1/36.  Basically we want to keep the
-      // shape from inverting from pulling too far inward.
-      // 3 diameters is pretty much a handwaving guess.
+      shrunk_points.resize (points.size ());
 
-      if (abs (proj) < 0.03)
-        proj = proj < 0 ? -0.03 : 0.03;
+      for (vsize i = 0; i < points.size (); i++)
+        {
+          int i0 = i;
+          int i1 = (i + 1) % points.size ();
+          int i2 = (i + 2) % points.size ();
+          Offset p0 = points[i0];
+          Offset p1 = points[i1];
+          Offset p2 = points[i2];
+          Offset p01 = p1 - p0;
+          Offset p12 = p2 - p1;
+          Offset inward0 = Offset(-p01[Y_AXIS], p01[X_AXIS]).direction ();
+          Offset inward2 = Offset(-p12[Y_AXIS], p12[X_AXIS]).direction ();
+
+          if (!ccw)
+            {
+              inward0 = -inward0;
+              inward2 = -inward2;
+            }
 
-      shrunk_points[i1] = p1 + (0.5 * blotdiameter / proj) * middle;
+          Offset middle = 0.5*(inward0 + inward2);
+
+          // "middle" now is a vector in the right direction for the
+          // shrinkage.  Its size needs to be large enough that the
+          // projection on either of the inward vectors has a size of 1.
+
+          Real proj = dot_product (middle, inward0);
+
+          // What's the size of proj?  Assuming that we have a corner
+          // angle of phi where 0 corresponds to a continuing line, the
+          // length of middle is 0.5 |(1+cos phi, sin phi)| = cos (phi/2),
+          // so its projection has length
+          // cos^2 (phi/2) = 0.5 + 0.5 cos (phi).
+          // We don't really want to move inwards more than 3 blob
+          // diameters corresponding to 6 blob radii.  So
+          // cos (phi/2) = 1/6 gives phi ~ 161, meaning that a 20 degree
+          // corner necessitates moving 3 blob diameters from the corner
+          // in order to stay inside the lines.  Ruler and circle agree.
+          // 0.03 is close enough to 1/36.  Basically we want to keep the
+          // shape from inverting from pulling too far inward.
+          // 3 diameters is pretty much a handwaving guess.
+
+          if (abs (proj) < 0.03)
+            proj = proj < 0 ? -0.03 : 0.03;
+
+          shrunk_points[i1] = p1 - (0.5 * blotdiameter / proj) * middle
+                          * extroversion;
+        }
     }
 
   /* build scm expression and bounding box */
   SCM shrunk_points_scm = SCM_EOL;
   Box box;
+  Box shrunk_box;
   for (vsize i = 0; i < shrunk_points.size (); i++)
     {
       SCM x = scm_from_double (shrunk_points[i][X_AXIS]);
       SCM y = scm_from_double (shrunk_points[i][Y_AXIS]);
       shrunk_points_scm = scm_cons (x, scm_cons (y, shrunk_points_scm));
       box.add_point (points[i]);
+      shrunk_box.add_point (shrunk_points[i]);
     }
+  shrunk_box.widen (0.5*blotdiameter, 0.5*blotdiameter);
+  box.unite (shrunk_box);
   SCM polygon_scm = scm_list_n (ly_symbol2scm ("polygon"),
                                 ly_quote_scm (shrunk_points_scm),
                                 scm_from_double (blotdiameter),
@@ -359,7 +380,6 @@ Lookup::round_filled_polygon (vector<Offset> const &points,
                                 SCM_UNDEFINED);
 
   Stencil polygon = Stencil (box, polygon_scm);
-  shrunk_points.clear ();
   return polygon;
 }
 
index 1c7153a1e39098699f06eacb738b549434caaae9..d0f853109468727e0d038adeb1fb2a5194f4ad36 100644 (file)
@@ -51,7 +51,7 @@ Midi_stream::write (const string &str)
   size_t written = fwrite (str.data (), sz, n, out_file_);
 
   if (written != sz * n)
-    warning (_f ("cannot write to file: `%s'", str.data ()));
+    warning (_f ("cannot write to file: `%s'", file_name_string_.c_str ()));
 }
 
 void
index 160a3935872cc32a0d0c3a3d2d4b1ea035445183..1479aa4c0be887d711ae4d2b46c3b1e1cdb78f8c 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "item.hh"
 #include "pointer-group-interface.hh"
-#include "simple-closure.hh"
 #include "stream-event.hh"
 #include "warn.hh"
 
index 87edcdafed7cc33c4cf48e4dc68c4998789e67dd..35d0aa48dc40cd46df5961780c6f8f2fab2d822e 100644 (file)
@@ -228,7 +228,7 @@ static Music *make_music_with_input (SCM name, Input where);
 SCM check_scheme_arg (Lily_parser *parser, Input loc,
                      SCM arg, SCM args, SCM pred, SCM disp = SCM_UNDEFINED);
 SCM make_music_from_simple (Lily_parser *parser, Input loc, SCM pitch);
-SCM loc_on_music (Input loc, SCM arg);
+SCM loc_on_music (Lily_parser *parser, Input loc, SCM arg);
 SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list);
 SCM make_chord_step (SCM step, Rational alter);
 SCM make_simple_markup (SCM a);
@@ -692,7 +692,7 @@ identifier_init_nonumber:
        | pitch_or_music
        | FRACTION
        | string
-        | embedded_scm
+       | embedded_scm
        | partial_markup
        | full_markup_list
         | context_modification
@@ -1282,10 +1282,10 @@ tempo_event:
        TEMPO steno_duration '=' tempo_range    {
                $$ = MAKE_SYNTAX (tempo, @$, SCM_EOL, $2, $4);
        }
-       | TEMPO scalar steno_duration '=' tempo_range   {
+       | TEMPO text steno_duration '=' tempo_range     {
                $$ = MAKE_SYNTAX (tempo, @$, $2, $3, $5);
        }
-       | TEMPO scalar {
+       | TEMPO text {
                $$ = MAKE_SYNTAX (tempo, @$, $2);
        } %prec ':'
        ;
@@ -1882,7 +1882,7 @@ function_arglist_backup:
                                $$ = scm_cons ($$, $3);
                        else
                        {
-                               $$ = scm_cons (loc_on_music (@3, $1), $3);
+                               $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                                MYBACKUP (SCM_ARG, $4, @4);
                        }
                }
@@ -1893,7 +1893,7 @@ function_arglist_backup:
                {
                        $$ = scm_cons ($4, $3);
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (EVENT_IDENTIFIER, $4, @4);
                }
        }
@@ -1909,7 +1909,7 @@ function_arglist_backup:
                } else if (scm_is_true (scm_call_1 ($2, $4)))
                        $$ = scm_cons ($4, $3);
                else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (PITCH_IDENTIFIER, $4, @4);
                }
        }
@@ -1925,7 +1925,7 @@ function_arglist_backup:
                } else if (scm_is_true (scm_call_1 ($2, $4)))
                        $$ = scm_cons ($4, $3);
                else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (TONICNAME_PITCH, $4, @4);
                }
        }
@@ -1934,7 +1934,7 @@ function_arglist_backup:
                if (scm_is_true (scm_call_1 ($2, $4)))
                        $$ = scm_cons ($4, $3);
                else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (SCM_IDENTIFIER, $4, @4);
                }
        }
@@ -1948,7 +1948,7 @@ function_arglist_backup:
                        SCM d = make_duration ($4);
                        if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
                        {
-                               $$ = scm_cons (loc_on_music (@3, $1), $3);
+                               $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                                MYBACKUP (UNSIGNED, $4, @4);
                        } else {
                                MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
@@ -1963,7 +1963,7 @@ function_arglist_backup:
                        $$ = $3;
                        MYREPARSE (@4, $2, REAL, $4);
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (REAL, $4, @4);
                }
        }
@@ -1973,7 +1973,7 @@ function_arglist_backup:
                {
                        $$ = scm_cons ($4, $3);
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (NUMBER_IDENTIFIER, $4, @4);
                }
        }
@@ -1990,7 +1990,7 @@ function_arglist_backup:
                        if (scm_is_true (scm_call_1 ($2, $$)))
                                $$ = scm_cons ($$, $3);
                        else {
-                               $$ = scm_cons (loc_on_music (@3, $1), $3);
+                               $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                                MYBACKUP (UNSIGNED, $5, @5);
                                parser->lexer_->push_extra_token (@4, '-');
                        }
@@ -2003,7 +2003,7 @@ function_arglist_backup:
                        MYREPARSE (@5, $2, REAL, n);
                        $$ = $3;
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (REAL, n, @5);
                }
        }
@@ -2013,7 +2013,7 @@ function_arglist_backup:
                if (scm_is_true (scm_call_1 ($2, n))) {
                        $$ = scm_cons (n, $3);
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (NUMBER_IDENTIFIER, n, @5);
                }
        }
@@ -2024,7 +2024,7 @@ function_arglist_backup:
                        MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
                        $$ = $3;
                } else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (DURATION_IDENTIFIER, $4, @4);
                }
        }
@@ -2039,7 +2039,7 @@ function_arglist_backup:
                        else
                                $$ = scm_cons (res, $3);
                else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (SCM_IDENTIFIER, $4, @4);
                }
        }
@@ -2054,7 +2054,7 @@ function_arglist_backup:
                        else
                                $$ = scm_cons (res, $3);
                else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
+                       $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
                        MYBACKUP (STRING, $4, @4);
                }
        }
@@ -2088,7 +2088,7 @@ function_arglist:
        function_arglist_nonbackup
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
        {
-               $$ = scm_cons (loc_on_music (@4, $1), $3);
+               $$ = scm_cons (loc_on_music (parser, @4, $1), $3);
        }
        ;
 
@@ -2096,7 +2096,7 @@ function_arglist_skip_nonbackup:
        function_arglist_nonbackup
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup
        {
-               $$ = scm_cons (loc_on_music (@3, $1), $3);
+               $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
        }
        ;
 
@@ -2334,7 +2334,7 @@ function_arglist_optional:
        function_arglist_backup
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup DEFAULT
        {
-               $$ = scm_cons (loc_on_music (@4, $1), $3);
+               $$ = scm_cons (loc_on_music (parser, @4, $1), $3);
        }
        | function_arglist_skip_backup BACKUP
        ;
@@ -2343,7 +2343,7 @@ function_arglist_skip_backup:
        function_arglist_backup
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup
        {
-               $$ = scm_cons (loc_on_music (@3, $1), $3);
+               $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
        }
        ;
 
@@ -2716,15 +2716,25 @@ music_property_def:
        ;
 
 string:
-       STRING {
-               $$ = $1;
-       }
+       STRING
        | full_markup
        ;
 
-simple_string: STRING {
-               $$ = $1;
+text:
+       STRING
+       | full_markup
+       | embedded_scm_bare
+       {
+               if (Text_interface::is_markup ($1)) {
+                       $$ = $1;
+               } else {
+                       parser->parser_error (@1, (_ ("markup expected")));
+                       $$ = scm_string (SCM_EOL);
+               }
        }
+       ;
+
+simple_string: STRING
        | embedded_scm_bare
        {
                if (scm_is_string ($1)) {
@@ -2811,8 +2821,8 @@ note_chord_element:
                  unsmob<Music> (scm_car (s))->set_property ("duration", dur);
                es = ly_append2 (es, postevs);
 
-               m-> set_property ("elements", es);
-               m->set_spot (@$);
+               m->set_property ("elements", es);
+               m->set_spot (parser->lexer_->override_input (@$));
                $$ = m->self_scm ();
        } %prec ':'
        ;
@@ -2919,7 +2929,7 @@ post_events:
                                        $$ = scm_cons (scm_car (p), $$);
                                }
                        } else {
-                               m->set_spot (@2);
+                               m->set_spot (parser->lexer_->override_input (@2));
                                $$ = scm_cons ($2, $$);
                        }
                }
@@ -3955,12 +3965,12 @@ SCM check_scheme_arg (Lily_parser *parser, Input loc,
        return args;
 }
 
-SCM loc_on_music (Input loc, SCM arg)
+SCM loc_on_music (Lily_parser *parser, Input loc, SCM arg)
 {
        if (Music *m = unsmob<Music> (arg))
        {
                m = m->clone ();
-               m->set_spot (loc);
+               m->set_spot (parser->lexer_->override_input (loc));
                return m->unprotect ();
        }
        return arg;
index 9a36699864e2228597b05100cb1666309cd3b250..479be1df22cdf87e9d02e47c18d5c72cc0733dcf 100644 (file)
@@ -35,9 +35,11 @@ class Phrasing_slur_engraver : public Slur_proto_engraver
 {
 protected:
   DECLARE_TRANSLATOR_LISTENER (phrasing_slur);
+  DECLARE_TRANSLATOR_LISTENER (note);
   DECLARE_ACKNOWLEDGER (slur);
 
 public:
+  SCM event_symbol ();
   TRANSLATOR_DECLARATIONS (Phrasing_slur_engraver);
 };
 
@@ -46,11 +48,25 @@ Phrasing_slur_engraver::Phrasing_slur_engraver () :
 {
 }
 
+SCM
+Phrasing_slur_engraver::event_symbol ()
+{
+  // Need a string constant for memoization
+  return ly_symbol2scm ("phrasing-slur-event");
+}
+
 IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, phrasing_slur);
 void
 Phrasing_slur_engraver::listen_phrasing_slur (Stream_event *ev)
 {
-  internal_listen_slur (ev);
+  Slur_proto_engraver::listen_slur (ev);
+}
+
+IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, note);
+void
+Phrasing_slur_engraver::listen_note (Stream_event *ev)
+{
+  Slur_proto_engraver::listen_note (ev);
 }
 
 void
index 08419d83dd0d223fcff7592af87f9a24cfec2f88..dd8f9257b933a93d9bfb92b7593180aa3cb16f7d 100644 (file)
 
 #include "scm-hash.hh"
 
-#include <cstdio>
-#include <algorithm>
-using namespace std;
-
-
-/*
-  Return: number of objects.
-*/
-SCM
-copy_handle (void *closure, SCM handle)
-{
-  SCM tab = (SCM) closure;
-  scm_hashq_set_x (tab, scm_car (handle), scm_cdr (handle));
-  return tab;
-}
-
-static void
-copy_scm_hashes (SCM dest, SCM src)
-{
-  scm_internal_hash_for_each_handle ((scm_t_hash_handle_fn) &copy_handle,
-                                     dest, src);
-}
-
-Scheme_hash_table::Scheme_hash_table ()
-{
-  hash_tab_ = SCM_EOL;
-  smobify_self ();
-  hash_tab_ = scm_c_make_hash_table (119);
-}
-
-Scheme_hash_table::Scheme_hash_table (Scheme_hash_table const &src)
-  : Smob<Scheme_hash_table> ()
-{
-  hash_tab_ = SCM_EOL;
-  smobify_self ();
-  copy (src);
-}
-
-void
-Scheme_hash_table::copy (Scheme_hash_table const &src)
-{
-  if (&src == this)
-    return;
-
-  hash_tab_ = scm_c_make_hash_table (SCM_HASHTABLE_N_ITEMS (src.hash_tab_));
-  copy_scm_hashes (hash_tab_, src.hash_tab_);
-}
-
-Scheme_hash_table::~Scheme_hash_table ()
-{
-}
+#include <cassert>
 
 SCM
-Scheme_hash_table::mark_smob () const
+Scheme_hash_table::make_smob ()
 {
-  scm_gc_mark (hash_tab_);
-  return SCM_EOL;
+  return Smob1::make_smob (scm_c_make_hash_table (119));
 }
 
 int
 Scheme_hash_table::print_smob (SCM p, scm_print_state *) const
 {
   scm_puts ("#<Scheme_hash_table  ", p);
-  scm_display (hash_tab_, p);
+  scm_display (hash_tab (), p);
   scm_puts ("> ", p);
   return 1;
 }
@@ -91,7 +40,7 @@ bool
 Scheme_hash_table::try_retrieve (SCM k, SCM *v)
 {
 
-  SCM handle = scm_hashq_get_handle (hash_tab_, k);
+  SCM handle = scm_hashq_get_handle (hash_tab (), k);
   if (scm_is_pair (handle))
     {
       *v = scm_cdr (handle);
@@ -104,14 +53,14 @@ Scheme_hash_table::try_retrieve (SCM k, SCM *v)
 bool
 Scheme_hash_table::contains (SCM k) const
 {
-  return scm_is_pair (scm_hashq_get_handle (hash_tab_, k));
+  return scm_is_pair (scm_hashq_get_handle (hash_tab (), k));
 }
 
 void
 Scheme_hash_table::set (SCM k, SCM v)
 {
   assert (scm_is_symbol (k));
-  SCM handle = scm_hashq_create_handle_x (hash_tab_, k, SCM_UNDEFINED);
+  SCM handle = scm_hashq_create_handle_x (hash_tab (), k, SCM_UNDEFINED);
   scm_set_cdr_x (handle, v);
 }
 
@@ -120,13 +69,13 @@ Scheme_hash_table::get (SCM k) const
 {
   /* SCM_UNSPECIFIED will stick out like a sore thumb, hopefully.
   */
-  return scm_hashq_ref (hash_tab_, k, SCM_UNSPECIFIED);
+  return scm_hashq_ref (hash_tab (), k, SCM_UNSPECIFIED);
 }
 
 void
 Scheme_hash_table::remove (SCM k)
 {
-  scm_hashq_remove_x (hash_tab_, k);
+  scm_hashq_remove_x (hash_tab (), k);
 }
 
 static SCM
@@ -142,5 +91,5 @@ SCM
 Scheme_hash_table::to_alist () const
 {
   return scm_internal_hash_fold ((scm_t_hash_fold_fn) &collect_handles,
-                                 NULL, SCM_EOL, hash_tab_);
+                                 NULL, SCM_EOL, hash_tab ());
 }
diff --git a/lily/simple-closure.cc b/lily/simple-closure.cc
deleted file mode 100644 (file)
index 465640e..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-  This file is part of LilyPond, the GNU music typesetter.
-
-  Copyright (C) 2005--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
-
-
-  LilyPond is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  LilyPond is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "simple-closure.hh"
-#include "unpure-pure-container.hh"
-
-#include "grob.hh"
-
-SCM
-evaluate_args (SCM delayed_argument, SCM args, bool pure, int start, int end)
-{
-  SCM new_args = SCM_EOL;
-  SCM *tail = &new_args;
-  for (SCM s = args; scm_is_pair (s); s = scm_cdr (s))
-    {
-      *tail = scm_cons (evaluate_with_simple_closure (delayed_argument, scm_car (s),
-                                                      pure, start, end),
-                        SCM_EOL);
-      if (scm_is_eq (scm_car (*tail), SCM_UNSPECIFIED))
-        return SCM_UNSPECIFIED;
-      tail = SCM_CDRLOC (*tail);
-    }
-
-  return new_args;
-}
-
-SCM
-evaluate_with_simple_closure (SCM delayed_argument,
-                              SCM expr,
-                              bool pure,
-                              int start,
-                              int end)
-{
-  if (Simple_closure *sc = unsmob<Simple_closure> (expr))
-    {
-      SCM inside = sc->expression ();
-      SCM proc = !pure && unsmob<Unpure_pure_container> (scm_car (inside))
-        ? unsmob<Unpure_pure_container> (scm_car (inside))->unpure_part ()
-        : scm_car (inside);
-      SCM args = scm_cons (delayed_argument,
-                           evaluate_args (delayed_argument, scm_cdr (inside),
-                                          pure, start, end));
-      if (scm_is_eq (scm_cdr (args), SCM_UNSPECIFIED))
-        return SCM_UNSPECIFIED;
-      if (pure)
-        return call_pure_function (proc, args, start, end);
-      return scm_apply_0 (proc, args);
-    }
-  else if (!scm_is_pair (expr))
-    return expr;
-  else if (scm_is_eq (scm_car (expr), ly_symbol2scm ("quote")))
-    return scm_cadr (expr);
-  else if (unsmob<Unpure_pure_container> (scm_car (expr))
-           || ly_is_procedure (scm_car (expr)))
-    {
-      SCM proc = !pure && unsmob<Unpure_pure_container> (scm_car (expr))
-        ? unsmob<Unpure_pure_container> (scm_car (expr))->unpure_part ()
-        : scm_car (expr);
-      SCM args = evaluate_args (delayed_argument, scm_cdr (expr), pure, start, end);
-      if (scm_is_eq (args, SCM_UNSPECIFIED))
-        return SCM_UNSPECIFIED;
-      if (pure)
-        return call_pure_function (proc, args, start, end);
-      return scm_apply_0 (proc, args);
-    }
-  else
-    // ugh. deviation from standard. Should print error?
-    return evaluate_args (delayed_argument, scm_cdr (expr), pure, start, end);
-
-  assert (false);
-  return SCM_EOL;
-}
-
-const char Simple_closure::type_p_name_[] = "ly:simple-closure?";
-
-LY_DEFINE (ly_make_simple_closure, "ly:make-simple-closure",
-           1, 0, 0, (SCM expr),
-           "Make a simple closure.  @var{expr} should be form of"
-           " @code{(@var{func} @var{a1} @var{a2} @dots{})}, and will be"
-           " invoked as @code{(@var{func} @var{delayed-arg} @var{a1}"
-           " @var{a2} @dots{})}.")
-{
-  return Simple_closure::make_smob (expr);
-}
-
-LY_DEFINE (ly_eval_simple_closure, "ly:eval-simple-closure",
-           2, 2, 0, (SCM delayed, SCM closure, SCM scm_start, SCM scm_end),
-           "Evaluate a simple @var{closure} with the given @var{delayed}"
-           " argument.  If @var{scm-start} and @var{scm-end} are defined,"
-           " evaluate it purely with those start and end points.")
-{
-  LY_ASSERT_SMOB (Simple_closure, closure, 2);
-  bool pure = (scm_is_number (scm_start) && scm_is_number (scm_end));
-  int start = robust_scm2int (scm_start, 0);
-  int end = robust_scm2int (scm_end, 0);
-  SCM expr = unsmob<Simple_closure> (closure)->expression ();
-  return evaluate_with_simple_closure (delayed, expr, pure, start, end);
-}
-
-int
-Simple_closure::print_smob (SCM port, scm_print_state *) const
-{
-  scm_puts ("#<simple-closure ", port);
-  scm_display (expression (), port);
-  scm_puts (" >", port);
-  return 1;
-}
index b6661993c17fbcafa0774fe30362a7fa56b79d3c..581136791d932daff6148c2ad80d2b82366c095b 100644 (file)
@@ -37,8 +37,10 @@ class Slur_engraver : public Slur_proto_engraver
 
 protected:
   DECLARE_TRANSLATOR_LISTENER (slur);
+  DECLARE_TRANSLATOR_LISTENER (note);
 
 public:
+  SCM event_symbol ();
   TRANSLATOR_DECLARATIONS (Slur_engraver);
 };
 
@@ -47,11 +49,25 @@ Slur_engraver::Slur_engraver () :
 {
 }
 
+SCM
+Slur_engraver::event_symbol ()
+{
+  // Need a string constant for memoization
+  return ly_symbol2scm ("slur-event");
+}
+
 IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, slur);
 void
 Slur_engraver::listen_slur (Stream_event *ev)
 {
-  internal_listen_slur (ev);
+  Slur_proto_engraver::listen_slur (ev);
+}
+
+IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, note);
+void
+Slur_engraver::listen_note (Stream_event *ev)
+{
+  Slur_proto_engraver::listen_note (ev);
 }
 
 void
index 215fcfd7a3deed937f0da012e7252190b5c6d29f..99e8e8ebfcd54fd87f8ac370466e01f0b45b82ad 100644 (file)
@@ -23,6 +23,7 @@
 #include "directional-element-interface.hh"
 #include "international.hh"
 #include "note-column.hh"
+#include "pointer-group-interface.hh"
 #include "slur.hh"
 #include "slur-proto-engraver.hh"
 #include "spanner.hh"
@@ -35,23 +36,43 @@ void
 Slur_proto_engraver::derived_mark () const
 {
   for (vsize i = start_events_.size (); i--;)
-    scm_gc_mark (start_events_[i]->self_scm ());
+    {
+      scm_gc_mark (start_events_[i].slur_->self_scm ());
+      if (start_events_[i].note_)
+        scm_gc_mark (start_events_[i].note_->self_scm ());
+    }
   for (vsize i = stop_events_.size (); i--;)
-    scm_gc_mark (stop_events_[i]->self_scm ());
+    {
+      scm_gc_mark (stop_events_[i].slur_->self_scm ());
+      if (stop_events_[i].note_)
+        scm_gc_mark (stop_events_[i].note_->self_scm ());
+    }
 }
 
 void
-Slur_proto_engraver::internal_listen_slur (Stream_event *ev)
+Slur_proto_engraver::listen_slur (Stream_event *ev, Stream_event *note)
 {
   Direction d = to_dir (ev->get_property ("span-direction"));
   if (d == START)
-    start_events_.push_back (ev);
+    start_events_.push_back (Event_info (ev, note));
   else if (d == STOP)
-    stop_events_.push_back (ev);
+    stop_events_.push_back (Event_info (ev, note));
   else ev->origin ()->warning (_f ("direction of %s invalid: %d",
                                      event_name_, int (d)));
 }
 
+void
+Slur_proto_engraver::listen_note (Stream_event *ev)
+{
+  for (SCM arts = ev->get_property ("articulations");
+       scm_is_pair (arts); arts = scm_cdr (arts))
+    {
+      Stream_event *art = unsmob<Stream_event> (scm_car (arts));
+      if (art->in_event_class (event_symbol ()))
+        listen_slur (art, ev);
+    }
+}
+
 void
 Slur_proto_engraver::acknowledge_note_column (Grob_info info)
 {
@@ -60,6 +81,25 @@ Slur_proto_engraver::acknowledge_note_column (Grob_info info)
     Slur::add_column (slurs_[i], e);
   for (vsize i = end_slurs_.size (); i--;)
     Slur::add_column (end_slurs_[i], e);
+  // Now cater for slurs starting/ending at a notehead: those override
+  // the column bounds
+  if (note_slurs_[START].empty () && note_slurs_[STOP].empty ())
+    return;
+  extract_grob_set (e, "note-heads", heads);
+  for (vsize i = heads.size (); i--;)
+    {
+      if (Stream_event *ev =
+          unsmob<Stream_event> (heads[i]->get_property ("cause")))
+        for (LEFT_and_RIGHT (d))
+          {
+            std::pair<Note_slurs::const_iterator, Note_slurs::const_iterator> its
+              = note_slurs_[d].equal_range (ev);
+            for (Note_slurs::const_iterator it = its.first;
+                 it != its.second;
+                 ++it)
+              it->second->set_bound (d, heads[i]);
+          }
+    }
 }
 
 void
@@ -123,10 +163,12 @@ Slur_proto_engraver::finalize ()
 }
 
 void
-Slur_proto_engraver::create_slur (const string &spanner_id, Stream_event *ev_cause, Grob *g_cause, Direction dir, bool left_broken)
+Slur_proto_engraver::create_slur (const string &spanner_id, Event_info evi, Grob *g_cause, Direction dir, bool left_broken)
 {
-  Grob *ccc = unsmob<Grob> (get_property ("currentCommandColumn"));
-  SCM cause = ev_cause ? ev_cause->self_scm () : g_cause->self_scm ();
+  Grob *ccc = left_broken
+    ? unsmob<Grob> (get_property ("currentCommandColumn"))
+    : 0; // efficiency
+  SCM cause = evi.slur_ ? evi.slur_->self_scm () : g_cause->self_scm ();
   Spanner *slur = make_spanner (grob_name_, cause);
   slur->set_property ("spanner-id", ly_string2scm (spanner_id));
   if (dir)
@@ -134,6 +176,9 @@ Slur_proto_engraver::create_slur (const string &spanner_id, Stream_event *ev_cau
   if (left_broken)
     slur->set_bound (LEFT, ccc);
   slurs_.push_back (slur);
+  if (evi.note_)
+    note_slurs_[START].insert (Note_slurs::value_type (evi.note_, slur));
+
   if (double_property_name_
       && to_boolean (get_property (double_property_name_)))
   {
@@ -144,6 +189,8 @@ Slur_proto_engraver::create_slur (const string &spanner_id, Stream_event *ev_cau
     if (left_broken)
       slur->set_bound (LEFT, ccc);
     slurs_.push_back (slur);
+    if (evi.note_)
+      note_slurs_[START].insert(Note_slurs::value_type (evi.note_, slur));
   }
 
 }
@@ -206,9 +253,9 @@ Slur_proto_engraver::can_create_slur (const string &id, vsize old_slurs, vsize *
 }
 
 bool
-Slur_proto_engraver::try_to_end (Stream_event *ev)
+Slur_proto_engraver::try_to_end (Event_info evi)
 {
-  string id = robust_scm2string (ev->get_property ("spanner-id"), "");
+  string id = robust_scm2string (evi.slur_->get_property ("spanner-id"), "");
 
   // Find the slurs that are ended with this event (by checking the spanner-id)
   bool ended = false;
@@ -218,6 +265,10 @@ Slur_proto_engraver::try_to_end (Stream_event *ev)
         {
           ended = true;
           end_slurs_.push_back (slurs_[j]);
+          if (evi.note_)
+            note_slurs_[STOP].insert
+              (Note_slurs::value_type
+               (evi.note_, dynamic_cast <Spanner *> (slurs_[j])));
           slurs_.erase (slurs_.begin () + j);
         }
     }
@@ -229,30 +280,32 @@ Slur_proto_engraver::process_music ()
 {
   for (vsize i = 0; i < stop_events_.size (); i++)
     {
-      string id = robust_scm2string (stop_events_[i]->get_property ("spanner-id"), "");
+      string id = robust_scm2string
+        (stop_events_[i].slur_->get_property ("spanner-id"), "");
       bool ended = try_to_end (stop_events_[i]);
       if (ended)
         {
           // Ignore redundant stop events for this id
           for (vsize j = stop_events_.size (); --j > i;)
             {
-              if (id == robust_scm2string (stop_events_[j]->get_property ("spanner-id"), ""))
+              if (id == robust_scm2string
+                  (stop_events_[j].slur_->get_property ("spanner-id"), ""))
                 stop_events_.erase (stop_events_.begin () + j);
             }
         }
       else
-        stop_events_[i]->origin ()->warning (_f ("cannot end %s", object_name_));
+        stop_events_[i].slur_->origin ()->warning (_f ("cannot end %s", object_name_));
     }
 
   vsize old_slurs = slurs_.size ();
   for (vsize i = start_events_.size (); i--;)
     {
-      Stream_event *ev = start_events_[i];
+      Stream_event *ev = start_events_[i].slur_;
       string id = robust_scm2string (ev->get_property ("spanner-id"), "");
       Direction updown = to_dir (ev->get_property ("direction"));
 
       if (can_create_slur (id, old_slurs, &i, ev))
-        create_slur (id, ev, 0, updown, false);
+        create_slur (id, start_events_[i], 0, updown, false);
     }
 
   set_melisma (slurs_.size ());
@@ -287,6 +340,8 @@ Slur_proto_engraver::stop_translation_timestep ()
   for (vsize i = 0; i < objects_to_acknowledge_.size (); i++)
     Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slurs_, end_slurs_);
 
+  note_slurs_[LEFT].clear ();
+  note_slurs_[RIGHT].clear ();
   objects_to_acknowledge_.clear ();
   end_slurs_.clear ();
   start_events_.clear ();
index edd45f64278a80bf36e1d180f70664b8e5ccb9c8..2d4865e19095aa0f4e983b83ad002e6d90d022db 100644 (file)
@@ -32,6 +32,7 @@
 #include "main.hh"
 #include "misc.hh"
 #include "note-column.hh"
+#include "note-head.hh"
 #include "output-def.hh"
 #include "paper-column.hh"
 #include "pitch.hh"
@@ -200,11 +201,14 @@ Slur_score_state::get_bound_info () const
                                          ::staff_space (extremes[d].stem_);
             }
 
-          if (extremes[d].slur_head_)
-            extremes[d].slur_head_x_extent_
-              = extremes[d].slur_head_->extent (common_[X_AXIS], X_AXIS);
-
         }
+      else if (has_interface<Note_head> (extremes[d].bound_))
+        {
+          extremes[d].slur_head_ = extremes[d].bound_;
+        }
+      if (extremes[d].slur_head_)
+        extremes[d].slur_head_x_extent_
+          = extremes[d].slur_head_->extent (common_[X_AXIS], X_AXIS);
     }
 
   return extremes;
@@ -254,8 +258,8 @@ Slur_score_state::fill (Grob *me)
     }
 
   extremes_ = get_bound_info ();
-  is_broken_ = (!extremes_[LEFT].note_column_
-                || !extremes_[RIGHT].note_column_);
+  is_broken_ = (!(extremes_[LEFT].note_column_ || extremes_[LEFT].slur_head_)
+                || !(extremes_[RIGHT].note_column_ || extremes_[RIGHT].slur_head_));
 
   has_same_beam_
     = (extremes_[LEFT].stem_ && extremes_[RIGHT].stem_
@@ -470,6 +474,11 @@ Slur_score_state::get_y_attachment_range () const
                                     dir_ * (dir_ + nc_extent[dir_])),
                                dir_ * base_attachments_[-d][Y_AXIS]);
         }
+      else if (extremes_[d].slur_head_)
+        {
+          // allow only minimal movement
+          end_ys[d] = base_attachments_[d][Y_AXIS] + 0.3 * dir_;
+        }
       else
         end_ys[d] = base_attachments_[d][Y_AXIS] + parameters_.region_size_ * dir_;
     }
@@ -528,12 +537,22 @@ Slur_score_state::get_base_attachments () const
                : extremes_[d].bound_->extent (common_[X_AXIS], X_AXIS))
               .linear_combination (CENTER);
         }
+      else if (head)
+        {
+          y = head->extent (common_[Y_AXIS], Y_AXIS)
+            .linear_combination (0.5*dir_);
+
+          // Don't "move_away_from_staffline" because that makes it
+          // harder to recognize the specific attachment point
+          x = head->extent (common_[X_AXIS], X_AXIS)[-d];
+        }
+
       base_attachment[d] = Offset (x, y);
     }
 
   for (LEFT_and_RIGHT (d))
     {
-      if (!extremes_[d].note_column_)
+      if (!extremes_[d].note_column_ && !extremes_[d].slur_head_)
         {
           Real x = 0;
           Real y = 0;
index e79dda1873d15e458168d65666a4f9cccfb8d670..c8d87439d67452e497049886b7cd25bf55cfa194 100644 (file)
@@ -413,14 +413,23 @@ LY_DEFINE (ly_round_filled_box, "ly:round-filled-box",
 }
 
 LY_DEFINE (ly_round_filled_polygon, "ly:round-filled-polygon",
-           2, 0, 0,
-           (SCM points, SCM blot),
+           2, 1, 0,
+           (SCM points, SCM blot, SCM extroversion),
            "Make a @code{Stencil} object that prints a black polygon with"
            " corners at the points defined by @var{points} (list of coordinate"
-           " pairs) and roundness @var{blot}.")
+           " pairs) and roundness @var{blot}.  Optional"
+           "@var{extroversion} shifts the outline outward, with the"
+           "default of@tie{}@code{-1.0} keeping the outer boundary of"
+           "the outline just inside of the polygon.")
 {
   SCM_ASSERT_TYPE (scm_ilength (points) > 0, points, SCM_ARG1, __FUNCTION__, "list of coordinate pairs");
   LY_ASSERT_TYPE (scm_is_number, blot, 2);
+  Real ext = -1;
+  if (!SCM_UNBNDP (extroversion))
+    {
+      LY_ASSERT_TYPE (scm_is_number, extroversion, 3);
+      ext = scm_to_double (extroversion);
+    }
   vector<Offset> pts;
   for (SCM p = points; scm_is_pair (p); p = scm_cdr (p))
     {
@@ -434,7 +443,8 @@ LY_DEFINE (ly_round_filled_polygon, "ly:round-filled-polygon",
           // TODO: Print out warning
         }
     }
-  return Lookup::round_filled_polygon (pts, scm_to_double (blot)).smobbed_copy ();
+  return Lookup::round_filled_polygon (pts, scm_to_double (blot), ext)
+    .smobbed_copy ();
 }
 
 LY_DEFINE (ly_register_stencil_expression, "ly:register-stencil-expression",
index 15edd7df4ab67a39ed9b7ddaff1d8bf6d0f9139a..67fa95a610b139608d94482ae54d6afb202221b3 100644 (file)
   should delete these after exit.
 */
 
-Scheme_hash_table *global_translator_dict = 0;
-Protected_scm global_translator_dict_scm;
+Protected_scm global_translator_dict;
 
 LY_DEFINE (get_all_translators, "ly:get-all-translators", 0, 0, 0, (),
            "Return a list of all translator objects that may be"
            " instantiated.")
 {
-  SCM l = global_translator_dict ? global_translator_dict->to_alist () : SCM_EOL;
+  Scheme_hash_table *dict = unsmob<Scheme_hash_table> (global_translator_dict);
+  SCM l = dict ? dict->to_alist () : SCM_EOL;
 
   for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
     scm_set_car_x (s, scm_cdar (s));
@@ -46,22 +46,24 @@ LY_DEFINE (get_all_translators, "ly:get-all-translators", 0, 0, 0, (),
 void
 add_translator (Translator *t)
 {
-  if (!global_translator_dict)
+  Scheme_hash_table *dict = unsmob<Scheme_hash_table> (global_translator_dict);
+  if (!dict)
     {
-      global_translator_dict = new Scheme_hash_table;
-      global_translator_dict_scm = global_translator_dict->unprotect ();
+      global_translator_dict = Scheme_hash_table::make_smob ();
+      dict = unsmob<Scheme_hash_table> (global_translator_dict);
     }
 
   SCM k = ly_symbol2scm (t->class_name ());
-  global_translator_dict->set (k, t->unprotect ());
+  dict->set (k, t->unprotect ());
 }
 
 Translator *
 get_translator (SCM sym)
 {
   SCM v = SCM_BOOL_F;
-  if (global_translator_dict)
-    global_translator_dict->try_retrieve (sym, &v);
+  Scheme_hash_table *dict = unsmob<Scheme_hash_table> (global_translator_dict);
+  if (dict)
+    dict->try_retrieve (sym, &v);
 
   if (scm_is_false (v))
     {
@@ -71,4 +73,3 @@ get_translator (SCM sym)
 
   return unsmob<Translator> (v);
 }
-
index 2dff6eea992a402c7beaeaf567f6611ef41164c9..0e389d4bcd087bf291413155e3398436393b9a17 100644 (file)
 */
 #include "unpure-pure-container.hh"
 
-// Reroutes a call to the contained function after dropping last two
-// arguments.  Used for applying an "unpure" function in a "pure"
+// Reroutes a call to the contained function after dropping second and
+// third argument.  Used for applying an "unpure" function in a "pure"
 // context.
 class Unpure_pure_call : public Smob1<Unpure_pure_call>
 {
 public:
+  // Smob procedures unfortunately can only take at most 3 SCM
+  // arguments.  Otherwise we could use a "3, 0, 1" call signature and
+  // not require an argument count check of our own.
   LY_DECLARE_SMOB_PROC (&Unpure_pure_call::call, 2, 0, 1)
-  SCM call (SCM arg1, SCM arg2, SCM rest)
+  SCM call (SCM arg1, SCM, SCM rest)
   {
-    return scm_apply_0 (scm1 (),
-                        scm_list_head (scm_cons2 (arg1, arg2, rest),
-                                       scm_length (rest)));
+    if (!scm_is_pair (rest))
+      scm_wrong_num_args (scm1 ());
+    return scm_apply_1 (scm1 (), arg1, scm_cdr (rest));
   }
 };
 
@@ -84,3 +87,40 @@ Unpure_pure_container::print_smob (SCM port, scm_print_state *) const
   scm_puts (" >", port);
   return 1;
 }
+
+LY_DEFINE (ly_pure_call, "ly:pure-call",
+           4, 0, 1, (SCM data, SCM grob, SCM start, SCM end, SCM rest),
+           "Convert property @var{data} (unpure-pure container or procedure)"
+           " to value in a pure context defined by @var{grob},"
+           " @var{start}, @var{end}, and possibly @var{rest} arguments.")
+{
+  if (Unpure_pure_container *upc = unsmob<Unpure_pure_container> (data))
+    {
+      // Avoid gratuitous creation of an Unpure_pure_call
+      if (upc->is_unchanging ())
+        data = upc->unpure_part ();
+      else
+        {
+          data = upc->pure_part ();
+          if (ly_is_procedure (data))
+            return scm_apply_3 (data, grob, start, end, rest);
+          return data;
+        }
+    }
+  if (ly_is_procedure (data))
+    return scm_apply_1 (data, grob, rest);
+  return data;
+}
+
+LY_DEFINE (ly_unpure_call, "ly:unpure-call",
+           2, 0, 1, (SCM data, SCM grob, SCM rest),
+           "Convert property @var{data} (unpure-pure container or procedure)"
+           " to value in an unpure context defined by @var{grob}"
+           " and possibly @var{rest} arguments.")
+{
+  if (Unpure_pure_container *upc = unsmob<Unpure_pure_container> (data))
+    data = upc->unpure_part ();
+  if (ly_is_procedure (data))
+    return scm_apply_1 (data, grob, rest);
+  return data;
+}
index f37de77352eb51cf4eefc4383d7530d04460aaf4..ba8365731ca67206e84f03d41962287591700a67 100644 (file)
@@ -23,7 +23,7 @@ That's it.  For more information, visit http://lilypond.org .
 
 %}
 
-\version "2.19.27"  % necessary for upgrading to future LilyPond versions.
+\version "2.19.29"  % necessary for upgrading to future LilyPond versions.
 
 \header{
   title = "A scale in LilyPond"
index 96ec47c3c6d2a4474a2d370f1158d452a8c67796..c8cfa03b6b9f6f318809a993e92d5a451ad986d8 100644 (file)
@@ -32,7 +32,7 @@ Good luck with LilyPond!  Happy engraving.
 
 %}
 
-\version "2.19.27"  % necessary for upgrading to future LilyPond versions.
+\version "2.19.29"  % necessary for upgrading to future LilyPond versions.
 
 \header{
   title = "A scale in LilyPond"
index e976cb66440498876a627e339fc194e0bbd35441..5c6fb24e6ed04e773d5f41bc22d40d0a6c13b046 100644 (file)
@@ -1294,25 +1294,7 @@ that they share a staff with stems directed downward.")
     #{ \with { \voiceTwo \override DynamicLineSpanner.direction = #DOWN } #}
     #{ \with { \voiceTwo \override DynamicLineSpanner.direction = #DOWN } #} ))
 
-partcombineForce =
-#(define-music-function (type once) (boolean-or-symbol? boolean?)
-   (_i "Override the part-combiner.")
-   (make-music 'EventChord
-               'elements (list (make-music 'PartCombineForceEvent
-                                           'forced-type type
-                                           'once once))))
-partcombineApart = \partcombineForce #'apart ##f
-partcombineApartOnce = \partcombineForce #'apart ##t
-partcombineChords = \partcombineForce #'chords ##f
-partcombineChordsOnce = \partcombineForce #'chords ##t
-partcombineUnisono = \partcombineForce #'unisono ##f
-partcombineUnisonoOnce = \partcombineForce #'unisono ##t
-partcombineSoloI = \partcombineForce #'solo1 ##f
-partcombineSoloIOnce = \partcombineForce #'solo1 ##t
-partcombineSoloII = \partcombineForce #'solo2 ##f
-partcombineSoloIIOnce = \partcombineForce #'solo2 ##t
-partcombineAutomatic = \partcombineForce ##f ##f
-partcombineAutomaticOnce = \partcombineForce ##f ##t
+%% Part combine forcing to be found in ly/property-init.ly
 
 partial =
 #(define-music-function (dur) (ly:duration?)
index 4a11fcf4d716c818ae3c519a65fcd7c837d3ba19..85adb52bb08b5b3314cecfed4d249097a2de86f2 100644 (file)
@@ -405,6 +405,21 @@ palmMute =
    (_i "Print @var{note} with a triangle-shaped note head.")
    (style-note-heads 'NoteHead 'do note))
 
+%% part combiner
+
+partcombineForce =
+#(define-music-function (type) ((symbol?))
+   (_i "Override the part-combiner.")
+   (if type (propertySet 'partCombineForced type)
+       (propertyUnset 'partCombineForced)))
+
+partcombineApart = \partcombineForce #'apart
+partcombineChords = \partcombineForce #'chords
+partcombineUnisono = \partcombineForce #'unisono
+partcombineSoloI = \partcombineForce #'solo1
+partcombineSoloII = \partcombineForce #'solo2
+partcombineAutomatic = \partcombineForce \default
+
 
 %% phrasing slurs
 
index 50cf12dbb2d188db45321083b1fd40bd21f0d418..756a55579e377935ab3b7242db358a54eb499576 100644 (file)
@@ -1,4 +1,19 @@
-\version "2.16.0"
+\version "2.19.29"
+
+"\\=" =
+#(define-event-function (id event) (number-or-string? ly:event?)
+  (_i "This sets the @code{spanner-id} property of the following
+@var{event} to the given @var{id} (numbers will be converted to a
+string).  This can be used to tell LilyPond how to connect overlapping
+or parallel slurs or phrasing slurs within a single @code{Voice}.
+@lilypond[quote,verbatim]
+\\fixed c' { c\\=1( d\\=2( e\\=1) f\\=2) }
+@end lilypond\n")
+  (set! (ly:music-property event 'spanner-id)
+       (if (number? id)
+           (number->string id)
+           id))
+  event)
 
 startGroup = #(make-span-event 'NoteGroupingEvent START)
 stopGroup = #(make-span-event 'NoteGroupingEvent STOP)
index 353c9b90b142f5f9f74cd74b2da4151b514741df..d3ada97b532f12e754f87ca151bd613772f3f9f5 100644 (file)
@@ -6,10 +6,10 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: lilypond 2.19.27\n"
+"Project-Id-Version: lilypond 2.19.29\n"
 "Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu."
 "lilypond.bugs\n"
-"POT-Creation-Date: 2015-09-12 12:41+0100\n"
+"POT-Creation-Date: 2015-10-18 11:46+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -141,7 +141,7 @@ msgstr ""
 msgid "%s has been replaced by %s"
 msgstr ""
 
-#: convertrules.py:25 lilylib.py:136 warn.cc:223
+#: convertrules.py:25 lilylib.py:136 warn.cc:224
 #, c-format, python-format
 msgid "warning: %s"
 msgstr ""
@@ -810,7 +810,7 @@ msgstr ""
 msgid "Unknown or invalid loglevel '%s'"
 msgstr ""
 
-#: lilylib.py:133 warn.cc:211
+#: lilylib.py:133 warn.cc:212
 #, c-format, python-format
 msgid "error: %s"
 msgstr ""
@@ -902,12 +902,12 @@ msgid ""
 msgstr ""
 
 #: abc2ly.py:1398 convert-ly.py:92 etf2ly.py:1208 lilypond-book.py:231
-#: midi2ly.py:1095 musicxml2ly.py:2590 main.cc:184
+#: midi2ly.py:1095 musicxml2ly.py:2590 main.cc:183
 msgid "show version number and exit"
 msgstr ""
 
 #: abc2ly.py:1401 convert-ly.py:96 etf2ly.py:1204 lilypond-book.py:140
-#: midi2ly.py:1062 musicxml2ly.py:2572 main.cc:163
+#: midi2ly.py:1062 musicxml2ly.py:2572 main.cc:162
 msgid "show this help and exit"
 msgstr ""
 
@@ -932,7 +932,7 @@ msgstr ""
 #. or if there is a LilyPond users list or forum in your language
 #. "Report bugs in English via %s or in YOUR_LANG via URI"
 #: abc2ly.py:1416 convert-ly.py:157 etf2ly.py:1218 lilypond-book.py:258
-#: midi2ly.py:1107 musicxml2ly.py:2674 main.cc:318
+#: midi2ly.py:1107 musicxml2ly.py:2674 main.cc:321
 #, c-format, python-format
 msgid "Report bugs via %s"
 msgstr ""
@@ -983,7 +983,7 @@ msgid ""
 msgstr ""
 
 #: convert-ly.py:111 lilypond-book.py:163 lilypond-book.py:181
-#: musicxml2ly.py:2629 main.cc:177
+#: musicxml2ly.py:2629 main.cc:176
 msgid "LOGLEVEL"
 msgstr ""
 
@@ -1015,7 +1015,7 @@ msgid "make a numbered backup [default: filename.ext~]"
 msgstr ""
 
 #: convert-ly.py:152 etf2ly.py:1212 lilypond-book.py:234 midi2ly.py:1096
-#: main.cc:186
+#: main.cc:185
 msgid "show warranty and copyright"
 msgstr ""
 
@@ -1074,7 +1074,7 @@ msgid ""
 msgstr ""
 
 #: etf2ly.py:1210 midi2ly.py:1067 midi2ly.py:1072 musicxml2ly.py:2659
-#: main.cc:169 main.cc:181
+#: main.cc:168 main.cc:180
 msgid "FILE"
 msgstr ""
 
@@ -1114,7 +1114,7 @@ msgid "add DIR to include path"
 msgstr ""
 
 #: lilypond-book.py:143 lilypond-book.py:150 lilypond-book.py:169
-#: lilypond-book.py:187 lilypond-book.py:208 lilypond-book.py:214 main.cc:168
+#: lilypond-book.py:187 lilypond-book.py:208 lilypond-book.py:214 main.cc:167
 msgid "DIR"
 msgstr ""
 
@@ -1598,91 +1598,91 @@ msgstr ""
 msgid "About <a href=\"%s\">automatic language selection</a>."
 msgstr ""
 
-#: getopt-long.cc:153
+#: getopt-long.cc:155
 #, c-format
 msgid "option `%s' requires an argument"
 msgstr ""
 
-#: getopt-long.cc:157
+#: getopt-long.cc:159
 #, c-format
 msgid "option `%s' does not allow an argument"
 msgstr ""
 
-#: getopt-long.cc:161
+#: getopt-long.cc:163
 #, c-format
 msgid "unrecognized option: `%s'"
 msgstr ""
 
-#: getopt-long.cc:167
+#: getopt-long.cc:169
 #, c-format
 msgid "invalid argument `%s' to option `%s'"
 msgstr ""
 
-#: warn.cc:56
+#: warn.cc:57
 #, c-format
 msgid "Log level set to %d\n"
 msgstr ""
 
-#: warn.cc:89
+#: warn.cc:90
 #, c-format
 msgid "unknown log level `%s', using default (INFO)"
 msgstr ""
 
 #. Some expected warning was not triggered, so print out a warning.
-#: warn.cc:112
+#: warn.cc:113
 #, c-format
 msgid "%d expected warning(s) not encountered: "
 msgstr ""
 
-#: warn.cc:183
+#: warn.cc:184
 #, c-format
 msgid "fatal error: %s"
 msgstr ""
 
-#: warn.cc:192
+#: warn.cc:193
 #, c-format
 msgid "suppressed programming error: %s"
 msgstr ""
 
-#: warn.cc:197
+#: warn.cc:198
 #, c-format
 msgid "programming error: %s"
 msgstr ""
 
-#: warn.cc:198
+#: warn.cc:199
 msgid "continuing, cross fingers"
 msgstr ""
 
-#: warn.cc:207
+#: warn.cc:208
 #, c-format
 msgid "suppressed error: %s"
 msgstr ""
 
-#: warn.cc:219
+#: warn.cc:220
 #, c-format
 msgid "suppressed warning: %s"
 msgstr ""
 
-#: accidental-engraver.cc:180
+#: accidental-engraver.cc:182
 #, c-format
 msgid "accidental typesetting list must begin with context-name: %s"
 msgstr ""
 
-#: accidental-engraver.cc:207
+#: accidental-engraver.cc:209
 #, c-format
 msgid "procedure or context-name expected for accidental rule, found %s"
 msgstr ""
 
-#: accidental.cc:141
+#: accidental.cc:144
 #, c-format
 msgid "Could not find glyph-name for alteration %s"
 msgstr ""
 
-#: accidental.cc:157
+#: accidental.cc:160
 msgid "natural alteration glyph not found"
 msgstr ""
 
-#: all-font-metrics.cc:159
+#: all-font-metrics.cc:161
 #, c-format
 msgid "cannot find font: `%s'"
 msgstr ""
@@ -1695,24 +1695,24 @@ msgstr ""
 msgid "no heads for arpeggio found?"
 msgstr ""
 
-#: axis-group-engraver.cc:149
+#: axis-group-engraver.cc:151
 msgid "Axis_group_engraver: vertical group already has a parent"
 msgstr ""
 
-#: axis-group-engraver.cc:150
+#: axis-group-engraver.cc:152
 msgid "are there two Axis_group_engravers?"
 msgstr ""
 
-#: axis-group-engraver.cc:151
+#: axis-group-engraver.cc:153
 msgid "removing this vertical group"
 msgstr ""
 
-#: axis-group-interface.cc:716
+#: axis-group-interface.cc:721
 #, c-format
 msgid "\"%s\" is not a valid outside-staff-placement-directive"
 msgstr ""
 
-#: axis-group-interface.cc:788
+#: axis-group-interface.cc:793
 msgid "an outside-staff object should have a direction, defaulting to up"
 msgstr ""
 
@@ -1729,7 +1729,7 @@ msgstr ""
 msgid "unterminated beam"
 msgstr ""
 
-#: beam-engraver.cc:282 chord-tremolo-engraver.cc:149
+#: beam-engraver.cc:282 chord-tremolo-engraver.cc:151
 msgid "stem must have Rhythmic structure"
 msgstr ""
 
@@ -1742,21 +1742,21 @@ msgid "beam was started here"
 msgstr ""
 
 #. We are completely screwed.
-#: beam-quanting.cc:850
+#: beam-quanting.cc:853
 msgid "no viable initial configuration found: may not find good beam slope"
 msgstr ""
 
-#: beam.cc:183
+#: beam.cc:187
 msgid "removing beam with no stems"
 msgstr ""
 
-#: change-iterator.cc:34
+#: change-iterator.cc:36
 #, c-format
 msgid "cannot change `%s' to `%s'"
 msgstr ""
 
 #. FIXME: constant error message.
-#: change-iterator.cc:67
+#: change-iterator.cc:69
 msgid "cannot find context to switch to"
 msgstr ""
 
@@ -1767,72 +1767,72 @@ msgstr ""
 #.
 #. last->translator_id_string () = get_change
 #. ()->change_to_id_string ();
-#: change-iterator.cc:78
+#: change-iterator.cc:80
 #, c-format
 msgid "not changing to same context type: %s"
 msgstr ""
 
 #. FIXME: incomprehensible message
-#: change-iterator.cc:82
+#: change-iterator.cc:84
 msgid "none of these in my family"
 msgstr ""
 
-#: chord-tremolo-engraver.cc:88
+#: chord-tremolo-engraver.cc:90
 msgid "No tremolo to end"
 msgstr ""
 
-#: chord-tremolo-engraver.cc:109
+#: chord-tremolo-engraver.cc:111
 msgid "unterminated chord tremolo"
 msgstr ""
 
-#: clef.cc:65
+#: clef.cc:67
 #, c-format
 msgid "clef `%s' not found"
 msgstr ""
 
-#: cluster.cc:120
+#: cluster.cc:123
 #, c-format
 msgid "unknown cluster style `%s'"
 msgstr ""
 
-#: cluster.cc:157
+#: cluster.cc:160
 msgid "junking empty cluster"
 msgstr ""
 
-#: coherent-ligature-engraver.cc:110
+#: coherent-ligature-engraver.cc:112
 #, c-format
 msgid "Coherent_ligature_engraver: setting `spacing-increment=0.01': ptr=%ul"
 msgstr ""
 
-#: constrained-breaking.cc:187 constrained-breaking.cc:206
+#: constrained-breaking.cc:189 constrained-breaking.cc:208
 msgid "cannot find line breaking that satisfies constraints"
 msgstr ""
 
-#: context-property.cc:46
+#: context-property.cc:45
 msgid "need symbol arguments for \\override and \\revert"
 msgstr ""
 
-#: context.cc:144
+#: context.cc:146
 #, c-format
 msgid "cannot find or create new `%s'"
 msgstr ""
 
-#: context.cc:223
+#: context.cc:225
 #, c-format
 msgid "cannot find or create `%s' called `%s'"
 msgstr ""
 
-#: context.cc:416
+#: context.cc:456
 #, c-format
 msgid "cannot find or create: `%s'"
 msgstr ""
 
-#: context.cc:430
+#: context.cc:470
 #, c-format
 msgid "cannot find or create new Bottom = \"%s\""
 msgstr ""
 
-#: custos.cc:87
+#: custos.cc:88
 #, c-format
 msgid "custos `%s' not found"
 msgstr ""
@@ -1854,19 +1854,19 @@ msgstr ""
 msgid "Already listening to dispatcher, ignoring request"
 msgstr ""
 
-#: dots.cc:48
+#: dots.cc:50
 #, c-format
 msgid "dot `%s' not found"
 msgstr ""
 
-#: dynamic-engraver.cc:169
+#: dynamic-engraver.cc:171
 #, c-format
 msgid ""
 "unknown crescendo style: %s\n"
 "defaulting to hairpin."
 msgstr ""
 
-#: dynamic-engraver.cc:234 slur-proto-engraver.cc:119
+#: dynamic-engraver.cc:236 slur-proto-engraver.cc:159
 #, c-format
 msgid "unterminated %s"
 msgstr ""
@@ -1878,15 +1878,15 @@ msgstr ""
 msgid "(De)crescendo with unspecified starting volume in MIDI."
 msgstr ""
 
-#: episema-engraver.cc:75
+#: episema-engraver.cc:77
 msgid "already have an episema"
 msgstr ""
 
-#: episema-engraver.cc:88
+#: episema-engraver.cc:90
 msgid "cannot find start of episema"
 msgstr ""
 
-#: episema-engraver.cc:137
+#: episema-engraver.cc:139
 msgid "unterminated episema"
 msgstr ""
 
@@ -1894,68 +1894,68 @@ msgstr ""
 msgid "unterminated extender"
 msgstr ""
 
-#: flag.cc:133
+#: flag.cc:135
 #, c-format
 msgid "flag `%s' not found"
 msgstr ""
 
-#: flag.cc:153
+#: flag.cc:155
 #, c-format
 msgid "flag stroke `%s' not found"
 msgstr ""
 
-#: font-config-scheme.cc:151 font-config.cc:82
+#: font-config-scheme.cc:153 font-config.cc:85
 #, c-format
 msgid "failed adding font directory: %s"
 msgstr ""
 
-#: font-config-scheme.cc:153 font-config.cc:84
+#: font-config-scheme.cc:155 font-config.cc:87
 #, c-format
 msgid "Adding font directory: %s"
 msgstr ""
 
-#: font-config-scheme.cc:167
+#: font-config-scheme.cc:169
 #, c-format
 msgid "failed adding font file: %s"
 msgstr ""
 
-#: font-config-scheme.cc:169
+#: font-config-scheme.cc:171
 #, c-format
 msgid "Adding font file: %s"
 msgstr ""
 
-#: font-config.cc:38
+#: font-config.cc:41
 msgid "Initializing FontConfig..."
 msgstr ""
 
-#: font-config.cc:70
+#: font-config.cc:73
 #, c-format
 msgid "failed to add fontconfig configuration file `%s'"
 msgstr ""
 
-#: font-config.cc:73
+#: font-config.cc:76
 #, c-format
 msgid "Adding fontconfig configuration file: %s"
 msgstr ""
 
-#: font-config.cc:86
+#: font-config.cc:89
 msgid "Building font database..."
 msgstr ""
 
-#: footnote-engraver.cc:87
+#: footnote-engraver.cc:89
 msgid "Must be footnote-event."
 msgstr ""
 
-#: general-scheme.cc:403
+#: general-scheme.cc:405
 #, c-format
 msgid "failed redirecting stderr to `%s'"
 msgstr ""
 
-#: general-scheme.cc:482 output-ps.scm:48
+#: general-scheme.cc:484 output-ps.scm:48
 msgid "Found infinity or nan in output.  Substituting 0.0"
 msgstr ""
 
-#: glissando-engraver.cc:158
+#: glissando-engraver.cc:161
 msgid "unterminated glissando"
 msgstr ""
 
@@ -1972,42 +1972,42 @@ msgstr ""
 msgid "elapsed time: %.2f seconds"
 msgstr ""
 
-#: gregorian-ligature-engraver.cc:70
+#: gregorian-ligature-engraver.cc:72
 #, c-format
 msgid "\\%s ignored"
 msgstr ""
 
-#: gregorian-ligature-engraver.cc:75
+#: gregorian-ligature-engraver.cc:77
 #, c-format
 msgid "implied \\%s added"
 msgstr ""
 
 #. ligature may not start with 2nd head of pes or flexa
-#: gregorian-ligature-engraver.cc:224
+#: gregorian-ligature-engraver.cc:226
 msgid "cannot apply `\\~' on first head of ligature"
 msgstr ""
 
 #. (pitch == prev_pitch)
-#: gregorian-ligature-engraver.cc:236
+#: gregorian-ligature-engraver.cc:238
 msgid "cannot apply `\\~' on heads with identical pitch"
 msgstr ""
 
-#: grob-interface.cc:68
+#: grob-interface.cc:70
 #, c-format
 msgid "Unknown interface `%s'"
 msgstr ""
 
-#: grob-interface.cc:79
+#: grob-interface.cc:81
 #, c-format
 msgid "Grob `%s' has no interface for property `%s'"
 msgstr ""
 
-#: grob-property.cc:33
+#: grob-property.cc:32
 #, c-format
 msgid "%d: %s"
 msgstr ""
 
-#: grob.cc:496
+#: grob.cc:499
 #, c-format
 msgid "ignored infinite %s-offset"
 msgstr ""
@@ -2020,11 +2020,11 @@ msgstr ""
 msgid "decrescendo too small"
 msgstr ""
 
-#: horizontal-bracket-engraver.cc:62
+#: horizontal-bracket-engraver.cc:64
 msgid "do not have that many brackets"
 msgstr ""
 
-#: horizontal-bracket-engraver.cc:71
+#: horizontal-bracket-engraver.cc:73
 msgid "conflicting note group events"
 msgstr ""
 
@@ -2036,17 +2036,17 @@ msgstr ""
 msgid "unterminated hyphen; removing"
 msgstr ""
 
-#: includable-lexer.cc:71 lily-guile.cc:92 lily-parser-scheme.cc:108
+#: includable-lexer.cc:72 lily-guile.cc:94 lily-parser-scheme.cc:110
 #, c-format
 msgid "cannot find file: `%s'"
 msgstr ""
 
-#: includable-lexer.cc:73 lily-parser-scheme.cc:100
+#: includable-lexer.cc:74 lily-parser-scheme.cc:102
 #, c-format
 msgid "(search path: `%s')"
 msgstr ""
 
-#: input.cc:138 source-file.cc:180 source-file.cc:195
+#: input.cc:139 source-file.cc:188 source-file.cc:203
 msgid "position unknown"
 msgstr ""
 
@@ -2054,12 +2054,12 @@ msgstr ""
 msgid "Incomplete keyAlterationOrder for key signature"
 msgstr ""
 
-#: key-signature-interface.cc:77
+#: key-signature-interface.cc:79
 #, c-format
 msgid "No glyph found for alteration: %s"
 msgstr ""
 
-#: key-signature-interface.cc:87
+#: key-signature-interface.cc:89
 msgid "alteration not found"
 msgstr ""
 
@@ -2091,25 +2091,25 @@ msgstr ""
 msgid "ligature was started here"
 msgstr ""
 
-#: lily-guile.cc:94
+#: lily-guile.cc:96
 #, c-format
 msgid "(load path: `%s')"
 msgstr ""
 
-#: lily-guile.cc:413
+#: lily-guile.cc:415
 #, c-format
 msgid "cannot find property type-check for `%s' (%s)."
 msgstr ""
 
-#: lily-guile.cc:416
+#: lily-guile.cc:418
 msgid "perhaps a typing error?"
 msgstr ""
 
-#: lily-guile.cc:423
+#: lily-guile.cc:425
 msgid "skipping assignment"
 msgstr ""
 
-#: lily-guile.cc:442
+#: lily-guile.cc:444
 #, c-format
 msgid "type check for `%s' failed; value `%s' must be of type `%s'"
 msgstr ""
@@ -2118,20 +2118,20 @@ msgstr ""
 #. unsmob<T> delivers true.  This means that unsmob<T> is a
 #. matching check from a base class of T, but var is of an
 #. incompatible derived type.
-#: lily-guile.cc:462
+#: lily-guile.cc:464
 msgid "Wrong kind of "
 msgstr ""
 
-#: lily-lexer.cc:251
+#: lily-lexer.cc:252
 msgid "include files are not allowed in safe mode"
 msgstr ""
 
-#: lily-lexer.cc:278
+#: lily-lexer.cc:279
 #, c-format
 msgid "identifier name is a keyword: `%s'"
 msgstr ""
 
-#: lily-lexer.cc:299 lily-lexer.cc:312
+#: lily-lexer.cc:300 lily-lexer.cc:313
 #, c-format
 msgid "%s:EOF"
 msgstr ""
@@ -2141,57 +2141,57 @@ msgstr ""
 msgid "Uninitialized variable `%s' in module (%s)"
 msgstr ""
 
-#: lily-parser-scheme.cc:80
+#: lily-parser-scheme.cc:82
 #, c-format
 msgid "Changing working directory to: `%s'"
 msgstr ""
 
-#: lily-parser-scheme.cc:84
+#: lily-parser-scheme.cc:86
 #, c-format
 msgid "unable to change directory to: `%s'"
 msgstr ""
 
-#: lily-parser-scheme.cc:99
+#: lily-parser-scheme.cc:101
 #, c-format
 msgid "cannot find init file: `%s'"
 msgstr ""
 
-#: lily-parser-scheme.cc:117
+#: lily-parser-scheme.cc:119
 #, c-format
 msgid "Processing `%s'"
 msgstr ""
 
-#: lily-parser-scheme.cc:210
+#: lily-parser-scheme.cc:212
 msgid ""
 "ly:parser-parse-string is only valid with a new parser.  Use ly:parser-"
 "include-string instead."
 msgstr ""
 
-#: lily-parser-scheme.cc:241
+#: lily-parser-scheme.cc:243
 msgid ""
 "ly:parse-string-expression is only valid with a new parser.  Use ly:parser-"
 "include-string instead."
 msgstr ""
 
-#: lily-parser.cc:106
+#: lily-parser.cc:107
 msgid "Parsing..."
 msgstr ""
 
-#: lookup.cc:178
+#: lookup.cc:179
 #, c-format
 msgid "Not drawing a box with negative dimension, %.2f by %.2f."
 msgstr ""
 
-#: lyric-combine-music-iterator.cc:204
+#: lyric-combine-music-iterator.cc:206
 msgid "argument of \\lyricsto should contain Lyrics context"
 msgstr ""
 
-#: lyric-combine-music-iterator.cc:344
+#: lyric-combine-music-iterator.cc:346
 #, c-format
 msgid "cannot find %s `%s'"
 msgstr ""
 
-#: main.cc:106
+#: main.cc:105
 #, c-format
 msgid ""
 "This program is free software.  It is covered by the GNU General Public\n"
@@ -2200,7 +2200,7 @@ msgid ""
 "information.\n"
 msgstr ""
 
-#: main.cc:112
+#: main.cc:111
 msgid ""
 "    This program is free software; you can redistribute it and/or\n"
 "modify it under the terms of the GNU General Public License as \n"
@@ -2218,102 +2218,102 @@ msgid ""
 "Boston, MA 02111-1307, USA.\n"
 msgstr ""
 
-#: main.cc:150
+#: main.cc:149
 msgid "SYM[=VAL]"
 msgstr ""
 
-#: main.cc:151
+#: main.cc:150
 msgid ""
 "set Scheme option SYM to VAL (default: #t).\n"
 "Use -dhelp for help."
 msgstr ""
 
-#: main.cc:155
+#: main.cc:154
 msgid "EXPR"
 msgstr ""
 
-#: main.cc:155
+#: main.cc:154
 msgid "evaluate scheme code"
 msgstr ""
 
 #. Bug in option parser: --output =foe is taken as an abbreviation
 #. for --output-format.
-#: main.cc:158
+#: main.cc:157
 msgid "FORMATs"
 msgstr ""
 
-#: main.cc:158
+#: main.cc:157
 msgid "dump FORMAT,...  Also as separate options:"
 msgstr ""
 
-#: main.cc:159
+#: main.cc:158
 msgid "generate PDF (default)"
 msgstr ""
 
-#: main.cc:160
+#: main.cc:159
 msgid "generate PNG"
 msgstr ""
 
-#: main.cc:161
+#: main.cc:160
 msgid "generate PostScript"
 msgstr ""
 
-#: main.cc:162
+#: main.cc:161
 msgid "generate big PDF files"
 msgstr ""
 
-#: main.cc:165
+#: main.cc:164
 msgid "FIELD"
 msgstr ""
 
-#: main.cc:165
+#: main.cc:164
 msgid ""
 "dump header field FIELD to file\n"
 "named BASENAME.FIELD"
 msgstr ""
 
-#: main.cc:168
+#: main.cc:167
 msgid "add DIR to search path"
 msgstr ""
 
-#: main.cc:169
+#: main.cc:168
 msgid "use FILE as init file"
 msgstr ""
 
-#: main.cc:172
+#: main.cc:171
 msgid "USER, GROUP, JAIL, DIR"
 msgstr ""
 
-#: main.cc:172
+#: main.cc:171
 msgid ""
 "chroot to JAIL, become USER:GROUP\n"
 "and cd into DIR"
 msgstr ""
 
-#: main.cc:177
+#: main.cc:176
 msgid ""
 "print log messages according to LOGLEVEL.  Possible values are:\n"
 "NONE, ERROR, WARNING, BASIC, PROGRESS, INFO (default) and DEBUG."
 msgstr ""
 
-#: main.cc:181
+#: main.cc:180
 msgid "write output to FILE (suffix will be added)"
 msgstr ""
 
-#: main.cc:182
+#: main.cc:181
 msgid "relocate using directory of lilypond program"
 msgstr ""
 
-#: main.cc:183
+#: main.cc:182
 msgid "no progress, only error messages (equivalent to loglevel=ERROR)"
 msgstr ""
 
-#: main.cc:185
+#: main.cc:184
 msgid "be verbose (equivalent to loglevel=DEBUG)"
 msgstr ""
 
 #. Do not update the copyright years here, run `make grand-replace'
-#: main.cc:264
+#: main.cc:267
 #, c-format
 msgid ""
 "Copyright (c) %s by\n"
@@ -2321,118 +2321,118 @@ msgid ""
 msgstr ""
 
 #. No version number or newline here.  It confuses help2man.
-#: main.cc:302
+#: main.cc:305
 #, c-format
 msgid "Usage: %s [OPTION]... FILE..."
 msgstr ""
 
-#: main.cc:304
+#: main.cc:307
 msgid "Typeset music and/or produce MIDI from FILE."
 msgstr ""
 
-#: main.cc:306
+#: main.cc:309
 msgid "LilyPond produces beautiful music notation."
 msgstr ""
 
-#: main.cc:308
+#: main.cc:311
 #, c-format
 msgid "For more information, see %s"
 msgstr ""
 
-#: main.cc:310
+#: main.cc:313
 msgid "Options:"
 msgstr ""
 
-#: main.cc:377
+#: main.cc:380
 #, c-format
 msgid "expected %d arguments with jail, found: %u"
 msgstr ""
 
-#: main.cc:391
+#: main.cc:394
 #, c-format
 msgid "no such user: %s"
 msgstr ""
 
-#: main.cc:393
+#: main.cc:396
 #, c-format
 msgid "cannot get user id from user name: %s: %s"
 msgstr ""
 
-#: main.cc:408
+#: main.cc:411
 #, c-format
 msgid "no such group: %s"
 msgstr ""
 
-#: main.cc:410
+#: main.cc:413
 #, c-format
 msgid "cannot get group id from group name: %s: %s"
 msgstr ""
 
-#: main.cc:418
+#: main.cc:421
 #, c-format
 msgid "cannot chroot to: %s: %s"
 msgstr ""
 
-#: main.cc:425
+#: main.cc:428
 #, c-format
 msgid "cannot change group id to: %d: %s"
 msgstr ""
 
-#: main.cc:431
+#: main.cc:434
 #, c-format
 msgid "cannot change user id to: %d: %s"
 msgstr ""
 
-#: main.cc:437
+#: main.cc:440
 #, c-format
 msgid "cannot change working directory to: %s: %s"
 msgstr ""
 
-#: main.cc:826
+#: main.cc:829
 #, c-format
 msgid "exception caught: %s"
 msgstr ""
 
 #. FIXME: constant error message.
-#: mark-engraver.cc:150
+#: mark-engraver.cc:149
 msgid "rehearsalMark must have integer value"
 msgstr ""
 
-#: mark-engraver.cc:156
+#: mark-engraver.cc:155
 msgid "mark label must be a markup object"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:100
+#: mensural-ligature-engraver.cc:102
 msgid "ligature with less than 2 heads -> skipping"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:127
+#: mensural-ligature-engraver.cc:129
 msgid "cannot determine pitch of ligature primitive -> skipping"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:141
+#: mensural-ligature-engraver.cc:143
 msgid "single note ligature - skipping"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:152
+#: mensural-ligature-engraver.cc:154
 msgid "prime interval within ligature -> skipping"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:163
+#: mensural-ligature-engraver.cc:165
 msgid "mensural ligature: duration none of Mx, L, B, S -> skipping"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:206
+#: mensural-ligature-engraver.cc:208
 msgid "semibrevis must be followed by another one -> skipping"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:216
+#: mensural-ligature-engraver.cc:218
 msgid ""
 "semibreves can only appear at the beginning of a ligature,\n"
 "and there may be only zero or two of them"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:236
+#: mensural-ligature-engraver.cc:238
 msgid ""
 "invalid ligatura ending:\n"
 "when the last note is a descending brevis,\n"
@@ -2440,35 +2440,35 @@ msgid ""
 "or the ligatura must be LB or SSB"
 msgstr ""
 
-#: mensural-ligature-engraver.cc:396
+#: mensural-ligature-engraver.cc:398
 msgid "unexpected case fall-through"
 msgstr ""
 
-#: midi-control-function-performer.cc:107 staff-performer.cc:153
+#: midi-control-function-performer.cc:109 staff-performer.cc:157
 #, c-format
 msgid "ignoring out-of-range value change for MIDI property `%s'"
 msgstr ""
 
-#: midi-item.cc:93
+#: midi-item.cc:95
 #, c-format
 msgid "no such MIDI instrument: `%s'"
 msgstr ""
 
-#: midi-item.cc:179
+#: midi-item.cc:181
 msgid "Time signature with more than 255 beats.  Truncating"
 msgstr ""
 
-#: midi-stream.cc:38
+#: midi-stream.cc:39
 #, c-format
 msgid "cannot open for write: %s: %s"
 msgstr ""
 
-#: midi-stream.cc:54
+#: midi-stream.cc:55
 #, c-format
 msgid "cannot write to file: `%s'"
 msgstr ""
 
-#: minimal-page-breaking.cc:40 paper-score.cc:116
+#: minimal-page-breaking.cc:40 paper-score.cc:118
 msgid "Calculating line breaks..."
 msgstr ""
 
@@ -2486,66 +2486,66 @@ msgstr ""
 msgid "octave check failed; expected \"%s\", found: \"%s\""
 msgstr ""
 
-#: new-fingering-engraver.cc:113
+#: new-fingering-engraver.cc:115
 msgid "cannot add text scripts to individual note heads"
 msgstr ""
 
-#: new-fingering-engraver.cc:269
+#: new-fingering-engraver.cc:271
 msgid "no placement found for fingerings"
 msgstr ""
 
-#: new-fingering-engraver.cc:270
+#: new-fingering-engraver.cc:272
 msgid "placing below"
 msgstr ""
 
-#: note-collision.cc:510
+#: note-collision.cc:512
 msgid "this Voice needs a \\voiceXx or \\shiftXx setting"
 msgstr ""
 
-#: note-column.cc:150
+#: note-column.cc:149
 msgid "cannot have note heads and rests together on a stem"
 msgstr ""
 
-#: note-head.cc:95
+#: note-head.cc:96
 #, c-format
 msgid "none of note heads `%s' or `%s' found"
 msgstr ""
 
-#: note-heads-engraver.cc:76
+#: note-heads-engraver.cc:77
 msgid "NoteEvent without pitch"
 msgstr ""
 
-#: open-type-font.cc:45
+#: open-type-font.cc:47
 #, c-format
 msgid "cannot allocate %lu bytes"
 msgstr ""
 
-#: open-type-font.cc:49
+#: open-type-font.cc:51
 #, c-format
 msgid "cannot load font table: %s"
 msgstr ""
 
-#: open-type-font.cc:54
+#: open-type-font.cc:56
 #, c-format
 msgid "FreeType error: %s"
 msgstr ""
 
-#: open-type-font.cc:115
+#: open-type-font.cc:117
 #, c-format
 msgid "unsupported font format: %s"
 msgstr ""
 
-#: open-type-font.cc:117
+#: open-type-font.cc:119
 #, c-format
 msgid "error reading font file %s: %s"
 msgstr ""
 
-#: open-type-font.cc:192
+#: open-type-font.cc:194
 #, c-format
 msgid "FT_Get_Glyph_Name () Freetype error: %s"
 msgstr ""
 
-#: open-type-font.cc:340 pango-font.cc:258
+#: open-type-font.cc:342 pango-font.cc:260
 #, c-format
 msgid "FT_Get_Glyph_Name () error: %s"
 msgstr ""
@@ -2585,153 +2585,153 @@ msgstr ""
 msgid "best score for this sys-count: %f"
 msgstr ""
 
-#: optimal-page-breaking.cc:216 page-turn-page-breaking.cc:249
-#: paper-score.cc:156
+#: optimal-page-breaking.cc:216 page-turn-page-breaking.cc:252
+#: paper-score.cc:158
 msgid "Drawing systems..."
 msgstr ""
 
-#: output-def.cc:229
+#: output-def.cc:231
 msgid "margins do not fit with line-width, setting default values"
 msgstr ""
 
-#: output-def.cc:236
+#: output-def.cc:238
 msgid ""
 "systems run off the page due to improper paper settings, setting default "
 "values"
 msgstr ""
 
-#: page-breaking.cc:276
+#: page-breaking.cc:279
 msgid ""
 "ignoring min-systems-per-page and max-systems-per-page because systems-per-"
 "page was set"
 msgstr ""
 
-#: page-breaking.cc:281
+#: page-breaking.cc:284
 msgid ""
 "min-systems-per-page is larger than max-systems-per-page, ignoring both "
 "values"
 msgstr ""
 
-#: page-breaking.cc:636
+#: page-breaking.cc:639
 #, c-format
 msgid "page %d has been compressed"
 msgstr ""
 
-#: page-layout-problem.cc:400
+#: page-layout-problem.cc:402
 msgid ""
 "A page layout problem has been initiated that cannot accommodate footnotes."
 msgstr ""
 
-#: page-layout-problem.cc:729
+#: page-layout-problem.cc:731
 msgid "ragged-bottom was specified, but page must be compressed"
 msgstr ""
 
-#: page-layout-problem.cc:732
+#: page-layout-problem.cc:734
 #, c-format
 msgid "compressing over-full page by %.1f staff-spaces"
 msgstr ""
 
-#: page-layout-problem.cc:1197
+#: page-layout-problem.cc:1199
 msgid "staff-affinities should only decrease"
 msgstr ""
 
-#: page-turn-page-breaking.cc:169
+#: page-turn-page-breaking.cc:172
 #, c-format
 msgid "page-turn-page-breaking: breaking from %d to %d"
 msgstr ""
 
-#: page-turn-page-breaking.cc:218
+#: page-turn-page-breaking.cc:221
 msgid ""
 "cannot fit the first page turn onto a single page.  Consider setting first-"
 "page-number to an even number."
 msgstr ""
 
-#: page-turn-page-breaking.cc:231
+#: page-turn-page-breaking.cc:234
 #, c-format
 msgid "Calculating page and line breaks (%d possible page breaks)..."
 msgstr ""
 
-#: page-turn-page-breaking.cc:301
+#: page-turn-page-breaking.cc:304
 #, c-format
 msgid "break starting at page %d"
 msgstr ""
 
-#: page-turn-page-breaking.cc:302
+#: page-turn-page-breaking.cc:305
 #, c-format
 msgid "\tdemerits: %f"
 msgstr ""
 
-#: page-turn-page-breaking.cc:303
+#: page-turn-page-breaking.cc:306
 #, c-format
 msgid "\tsystem count: %d"
 msgstr ""
 
-#: page-turn-page-breaking.cc:304
+#: page-turn-page-breaking.cc:307
 #, c-format
 msgid "\tpage count: %d"
 msgstr ""
 
-#: page-turn-page-breaking.cc:305
+#: page-turn-page-breaking.cc:308
 #, c-format
 msgid "\tprevious break: %d"
 msgstr ""
 
-#: pango-font.cc:247
+#: pango-font.cc:249
 #, c-format
 msgid "no glyph for character U+%0X in font `%s'"
 msgstr ""
 
-#: pango-font.cc:274
+#: pango-font.cc:276
 #, c-format
 msgid ""
 "Glyph has no name, but font supports glyph naming.\n"
 "Skipping glyph U+%0X, file %s"
 msgstr ""
 
-#: pango-font.cc:324
+#: pango-font.cc:326
 #, c-format
 msgid "no PostScript font name for font `%s'"
 msgstr ""
 
-#: pango-font.cc:374
+#: pango-font.cc:376
 msgid "FreeType face has no PostScript font name"
 msgstr ""
 
-#: paper-book.cc:200
+#: paper-book.cc:202
 #, c-format
 msgid "program option -dprint-pages not supported by backend `%s'"
 msgstr ""
 
-#: paper-book.cc:219
+#: paper-book.cc:221
 #, c-format
 msgid "program option -dpreview not supported by backend `%s'"
 msgstr ""
 
-#: paper-column-engraver.cc:263
+#: paper-column-engraver.cc:265
 msgid ""
 "forced break was overridden by some other event, should you be using bar "
 "checks?"
 msgstr ""
 
-#: paper-outputter-scheme.cc:41
+#: paper-outputter-scheme.cc:43
 #, c-format
 msgid "Layout output to `%s'..."
 msgstr ""
 
-#: paper-score.cc:128
+#: paper-score.cc:130
 #, c-format
 msgid "Element count %d (spanners %d) "
 msgstr ""
 
-#: paper-score.cc:132
+#: paper-score.cc:134
 msgid "Preprocessing graphical objects..."
 msgstr ""
 
-#: parse-scm.cc:124
+#: parse-scm.cc:123
 msgid "GUILE signaled an error for the expression beginning here"
 msgstr ""
 
-#: pdf-scheme.cc:65
+#: pdf-scheme.cc:64
 #, c-format
 msgid "Conversion of string `%s' to UTF-16be failed: %s"
 msgstr ""
@@ -2740,128 +2740,128 @@ msgstr ""
 msgid "unterminated percent repeat"
 msgstr ""
 
-#: performance.cc:76
+#: performance.cc:77
 msgid "Track..."
 msgstr ""
 
-#: performance.cc:126
+#: performance.cc:127
 #, c-format
 msgid "MIDI output to `%s'..."
 msgstr ""
 
-#: piano-pedal-engraver.cc:279
+#: piano-pedal-engraver.cc:281
 #, c-format
 msgid "expect 3 strings for piano pedals, found: %ld"
 msgstr ""
 
-#: piano-pedal-engraver.cc:294 piano-pedal-engraver.cc:305
-#: piano-pedal-performer.cc:104
+#: piano-pedal-engraver.cc:296 piano-pedal-engraver.cc:307
+#: piano-pedal-performer.cc:107
 #, c-format
 msgid "cannot find start of piano pedal: `%s'"
 msgstr ""
 
-#: piano-pedal-engraver.cc:340
+#: piano-pedal-engraver.cc:342
 #, c-format
 msgid "cannot find start of piano pedal bracket: `%s'"
 msgstr ""
 
-#: program-option-scheme.cc:223
+#: program-option-scheme.cc:225
 #, c-format
 msgid "no such internal option: %s"
 msgstr ""
 
-#: property-iterator.cc:115
+#: property-iterator.cc:66
 #, c-format
 msgid "not a grob name, `%s'"
 msgstr ""
 
-#: relative-octave-check.cc:49
+#: relative-octave-check.cc:51
 msgid "Failed octave check, got: "
 msgstr ""
 
-#: relocate.cc:56
+#: relocate.cc:59
 #, c-format
 msgid "Setting %s to %s"
 msgstr ""
 
 #. this warning should only be printed in debug mode!
-#: relocate.cc:77
+#: relocate.cc:80
 #, c-format
 msgid "no such file: %s for %s"
 msgstr ""
 
 #. this warning should only be printed in debug mode!
 #. this warning should only be printed in debug mode
-#: relocate.cc:88 relocate.cc:106
+#: relocate.cc:91 relocate.cc:109
 #, c-format
 msgid "no such directory: %s for %s"
 msgstr ""
 
-#: relocate.cc:97
+#: relocate.cc:100
 #, c-format
 msgid "%s=%s (prepend)\n"
 msgstr ""
 
-#: relocate.cc:124
+#: relocate.cc:127
 #, c-format
 msgid "not relocating, no %s/ or current/ found under %s"
 msgstr ""
 
-#: relocate.cc:134
+#: relocate.cc:137
 #, c-format
 msgid "Relocation: compile datadir=%s, new datadir=%s"
 msgstr ""
 
-#: relocate.cc:146
+#: relocate.cc:149
 #, c-format
 msgid "Relocation: framework_prefix=%s"
 msgstr ""
 
-#: relocate.cc:172
+#: relocate.cc:175
 #, c-format
 msgid "Relocation: is absolute: argv0=%s\n"
 msgstr ""
 
-#: relocate.cc:178
+#: relocate.cc:181
 #, c-format
 msgid "Relocation : from cwd: argv0=%s\n"
 msgstr ""
 
-#: relocate.cc:196
+#: relocate.cc:199
 #, c-format
 msgid ""
 "Relocation: from PATH=%s\n"
 "argv0=%s\n"
 msgstr ""
 
-#: relocate.cc:222
+#: relocate.cc:225
 msgid "LILYPONDPREFIX is obsolete, use LILYPOND_DATADIR"
 msgstr ""
 
-#: relocate.cc:347
+#: relocate.cc:350
 #, c-format
 msgid "Relocation file: %s"
 msgstr ""
 
-#: relocate.cc:351 source-file.cc:65
+#: relocate.cc:354 source-file.cc:73
 #, c-format
 msgid "cannot open file: `%s'"
 msgstr ""
 
-#: relocate.cc:381
+#: relocate.cc:384
 #, c-format
 msgid "Unknown relocation command %s"
 msgstr ""
 
-#: rest-collision.cc:154
+#: rest-collision.cc:155
 msgid "cannot resolve rest collision: rest direction not set"
 msgstr ""
 
-#: rest-collision.cc:165 rest-collision.cc:274
+#: rest-collision.cc:166 rest-collision.cc:275
 msgid "too many colliding rests"
 msgstr ""
 
-#: rest.cc:239
+#: rest.cc:241
 #, c-format
 msgid "rest `%s' not found"
 msgstr ""
@@ -2884,100 +2884,100 @@ msgstr ""
 msgid "Aborting"
 msgstr ""
 
-#: score.cc:161
+#: score.cc:160
 msgid "already have music in score"
 msgstr ""
 
-#: score.cc:163
+#: score.cc:162
 msgid "this is the previous music"
 msgstr ""
 
-#: score.cc:169
+#: score.cc:168
 msgid "errors found, ignoring music expression"
 msgstr ""
 
 #. FIXME:
-#: script-engraver.cc:115
+#: script-engraver.cc:117
 msgid "do not know how to interpret articulation:"
 msgstr ""
 
-#: script-engraver.cc:116
+#: script-engraver.cc:118
 msgid " scheme encoding: "
 msgstr ""
 
-#: skyline-pair.cc:135
+#: skyline-pair.cc:137
 msgid "direction must not be CENTER in ly:skyline-pair::skyline"
 msgstr ""
 
-#: slur-proto-engraver.cc:51
+#: slur-proto-engraver.cc:60
 #, c-format
 msgid "direction of %s invalid: %d"
 msgstr ""
 
 #. We already have an old slur, so give a warning
 #. and completely ignore the new slur.
-#: slur-proto-engraver.cc:166
+#: slur-proto-engraver.cc:213
 #, c-format
 msgid "already have %s"
 msgstr ""
 
-#: slur-proto-engraver.cc:183
+#: slur-proto-engraver.cc:230
 #, c-format
 msgid "%s without a cause"
 msgstr ""
 
-#: slur-proto-engraver.cc:244
+#: slur-proto-engraver.cc:297
 #, c-format
 msgid "cannot end %s"
 msgstr ""
 
-#: slur.cc:431
+#: slur.cc:434
 #, c-format
 msgid "Ignoring grob for slur: %s.  avoid-slur not set?"
 msgstr ""
 
-#: source-file.cc:85
+#: source-file.cc:93
 #, c-format
 msgid "expected to read %d characters, got %d"
 msgstr ""
 
-#: staff-performer.cc:301
+#: staff-performer.cc:305
 msgid "MIDI channel wrapped around"
 msgstr ""
 
-#: staff-performer.cc:302
+#: staff-performer.cc:306
 msgid "remapping modulo 16"
 msgstr ""
 
-#: stem-engraver.cc:100
+#: stem-engraver.cc:102
 msgid "tremolo duration is too long"
 msgstr ""
 
-#: stem-engraver.cc:152
+#: stem-engraver.cc:154
 #, c-format
 msgid "adding note head to incompatible stem (type = %d/%d)"
 msgstr ""
 
-#: stem-engraver.cc:155
+#: stem-engraver.cc:157
 msgid "maybe input should specify polyphonic voices"
 msgstr ""
 
-#: stem.cc:128
+#: stem.cc:130
 msgid "weird stem size, check for narrow beams"
 msgstr ""
 
-#: system.cc:195
+#: system.cc:197
 #, c-format
 msgid "Element count %d"
 msgstr ""
 
-#: system.cc:506
+#: system.cc:508
 #, c-format
 msgid "Grob count %d"
 msgstr ""
 
 #. TODO: Also print the arguments of the markup!
-#: text-interface.cc:139
+#: text-interface.cc:141
 #, c-format
 msgid "Markup depth exceeds maximal value of %d; Markup: %s"
 msgstr ""
@@ -2994,11 +2994,11 @@ msgstr ""
 msgid "unterminated text spanner"
 msgstr ""
 
-#: tie-engraver.cc:121
+#: tie-engraver.cc:123
 msgid "unterminated tie"
 msgstr ""
 
-#: tie-engraver.cc:377
+#: tie-engraver.cc:379
 msgid "lonely tie"
 msgstr ""
 
@@ -3012,7 +3012,7 @@ msgstr ""
 msgid "strange time signature found: %d/%d"
 msgstr ""
 
-#: translator-ctors.cc:68
+#: translator-ctors.cc:70
 #, c-format
 msgid "unknown translator: `%s'"
 msgstr ""
@@ -3022,67 +3022,67 @@ msgstr ""
 msgid "fatal error.  Couldn't find type: %s"
 msgstr ""
 
-#: translator-group.cc:187
+#: translator-group.cc:189
 #, c-format
 msgid "cannot find: `%s'"
 msgstr ""
 
-#: translator.cc:310
+#: translator.cc:313
 #, c-format
 msgid "Two simultaneous %s events, junking this one"
 msgstr ""
 
-#: translator.cc:311
+#: translator.cc:314
 #, c-format
 msgid "Previous %s event here"
 msgstr ""
 
-#: ttf.cc:480 ttf.cc:528
+#: ttf.cc:483 ttf.cc:531
 #, c-format
 msgid "font index %d too large for font `%s', using index 0"
 msgstr ""
 
-#: ttf.cc:512 ttf.cc:562
+#: ttf.cc:515 ttf.cc:565
 msgid "font index must be non-negative, using index 0"
 msgstr ""
 
-#: tuplet-engraver.cc:110
+#: tuplet-engraver.cc:112
 msgid "No tuplet to end"
 msgstr ""
 
-#: vaticana-ligature-engraver.cc:400
+#: vaticana-ligature-engraver.cc:403
 #, c-format
 msgid ""
 "ignored prefix(es) `%s' of this head according to restrictions of the "
 "selected ligature style"
 msgstr ""
 
-#: vaticana-ligature-engraver.cc:466
+#: vaticana-ligature-engraver.cc:469
 msgid ""
 "Ambiguous use of dots in ligature: there are multiple dotted notes with the "
 "same pitch.  The ligature should be split."
 msgstr ""
 
-#: vaticana-ligature-engraver.cc:524
+#: vaticana-ligature-engraver.cc:527
 msgid ""
 "This ligature has a dotted head followed by a non-dotted head.  The ligature "
 "should be split after the last dotted head before this head."
 msgstr ""
 
-#: vaticana-ligature-engraver.cc:736
+#: vaticana-ligature-engraver.cc:739
 #, c-format
 msgid "Vaticana_ligature_engraver: setting `spacing-increment = %f': ptr =%ul"
 msgstr ""
 
-#: vaticana-ligature.cc:94
+#: vaticana-ligature.cc:96
 msgid "flexa-height undefined; assuming 0"
 msgstr ""
 
-#: vaticana-ligature.cc:99
+#: vaticana-ligature.cc:101
 msgid "ascending vaticana style flexa"
 msgstr ""
 
-#: vertical-align-engraver.cc:95
+#: vertical-align-engraver.cc:98
 msgid "Ignoring Vertical_align_engraver in VerticalAxisGroup"
 msgstr ""
 
@@ -3155,154 +3155,158 @@ msgstr ""
 msgid "bad context property path"
 msgstr ""
 
-#: parser.yy:2733
+#: parser.yy:2731
+msgid "markup expected"
+msgstr ""
+
+#: parser.yy:2743
 msgid "simple string expected"
 msgstr ""
 
-#: parser.yy:2750
+#: parser.yy:2760
 msgid "symbol expected"
 msgstr ""
 
-#: parser.yy:2886
+#: parser.yy:2896
 msgid "not a rhythmic event"
 msgstr ""
 
-#: parser.yy:2936
+#: parser.yy:2946
 msgid "post-event expected"
 msgstr ""
 
-#: parser.yy:2945 parser.yy:2950
+#: parser.yy:2955 parser.yy:2960
 msgid "have to be in Lyric mode for lyrics"
 msgstr ""
 
-#: parser.yy:3026
+#: parser.yy:3036
 msgid "expecting string or post-event as script definition"
 msgstr ""
 
-#: parser.yy:3130
+#: parser.yy:3140
 msgid "not an articulation"
 msgstr ""
 
-#: parser.yy:3202 parser.yy:3245
+#: parser.yy:3212 parser.yy:3255
 msgid "not a duration"
 msgstr ""
 
-#: parser.yy:3266
+#: parser.yy:3276
 msgid "bass number expected"
 msgstr ""
 
-#: parser.yy:3358
+#: parser.yy:3368
 msgid "have to be in Note mode for notes"
 msgstr ""
 
-#: parser.yy:3397
+#: parser.yy:3407
 msgid "have to be in Chord mode for chords"
 msgstr ""
 
-#: parser.yy:3440
+#: parser.yy:3450
 msgid "markup outside of text script or \\lyricmode"
 msgstr ""
 
-#: parser.yy:3445
+#: parser.yy:3455
 msgid "unrecognized string, not in text script or \\lyricmode"
 msgstr ""
 
-#: parser.yy:3597 parser.yy:3606
+#: parser.yy:3607 parser.yy:3616
 msgid "not an unsigned integer"
 msgstr ""
 
-#: parser.yy:3693
+#: parser.yy:3703
 msgid "not a markup"
 msgstr ""
 
-#: lexer.ll:193
+#: lexer.ll:194
 msgid "stray UTF-8 BOM encountered"
 msgstr ""
 
-#: lexer.ll:196
+#: lexer.ll:197
 msgid "Skipping UTF-8 BOM"
 msgstr ""
 
-#: lexer.ll:248
+#: lexer.ll:249
 #, c-format
 msgid "Renaming input to: `%s'"
 msgstr ""
 
-#: lexer.ll:265
+#: lexer.ll:266
 msgid "quoted string expected after \\version"
 msgstr ""
 
-#: lexer.ll:269
+#: lexer.ll:270
 msgid "quoted string expected after \\sourcefilename"
 msgstr ""
 
-#: lexer.ll:273
+#: lexer.ll:274
 msgid "integer expected after \\sourcefileline"
 msgstr ""
 
-#: lexer.ll:300
+#: lexer.ll:301
 msgid "\\maininput not allowed outside init files"
 msgstr ""
 
-#: lexer.ll:324
+#: lexer.ll:325
 #, c-format
 msgid "wrong or undefined identifier: `%s'"
 msgstr ""
 
-#: lexer.ll:349
+#: lexer.ll:350
 msgid "string expected after \\include"
 msgstr ""
 
-#: lexer.ll:359
+#: lexer.ll:360
 msgid "end quote missing"
 msgstr ""
 
-#: lexer.ll:714
+#: lexer.ll:715
 msgid "EOF found inside a comment"
 msgstr ""
 
-#: lexer.ll:719
+#: lexer.ll:720
 msgid "EOF found inside string"
 msgstr ""
 
-#: lexer.ll:734
+#: lexer.ll:735
 msgid "Unfinished main input"
 msgstr ""
 
-#: lexer.ll:805
+#: lexer.ll:806
 #, c-format
 msgid "invalid character: `%s'"
 msgstr ""
 
-#: lexer.ll:925
+#: lexer.ll:926
 #, c-format
 msgid "unknown escaped string: `\\%s'"
 msgstr ""
 
-#: lexer.ll:945
+#: lexer.ll:946
 #, c-format
 msgid "undefined character or shorthand: %s"
 msgstr ""
 
-#: lexer.ll:1236
+#: lexer.ll:1237
 msgid "non-UTF-8 input"
 msgstr ""
 
-#: lexer.ll:1280
+#: lexer.ll:1281
 #, c-format
 msgid "Invalid version string \"%s\""
 msgstr ""
 
-#: lexer.ll:1285
+#: lexer.ll:1286
 #, c-format
 msgid "file too old: %s (oldest supported: %s)"
 msgstr ""
 
-#: lexer.ll:1286
+#: lexer.ll:1287
 msgid "consider updating the input with the convert-ly script"
 msgstr ""
 
-#: lexer.ll:1292
+#: lexer.ll:1293
 #, c-format
 msgid "program too old: %s (file requires: %s)"
 msgstr ""
@@ -3383,7 +3387,7 @@ msgstr ""
 msgid "No span bar glyph defined for bar glyph '~a'; ignoring."
 msgstr ""
 
-#: chord-entry.scm:52
+#: chord-entry.scm:54
 #, scheme-format
 msgid "Spurious garbage following chord: ~A"
 msgstr ""
@@ -3413,42 +3417,42 @@ msgstr ""
 msgid "no systems found in \\score markup, does it have a \\layout block?"
 msgstr ""
 
-#: define-markup-commands.scm:2926
+#: define-markup-commands.scm:2943
 #, scheme-format
 msgid "Cannot find glyph ~a"
 msgstr ""
 
-#: define-markup-commands.scm:3402
+#: define-markup-commands.scm:3419
 #, scheme-format
 msgid "no brace found for point size ~S "
 msgstr ""
 
-#: define-markup-commands.scm:3403
+#: define-markup-commands.scm:3420
 #, scheme-format
 msgid "defaulting to ~S pt"
 msgstr ""
 
-#: define-markup-commands.scm:3647
+#: define-markup-commands.scm:3665
 #, scheme-format
 msgid "not a valid duration string: ~a"
 msgstr ""
 
-#: define-markup-commands.scm:3858
+#: define-markup-commands.scm:3878
 #, scheme-format
 msgid "not a valid duration string: ~a - ignoring"
 msgstr ""
 
-#: define-music-types.scm:803
+#: define-music-types.scm:798
 #, scheme-format
 msgid "symbol expected: ~S"
 msgstr ""
 
-#: define-music-types.scm:806
+#: define-music-types.scm:801
 #, scheme-format
 msgid "cannot find music object: ~S"
 msgstr ""
 
-#: define-music-types.scm:826
+#: define-music-types.scm:821
 #, scheme-format
 msgid "bad make-music argument: ~S"
 msgstr ""
@@ -3581,19 +3585,19 @@ msgstr ""
 msgid "Music unsuitable for output-def"
 msgstr ""
 
-#: lily-library.scm:910
+#: lily-library.scm:903
 msgid ""
 "Find the index between @var{start} and @var{end} (an integer)\n"
 "which produces the closest match to @var{target-val} if\n"
 "applied to function @var{getter}."
 msgstr ""
 
-#: lily-library.scm:1004
+#: lily-library.scm:997
 #, scheme-format
 msgid "unknown unit: ~S"
 msgstr ""
 
-#: lily-library.scm:1029
+#: lily-library.scm:1022
 #, scheme-format
 msgid "no \\version statement found, please add~afor future compatibility"
 msgstr ""
@@ -3619,37 +3623,37 @@ msgstr ""
 msgid "cannot find: ~A"
 msgstr ""
 
-#: lily.scm:903
+#: lily.scm:902
 msgid "Success: compilation successfully completed"
 msgstr ""
 
-#: lily.scm:904
+#: lily.scm:903
 msgid "Compilation completed with warnings or errors"
 msgstr ""
 
-#: lily.scm:965
+#: lily.scm:964
 #, scheme-format
 msgid "job ~a terminated with signal: ~a"
 msgstr ""
 
-#: lily.scm:968
+#: lily.scm:967
 #, scheme-format
 msgid ""
 "logfile ~a (exit ~a):\n"
 "~a"
 msgstr ""
 
-#: lily.scm:990 lily.scm:1079
+#: lily.scm:989 lily.scm:1078
 #, scheme-format
 msgid "failed files: ~S"
 msgstr ""
 
-#: lily.scm:1070
+#: lily.scm:1069
 #, scheme-format
 msgid "Redirecting output to ~a..."
 msgstr ""
 
-#: lily.scm:1089
+#: lily.scm:1088
 #, scheme-format
 msgid "Invoking `~a'...\n"
 msgstr ""
@@ -3768,12 +3772,12 @@ msgstr ""
 msgid "Missing duration"
 msgstr ""
 
-#: music-functions.scm:2626
+#: music-functions.scm:2634
 #, scheme-format
 msgid "not a symbol list: ~a"
 msgstr ""
 
-#: music-functions.scm:2629
+#: music-functions.scm:2637
 #, scheme-format
 msgid "conflicting tag group ~a"
 msgstr ""
@@ -3836,7 +3840,7 @@ msgstr ""
 msgid "error in #{ ... #}"
 msgstr ""
 
-#: part-combiner.scm:894
+#: part-combiner.scm:931
 #, scheme-format
 msgid "quoted music `~a' is empty"
 msgstr ""
@@ -3856,40 +3860,40 @@ msgstr ""
 msgid "assertion failed: ~S"
 msgstr ""
 
-#: translation-functions.scm:389
+#: translation-functions.scm:373
 #, scheme-format
 msgid "Negative fret for pitch ~a on string ~a"
 msgstr ""
 
-#: translation-functions.scm:392
+#: translation-functions.scm:376
 #, scheme-format
 msgid "Missing fret for pitch ~a on string ~a"
 msgstr ""
 
-#: translation-functions.scm:435
+#: translation-functions.scm:419
 #, scheme-format
 msgid "No open string for pitch ~a"
 msgstr ""
 
-#: translation-functions.scm:450 translation-functions.scm:462
+#: translation-functions.scm:434 translation-functions.scm:446
 #, scheme-format
 msgid "Requested string for pitch requires negative fret: string ~a pitch ~a"
 msgstr ""
 
-#: translation-functions.scm:453
+#: translation-functions.scm:437
 msgid "Ignoring string request and recalculating."
 msgstr ""
 
-#: translation-functions.scm:465
+#: translation-functions.scm:449
 msgid "Ignoring note in tablature."
 msgstr ""
 
-#: translation-functions.scm:490
+#: translation-functions.scm:474
 #, scheme-format
 msgid "No string for pitch ~a (given frets ~a)"
 msgstr ""
 
-#: translation-functions.scm:595
+#: translation-functions.scm:579
 #, scheme-format
 msgid ""
 "No label for fret ~a (on string ~a);\n"
index c5665644d4af35bd4da47db169b5c9d62a6d2d4d..b80ce045556f674e60919b9977ade34d612581c7 100644 (file)
--- a/po/nl.po
+++ b/po/nl.po
@@ -8,12 +8,13 @@
 # Han-Wen Nienhuys <hanwen@cs.uu.nl>, 1998.
 # Jan Nieuwenhuizen <janneke@gnu.org>, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007.
 # Benno Schulenberg <benno@vertaalt.nl>, 2013, 2015.
+# Frans Spiesschaert <Frans.Spiesschaert@yucom.be>, 2015.
 msgid ""
 msgstr ""
 "Project-Id-Version: lilypond 2.19.26\n"
 "Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu.lilypond.bugs\n"
 "POT-Creation-Date: 2015-08-27 10:48+0100\n"
-"PO-Revision-Date: 2015-09-22 20:04+0200\n"
+"PO-Revision-Date: 2015-10-20 21:02+0200\n"
 "Last-Translator: Benno Schulenberg <benno@vertaalt.nl>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
 "Language: nl\n"
@@ -40,10 +41,12 @@ msgstr "kan \\begin{document} niet vinden in LaTeX-document"
 #, python-format
 msgid "Running `%s' on file `%s' to detect default page settings.\n"
 msgstr ""
+"'%s' wordt op bestand '%s' uitgevoerd\n"
+"om de standaard paginaopmaak te achterhalen.\n"
 
 #: book_latex.py:219 book_texinfo.py:228
 msgid "Unable to auto-detect default settings:\n"
-msgstr ""
+msgstr "Kan de standaardinstellingen niet automatisch achterhalen:\n"
 
 #: book_latex.py:231 book_texinfo.py:240
 #, python-format
@@ -51,10 +54,12 @@ msgid ""
 "Unable to auto-detect default settings:\n"
 "%s"
 msgstr ""
+"Kan de standaardinstellingen niet automatisch achterhalen:\n"
+"%s"
 
 #: book_latex.py:254
 msgid "cannot detect textwidth from LaTeX"
-msgstr ""
+msgstr "kan de tekstbreedte uit LaTeX niet achterhalen"
 
 #: book_snippets.py:406
 #, python-format
@@ -64,7 +69,7 @@ msgstr "verouderde ly-optie gebruikt: %s=%s"
 #: book_snippets.py:408
 #, python-format
 msgid "compatibility mode translation: %s=%s"
-msgstr "compatibiliteitsmodus-vertaling: %s=%s"
+msgstr "vertaling vanwege compatibiliteitsmodus: %s=%s"
 
 #: book_snippets.py:411
 #, python-format
@@ -74,7 +79,7 @@ msgstr "verouderde ly-optie gebruikt: %s"
 #: book_snippets.py:413
 #, python-format
 msgid "compatibility mode translation: %s"
-msgstr "compatibiliteitsmodus-vertaling: %s"
+msgstr "vertaling vanwege compatibiliteitsmodus: %s"
 
 #: book_snippets.py:530
 #, python-format
@@ -89,12 +94,12 @@ msgstr "Ontbrekende bestanden: %s"
 #: book_snippets.py:661
 #, python-format
 msgid "Could not overwrite file %s"
-msgstr "Kan bestand %s  niet overschrijven"
+msgstr "Kan bestand %s niet overschrijven"
 
 #: book_snippets.py:748
 #, python-format
 msgid "Running through filter `%s'"
-msgstr ""
+msgstr "Filteren door '%s'"
 
 #: book_snippets.py:769
 #, python-format
@@ -103,7 +108,7 @@ msgstr "'%s' is mislukt (%d)"
 
 #: book_snippets.py:770
 msgid "The error log is as follows:"
-msgstr "De foutlog is als volgt:"
+msgstr "Het foutenlogbestand zegt het volgende:"
 
 # lisp-format
 #: book_snippets.py:890
@@ -117,6 +122,8 @@ msgid ""
 "%s: duplicate filename but different contents of original file,\n"
 "printing diff against existing file."
 msgstr ""
+"%s: zelfde bestandsnaam maar andere inhoud dan het originele bestand;\n"
+"verschil met bestaand bestand wordt weergegeven."
 
 #: book_snippets.py:930
 #, python-format
@@ -124,6 +131,8 @@ msgid ""
 "%s: duplicate filename but different contents of converted lilypond file,\n"
 "printing diff against existing file."
 msgstr ""
+"%s: zelfde bestandsnaam maar andere inhoud dan het geconverteerde\n"
+"lilypond-bestand; verschil met bestaand bestand wordt weergegeven."
 
 #. Work around a texi2pdf bug: if LANG=C is not given, a broken regexp is
 #. used to detect relative/absolute paths, so the absolute path is not
@@ -131,7 +140,7 @@ msgstr ""
 #: book_texinfo.py:206
 #, python-format
 msgid "Running texi2pdf on file %s to detect default page settings.\n"
-msgstr ""
+msgstr "Op bestand %s wordt texi2pdf uitgevoerd om de standaardinstellingen te achterhalen.\n"
 
 #: convertrules.py:13
 #, python-format
@@ -140,7 +149,7 @@ msgstr "Niet slim genoeg om %s te converteren."
 
 #: convertrules.py:14
 msgid "Please refer to the manual for details, and update manually."
-msgstr "Zie de handleiding voor de details, en actualiseer handmatig."
+msgstr "Raadpleeg de handleiding voor de details, en actualiseer handmatig."
 
 #: convertrules.py:15
 #, python-format
@@ -152,9 +161,10 @@ msgstr "%s is vervangen door %s"
 msgid "warning: %s"
 msgstr "waarschuwing: %s"
 
+# ONZEKER
 #: convertrules.py:50 convertrules.py:95
 msgid "\\header { key = concat + with + operator }"
-msgstr ""
+msgstr "\\header { sleutel = concat + met + operator }"
 
 #: convertrules.py:57
 #, python-format
@@ -163,17 +173,17 @@ msgstr "verouderde %s"
 
 #: convertrules.py:66
 msgid "deprecated \\textstyle, new \\key syntax"
-msgstr ""
+msgstr "de syntax \\textstyle is verouderd, \\key is de nieuwe syntaxis"
 
 #: convertrules.py:82 convertrules.py:1856 convertrules.py:2032
 #: convertrules.py:2175 convertrules.py:2506 convertrules.py:2801
 #: convertrules.py:3151 convertrules.py:3388 convertrules.py:3700
 msgid "bump version for release"
-msgstr ""
+msgstr "voor uitgave de versie verhogen"
 
 #: convertrules.py:98
 msgid "new \\header format"
-msgstr ""
+msgstr "nieuwe indeling van \\header"
 
 #: convertrules.py:125
 msgid "\\translator syntax"
@@ -181,47 +191,48 @@ msgstr "syntax van \\translator"
 
 #: convertrules.py:176
 msgid "\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative"
-msgstr ""
+msgstr "\\repeat NUM Muziek Alternatief -> \\repeat FOLDSTR Muziek Alternatief"
 
 #: convertrules.py:206 convertrules.py:679 convertrules.py:1351
 #: convertrules.py:2318
 #, python-format
 msgid "deprecate %s"
-msgstr ""
+msgstr "verouderde %s"
 
 #: convertrules.py:280
 #, python-format
 msgid "deprecate %s "
-msgstr ""
+msgstr "verouderde %s "
 
 #: convertrules.py:306
 msgid "new \\notenames format"
-msgstr ""
+msgstr "nieuwe indeling voor \\notenames"
 
 #: convertrules.py:322
 msgid "new tremolo format"
-msgstr ""
+msgstr "nieuwe indeling voor tremolo"
 
 #: convertrules.py:326
 msgid "Staff_margin_engraver deprecated, use Instrument_name_engraver"
-msgstr ""
+msgstr "Staff_margin_engraver is verouderd; gebruik Instrument_name_engraver"
 
 #: convertrules.py:377
 msgid "change property definition case (eg. onevoice -> oneVoice)"
-msgstr ""
+msgstr "schrijfwijze van eigenschap wijzigen (bijv. onevoice -> oneVoice)"
 
 #: convertrules.py:438
 msgid "new \\textscript markup text"
-msgstr ""
+msgstr "nieuwe markeringstekst in \\textscript"
 
+# ONZEKER
 #: convertrules.py:510
 #, python-format
 msgid "identifier names: %s"
-msgstr "identifier-namen: %s"
+msgstr "namen van variabelen: %s"
 
 #: convertrules.py:549
 msgid "point-and-click argument changed to procedure."
-msgstr ""
+msgstr "argument van point-and-click() is veranderd naar een procedure"
 
 #: convertrules.py:591
 msgid "semicolons removed"
@@ -231,15 +242,15 @@ msgstr "puntkomma's verwijderd"
 #: convertrules.py:634
 #, python-format
 msgid "%s property names"
-msgstr ""
+msgstr "%s-eigenschapsnamen"
 
 #: convertrules.py:704
 msgid "automaticMelismata turned on by default"
-msgstr ""
+msgstr "automaticMelismata is standaard geactiveerd"
 
 #: convertrules.py:709
 msgid "automaticMelismata is turned on by default since 1.5.67."
-msgstr ""
+msgstr "automaticMelismata is sinds 1.5.67 standaard geactiveerd"
 
 #: convertrules.py:943 convertrules.py:1636 convertrules.py:1890
 #: convertrules.py:2135
@@ -253,40 +264,45 @@ msgstr "cluster-syntax"
 
 #: convertrules.py:988
 msgid "new Pedal style syntax"
-msgstr ""
+msgstr "nieuwe syntax van de Pedal-stijl"
 
 #: convertrules.py:1247
 msgid ""
 "New relative mode,\n"
 "Postfix articulations, new text markup syntax, new chord syntax."
 msgstr ""
+"Nieuwe relatieve modus,\n"
+"Achteraan geplaatste articulatietekens, nieuwe syntax voor tekstopmaak, nieuwe syntax voor akkoorden."
 
+# ONZEKER
 #: convertrules.py:1260
 msgid "Remove - before articulation"
-msgstr ""
+msgstr "Een - voor het articulatieteken verwijderen"
 
 #: convertrules.py:1295
 #, python-format
 msgid "%s misspelling"
-msgstr ""
+msgstr "spelfout in %s"
 
 #: convertrules.py:1314
 msgid "Swap < > and << >>"
-msgstr ""
+msgstr "< > en << >> omwisselen"
 
 #: convertrules.py:1317
 msgid "attempting automatic \\figures conversion.  Check results!"
-msgstr ""
+msgstr "Er wordt geprobeerd de conversie van \\figures automatisch uit te voeren. Controleer het resultaat!"
 
 #: convertrules.py:1363
 msgid "Use Scheme code to construct arbitrary note events."
-msgstr ""
+msgstr "Gebruik Scheme-code om arbitraire nootgebeurtenissen te construeren."
 
 #: convertrules.py:1370
 msgid ""
 "use symbolic constants for alterations,\n"
 "remove \\outputproperty, move ly:verbose into ly:get-option"
 msgstr ""
+"symbolische constanten gebruiken voor alteraties;\n"
+"\\outputproperty verwijderen; ly:verbose omzetten naar ly:get-option"
 
 #: convertrules.py:1395
 #, python-format
@@ -298,6 +314,12 @@ msgid ""
 "\n"
 "as a substitution text."
 msgstr ""
+"\\outputproperty gevonden,\n"
+"Gelieve handmatig te bewerken en gebruik\n"
+"\n"
+"  \\applyoutput #(outputproperty-compatibility %s '%s <GROB PROPERTY VALUE>)\n"
+"\n"
+"als vervangende tekst."
 
 #: convertrules.py:1407
 msgid ""
@@ -307,24 +329,31 @@ msgid ""
 "* calls of ly:make-pitch and ly:pitch-alteration\n"
 "* keySignature settings made with \\property\n"
 msgstr ""
+"Het alteraties-veld van de Scheme-toonhoogtes werd met 2 vermenigvuldigd\n"
+"om alteraties van een kwarttoon te ondersteunen. U dient de volgende constructies handmatig bij te werken:\n"
+"\n"
+"* aanroepen van ly:make-pitch en ly:pitch-alteration\n"
+"* met \\property aangemaakte instellingen voor keySignature\n"
 
 #: convertrules.py:1450
 msgid "removal of automaticMelismata; use melismaBusyProperties instead."
-msgstr ""
+msgstr "verwijderen van automaticMelismata; gebruik melismaBusyProperties ervoor in de plaats."
 
 #: convertrules.py:1557
 msgid "\\partcombine syntax change to \\newpartcombine"
-msgstr ""
+msgstr "syntax \\partcombine is veranderd naar \\newpartcombine"
 
 #: convertrules.py:1582
 msgid ""
 "Drum notation changes, Removing \\chordmodifiers, \\notenames.\n"
 "Harmonic notes. Thread context removed. Lyrics context removed."
 msgstr ""
+"Wijzigingen aan slagwerknotatie. Verwijderen van \\chordmodifiers, \\notenames.\n"
+"Harmonische noten. De contexten Thread en Lyrics werden verwijderd."
 
 #: convertrules.py:1586
 msgid "Drums found. Enclose drum notes in \\drummode"
-msgstr ""
+msgstr "Slagwerk gevonden. Plaats slagwerknoten tussen \\drummode-markeringen."
 
 #: convertrules.py:1597 convertrules.py:1604 convertrules.py:1615
 #, python-format
@@ -332,22 +361,24 @@ msgid ""
 "\n"
 "%s found. Check file manually!\n"
 msgstr ""
+"\n"
+"%s gevonden. Controleer het bestand handmatig!\n"
 
 #: convertrules.py:1597
 msgid "Drum notation"
-msgstr ""
+msgstr "Slagwerknotatie"
 
 #: convertrules.py:1656
 msgid "new syntax for property settings:"
-msgstr ""
+msgstr "nieuwe syntax voor eigenschapsinstellingen:"
 
 #: convertrules.py:1682
 msgid "Property setting syntax in \\translator{ }"
-msgstr ""
+msgstr "Syntax voor een eigenschapsinstelling in \\translator{ }"
 
 #: convertrules.py:1721
 msgid "Scheme grob function renaming"
-msgstr ""
+msgstr "Hernoemen van de grob-functie voor Scheme"
 
 #: convertrules.py:1732 convertrules.py:2139 convertrules.py:2143
 #: convertrules.py:2709
@@ -357,19 +388,23 @@ msgstr "Gebruik %s\n"
 
 #: convertrules.py:1748
 msgid "More Scheme function renaming"
-msgstr ""
+msgstr "Hernoemen van andere Scheme-functies"
 
 #: convertrules.py:1872
 msgid ""
 "Page layout has been changed, using paper size and margins.\n"
 "textheight is no longer used.\n"
 msgstr ""
+"Paginaopmaak werd gewijzigd en maakt gebruik van paper size (papierformaat) en margins (marges);\n"
+"textheight (teksthoogte) wordt niet meer gebruikt.\n"
 
 #: convertrules.py:1958
 msgid ""
 "\\foo -> \\foomode (for chords, notes, etc.)\n"
 "fold \\new FooContext \\foomode into \\foo."
 msgstr ""
+"\\foo -> \\foomode (voor akkoorden, noten, enz.)\n"
+"\\new FooContext \\foomode reduceren naar \\foo."
 
 #: convertrules.py:1996
 msgid ""
@@ -379,22 +414,28 @@ msgid ""
 "  #(set-global-staff-size <STAFF-HEIGHT-IN-POINT>)\n"
 "\n"
 msgstr ""
+"grootte van de notenbalk moet op het hoogste niveau gewijzigd worden\n"
+"met\n"
+"\n"
+"  #(set-global-staff-size <NOTENBALK-HOOGTE-IN-PUNTEN>)\n"
+"\n"
 
 #: convertrules.py:2016
 msgid "regularize other identifiers"
-msgstr ""
+msgstr "andere variabelen normaliseren"
 
 #: convertrules.py:2084
 msgid "\\encoding: smart recode latin1..utf-8. Remove ly:point-and-click"
-msgstr ""
+msgstr "\\encoding: latin1 slim omzetten naar utf-8; ly:point-and-click verwijderen"
 
 #: convertrules.py:2095
 msgid "LilyPond source must be UTF-8"
-msgstr "LilyPond bron moet UTF-8 zijn"
+msgstr "LilyPond-brontekst moet UTF-8 zijn"
 
+# ONZEKER
 #: convertrules.py:2098
 msgid "Try the texstrings backend"
-msgstr "Probeer het textstring backend"
+msgstr "Probeer de backend voor teksttekenreeksen."
 
 #: convertrules.py:2101
 #, python-format
@@ -403,15 +444,15 @@ msgstr "Doe iets als: %s"
 
 #: convertrules.py:2104
 msgid "Or save as UTF-8 in your editor"
-msgstr "Of bewaar als UTF-8 in je editor"
+msgstr "Of sla het op als UTF-8 in uw editor."
 
 #: convertrules.py:2154
 msgid "warn about auto beam settings"
-msgstr ""
+msgstr "waarschuwen bij instellingen voor automatische waardestrepen"
 
 #: convertrules.py:2158
 msgid "auto beam settings"
-msgstr ""
+msgstr "instellingen voor automatische waardestrepen"
 
 #: convertrules.py:2159
 msgid ""
@@ -419,38 +460,42 @@ msgid ""
 "Auto beam settings must now specify each interesting moment in a measure\n"
 "explicitly; 1/4 is no longer multiplied to cover moments 1/2 and 3/4 too.\n"
 msgstr ""
+"\n"
+"Instellingen voor automatische waardestrepen moeten nu iedere relevante\n"
+"nootwaarde in een maat expliciet specificeren; 1/4 wordt niet langer\n"
+"vermenigvuldigd om ook de nootwaarden 1/2 en 3/4 te bestrijken.\n"
 
 #: convertrules.py:2272
 msgid "verticalAlignmentChildCallback has been deprecated"
-msgstr ""
+msgstr "verticalAlignmentChildCallback is verouderd"
 
 #: convertrules.py:2277
 msgid "Remove callbacks property, deprecate XY-extent-callback."
-msgstr ""
+msgstr "De callbacks-eigenschap verwijderen; de XY-extent-callback is verouderd."
 
 #: convertrules.py:2298
 msgid "Use grob closures iso. XY-offset-callbacks."
-msgstr ""
+msgstr "Grob-afsluitingen gebruiken in plaats van XY-offset-callbacks."
 
 #: convertrules.py:2360
 msgid "foobar -> foo-bar for \\paper, \\layout"
-msgstr ""
+msgstr "foobar -> foo-bar voor \\paper, \\layout"
 
 #: convertrules.py:2470
 msgid "deprecate \\tempo in \\midi"
-msgstr ""
+msgstr "\\tempo in \\midi is verouderd"
 
 #: convertrules.py:2523
 msgid "deprecate cautionary-style. Use AccidentalCautionary properties"
-msgstr ""
+msgstr "cautionary-style is verouderd; eigenschappen van AccidentalCautionary gebruiken"
 
 #: convertrules.py:2536
 msgid "Rename accidental glyphs, use glyph-name-alist."
-msgstr ""
+msgstr "Alteratiesymbolen hernoemen, via glyph-name-alist()."
 
 #: convertrules.py:2591
 msgid "edge-text settings for TextSpanner"
-msgstr ""
+msgstr "Randtekstinstellingen voor TextSpanner"
 
 #: convertrules.py:2592
 #, python-format
@@ -459,46 +504,51 @@ msgid ""
 "\n"
 "%s"
 msgstr ""
+"Gebruik\n"
+"\n"
+"%s"
 
 # FIXME: this and next two should be one
 #: convertrules.py:2625
 msgid "Use the `alignment-offsets' sub-property of\n"
-msgstr ""
+msgstr "Gebruik de sub-eigenschap 'alignment-offsets' van\n"
 
 #: convertrules.py:2626
 msgid "NonMusicalPaperColumn #'line-break-system-details\n"
-msgstr ""
+msgstr "NonMusicalPaperColumn #'line-break-system-details\n"
 
 #: convertrules.py:2627
 msgid "to set fixed distances between staves.\n"
-msgstr ""
+msgstr "om vaste afstanden tussen notenbalken in te stellen.\n"
 
 #: convertrules.py:2639
 msgid "Use #'style not #'dash-fraction to select solid/dashed lines."
-msgstr ""
+msgstr "Gebruik #'style en niet #'dash-fraction om volle/streeplijnen te selecteren."
 
 #: convertrules.py:2645
 msgid "all settings related to dashed lines"
-msgstr ""
+msgstr "alle instellingen met betrekking tot streeplijnen"
 
 # FIXME: this and next should be one
 #: convertrules.py:2646
 msgid "Use \\override ... #'style = #'line for solid lines and\n"
-msgstr ""
+msgstr "Gebruik \\override ... #'style = #'line voor volle lijnen en\n"
 
 #: convertrules.py:2647
 msgid "\t\\override ... #'style = #'dashed-line for dashed lines."
-msgstr ""
+msgstr "\t\\override ... #'style = #'dashed-line voor streeplijnen."
 
 #: convertrules.py:2683
 msgid ""
 "metronomeMarkFormatter uses text markup as second argument,\n"
 "fret diagram properties moved to fret-diagram-details."
 msgstr ""
+"metronomeMarkFormatter heeft tekstmarkering als tweede argument;\n"
+"de eigenschappen van fretdiagram zijn verplaatst naar fret-diagram-details."
 
 #: convertrules.py:2689
 msgid "metronomeMarkFormatter got an additional text argument.\n"
-msgstr ""
+msgstr "metronomeMarkFormatter kreeg een bijkomend tekstargument.\n"
 
 #: convertrules.py:2690
 #, python-format
@@ -506,11 +556,13 @@ msgid ""
 "The function assigned to Score.metronomeMarkFunction now uses the signature\n"
 "%s"
 msgstr ""
+"De aan Score.metronomeMarkFunction toegewezen functie gebruikt nu de signatuur\n"
+"%s"
 
 #: convertrules.py:2708
 #, python-format
 msgid "%s in fret-diagram properties"
-msgstr ""
+msgstr "%s in de eigenschappen van fretdiagram"
 
 #: convertrules.py:2752
 msgid "\\put-adjacent argument order"
@@ -878,13 +930,14 @@ msgstr "Kan instrument voor ID=%s niet vinden\n"
 msgid "%s [OPTION]... FILE"
 msgstr "%s [OPTIE...] BESTAND"
 
+# Dit is een docstring: derde persoon.
 #: abc2ly.py:1390
 #, python-format
 msgid ""
 "abc2ly converts ABC music files (see\n"
 "%s) to LilyPond input.\n"
 msgstr ""
-"'abc2ly' converteert ABC-muziekbestanden\n"
+"Converteert ABC-muziekbestanden\n"
 "(zie %s) naar LilyPond-invoer.\n"
 
 #: abc2ly.py:1398 convert-ly.py:92 etf2ly.py:1208 lilypond-book.py:231
@@ -922,7 +975,8 @@ msgstr "voortgangsberichten onderdrukken"
 #, c-format, python-format
 msgid "Report bugs via %s"
 msgstr ""
-"Rapporteer gebreken in het programma aan <%s>;\n"
+"Rapporteer (in het Engels) gebreken in het programma via\n"
+"<%s>;\n"
 "meld vertaalfouten aan <vertaling@vrijschrift.org>."
 
 #: convert-ly.py:47
@@ -1046,13 +1100,13 @@ msgstr ""
 #, python-format
 msgid "There was %d error."
 msgid_plural "There were %d errors."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Er was %d fout."
+msgstr[1] "Er waren %d fouten."
 
 #: etf2ly.py:1197
 #, python-format
 msgid "%s [OPTION]... ETF-FILE"
-msgstr "%s [OPTIE]... ETF-BESTAND"
+msgstr "%s [OPTIE...] ETF-BESTAND"
 
 #: etf2ly.py:1198
 msgid ""
@@ -1108,7 +1162,7 @@ msgstr "MAP"
 
 #: lilypond-book.py:148
 msgid "format Texinfo output so that Info will look for images of music in DIR"
-msgstr ""
+msgstr "Texinfo-uitvoer zo opmaken dat Info in MAP zal kijken voor beelden van muziek"
 
 #: lilypond-book.py:155
 msgid "PAD"
@@ -1124,7 +1178,7 @@ msgstr "Print Lilypond-log-berichten volgens LOG-NIVEAU."
 
 #: lilypond-book.py:168
 msgid "write lily-XXX files to DIR, link into --output dir"
-msgstr ""
+msgstr "lily-XXX-bestanden naar MAP schrijven, linken naar de --output map"
 
 #: lilypond-book.py:173
 msgid "Load the additional python PACKAGE (containing e.g. a custom output format)"
@@ -1149,11 +1203,11 @@ msgstr "ly-bestanden verwerken met 'OPDRACHT BESTAND...'"
 # lisp-format
 #: lilypond-book.py:197
 msgid "Redirect the lilypond output"
-msgstr "Omleiden van Lilypond-uitvoer"
+msgstr "Lilypond-uitvoer omleiden"
 
 #: lilypond-book.py:201
 msgid "Compile snippets in safe mode"
-msgstr "Snippers compileren in veilige modus"
+msgstr "snippers compileren in veilige modus"
 
 #: lilypond-book.py:207
 msgid "do not fail if no lilypond output is found"
@@ -1469,6 +1523,7 @@ msgstr "musicxml2ly [OPTIE...] BESTAND.xml"
 
 # FIXME: command line ==> standard input
 # that is: use the existing standard phrase instead
+# Dit is een docstring: derde persoon.
 #: musicxml2ly.py:2566
 msgid ""
 "Convert MusicXML from FILE.xml to LilyPond input.\n"
@@ -1736,12 +1791,12 @@ msgstr "verwijderen van waardestreep zonder stokken"
 #: change-iterator.cc:34
 #, c-format
 msgid "cannot change `%s' to `%s'"
-msgstr "kan `%s' niet in `%s' veranderen"
+msgstr "kan '%s' niet in '%s' veranderen"
 
 #. FIXME: constant error message.
 #: change-iterator.cc:67
 msgid "cannot find context to switch to"
-msgstr "kan `%s' niet wisselen in `%s'"
+msgstr "kan context om naar over te schakelen niet vinden"
 
 #. No enclosing context was found because the iterator's immediate
 #. context is the kind that was sought.
@@ -1798,17 +1853,17 @@ msgstr "heb symbool-argumenten nodig voor \\override en \\revert"
 #: context.cc:144
 #, c-format
 msgid "cannot find or create new `%s'"
-msgstr "kan niet vinden of nieuw maken `%s'"
+msgstr "kan '%s' niet vinden of nieuw maken"
 
 #: context.cc:223
 #, c-format
 msgid "cannot find or create `%s' called `%s'"
-msgstr "kan niet vinden of maken `%s' genaamd `%s'"
+msgstr "kan '%s' genaamd '%s' niet vinden of aanmaken"
 
 #: context.cc:416
 #, c-format
 msgid "cannot find or create: `%s'"
-msgstr "kan niet vinden of scheppen: `%s'"
+msgstr "kan '%s' niet vinden of aanmaken"
 
 #: context.cc:430
 #, fuzzy, c-format
@@ -1883,7 +1938,7 @@ msgstr "onbeëindigde extender"
 #: flag.cc:133
 #, c-format
 msgid "flag `%s' not found"
-msgstr "vlag `%s' niet gevonden"
+msgstr "vlag '%s' is niet gevonden"
 
 #: flag.cc:153
 #, c-format
@@ -1948,7 +2003,7 @@ msgstr "onbeëindigde glissando"
 
 #: global-context-scheme.cc:95 global-context-scheme.cc:113
 msgid "no music found in score"
-msgstr "geen muziek gevonden in score"
+msgstr "geen muziek gevonden in partituur"
 
 #: global-context-scheme.cc:103
 msgid "Interpreting music..."
@@ -1987,7 +2042,7 @@ msgstr "onbekende interface `%s'"
 #: grob-interface.cc:79
 #, c-format
 msgid "Grob `%s' has no interface for property `%s'"
-msgstr "Grob `%s' heeft geen interface voor eigenschap `%s'"
+msgstr "Grob '%s' heeft geen interface voor eigenschap '%s'"
 
 #: grob-property.cc:33
 #, c-format
@@ -2026,12 +2081,12 @@ msgstr "verwijderen van onafgesloten streepje"
 #: includable-lexer.cc:71 lily-guile.cc:92 lily-parser-scheme.cc:108
 #, c-format
 msgid "cannot find file: `%s'"
-msgstr "kan bestand niet vinden: `%s'"
+msgstr "kan bestand '%s' niet vinden"
 
 #: includable-lexer.cc:73 lily-parser-scheme.cc:100
 #, c-format
 msgid "(search path: `%s')"
-msgstr "(zoekpad: `%s')"
+msgstr "(zoekpad: '%s')"
 
 #: input.cc:138 source-file.cc:180 source-file.cc:195
 msgid "position unknown"
@@ -2072,7 +2127,7 @@ msgstr "onbeëindigde ligatuur"
 
 #: ligature-engraver.cc:216
 msgid "ignoring rest: ligature may not contain rest"
-msgstr "negeer rust: ligatuur mag geen rust bevatten"
+msgstr "ligatuur mag geen rust bevatten;  genegeerd"
 
 #: ligature-engraver.cc:217
 msgid "ligature was started here"
@@ -2081,7 +2136,7 @@ msgstr "ligatuur werd hier gestart"
 #: lily-guile.cc:94
 #, c-format
 msgid "(load path: `%s')"
-msgstr "(zoekpad: `%s')"
+msgstr "(laadpad: '%s')"
 
 #: lily-guile.cc:413
 #, c-format
@@ -2142,7 +2197,7 @@ msgstr "kan werkmap niet veranderen naar: '%s'"
 #: lily-parser-scheme.cc:99
 #, c-format
 msgid "cannot find init file: `%s'"
-msgstr "kan init-bestand niet vinden: '%s'"
+msgstr "kan init-bestand '%s' niet vinden"
 
 #: lily-parser-scheme.cc:117
 #, c-format
@@ -2230,43 +2285,44 @@ msgid ""
 "set Scheme option SYM to VAL (default: #t).\n"
 "Use -dhelp for help."
 msgstr ""
-"zet Scheme optie SYM to WAARDE (standaard: #t)\n"
-"Gebruik -dhelp voor hulp."
+"scheme-optie SYM omzetten naar WAARDE\n"
+"(standaard: #t);  '-dhelp' voor hulp"
 
 #: main.cc:155
 msgid "EXPR"
-msgstr "EXPR"
+msgstr "EXPRESSIE"
 
 #: main.cc:155
 msgid "evaluate scheme code"
-msgstr "evalueer scheme code"
+msgstr "scheme-code evalueren"
 
 #. Bug in option parser: --output =foe is taken as an abbreviation
 #. for --output-format.
 #: main.cc:158
 msgid "FORMATs"
-msgstr "FORMAATen"
+msgstr "FORMAAT[,...]"
 
 #: main.cc:158
 msgid "dump FORMAT,...  Also as separate options:"
-msgstr "dump FORMAAT,...  Ook als separate opties:"
+msgstr ""
+"de aangegeven soort bestanden produceren;\n"
+"kan ook via aparte opties:"
 
 #: main.cc:159
 msgid "generate PDF (default)"
-msgstr "genereer PDF (standaard)"
+msgstr "PDF genereren  (standaard)"
 
 #: main.cc:160
 msgid "generate PNG"
-msgstr "genereer PNG"
+msgstr "PNG genereren"
 
 #: main.cc:161
 msgid "generate PostScript"
-msgstr "genereer PostScipt"
+msgstr "PostScript genereren"
 
 #: main.cc:162
-#, fuzzy
 msgid "generate big PDF files"
-msgstr "genereer PDF (standaard)"
+msgstr "grote PDF-bestanden genereren"
 
 #: main.cc:165
 msgid "FIELD"
@@ -2277,28 +2333,28 @@ msgid ""
 "dump header field FIELD to file\n"
 "named BASENAME.FIELD"
 msgstr ""
-"schrijf kopveld VELD naar bestand\n"
+"kopveld VELD schrijven naar bestand\n"
 "genaamd BASISNAAM.VELD"
 
 #: main.cc:168
 msgid "add DIR to search path"
-msgstr "voeg DIR toe aan zoekpad"
+msgstr "deze MAP toevoegen aan zoekpad"
 
 #: main.cc:169
 msgid "use FILE as init file"
-msgstr "gebruik BESTAND als initialisatiebestand"
+msgstr "te gebruiken initialisatiebestand"
 
 #: main.cc:172
 msgid "USER, GROUP, JAIL, DIR"
-msgstr "GEBR, GROEP, GEVANG, DIR"
+msgstr "GEBRKR, GROEP, BOX, MAP"
 
 #: main.cc:172
 msgid ""
 "chroot to JAIL, become USER:GROUP\n"
 "and cd into DIR"
 msgstr ""
-"chroot naar GEVANG, word GEBR:GROEP\n"
-"en cd naar MAP"
+"chrooten naar BOX, overschakelen naar\n"
+"GEBRKR:GROEP, en cd'en naar MAP"
 
 #: main.cc:177
 msgid ""
@@ -2309,22 +2365,26 @@ msgstr ""
 #: main.cc:181
 msgid "write output to FILE (suffix will be added)"
 msgstr ""
-"schrijf uitvoer naar BESTAND\n"
+"uitvoer naar dit BESTAND schrijven\n"
 "(extensie wordt toegevoegd)"
 
 #: main.cc:182
 msgid "relocate using directory of lilypond program"
 msgstr ""
-"verhuis aan de hand van de map van het\n"
-"lilypond programma"
+"verhuizen aan de hand van de map van\n"
+"het lilypond-programma"
 
 #: main.cc:183
 msgid "no progress, only error messages (equivalent to loglevel=ERROR)"
 msgstr ""
+"geen voortgang tonen, alleen foutmeldingen\n"
+"(equivalent aan loglevel=ERROR)"
 
 #: main.cc:185
 msgid "be verbose (equivalent to loglevel=DEBUG)"
 msgstr ""
+"gedetailleerde informatie produceren\n"
+"(equivalent aan loglevel=DEBUG)"
 
 #. Do not update the copyright years here, run `make grand-replace'
 #: main.cc:264
@@ -2340,11 +2400,11 @@ msgstr ""
 #: main.cc:302
 #, c-format
 msgid "Usage: %s [OPTION]... FILE..."
-msgstr "Gebruik: %s [OPTIE]... BESTAND..."
+msgstr "Gebruik:  %s [OPTIE...] BESTAND..."
 
 #: main.cc:304
 msgid "Typeset music and/or produce MIDI from FILE."
-msgstr "Zet muziek en of produceer MIDI van BESTAND."
+msgstr "Zet muziek en/of produceert MIDI van BESTAND."
 
 #: main.cc:306
 msgid "LilyPond produces beautiful music notation."
@@ -2392,17 +2452,17 @@ msgstr "kan niet chrooten naar: %s: %s"
 #: main.cc:425
 #, c-format
 msgid "cannot change group id to: %d: %s"
-msgstr "kan groep id niet veranderen in: %d: %s"
+msgstr "kan groeps-ID niet veranderen naar: %d: %s"
 
 #: main.cc:431
 #, c-format
 msgid "cannot change user id to: %d: %s"
-msgstr "kan kan gebruiker id niet veranderen in: %d: %s"
+msgstr "kan kan gebruikers-ID niet veranderen naar: %d: %s"
 
 #: main.cc:437
 #, c-format
 msgid "cannot change working directory to: %s: %s"
-msgstr "kan werkmap niet veranderen in: %s: %s"
+msgstr "kan werkmap niet veranderen naar: %s: %s"
 
 #: main.cc:826
 #, c-format
@@ -2420,27 +2480,27 @@ msgstr "mark etiket moet een markup zijn"
 
 #: mensural-ligature-engraver.cc:100
 msgid "ligature with less than 2 heads -> skipping"
-msgstr "ligatuur met minder dan 2 bolletjes -> overslaan"
+msgstr "ligatuur met minder dan 2 bolletjes -> overgeslagen"
 
 #: mensural-ligature-engraver.cc:127
 msgid "cannot determine pitch of ligature primitive -> skipping"
-msgstr "kan toonhoogte van primitieve ligatuur niet bepalen -> overslaan"
+msgstr "kan toonhoogte van primitieve ligatuur niet bepalen -> overgeslagen"
 
 #: mensural-ligature-engraver.cc:141
 msgid "single note ligature - skipping"
-msgstr "enkelnootse ligatuur - overslaan"
+msgstr "enkelnootse ligatuur -> overgeslagen"
 
 #: mensural-ligature-engraver.cc:152
 msgid "prime interval within ligature -> skipping"
-msgstr "prieminterval binnen ligatuur -> overslaan"
+msgstr "prieminterval binnen ligatuur -> overgeslagen"
 
 #: mensural-ligature-engraver.cc:163
 msgid "mensural ligature: duration none of Mx, L, B, S -> skipping"
-msgstr "mensural ligature: lengte geen van Mx, L, S -> overslaan"
+msgstr "mensurale ligatuur: lengte is geen van Mx, L, B, S -> overgeslagen"
 
 #: mensural-ligature-engraver.cc:206
 msgid "semibrevis must be followed by another one -> skipping"
-msgstr "semibrevis moet worden gevolgd door een andere -> overslaan"
+msgstr "semibrevis moet worden gevolgd door een andere -> overgeslagen"
 
 #: mensural-ligature-engraver.cc:216
 msgid ""
@@ -2448,7 +2508,7 @@ msgid ""
 "and there may be only zero or two of them"
 msgstr ""
 "semibrevi kunnen alleen aan het begin van een ligatuur voorkomen,\n"
-"en het mogen er uitsluitend een of twee zijn"
+"en het mogen er uitsluitend nul of twee zijn"
 
 #: mensural-ligature-engraver.cc:236
 msgid ""
@@ -2457,9 +2517,9 @@ msgid ""
 "the penultimate note must be another one,\n"
 "or the ligatura must be LB or SSB"
 msgstr ""
-"ongeldig ligatuur einde:\n"
+"ongeldig ligatuureinde:\n"
 "als de laatste noot een dalende brevis is,\n"
-"moet de penultimate note een andere zijn,\n"
+"moet de voorlaatste noot een andere zijn,\n"
 "of de ligatuur moet LB of SSB zijn"
 
 #: mensural-ligature-engraver.cc:396
@@ -2870,7 +2930,7 @@ msgstr "Onbekend verhuizingscommando %s"
 
 #: rest-collision.cc:154
 msgid "cannot resolve rest collision: rest direction not set"
-msgstr "kan rust bosting niet oplossen: richting van de rust is niet gezet"
+msgstr "kan rusten-botsing niet oplossen: richting van de rust is niet ingesteld"
 
 #: rest-collision.cc:165 rest-collision.cc:274
 msgid "too many colliding rests"
@@ -2879,12 +2939,12 @@ msgstr "te veel botsende rusten"
 #: rest.cc:239
 #, c-format
 msgid "rest `%s' not found"
-msgstr "rust `%s' niet gevonden"
+msgstr "rust '%s' is niet gevonden"
 
 #: score-engraver.cc:77
 #, c-format
 msgid "cannot find `%s'"
-msgstr "kan niet vinden `%s'"
+msgstr "kan '%s' niet vinden"
 
 #: score-engraver.cc:79
 msgid "Music font has not been installed properly."
@@ -2893,7 +2953,7 @@ msgstr "Muziek-font is niet correct geïnstalleerd."
 #: score-engraver.cc:81
 #, c-format
 msgid "Search path `%s'"
-msgstr "Zoekpad: `%s'"
+msgstr "Zoekpad: '%s'"
 
 #: score-engraver.cc:83
 msgid "Aborting"
@@ -2901,7 +2961,7 @@ msgstr "Afbreken"
 
 #: score.cc:161
 msgid "already have music in score"
-msgstr "heb al muziek nodig in score"
+msgstr "heb al muziek in partituur"
 
 #: score.cc:163
 msgid "this is the previous music"
@@ -2909,7 +2969,7 @@ msgstr "dit is de vorige muziek"
 
 #: score.cc:169
 msgid "errors found, ignoring music expression"
-msgstr "fouten gevonden, negeer muziekexpressie"
+msgstr "fouten gevonden;  muziekexpressie wordt genegeerd"
 
 #. FIXME:
 #: script-engraver.cc:115
@@ -3124,9 +3184,8 @@ msgid "not a context mod"
 msgstr ""
 
 #: parser.yy:1054
-#, fuzzy
 msgid "Missing music in \\score"
-msgstr "geen muziek gevonden in score"
+msgstr ""
 
 #: parser.yy:1091
 msgid "\\paper cannot be used in \\score, use \\layout instead"
@@ -3272,7 +3331,7 @@ msgstr "tekst tussen aanhalingstekens verwacht na \\version"
 
 #: lexer.ll:359
 msgid "end quote missing"
-msgstr "aanhalingstekens sluite mist"
+msgstr "afsluitend aanhalingsteken ontbreekt"
 
 #: lexer.ll:714
 msgid "EOF found inside a comment"
@@ -3331,7 +3390,7 @@ msgstr ""
 #: backend-library.scm:27
 #, scheme-format
 msgid "Invoking `~a'..."
-msgstr "Inroepen van `~a'..."
+msgstr "Aanroepen van '~a'..."
 
 #: backend-library.scm:31
 #, scheme-format
@@ -3427,7 +3486,7 @@ msgstr "Ongedefinieerde moedergebeurtenisklasse '~S'"
 
 #: define-markup-commands.scm:1098
 msgid "no systems found in \\score markup, does it have a \\layout block?"
-msgstr "geen systemen gevonden in \\score markup, heeft het een \\layout blok?"
+msgstr "geen systemen gevonden in \\score markup; heeft het een \\layout blok?"
 
 #: define-markup-commands.scm:2922
 #, scheme-format
@@ -3450,9 +3509,9 @@ msgid "not a valid duration string: ~a"
 msgstr "geen geldige duurtekst: ~a"
 
 #: define-markup-commands.scm:3854
-#, fuzzy, scheme-format
+#, scheme-format
 msgid "not a valid duration string: ~a - ignoring"
-msgstr "geen geldige duurtekst: ~a"
+msgstr "geen geldige duurtekst: ~a --  genegeerd"
 
 #: define-music-types.scm:803
 #, scheme-format
@@ -3735,9 +3794,9 @@ msgid "negative replication count; ignoring"
 msgstr ""
 
 #: music-functions.scm:319
-#, fuzzy, scheme-format
+#, scheme-format
 msgid "invalid tremolo repeat count: ~a"
-msgstr "Ongeldige eigenschap operatie ~a"
+msgstr "ongeldig tremolo-herhalingsaantal: ~a"
 
 #: music-functions.scm:348
 #, scheme-format
@@ -3754,14 +3813,14 @@ msgid "bad grob property path ~a"
 msgstr "Ongeldige eigenschap operatie ~a"
 
 #: music-functions.scm:511
-#, fuzzy, scheme-format
+#, scheme-format
 msgid "bad context property ~a"
-msgstr "Ongeldige eigenschap operatie ~a"
+msgstr "ongeldige contexteigenschap ~a"
 
 #: music-functions.scm:534
-#, fuzzy, scheme-format
+#, scheme-format
 msgid "bad music property ~a"
-msgstr "Ongeldige eigenschap operatie ~a"
+msgstr "ongeldige muziekeigenschap ~a"
 
 #: music-functions.scm:840
 msgid "Bad chord repetition"
@@ -3775,7 +3834,7 @@ msgstr "muziek verwacht: ~S"
 #: music-functions.scm:1295
 #, scheme-format
 msgid "cannot find quoted music: `~S'"
-msgstr "kan aangehaalde muziek niet vinden: `~S'"
+msgstr "kan aangehaalde muziek niet vinden: '~S'"
 
 #: music-functions.scm:1432
 msgid "Add @var{octave-shift} to the octave of @var{pitch}."
@@ -3963,7 +4022,7 @@ msgstr ""
 #~ msgstr "Te veel vooruitkijk"
 
 #~ msgid "score expected"
-#~ msgstr "score verwacht"
+#~ msgstr "partituur verwacht"
 
 #~ msgid "unknown repeat type `~S'"
 #~ msgstr "onbekend herhaaltype `~S'"
@@ -4359,9 +4418,6 @@ msgstr ""
 #~ msgid "beam has less than two visible stems"
 #~ msgstr "waardestreep heeft minder dan twee zichtbare stokken"
 
-#~ msgid "I'm one myself"
-#~ msgstr "Ben er zelf een"
-
 #~ msgid "Chord tremolo with %d elements. Must have two elements."
 #~ msgstr "Akkoordtremool met %d elementen. Moet twee elementen hebben."
 
@@ -4536,12 +4592,6 @@ msgstr ""
 #~ msgid "Report errors to <a href=\"%(mail_address_url)s\">%(mail_address)s</a>."
 #~ msgstr "Meld fouten naar <a href=\\\"%(mail_address_url)s\\\">%(mail_address)s</a>."
 
-#~ msgid "stable-branch"
-#~ msgstr "stabiele tak"
-
-#~ msgid "development-branch"
-#~ msgstr "ontwikkel tak"
-
 #~ msgid "French"
 #~ msgstr "Frans"
 
index d46daa6577ff2b3eacbf029fa2ee17119ddc9ed2..f86b90ba4eb8fded7bcd00c5c9972d232cda100b 100644 (file)
@@ -3845,6 +3845,16 @@ def conv (str):
     str = re.sub (r":1\.5(?=\s|[.^}])", r":5", str)
     return str
 
+@rule ((2, 19, 29), r"partcombine*Once -> \once \partcombine*")
+def conv(str):
+    str = re.sub (r"(\\partcombine(?:Apart|Chords|Unisono|SoloII?|Automatic))Once\b",
+                  r"\\once \1", str)
+    str = re.sub (r"(\\partcombineForce" + matcharg + r")\s*##f(\s)",
+                  r"\1\2", str)
+    str = re.sub (r"(\\partcombineForce" + matcharg + r")\s*##t(\s)",
+                  r"\\once \1\2", str)
+    return str
+
 # Guidelines to write rules (please keep this at the end of this file)
 #
 # - keep at most one rule per version; if several conversions should be done,
index ca864f3e1057fe44d32d8ac825a302a7dee9607c..1d41c973e80330876afc9de25d5e090e4bc223ef 100644 (file)
@@ -51,7 +51,8 @@ Entry point for the parser."
             (set! bass (cadr mods))
             (set! mods (cddr mods))))
       (if (pair? mods)
-          (ly:warning (_ "Spurious garbage following chord: ~A") mods))
+          (ly:parser-error
+           (format #f (_ "Spurious garbage following chord: ~A") mods)))
       chord)
 
     (define (interpret-removals  chord mods)
index 3ad11f49133bd29eff0792065b92a6645fb7d7ed..df664bd98f09b1ea413129621432fa139bbee579 100644 (file)
@@ -495,6 +495,9 @@ Changing this creates a new text spanner.")
 translator during music interpretation.")
 
 
+     (partCombineForced ,symbol? "Override for the partcombine
+decision.  Can be @code{apart}, @code{chords}, @code{unisono},
+@code{solo1}, or @code{solo2}.")
      (partCombineTextsOnNote ,boolean? "Print part-combine texts only on
 the next note rather than immediately on rests or skips.")
      (pedalSostenutoStrings ,list? "See @code{pedalSustainStrings}.")
index dd976e1b04d15ce64e443e830c3a2c19d04434a5..4eebdfac0ee7627aec9cdc616fbafe7e58bcb2b1 100644 (file)
@@ -31,7 +31,7 @@
                     extender-event span-event rhythmic-event dynamic-event
                     break-event label-event percent-event key-change-event
                     string-number-event stroke-finger-event tie-event
-                    part-combine-event part-combine-force-event
+                    part-combine-event
                     beam-forbid-event script-event tempo-change-event
                     tremolo-event bend-after-event fingering-event
                     glissando-event harmonic-event hyphen-event
index 0bcc5a20afca3ce95ec88ced86da76ed28d2e46e..4df3f933405fd4a1be7ea953eae62912a295bcb5 100644 (file)
@@ -96,7 +96,6 @@ a sequential iterator.  Takes a single music parameter.")
      (footnote-text ,markup? "Text to appear in a footnote.")
      (force-accidental ,boolean? "If set, a cautionary accidental should
 always be printed on this note.")
-     (forced-type ,symbol? "Override for the part-combiner.")
 
      (grob-property ,symbol? "The symbol of the grob property to set.")
      (grob-property-path ,list? "A list of symbols, locating a nested grob
index 5ae59799f604303e90bdebcc25f448653ca3e755..e0190eda5516c419eb6763affa58e968b082ae20 100644 (file)
@@ -386,11 +386,6 @@ Syntax: @code{\\override} [ @var{context} @code{.} ]
         (types . (break-event page-turn-event event))
         ))
 
-    (PartCombineForceEvent
-     . ((description . "Override the part-combiner's strategy.")
-        (types . (part-combine-force-event event))
-        ))
-
     (PartialSet
      . ((description . "Create an anacrusis or upbeat (partial measure).")
         (iterator-ctor . ,ly:partial-iterator::constructor)
index 85cfbb9b3679c0a01677e288c9a4d28e6f0c44f1..3b0990cf415109a0d52ddb9dfedd05c0a9b802fb 100644 (file)
@@ -405,17 +405,17 @@ baseline at fret coordinate @var{base}, a height of
                bottom-control-point-height cp-right-width)))
 
         ;; order of bezier control points is:
-        ;;    left cp low, right cp low, right end low, left end low
-        ;;   right cp high, left cp high, left end high, right end high.
+        ;;   left cp low, left cp low, right cp low, right end low
+        ;;   right cp high, left cp high
 
-        (list left-lower-control-point
+        (list
+              left-end-point
+              left-lower-control-point
               right-lower-control-point
               right-end-point
-              left-end-point
+
               right-upper-control-point
-              left-upper-control-point
-              left-end-point
-              right-end-point)))
+              left-upper-control-point)))
 
     (define (draw-strings)
       "Draw the string lines for a fret diagram with
@@ -564,24 +564,10 @@ fret-diagram overall parameters."
                (* size end-string-coordinate)
                (* size fret-coordinate)
                (* size bezier-height)
-               (* size bezier-thick)))
-             (box-lower-left
-              (stencil-coordinates
-               (+ (* size fret-coordinate) half-thickness)
-               (- (* size start-string-coordinate) half-thickness)))
-             (box-upper-right
-              (stencil-coordinates
-               (- (* size fret-coordinate)
-                  (* size bezier-height)
-                  half-thickness)
-               (+ (* size end-string-coordinate) half-thickness)))
-             (x-extent (cons (car box-lower-left) (car box-upper-right)))
-             (y-extent (cons (cdr box-lower-left) (cdr box-upper-right))))
+               (* size bezier-thick))))
         (make-bezier-sandwich-stencil
          bezier-list
-         (* size bezier-thick)
-         x-extent
-         y-extent)))
+         (* size bezier-thick))))
 
     (define (draw-dots dot-list)
       "Make dots for fret diagram."
index c5bf8cc59de12066e1f4bbf7e6aa88e321ef883e..0bfce9eb0c8a748099b3af053cf29d822de8a4b6 100644 (file)
@@ -707,20 +707,13 @@ right (@var{dir}=+1)."
 (define-public (coord-scale coordinate amount)
   (coord-operation * amount coordinate))
 
-(define-public (coord-rotate coordinate degrees-in-radians)
-  (let*
-      ((coordinate
-        (cons
-         (exact->inexact (coord-x coordinate))
-         (exact->inexact (coord-y coordinate))))
-       (radius
-        (sqrt
-         (+ (* (coord-x coordinate) (coord-x coordinate))
-            (* (coord-y coordinate) (coord-y coordinate)))))
-       (angle (angle-0-2pi (atan (coord-y coordinate) (coord-x coordinate)))))
-    (cons
-     (* radius (cos (+ angle degrees-in-radians)))
-     (* radius (sin (+ angle degrees-in-radians))))))
+(define-public (coord-rotate coordinate angle)
+  (let ((c (cos angle))
+        (s (sin angle))
+        (x (coord-x coordinate))
+        (y (coord-y coordinate)))
+    (cons (- (* c x) (* s y))
+          (+ (* s x) (* c y)))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; trig
index ff5d66dfeda1ca70294b161031d538d6815b16bf..c670eb15bf31e90ac6218fe08df33ebcd9e31847 100644 (file)
@@ -732,7 +732,6 @@ messages into errors.")
     (,ly:pitch? . "pitch")
     (,ly:prob? . "property object")
     (,ly:score? . "score")
-    (,ly:simple-closure? . "simple closure")
     (,ly:skyline? . "skyline")
     (,ly:skyline-pair? . "pair of skylines")
     (,ly:source-file? . "source file")
index 8a5cae2b23f0fbcc79ab61c6334dd0222b115380..f525a1ebad7893eae39a8747854057b4ca4ffd2a 100644 (file)
@@ -967,14 +967,53 @@ and duration-log @var{log}."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
 
-(define-public (chain-grob-member-functions grob value . funcs)
-  (for-each
-   (lambda (func)
-     (set! value (func grob value)))
-   funcs)
-
-  value)
-
+(define-public (grob::compose-function func data)
+  "This creates a callback entity to be stored in a grob property,
+based on the grob property data @var{data} (which can be plain data, a
+callback itself, or an unpure-pure-container).
+
+Function or unpure-pure-container @var{func} accepts a grob and a
+value and returns another value.  Depending on the type of @var{data},
+@var{func} is used for building a grob callback or an
+unpure-pure-container."
+  (if (or (ly:unpure-pure-container? func)
+          (ly:unpure-pure-container? data))
+      (ly:make-unpure-pure-container
+       (lambda (grob) (ly:unpure-call func grob (ly:unpure-call data grob)))
+       (lambda (grob start end)
+         (ly:pure-call func grob start end
+                       (ly:pure-call data grob start end))))
+      (lambda (grob) (ly:unpure-call func grob (ly:unpure-call data grob)))))
+
+(define*-public (grob::offset-function func data
+                                       #:optional (plus +))
+  "This creates a callback entity to be stored in a grob property,
+based on the grob property data @var{data} (which can be plain data, a
+callback itself, or an unpure-pure-container).
+
+Function @var{func} accepts a grob and returns a value that is added
+to the value resulting from @var{data}.  Optional arguments @var{plus}
+and @var{valid?} default to @code{+} and @code{number?} respectively
+and allow for using a different underlying accumulation/type.
+
+If @var{data} is @code{#f} or @code{'()}, it is not included in the sum."
+  (cond ((or (not data) (null? data))
+         func)
+        ((or (ly:unpure-pure-container func)
+             (ly:unpure-pure-container data))
+         (ly:make-unpure-pure-container
+          (lambda rest
+            (plus (apply ly:unpure-call func rest)
+                  (apply ly:unpure-call data rest)))
+          (lambda rest
+            (plus (apply ly:pure-call func rest)
+                  (apply ly:pure-call data rest)))))
+        ((or (procedure? func)
+             (procedure? data))
+         (lambda rest
+           (plus (apply ly:unpure-call func rest)
+                 (apply ly:unpure-call data rest))))
+        (else (plus func data))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; falls/doits
index 71b5e5652643c4017f135145194360d20d1305d8..94860cdf6fc5a56103e700abab7a6140a0d1f02a 100644 (file)
@@ -345,9 +345,16 @@ LilyPond version 2.8 and earlier."
     (define (analyse-forced-combine result-idx prev-res)
 
       (define (get-forced-event x)
-        (and (ly:in-event-class? x 'part-combine-force-event)
-             (cons (ly:event-property x 'forced-type)
-                   (ly:event-property x 'once))))
+        (cond
+         ((and (ly:in-event-class? x 'SetProperty)
+               (eq? (ly:event-property x 'symbol) 'partCombineForced))
+          (cons (ly:event-property x 'value #f)
+                (ly:event-property x 'once #f)))
+         ((and (ly:in-event-class? x 'UnsetProperty)
+               (eq? (ly:event-property x 'symbol) 'partCombineForced))
+          (cons #f (ly:event-property x 'once #f)))
+         (else #f)))
+
       (define (part-combine-events vs)
         (if (not vs)
             '()
index fb2809e9fd2fee40c1d98660f7f10ac5ccf4711d..6410eae44c961ca049366d4fb12e3f1202da7780 100644 (file)
 ;;;; You should have received a copy of the GNU General Public License
 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
-(define (make-bezier-sandwich-stencil coords thick xext yext)
-  (let* ((command-list `(moveto
-                         ,(car (list-ref coords 3))
-                         ,(cdr (list-ref coords 3))
-                         curveto
-                         ,(car (list-ref coords 0))
-                         ,(cdr (list-ref coords 0))
-                         ,(car (list-ref coords 1))
-                         ,(cdr (list-ref coords 1))
-                         ,(car (list-ref coords 2))
-                         ,(cdr (list-ref coords 2))
-                         curveto
-                         ,(car (list-ref coords 4))
-                         ,(cdr (list-ref coords 4))
-                         ,(car (list-ref coords 5))
-                         ,(cdr (list-ref coords 5))
-                         ,(car (list-ref coords 6))
-                         ,(cdr (list-ref coords 6))
-                         closepath)))
-    (ly:make-stencil
-     `(path ,thick `(,@' ,command-list) 'round 'round #t)
-     xext
-     yext)))
+(define (make-bezier-sandwich-stencil coords thick)
+   (make-path-stencil
+       `(moveto
+           ,(car (list-ref coords 0))
+           ,(cdr (list-ref coords 0))
+         curveto
+           ,(car (list-ref coords 1))
+           ,(cdr (list-ref coords 1))
+           ,(car (list-ref coords 2))
+           ,(cdr (list-ref coords 2))
+           ,(car (list-ref coords 3))
+           ,(cdr (list-ref coords 3))
+         curveto
+           ,(car (list-ref coords 4))
+           ,(cdr (list-ref coords 4))
+           ,(car (list-ref coords 5))
+           ,(cdr (list-ref coords 5))
+           ,(car (list-ref coords 0))
+           ,(cdr (list-ref coords 0))
+         closepath)
+       thick
+       1
+       1
+       #t))
 
 (define-public (stack-stencils axis dir padding stils)
   "Stack stencils @var{stils} in direction @var{axis}, @var{dir}, using
@@ -142,26 +143,24 @@ the more angular the shape of the parenthesis."
           (cons inner-control-x upper-control-y))
          (lower-inner-control-point
           (cons inner-control-x lower-control-y)))
-
-    (make-bezier-sandwich-stencil
-     (list
-      ;; Step 4: curve through inner control points
-      ;; to lower end point.
-      upper-inner-control-point
-      lower-inner-control-point
-      lower-end-point
-      ;; Step 3: move to upper end point.
-      upper-end-point
-      ;; Step 2: curve through outer control points
-      ;; to upper end point.
-      lower-outer-control-point
-      upper-outer-control-point
-      upper-end-point
-      ;; Step 1: move to lower end point.
-      lower-end-point)
-     (min (* 2 half-thickness) line-width)
-     (interval-widen x-extent (/ line-width 2))
-     (interval-widen y-extent (/ line-width 2)))))
+  (ly:make-stencil
+    (ly:stencil-expr
+      (make-bezier-sandwich-stencil
+       (list
+        ;; Step 1: move to lower end point.
+        lower-end-point
+        ;; Step 2: curve through outer control points
+        ;; to upper end point.
+        lower-outer-control-point
+        upper-outer-control-point
+        upper-end-point
+        ;; Step 3: curve through inner control points
+        ;; to lower end point.
+        upper-inner-control-point
+        lower-inner-control-point)
+       (min (* 2 half-thickness) line-width)))
+    (interval-widen x-extent (/ line-width 2))
+    (interval-widen y-extent (/ line-width 2)))))
 
 (define-public (parenthesize-stencil
                 stencil half-thickness width angularity padding)