]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/key-performer.cc (create_audio_elements): always use major
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 25 May 2003 20:30:40 +0000 (20:30 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 25 May 2003 20:30:40 +0000 (20:30 +0000)
key

* Documentation/user/internals.itely: updates

* input/regression/beam-break.ly: new file.

* lily/beam.cc (brew_molecule): handle broken beams (i.e. print
beams if starting or terminating stems have 'beaming set.)

* lily/beam-engraver.cc (process_music): add forbidBeamBreak
property.

15 files changed:
ChangeLog
Documentation/user/converters.itely
Documentation/user/internals.itely
Documentation/user/invoking.itexi
Documentation/user/lilypond-book.itely
Documentation/user/refman.itely
Documentation/user/tutorial.itely
input/regression/beam-break.ly [new file with mode: 0644]
lily/beam-engraver.cc
lily/beam.cc
lily/key-performer.cc
lily/music-constructor.cc
ly/engraver-init.ly
scm/define-translator-properties.scm
scm/midi.scm

index c92ef27f79ae385d7a9cc323e3e8b3b2669c0816..ae223fe91b4dd8734a029547815013cf09880238 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2003-05-25  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
+
+       * lily/key-performer.cc (create_audio_elements): always use major
+       key
+
+       * Documentation/user/internals.itely: updates
+
+       * input/regression/beam-break.ly: new file.
+
+       * lily/beam.cc (brew_molecule): handle broken beams (i.e. print
+       beams if starting or terminating stems have 'beaming set.)
+
+       * lily/beam-engraver.cc (process_music): add forbidBeamBreak
+       property.
+
+       * lily/parser.yy (verbose_command_req): add comment about scales.
+
 2003-05-25  Heikki Junes  <hjunes@cc.hut.fi>
 
        * lilypond-indent.el: adjust regexps in bracket-matching.
index 53922b0f926e85dae4ed41cc77b6cf9b25a3c0e7..e548a144722964bdf88558b4d73aa83b673f129a 100644 (file)
@@ -7,7 +7,7 @@ Music can be entered also by importing it from other formats.  This
 chapter documents the tools included in the distribution to do so.
 There are other tools that produce LilyPond input, for example GUI
 sequencers and XML converters. Refer to the
-@uref{website,http://lilypond.org} for more details.
+@uref{http://lilypond.org,website} for more details.
 
 
 
@@ -296,7 +296,7 @@ version information
 
 @refbugs
 
-musedata2ly converts only a small subset musedata. 
+@file{musedata2ly} converts only a small subset of musedata. 
 
 @node Invoking mup2ly
 @section Invoking mup2ly
@@ -335,7 +335,7 @@ print warranty and copyright.
 
 @refbugs
 
-Currently, only plain notes (pitches, durations), voices and staves are
+Currently, only plain notes (pitches, durations), voices, and staves are
 converted.
 
 
index 003bed65818cf7e887c1bb745c5ecc9fcc507fa0..692a61d55a48b33b91052a9a8225fc29be47b144 100644 (file)
 @chapter Advanced topics
 
 
-When LilyPond is run, it reads an input file.  During parsing, Music
-objects are created. This music is interpreted, which is done by
-contexts, that produce graphical objects.  This section discusses
-details of these three concepts, and how they are glued together with
-the embedded Scheme interpreter. 
+When LilyPond is run, it reads an input file which is parsed.  During
+parsing, Music objects are created. This music is interpreted, which
+is done by contexts, that produce graphical objects.  This section
+discusses details of these three concepts, and how they are glued
+together with the embedded Scheme interpreter.
 
 @menu
 * Interpretation context::      
@@ -32,20 +32,21 @@ the embedded Scheme interpreter.
 @menu
 * Creating contexts::           
 * Default contexts::            
-* Context evaluation::          
 * Context properties::          
+* Context evaluation::          
+* Defining contexts::           
 * Engravers and performers::    
-* Changing context definitions::  
 * Defining new contexts::       
 @end menu
 
 
 Interpretation contexts are objects that only exist during program
 run.  During the interpretation phase (when @code{interpreting music}
-is interpreted to standard output), the music expression in a
+is printed on the standard output), the music expression in a
 @code{\score} block is interpreted in time order, the same order in
-which hear and play the music.  During this phase, the interpretation
-context holds the state for the current point within the music, for example
+which we hear and play the music.  During this phase, the interpretation
+context holds the state for the current point within the music, for
+example
 @itemize @bullet
 @item What notes are playing at this point?
 
@@ -94,20 +95,29 @@ If no such context exists, it will be created.
 @end lilypond
 
 @noindent
-In this example, the @code{c} and @code{d} are printed on the
-default staff.  For the @code{e}, a context Staff called
-@code{another} is specified; since that does not exist, a new
-context is created.  Within @code{another}, a (default) Voice context
-is created for the @code{e4}.  When all music referring to a
-context is finished, the context is ended as well.  So after the
-third quarter, @code{another} is removed.
+In this example, the @code{c} and @code{d} are printed on the default
+staff.  For the @code{e}, a context @code{Staff} called @code{another}
+is specified; since that does not exist, a new context is created.
+Within @code{another}, a (default) Voice context is created for the
+@code{e4}.  A context is ended when when all music referring it has
+finished, so after the third quarter, @code{another} is removed.
 
 
 @node Default contexts
 @subsection Default contexts
 
-Most music expressions do not need an explicit @code{\context}
-declaration: they inherit the notation context from their parent.  In
+Every top level music is interpreted by the @code{Score} context; in
+other words, you may think of @code{\score} working like
+
+@example
+\score @{
+  \context Score @var{music}
+@}
+@end example
+
+Music expressions  inherit their context from the enclosing music
+expression. Hence, it is not necessary to explicitly specify
+@code{\context} for most expressions.  In
 the following example, only the sequential expression has an explicit
 context. The notes contained therein inherit the @code{goUp} context
 from the enclosing music expression.
@@ -116,17 +126,6 @@ from the enclosing music expression.
   \notes \context Voice = goUp { c'4 d' e' }
 @end lilypond
 
-There are some quirks that you must keep in mind when dealing with
-defaults:
-
-First, every top level music is interpreted by the Score context; in other
-words, you may think of @code{\score} working like
-
-@example
-\score @{
-  \context Score @var{music}
-@}
-@end example
 
 Second, contexts are created automatically to be able to interpret the
 music expressions.  Consider the following example.
@@ -136,40 +135,18 @@ music expressions.  Consider the following example.
 @end lilypond
 
 @noindent
-The sequential music is interpreted by the Score context initially
-(notice that the @code{\context} specification is redundant), but when a
-note is encountered, contexts are setup to accept that note.  In this
-case, a Thread, Voice, and Staff context are created.  The rest of the
-sequential music is also interpreted with the same Thread, Voice, and
-Staff context, putting the notes on the same staff, in the same voice.
-
-@node Context evaluation
-@subsection Context evaluation
-
-Scheme code can be used to modify contexts. The syntax for this is
-
-@example
-  \applycontext @var{function}
-@end example
-
-@var{function} should be a Scheme function taking a single argument,
-being the context to apply it with. The following code will print the
-current bar number on the standard output during the compile.
-
-@example
-    \applycontext
-       #(lambda (x)
-        (format #t "\nWe were called in barnumber ~a.\n"
-         (ly:get-context-property x 'currentBarNumber)))
-@end example
-
+The sequential music is interpreted by the Score context initially,
+but when a note is encountered, contexts are setup to accept that
+note.  In this case, a Thread, Voice, and Staff context are created.
+The rest of the sequential music is also interpreted with the same
+Thread, Voice, and Staff context, putting the notes on the same staff,
+in the same voice.
 
 @node Context properties
 @subsection Context properties
 
-
-Notation contexts have properties.  These properties are from
-the @file{.ly} file using the following expression:
+Contexts have properties.  These properties are set from the @file{.ly}
+file using the following expression:
 @cindex @code{\property}
 @cindex context properties
 @cindex properties, context
@@ -233,17 +210,37 @@ The syntax of @code{\unset} is asymmetric: @code{\property \unset} is not
 the inverse of @code{\property \set}.
 
 
-@node Engravers and performers
-@subsection Engravers and performers
+@node Context evaluation
+@subsection Context evaluation
+
+Contexts can be modified during interpretation with Scheme code. The
+syntax for this is
+@example
+  \applycontext @var{function}
+@end example
+
+@var{function} should be a Scheme function taking a single argument,
+being the context to apply it to. The following code will print the
+current bar number on the standard output during the compile.
+
+@example
+    \applycontext
+      #(lambda (x)
+         (format #t "\nWe were called in barnumber ~a.\n"
+          (ly:get-context-property x 'currentBarNumber)))
+@end example
+
+
+
+@node Defining contexts
+@subsection Defining contexts
 
-@node Changing context definitions
-@subsection Changing context definitions
 @cindex context definition
 @cindex translator definition
 
-The most common way to define a context is by extending an existing
-context.  You can change an existing context from the paper block by
-first initializing a translator with an existing context identifier:
+The most common way to create a new context definition is by extending
+an existing one.  An existing context from the paper block is copied
+by referencing a context identifier:
 
 @example
 \paper @{
@@ -257,13 +254,12 @@ first initializing a translator with an existing context identifier:
 Every predefined context has a standard identifier. For example, the
 @code{Staff} context can be referred to as @code{\StaffContext}.
 
-@noindent
 The context can then be modified by setting or changing properties,
 e.g.
 @example
 \translator @{
   \StaffContext
-  Stem \set #'thickness = #1.2
+  Stem \set #'thickness = #2.0
   defaultBarType = #"||"
 @}
 @end example
@@ -278,11 +274,9 @@ It is not possible to collect multiple property assignments in a
 variable, and apply to one @code{\translator} definition by
 referencing that variable.
 
-@node Defining new contexts
-@subsection Defining new contexts
+@node Engravers and performers
+@subsection  Engravers and performers
 
-@cindex engraver
-@cindex plug-in
 
 Each context is composed of a number of building blocks, or plug-ins
 called engravers.  An engraver is a specialized C++ class that is
@@ -291,6 +285,11 @@ for one function: the @code{Slur_engraver} creates only @code{Slur}
 objects, and the @code{Skip_event_swallow_translator} only swallows
 (silently gobbles) @code{SkipEvent}s.
 
+
+
+@cindex engraver
+@cindex plug-in
+
 An existing context definition can be changed by adding or removing an
 engraver. The syntax for these operations is 
 @example
@@ -324,6 +323,10 @@ the central C is at its default position, the center line.
 A list of all engravers is in the internal documentation,
 see @internalsref{All engravers}.
 
+@node Defining new contexts
+@subsection Defining new contexts
+
+
 It is also possible to define new contexts from scratch.  To do this,
 you must define give the new context a name.  In the following
 example, a very simple Staff context is created: one that will put
@@ -388,25 +391,15 @@ do anything.
 @cindex evaluating Scheme
 @cindex LISP
 
-LilyPond internally uses GUILE, a Scheme-interpreter.
-
-
-Scheme is used to represent data throughout the whole program.
-
-In some places of the input file, Scheme expressions also form valid
-syntax: wherever it is allowed, GUILE can be accessed directly by
-entering a hash-sign (@code{#}).  The expression following the
-hash-sign is evaluated as Scheme. For example,  the boolean value @var{true} is
-@code{#t} in Scheme, so for LilyPond @var{true} looks like @code{##t},
-and can be used in property assignments:
-@example
-  \property Staff.autoBeaming = ##f
-@end example
+LilyPond internally uses GUILE, a Scheme-interpreter, to represent
+data throughout the whole program, and glue together different program
+modules. For advanced usage, it is sometimes necessary to access and
+program the Scheme interpreter.
 
-Scheme is a full-blown programming language, from the LISP family. and
-a full discussion is outside the scope of this document.  Interested
-readers are referred to the website @uref{http://www.schemers.org/}
-for more information on Scheme.
+Scheme is a full-blown programming language, from the LISP
+family. and a full discussion is outside the scope of this document.
+Interested readers are referred to the website
+@uref{http://www.schemers.org/} for more information on Scheme.
 
 The GUILE library for extension is documented at
 @uref{http://www.gnu.org/software/guile}.
@@ -416,11 +409,25 @@ When it is installed, the following link should take you to its manual
 @end ifinfo
 
 @menu
+* Inline Scheme::               
 * Input variables and Scheme::  
 * Scheme datatypes::            
 * Assignments::                 
 @end menu
 
+@node Inline Scheme
+@subsection Inline Scheme
+
+Scheme expressions can be entered in the input file by entering a
+hash-sign (@code{#}).  The expression following the hash-sign is
+evaluated as Scheme. For example, the boolean value @var{true} is
+@code{#t} in Scheme, so for LilyPond @var{true} looks like @code{##t},
+and can be used in property assignments:
+@example
+  \property Staff.autoBeaming = ##f
+@end example
+
+
 @node Input variables and Scheme
 @subsection Input variables and Scheme
 
@@ -436,7 +443,7 @@ example, a music expression is assigned to a variable with the name
 
 There is also a form of scoping: in the following example, the
 @code{\paper} block also contains a @code{traLaLa} variable, which is
-independent of the outer \traLaLa.
+independent of the outer @code{\traLaLa}.
 @example
   traLaLa = \notes @{ c'4 d'4 @}
   \paper @{ traLaLa = 1.0 @}
@@ -447,7 +454,7 @@ In effect, each input file is a scope, and all @code{\header},
 toplevel scope.
 
 Both variables and scoping are implemented in the GUILE module system.
-A anonymous Scheme module is attached to each scope. An assignment of
+An anonymous Scheme module is attached to each scope. An assignment of
 the form
 @example
  traLaLa = \notes @{ c'4 d'4 @} 
@@ -456,7 +463,7 @@ the form
 @noindent
 is internally converted to a Scheme definition
 @example
- (define traLaLa @var{Scheme value of @code{\notes ... }})
+ (define traLaLa @var{Scheme value of ``@code{\notes ... }''})
 @end example
 
 This means that input variables and Scheme variables may be freely
@@ -499,7 +506,7 @@ Scheme value.
 
 The following list are all lilypond specific types, that
 can exist during parsing:
-@itemize @bullet
+@table @code
 @item Duration
 @item Identifier
 @item Input
@@ -509,12 +516,12 @@ can exist during parsing:
 @item Pitch
 @item Score
 @item Translator_def
-@end itemize
+@end table
 
 
 During a run, transient objects are also created and destroyed.
 
-@itemize @bullet
+@table @code
 @item Grob: short for `Graphical object'.
 @item Scheme_hash_table 
 @item Music_iterator
@@ -530,7 +537,7 @@ including dimensions.
 not yet user-accessible.
 
 @item Font_metric: An object representing a font.
-@end itemize
+@end table
 
 Many functions are defined to manipulate these data structures. They
 are all listed and documented in the internals manual, see
@@ -541,29 +548,33 @@ are all listed and documented in the internals manual, see
 @subsection Assignments
 @cindex Assignments
 
-Identifiers allow objects to be assigned to names during the parse
-stage.  To assign an identifier, use @var{name}@code{=}@var{value}.
-To refer to an identifier, precede its name with a backslash:
+Variables allow objects to be assigned to names during the parse
+stage.  To assign a variable, use
+@example
+@var{name}@code{=}@var{value}
+@end example
+To refer to a variable, precede its name with a backslash:
 `@code{\}@var{name}'.  @var{value} is any valid Scheme value or any of
-the input-types listed above.  Identifier assignments can appear at top
+the input-types listed above.  Variable assignments can appear at top
 level in the LilyPond file, but also in @code{\paper} blocks.
 
-An identifier can be created with any string for its name, but you will
-only be able to refer to identifiers whose names begin with a letter,
-being entirely alphabetical.  It is impossible to refer to an identifier
-whose name is the same as the name of a keyword.
-
-The right hand side of an identifier assignment is parsed completely
-before the assignment is done, so it is allowed to redefine an
-identifier in terms of its old value, e.g.
+A variable can be created with any string for its name, but for
+accessing it in the LilyPond syntax, its name must consist of
+alphabetic characters only, and may not be a keyword of the syntax.
+There are no restrictions for naming and accessing variables in the
+Scheme interpreter,
 
+The right hand side of a variable assignment is parsed completely
+before the assignment is done, so variables may be  redefined in terms
+of its old value, e.g.
+@c
 @example
 foo = \foo * 2.0
 @end example
 
-When an identifier is referenced, the information it points to is
-copied.  For this reason, an identifier reference must always be the
-first item in a block.
+When a variable is referenced in LilyPond syntax, the information it
+points to is copied.  For this reason, an variable reference must
+always be the first item in a block.
 
 @example
 \paper @{
@@ -584,6 +595,12 @@ first item in a block.
 @node Music storage format
 @section Music storage format
 
+Music in LilyPond is entered as music expressions. This section
+discusses different types of music expressions, and explains
+information is stored internally. This internal storage is accessible
+through the Scheme interpreter, so music expressions may be
+manipulated using Scheme functions. 
+
 @menu
 * Music expressions::           
 * Internal music representation::  
@@ -594,12 +611,11 @@ first item in a block.
 @subsection Music expressions
 @cindex music expressions
 
-Music in LilyPond is entered as a music expression.  Notes, rests, lyric
-syllables are music expressions, and you can combine music expressions
-to form new ones, for example by enclosing a list of expressions in
-@code{\sequential @{ @}} or @code{< >}.  In the following example, a
-compound expression is formed out of the quarter note @code{c} and a
-quarter note @code{d}:
+Notes, rests, lyric syllables are music expressions.  Small music
+expressions may be combined to form larger ones, for example by
+enclosing a list of expressions in @code{\sequential @{ @}} or @code{<
+>}.  In the following example, a compound expression is formed out of
+the quarter note @code{c} and a quarter note @code{d}:
 
 @example 
 \sequential @{ c4 d4 @} 
@@ -671,9 +687,6 @@ Other compound music expressions include
 
 
 
-@node Manipulating music expressions
-@subsection Manipulating music expressions
-
 When a music expression is parsed, it is converted into a set of
 Scheme music objects. The defining property of a music object is that
 it takes up time. Time is a rational number that measures the length
@@ -696,14 +709,13 @@ expressions}.
   All classes of music are listed in the internals manual, under
   @internalsref{Music classes}. 
 @item
-Each music object is represented by a C++ object.  may be represented
-by different C++ classes.  For technical reasons, different music
-objects may be represented by different C++ object types. For example,
-a note is @code{Event} object, while @code{\grace} creates a
-@code{Grace_music} object.
-
- The distinctions between different C++ types will disappear in the
-future.
+Each music object is represented by a C++ object.  For technical
+reasons, different music objects may be represented by different C++
+object types. For example, a note is @code{Event} object, while
+@code{\grace} creates a @code{Grace_music} object.
+
+We expect that distinctions between different C++ types will disappear
+in the future.
 @end itemize
 
 The actual information of a music expression is stored in properties.
@@ -721,11 +733,14 @@ and @internalsref{GraceMusic} has its single argument in
 @code{element}. The body of a repeat is in @code{element} property of
 @internalsref{RepeatedMusic}, and the alternatives in @code{elements}.
 
-These properties and objects can be directly accessed and manipulated,
-through the @code{\apply} mechanism.  Scheme functions can read and
-write properties using the functions @code{ly:get-music-property} and
-@code{ly:set-music-property!}.
+@node Manipulating music expressions
+@subsection Manipulating music expressions
 
+Music objects and their properties can be accessed and manipulated
+directly, through the @code{\apply} mechanism.  Scheme functions can
+read and write properties using the functions
+@code{ly:get-music-property} and @code{ly:set-music-property!}.
+6
 The syntax for @code{\apply} 
 @example
 \apply #@var{func} @var{music}
@@ -836,7 +851,7 @@ be concatenated with the @code{+} operator.
 
 LilyPond's default output format is @TeX{}.  Using the option @option{-f}
 (or @option{--format}) other output formats can be selected also, but
-currently none of them reliably work.
+currently none of them work reliably.
 
 At the beginning of the output file, various global parameters are defined.
 It also contains a large @code{\special} call to define PostScript routines
index 9a53f1ff9c577a1b894a80e37edff7d09a783a03..9e11df8788ea1f7a74ee5428becd427f4a0a2c9e 100644 (file)
@@ -5,6 +5,7 @@
 @menu
 * Reporting bugs::              
 * Website::                     
+* Point and click::             
 * Invoking ly2dvi::             Titling LilyPond scores.
 @end menu
 
@@ -77,7 +78,7 @@ Add @var{directory} to the search path for input files.
 Set init file to @var{file} (default: @file{init.ly}).
 @item -m,--no-paper
 @cindex MIDI
-Disable @TeX{} output. If you have a @code{\midi} definition midi output
+Disable @TeX{} output. If you have a @code{\midi} definition MIDI output
 will be generated.
 @item -M,--dependencies
 Output rules to be included in Makefile.
@@ -229,13 +230,9 @@ website contains updates to the manual. You can find the website at
 @uref{http://www.lilypond.org/}.
 
 
-@c .  {Point and click}
-@menu
-* Point and click::             
-@end menu
 
 @node Point and click
-@subsection Point and click
+@section Point and click
 @cindex poind and click
 
 Point and click lets you find notes in the input by clicking on them in
@@ -255,6 +252,9 @@ To use it, you need the following software
 @item KDVI.  A dvi viewer for KDE.  You need KDVI from KDE 3.0 or
 newer.  Enable option @emph{Inverse search} in the menu @emph{Settings}.
 
+Apparently, KDVI does not process PostScript specials correctly. Beams
+and slurs will not be visible in KDVI.
+
 @cindex Xdvi
 @cindex KDVI
 @cindex KDE
@@ -552,11 +552,4 @@ positive integer, start with this value as the first page number.
      property in the score.
 @end table
 
-@subsection Environment variables
-
-@table @code
-
-
-@end table
-
 
index 34add649747b63b8e10eccada78de50ba1433f54..bf75bc50cf88718ed94ba541c2dcba113e58f981 100644 (file)
@@ -36,14 +36,13 @@ Short Introduction to LaTeX} provides a introction to using La@TeX{}.
 
 
 @menu
-* Integrating Texinfo and music::
-* Integrating La@TeX{} and music::
-* Integrating HTML and music::
-* Music fragment options::
-* Invoking lilypond-book::
+* Integrating Texinfo and music::  
+* Integrating La@TeX{} and music::  
+* Integrating HTML and music::  
+* Music fragment options::      
+* Invoking lilypond-book::      
 @end menu
 
-TODO: explain how to use lilypond fonts in text.
 
 
 @cindex texinfo
index 64e62d0d51d34f205dd8c512fedba37be61a4114..b555134120015f5651e865066f6cc22f03eca0fb 100644 (file)
@@ -11,7 +11,7 @@
 @chapter Notation manual
 
 @html
-<!--- @@WEB-TITLE@@=Reference Manual --->
+<!--- @@WEB-TITLE@@=Notation manual --->
 @end html
 
 
@@ -183,9 +183,17 @@ ways. For more information, refer to @ref{Accidentals}.
 @subsection Chords
 
 A chord is formed by a enclosing a set of pitches in @code{<<} and
-@code{>>}.
+@code{>>}. A chord may be followed by  a duration, and a set of
+articulations, just like simple notes.
+
+Additionally, fingerings and articulations may be attached to
+individual pitches of the chord:
+
+@lilypond[singleline,verbatim,relative 1]
+  <<f-1 a-^ c-5>>
+@end lilypond
+
 
-TODO: accidental overides?
 
 @node  Rests
 @subsection Rests
@@ -385,52 +393,6 @@ optimal results.
 
 
 
-@node Automatic note splitting 
-@subsection Automatic note splitting
-@c FIXME: This subsection does not belong in @ref{Note entry}.
-
-Long notes can be converted automatically to tied notes.  This is done
-by replacing the @internalsref{Note_heads_engraver} by the
-@internalsref{Completion_heads_engraver}.
-
-@example
-  \paper @{ \translator @{
-      \ThreadContext
-      \remove "Note_heads_engraver"
-      \consists "Completion_heads_engraver"
-  @} @}
-@end example
-
-For example,
-@example
-  \time 2/4
-  c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2 
-@end example
-
-@lilypond[noindent]
-\score{
-  \notes\relative c'{
-  \time 2/4
-  c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2 
-  }
-  \paper { \translator {
-      \ThreadContext
-      \remove "Note_heads_engraver"
-      \consists "Completion_heads_engraver"
-  } }
-  }
-@end lilypond
-
-This engraver splits all running notes at the bar line, and inserts
-ties.  One of its uses is to debug complex scores: if the measures are
-not entirely filled, then the ties exactly show how much each measure
-is off.
-
-@refbugs
-
-Not all durations (especially those containing tuplets) can be
-represented exactly; the engraver will not insert tuplets. 
-
 @node Tuplets
 @subsection Tuplets
 
@@ -520,17 +482,30 @@ produce the correct result.
 @node Easier music entry
 @section Easier music entry
 @cindex Music entry
+
+When entering music it is easy to introduce errors. This section deals
+with tricks and features of the input language that help when entering
+music, and find and correct mistakes.
+
+Some features of the input language ease entering music, for example
+the use of variables (for splitting up large pieces of music), and
+unfolded repeats for writing repetitive parts. They are described in
+other sections (see @ref{Repeats} and @ref{Assignments}), since they
+are not especially aimed at easing entry
+
+It is also possible to use external programs, for example GUI
+interfaces, or MIDI transcription programs, to enter or edit
+music. Refer to the website for more information. Finally, there are
+tools make debugging easier, by linking the input file and the output
+shown on screen. See @ref{Point and click} for more information.
+
+
 @menu
 * Relative octaves::            
 * Bar check::                   
 * Skipping corrected music::    
 @end menu
 
-When entering music it is easy to introduce errors. This section deals
-with tricks and features that help entering music, and find and
-correct mistakes.  It is also possible to use external programs, for
-example GUI interfaces, or MIDI transcription programs, to enter or
-edit music. Refer to the website for more information.
 
 
 
@@ -646,6 +621,51 @@ been checked for errors.
 c d b bes a g c2 } 
 @end lilypond
 
+@node Automatic note splitting 
+@subsection Automatic note splitting
+
+Long notes can be converted automatically to tied notes.  This is done
+by replacing the @internalsref{Note_heads_engraver} by the
+@internalsref{Completion_heads_engraver}.
+
+@example
+  \paper @{ \translator @{
+      \ThreadContext
+      \remove "Note_heads_engraver"
+      \consists "Completion_heads_engraver"
+  @} @}
+@end example
+
+For example,
+@example
+  \time 2/4
+  c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2 
+@end example
+
+@lilypond[noindent]
+\score{
+  \notes\relative c'{
+  \time 2/4
+  c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2 
+  }
+  \paper { \translator {
+      \ThreadContext
+      \remove "Note_heads_engraver"
+      \consists "Completion_heads_engraver"
+  } }
+  }
+@end lilypond
+
+This engraver splits all running notes at the bar line, and inserts
+ties.  One of its uses is to debug complex scores: if the measures are
+not entirely filled, then the ties exactly show how much each measure
+is off.
+
+@refbugs
+
+Not all durations (especially those containing tuplets) can be
+represented exactly; the engraver will not insert tuplets. 
+
 
 
 
@@ -4624,7 +4644,9 @@ volume of the Antiphonale Romanum (@emph{Liber Hymnarius}), published
 
 @c TODO: \paper block is identical in all of the below examples.
 @c Therefore, it should somehow be included rather than duplicated all
-@c the time.
+@c the time. --jr
+
+@c why not make identifiers in ly/engraver-init.ly? --hwn
 
 @item
 @code{1. Punctum}
index 6989d9d7e37b0e6a4a968835fad4da48a1e806b7..86f4567c29fb77e48a312718bc564ae14b081158 100644 (file)
@@ -21,8 +21,9 @@
 * A lead sheet::                
 * Listening to output::         
 * More movements ::             Joining separate pieces of music
+* Single staff polyphony  ::    
+* Piano music::                 
 * Organising larger pieces::    
-* A piano excerpt::             Piano music
 * Fine tuning a piece::         
 * An orchestral score::         Conductor's score and individual parts
 * Integrating text and music::  Integrating text and music
@@ -908,18 +909,28 @@ before the chords thus entered:
 A complete list of modifiers, and other options for layout are in the
 reference manual section @ref{Chords}.
 
-TODO: template example with chord names, lyrics and staff.
+@cindex lead sheet 
+When put together,  chord names, lyrics and a melody form
+a lead sheet, for example:
+@lilypond[singleline,verbatim]
+\score  {
+  < 
+   \context ChordNames \chords { r8 c2:sus4 f } 
+   \addlyrics
+    \notes \relative c' {
+     \partial 8
+     c8
+     \times 2/3 { f g g } \times 2/3 { g4-( a2-) } }
+   \context Lyrics  \lyrics { I want to break free __ }
+  >
+ \paper{ }
+}
+@end lilypond
 
 
 @node Listening to output
 @section Listening to output
-@example 
 
-        \midi  @{ \tempo 4=72@}
-@end example 
 MIDI (Musical Instrument Digital Interface) is a standard for
 connecting and recording digital instruments.  A MIDI file is like a
 tape recording of a MIDI instrument. The @code{\midi} block makes the
@@ -928,12 +939,18 @@ It is great for checking the music: octaves that are off, or
 accidentals that were mistyped, stand out very much when listening to
 the musical transcription.
 
-@code{\midi} is similar to @code{\paper @{ @}}, since it also
-specifies an output method.  You can specify the tempo using the
-@code{\tempo} command, in this case the tempo of quarter notes is set
-to 72 beats per minute.
-
+@code{\midi} can be used in similarly to @code{\paper @{ @}}, for
+example
+@example 
+\score @{
+    @var{..music..}
+    \midi  @{ \tempo 4=72@}
+    \paper  @{ @}
+@}
+@end example 
 
+Here, the tempo is specified using the @code{\tempo} command.  In this
+case the tempo of quarter notes is set to 72 beats per minute.
 
 
 @node More movements 
@@ -1046,69 +1063,54 @@ For example, the Opus number is put at the right, and the "piece" string
 will be at the left.
 
 
+@node Single staff polyphony  
+@section Single staff polyphony
 
-@node Organising larger pieces
-@section Organising larger pieces
+When different melodic lines are combined on a single staff, these are
+printed as polyphonic voices: each voice has its own stems, slurs
+and beams, and the top voice has the stems up, while the bottom voice
+has stems down.
 
-TODO: discuss identifiers, p&c, .
+Entering such parts is done by entering each voice as a sequence (with
+@code{@{ .. @}}), and combing those simultaneously, separating the
+voices with @code{\\}:
 
-@separate
-@example 
-\version "1.5.72"
-@end example 
-Lilypond and its language are still under development, and
-occasionally details of the syntax are changed.  The @code{version}
-fragment indicates which LilyPond version the input file was written
-for.  When you compile this file, the version number will be checked
-and you will get a warning when the file is too old.  This version
-number is also used by the @code{convert-ly} program (See
-@ref{Invoking convert-ly}), which can used to update the file to the
-latest lily version.
+@lilypond[verbatim,relative]
+  < { a4 g2 f4-~ f4 } \\
+    { r4 g4 f2 f4 } >
+@end lilypond
+More features of polyphonic typesetting are in the notation manual,
+@ref{Polyphony}.
 
+@node Piano staffs
+@section Piano staffs
 
-@node A piano excerpt
-@section A piano excerpt
+@cindex staff switch, manual
+@cindex cross staff voice, manual
+@cindex @code{\translator}
 
-Our eighth subject is a piece of piano music.  The fragment in the
-input file is a piano reduction of the G major Sinfonia by Giovanni
-Battista Sammartini, composed around 1740.  It's in the source
-package under the name @inputfileref{input/tutorial,sammartini.ly}.
 
-@lilypondfile[smallverbatim]{sammartini.ly}
 
-As you can see, this example features multiple voices on one staff.  To
-make room for those voices, their notes should be stemmed in opposite
-directions.
 
+@node Organising larger pieces
+@section Organising larger pieces
 
+TODO: discuss identifiers, p&c, .
 
 @separate
 @example 
-viola = \notes \relative c'  \context Voice = viola @{ 
+\version "1.5.72"
 @end example 
-In this example you see multiple parts on a staff.  Each part is
-associated with one notation context.  This notation context handles
-stems and dynamics (among other things).  The type name of this
-context is @code{Voice}.  For each part we have to make sure that
-there is precisely one @code{Voice} context, so we give it a unique
-name (`@code{viola}').
-
-@separate
-
-@cindex arpeggio
-
-
-
-
+Lilypond and its language are still under development, and
+occasionally details of the syntax are changed.  The @code{version}
+fragment indicates which LilyPond version the input file was written
+for.  When you compile this file, the version number will be
+checked. When the file is too old, a warning is issued.  The version
+number is also used by the @code{convert-ly} program (See
+@ref{Invoking convert-ly}), which updates the file to the latest
+version automatically.
 
-@separate
-@example 
-        g'8. b,16 
-@end example 
-Relative octaves work a little differently with chords.  The starting
-point for the note following a chord is the first note of the chord.  So
-the @code{g} gets an octave up quote: it is a fifth above the starting
-note of the previous chord (the central C).
 
 @separate
 @example 
@@ -1117,23 +1119,7 @@ s1 s2. r4
 @code{s} is a spacer rest.  It does not print anything, but it does have
 the duration of a rest. It is useful for filling up voices that
 temporarily do not play. In this case, the viola does not come until one
-and a half measure later.
-
-@separate
-@example 
-oboes = \notes \relative c'' \context Voice = oboe @{ 
-@end example 
-Now comes a part for two oboes.  They play homophonically, so we
-print the notes as one voice that makes chords. Again, we insure that
-these notes are indeed processed by precisely one context with
-@code{\context}.
-@separate
-@example 
-  s4  g8. b,16 c8 r <<e' g>>8. <<f a>>16
-@end example
-
-The oboes should have stems up to keep them from interfering with
-the staff-jumping bass figure.  To do that, we use @code{\voiceOne}.
+and a half measure later. 
 
 @separate
 @example 
@@ -1160,44 +1146,6 @@ ending on the following chord.
 The piece of music to be `tripletted' is sequential music containing
 three chords.
 
-@separate
-@example 
-< 
-@end example 
-At this point, the homophonic music splits into two rhythmically
-different parts.  We cannot use a sequence of chords to enter this, so
-we make a "chord of sequences" to do it.  We start with the upper
-voice, which continues with upward stems:
-@separate
-@example 
- @{ \times 2/3 @{ a8 g c @} c2 @} 
-@end example
-
-@separate
-@example
-\\
-@end example
-Entering multiple voices is demonstrated here. Separate the
-components of the voice (single notes or entire sequences) with
-@code{\\} in a simultaneous music expression. The @code{\\} separators
-split first voice, second voice, third voice, and so on.
-
-As far as relative mode is concerned, the previous note is the
-@code{c'''2} of the upper voice, so we have to go an octave down for
-the @code{f}.
-@separate
-@example 
-
-  f,8 e e2
-@} > 
-@end example 
-This ends the two-part section.
-@separate
-@example 
-\grace <<c, e>>8-( <<b d>>8.-\trill <<c e>>16 |  
-@end example
-@cindex trill
-@cindex stemBoth
 
 The bass has a little hoom-pah melody to demonstrate parts switching
 between staves.  Since it is repetitive, we use repeats:
@@ -1210,72 +1158,6 @@ The unfolded repeat prints the notes in its argument as if they were
 written out in full eight times.
 @separate
 
-@cindex staff switch, manual
-@cindex cross staff voice, manual
-@cindex @code{\translator}
-
-@example
-\translator Staff = down
-\stemUp
-c8
-\translator Staff = up
-\stemDown
-c'8 @}
-@end example
-Voices can switch between staves.  Here you see two staff switching
-commands.  The first one moves to the lower staff, the second one to
-the lower one.  If you set the stem directions explicitly
-(using the identifiers @code{\stemUp} and @code{\stemDown}, the notes
-can be beamed together (despite jumping between staffs).
-
-@separate
-@example 
-bassvoices = \notes \relative c' @{
-c4 g8. b,16
-\autochange Staff \hoomPah \context Voice
-@end example
-
-@separate
-@example
-        \translator Staff = down
-@end example
-@cindex staff switch
-@cindex cross staff voice
-We want the remaining part of this melody on the lower staff, so we do a
-manual staff switch here.
-
-
-
-
-@separate
-@example 
-\context PianoStaff 
-@end example 
- A special context is needed to get cross staff beaming right.  This
-context is called @code{PianoStaff}.
-@separate
-@example 
-\context Staff = bottom < \time 2/2 \clef bass 
-@end example 
-The bottom staff must have a different clef.
-@separate
-@example 
-indent = 0.0 
-@end example 
-To make some more room on the line, the first (in this case the only)
-line is not indented.  The line still looks very cramped, but that is due
-to the page layout of this document.
-
-
-@ignore
-[TODO:
-
-* font-size
-
-* Simple part combining in a Hymn
-@end ignore
-
-
 @node Fine tuning a piece
 @section  Fine tuning a piece
 
@@ -2157,4 +2039,3 @@ to put the example in a separate file:
 
 The @code{printfilename} option adds the file name to the output.
 
-[TODO: include excercises? ]
diff --git a/input/regression/beam-break.ly b/input/regression/beam-break.ly
new file mode 100644 (file)
index 0000000..8543c7e
--- /dev/null
@@ -0,0 +1,10 @@
+\header {
+    texidoc = "Beams can be printed across line breaks if forced.
+"
+
+}
+\version "1.7.19"
+
+\score { \notes \relative c''  {
+    \property Score.forbidBeamBreak = ##f
+    c2. c8-[ c8 \break c8 c8-]   } }
index feb5ec75758f906c1cc689e5f97aea65b8b6527c..efa4eb40e2cb2e7700e296cf925c70cfb775f9ea 100644 (file)
@@ -164,10 +164,11 @@ Beam_engraver::process_music ()
       beam_ = 0;
     }
 
-  if (beam_)
+  if (beam_ && to_boolean (get_property ("forbidBeamBreak")))
     {
       top_engraver ()->forbid_breaks ();
     }
+
   if (evs_drul_[START])
     {
       if (beam_)
@@ -374,6 +375,6 @@ ENTER_DESCRIPTION(Grace_beam_engraver,
 /* creats*/       "Beam",
 /* accepts */     "beam-event abort-event new-beam-event",
 /* acks  */      "stem-interface rest-interface",
-/* reads */       "beamMelismaBusy beatLength subdivideBeams",
+/* reads */       "beamMelismaBusy beatLength forbidBeamBreak subdivideBeams",
 /* write */       "");
 
index fc93ed4bc20f40fa330a9304bad41d5fe1f75f1d..34601e1b99613e29ea81c1db57a8219ff4f81fa6 100644 (file)
@@ -340,116 +340,120 @@ Beam::brew_molecule (SCM grob)
   Molecule the_beam;
   Real lt = me->get_paper ()->get_var ("linethickness");
   
-  for (int i = 0; i< stems.size(); i++)
+  for (int i = 0; i<= stems.size(); i++)
     {
-      Grob * st =stems[i];
+      Grob * st = (i < stems.size()) ? stems[i] : 0;
       
-      SCM this_beaming = st->get_grob_property ("beaming");
-      Real xposn = st->relative_coordinate (xcommon, X_AXIS);
-      Real stem_width = gh_scm2double (st->get_grob_property ("thickness")) *lt;
+      SCM this_beaming = st ? st->get_grob_property ("beaming") : SCM_EOL;
+      Real xposn = st ? st->relative_coordinate (xcommon, X_AXIS) : 0.0;
+      Real stem_width = st ? gh_scm2double (st->get_grob_property ("thickness")) *lt : 0 ;
 
       /*
        We do the space left of ST, with lfliebertjes pointing to the
        right from the left stem, and rfliebertjes pointing left from
        right stem.
        */
-      if (i > 0)
-       {
-         SCM left = gh_cdr (last_beaming);
-         SCM right = gh_car (this_beaming);
+      SCM left = (i>0) ? gh_cdr (last_beaming) : SCM_EOL;
+      SCM right = st ? gh_car (this_beaming) : SCM_EOL;
 
-         Array<int> fullbeams;
-         Array<int> lfliebertjes;
-         Array<int> rfliebertjes;        
+      Array<int> fullbeams;
+      Array<int> lfliebertjes;
+      Array<int> rfliebertjes;   
 
-         for (SCM s = left;
-              gh_pair_p (s); s =gh_cdr (s))
+      for (SCM s = left;
+          gh_pair_p (s); s =gh_cdr (s))
+       {
+         int b = gh_scm2int (gh_car (s));
+         if (scm_memq (gh_car(s), right) != SCM_BOOL_F)
            {
-             int b = gh_scm2int (gh_car (s));
-             if (scm_memq (gh_car(s), right) != SCM_BOOL_F)
-               {
-                 fullbeams.push (b);
-               }
-             else
-               {
-                 lfliebertjes.push (b); 
-               }
+             fullbeams.push (b);
            }
-         for (SCM s = right;
-              gh_pair_p (s); s =gh_cdr (s))
+         else
            {
-             int b = gh_scm2int (gh_car (s));
-             if (scm_memq (gh_car(s), left) == SCM_BOOL_F)
-               {
-                 rfliebertjes.push (b);
-               }
+             lfliebertjes.push (b); 
            }
-
-         
-         Real w = xposn - last_xposn;
-         Real stem_offset = 0.0;
-         Real width_corr = 0.0;
-         if (i == 1)
+       }
+      for (SCM s = right;
+          gh_pair_p (s); s =gh_cdr (s))
+       {
+         int b = gh_scm2int (gh_car (s));
+         if (scm_memq (gh_car(s), left) == SCM_BOOL_F)
            {
-             stem_offset -= last_width/2;
-             width_corr += last_width/2;
+             rfliebertjes.push (b);
            }
+       }
+
+      /*
+       how much to stick out for beams across linebreaks
+       */
+      Real break_overshoot = 3.0;
+      Real w = (i>0 && st)? xposn - last_xposn : break_overshoot;
+      Real stem_offset = 0.0;
+      Real width_corr = 0.0;
+      if (i == 1)
+       {
+         stem_offset -= last_width/2;
+         width_corr += last_width/2;
+       }
          
-         if (i == stems.size() -1)
-           {
-             width_corr += stem_width/2;
-           }
+      if (i == stems.size() -1)
+       {
+         width_corr += stem_width/2;
+       }
 
-         if (gh_number_p (gap))
-           {
-             Real g = gh_scm2double (gap);
-             stem_offset += g;
-             width_corr -= 2*g; 
-           }
+      if (gh_number_p (gap))
+       {
+         Real g = gh_scm2double (gap);
+         stem_offset += g;
+         width_corr -= 2*g; 
+       }
          
-         Molecule whole = Lookup::beam (dydx, w + width_corr, thick);
-         for (int j = fullbeams.size(); j--;)
-           {
-             Molecule b (whole);
-             b.translate_axis (last_xposn -  x0 + stem_offset, X_AXIS);
-             b.translate_axis (dydx * (last_xposn - x0) + bdy * fullbeams[j], Y_AXIS);
-             the_beam.add_molecule (b);              
-           }
+      Molecule whole = Lookup::beam (dydx, w + width_corr, thick);
+      for (int j = fullbeams.size(); j--;)
+       {
+         Molecule b (whole);
+         b.translate_axis (last_xposn -  x0 + stem_offset, X_AXIS);
+         b.translate_axis (dydx * (last_xposn - x0) + bdy * fullbeams[j], Y_AXIS);
+         the_beam.add_molecule (b);          
+       }
 
-         if (lfliebertjes.size() || rfliebertjes.size())
-           {
-             Real nw_f;
+      if (lfliebertjes.size() || rfliebertjes.size())
+       {
+         Real nw_f;
 
+         if (st)
+           {
              int t = Stem::duration_log (st); 
 
              SCM proc = me->get_grob_property ("flag-width-function");
              SCM result = gh_call1 (proc, scm_int2num (t));
              nw_f = gh_scm2double (result);
-               
-             
-             /* Half beam should be one note-width,
-                but let's make sure two half-beams never touch */
+           }
+         else
+           nw_f = break_overshoot;
              
-             Real w = xposn - last_xposn;
-             w = w/2 <? nw_f;
+         /* Half beam should be one note-width,
+            but let's make sure two half-beams never touch */
+         Real w = (i>0 && st) ? (xposn - last_xposn) : break_overshoot;
+         w = w/2 <? nw_f;
 
-             Molecule half = Lookup::beam (dydx, w, thick);
-             for (int j = lfliebertjes.size(); j--;)
-               {
-                 Molecule b (half);
-                 b.translate_axis (last_xposn -  x0, X_AXIS);
-                 b.translate_axis (dydx * (last_xposn-x0) + bdy * lfliebertjes[j], Y_AXIS);
-                 the_beam.add_molecule (b);          
-               }
-             for (int j = rfliebertjes.size(); j--;)
-               {
-                 Molecule b (half);
-                 b.translate_axis (xposn -  x0 - w , X_AXIS);
-                 b.translate_axis (dydx * (xposn-x0 -w) + bdy * rfliebertjes[j], Y_AXIS);
-                 the_beam.add_molecule (b);          
-               }
+         Molecule half = Lookup::beam (dydx, w, thick);
+         for (int j = lfliebertjes.size(); j--;)
+           {
+             Molecule b (half);
+             b.translate_axis (last_xposn -  x0, X_AXIS);
+             b.translate_axis (dydx * (last_xposn-x0) + bdy * lfliebertjes[j], Y_AXIS);
+             the_beam.add_molecule (b);              
+           }
+         for (int j = rfliebertjes.size(); j--;)
+           {
+             Molecule b (half);
+             b.translate_axis (xposn -  x0 - w , X_AXIS);
+             b.translate_axis (dydx * (xposn-x0 -w) + bdy * rfliebertjes[j], Y_AXIS);
+             the_beam.add_molecule (b);              
            }
-       }
+       }
+
 
       last_xposn = xposn;
       last_width = stem_width;
index 8836930bb4908ac7813095a6203bdc8b1f7e309e..8ebe88b0ebf3f8256eca9bb43b55e513066719e4 100644 (file)
@@ -51,7 +51,6 @@ Key_performer::create_audio_elements ()
       SCM pitchlist = key_req_->get_mus_property ("pitch-alist");
       SCM proc = scm_primitive_eval (ly_symbol2scm ("accidentals-in-key")); 
       SCM acc = gh_call1 (proc, pitchlist);
-      proc = scm_primitive_eval (ly_symbol2scm ("major-key"));
  
       Pitch my_do (0, 
                   gh_scm2int (ly_caar (pitchlist)),
@@ -65,9 +64,13 @@ Key_performer::create_audio_elements ()
       to_c = my_do.transposed (Pitch(0,0,- my_do.get_alteration ()));
 
       SCM c_pitchlist = transpose_key_alist (pitchlist, to_c.smobbed_copy());
-      SCM major = gh_call1 (proc, c_pitchlist);
 
-      audio_ = new Audio_key (gh_scm2int (acc), major == SCM_BOOL_T); 
+      /*
+       MIDI keys are too limited for lilypond scales.
+
+       TODO: should probably detect minor key, though.
+      */
+      audio_ = new Audio_key (gh_scm2int (acc), true); 
       Audio_element_info info (audio_, key_req_);
       announce_element (info);
       key_req_ = 0;
index ea46865599f8c5c9c0e053ab99500b3e6ff609ef..31427ecdead1d3703649df9428b19c99bae1ef8e 100644 (file)
@@ -9,8 +9,10 @@
 
 #include <map>                 // UGH.
 #include <assert.h>
+
 #include "warn.hh"
 #include "music-constructor.hh"
+
 typedef Music* (*Music_ctor) ();
 
 static std::map<String,Music_ctor> *ctors_map_;
index e1c34b0ab75a6237ba7802bfc708de17b96f1165..6172fbaa1edea8c170174547cf39446d1fe04dcf 100644 (file)
@@ -463,6 +463,7 @@ ScoreContext = \translator {
        tupletNumberFormatFunction = #denominator-tuplet-formatter
        
        subdivideBeams = ##f
+       forbidBeamBreak = ##t
        extraNatural = ##t
        autoAccidentals = #'(Staff (same-octave . 0))
        autoCautionaries = #'()  
index f76d179acde1b7faec6a027c870502cac7a3681a..122de94ff49bf1a5fabfa69f67db29ca96959546 100644 (file)
@@ -251,6 +251,9 @@ another non-natural.
                                 "Used to set the relative size of all grobs
 in a context. This is done using the @code{Font_size_engraver}.")
 
+(translator-property-description 'forbidBeamBreak boolean?
+                                "If false, allow line breaks during beams.")
+
 (translator-property-description 'forceClef boolean? "Show clef symbol, even if it hasn't changed. Only active for the first clef after the property is set, not for the full staff.")
 (translator-property-description 'graceAccidentalSpace number? "amount space to alot for an accidental")
 (translator-property-description 'graceAlignPosition ly:dir? "put the grace note before or after the main note?")
index cebc38a27800ba773e6b575b3cd58e22e466e098..f96a6c9bab7b4b334517768a62937e8f3748cd66 100644 (file)
@@ -280,16 +280,3 @@ returns the program of the instrument
 (define-public (accidentals-in-key pitch-list)
   "Count number of sharps minus number of flats"
   (apply + (map cdr pitch-list)))
-
-(define-public (major-key pitch-list)
-  "Characterise the key as major if the alteration of the 
-third scale note is the same as that of the main note.
-Note: MIDI cannot handle other tonalities than major/minor.
-"
-  ;; This charactersition is only true for a scale that starts at `c'.
-  (if (not (equal? (car pitch-list) '(0 . 0)))
-      (begin
-       (ly:warn "Attempt to determine tonality of transposed scale")
-       #t)
-      (eq? (cdr (list-ref pitch-list 4)) (cdr (list-ref pitch-list 6))))
-  )