\version "2.13.1"
\header {
- lsrtags = "titles"
+ lsrtags = "text, titles"
texidoces = "
Con algo de código de Scheme, se puede añadir fácilmente la fecha
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
\header {
lsrtags = "rhythms"
+ texidoces = "
+
+Los números de compás se alinean de forma predeterminada por la
+derecha con su objeto padre. Éste es por lo general el borde
+izquierdo de una lÃnea o, si los números se imprimen dentro de la
+lÃnea, el lado isquierdo de una lÃnea divisoria. Los números
+también se pueden situar directamente sobre la barra de compás o
+alineados por la izquierda con ella.
+
+"
+
+ doctitlees = "Alineación de los números de compás"
+
texidoc = "
Bar numbers by default are right-aligned to their parent object. This
is usually the left edge of a line or, if numbers are printed within a
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
doctitlees = "Cambiar la forma de los silencios multicompás"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
doctitlede = "Die Taktart verändern ohne die Bebalkung zu beeinflussen"
+%% Translation of GIT committish :<e71f19ad847d3e94ac89750f34de8b6bb28611df>
+ texidocfr = "
+La commande @code{\time} gère les propriétés
+@code{timeSignatureFraction}, @code{beatLength}, @code{beatGrouping}
+et @code{measureLength} dans le contexte @code{Timing}, normallement
+rattaché à @code{Score}. Le fait de modifier la valeur de
+@code{timeSignatureFraction} aura pour effet de changer l'apparence du
+symbole affiché sans pour autant affecter les autres propriétés de la
+métrique :
+
+"
+ doctitlefr = "Changement de métrique sans affecter les règles de ligature"
+
texidoc = "
The @code{\\time} command sets the properties
@code{timeSignatureFraction}, @code{beatLength}, @code{beatGrouping}
"
doctitlede = "Die Zahl der N-tole verändern"
+
+%% Translation of GIT committish :<e71f19ad847d3e94ac89750f34de8b6bb28611df>
+ texidocfr = "
+L'apparence du chiffre est déterminée par la propriété @code{text} dans
+@code{TupletNumber}. La valeur par défaut imprime seulement le
+dénominateur, mais si elle est définie par la fonction
+@code{tuplet-number::calc-fraction-text}, la fraction entière
+@var{num}:@var{den} sera imprimée à la place.
+
+"
+ doctitlefr = "Modifier l'apparence du chiffre de nolet"
+
texidoc = "
By default, only the numerator of the tuplet number is printed over the
tuplet bracket, i.e., the denominator of the argument to the
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.13.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "paper-and-layout" % a new tag like "Mixing text and music" or
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "pitches,editorial-annotations,really-cool"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "tweaks-and-overrides"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "tweaks-and-overrides"
"
doctitlede = "Bindebögen manuell setzen"
+
+%% Translation of GIT committish :<e71f19ad847d3e94ac89750f34de8b6bb28611df>
+ texidocfr = "
+Il est possible de graver manuellement les liaisons de tenue, en
+modifiant la propriété @code{tie-configuration}. Pour chaque paire, le
+premier nombre indique la distance à la portée, en espaces de portée, et
+le second la direction (1 pour haut, @minus{}1 pour bas).
+
+"
+ doctitlefr = "Dessin à main levée de liaisons de tenue"
+
texidoc = "
Ties may be engraved manually by changing the @code{tie-configuration}
property of the @code{TieColumn} object. The first number indicates the
"
doctitlede = "Mehrere Triolen notieren, aber nur einmal \\times benutzen"
+
+%% Translation of GIT committish :<e71f19ad847d3e94ac89750f34de8b6bb28611df>
+ texidocfr = "
+La propriété @code{tupletSpannerDuration} spécifie la longueur voulue de
+chaque crochet. Avec elle, vous pouvez faire plusieurs nolets en ne
+tapant @code{\times} qu'une fois, ce qui évite une longue saisie.
+
+Dans l'exemple suivant, deux triolets sont imprimés avec une seule fonction
+@code{\times}.
+
+Pour plus d'information sur @code{make-moment}, voir @ref{Time administration}.
+
+"
+ doctitlefr = "Plusieurs triolets avec une seule commande \\times"
+
texidoc = "
The property @code{tupletSpannerDuration} sets how long each of the
tuplets contained within the brackets after @code{\\times} should last.
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
doctitlede = "Schlagrhythmus für Guitarren"
lsrtags = "rhythms,fretted-strings"
- texidoc = "For guitar music, it is possible to show strum rhythms, along
+ texidoc = "
+For guitar music, it is possible to show strum rhythms, along
with melody notes, chord names, and fret diagrams.
"
doctitle = "Guitar strum rhythms"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "rhythms,tweaks-and-overrides"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.13.1
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.13.1
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.13.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
-%% Do not edit this file; it is auto-generated from input/new
+%% Do not edit this file; it is auto-generated from LSR http://lsr.dsi.unimi.it
%% This file is in the public domain.
\version "2.13.1"
\header {
- lsrtags = "text"
+ lsrtags = "text, titles"
+
texidoc = "
-By putting the output of @code{lilypond-version} into lyrics or a
-text markup, it is possible to print the version number of LilyPond in
-a score, or in a document generated with @code{lilypond-book}.
+By putting the output of
+ @code{lilypond-version} into a lyric, it is possible to print the
+ version number of LilyPond in a score, or in a document generated
+ with @code{lilypond-book}. Another possibility is to append the
+ version number to the doc-string, in this manner:
+
"
doctitle = "Outputting the version number"
} % begin verbatim
-
\score {
\new Lyrics {
\override Score.RehearsalMark #'self-alignment-X = #LEFT
- \mark #(ly:export (string-append "Processed with LilyPond version "
- (lilypond-version)))
+ \mark #(string-append "Processed with LilyPond version " (lilypond-version))
s2
}
}
+
+
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "spacing"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
"
doctitlede = "Zeilenumbrüche bei N-tolen mit Balken erlauben"
+
+%% Translation of GIT committish :<e71f19ad847d3e94ac89750f34de8b6bb28611df>
+ texidocfr = "
+Cet exemple peu académique démontre comment il est possible d'insérer un saut
+de ligne dans un nolet portant une ligature. Ces ligatures doivent toutefois
+être explicites.
+
+"
+ doctitlefr = "Saut de ligne au milieu d'un nolet avec ligature"
+
texidoc = "
This artificial example shows how both manual and automatic line breaks
may be permitted to within a beamed tuplet. Note that such off-beat
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
\header {
lsrtags = "rhythms"
+ texidoces = "
+
+Al establecer la propiedad @code{'strict-grace-spacing} hacemos
+que las columnas musicales para las notas de adorno sean
+'flotantes', es decir, desacopladas de las notas que no son de
+adorno: primero se aplica el espaciado de las notas normales, y
+luego se ponen las columnas musicales de las notas de adorno a la
+izquierda de las columnas musicales de las notas principales.
+
+"
+
+ doctitlees = "Posicionamiento de las notas de adorno con espacio flotante"
+
texidoc = "
Setting the property @code{'strict-grace-spacing} makes the musical
columns for grace notes 'floating', i.e., decoupled from the non-grace
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
doctitlees = "Posicionar los silencios multicompás"
\header {
lsrtags = "rhythms"
+ texidoces = "
+
+Se pueden imprimir los números de compás a intervalos regulares
+mediante el establecimiento de la propiedad
+@code{barNumberVisibility}. Aquà los números de compás se
+imprimen a cada dos compases excepto al final de la lÃnea.
+
+"
+
+ doctitlees = "Imprimir números de compás a intervalos regulares"
+
texidoc = "
Bar numbers can be printed at regular intervals by setting the property
@code{barNumberVisibility}. Here the bar numbers are printed every two
\header {
lsrtags = "rhythms, tweaks-and-overrides"
+ texidoces = "
+
+Los números de compás también se pueden imprimir dentro de rectángulos o de circunferencias.
+
+"
+ doctitlees = "Imprimir números de compás dentro de rectángulos o circunferencias"
+
texidoc = "
Bar numbers can also be printed inside boxes or circles.
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.1
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
\header {
lsrtags = "rhythms"
+ texidoces = "
+
+Los valores predeterminados para las notas de adorno están
+almacenados en los identificadores @code{startGraceMusic},
+@code{stopGraceMusic}, @code{startAcciaccaturaMusic},
+@code{stopAcciaccaturaMusic}, @code{startAppoggiaturaMusic} y
+@code{stopAppoggiaturaMusic}, que están definidos en el archivo
+@code{ly/grace-init.ly}. Redefiniéndolos se pueden obtener otros
+efectos.
+
+"
+
+ doctitlees = "Redefinición de los valores globales predeterminados para notas de adorno"
+
texidoc = "
The global defaults for grace notes are stored in the identifiers
@code{startGraceMusic}, @code{stopGraceMusic},
\header {
lsrtags = "rhythms, contexts-and-engravers"
+ texidoces = "
+
+Se pueden eliminar completamente los números de compás quitando el
+grabador @code{Bar_number_engraver} del contexto de @code{Score}.
+
+"
+
+ doctitlees = "Suprimir los números de compás de toda la partitura"
+
texidoc = "
Bar numbers can be removed entirely by removing the
@code{Bar_number_engraver} from the @code{Score} context.
Pausen können in verschiedenen Stilen dargestellt werden.
"
+
+%% Translation of GIT committish :<e71f19ad847d3e94ac89750f34de8b6bb28611df>
+ texidocfr = "
+Les silences peuvent être gravés selon différents styles.
+
+"
+ doctitlefr = "Styles de silences"
+
texidoc = "
Rests may be used in various styles.
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
@q{pizzicato fuerte en que la cuerda se pulsa verticalmente produciendo un
chasquido y rebotando en el diapasón del instrumento} (Wikipedia). Se
denota mediante una circunferencia con una lÃnea vertical corta que parte
-del centro de aquélla hacia fuera. Aunque Lilypond no tiene ninguna
+del centro de aquélla hacia fuera. Aunque LilyPond no tiene ninguna
instrucción predefinida para crear esta marca, es fácil hacer la definición
y colocarla directamente en el archivo de lilypond.
"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "simultaneous-notes,tweaks-and-overrides"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "paper-and-layout"
+adding-the-current-date-to-a-score.ly
adjusting-lyrics-vertical-spacing.ly
aligning-and-centering-instrument-names.ly
aligning-marks-with-various-notation-objects.ly
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "staff-notation"
adding-the-current-date-to-a-score.ly
aligning-and-centering-instrument-names.ly
demonstrating-all-headers.ly
+outputting-the-version-number.ly
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
doctitlees = "Transportar música con el menor número de alteraciones"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
\header {
lsrtags = "rhythms"
+ texidoces = "
+
+Es posible aplicar la barrita que cruza la barra de las
+acciaccaturas, en otras situaciones.
+
+"
+
+ doctitlees = "Utilizar la barra que tacha las notas de adorno con notas normales"
+
texidoc = "
The slash through the stem found in acciaccaturas can be applied in
other situations.
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "tweaks-and-overrides"
"
doctitlede = "Überbingungen für Arpeggio genutzen"
+
+%% Translation of GIT committish :<e71f19ad847d3e94ac89750f34de8b6bb28611df>
+ texidocfr = "
+Les liaisons de tenue servent parfois à rendre un accord arpégé. Dans
+ce cas, les notes liées ne sont pas toutes consécutives. Il faut alors
+assigner à la propriété @code{tieWaitForNote} la valeur @code{#t}
+(@emph{true} pour @qq{vrai}). Cette même méthode peut servir, par
+exemple, à lier un trémolo à un accord.
+"
+ doctitlefr = "Liaison de tenue et arpège"
+
texidoc = "
Ties are sometimes used to write out arpeggios. In this case, two tied
notes need not be consecutive. This can be achieved by setting the
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
%% Edit this file using a Unicode aware editor, such as GVIM, GEDIT, Emacs
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
texidoces = "
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
lsrtags = "repeats,staff-notation"
%% Do not edit this file; it is auto-generated from input/new
%% This file is in the public domain.
+%% Note: this file works from version 2.12.0
\version "2.13.1"
\header {
-\version "2.12.3"
+\version "2.13.1"
\header {
lsrtags = "rhythms"
+++ /dev/null
-\version "2.12.0"
-
-\header {
- lsrtags = "text"
- texidoc = "
-By putting the output of @code{lilypond-version} into lyrics or a
-text markup, it is possible to print the version number of LilyPond in
-a score, or in a document generated with @code{lilypond-book}.
-"
- doctitle = "Outputting the version number"
-}
-
-\score {
- \new Lyrics {
- \override Score.RehearsalMark #'self-alignment-X = #LEFT
- \mark #(ly:export (string-append "Processed with LilyPond version "
- (lilypond-version)))
- s2
- }
-}
--- /dev/null
+\version "2.11.37"
+
+\header {
+ texidoc = "When two (or more) accidentals modify the same pitch,
+they are printed adjacent to one another unless they represent the same
+alteration, in which case they are printed in exactly the same position
+as one another. In either case, collisions with accidentals of different
+pitches are correctly computed."
+}
+
+\relative c''
+{<< <dis aeses as a! a! ais aisis a,! aeh cis'> \\ <ais aih> >> }
+
+\paper {ragged-right = ##t}
\version "2.12.0"
+#(set-default-paper-size "a6")
+
+\book {
+
\header{
texidoc="The optimal page breaker will stretch the
systems horizontally so that the vertical spacing will be
\repeat unfold 5 {a b c d}
}
-
+}
\ No newline at end of file
\header {
texidoc = "The max-systems-per-page variable prevents more
than a given number of systems from being on a page. Titles
-are not counted as systems. \noPageBreak can override
+are not counted as systems. \\noPageBreak can override
max-systems-per-page in unusual situations."
title = "Title"
}
--- /dev/null
+\version "2.13.1"
+
+\header {
+ texidoc = "If right hand stems have accidentals, optical spacing
+correction is still applied, but only if the stem directions are
+different."
+}
+
+\relative c' {
+ \time 2/4
+ c8 cis''
+ cis8 cis,,
+}
#include "stream-event.hh"
#include "warn.hh"
-
-void
-Accidental_placement::add_accidental (Grob *me, Grob *a)
+static Pitch*
+accidental_pitch (Grob *acc)
{
- a->set_parent (me, X_AXIS);
- a->set_property ("X-offset", Grob::x_parent_positioning_proc);
- SCM cause = a->get_parent (Y_AXIS)->get_property ("cause");
+ SCM cause = acc->get_parent (Y_AXIS)->get_property ("cause");
Stream_event *mcause = unsmob_stream_event (cause);
if (!mcause)
{
programming_error ("note head has no event cause");
- return;
+ return 0;
}
- Pitch *p = unsmob_pitch (mcause->get_property ("pitch"));
+ return unsmob_pitch (mcause->get_property ("pitch"));
+}
+
+void
+Accidental_placement::add_accidental (Grob *me, Grob *a)
+{
+ Pitch *p = accidental_pitch (a);
+ if (!p)
+ return;
+ a->set_parent (me, X_AXIS);
+ a->set_property ("X-offset", Grob::x_parent_positioning_proc);
int n = p->get_notename ();
SCM accs = me->get_object ("accidental-grobs");
Interval vertical_extent_;
vector<Box> extents_;
vector<Grob*> grobs_;
- Real offset_;
- int notename_;
- Accidental_placement_entry ()
- {
- offset_ = 0.0;
- notename_ = -1;
- }
};
-static Interval all_accidental_vertical_extent;
Real ape_priority (Accidental_placement_entry const *a)
{
return a->vertical_extent_[UP];
}
-int ape_compare (Accidental_placement_entry *const &a,
- Accidental_placement_entry *const &b)
-{
- return sign (ape_priority (a) - ape_priority (b));
-}
-
bool ape_less (Accidental_placement_entry *const &a,
Accidental_placement_entry *const &b)
{
return ape_priority (a) < ape_priority (b);
}
-int ape_rcompare (Accidental_placement_entry *const &a,
- Accidental_placement_entry *const &b)
+/*
+ This function provides a method for sorting accidentals that belong to the
+ same note. The accidentals that this function considers to be "smallest"
+ will be placed to the left of the "larger" accidentals.
+
+ Naturals are the largest (so that they don't get confused with cancellation
+ naturals); apart from that, we order according to the alteration (so
+ double-flats are the smallest).
+
+ Precondition: the accidentals are attached to NoteHeads of the same note
+ name -- the octaves, however, may be different.
+*/
+static bool
+acc_less (Grob *const &a, Grob *const &b)
{
- return -sign (ape_priority (a) - ape_priority (b));
+ Pitch *p = accidental_pitch (a);
+ Pitch *q = accidental_pitch (b);
+
+ if (!p || !q)
+ {
+ programming_error ("these accidentals do not have a pitch");
+ return false;
+ }
+
+ if (p->get_octave () != q->get_octave ())
+ return p->get_octave () < q->get_octave ();
+
+ if (p->get_alteration () == Rational (0))
+ return false;
+ if (q->get_alteration () == Rational (0))
+ return true;
+
+ return p->get_alteration () < q->get_alteration ();
}
/*
reverse (*apes);
}
-/*
- This routine computes placements of accidentals. During
- add_accidental (), accidentals are already grouped by note, so that
- octaves are placed above each other; they form columns. Then the
- columns are sorted: the biggest columns go closest to the note.
- Then the columns are spaced as closely as possible (using skyline
- spacing).
-
-
- TODO: more advanced placement. Typically, the accs should be placed
- to form a C shape, like this
-
-
- ##
- b b
- # #
- b
- b b
-
- The naturals should be left of the C as well; they should
- be separate accs.
-
- Note that this placement problem looks NP hard, so we just use a
- simple strategy, not an optimal choice.
-*/
-
-/*
- TODO: there should be more space in the following situation
-
-
- Natural + downstem
-
- *
- * |_
- * | | X
- * |_| |
- * | |
- *
-
-*/
-
-MAKE_SCHEME_CALLBACK (Accidental_placement, calc_positioning_done, 1);
-SCM
-Accidental_placement::calc_positioning_done (SCM smob)
+static vector<Accidental_placement_entry*>
+build_apes (SCM accs)
{
- Grob *me = unsmob_grob (smob);
- if (!me->is_live ())
- return SCM_BOOL_T;
-
- me->set_property ("positioning-done", SCM_BOOL_T);
-
- SCM accs = me->get_object ("accidental-grobs");
- if (!scm_is_pair (accs))
- return SCM_BOOL_T;
-
- /*
- TODO: there is a bug in this code. If two accs are on the same
- Y-position, they share an Ape, and will be printed in overstrike.
- */
vector<Accidental_placement_entry*> apes;
for (SCM s = accs; scm_is_pair (s); s = scm_cdr (s))
{
Accidental_placement_entry *ape = new Accidental_placement_entry;
- ape->notename_ = scm_to_int (scm_caar (s));
for (SCM t = scm_cdar (s); scm_is_pair (t); t = scm_cdr (t))
ape->grobs_.push_back (unsmob_grob (scm_car (t)));
apes.push_back (ape);
}
- Grob *common[] = {me, 0};
+ return apes;
+}
- /*
- First we must extract *all* pointers. We can only determine
- extents if we're sure that we've found the right common refpoint
- */
- vector<Grob*> note_cols, heads;
- for (vsize i = apes.size (); i--;)
+static void
+set_ape_skylines (Accidental_placement_entry *ape,
+ Grob **common)
+{
+ vector<Grob*> accs (ape->grobs_);
+ vector_sort (accs, &acc_less);
+
+ /* We know that each accidental has the same note name and we assume that
+ accidentals in different octaves won't collide. If two or more
+ accidentals are in the same octave:
+ 1) if they are the same accidental, print them in overstrike
+ 2) otherwise, shift one to the left so they don't overlap. */
+ int last_octave = 0;
+ Real offset = 0;
+ Real last_offset = 0;
+ Rational last_alteration (0);
+ for (vsize i = accs.size (); i--;)
{
- Accidental_placement_entry *ape = apes[i];
- for (vsize j = ape->grobs_.size (); j--;)
+ Grob *a = accs[i];
+ Pitch *p = accidental_pitch (a);
+
+ if (!p)
+ continue;
+
+ if (i == accs.size () - 1 || p->get_octave () != last_octave)
{
- Grob *a = ape->grobs_[j];
+ last_offset = 0;
+ offset = a->extent (a, X_AXIS)[LEFT] - 0.2;
+ }
+ else if (p->get_alteration () == last_alteration)
+ a->translate_axis (last_offset, X_AXIS);
+ else /* Our alteration is different from the last one */
+ {
+ Real this_offset = offset - a->extent (a, X_AXIS)[RIGHT];
+ a->translate_axis (this_offset, X_AXIS);
- if (common[Y_AXIS])
- common[Y_AXIS] = common[Y_AXIS]->common_refpoint (a, Y_AXIS);
- else
- common[Y_AXIS] = a;
+ /* FIXME: read the padding from the AccidentalPlacement grob */
+ last_offset = this_offset;
+ offset -= a->extent (a, X_AXIS).length () + 0.2;
+ }
- Grob *head = a->get_parent (Y_AXIS);
+ vector<Box> boxes = Accidental_interface::accurate_boxes (a, common);
+ ape->extents_.insert (ape->extents_.end (), boxes.begin (), boxes.end ());
+ for (vsize j = boxes.size (); j--;)
+ ape->vertical_extent_.unite (boxes[j][Y_AXIS]);
+
+ last_octave = p->get_octave ();
+ last_alteration = p->get_alteration ();
+ }
+ ape->left_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, LEFT);
+ ape->right_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, RIGHT);
+}
+
+static vector<Grob*>
+extract_heads_and_stems (vector<Accidental_placement_entry*> const &apes)
+{
+ vector<Grob*> note_cols;
+ vector<Grob*> ret;
+
+ for (vsize i = apes.size (); i--;)
+ {
+ Accidental_placement_entry *ape = apes[i];
+ for (vsize j = ape->grobs_.size (); j--;)
+ {
+ Grob *acc = ape->grobs_[j];
+ Grob *head = acc->get_parent (Y_AXIS);
Grob *col = head->get_parent (X_AXIS);
+
if (Note_column::has_interface (col))
note_cols.push_back (col);
else
- heads.push_back (head);
+ ret.push_back (head);
}
}
/*
- This is a little kludgy: to get all notes, we look if there are
- collisions as well.
+ This is a little kludgy: in case there are note columns without
+ accidentals, we get them from the Note_collision objects.
*/
for (vsize i = note_cols.size (); i--;)
{
Grob *c = note_cols[i]->get_parent (X_AXIS);
if (Note_collision_interface::has_interface (c))
{
- extract_grob_set (c, "elements", gs);
-
- concat (note_cols, gs);
+ extract_grob_set (c, "elements", columns);
+ concat (note_cols, columns);
}
}
+ /* Now that we have all of the columns, grab all of the note-heads */
for (vsize i = note_cols.size (); i--;)
- concat (heads, extract_grob_array (note_cols[i], "note-heads"));
-
- vector_sort (heads, less<Grob*> ());
- uniq (heads);
-
- vector<Grob *> stems;
- for (vsize i = 0; i < heads.size (); i++)
- {
- if (Grob *s = Rhythmic_head::get_stem (heads[i]))
- stems.push_back (s);
- }
-
- vector_sort (stems, less<Grob*> ());
- uniq (stems);
-
- common[Y_AXIS] = common_refpoint_of_array (heads, common[Y_AXIS], Y_AXIS);
- common[Y_AXIS] = common_refpoint_of_array (stems, common[Y_AXIS], Y_AXIS);
-
- for (vsize i = 0; i < heads.size (); i++)
- {
- if (Grob *s = Rhythmic_head::get_stem (heads[i]))
- {
- stems.push_back (s);
- common[Y_AXIS] = s->common_refpoint (common[Y_AXIS], Y_AXIS);
- }
- }
+ concat (ret, extract_grob_array (note_cols[i], "note-heads"));
- vector_sort (stems, less<Grob*> ());
- uniq (stems);
-
+ /* Now that we have all of the heads, grab all of the stems */
+ for (vsize i = ret.size (); i--;)
+ if (Grob *s = Rhythmic_head::get_stem (ret[i]))
+ ret.push_back (s);
- for (vsize i = apes.size (); i--;)
- {
- Accidental_placement_entry *ape = apes[i];
- for (vsize j = apes[i]->grobs_.size (); j--;)
- {
- Grob *a = apes[i]->grobs_[j];
- vector<Box> boxes = Accidental_interface::accurate_boxes (a, common);
+ vector_sort (ret, less<Grob*> ());
+ uniq (ret);
+ return ret;
+}
- ape->extents_.insert (ape->extents_.end (), boxes.begin (), boxes.end ());
- }
- ape->left_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, LEFT);
- ape->right_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, RIGHT);
- }
+static Grob*
+common_refpoint_of_accidentals (vector<Accidental_placement_entry*> const &apes, Axis a)
+{
+ Grob *ret = 0;
- Interval total;
for (vsize i = apes.size (); i--;)
- {
- Interval y;
+ for (vsize j = apes[i]->grobs_.size (); j--;)
+ {
+ if (!ret)
+ ret = apes[i]->grobs_[j];
+ else
+ ret = ret->common_refpoint (apes[i]->grobs_[j], a);
+ }
- for (vsize j = apes[i]->extents_.size (); j--;)
- y.unite (apes[i]->extents_[j][Y_AXIS]);
- apes[i]->vertical_extent_ = y;
- total.unite (y);
- }
- all_accidental_vertical_extent = total;
- stagger_apes (&apes);
+ return ret;
+}
- Accidental_placement_entry *head_ape = new Accidental_placement_entry;
- common[X_AXIS] = common_refpoint_of_array (heads, common[X_AXIS], X_AXIS);
-
+static Skyline
+build_heads_skyline (vector<Grob*> const &heads_and_stems,
+ Grob **common)
+{
vector<Box> head_extents;
- for (vsize i = heads.size (); i--;)
- head_extents.push_back (Box (heads[i]->extent (common[X_AXIS], X_AXIS),
- heads[i]->extent (common[Y_AXIS], Y_AXIS)));
+ for (vsize i = heads_and_stems.size (); i--;)
+ head_extents.push_back (Box (heads_and_stems[i]->extent (common[X_AXIS], X_AXIS),
+ heads_and_stems[i]->pure_height (common[Y_AXIS], 0, INT_MAX)));
- for (vsize i = 0; i < stems.size (); i ++)
- {
- int very_large = INT_MAX;
-
- head_extents.push_back (Box (stems[i]->extent (common[X_AXIS], X_AXIS),
- stems[i]->pure_height (common[Y_AXIS], 0, very_large)));
- }
-
- head_ape->left_skyline_ = Skyline (head_extents, 0, Y_AXIS, LEFT);
- head_ape->offset_ = 0.0;
+ return Skyline (head_extents, 0, Y_AXIS, LEFT);
+}
+/*
+ Position the apes, starting from the right, so that they don't collide.
+ Return the total width.
+*/
+static Interval
+position_apes (Grob *me,
+ vector<Accidental_placement_entry*> const &apes,
+ Skyline const &heads_skyline)
+{
Real padding = robust_scm2double (me->get_property ("padding"), 0.2);
-
- Skyline left_skyline = head_ape->left_skyline_;
+ Skyline left_skyline = heads_skyline;
left_skyline.raise (-robust_scm2double (me->get_property ("right-padding"), 0));
/*
Add accs entries right-to-left.
*/
+ Interval width;
+ Real last_offset = 0.0;
for (vsize i = apes.size (); i-- > 0;)
{
- Real offset = -apes[i]->right_skyline_.distance (left_skyline);
+ Accidental_placement_entry *ape = apes[i];
+
+ Real offset = -ape->right_skyline_.distance (left_skyline);
if (isinf (offset))
- offset = (i + 1 < apes.size ()) ? apes[i + 1]->offset_ : 0.0;
+ offset = last_offset;
else
offset -= padding;
- apes[i]->offset_ = offset;
-
- Skyline new_left_skyline = apes[i]->left_skyline_;
- new_left_skyline.raise (apes[i]->offset_);
+ Skyline new_left_skyline = ape->left_skyline_;
+ new_left_skyline.raise (offset);
new_left_skyline.merge (left_skyline);
left_skyline = new_left_skyline;
- }
- for (vsize i = apes.size (); i--;)
- {
- Accidental_placement_entry *ape = apes[i];
+ /* Shift all of the accidentals in this ape */
for (vsize j = ape->grobs_.size (); j--;)
- ape->grobs_[j]->translate_axis (ape->offset_, X_AXIS);
+ ape->grobs_[j]->translate_axis (offset, X_AXIS);
+
+ for (vsize j = ape->extents_.size (); j--;)
+ width.unite (offset + ape->extents_[j][X_AXIS]);
+
+ last_offset = offset;
}
- Interval left_extent, right_extent;
- Accidental_placement_entry *ape = apes[0];
+ return width;
+}
- for (vsize i = ape->extents_.size (); i--;)
- left_extent.unite (ape->offset_ + ape->extents_[i][X_AXIS]);
- ape = apes.back ();
- for (vsize i = ape->extents_.size (); i--;)
- right_extent.unite (ape->offset_ + ape->extents_[i][X_AXIS]);
+/*
+ This routine computes placements of accidentals. During
+ add_accidental (), accidentals are already grouped by note, so that
+ octaves are placed above each other; they form columns. Then the
+ columns are sorted: the biggest columns go closest to the note.
+ Then the columns are spaced as closely as possible (using skyline
+ spacing).
- left_extent[LEFT] -= robust_scm2double (me->get_property ("left-padding"), 0);
- Interval width (left_extent[LEFT], right_extent[RIGHT]);
- SCM scm_width = ly_interval2scm (width);
+ TODO: more advanced placement. Typically, the accs should be placed
+ to form a C shape, like this
+
+
+ ##
+ b b
+ # #
+ b
+ b b
+
+ The naturals should be left of the C as well; they should
+ be separate accs.
+
+ Note that this placement problem looks NP hard, so we just use a
+ simple strategy, not an optimal choice.
+*/
+
+/*
+ TODO: there should be more space in the following situation
+
+
+ Natural + downstem
+
+ *
+ * |_
+ * | | X
+ * |_| |
+ * | |
+ *
+
+*/
+
+MAKE_SCHEME_CALLBACK (Accidental_placement, calc_positioning_done, 1);
+SCM
+Accidental_placement::calc_positioning_done (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ if (!me->is_live ())
+ return SCM_BOOL_T;
+
+ me->set_property ("positioning-done", SCM_BOOL_T);
+
+ SCM accs = me->get_object ("accidental-grobs");
+ if (!scm_is_pair (accs))
+ return SCM_BOOL_T;
+
+ vector<Accidental_placement_entry*> apes = build_apes (accs);
+
+ Grob *common[] = {me, 0};
+
+ vector<Grob*> heads_and_stems = extract_heads_and_stems (apes);
+
+ common[Y_AXIS] = common_refpoint_of_accidentals (apes, Y_AXIS);
+ common[Y_AXIS] = common_refpoint_of_array (heads_and_stems, common[Y_AXIS], Y_AXIS);
+ common[X_AXIS] = common_refpoint_of_array (heads_and_stems, me, X_AXIS);
+
+ for (vsize i = apes.size (); i--;)
+ set_ape_skylines (apes[i], common);
+ Skyline heads_skyline = build_heads_skyline (heads_and_stems, common);
+
+ stagger_apes (&apes);
+ Interval width = position_apes (me, apes, heads_skyline);
+
me->flush_extent_cache (X_AXIS);
- me->set_property ("X-extent", scm_width);
+ me->set_property ("X-extent", ly_interval2scm (width));
junk_pointers (apes);
- delete head_ape;
-
return SCM_BOOL_T;
}
if (!pango_dict_->try_retrieve (key, &val))
{
if (be_verbose_global)
- progress_indication ("[" + string (pango_fn));
+ progress_indication ("\n[" + string (pango_fn));
Pango_font *pf = new Pango_font (pango_ft2_fontmap_,
description,
return 0;
if (be_verbose_global)
- progress_indication ("[" + file_name);
+ progress_indication ("\n[" + file_name);
val = Open_type_font::make_otf (file_name);
/*
We use the following optimal substructure. Let W (A) be our weight function.
- Let A_{k, n} = (a_{k, n,1}, ... a_{k, n, k}) be the optimal set of line breaks
+ Let A_{k, n} = (a_{k, n, 1}, ... a_{k, n, k}) be the optimal set of line breaks
for k systems and n potential breakpoints. a_{k, n, k} = n (it is the end of
the piece)
" The error is formatted with @code{format} and @var{rest}.")
{
LY_ASSERT_TYPE (scm_is_string, str, 1);
- if (scm_is_pair(scm_car(rest)))
- rest=scm_car(rest);
str = scm_simple_format (SCM_BOOL_F, str, rest);
error (ly_scm2string (str));
return SCM_UNSPECIFIED;
state_stack_.push_back (yy_current_buffer);
if (be_verbose_global)
- progress_indication (string ("[") + file->name_string ());
+ {
+ string spaces = "";
+ for (size_t i = 0; i < state_stack_.size (); i++)
+ spaces += " ";
+ progress_indication (string ("\n") + spaces + string ("[") + file->name_string ());
+ }
include_stack_.push_back (file);
state_stack_.push_back (yy_current_buffer);
if (be_verbose_global)
- progress_indication (string ("[") + name);
+ {
+ string spaces = "";
+ for (size_t i = 0; i < state_stack_.size (); i++)
+ spaces += " ";
+ progress_indication (string ("\n") + spaces + string ("[") + name);
+ }
include_stack_.push_back (file);
yy_switch_to_buffer (yy_create_buffer (file->get_istream (), YY_BUF_SIZE));
string result (&chars[0], chars.size ());
if (be_verbose_global)
- progress_indication ("]");
+ progress_indication ("]\n");
return result;
}
}
-/**
+/*
Correct for optical illusions. See [Wanske] p. 138. The combination
up-stem + down-stem should get extra space, the combination
down-stem + up-stem less.
Direction d = LEFT;
+ bool acc_right = false;
+
Grob *bar = Spacing_interface::extremal_break_aligned_grob (me, RIGHT,
rcolumn->break_status_dir (),
&bar_xextent);
continue;
/*
- don't correct if accidentals are sticking out of the right side.
+ Find accidentals which are sticking out of the right side.
*/
- if (d == RIGHT && Note_column::accidentals (it))
- return;
+ if (d == RIGHT)
+ acc_right = acc_right || Note_column::accidentals (it);
Grob *stem = Note_column::get_stem (it);
correction *= 0.5;
}
}
- else if (stem_dirs[LEFT] * stem_dirs[RIGHT] == 1)
+ /*
+ Only apply same direction correction if there are no
+ accidentals sticking out of the right hand side.
+ */
+ else if (stem_dirs[LEFT] * stem_dirs[RIGHT] == 1
+ && !acc_right)
correction = same_direction_correction (me, head_posns);
*space += correction;
(c) 2006--2009 Joe Neeman <joeneeman@gmail.com>
*/
+/*
+ This is a utility class for page-breaking algorithms. There are some complex
+ parts of this class, some of which are useful to understand if you intend
+ to write a page breaking algorithm (ie. a subclass of Page_breaking). Most
+ of these complexities were introduced in order to break the problem of
+ page-breaking into simpler subproblems and to hide some of the bookkeeping
+ complexities of page breaking from the page breaking algorithms.
+
+ COMPRESSED LINES
+ There are several functions that actually distribute systems across pages
+ (for example, the space_systems_XXX and pack_systems_XXX functions). If
+ each of these functions had to handle \noPageBreak, it would be a mess.
+ Therefore, we handle \noPageBreak by "compressing" the list of systems
+ before doing any layout: we concatenate any two systems separated by a
+ \noPageBreak into a single system. The page-breaking functions can do their
+ magic without encountering a \noPageBreak; we then "uncompress" the systems
+ at the end. We almost always work with cached_line_details_, which are
+ "compressed."
+
+ CHUNKS
+ The basic operation of a page breaking algorithm is to repeatedly request
+ some systems from the line-breaker and place those systems on some pages.
+ With each repetition, the page breaking algorithm asks the line-breaker for
+ some systems that it thinks will help it achieve a better layout. The
+ Page_breaking class provides functionality to facilitate this in the case
+ that the page breaking algorithm only cares about the number of systems.
+
+ Even if a page breaking algorithm only cares number of systems, there may
+ be many ways to satisfy its request. For example, in a piece with 2 scores
+ and a request for 10 systems, we could return 5 systems from each score or
+ 4 from the first and 6 from the second. Even within a score, we might
+ want to try several different line breaking configurations with a fixed
+ system count; if there is a forced \pageBreak, for example, we might wish
+ to tweak the number of systems on both sides of the \pageBreak independently.
+
+ The Page_breaking class takes care of finding these configurations. It
+ divides the piece into "chunks" and sets up the line-breaker in such a way
+ that the number of systems in each chunk can be modified independently.
+ Chunks never cross score boundaries; each title and markup is its own chunk.
+ When a page breaking algorithm requests a number of systems, the Page_breaker
+ stores an array of potential configurations, which the page breaking
+ algorithm can iterate over using current_configuration(vsize).
+
+ LINE_DIVISION
+ A Line_division is simply a way of storing the exact way in which the
+ total number of systems is distributed among chunks. Note that a
+ Line_division may not (in fact, usually will not) describe all of the chunks
+ in the entire book. Rather, it will describe the subset of chunks that lie
+ between some fixed starting and ending point. This subset of chunks changes
+ whenever a page breaking algorithm asks to consider a different pair of
+ starting and ending breakpoints. In particular, a Line_division should be
+ discarded after a call to set_current_breakpoints, since that Line_division
+ refers to a subset of chunks which might be different from the current
+ subset of chunks under consideration.
+*/
+
#include "page-breaking.hh"
#include "international.hh"
max_page_count_ = page_count;
}
+// Carries out one step in the dynamic programming algorithm for putting systems
+// on a fixed number of pages. One call to this routine calculates the best
+// configuration for putting lines 0 through LINE-1 on PAGE+1 pages, provided that
+// we have previously called calc_subproblem(page-1, k) for every k < LINE.
+//
+// This algorithm is similar to the constrained-breaking algorithm.
bool
Page_spacer::calc_subproblem (vsize page, vsize line)
{
line_count += lines_[page_start].compressed_nontitle_lines_count_;
if (page > 0 || page_start == 0)
{
+ // If the last page is ragged, set its force to zero. This way, we will leave
+ // the last page half-empty rather than trying to balance things out
+ // (which only makes sense in non-ragged situations).
if (line == lines_.size () - 1 && ragged && last && space.force_ > 0)
space.force_ = 0;
string file_name = ly_scm2string (pfb_file_name);
if (be_verbose_global)
- progress_indication ("[" + file_name);
+ progress_indication ("\n[" + file_name);
vector<char> pfb_string = gulp_file (file_name, 0);
char *pfa = pfb2pfa ((Byte *) &pfb_string[0], pfb_string.size ());
string file_name = ly_scm2string (otf_file_name);
if (be_verbose_global)
- progress_indication ("[" + file_name);
+ progress_indication ("\n[" + file_name);
FT_Face face = open_ft_face (file_name, 0 /* index */);
string table = get_otf_table (face, "CFF ");
}
if (be_verbose_global)
- message (_f ("Element count %d.", count + element_count ()));
+ message (_f ("Element count %d", count + element_count ()) + "\n");
}
SCM
"@var{layout} is a @code{\\layout} block; it may be obtained from a grob with"
" @code{ly:grob-layout}. @var{props} is an alist chain, i.e. a list of"
" alists. This is typically obtained with"
-" @code{(ly:grob-alist-chain (ly:layout-lookup layout 'text-font-defaults))}."
+" @code{(ly:grob-alist-chain grob (ly:output-def-lookup layout 'text-font-defaults))}."
" @var{markup} is the markup text to be processed.");
SCM
Text_interface::interpret_markup (SCM layout_smob, SCM props, SCM markup)
string file_name = ly_scm2string (ttf_file_name);
if (be_verbose_global)
- progress_indication ("[" + file_name);
+ progress_indication ("\n[" + file_name);
FT_Face face;
string file_name = ly_scm2string (ttf_file_name);
if (be_verbose_global)
- progress_indication ("[" + file_name);
+ progress_indication ("\n[" + file_name);
Memory_out_stream stream;
(make-music 'SequentialMusic)))
-tag = #(define-music-function (parser location tag arg)
+tag =
+#(define-music-function (parser location tag arg)
(symbol? ly:music?)
(_i "Add @var{tag} to the @code{tags} property of @var{arg}.")
(ly:pitch-negate (pitch-of-note pitch-note)))
'Staff))
-tweak = #(define-music-function (parser location sym val arg)
- (symbol? scheme? ly:music?)
+tweak =
+#(define-music-function (parser location sym val arg)
+ (symbol? scheme? ly:music?)
+ (_i "Add @code{sym . val} to the @code{tweaks} property of @var{arg}.")
- (_i "Add @code{sym . val} to the @code{tweaks} property of @var{arg}.")
-
- (set!
- (ly:music-property arg 'tweaks)
- (acons sym val
- (ly:music-property arg 'tweaks)))
- arg)
+ (if (equal? (object-property sym 'backend-type?) #f)
+ (begin
+ (ly:warning (_ "cannot find property type-check for ~a") sym)
+ (ly:warning (_ "doing assignment anyway"))))
+ (set!
+ (ly:music-property arg 'tweaks)
+ (acons sym val
+ (ly:music-property arg 'tweaks)))
+ arg)
\\sustainUp -> \\sustainOff, \\sustainDown -> \\sustainOn\n\
\\sostenutoDown -> \\sostenutoOn, \\sostenutoUp -> \\sostenutoOff")
def conv (str):
- str = re.sub (r"\\octave", r"\\octaveCheck", str)
+ str = re.sub (r"\\octave(?![a-zA-Z])", r"\\octaveCheck", str)
str = re.sub (r"arpeggioUp", r"arpeggioArrowUp", str)
str = re.sub (r"arpeggioDown", r"arpeggioArrowDown", str)
str = re.sub (r"arpeggioNeutral", r"arpeggioNormal", str)
('F', 4): "bass",
('F', 5): "subbass",
("percussion", 2): "percussion",
+ # Workaround: MuseScore uses PERC instead of percussion
+ ("PERC", 2): "percussion",
("TAB", 5): "tab"}.get ((self.type, self.position), None)
def ly_expression (self):
return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
command
(format #f "~a > ~a 2>&1 " command dev-null))))
(if (ly:get-option 'verbose)
- (ly:message (_ "Invoking `~a'...") command))
+ (begin
+ (ly:message (_ "Invoking `~a'...") command))
+ (ly:progress "\n"))
(set! status
(if (pair? rest)
".pdf"))
(is-eps (string-match "\\.eps$" name))
(paper-size-string (if is-eps
- " -dEPSCrop "
- (ly:format "-dDEVICEWIDTHPOINTS=~$ \
--dDEVICEHEIGHTPOINTS=~$ "
- paper-width paper-height )))
+ "-dEPSCrop"
+ (ly:format "-dDEVICEWIDTHPOINTS=~$\
+ -dDEVICEHEIGHTPOINTS=~$"
+ paper-width paper-height)))
(cmd (simple-format #f
"~a\
~a\
~a\
~a\
- -dCompatibilityLevel=1.4 \
+ -dCompatibilityLevel=1.4\
-dNOPAUSE\
-dBATCH\
- -r1200 \
+ -r1200\
-sDEVICE=pdfwrite\
-sOutputFile=~S\
-c .setpdfwrite\
(if (ly:get-option 'verbose) "" "-q")
(if (or (ly:get-option 'gs-load-fonts)
(ly:get-option 'gs-load-lily-fonts))
-
- " -dNOSAFER "
- " -dSAFER ")
+ "-dNOSAFER"
+ "-dSAFER")
paper-size-string
pdf-name
name)))
ly:arpeggio::print
ly:arpeggio::brew-chord-bracket
ly:bar-line::print
+ ly:mensural-ligature::brew-ligature-primitive
ly:note-head::print
ly:dots::print
ly:clef::print
(ly:error (_ "cannot find: ~A") x))
(primitive-load file-name)
(if (ly:get-option 'verbose)
- (ly:progress "]"))))
+ (ly:progress "]\n"))))
(define-public DOS
(let ((platform (string-tokenize
(if separate-logs
(ly:stderr-redirect (format "~a.log" base) "w"))
(if ping-log
- (format ping-log "Procesing ~a\n" base))
+ (format ping-log "Processing ~a\n" base))
(if (ly:get-option 'trace-memory-frequency)
(mtrace:start-trace (ly:get-option 'trace-memory-frequency)))
(lilypond-file handler x)
;; FIXME: soft-code, localize
(welcome-ly (string-append ly "Welcome_to_LilyPond.ly"))
(cmd (get-editor-command welcome-ly 0 0 0)))
- (ly:message (_ "Invoking `~a'...") cmd)
+ (ly:message (_ "Invoking `~a'...\n") cmd)
(system cmd)
(exit 1)))
(string-append
make-name ": "
(_ "Invalid argument in position ~A. Expect: ~A, found: ~S."))
- error-msg)
+ (car error-msg) (cadr error-msg)(caddr error-msg))
(cons markup-function args))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
begin_header_re = re.compile (r'\\header\s*{', re.M)
+ly_new_version_re = re.compile (r'\\version\s*"(.+?)"')
+
# add tags to ly files from LSR
def add_tags (ly_code, tags):
return begin_header_re.sub ('\\g<0>\n lsrtags = "' + tags + '"\n', ly_code, 1)
+# for snippets from input/new, add message for earliest working version
+def add_version (ly_code):
+ return '''%% Note: this file works from version ''' + ly_new_version_re.search (ly_code).group (1) + '\n'
+
def copy_ly (srcdir, name, tags):
global unsafe
global unconverted
if in_dir and in_dir in srcdir:
s = LY_HEADER_LSR + add_tags (s, tags)
else:
- s = LY_HEADER_NEW + s
+ s = LY_HEADER_NEW + add_version (s) + s
s = mark_verbatim_section (s)
s = lsr_comment_re.sub ('', s)