]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.1.52.gp2
authorGlen Prideaux <glenprideaux@iname.com>
Mon, 5 Jul 1999 13:05:33 +0000 (15:05 +0200)
committerGlen Prideaux <glenprideaux@iname.com>
Mon, 5 Jul 1999 13:05:33 +0000 (15:05 +0200)
pl 52.gp2
- hyphens between syllables of lyrics:
---
Generated by (address unknown) using package-diff 0.62,
From = lilypond-1.1.52.gp1, To = lilypond-1.1.52.gp2

usage

    cd lilypond-source-dir; patch -E -p1 < lilypond-1.1.52.gp2.diff

Patches do not contain automatically generated files
or (urg) empty directories,
i.e., you should rerun autoconf, configure --state
1.1.52.gp1
1.1.52.gp2
++state

19 files changed:
Documentation/tex/refman.yo
Documentation/tex/refman.yo.orig [new file with mode: 0644]
NEWS
VERSION
input/test/hyphen.ly [new file with mode: 0644]
lily/hyphen-engraver.cc [new file with mode: 0644]
lily/hyphen-spanner.cc [new file with mode: 0644]
lily/include/hyphen-engraver.hh [new file with mode: 0644]
lily/include/hyphen-spanner.hh [new file with mode: 0644]
lily/include/lily-proto.hh
lily/include/ly-symbols.hh
lily/include/ly-symbols.hh.orig [new file with mode: 0644]
lily/include/musical-request.hh
lily/include/musical-request.hh.orig [new file with mode: 0644]
lily/lexer.ll
lily/parser.yy
lily/parser.yy.orig [new file with mode: 0644]
ly/engraver.ly
ly/params.ly

index 719770e081448cfa8f8d70c9453ddc3f1f24d1e9..b8aefcb0e87a30d9fb32bf7f31bb0e47c3e6ac61 100644 (file)
@@ -883,6 +883,21 @@ mudela(verbatim)(\score{
      foo1 __  bar2. __ _4 baz1 __ }
 > })
      
+If you want to have hyphens centred between syllables (rather than attached
+to the end of the first syllable) you can use the special code(--) lyric as
+separate word between syllables. This will result in a hyphen whose length
+varies depending on the space between syllables, and centred between the
+syllables. For example: 
+mudela(verbatim)(\score{
+  <  \notes \transpose c'' {c d e c | c d e c | e f g'2 | 
+                              e'4 f g'2 \bar "|."; }
+     \context Lyrics \lyrics { 
+              DOEXPAND(Fr\)`e4 -- re Ja -- que DOEXPAND(Fr\)`e -- re Ja -- que
+              Dor -- mez vous?2 Dor4 -- mez vous?2  }
+  >
+})
+
 
 
 sect(Time)  
diff --git a/Documentation/tex/refman.yo.orig b/Documentation/tex/refman.yo.orig
new file mode 100644 (file)
index 0000000..719770e
--- /dev/null
@@ -0,0 +1,2213 @@
+mailto(gnu-music-discuss@gnu.org)
+COMMENT(-*-text-*-)
+
+redef(var)(1)(whenlatex(latexcommand({\normalfont\scshape )ARG1+latexcommand(}))\
+    whenhtml(sc(ARG1)))
+
+
+redef(code)(1)(tt(ARG1))
+
+
+COMMENT(
+
+  BUGS:
+
+    Causes segfault:
+
+    \score{
+      \notes{  \context Voice {
+         \repeat fold 2 { a b c d } {}
+     }
+     }
+    }
+    
+
+   restStyle=mensural doesn't seem to work (lots of characters not found
+     for rests.fly)
+
+TODO:
+   thread
+   paper size?
+   paper variables
+   the explanation of how lyrics mode parses words seems ridiculous.  
+      Is there a simple way to explain this, or is the behavior
+      too complicated for a reasonable explanation?
+   accordion symbols
+   interstaff beams (beam-interstaff.ly)
+   interstaff slurs (see preludes-1.ly)
+)
+
+
+COMMENT( 
+This document contains Mudela fragments.  You need at least
+Yodl-1.30.18 to convert this to tex or html.
+)
+
+htmlbodyopt(bgcolor)(white)
+htmlcommand(<font color=black>)
+
+latexlayoutcmds(
+\setlength{\topmargin}{-0.25in}
+\setlength{\textheight}{9in}
+\setlength{\textwidth}{5.875in} 
+\setlength{\oddsidemargin}{0.25in}   
+\setlength{\evensidemargin}{0.25in}
+\input mudela-book
+)
+
+whentexinfo(notableofcontents())
+
+article(Mudela 1.0.21 / LilyPond 1.1.49 Reference Manual)
+      (Adrian Mariano, Han-Wen Nienhuys and Jan Nieuwenhuizen)
+      (nop()PIPETHROUGH(date "+%B %d, %Y")()()nop())
+
+COMMENT(
+
+* The [ ] look weird
+
+* paragraphs have too much space.
+
+)
+
+
+latexcommand(\def\interexample{})
+latexcommand(\def\preexample{\par})
+latexcommand(\def\postexample{\par\medskip})
+latexcommand(\def\file#1{{code(#1)}})
+COMMENT(
+latexcommand(\def\texttt#1{\tt #1})
+latexcommand(\def\textbf#1{\bf #1})
+)
+
+COMMENT(urg, texinfo include breaks)
+whenhtml(
+includefile(html-disclaimer.yo-urg)
+)
+
+bf(This document is not up to date).  All rendered examples of course
+are current, but the rest probably isn't.  Adjusting the tutorial was
+considered more important than writing the reference manual.  We
+apologize for the inconvenience.  For a complete and up-to-date
+definition, see file(lily/parser.yy), file(lily/lexer.ll), and the
+init files.
+
+This document describes the the GNU LilyPond input format, which is an
+effective language for defining music.  We call this language (rather
+arrogantly) The Musical Definition Language or Mudela, for
+short.footnote(If anybody comes up with a better name, we'd gladly
+  take this. Gourlay already uses Musical Description Language,
+  G-Sharp Score Definition Language.  ISO standard 10743 defines a
+  Standard Music Description Language.  We're not being original here.)
+
+The first aim of Mudela is to define a piece of music, being complete
+from both from a musical typesetting, as from a musical performing
+point of view.
+
+The Musical Definition Language (Mudela), has a logical structure,
+making use of identifiers, that allows for flexible input, and
+definition reuse. See the documentation file file(MANIFESTO), included
+with the LilyPond sources for reasons and design considerations.
+
+
+sect(Running LilyPond)
+
+When invoked with a filename that has no extension, LilyPond will try adding
+a file(.fly) extension first, and a file(.ly) extension second.  
+If the filename ends with 
+file(.fly),  LilyPond processes  the file as music using
+file(init.fly).  In this case, LilyPond does something
+like:
+verb(\score {
+  \notes\relative c {
+    \input "yourfile.fly"
+  }
+  \paper{}
+  \midi{}
+})
+If you invoke LilyPond with a file file(foo.)var(ext) that doesn't
+have the file(.ly) extension then LilyPond will look for a file called
+file(init.)var(ext) and process this file.  The file
+file(init.)var(ext) must contain the code(\maininput) keyword or LilyPond
+will not read the user specified file.
+
+When LilyPond processes file(filename.ly) it will produce file(filename.tex) as
+output.  If file(filename.ly) contains a second code(\paper) keyword, then
+LilyPond will produce file(filename-1.tex) as well.  Subsequent code(\paper)
+keywords will produces sequentially numbered file names.  Several files can be
+specified; they will each be processed independently.
+
+sect(Syntax)
+
+subsect(Basic Mudela)
+
+A Mudela file consists of keywords with arguments and identifier
+assignments separated by spaces, tabs or newlines.  Semicolons are
+used by some keywords and are inconsistantly required in other
+circumstances.  A one line comment is introduced by a code(%)
+character.  Block comments are started by code(%{) and ended by
+code(%}).  They cannot be nested.
+
+Mudela supports several types:
+
+description(
+
+dit(integer) 
+Formed from an optional minus sign followed by digits.  Arithmetic
+operations cannot be done with integers, and integers cannot be mixed
+with reals.
+
+dit(real) 
+Formed from an optional minus sign and a sequence of digits followed
+by a emph(required) decimal point and an optional exponent such as
+code(-1.2e3).  Reals can be built up using the usual operations:
+code(+), code(-), code(*), and code(/), with parentheses for grouping.
+
+dit(string) 
+Begins and ends with the code(") character.  To include a code(")
+character in a string write code(\").  Various other backslash
+sequences have special interpretations as in the C language.  A string
+that contains no spaces can be written without the quotes.  See
+Section ref(modes) for details on unquoted strings; their
+interpretation varies depending on the situation.  On the right side
+of identifier assignments and within the code(\header) keyword,
+strings can be concatenated using the code(+) character.
+
+dit(dimension) Consists of a real followed by one of the dimension
+keywords: code(\mm), code(\pt), code(\in), or code(\cm).  Dimensions
+are converted immediately to a real which gives the dimension in
+points, so they can be mixed with reals, but the result is no longer
+of type dimension.  The keywords that require a dimension
+(code(\shape)).
+
+dit(pitch) 
+A pitch is a string which is the name of a pitch.  Example: code(a).
+The pitch names can be redefined with the code(\notenames) keyword.
+See Section(notelang) for pitch names in different languages.  Pitches
+can only be specified inside note mode which is specified with
+code(\notes).  Therefore, keywords which require pitch arguments must
+appear inside code(\notes).  
+
+dit(music) 
+Music is a compound type: arbitrarily complicated expressions with a
+hierarchical structure can be formed from simple building blocks.  The
+simplest expression of type music is a single note.  A note is formed
+from a pitch and an optional duration and must be specified within
+code(\notes).  See Section ref(notedesc) for details.  More
+complicated expressions of type music are formed by surrounding a
+sequence of expressions of type music with braces code({) and code(})
+or with angle brackets code(<) and code(>).  Items appearing in braces
+will be treated as serial. Items in angle brackets will be
+simultaneous.  So for example code({ c e g }) represents an arpeggio
+and code(< c e g >) represents a chord.  These items can be nested any
+way you like.  This simple example shows how three chords can be
+expressed in two different ways:
+mudela(fragment,verbatim,center)(
+\notes{
+  c
+  <a c' e'> <b  d' f'> <c' e' g'>
+  <{a b  c'}{c' d' e'}{e' f' g'}>
+})
+
+)
+
+
+
+subsect(Identifiers)
+
+Identifiers allow names to be assigned to constants, music, or other
+Mudela structures.  To assign an identifier you use
+var(name)=var(value) and to refer to an identifier, you preceed its
+name with a backslash: code(\)var(name).  It is legal to redefine an
+identifier in terms of its old value: code(foo = \foo * 2.0).
+Identifier assignments must appear at the top level in the Mudela
+file.  Note that semicolons are forbidden after assignments appearing
+at the top level but they are obligatory after assignments appearing
+elsewhere.  (Semicolons are also forbidden after code(\property) assignments.)
+
+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 and are entirely alphanumeric.  It is also impossible to refer
+to an identifier whose name is the same as the name of a keyword.  The
+following words are keywords:
+verb(accepts         duration      midi          relative      textscript 
+alternative     font          mm            remove        time       
+bar             grouping      musicalpitch  repeat        times      
+cadenza         header        name          scm           translator 
+chordmodifiers  in            notenames     scmfile       transpose  
+chords          include       notes         score         type       
+clef            key           paper         script        version
+cm              keysignature  partial       shape      
+consists        lyrics        penalty       skip       
+consistsend     maininput     property      spanrequest
+context         mark          pt            tempo)
+
+The right hand side of an identifier assignment is parsed completely
+when the assignment is made.  It therefore must have any context
+specified in the definition.  For example, you must write
+code(foo=\notes{a8 b c}) rather than code(foo={a8 b c}).  Even though
+the context is specified in the definition, you must refer to the
+identifier inside the correct context:
+verb(foo = \paper{ linewidth = 6.0\in; }
+\score{
+  \notes{ ... }
+  \paper{ \foo }
+})
+If code(\foo) is used here without the surrounding code(\paper) then
+an error will result.  Note however that the following is acceptible
+verb(foo = \notes { ... }
+\score{ \foo })  
+It is not necessary to specify code(\notes).
+
+Identifiers can be set equal to integers, reals, strings, music,
+durations (specified with code(\duration)), note ornaments (specified
+with code(\script), dynamics commands, or code(:)), note name tables
+(specified with code(\notenames), translator definitions, the
+code(\paper) block, the code(\midi) block or the code(\score) block.
+When identifiers are used for translators, the code(\paper),
+code(\midi), and code(\score) blocks, they may only be referred to as
+the first item in a block.  So code(\paper{\one \two}) is illegal
+because the identifier code(\two) is not the first thing in the block.
+Unlike other identifier definitions, translator identifier definitions
+can only appear within code(\midi) or code(\paper) blocks.  See
+Section ref(translators) for more information.
+
+
+
+subsect(Modes)
+label(modes)
+
+To simplify different aspects of music definition (entering the notes
+and manipulating them) Mudela has three different input modes which
+affect how unquoted strings are interpreted.
+In each mode, words are identified on the input.  If code("word") is
+encountered, it is treated as a string.  If code(\word) is
+encountered it is treated as a keyword or as an identifier.  The
+behavior of the modes differs in two ways: different modes treat
+unquoted words different, and different modes have different rules for
+deciding what is a word.  
+
+description(
+
+dit(Normal mode)
+At the start of parsing, Mudela is in normal mode.
+In normal mode, a word is an alphabetic character followed by
+alphanumeric characters.  If code(word) is encountered on the input it
+is treated as a string. 
+
+dit(Note mode) Note mode is introduced by the keyword
+code(\notes).  In Note mode, words can only contain alphabetic
+characters.  If code(word) is encountered, LilyPond first checks for a
+notename of code(word).  If no notename is found, then code(word) is
+treated as a string.  If you mistype a notename, the parser will most
+likely complain that you should be in code(\lyrics) mode to do lyrics. 
+
+dit(Chord mode) Chord mode is instroduced by the keyword code(\chords).
+Very similar to Note mode.  
+COMMENT(I'm not sure how it differs)
+
+dit(Lyric mode) Lyrics mode is introduced by the keyword
+code(\lyrics).  This mode is has rules that make it easy to include
+punctuation and diacritical marks in words.  A word in Lyrics mode
+begins with: an alphabetic character, code(_),
+code(?), code(!), code(:), code('), 
+the control characters code(^A) through code(^F), code(^Q) through
+code(^W), code(^Y), code(^^), any 8-bit character with ASCII code over
+127, or a two character combination of a backslash followed by one
+of code(`), code('), code(") or code(^).  
+Subsequent characters of a word can be any character that is not a
+digit and not white space.  One important consequence of this is that
+a word can end with code(}), which may be confusing if you thought the
+code(}) was going to terminate lyrics mode.  Any code(_) characters
+which appear in an unquoted word are converted to spaces, providing a
+mechanism for introducing spaces into words without using quotes.  
+Quoted words can also be used in lyrics mode to specify words that
+cannot be specified with the above rules.  Here are some examples.
+Not all of these words are printable by TeX().  
+verb(a&@&@&TSI|{[    % a word
+\'afoo}         % a word
+1THtrhortho     % not a word because it starts with a digit
+``Hello''       % not a word because it starts with `
+Leise DOEXPAND(Fl\)DOEXPAND("u\)ss{}teren meine Sapfe       % 4 words
+_ _ _ _         % 4 words, each one a space
+))
+
+It is possible to create words that break the rules by prefixing them with the
+dollar sign code($).  Regardless of the context, a word beginning with code($)
+extends until the next white space character.  Such words can contain numbers
+(even in Note mode), or other forbidden characters.  The dollar sign can be
+used to create and access identifiers that could not otherwise be used.  
+
+COMMENT(
+These modes are of a lexical nature. Normal and Note mode largely
+resemble each other, save the possibility of entering Reals, 
+meaning of code(_) and the resolution of words
+
+What's this about reals?  When can you enter them or not enter them?)
+
+
+sect(Note Description)
+label(notedesc)
+
+subsect(Basic Note Specification)
+
+A note specification has the form 
+var(pitch)[var(octavespec)][code(!)][code(?)][var(duration)].
+The pitch of the note is specified by the note's name.  
+
+LilyPond has predefined note names for various languages.  The default
+names are the Dutch note names.  The notes are specified by the
+letters code(c) through code(b), where code(c) is an octave below
+middle C and the letters span the ocatave above that C.  
+In Dutch, a sharp is formed by adding
+code(-is) to the end of a pitch name.  A flat is formed by adding code(-es).
+Double sharps and double flats are obtained by adding code(-isis) or
+code(-eses).  
+Lily has predefined sets of notenames
+for various nop(languages).  See Section ref(notelang) for details.
+Rests are specified with the note name code(r) or code(R).  
+There is also a note name code(s) which produces a nonprinting note of the
+specified duration.
+
+The optional octave specification takes the form of a series of single
+quote 
+code(') characters or a series of comma code(,) characters.  Each
+code(') raises the pitch by one octave; each code(,) lowers the pitch
+by an octave.  
+
+mudela(fragment,verbatim,center)(
+c' d' e' f' g' a' b' c''
+)
+
+mudela(fragment,verbatim,center)(
+cis' dis' eis' fis' gis' ais' bis'
+)
+
+mudela(fragment,verbatim,center)(
+ces' des' es' fes' ges' as' bes'
+)
+
+mudela(fragment,verbatim,center)(
+cisis' eisis' gisis' aisis' beses'
+)
+
+mudela(fragment,verbatim,center)(
+ceses' eses' geses' ases' beses'
+)
+
+Whenever a C-sharp is desired,  you must specify a C-sharp.  LilyPond
+will determine what accidentals to  typeset  depending on the  key and
+context.   
+A reminder accidental can be forced by
+using the  optional exclamation mark `code(!)'
+on the pitch.
+A cautionary accidental, i.e., an accidental within paranthesis
+can be obtained using the optional question mark `code(?)' on the pitch.
+mudela(fragment,verbatim,center)(
+cis' d' e' cis'  c'? d' e' c'!  
+)
+
+
+Durations are entered as their reciprocal values
+mudela(fragment,verbatim,center)(
+a'1 a'2 a'4 a a'8 a a'16 a'32 a'64
+)
+mudela(fragment,verbatim,center)(
+r1 r2 r4 r8 r16 r32
+)
+
+If the duration is omitted then it is set equal to the previous
+duration.  If there is no previous duration, then a quarter note is
+assumed.  
+The duration can be followed by a dot code(.) to obtain dotted note
+lengths.  
+mudela(fragment,verbatim,center)(
+a'4. b'4.
+)
+
+Extra long notes can be obtained using the code(\breve) and
+code(longa) durations:
+mudela(fragment,verbatim,center)(
+c'\breve gis'\longa
+)
+
+In order to get triplets and other tuplets, you must use the
+code(\times) keyword which multiplies the duration by a fraction.  The
+syntax is code(\times) var(fraction) var(music).  The length of all of
+the specified music will be multiplied by the fraction and the
+fraction's denominator will be printed over the notes.  The most
+common tuplet is the triplet in which 3 notes have the length of 2, so
+the notes are 2/3 their written length:
+mudela(fragment,verbatim,center)( b'4 \times 2/3 {c'4 c' c'} d'4 d'4 )
+If you try to use code(\times) as the first thing in your music, you
+may encounter the warning ``No one to print a tuplet start bracket''.
+This happens because the Tuplet-engraver is in Voice and no Voice has
+been created yet.  You must explicitly specify the Voice context in
+this situation 
+mudela(fragment,verbatim,center)( 
+\context Voice { \times 2/3 {c'4 d' e'}} 
+)
+
+A shorthand for code(\times) is to write code(*)var(fraction) after a
+duration.  This shorthand will not label triplets correctly, but
+it is convenient for long rests.  
+For long rests with durations equal to an integer number of whole notes,
+LilyPond produces output that indicates the duration of the rest.  If you use
+code(r) then one rest symbol will be printed and several measures left blank.
+If you use code(R) then all of the measure will be filled with whole rests.
+mudela(fragment,verbatim,center)(
+r1 r1*3 R1*3
+)
+If you set the code(Score.skipBars) property, then only one measure will be
+printed; with code(R), a number indicating the length of the rest will be
+displayed.  
+mudela(fragment,verbatim,center)(
+\property Score.skipBars=1
+r1 r1*3 R1*3
+)
+Even though the code(\times) command is not explicit, it is still
+necessary to specify a code(Voice) context if the music begins with
+rests lengthened using code(*).  
+Otherwise, the following will result:
+mudela(fragment,verbatim,center)(
+R1*3 c'1 d'
+)
+
+
+subsect(Automatic Beam Generation)
+label(autobeam)
+
+By default, Lilypond will generate beams automatically.  This feature can be
+disabled by setting the code(Voice.beamAuto) property to 0.  It can be
+overridden for specific cases by specifying explicit beams as
+described in Section ref(manualbeam).  
+
+In order to decide how to generate beams, Lilypond uses a large number
+of Voice properties, whose default values appear in
+file(auto-beam-settings.ly).  In general, beams can begin anywhere,
+but their ending location is significant.  Beams can end on a beat, or
+at durations specified by the code(Voice.beamAutoEnd) property.  To
+end beams every quarter note, for example, you could use set
+code(Voice.beamAutoEnd) equal to code("1/4").  To end beams every
+three eighth notes you would set it to code("3/8").  The same syntax
+can be used to specify beam starting points using code(Voice.beamAutoBegin).
+
+To allow different settings for different time signatures, these
+property names can start with code(time)var(N)code(_)var(M) to
+restrict the definition to var(N)code(/)code(M) time.  So for example,
+to specify beams ending only for 6/8 time you would use the property
+code(Voice.time6_8beamAutoEnd).  To allow different endings for notes
+of different durations, the duration can be tacked onto the end of the
+property.  To specify beam endings for beams that contain 32nd notes,
+you would use code(Voice.beamAutoEnd_32).
+
+
+subsect(Note Spanners: Beams, Slurs and Ties)
+label(manualbeam)
+
+A beam is specified by surrounding the beamed notes with brackets
+code([) and code(]).  
+mudela(fragment,verbatim,center)(
+[a'8 a'] [a'16 a' a' a'] 
+)
+Some more elaborate constructions:
+mudela(fragment,verbatim,center)(
+[a'16 <a' c''> c'' <a' c''>]
+\times 2/3 { [e'8 f' g'] }
+)
+
+Another type of spanner is the slur.  Slurs connects chords and try to
+avoid crossing stems.  A slur is started with code(CHAR(40)) and stopped with
+code(CHAR(41)).  The starting code(CHAR(40)) appears to the right of the first note
+in the slur.  The terminal code(CHAR(41)) apppears to the left of the first
+note in the slur.  This makes it possible to put a note in slurs from
+both sides:
+mudela(fragment,verbatim,center)(
+f'()g'()a' [a'8 b'(] a'4 g' )f'
+)
+
+A tie connects two adjacent note heads of the same pitch.  
+When used with chords, it
+connects all of the note heads whose pitches match.  
+Ties are indicated using the tilde symbol
+code(~) by analogy with TeX()'s tie which connects words.  
+Note that if you try to tie together chords which have no common
+pitches, then a warning message will appear and no tie will be created.
+(Note that ties between different pitches can be enabled using the
+property Voice.oldTieBehavior.)
+
+mudela(fragment,verbatim,center)(
+e' ~ e' <c' e' g'> ~ <c' e' g'>
+)
+
+It is possible to create beams and slurs that cross staffs by switching the
+context:
+mudela(fragment,verbatim,center)(
+\context PianoStaff <
+\context Staff=one \notes\relative c'{
+  \stemup
+  [c8 c \translator Staff=two \stemup c c]
+  \translator Staff=one
+  d4( \translator Staff=two )a4
+  }
+\context Staff=two \notes{ \clef bass; s1}
+>
+)
+
+
+
+subsect(Note Ornaments)
+
+A variety of symbols can appear above and below notes to indicate
+different characteristics of the performance.  These symbols can be
+added to a note with `var(note)code(-\)var(name)'.  Numerous symbols
+are defined in file(script.ly) and file(script.scm).  Symbols can be
+forced to appear above the note by writing
+`var(note)code(^\)var(name)', and they can be forced to appear below
+by writing `var(note)code(_\)var(name)'.  Here is a chart showing
+symbols above notes, with the name of the corresponding symbol
+appearing underneath.
+
+mudela()(
+\score{
+ < \notes{ c''-\accent c''-\marcato c''-\staccatissimo f'-\fermata 
+          c''-\stopped c''-\staccato c''-\tenuto c''-\upbow c''-\downbow
+          c''-\lheel c''-\rheel  c''-\ltoe  c''-\rtoe  c''-\turn
+          c''-\open  c''-\flageolet  c''-\reverseturn 
+          c''-\trill
+          c''-\prall c''-\mordent c''-\prallprall  c''-\prallmordent
+          c''-\upprall c''-\downprall c''-\thumb c''-\segno c''-\wheel}
+  \context Lyrics \lyrics{  
+        accent__ marcato__ staccatissimo__ fermata stopped__
+        staccato__ tenuto__ upbow downbow__ lheel__ rheel__ ltoe
+        rtoe__ turn__ open__ flageolet reverseturn__ trill__ prall__
+        mordent prallprall__ prallmordent__ uprall__ downprall thumb 
+       segno wheel}
+  >
+  \paper{ linewidth = 5.875\in;          
+          indent = 0.0;        }
+ }
+)
+
+In addition, it is possible to place arbitrary strings of text or
+TeX() above or below notes by using a string instead of an identifier:
+`code(c^"text")'.  Fingerings can be placed by simply using digits.
+All of these note ornaments appear in the printed output but have no
+effect on the MIDI rendering of the music.
+
+To save typing,  a few common symbols  can  be  abbreviated  with
+single characters:
+mudela()(
+\score{ \notes {
+        \property Voice.textStyle = typewriter
+        c''4-._"c-." s4
+        c''4--_"c-{}-"  s4
+        c''4-+_"c-+" s4
+        c''4-|_"c-|" s4
+        c''4->_"c->"  s4
+        c''4-^_"c-\\^{ }"  s4 }
+        \paper { linewidth = 12.\cm; }})
+
+Dynamic marks are specified by using an identifier after a note without a dash:
+code(c4 \ff).  Note that this syntax is inconsistent with the syntax for other
+types of ornaments.  The available dynamic marks are: code(\pppppp),
+code(\ppppp), code(\pppp), code(\ppp), code(\pp), code(\p), code(\mp),
+code(\mf), code(\f), code(\ff), code(\fff), code(\ffff), code(\fffff),
+code(\ffffff), code(\fp), code(\sf), code(\sff), code(\sp), code(\spp),
+code(\sfz) and code(\rfz).
+
+A crescendo mark is started with code(\cr) and terminated with
+code(\rc).  A decrescendo mark is started with code(\decr) and
+terminated with code(\rced).  There are also shorthands for these
+marks.  A crescendo can be started with code(\<) and a decrescendo can
+be started with code(\>).  Either one can be terminated with code(\!).
+Note that code(\!) must go before the last note of the dynamic mark whereas
+code(\rc) and code(\rced) go after the last note.  Because these marks are
+bound to notes, if you want to get several marks during one note, you must use
+spacer notes. 
+mudela(fragment,verbatim,center)(
+c'' \< \! c''   d'' \decr e'' \rced 
+< f''1 {s4 \< \! s4 \> \! s2 } >)
+
+
+COMMENT(Broken!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
+
+Tremolo marks can be printed by a note by adding code(:)[var(length)]
+after the note.  The length must be at least 8.  A var(length) value
+of 8 gives one line across the note stem.  
+If the length is omitted,
+then the last value is used, or the value of the code(Abbrev)
+property if there was no last value.  To place tremolo marks in
+between two notes, begin with code([:)var(length) and end with code(]).
+The tremolo marks will appear instead of beams.  Putting more than two
+notes in such a construction will produce odd effects. 
+
+[TREMOLO BEAMS TEMPORARILY OUT OF ORDER]
+
+COMMENT(mudela (fragment,verbatim,center)(
+c'2:8 c':32 [:16 e'1 g'] [:8 e'4 f']
+))
+
+COMMENT(
+Is the last paragraph correct?  Is it called "tremolo"?  Why is
+"abbreviation" used?  (What is the unabreviated form?)
+
+COMMENT(
+mudela (fragment,verbatim,center)(
+c'4:32 [:16 c'8 d'8]
+))
+
+)
+
+
+sect(Other Ways to Enter Pitches)
+
+subsect(Pitch Names in Other Languages)
+label(notelang)
+
+The pitch names can be easily redefined using the code(\notenames) command.
+Note name definitions have been provided in various languages.  
+Simply include the language specific init file.  For example:
+code(\include "english.ly").  The available language files and the names
+they define are:
+
+verb(                        Note Names               sharp       flat
+nederlands.ly  c   d   e   f   g   a   bes b   -is         -es
+english.ly     c   d   e   f   g   a   bf  b   -s/-sharp   -f/-flat
+deutsch.ly     c   d   e   f   g   a   b   h   -is         -es
+norsk.ly       c   d   e   f   g   a   b   h   -iss/-is    -ess/-es
+svenska.ly     c   d   e   f   g   a   b   h   -iss        -ess
+italiano.ly    do  re  mi  fa  sol la  sid si  -d          -b
+catalan.ly     do  re  mi  fa  sol la  sid si  -d/-s       -b)
+
+subsect(Relative Pitch Specification)
+label(relative)
+
+One very common error when entering music is to place notes in the wrong
+octave.  One way to avoid being confused by large numbers of octave changing
+marks is to use
+the code(\relative) keyword. 
+Music which appears within code(\relative) is
+interpreted differently.  The octave of a note is determined by making it as
+close to the previous note as possible.  The octave changing marks code(') and
+code(,) can then be added to raise or lower this note by octaves.  You have to
+specify a starting pitch because the first note of a list has no predecessor.  
+
+mudela(fragment,verbatim,center)(
+\relative c'' { c d b c, d b c' d 
+                b c,, d b }
+)
+
+When the preceeding item is a chord, the first note of the chord is used to
+determine the first note of the next chord.  But other notes within the second
+chord are determined by looking at the immediately preceeding note.  
+
+mudela(fragment,verbatim,center)(
+\relative c' { c <c e g> 
+    <c' e g> <c, e' g> }
+) 
+
+The code(\relative) keyword can only appear in music, so there must be a
+surrounding code(\notes) keyword which does not appear in the fragments shown
+above.  Also note that if the music passed to a code(\relative) keyword 
+contains a code(\transpose) keyword, the tranposed music will not be
+processed in relative mode.  An additional code(\relative) must be placed
+inside the code(\transpose).  If code(\relative) will be used several
+times, or if it will be used in the same music with code(\transpose),
+then you may get bizarre effects.  This can be fixed by using an
+explicit code(Staff) context.   
+
+
+subsect(Tranposition of Pitches)
+label(transpose)
+
+Another way to modify the meaning of the note names is to use the
+code(\transpose) keyword.  This keyword allows you to transpose music.
+To use transposition, specify the pitch that middle C should be tranposed to.
+It is important to distinguish between enharmonic pitches as they can produce
+different transpositions.  To transpose up half a step, for example, either 
+code(\transpose cis') or code(\transpose des') will work.  But the first
+version will print sharps and the second version will print flats.  
+In this example, a scale in the key of E is transposed to F, or to E-sharp 
+with odd results.
+mudela(fragment,verbatim,center)(
+\relative c' { \key e; 
+  e fis gis a b cis dis e }
+)
+mudela(fragment,verbatim,center)(
+\transpose des' \relative c' { \key e; 
+   e fis gis a b cis dis e }
+)
+mudela(fragment,verbatim,center)(
+\transpose cis' \relative c' { \key e; 
+    e fis gis a b cis dis e }
+)
+If you want to use both code(\transpose) and code(\relative), then you must use
+code(\transpose) first.  Any code(\relative) keywords that are outside the 
+code(\transpose) have no effect on notes that appear inside the
+code(\transpose).  As with code(\relative), using code(\transpose)
+repeatedly can cause bizarre effects.  An explicit code(Staff) context
+will eliminate the problems.  
+
+sect(Chords)
+
+Chords can be entered either by name or by listing the notes in angle brackets.
+Chords can be displayed either as notes or by name.  To enter chords by name,
+either place them inside the code(\chords) keyword, or use
+code(\notes) and surround them with
+code(@) characters. 
+Chord names have the form
+var(tonic)[var(duration)][code(-)var(modifier)][code(^)var(subtractions)][code(/)var(inversion)]
+The var(tonic) should be the tonic note of the chord, and the var(duration) is
+the chord duration in the usual notation.  There are two kinds of modifiers.
+One type is chord additions, which are obtained by listing intervals separated
+by dots.  An interval is written by its number with an optional code(+) or
+code(-) to indicate raising or lowering by half a step.  A chord additions has
+two effects:  it adds the specified interval and all lower odd numbered
+intervals to the chord, and it may lower or raise the specified interval.
+Intervals can be separated by a dot (code(.)) if you need to list
+several unmodified intervals.
+Repeating a code(-) character will remove a half step from the preceeding
+interval.  
+mudela(fragment,verbatim,center)(
+\transpose c''{ 
+\chords{
+  c1 c-3- c-7 c-8 c-9  
+  c-9-5+7+ c-3-5- c-4.6.8
+}}) 
+The second type of modifier that may appear after the code(-) is 
+a named modifier. 
+Named modifiers are listed in the file file(chord-modifiers.ly).  The
+available modifiers are code(m) and code(min) which lower
+the 3rd half a step, code(aug) which raises the 5th, code(dim) which lowers
+the 5th, code(maj) which adds a raised 7th, and code(sus) which replaces the
+5th with a 4th.  
+mudela(fragment,verbatim,center)(
+\transpose c''{ 
+\chords{
+  c1-m c-min c-maj c-aug c-dim c-sus
+}}) 
+
+Chord subtractions are used to eliminate notes from a chord.  The notes to be
+subtracted are listed after a code(^) character, separated by dots.  
+mudela(fragment,verbatim,center)(
+\transpose c''{ 
+\chords{
+  c1^3 c-7^5.3 c-8^7
+}}) 
+
+Chord inversions can be specified by appending code(/) and the name of a
+single note to a chord.  This has the effect of lowering the specified note by
+an octave so it becomes the lowest note in the chord.  If the
+specified note is not in the chord then a warning will be printed.  
+mudela(fragment,verbatim,center)(
+\transpose c'''{ 
+ @c1@ @c/e@ @c/g@ @c-7/e@
+}) 
+Throughout these examples, chords have been shifted around the staff
+using code(\transpose).  The code(\relative) keyword has odd effects
+when combined with named chords.  
+
+For displaying printed chord names, use the code(ChordNames) context.  
+The chords may be entered either using the notation described above,
+or directly using angle brackets. 
+mudela(fragment,verbatim)(
+<
+  \context ChordNames { \chords{ a b c} \notes{ < d f g >  < e g b > } }
+  \context Staff \notes{ a b c' d' e' }
+>
+)
+Lilypond examines chords specified as lists of notes to determine a
+name to give the chord.  By default, LilyPond will not try to identify
+chord inversions:
+mudela(fragment,verbatim,center)(
+<
+  \context ChordNames { 
+     \notes{ < e' g' c'' > } }
+  \context Staff \notes{ c' } 
+>)
+If you want inversions to be recognized, you must set the property
+code(Score.chordInversion): 
+mudela(fragment,verbatim,center)(
+<
+  \property Score.chordInversion = 1
+  \context ChordNames { 
+       \notes{ < e' g' c'' > } }
+  \context Staff \notes{ c' } 
+>)
+
+
+
+sect(Lyrics)
+
+Lyrics are entered like notes, with pitches replaced
+by text.  For example code(Twin-4 kle4 twin-4 kle4) enters four
+syllables, each with quarter note duration.  Note that the hyphen has
+no special meaning for lyrics, and does not introduce special symbols.
+See Section ref(modes) for a description of what is interpreted as a lyric.
+
+In order to instruct LilyPond to write lyrics underneath the
+staff, you must enter the lyrics context with code(\context Lyrics).  
+Lyrics should be entered in lyrics mode which is entered with code(\lyrics).
+
+Spaces can be introduced into a lyric either by using quotes (code("))
+or by using an underscore without quotes: code(He_could4 not4).  All
+unquoted underscores are converted to spaces.  Here is a full example: 
+mudela(verbatim)(\score{
+  <  \notes \transpose c'' {c d e c | c d e c | e f g'2 | 
+                              e'4 f g'2 \bar "|."; }
+     \context Lyrics \lyrics { 
+              DOEXPAND(Fr\)`e-4 re Ja- que DOEXPAND(Fr\)`e- re Ja- que
+              Dor- mez vous?2 Dor-4 mez vous?2  }
+  >
+})
+
+COMMENT(
+URG
+                        Fr\`e-4 re Ja- que
+                        Fr\`e- re Ja- que
+Why does this warrant an URG?
+)
+
+When one word is attached to many notes, you may 
+want a  continuous line after the lyric to show  this.   To achieve
+this effect, add a code(__) lyric as a separate word 
+after the lyric to be extended.  
+This will create
+an extender, a line  that extends over the entire duration of 
+the lyric.  This line will run all the way to the start of the next
+lyric, so you may want to shorten it by using a blank lyric.  
+mudela(verbatim)(\score{
+< \notes \relative c''{ 
+     a4()b()c()d c()d()b()a c()d()b()a }
+   \context Lyrics \lyrics {
+     foo1 __  bar2. __ _4 baz1 __ }
+> })
+     
+
+
+sect(Time)  
+
+LilyPond aligns all musical objects according to the amount of time
+they occupy.  All musical objects have a duration.  When music is
+written sequentially using braces the duration is the sum of the 
+durations of the elements.  When music is stacked into simultaneous music 
+using angle
+brackets, the duration is the maximum of the durations of the
+elements.  
+
+Because LilyPond knows the durations of all musical elements, the time
+signature enables LilyPond to draw bar lines automatically.  The time
+signature is specified with the code(\time) keyword: code(\time 3/4).
+If no time signature is given, LilyPond assumes 4/4.  The automatic
+generation of bar lines can toggled with the code(\cadenza) keyword or the
+code(Staff.barNonAuto) property,
+and an incomplete measure at the start of the music can be created
+using the code(\partial) keyword: code(\partial 8*2;) creates a
+starting measure lasting two eighth notes.
+
+In order to help with error checking, you can insert bar markers in
+your music by typing code(|).  Whenever LilyPond encounters a code(|)
+that doesn't fall at a measure boundary, she prints a warning message.
+
+Rhythmic grouping is  a concept closely associated with this. 
+A default grouping is selected for the chosen time signature.  
+The default consists of combinations of 2 and 3 beats with as many
+groups of 3 as possible, and the groups of 3 coming first.  For
+example, 4/4 is divided into 2+2 and 8/8 is divided into 3+3+2.  This
+default grouping can be changed using the \grouping keyword which
+takes a list of durations to specify the grouping. 
+
+
+COMMENT(
+sect(Composition: forming bigger structures)
+label(sec:grammar)
+
+The computer savy user may be interested in a more formal
+specification.  We can capture what have learned about forming
+sentences in Mudela in a context-free grammar.
+
+latexcommand(\smallskip)
+
+table(2)(lll)(
+        row(cell(em(Music))cell(: em(Note)))
+        row(cell()cell(code(|) em(Rest)))
+        row(cell()cell(code(|) code({) em(MusicList) code(})))
+        row(cell()cell(code(|) code(<) em(MusicList) code(>)))
+        row(cell()cell(code(|) em(Command)))
+        row(cell()cell(code(|) code(\context) em(string) code(=) em(string)  em(Music)))
+        row(cell()cell(;))
+        row(cell(em(MusicList))cell(: em(empty)))
+        row(cell()cell(code(|)  em(MusicList)  em(Music)))
+        row(cell()cell(;))
+)
+
+latexcommand(\smallskip)
+
+In mathematics you can form expressions by combining expressions,
+which are ultimately some kind of atom or terminal symbol.  The same
+goes for Mudela: there are some basic building blocks, and by
+combining those you create complex music.
+
+You can combine music in three ways:
+itemize(
+it()If you enclose a sequence of music-elements in braces ( code({)
+    and code(}) ), then you form another kind of music called
+sequential music
+    with those pieces.
+  The duration of sequential composition is the sum of the durations of its elements
+  verb(
+      { c c g g a a g2 }      % twinkle twinkle
+      { { c c g g} { a a g2 } }
+  )
+it()You can stack music by enclosing a sequence of music elements
+    with code(<) and code(>). This is called simultaneous music.  
+    The duration of a simultaneous composition is the maximum of the durations 
+    of its elements Example:
+    verb(
+        <a4 {cis8 cis8} e'4>      % a-major chord
+    )
+it()You can form music by transposing music:
+    verb(
+    \transpose  
+        d       % from c to the d that's almost one octave down
+                { e4 f4 }       % the horizontal music
+)
+it()verb(\context)
+it()verb(\property)
+it()verb(\translator)
+it()verb(\relative)
+)
+
+Of course you can also combine these three mechanisms.
+verb(
+{ c <c e> <c e g> <c e g \transpose d' dis > }  % 4 increasing chords
+)
+
+END OF COMMENT  )
+
+
+sect(Repeats)
+
+In order to specify repeats, use the code(\repeat) keyword.  By
+default, repeats are printed with repeat symbols.  
+mudela(fragment,verbatim,center)(
+c'1
+\repeat semi 2 { c'4 d' e' f' }
+\repeat semi 2 { f' e' d' c' })
+In order to specify alternate endings, use the code(\alternative)
+keyword.  
+mudela(fragment,verbatim,center)(
+c'1
+\repeat semi 2 {c'4 d' e' f'} 
+\alternative { {d'2 d'} {f' f} })
+The code(semi) specifies that normal repeats will be printed.  If
+code(fold) is used instead then the alternatives will be stacked:
+mudela(fragment,verbatim,center)(
+c'1
+\repeat fold 2 {c'4 d' e' f'} 
+\alternative { {d'2 d'} {f' f} })
+When the repeats involve partial measures, it will be necessary to use
+code(\partial) keywords in a somewhat unexpected way 
+to indicate some measure lengths.
+mudela(fragment,verbatim)(
+\context Staff { \relative c'{
+  \repeat semi 2 { \partial 4; e | c2 d2 | e2 f2 | }
+  \alternative { { g4 g g } {\partial 1; a a a a | b1 } }
+}})
+Repeats can be unfolded by setting the property Staff.unfoldRepeats.
+Note also that if your music begins with code(\repeat), you must place
+it in an explicit code(Staff) context or you will get bizarre results. 
+
+If you don't give enough alternatives for all of the repeats, then the
+first alternative is assumed to be repeated enough to equal to
+specified number of repeats.  
+mudela(fragment,verbatim)(
+\context Staff { \relative c'{
+  \repeat semi 3 { \partial 4; e | c2 d2 | e2 f2 | }
+  \alternative { { g4 g g } {\partial 1; e4 e e } 
+                 {\partial 1; a a a a | b1 } }
+}})
+
+
+sect(Keywords)
+
+Keywords sometimes appear alone, but usually they require arguments.
+A keyword may have a single argument, a sequence of arguments in
+braces, or a sequence of arguments separated by spaces and terminated
+by a semicolon.  The precise syntax of each keyword is shown below.
+Keywords must appear in the right context.  If you use a keyword in
+the wrong place, even if the usage is syntactically correct, you will
+get the message ``parse error'' from LilyPond.
+
+
+description(
+
+dit(code(\absdynamic) code({) var(code) code(})) Internal keyword for
+printing dynamic marks such as $f$ under music.  The parameter
+var(code) is unsigned and specifies the dynamic mark to print.
+Normally you should use the more user friendly abbreviations defined
+in the init file file(dynamic.ly).
+
+FIXME: Changed to code(\textscript) var(text) var(style).  Defines
+a text-request.
+
+dit(code(\accepts) var(string)code(;)) This keyword can appear only within a
+code(\translator) block.  It specifies what contexts are allowed with the
+context that is being defined.  See Section ref(translators).  
+
+dit(code(\alternative) code({) var(music1) var(music2) ... code(}))
+Specifies alternative endings.  Must come after a code(\repeat) keyword.  
+
+dit(code(\bar) var(bartype)code(;)) Prints a special bar symbol, or at
+measure boundaries, replaces the regular bar symbol with a special
+symbol.  The argument var(bartype) is a string which specifies the
+kind of bar to print.  Options are code(":|"), code("|:"),
+code(":|:"), code("||"), code("|."), code(".|"), or code(".|.").
+These produce respectively a right repeat, a left repeat, a double
+repeat, a double bar, a start bar, an end bar, or a thick double bar.
+If var(bartype) is set to code("empty") then nothing is printed, but a
+line break is allowed at that spot.  Note that the printing of special bars
+has no effect on the MIDI output.
+
+dit(code(\cadenza) var(togglevalue)code(;)) Toggles the automatic generation
+of bar lines.  If var(togglevalue) is 0 then bar line generation is
+turned off.   If var(togglevalue) is  1  then a bar is  immediately
+printed and bar generation is turned on.
+
+dit(code(\clef) var(clefname)code(;)) Allowed only in music.  
+Sets the current clef.  The argument is
+a string which specifies the name of the clef.  Several clef names are
+supported.  If code(_8) or code(^8) is added to the end of a clef
+name then the clef lowered or raised an octave will be generated.  
+Here are the supported clef names with middle C shown in each clef:
+mudela(center)(
+\score{
+  \notes{ \cadenza 1;
+   %\property Voice.textStyle = typewriter
+   \clef subbass; c'4-"\kern-10mm subbass" 
+           \clef bass;    c'4^"\kern -8mm bass"
+           \clef baritone; c'4_"\kern -10mm baritone"
+           \clef varbaritone; c'4^"\kern -10mm varbaritone"
+           \clef tenor;     c'4_"\kern -10mm tenor"
+           \clef "G_8";   c'4^"\kern -6mm G\_8" 
+   }  
+   \paper{ linewidth= 4.5 \in; }
+}
+)
+mudela(center)(
+\score{
+  \notes{\cadenza 1; \clef alto;    c'4_"\kern -10mm alto"
+      %     \clef scarlatti;    c'4_"\kern -4mm scarlatti"
+           \clef mezzosoprano; c'4^"\kern -10mm mezzosoprano"
+           \clef soprano;  c'4_"\kern -10mm soprano"
+           \clef treble;  c'4^"\kern -6mm treble"
+           \clef french;  c'4_"\kern -10mm french" }  
+  \paper{ linewidth= 4.5 \in; }
+}
+)
+The treble  clef  can also  be obtained using  the  names code(G) or
+code(violin).  The bass clef is also available by code(\clef  F). 
+
+dit(code(\chord) var(chordlist)) Parse var(chordlist) in chords mode.
+
+dit(code(\chordmodifiers) var(modifierlist)) Specify the text chord
+modifiers that may appear after chord names.  These are specified in
+the file file(chord-modifiers.ly).  
+
+dit(code(\cm)) Specify a dimension in centimeters. 
+
+dit(code(\consists) var(string)code(;)) This keyword can appear only within a
+code(\translator) block.  It specifies that an engraver or performer named
+var(string) should be added to the translator.  See Section
+ref(translators).
+
+dit(code(\consistsend) var(string)code(;)) Unknown function.  
+
+dit(code(\context) var(contexttype) [code(=) var(contextname)]
+var(music) or code(\context) var(translatortype)code(;)) The first
+variant is used only within music to create an instance of a
+context.  The new context can optionally be given a name.  The
+specified var(music) is processed in the new context. The second
+variant appears within a code(\translator) block and specifies the
+type of translator being created.
+
+dit(code(\duration) code({) var(length) var(dotcount) code(})) Specify note
+duration.  The parameter var(length) is the negative logarithm (base
+2) of duration: 1 is a half note, 2 is a quarter note, 3 is an eighth
+note, etc.  The number of dots  after  the  note is given by
+var(dotcount). 
+
+dit(code(\font) var(string)) Internal keyword.  Used within
+code(\paper) to specify the font.
+
+dit(code(\grouping) var(durationseq)code(;))  Sets  the  metric structure of
+the measure.  Each argument specifies the duration of one metric unit.
+For example, code(\duration 16*5;) specifies a grouping of five beats
+together in 5/16 time.  The default grouping is to have as many groups
+of 3 as possible followed by groups of two.  
+
+dit(code(\header) code({) var(key1) = var(val1); var(key2) = var(val2); ... code(}))
+Specifies information about the music.  A header should appear at the
+top of the file describing the file's contents.  If a file has
+multiple code(\score) blocks, then a header should appear in
+each score block describing its contents.  Tools like code(ly2dvi) can
+use this information for generating titles.   Key values that are used
+by ly2dvi are: title, subtitle, composer, opus, poet, instrument,
+metre, arranger, piece and tagline.  
+
+dit(code(\in)) Specify a dimension in inches.  
+
+dit(code(\include) var(file)) Include the specified file.  The
+argument var(file) is a string.  The full filename including the
+file(.ly) extension must be given, and the filename must be quoted.
+(An unquoted string will not work here.)
+
+dit(code(\key) var(pitch) var(type) code(;)) Change the key signature. 
+var(type) should be code(\major) or code(\minor) to get
+var(pitch)-major or var(pitch)-minor, respectively. The second
+argument is optional, the default is major keys. 
+The var(\context) argument can also be given as an integer, which tells
+the number of semitones that should be added to the pitch given in the
+subsequent code(\key) commands to get the corresponding major key,
+e.g. code(\minor) is defined as 3.  The standard mode names 
+code(\ionian), code(\locrian), code(\aeolian), code(\mixolydian),
+code(\lydian), code(\phrygian), and code(\dorian) are also defined. 
+
+dit(code(\keysignature) var(pitchseq)code(;))
+Specify an arbitrary key signature.  The pitches from var(pitch) will
+be printed in the key signature in the order that they appear on the list.
+
+dit(code(\lyrics) var(lyriclist)) Parse var(lyriclist) in lyrics mode.
+
+dit(code(\maininput)) Internal command.  This command is used for creating init
+files like file(init.fly) that read the user file into the middle of another
+file.  It is illegal to use this command in a user file.  
+        
+dit(code(\mark) var(unsigned)code(;) or code(\mark) var(string)code(;)) 
+Allowed in music only.  Prints a mark over or under (depending on the
+code(markDirection) property) the staff.
+You must add code(Mark_engraver) to the Score context.
+
+dit(code(\midi) var(statementlist)) Appears in a score block to
+indicate that musical output should be produced and to set output
+parameters.  Can also appear at the top level to set default output
+parameters.  See code(\tempo).
+
+dit(code(\mm)) Specify a dimension in millimeters. 
+
+dit(code(\musicalpitch) code({) var(octave) var(note) var(shift) code(})) 
+Specify note pitch.  The octave is specified by an integer,
+zero for the octave containing middle C.  The note is a number from 0
+to 7, with 0 corresponding to C and 7 corresponding to B.  The shift
+is zero for a natural, negative to add flats, or positive to add
+sharps.
+
+dit(code(\name) var(context)code(;)) Appears within code(\translator) to
+specify the name of the context that the translator handles. See Section
+ref(translators).   
+
+dit(code(\notenames) var(assignmentlist)) Define new note names.  This
+keyword can appear only at the top level. 
+The argument is a list of definitions of  the form
+var(name) = var(pitch),  where var(pitch) is specified with the
+code(\musicalpitch) keyword.  
+
+dit(code(\notes) var(music)) Enter note mode and process the
+specified music. 
+
+dit(code(\paper) var(statmentlist)) 
+Appears in a score block to indicate that the music should be printed
+or to set output parameters.  Can also appear at the top level to set
+default output parameters for all of the score blocks.  
+The var(statmentlist) contains statements that change features of the
+output.  See Section ref(paper).  
+
+dit(code(\partial) var(duration)code(;)) Specify that the first measure of
+the music lasts only for the specified duration.  Use also to specify
+the duration of the first measure of the argument to
+code(\alternative).  
+
+dit(code(\penalty) var(int)code(;)) Allowed only in music.
+Discourage or encourage line breaks.  See identifiers code(\break) and
+code(\nobreak) in Section ref(ident). 
+
+dit(code(\property) var(contextname)code(.)var(propname) code(=) var(value))
+Sets the var(propname) property of the context var(contextname) to the
+specified var(value).  All three arguments are strings.  Depending on
+the context it may be necessary to quote the strings or to leave space
+on both sides of the dot. 
+
+dit(code(\pt)) Specify a dimension in points. 
+
+dit(code(\relative) var(pitch) var(music)) Processes the specified
+var(music) in relative pitch
+mode.  In this mode, the octave of a pitch is chosen so that the
+pitch is closest to the preceeding pitch.  
+The argument var(pitch) is
+the starting pitch for this comparision.  In the case of chords, the
+first note of a chord is used as the base for the first pitches in the next
+chord.  See Section ref(relative).
+
+dit(code(\remove) var(string)code(;)) Can appear only in a
+code(\translator) block.  Specifies that a performer or engraver named
+var(string) should be removed.  See Section ref(translators).  
+
+dit(code(\repeat) var(style) var(count) code({) var(music) code(}))
+Repeats the specified
+music var(count) times.  Alternative endings can be specified by adding a
+code(\alternative) keyword after the code(\repeat).  The var(style)
+parameter should be either code(semi), for regular repeats,  or
+code(fold) for repeats displayed vertically. 
+
+dit(code(\scm) var(scheme)code(;)) Embeds specified Scheme code.  
+
+dit(code(\scmfile) var(filename)code(;)) Reads Scheme code from the specified
+file.  
+
+dit(code(\score) var(statementlist)) Create a Score context.  This
+is the top level notation context.  
+COMMENT(this still needs work)
+
+dit(code(\script) var(alias)) Prints a symbol above or below a note.
+The argument is a string which points into the script-alias table
+defined in file(script.scm).  The scheme definitions specify whether
+the symbol follows notes into the staff, dependence of symbol
+placement on staff direction, and a priority for placing several
+symbols over one note.  Usually the code(\script) keyword is not used
+directly.  Various helpful identifier definitions appear in
+file(script.ly).
+
+dit(code(\shape) code(=) var(indent1) var(width1) var(indent2)
+var(width2) ... code(;)) Allowed only within code(\paper).  Each pair
+of var(indent) and var(width) values is a dimension specifying how far
+to indent and how wide to make the line.  The indentation and width of
+successive lines are specified by the successive pairs of dimensions.
+The last pair of dimensions will define the characeristics of all
+lines beyond those explicitly specified.
+
+COMMENT(First pair of dimensions seems to be skipped.  At least it is
+in the example file denneboom.ly.)
+
+dit(code(\skip) var(duration)code(;)) Skips the amount of time specified by
+var(duration).  A gap will be left for the skipped time with no notes
+printed.  It works in Note Mode or Lyrics Mode (but generates a
+mysterious error in lyrics).
+
+dit(code(\spanrequest) var(startstop) var(type)).  Define a spanning request
+var(startstop) is either -1 (code(\start)) or 1 (code(\stop)). The var(type)
+parameter is a string that describes what should be started.  Supported types
+are "crescendo", "decrescendo", "beam", "slur".  This is an internal command.
+Users should use the abbreviations  which are defined in the
+initialization file file(dynamic.ly).
+
+dit(code(\tempo) var(duration) = var(perminute)code(;)) Used within
+code(\midi) or within music to specify the tempo.  For example, 
+`code(\midi { \tempo 4 = 76;})' requests output with 76 quarter notes
+per minute.  Note that if the music contains several tempo commands,
+only the last one is used to set the tempo for the entire MIDI output. 
+COMMENT(Is this true?)
+
+dit(code(\textscript) var(text) var(style)) Print the specified text as a
+script in the specified style.  
+
+dit(code(\time) var(numerator)code(/)var(denominator)code(;)) Change the time
+signature.  The default time signature is 4/4.  
+
+dit(code(\times) var(numerator)code(/)var(denominator) var(music))
+Multiply the duration of var(music) by the specified fraction.
+
+dit(code(\translator) var(statements) or code(\translator)
+var(context) = var(name)) The first variant appears only within
+code(\paper) and specifies a translator for
+converting music to notation.  The translator is specified with a
+single code(\context) statement and a series of code(\accepts), and
+code(\consists) statements.  See Section ref(translators). 
+The second variant appears in 
+music.  It specifies that the current the contexts
+contained within the specified context should be shifted to the
+context with the specified name.  
+
+COMMENT( \translator seems like a strange name for the second
+operation, and is the overloading desireable? )
+
+dit(code(\transpose) var(pitch) var(music)) Transposes the specified
+music.  Middle C is tranposed to var(pitch).  This is allowed in music only,
+and if it appears inside code(\relative), then any notes specified for
+transposition should be specified inside another code(\relative).  See Section
+ref(transpose).  
+
+dit(code(\type) var(string)code(;)) Use inside code(\translator) to
+specify the type of the translator.  
+
+dit(code(\version) var(string)) Specify the version of Mudela that a
+file was written for.  The argument is the version number, for example
+code("1.0.1").  Note that the Mudela version is different from the
+LilyPond version.
+
+)  
+
+
+sect(Notation Contexts)
+
+Notation contexts provide information that appears in printed music
+but not in the music itself.  A new musical context is created using
+the code(\context) keyword: `code(\context) var(contexttype) [code(=)
+var(contextname)] var(music)'.  The following context types are
+allowed.
+
+description(
+
+dit(code(LyricVoice)) Corresponds to a voice with lyrics.  Handles the printing
+of a single line of lyrics.  
+
+dit(code(Voice)) Corresponds to a voice on a staff.
+  This context handles the conversion of noteheads,
+  dynamic signs, stems, beams, super- and subscripts, slurs, ties and rests.
+
+dit(code(ChordNamesVoice)) A voice with chord names.  Handles printing
+of a line of chord names.  
+
+dit(code(ChordNames))  Typesets chord names.  Can contain
+code(ChordNamesVoice) contexts.  
+
+dit(code(Lyrics)) Typesets lyrics.  It can contain code(LyricVoice) contexts.
+
+dit(code(Staff)) Handles clefs, bar lines, keys,
+  accidentals.  It can contain code(Voice) contexts.
+
+dit(code(RhythmicStaff)) A context like code(Staff) but for printing
+rhythms.  Pitches are ignored; the notes are printed on one line.  
+It can contain code(Voice) contexts. 
+
+dit(code(GrandStaff)) Contains code(Staff) or code(RhythmicStaff)
+contexts.  It adds a brace on the left side grouping the staffs
+together. The bar lines of the contained staffs are connected vertically.
+It can contain code(Staff) contexts.
+
+dit(code(PianoStaff)) Just like code(GrandStaff) but with
+code(minVerticalAlign) set equal to code(maxVerticalAlign) so that
+interstaff beaming and slurring can be used.  
+
+dit(code(StaffGroup)) Contains code(Staff) or code(RhythmicStaff)
+contexsts.  Adds a bracket on the left side, grouping the staffs
+together.  The bar lines of the contained staffs are connected vertically.
+It can contain code(Staff), code(RhythmicStaff), code(GrandStaff) or code(Lyrics) contexts.  
+
+dit(code(ChoirStaff)) Identical to code(StaffGroup) except that the
+contained staffs are not connected vertically.  
+
+dit(code(Score)) This is the top level notation context.  It is specified with
+the code(\score) keyword rather than the code(\context) command.  No
+other context can contain a code(Score) context.  This context handles
+the administration of time signatures.  It also makes sure that items
+such as clefs, time signatures, and key-signatures are aligned across
+staffs.  It can contain code(Lyrics), code(Staff),
+code(RhythmicStaff), code(GrandStaff), code(StaffGroup), and
+code(ChoirStaff) contexts.
+
+)
+
+The various contexts have properties associated with them.  These
+properties can be changed using the code(\property) command:
+`code(\property) var(context)code(.)var(propname) code(=) var(value)'.
+Properties can also be set within the code(\translator) block
+corresponding to the appropriate context.  In this case, they are
+assigned by `var(propname) code(=) var(value)'.  The settings made with
+code(\property) are processed after settings made in the code(\translator)
+block, so the code(\property) settings will override code(\translator)
+settings.  
+
+The code(\property) keyword will create any property you specify.
+There is no guarantee that a property will actually be used.  If you
+spell a property name wrong, there will be no error message.  In order to find
+out what properties are used, you must search the source code 
+for code(get_property).  
+Properties that are set in one context are inherited by all of the
+contained contexts.  This means that a property valid for the Voice
+context can be set in the Score context (for example) and thus take
+effect in all Voice contexts.  
+
+subsubsubsect(Lyrics properties)
+
+description(
+
+dit(code(textStyle)) Set the font for lyrics.  The available font
+choices are code(roman), code(italic), code(bold), code(large),
+code(Large), code(typewriter), and code(finger).  The code(finger)
+font can only display numbers.  Note also that you must be careful
+when using code(\property) in Lyrics mode.  Because of the way strings
+are parsed, either put quotes around the arguments to code(\property)
+or be sure to leave a space on both sides of the dot.
+
+
+)
+
+subsubsubsect(Voice properties)
+
+description(  
+
+dit(code(stemLeftBeamCount)) Specify the number of beams to draw on
+the left side of the next note.  
+
+dit(code(stemRightBeamCount)) Specify the number of beams to draw on
+the right side of the next note.  
+
+dit(code(beamAuto)) If set to 1 then beams are generated
+automatically.  If set to zero then no beams will be automatically
+generated.  The default value is 1.  
+
+dit(code(beamAutoEnd)) Specifies when automatically generated beams
+can end.  See Section ref(autobeam).
+
+dit(code(beamAutoBegin)) Specifies when automatically generated beams
+can start.  See Section ref(autobeam). 
+
+dit(code(textEmptyDimension)) If set to 1 then text placed above or
+below the staff is assumed to have zero width.  
+
+dit(code(noteheadStyle)) Selects type of note head.  Choices are
+code(cross), code(diamond), code(harmonic), code(transparent), and
+code("").  They are shown in that order below.  
+mudela(center)(
+\score{
+  \notes{ 
+     \property Staff.barNonAuto = 1
+     \property Voice.noteHeadStyle = cross 
+     a'
+     \property Voice.noteHeadStyle = diamond
+     a'
+     \property Voice.noteHeadStyle = harmonic
+     a'
+     \property Voice.noteHeadStyle = transparent
+     a' 
+     \property Voice.noteHeadStyle = ""
+     a'
+  }
+ \paper{ linewidth = -1.;}
+}
+)
+
+
+dit(code(restStyle)) Change the layout of rests shorter than quarter notes. 
+Currently, the standard layout code(restStyle="") and mensural notation
+code(restStyle="mensural") are available.
+
+dit(code("midiInstrument")) Sets the instrument for MIDI output.  This
+property name must be quoted because of the embedded underscore.  If
+this property is not set then LilyPond will use the code(instrument)
+property.  This must be set to one of the strings on the list of MIDI
+instruments that appears in Section ref(midilist).  If you use a
+string which is not listed, LilyPond will silently substitute piano. 
+
+dit(code(transposing)) Tranpose the MIDI output.  Set this property to
+the number of half-steps to transpose by.
+
+dit(code(oldTieBehavior)) Set to 1 in order to get old tie behavior
+where ties would connect unequal pitches.  
+
+dit(code(verticalDirection)) Determines the direction of stems, subscripts,
+beams, slurs, and ties.  Set to code(\down) to force them down,
+code(\up) to force them up, or code(\free) to let LilyPond decide.
+This can be used to distinguish between voices on the same staff.  The
+code(\stemdown), code(\stemup), and code(\stemboth) identifiers set
+this property.  See also the identifiers code(\voiceone),
+code(\voicetwo), code(\voicethree) and code(\voicefour).
+
+dit(code(slurVerticalDirection)) Set to code(\free) for free choice of slur
+direction, set to code(\up) to force slurs up, set to code(\down) to
+force slurs down.  The shorthands code(\slurup), code(\slurdown), and
+code(\slurboth) are available.
+
+dit(code(tieVerticalDirection)) Set to code(\free) for free choice of tie
+direction, set to code(\up) to force ties up, set to code(\down) to
+force ties down.  
+
+dit(code(slurdash)) Set to 0 for normal slurs, 1 for dotted slurs, and
+a larger value for dashed slurs.  Identifiers code(\slurnormal) and
+code(\slurdotted) are predefined to set the first two settings.
+
+dit(code(horizontalNoteShift)) Set to 1 to enable LilyPond to shift notes
+horizontally if they collide with other notes.  This is useful when
+typesetting many voices on one staff.  The identifier code(\shift) is
+defined to enable this.  If there are several voices, every voice must
+have a distinct value of this property or no shifting will occur.
+
+dit(code(dynamicDir)) Determines location of dynamic marks.  Set to
+code(\up) to print marks above the staff; set to code(\down) to print
+marks below the staff.
+
+dit(code(dynamicStyle)) Set the text style for dynamics.  
+
+dit(code(textStyle)) Set the text style for superscripts and
+subscripts.  See above for list of text styles.
+
+dit(code(textScriptPadding)) Determines the extra space added between
+super-/subscripted text and the closest staff line or note.
+
+dit(code(fontSize)) Can be used to select smaller font sizes for
+music.  The normal font size is 0, and the two smaller sizes are -1
+and -2.
+
+dit(code(abbrev)) Set length for tremolo to be used if no length is
+explicitly specified.
+
+dit(code(tupletDirection)) Determines the direction of triplets and 
+other tuplets.  Set to code(\down) to force them below the staff,
+code(\up) to force them above, or code(\free) to let LilyPond decide.
+
+dit(code(tupletVisibility)) Determines whether tuplets of notes are
+labelled.  Setting to 0 shows nothing; setting to 1 shows a number;
+setting to 2 shows a number and a bracket if there is no beam; setting
+to 3 shows a number, and if there is no beam it adds a bracket;
+setting to 4 shows both a number and a bracket unconditionally. The 
+code(pletoff) and code(pleton) identifiers set the property to 0 and 3, 
+respectively. 
+
+dit(code(markScriptPadding)) Determines the extra space added between
+the mark and the closest staff line or note.
+
+dit(code(markDirection)) Determines if marks should be printed above
+or below the staff. Set to code(\up) to print marks above the staff;
+set to code(\down) to print marks below the staff.
+
+dit(code(articulationScriptPadding)) Determines the extra space added 
+between articulation marks, such as staccato, tenuto, trill, up/down 
+bow or fermata, and the closest staff line or note.
+)
+
+subsubsubsect(Staff properties)
+
+description(
+
+dit(code(createInitdefaultClef)) Specify whether clefs are created on
+default?  (Doesn't seem to do anything.)
+
+dit(code(barNumberDirection)) Set to code(\up) or code(\down) to put
+bar numbers above or below the staff.  
+
+dit(code(barNumberHangOnClef)) Set to 1 to cause bar numbers to appear
+above or below the clef instead of on the bar line.
+
+dit(code(barNumberScriptPadding)) Sets extra space between the bar
+number and the bar it labels.
+
+dit(code(markHangOnClef)) Set to 1 to cause marks to appear by clefs
+instead of by bar lines.
+
+dit(code(marginDirection)) Set to code(\left) or code(\right) to
+specify location of marginal scripts.  
+
+dit(code(marginScriptPadding)) Specify extra space for marginal scripts.
+
+dit(code(forgetAccidentals)) Causes accidentals to be printed at every
+note instead of remembered for the duration of a measure.  
+
+dit(code(noResetKey)) Do not reset the key at the start of a measure.
+Accidentals will be printed only once and are in effect until
+overridden, possibly many measures later. 
+
+dit(code(staffLineLeading)) Specifies the distance (in points) between lines
+of the staff.  
+
+dit(code(postBreakPadding)) Extra space in points to be added after
+the clef, time signature and key signature on the staff.
+
+dit(code(barAtLineStart)) Set to 1 to produce a bar line after the
+clef at the start of each line (but not at the beginning of the
+music).  
+
+dit(code(voltaVisibility)) Set to 0 to suppress the printing
+of brackets over alternate endings specified by code(\alternative).
+
+dit(code(voltaSpannerDuration)) Set to an integer to control the size
+of the brackets printed by code(\alternative).  The integer specifies
+the number of whole notes duration to use for the brackets.  It seems
+to be rounded to the nearest measure.  This can be used to shrink the
+length of brackets in the situation where one alternative is very
+large.  It may have odd effects if the specified duration is longer
+than the music given in an code(\alternative).  
+
+dit(code(barNonAuto)) If set to 1 then bar lines will not be printed
+automatically; they must be explicitly created with code(\bar) keywords.
+Unlike with the code(\cadenza) keyword, measures are still counted.  Bar
+generation will resume according to that count if this property is set to
+zero.  
+
+dit(code(defaultClef)) Determines the default clef.  See code(\clef)
+keyword.
+
+dit(code(nuberOfStaffLines)) Sets the number of lines that the staff has.
+dit(code(barAlways)) If set to 1 a bar line is drawn after each note.
+
+dit(code(defaultBarType)) Sets the default type of bar line.  See
+code(\bar) keyword.
+
+dit(code(keyoctaviation)) If set to 1, then keys are the same in all
+octaves.  If set to 0 then the key signature for different octaves can
+be different and is specified independently: code(\keysignature bes
+fis').  The default value is 1.  Can be set to zero with
+code(\specialkey) or reset to 1 with code(\normalkey).
+
+dit(code(instrument) and code(instr)) If code(Staff_margin_engraver)
+is added to the Staff translator, then the code(instrument) property
+is used to label the first line of the staff and the code(instr)
+property is used to label subsequent lines.  If the
+code(midiInstrument) property is not set then code(instrument) is
+used to determine the instrument for MIDI output.
+COMMENT(This prints the instrument name on top of the staff lines.)
+
+dit(code(createKeyOnClefChange)) Set to a nonempty string if you want key
+signatures to be printed when the clef changes.  Set to the empty string (the
+default) if you do not want key signatures printed.
+
+
+dit(code(timeSignatureStyle)) Changes the default two-digit layout
+   for time signatures. The following values are recognized:
+   description(
+      dit(code(C)) 4/4 and 2/2 are typeset as C and struck C,
+      respectively. All other time signatures are written with two digits.
+      dit(code(old)) 2/2, 3/2, 3/4, 4/4, 6/4, 9/4, 6/8 and 9/8 are typeset 
+      with old-style mensuration marks. All other time signatures are 
+      written with two digits.
+      dit(code(1)) All time signatures are typeset with a single
+      digit, e.g. 3/2 is written as 3.
+      dit(code(C2/2), code(C4/4), code(old2/2), code(old3/2),
+      code(old3/4), code(old4/4), code(old6/4), code(old9/4), 
+      code(old6/8) or code(old9/8))Tells Lilypond to use a 
+      specific symbol as time signature.
+   )
+The different time signature characters are shown below with
+their names:
+mudela(center)(
+\score{
+  \notes\relative c'' {
+\property Voice.textStyle = typewriter
+\property Staff.timeSignatureStyle = "C2/2"
+\time 2/2; a2^"C2/2" a2 
+\property Staff.timeSignatureStyle = "C4/4"
+\time 2/2; a2^"C4/4" a2 
+\property Staff.timeSignatureStyle = "old2/2"
+\time 2/2; a2^"old2/2" a2 
+\property Staff.timeSignatureStyle = "old3/2"
+\time 2/2; a2^"old3/2" a2 
+\property Staff.timeSignatureStyle = "old4/4"
+\time 2/2; a2^"old4/4" a2 
+\property Staff.timeSignatureStyle = "old6/4"
+\time 2/2; a2^"old6/4" a2 
+\property Staff.timeSignatureStyle = "old9/4"
+\time 2/2; a2^"old9/4" a2 
+\property Staff.timeSignatureStyle = "old6/8"
+\time 2/2; a2^"old6/8" a2 
+\property Staff.timeSignatureStyle = "old9/8"
+\time 2/2; a2^"old9/8" a2 
+}
+   \paper{ linewidth= 4.5 \in; }
+}
+)
+
+dit(code(clefStyle)) Determines how clefs are typeset. When set to
+code(transparent), the clefs are not printed at all, when set to
+code(fullSizeChanges), clef changes in the middle of a line are
+typeset with a full size clef. By default, clef changes are typeset in
+smaller size.
+
+)
+   
+subsubsubsect(GrandStaff properties)
+
+description( 
+
+dit(code(alignmentReference)) Set to code(\center) for vertical
+alignment reference point to be in the center of the vertical group.
+Set to code(\up) to put the reference point at the top of the group. 
+
+dit(code(maxVerticalAlign)) Set the maximum vertical distance between
+staffs.
+
+dit(code(minVerticalAlign)) Set the minimum vertical distance between
+staffs.  
+
+)
+
+subsubsubsect(Score properties)
+
+description(
+
+dit(code(skipBars)) Set to 1 to skip the empty bars that are produced
+by multimeasure notes and rests.  These bars will not appear on the
+printed output.  Set to zero (the default) to expand multimeasure
+notes and rests into their full length, printing the appropriate
+number of empty bars so that synrchonization with other voices is
+preserved.  COMMENT(meaning of "skip" here seems to be different from
+the meaning used for the keyword \skip.)
+
+dit(code(beamquantisation)) Set to code(\none) for no quantization.
+Set to code(\normal) to quantize position and slope.  Set to
+code(\traditional) to avoid wedges.  These three settings are
+available via code(\beamposfree), code(\beamposnormal), and
+code(\beampostraditional).
+
+dit(code(beamslopedamping)) Set to code(\none) for undamped beams.
+Set to code(\normal) for damped beams.  Set to code(\infinity) for
+beams with zero slope.  The identifiers code(\beamslopeproportional),
+code(\beamslopedamped), and code(\beamslopezero) each set the
+corresponding value.
+
+dit(code(chordInversion)) Determines whether LilyPond should look for
+chord inversions when translating from notes to chord names.  Set to 1
+to find inversions.  The default is 0 which does not look for inversions.
+
+)
+
+
+
+sect(Pre-defined Identifiers)
+label(ident)
+
+Various identifiers are defined in the initialization files to
+provide shorthands for some settings.  
+
+description(
+dit(code(\aeolian)) Used as the second argument of the code(\key)
+keyword to get an aeolian mode. 
+dit(code(\break)) Force a line break in music by using a large
+argument for the keyword code(\penalty). 
+dit(code(\center)) Used for setting textalignment property.  Is set to 0.
+dit(code(\cr)) Start a crescendo.
+dit(code(\decr)) Start a decrescendo.
+dit(code(\dorian)) Used as the second argument of the code(\key)
+keyword to get a dorian mode.
+dit(code(\down)) Used for setting direction setting properties.  Is
+equal to -1.  
+dit(code(\f)) Print forte symbol on the preceeding note.
+dit(code(\ff)) Print fortissimo symbol on the preceeding note. 
+dit(code(\fff)) Print fortississimo symbol on preceeding note. 
+dit(code(\ffff)) Print fortissississimo symbol on preceeding note.
+dit(code(\fffff)) Print fffff symbol on preceeding note.
+dit(code(\ffffff)) Print ffffff symbol on preceeding note.
+dit(code(\fp)) Print fortepiano symbol on preceeding note. 
+dit(code(\free)) Used for setting direction setting properties.  Is
+equal to 0.  
+dit(code(\Gourlay)) Used for setting the paper variable
+code(castingalgorithm).  Is equal to 1.0.  
+dit(code(\infinity)) Used for setting the Score.beamslopedamping
+property.  Is actually equal to 10000.  
+dit(code(\ionian)) Used as the second argument of the code(\key)
+keyword to get an ionian mode. 
+dit(code(\left)) Used for setting textalignment property.  Is equal to -1.
+dit(code(\locrian)) Used as the second argument of the code(\key)
+keyword to get a locrian mode. 
+dit(code(\lydian)) Used as the second argument of the code(\key)
+keyword to get a lydian mode. 
+dit(code(\major)) Used as the second argument of the code(\key)
+keyword to get a major key.
+dit(code(\minor)) Used as the second argument of the code(\key)
+keyword to get a minor key.
+dit(code(\mixolydian)) Used as the second argument of the code(\key)
+keyword to get a mixolydian mode.
+dit(code(\mf)) Print mezzoforte symbol on preceeding note. 
+dit(code(\mp)) Print mezzopiano symbol on preceeding note. 
+dit(code(\nobreak)) Prevent a line break in music by using a large
+negative argument for the keyword code(\penalty). 
+dit(code(\none)) Used for setting Score.beamslopedamping and
+Score.beamquantisation properties.  Is equal to 0.
+dit(code(\normal)) Used for setting Score.beamslopedamping and
+Score.beamquantisation properties.  Is equal to 1.
+dit(code(\normalkey)) Select normal key signatures where each octave
+has the same key signature.  This sets the Staff.keyoctaviation property.
+dit(code(\p)) Print a piano symbol on preceeding note. 
+dit(code(\phrygian)) Used as the second argument of the code(\key)
+keyword to get a phrygian mode.
+dit(code(\pp)) Print pianissimo symbol on preceeding note. 
+dit(code(\ppp)) Print pianississimo symbol on preceeding note. 
+dit(code(\pppp)) Print pianissississimo symbol on preceeding note.
+dit(code(\ppppp)) Print ppppp symbol on preceeding note.
+dir(code(\pppppp)) Print pppppp symbol on preceeding note.
+dit(code(\rc)) Terminate a crescendo. 
+dit(code(\rced)) Terminate a decrescendo
+dit(code(\rfz)) Print a rinforzato symbol on preceeding note.
+dit(code(\right)) Used for setting textalignment property.  Is set to 1.
+dit(code(\sf)) Print a subito-forte symbol on preceeding note. 
+dit(code(\sff)) Print a subito-fortissimo symbol on preceeding note.
+dit(code(\sfz)) Print a sforzato symbol on preceeding note. 
+dit(code(\shiftoff)) Disable horizontal shifting of note heads that collide.  
+Sets the Voice.horizontalNoteShift property.
+dit(code(\shifton)) Enable note heads that collide with other note heads
+to be shifted horiztonally.  Sets the Voice.horizontalNoteShift property.
+dit(code(\slurboth)) Allow slurs to be above or below notes.  This
+sets the Voice.slurVerticalDirection property. 
+dit(code(\slurdown)) Force slurs to be below notes. This sets the
+Voice.slurVerticalDirection property. 
+dit(code(\slurup)) Force slurs to be above notes.  This sets the
+Voice.slurVerticalDirection property.  
+dit(code(\sp)) Print a subito-piano symbol on preceeding note.
+dit(code(\spp)) Print a subito-forte symbol on preceeding note.
+dit(code(\specialkey)) Allow keys signatures do differ in different
+octaves.  This sets the Staff.keyoctaviation property.  
+dit(code(\stemboth)) Allow stems, beams, and slurs to point either
+direction.  This sets the Voice.verticalDirection property. 
+dit(code(\stemdown)) Force stems, beams, and slurs to point down.
+This sets the Voice.verticalDirection property. 
+dit(code(\stemup)) Force stems, beams and slurs to point up.  This
+sets the Voice.verticalDirection property. 
+dit(code(\traditional)) Used for setting the 
+Score.beamquantisation property.  Is equal to 2.  
+dit(code(\up)) Used for setting various direction properties.  Is
+equal to 1. 
+dit(code(\voiceone)) Enter Voice context called code(one) and force stems down.
+(See code(\stemdown).)
+dit(code(\voicetwo)) Enter Voice context called code(two) and force stems
+up. (See code(\stemup).)
+dit(code(\voicethree)) Enter Voice context called code(three) and force stems
+up.  
+dit(code(\voicefour)) Enter Voice context called code(four), force stems down
+and turn on horizontal shifting.  (See code(\stemdown) and code(\shifton).)
+dit(code(\Wordwrap)) Used for setting the paper variable
+code(castingalgorithm).  Equal to 0.0.  
+)
+
+
+sect(Output)
+label(output)
+label(paper)
+
+The output produced by LilyPond is controlled by the code(\paper) and
+code(\midi) keywords.  These keywords appear in the code(\score) block
+to indicate that printed or musical output should be produced.  If
+neither keyword appears in a code(\score) block, then paper output is
+produced but MIDI output is not produced.  
+
+The contents of the code(\paper) and code(\midi) blocks can change the
+output in various ways.  These blocks can appear at the top level of a
+Mudela file to set default parameters for each type of output.  It is
+still necessary to explicitly specify the output type in the
+code(\score) blocks if you don't want the default behavior of
+producing only paper output.  
+
+The code(\paper) and code(\midi) blocks 
+may begin with an optional identifier reference.  No
+identifier references are allowed anywhere else in the block.  
+The code(\paper) block can contain the code(\shape) keyword; the
+code(\midi) block can contain the code(\tempo) keyword.  Both of them
+can contain code(\translator) keywords.  The code(\paper) block can
+also contain identifier assignments and parameter assignments.  Unlike
+at the top level, these assignments must be terminated by a semicolon.
+
+
+subsect(Paper variables)
+
+Warning: this section is outdated and inaccurate.  
+
+There are a large number of paper variables that are used to control
+details of the layout.  Usually you will not want to change these
+variables; they are set by default to vaules that depend on the font
+size in use.  The only way to find out what variables are supported is
+to search the source code for code(get_var).  Two variables that you
+may want to change are code(linewidth) and code(indent).
+
+In order to change the font size used for the output, many variables
+need to be changed.  Some identifiers and initialization files can
+simplify this process.  The default size is 20pt.  In order to select
+a different size, you must do two things.  At the top level, do
+code(\include "paper)var(SZ)code(.ly") where var(SZ) is the height of
+the staff in points.  Values presently allowed are 11, 13, 16, 20, and
+26.  This loads some definitions, but does not cause them to take
+effect.  In order to actually change the size, you must use one of the
+identifiers: code(\paper_eleven), code(\paper_thirteen),
+code(\paper_sixteen), code(\paper_twenty) or code(\paper_twentysix)
+inside a code(\paper) block.
+
+
+description(
+  dit(var(integer)) If an integer appears on the left side of an
+assignment then a code(\font) keyword must appear on the right
+side.  This defines a music font at a particular size.  See Voice
+property code(fontSize).
+
+dit(code(arithmetic_basicspace) and code(arithmetic_multiplier))
+The space taken by a note is determined by the formula 
+COMMENT(
+
+)verb(arithmetic_multiplier * ( c + log2 (time) ))COMMENT(
+
+) where code(time) is the amount of time a note occupies.  The value
+of code(c) is chosen such that the smallest space within a measure is
+arithmetic_basicspace.  The smallest space is the one following the
+shortest note in the measure.  Typically arithmetic_basicspace is set
+to the width of a quarter note head.
+
+dit(code(barsize)) Specify height of bars.  This value may need to be
+adjusted if you change the number of lines in the staff.
+dit(code(beam_dir_algorithm)) Specify algorithm for determining
+whether beams go up or down.  It is real valued.  If set to 2.0 then
+majority selection is used.  If set to 3.0, then mean selection is
+used based on the mean center distance.  If set to 4.0 then median
+selection is used, based on the median center distance.  
+dit(code(castingalgorithm)) 
+dit(code(crescendo_shorten))
+dit(code(forced_stem_shorten)) Stems that have been forced to go the
+unnatural direction are shortened by this amount.  Equal to
+dit(code(forced_stem_shorten0))
+dit(code(gourlay_energybound))
+dit(code(gourlay_maxmeasures)) Maximum number of measures per line
+when using Gourlay method.
+Decreasing this greatly reduces computation time.  Default value: 10.  
+dit(code(indent)) Sets the indentation of the first line of music.  
+dit(code(interbeam))
+dit(code(interbeam4))
+dit(code(interline))  The distance between two staff
+lines, calculated from the center of the lines.  
+dit(code(linewidth))  Sets the width of the lines.  If it is set to
+-1.0, then a single unjustified line is produced.  
+dit(code(notewidth)) Width of an average note head.  
+dit(code(output)) Specifies an alternate
+name for the TeX() output.  A file(.tex) extension will be added to
+the string you specify.
+dit(code(rulethickness)) Determines thickness of staff lines and bars. 
+dit(code(slur_clip_angle))
+dit(code(slur_clip_height))
+dit(code(slur_clip_ratio))
+dit(code(slur_height_limit)) Specifies the maximum height of slurs.
+Normally equal to staff_height.
+dit(code(slur_ratio)) Specifes the ratio of slur hight to slur width
+to aim for.  Default value is 0.3.  
+dit(code(slur_rc_factor))
+dit(code(slur_slope_damping)) Allows slurs to start and end at
+different heights ????  Default value is 0.5.
+dit(code(slur_thickness)) Specify slur thickness.  Equal to code(1.4 *
+\staffline) by default.  
+dit(code(slur_x_gap)) Horizontal space between note and slur.  Set to
+code(\interline / 5) by default.  
+dit(code(slur_x_minimum))
+dit(code(staffheight)) The height of the staff from the center of the
+bottom line to the center of the top line.  Equal to to code(4 * \interline).
+dit(code(stem_length)) Specify length of stems for notes in the staff
+that don't have beams.  
+dit(code(stemthickness)) Specifies the thickness of the stem lines.  
+dit(code(tie_slope_damping))
+dit(code(tie_x_minimum))
+)
+
+
+subsect(MIDI Instrument Names)
+label(midilist)
+
+The MIDI instrument name is set by the code(Staff.midiInstrument)
+property or, if that property is not set, the code(Staff.instrument)
+property.  The instrument name should be chosen from this list.  If
+string does not exactly match one from this list then LilyPond uses
+the default piano.
+
+COMMENT( acordina = accordion, tango accordian = concertina
+         distortion guitar = distorted guitar
+         orchestral strings = harp 
+         pan flute = wood flute? )
+
+verb("acoustic grand"               "contrabass"             "lead 7 (fifths)"
+"bright acoustic"              "tremolo strings"        "lead 8 (bass+lead)"
+"electric grand"               "pizzicato strings"      "pad 1 (new age)"
+"honky-tonk"                   "orchestral strings"     "pad 2 (warm)"
+"electric piano 1"             "timpani"                "pad 3 (polysynth)"
+"electric piano 2"             "string ensemble 1"      "pad 4 (choir)"
+"harpsichord"                  "string ensemble 2"      "pad 5 (bowed)"
+"clav"                         "synthstrings 1"         "pad 6 (metallic)"
+"celesta"                      "synthstrings 2"         "pad 7 (halo)"
+"glockenspiel"                 "choir aahs"             "pad 8 (sweep)"
+"music box"                    "voice oohs"             "fx 1 (rain)"
+"vibraphone"                   "synth voice"            "fx 2 (soundtrack)"
+"marimba"                      "orchestra hit"          "fx 3 (crystal)"
+"xylophone"                    "trumpet"                "fx 4 (atmosphere)"
+"tubular bells"                "trombone"               "fx 5 (brightness)"
+"dulcimer"                     "tuba"                   "fx 6 (goblins)"
+"drawbar organ"                "muted trumpet"          "fx 7 (echoes)"
+"percussive organ"             "french horn"            "fx 8 (sci-fi)"
+"rock organ"                   "brass section"          "sitar"
+"church organ"                 "synthbrass 1"           "banjo"
+"reed organ"                   "synthbrass 2"           "shamisen"
+"accordion"                    "soprano sax"            "koto"
+"harmonica"                    "alto sax"               "kalimba"
+"concertina"                   "tenor sax"              "bagpipe"
+"acoustic guitar (nylon)"      "baritone sax"           "fiddle"
+"acoustic guitar (steel)"      "oboe"                   "shanai"
+"electric guitar (jazz)"       "english horn"           "tinkle bell"
+"electric guitar (clean)"      "bassoon"                "agogo"
+"electric guitar (muted)"      "clarinet"               "steel drums"
+"overdriven guitar"            "piccolo"                "woodblock"
+"distorted guitar"             "flute"                  "taiko drum"
+"guitar harmonics"             "recorder"               "melodic tom"
+"acoustic bass"                "pan flute"              "synth drum"
+"electric bass (finger)"       "blown bottle"           "reverse cymbal"
+"electric bass (pick)"         "skakuhachi"             "guitar fret noise"
+"fretless bass"                "whistle"                "breath noise"
+"slap bass 1"                  "ocarina"                "seashore"
+"slap bass 2"                  "lead 1 (square)"        "bird tweet"
+"synth bass 1"                 "lead 2 (sawtooth)"      "telephone ring"
+"synth bass 2"                 "lead 3 (calliope)"      "helicopter"
+"violin"                       "lead 4 (chiff)"         "applause"
+"viola"                        "lead 5 (charang)"       "gunshot"
+"cello"                        "lead 6 (voice)")
+
+
+
+subsect(Translators)
+label(translators)
+
+The behavior of notation contexts is defined by the translators for
+those contexts.  The translator for a context specifies what notations
+are handled by the context, it specifies what other contexts the
+context can contain, and it sets property values for the context.  
+There are different translators for each type of output.  The
+translators for paper output are defined in file(engraver.ly).  The
+translators for MIDI output are defined in file(performer.ly).  
+
+The first thing that appears inside a code(\translator) definition is
+the type of the context being created.  This is specified with the
+code(\type) keyword: code(\type) var(typename)code(;).  After the type
+of the context is specified, property assignments, the code(\name)
+keyword and code(\consists), code(\accepts), and code(\remove)
+keywords can appear in any order.  The code(\name) keyword specifies
+the name of the context that is handled by the translator.  If the
+name is not specified, the translator won't do anything.  Each
+code(\accepts) keyword specifies what contexts can be contained inside
+this one.  The code(\consists) keywords specify which notations are
+handled by the context.  Each code(\consists) keyword specifies the
+name of an engraver (for paper ouput) or performer (for MIDI output)
+which handles a certain notation.  The code(\remove) keyword can be
+used to remove a performer or engraver from the translator.
+
+In the code(\paper) block, it is also possible to define translator
+identifiers.  Like other block identifiers, the identifier can only
+be used as the very first item of a translator.  In order to define
+such an identifier outside of code(\score), you must do
+verb(\paper{ foo=\translator{ ... }
+\score{
+  \notes{ ... }
+  \paper{ \translator{ \foo ... } }
+})
+
+Some All of the standard translators have predefined identifiers,  making
+it easy to redefine these contexts by adding or removing items. 
+The predefined identifiers are:  code(StaffContext),
+code(RhythmicStaffContext),  code(VoiceContext),  code(ScoreContext), code(ScoreWithNumbers)
+
+
+subsubsect(Paper Types and Engravers and Pre-defined Translators)
+
+Some pre-defined identifiers can simplify modification of translators.
+The pre-defined identifiers are:  
+description(
+dit(code(StaffContext)) Default Staff  context. 
+dit(code(RhythmicStaffContext)) Default RhythmicStaff  context. 
+dit(code(VoiceContext)) Default Voice  context.  
+dit(code(ScoreContext))  Default  Score context. 
+dit(code(ScoreWithNumbers)) Score  context with numbering at  the
+Score level.   
+dit(code(BarNumberingStaffContext)) Staff context with numbering  at
+the Staff level.  
+dit(code(HaraKiriStaffContext))  
+dit(code(OrchestralPartStaffContext))
+dit(code(OrchestralScoreContext))
+)
+Using these pre-defined values, you can remove  or add items to the
+translator verb(\paper{ \translator{ \StaffContext
+                     \remove Some_engraver;
+                     \consists Different_engraver;  }})
+      
+
+
+There are four types for paper translators:
+description(
+  dit(code(Engraver_group_engraver))
+  dit(code(Hara_kiri_line_group_engraver))
+  dit(code(Line_group_engraver_group))
+  dit(code(Score_engraver))  
+)
+COMMENT( The names of these types seem somewhat confusing. )
+
+The engravers for paper output are:
+
+description(
+dit(code(Abbreviation_beam_engraver))
+dit(code(Bar_engraver)) Engraves bar lines.  Normally in code(Staff) and
+code(RhythmicStaff).  
+dit(code(Bar_number_engraver)) Engrave bar numbers.  These numbers
+appear at the start of each line.  Not normally in any translator.  Can
+be added to code(Score) for Score-wide numbering or to code(Staff) for
+numbering on each staff.  
+
+dit(code(Beam_engraver)) Handles beam requests by engraving beams.  Normally
+appears in the code(Voice) translator.  If omitted, then notes will be printed
+with flags instead of beams.
+
+dit(code(Beam_req_swallow_translator)) Swallows beam requests.  In
+code(LyricVoice).  
+dit(code(Chord_name_engraver)) Engraves chord names.  Normally in
+code(ChordNameVoice) 
+dit(code(Clef_engraver)) Engraves the clef symbol.  Normally in code(Staff).
+dit(code(Collision_engraver))
+dit(code(Dot_column_engraver)) Engraves dots on dotted notes shifted to the
+right of the note.  Normally in code(Voice).  If omitted, then dots appear on
+top of the notes.  
+dit(code(Dynamic_engraver)) Engraves dynamics symbols.  Normally in code(Voice).
+dit(code(Font_size_engraver))
+dit(code(Key_engraver)) Engraves the key signature.  Normally in code(Staff).
+dit(code(Local_key_engraver))
+dit(code(Lyric_engraver)) Engraves lyrics.  Normally in code(LyricVoice).
+dit(code(Multi_measure_rest_engraver)) Engraves multi-measure rests that are
+produced with code(R).  Normally in code(Voice).
+dit(code(Piano_bar_engraver))
+dit(code(Pitch_squash_engraver)) Treat all pitches as middle C.  Used in
+code(RhythmicStaff).  Note that the notes move, but the locations of
+accidentals stay the same. 
+dit(code(Priority_horizontal_align_engraver))
+dit(code(Repeat_engraver)) Handles repeats? In code(Staff) and 
+   code(RhythmicStaff).
+dit(code(Rest_collision_engraver)) Handles collisions of rests. In code(Staff).
+dit(code(Rest_engraver)) Engraves rests.  Normally in code(Voice).
+dit(code(Rhythmic_column_engraver))
+dit(code(Score_priority_engraver))
+dit(code(Script_engraver)) Handles note ornaments generated by code(\script).
+Normally in code(Voice).  
+dit(code(Separating_line_group_engraver))
+dit(code(Skip_req_swallow_translator))
+dit(code(Slur_engraver)) Engraves slurs.  Normally in code(Voice).
+dit(code(Span_bar_engraver)) Engraves lines across multiple staffs.  Normally
+in code(Staffgroup) and code(GrandStaff).  Removing this from code(StaffGroup)
+gives the definition of code(ChoirStaff).  
+dit(code(Span_score_bar_engraver))
+dit(code(Staff_group_bar_engraver))
+dit(code(Staff_margin_engraver)) Prints the name of the instrument
+(specified by code(Staff.instrument) and code(Staff.instr)) at the
+left of the staff.  
+dit(code(Staff_sym_engraver))
+dit(code(Stem_engraver)) Engraves stems.  Normally in code(Voice).
+dit(code(Ties_engraver)) Engraves ties.  Normally in code(Voice).
+dit(code(Time_signature_engraver)) Engraves the time signature.  Normally in
+code(Staff) and code(RhythmicStaff).
+dit(code(Timing_engraver)) Responsible for synchronizing timing information
+from staffs.  Normally in code(Score).  In order to create polyrhythmic music,
+this engraver should be removed from code(Score) and placed in code(Staff).
+dit(code(Tuplet_engraver)) Engraves tuplet brackets?  In code(Staff).
+dit(code(Vertical_align_engraver)) 
+)
+
+
+subsubsect(MIDI Types and Performers)
+
+The types available for  MIDI translators are:
+description(
+dit(code(Performer_group_performer))
+dit(code(Score_performer))
+dit(code(Staff_performer))
+)
+
+The performers for MIDI translators are:
+description(
+dit(code(Key_performer))
+dit(code(Time_signature_performer))
+dit(code(Note_performer))
+dit(code(Lyric_performer))
+dit(code(Swallow_performer))
+)
+
diff --git a/NEWS b/NEWS
index 8b17eca67967f6679a608a0753e993e3a143ddeb..fd4812c8714da373c393efbed12dd39f493966db 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,11 @@
---- ../lilypond-1.1.52.mb1/NEWS        Thu Jul  1 00:53:02 1999
+--- ../lilypond-1.1.52.gp1/NEWS        Fri Jul  2 21:08:04 1999
+++ b/NEWS      Mon Jul  5 15:05:33 1999
+@@ -1,3 +1,5 @@
+pl 52.gp2
+       - hyphens between syllables of lyrics:
+ pl 52.gp1
+       - bf: make doc++ corrected to only include *.h and *.hh files.
+ ************--- ../lilypond-1.1.52.mb1/NEWS   Thu Jul  1 00:53:02 1999
 ++ b/NEWS      Sat Jul  3 23:11:12 1999
 @@ -1,3 +1,8 @@
 pl 52.mb2
diff --git a/VERSION b/VERSION
index c0bc37e1b05fd2d1c88f5539b137d84094120f4b..a69ab678e97eab1ac8e05586dd19a9774469d8a5 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=1
 PATCH_LEVEL=52
-MY_PATCH_LEVEL=mb2
+MY_PATCH_LEVEL=gp2
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
diff --git a/input/test/hyphen.ly b/input/test/hyphen.ly
new file mode 100644 (file)
index 0000000..149b02d
--- /dev/null
@@ -0,0 +1,11 @@
+\score{
+       <
+       \context Staff \notes { c' () c' () c' c' }
+       \context Lyrics \context LyricVoice \lyrics { bla -- alb xxx -- yyy }
+       >
+}
+
+\version "1.0.21"; 
+
+
+
diff --git a/lily/hyphen-engraver.cc b/lily/hyphen-engraver.cc
new file mode 100644 (file)
index 0000000..013c962
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+  hyphen-engraver.cc -- implement Hyphen_engraver
+
+  (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+*/
+
+#include "proto.hh"
+#include "musical-request.hh"
+#include "hyphen-engraver.hh"
+#include "hyphen-spanner.hh"
+#include "score-column.hh"
+#include "text-item.hh"
+#include "extender-engraver.hh"
+
+ADD_THIS_TRANSLATOR (Hyphen_engraver);
+
+Hyphen_engraver::Hyphen_engraver ()
+{
+  hyphen_spanner_p_ = 0;
+  req_l_ = 0;
+}
+
+void
+Hyphen_engraver::acknowledge_element (Score_element_info i)
+{
+  if (Text_item* t = dynamic_cast<Text_item*> (i.elem_l_))
+    {
+      Rhythmic_req * rh = dynamic_cast<Rhythmic_req*>  (i.req_l_);
+      if (!rh)
+       return;
+
+      now_lyrics_.push (Text_lyric_tuple (t, rh, now_mom () + rh->length_mom ()));
+      /*
+       UGH.  What do we do in case of multiple alternatives? 
+       */
+      if (hyphen_spanner_p_
+         && !hyphen_spanner_p_->spanned_drul_[RIGHT]
+           )
+         {
+           hyphen_spanner_p_->set_textitem (RIGHT, t);
+         }
+    }
+}
+
+
+bool
+Hyphen_engraver::do_try_music (Music* r)
+{
+  if (Hyphen_req* p = dynamic_cast <Hyphen_req *> (r))
+    {
+      if (req_l_)
+       return false;
+
+      req_l_ = p;
+      return true;
+    }
+  return false;
+}
+
+void
+Hyphen_engraver::do_removal_processing ()
+{
+  if (hyphen_spanner_p_)
+    {
+      req_l_->warning (_ ("unterminated hyphen"));
+      hyphen_spanner_p_->set_bounds(RIGHT, get_staff_info ().command_pcol_l ());
+    }
+}
+
+void
+Hyphen_engraver::do_process_requests ()
+{
+  Array<Text_lyric_tuple> stopped_texts;
+  Moment now = now_mom ();
+
+  stopped_texts.clear ();
+  while (past_lyrics_pq_.size ()
+        && past_lyrics_pq_.front ().end_ == now)
+    stopped_texts.push (past_lyrics_pq_.get ());
+
+  if (req_l_)
+    {
+      if (!stopped_texts.size ())
+       {
+         req_l_->warning ("Nothing to connect hyphen to on the left. Ignoring hyphen request");
+         return;
+       }
+      
+      hyphen_spanner_p_ = new Hyphen_spanner;
+      hyphen_spanner_p_->set_textitem  (LEFT, stopped_texts[0].text_l_);
+      announce_element (Score_element_info (hyphen_spanner_p_, req_l_));
+    }
+}
+
+
+void
+Hyphen_engraver::do_pre_move_processing ()
+{
+  for (int i=0; i < now_lyrics_.size (); i++)
+    {
+      past_lyrics_pq_.insert (now_lyrics_[i]);
+    }
+  now_lyrics_.clear ();
+
+  if (hyphen_spanner_p_)
+    {
+      typeset_element (hyphen_spanner_p_);
+      hyphen_spanner_p_ = 0;
+    }
+}
+void
+Hyphen_engraver::do_post_move_processing ()
+{
+  Moment now = now_mom ();
+  while (past_lyrics_pq_.size () && past_lyrics_pq_.front ().end_ < now)
+    past_lyrics_pq_.delmin ();
+
+  req_l_ =0;
+}
+
+
diff --git a/lily/hyphen-spanner.cc b/lily/hyphen-spanner.cc
new file mode 100644 (file)
index 0000000..8636dbb
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+  hyphen-spanner.cc -- implement Hyphen_spanner
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+
+  (adapted from extender-spanner)
+*/
+
+/*
+  TODO: too complicated implementation.  Why the dx_drul?.
+ */
+
+#include <math.h>
+#include "box.hh"
+#include "debug.hh"
+#include "lookup.hh"
+#include "molecule.hh"
+#include "p-col.hh"
+#include "paper-def.hh"
+#include "hyphen-spanner.hh"
+
+Hyphen_spanner::Hyphen_spanner ()
+  : Directional_spanner ()
+{
+  dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0;
+}
+
+// UGH - is this even used?
+Offset
+Hyphen_spanner::center () const
+{
+  Real dx = extent (X_AXIS).length ();
+
+  return Offset (dx / 2, 0);
+}
+
+Molecule*
+Hyphen_spanner::do_brew_molecule_p () const
+{
+  Molecule* mol_p = new Molecule;
+
+  Real w = extent (X_AXIS).length ();
+
+  w += (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT]);
+
+  Real th = paper_l ()->get_realvar (hyphen_thickness_scm_sym);
+  Real h = paper_l ()->get_realvar (hyphen_height_scm_sym);
+
+  // UGH. First try: just make the hyphen take 1/3 of the available space  
+  // for length, use a geometric mean of the available space and some minimum
+  Real l = paper_l ()->get_realvar (hyphen_minimum_length_scm_sym);
+  if(l < w)
+    l = sqrt(l*w);
+  Molecule a = lookup_l ()->filledbox ( Box (Interval ((w-l)/2,(w+l)/2), Interval (h,h+th)));
+  a.translate (Offset (dx_f_drul_[LEFT], 0));
+
+  mol_p->add_molecule (a);
+
+  return mol_p;
+}
+
+Interval
+Hyphen_spanner::do_height () const
+{
+  return Interval (0,0);
+}
+
+void
+Hyphen_spanner::do_post_processing ()
+{
+  // UGH
+  Real nw_f = paper_l ()->note_width () * 0.8;
+
+  Direction d = LEFT;
+  do
+    {
+      Item* t = spanned_drul_[d]
+       ? spanned_drul_[d] : spanned_drul_[(Direction)-d];
+      if (d == LEFT)
+        dx_f_drul_[d] += t->extent (X_AXIS).length ();
+      else
+       dx_f_drul_[d] -= d * nw_f / 2;
+    }
+  while (flip(&d) != LEFT);
+}
+
+  
+void
+Hyphen_spanner::set_textitem (Direction d, Item* textitem_l)
+{
+  set_bounds (d, textitem_l);
+  add_dependency (textitem_l);
+}
+
diff --git a/lily/include/hyphen-engraver.hh b/lily/include/hyphen-engraver.hh
new file mode 100644 (file)
index 0000000..6ab2eb5
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+  hyphen-engraver.hh -- declare Hyphen_engraver
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+*/
+
+#ifndef HYPHEN_ENGRAVER_HH
+#define HYPHEN_ENGRAVER_HH
+
+#include "engraver.hh"
+#include "drul-array.hh"
+#include "hyphen-spanner.hh"
+#include "pqueue.hh"
+#include "extender-engraver.hh"
+
+
+/**
+  Generate an centred hyphen.  Should make a Hyphen_spanner that typesets
+  a nice centred hyphen of varying length depending on the gap between syllables.
+
+  We remember all Text_items that come across, and store their
+  termination times. When we get a request, we create the spanner, and
+  attach the left point to the finished lyrics, and the right point to
+  any lyrics we receive by then.
+*/
+class Hyphen_engraver : public Engraver
+{
+  PQueue<Text_lyric_tuple> past_lyrics_pq_;
+  Array<Text_lyric_tuple> now_lyrics_;
+  Array<Text_lyric_tuple> stopped_lyrics_;  
+  
+  Hyphen_req* req_l_;
+  Hyphen_spanner* hyphen_spanner_p_;
+
+  
+public:
+  Hyphen_engraver ();
+  VIRTUAL_COPY_CONS (Translator);
+
+protected:
+  virtual void acknowledge_element (Score_element_info);
+  virtual void do_removal_processing();
+  virtual void do_process_requests();
+  virtual bool do_try_music (Music*);
+  virtual void do_pre_move_processing();
+  virtual void do_post_move_processing ();
+private:
+
+};
+
+#endif // HYPHEN_ENGRAVER_HH
diff --git a/lily/include/hyphen-spanner.hh b/lily/include/hyphen-spanner.hh
new file mode 100644 (file)
index 0000000..e131625
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+  hyphen-spanner.hh -- part of GNU LilyPond
+
+  (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+*/
+
+#ifndef HYPHEN_SPANNER_HH
+#define HYPHEN_SPANNER_HH
+
+#include "directional-spanner.hh"
+
+/** 
+  centred hyphen 
+
+  A centred hyphen is a simple line between lyrics used to
+  divide syllables.
+
+  The length of the hyphen line should stretch based on the
+  size of the gap between syllables.
+  */
+class Hyphen_spanner : public Directional_spanner
+{
+public:
+Hyphen_spanner ();
+  Offset center () const;  
+  void set_textitem (Direction, Item*);
+
+protected:
+  virtual Molecule* do_brew_molecule_p () const;
+  Interval do_height () const;
+
+  void do_post_processing ();
+  VIRTUAL_COPY_CONS (Score_element);
+
+  Drul_array<Real> dx_f_drul_;
+};
+
+#endif // HYPHEN_SPANNER_HH
+
index 97d9d579702bdf3ddc4c30279e4dd1e40ad3b23b..94f9be43dc529bf8f292ac369144d4089b9db43b 100644 (file)
@@ -57,6 +57,7 @@ struct Change_iterator;
 struct Change_translator;
 struct Chord;
 struct Chord_name_engraver;
+struct CHyphen_req;
 struct Clef_change_req;
 struct Clef_item;
 struct Clef_engraver;
index 07890e4c105ea77fdaa63bf9bda1f9152a4f7616..444da6f181f7532ce05bae45e87bcd8883a10e51 100644 (file)
@@ -35,6 +35,9 @@ DECLARE_LY_SYMBOL(extra_space);
 DECLARE_LY_SYMBOL(dir_forced);
 DECLARE_LY_SYMBOL(dir_list);
 DECLARE_LY_SYMBOL(extender_height);
+DECLARE_LY_SYMBOL(hyphen_thickness);
+DECLARE_LY_SYMBOL(hyphen_height);
+DECLARE_LY_SYMBOL(hyphen_minimum_length);
 DECLARE_LY_SYMBOL(filledbox);
 DECLARE_LY_SYMBOL(fontsize);
 DECLARE_LY_SYMBOL(grace);
diff --git a/lily/include/ly-symbols.hh.orig b/lily/include/ly-symbols.hh.orig
new file mode 100644 (file)
index 0000000..07890e4
--- /dev/null
@@ -0,0 +1,76 @@
+/*   
+  ly-symbols.hh -- declare SCM symbols.
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#ifndef LY_SYMBOLS_HH
+#define LY_SYMBOLS_HH
+
+#include "lily-guile.hh"
+
+#ifndef DECLARE_LY_SYMBOL
+#define DECLARE_LY_SYMBOL(a) extern SCM a ## _scm_sym
+#endif
+
+DECLARE_LY_SYMBOL(alt_symbol);
+DECLARE_LY_SYMBOL(at_line_start);
+DECLARE_LY_SYMBOL(beam);
+DECLARE_LY_SYMBOL(beam_thickness);
+DECLARE_LY_SYMBOL(beam_dir);
+DECLARE_LY_SYMBOL(beam_gap);
+DECLARE_LY_SYMBOL(bracket);
+DECLARE_LY_SYMBOL(break_helper_only);
+DECLARE_LY_SYMBOL(break_priority);
+DECLARE_LY_SYMBOL(breakable);
+DECLARE_LY_SYMBOL(char);
+DECLARE_LY_SYMBOL(change);
+DECLARE_LY_SYMBOL(damping);
+DECLARE_LY_SYMBOL(dashed);
+DECLARE_LY_SYMBOL(extremal);
+DECLARE_LY_SYMBOL(extra_space);
+DECLARE_LY_SYMBOL(dir_forced);
+DECLARE_LY_SYMBOL(dir_list);
+DECLARE_LY_SYMBOL(extender_height);
+DECLARE_LY_SYMBOL(filledbox);
+DECLARE_LY_SYMBOL(fontsize);
+DECLARE_LY_SYMBOL(grace);
+DECLARE_LY_SYMBOL(header);
+DECLARE_LY_SYMBOL(horizontal_shift);
+DECLARE_LY_SYMBOL(interbeam);
+DECLARE_LY_SYMBOL(interbeam4);
+DECLARE_LY_SYMBOL(interline);
+DECLARE_LY_SYMBOL(length);
+DECLARE_LY_SYMBOL(linewidth);
+DECLARE_LY_SYMBOL(minimum_space);
+DECLARE_LY_SYMBOL(molecule);
+DECLARE_LY_SYMBOL(notewidth);
+DECLARE_LY_SYMBOL(non_default);
+DECLARE_LY_SYMBOL(octave_dir);
+DECLARE_LY_SYMBOL(origin);
+DECLARE_LY_SYMBOL(output);
+DECLARE_LY_SYMBOL(padding);
+DECLARE_LY_SYMBOL(pianobrace);
+DECLARE_LY_SYMBOL(placebox);
+DECLARE_LY_SYMBOL(rulesym);
+DECLARE_LY_SYMBOL(rulethickness);
+DECLARE_LY_SYMBOL(script_priority);
+DECLARE_LY_SYMBOL(staffheight);
+DECLARE_LY_SYMBOL(style);
+DECLARE_LY_SYMBOL(text);
+DECLARE_LY_SYMBOL(transparent);
+DECLARE_LY_SYMBOL(tuplet);
+DECLARE_LY_SYMBOL(tuplet_thick);
+DECLARE_LY_SYMBOL(tuplet_visibility);
+DECLARE_LY_SYMBOL(visibility_lambda);
+DECLARE_LY_SYMBOL(volta);
+DECLARE_LY_SYMBOL(void);
+DECLARE_LY_SYMBOL(volta_thick);
+
+
+
+#endif /* LY_SYMBOLS_HH */
+
index 2c220138a9c384e636d31e17a40f1ee6e5612191..88d5f6fbcee88c9fd5c97df69c36a7a470ff8370 100644 (file)
@@ -145,4 +145,10 @@ public:
   VIRTUAL_COPY_CONS(Music);
 };
 
+/// a centred hyphen
+class Hyphen_req : public Request  {
+public:
+  VIRTUAL_COPY_CONS(Music);
+};
+
 #endif // MUSICALREQUESTS_HH
diff --git a/lily/include/musical-request.hh.orig b/lily/include/musical-request.hh.orig
new file mode 100644 (file)
index 0000000..2c22013
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+  musical-request.hh -- declare Musical requests
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+
+#ifndef MUSICALREQUESTS_HH
+#define MUSICALREQUESTS_HH
+
+#include "lily-proto.hh"
+#include "request.hh"
+#include "duration.hh"
+#include "musical-pitch.hh"
+
+
+/** a request with a duration.
+  This request is used only used as a base class.
+ */
+class Rhythmic_req  : public virtual Request  {
+public:
+  Duration duration_;
+  virtual void do_print () const;
+
+  bool do_equal_b (Request*) const;
+  void compress (Moment);
+  virtual Moment length_mom () const;
+  static int compare (Rhythmic_req const&,Rhythmic_req const&);
+  VIRTUAL_COPY_CONS(Music);
+};
+
+class Skip_req  : public Rhythmic_req  {
+public:
+  VIRTUAL_COPY_CONS(Music);
+};
+
+
+struct Tremolo_req : public Request {
+  VIRTUAL_COPY_CONS (Music);
+  Tremolo_req ();
+  int type_i_;
+  virtual void do_print () const;
+};
+
+
+/** a syllable  or lyric is a string with rhythm.
+  */
+class Lyric_req  : public  Rhythmic_req  {
+public:
+  virtual void do_print () const;
+  String text_str_;
+  VIRTUAL_COPY_CONS(Music);
+};
+
+
+class Articulation_req : public Script_req
+{
+public:
+  String articulation_str_;
+protected:
+  virtual bool do_equal_b (Request*) const;
+  virtual void do_print () const;
+  VIRTUAL_COPY_CONS(Music);
+};
+
+class Text_script_req : public Script_req {
+public:
+  String text_str_;
+
+  // should be generic property of some kind.. 
+  String style_str_;
+protected:
+  VIRTUAL_COPY_CONS(Music);
+  virtual bool do_equal_b (Request*)const;
+  virtual void do_print () const;
+};
+
+
+/// request which has some kind of pitch
+struct Melodic_req :virtual Request
+{
+  Musical_pitch pitch_;
+
+  static int compare (Melodic_req const&,Melodic_req const&);
+  
+protected:
+  /// transpose. #delta# is relative to central c.
+  virtual void transpose (Musical_pitch delta);
+  virtual bool do_equal_b (Request*) const;
+  virtual void do_print () const;
+  VIRTUAL_COPY_CONS(Music);
+};
+
+/// specify tonic of a chord
+struct Tonic_req : public Melodic_req
+{
+  VIRTUAL_COPY_CONS(Music);
+};
+
+/// Put a note of specified type, height, and with accidental on the staff.
+class Note_req  : public Rhythmic_req, virtual public Melodic_req  {
+public:
+    
+  /// force/supress printing of accidental.
+  bool forceacc_b_;
+  /// Cautionary, i.e. parenthesized accidental.
+  bool cautionary_b_;
+  Note_req();
+protected:
+  virtual void do_print () const;
+  bool do_equal_b (Request*) const;
+  VIRTUAL_COPY_CONS(Music);
+};
+
+/**
+Put a rest on the staff. Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded.
+*/
+class Rest_req : public Rhythmic_req {
+public:
+  VIRTUAL_COPY_CONS(Music);
+};
+
+/**
+ Part: typeset a measure with the number of measures rest
+ Score: typeset all individual measures as full rests
+ */
+class Multi_measure_rest_req : public Rhythmic_req  {
+public:
+  VIRTUAL_COPY_CONS(Music);
+};
+
+/**
+ Typeset a repetition sign in each bar.
+ */
+class Repetitions_req : public Rhythmic_req  {
+public:
+  VIRTUAL_COPY_CONS(Music);
+};
+
+/// an extender line
+class Extender_req : public Request  {
+public:
+  VIRTUAL_COPY_CONS(Music);
+};
+
+#endif // MUSICALREQUESTS_HH
index e9a0c10371b4a4058317ea1056693b3e0dee2d5c..8c340af25c94a23ec9ccfd29339a1e0d57d9e851 100644 (file)
@@ -93,7 +93,7 @@ NOTECOMMAND   \\{A}+
 LYRICS         ({AA}|{TEX})[^0-9 \t\n\f]*
 ESCAPED                [nt\\'"]
 EXTENDER       __
-
+HYPHEN         --
 %%
 
 
@@ -267,6 +267,8 @@ EXTENDER    __
                String s (YYText ()); 
                if (s == "__")
                        return yylval.i = EXTENDER;
+               if (s == "--")
+                       return yylval.i = HYPHEN;
                int i = 0;
                        while ((i=s.index_i ("_")) != -1) // change word binding "_" to " "
                        *(s.ch_l () + i) = ' ';
index 78815d1cd2af7aca5b5e289f379cc77e9e870d2d..5af4fb7ed8cebbde4307005d81bc6281f667b216 100644 (file)
@@ -143,6 +143,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %token CADENZA
 %token CHORDMODIFIERS
 %token CHORDS
+%token HYPHEN
 %token CLEF
 %token CM_T
 %token CONSISTS
@@ -253,6 +254,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %type <request>        post_request 
 %type <request> command_req verbose_command_req
 %type <request>        extender_req
+%type <request> hyphen_req
 %type <string> string
 %type <score>  score_block score_body
 %type <intarr> shape_array
@@ -910,6 +912,9 @@ abbrev_command_req:
        extender_req {
                $$ = $1;
        }
+       | hyphen_req {
+               $$ = $1;
+       }
        | '|'                           {
                $$ = new Barcheck_req;
        }
@@ -1175,6 +1180,14 @@ extender_req:
        }
        ;
 
+hyphen_req:
+       HYPHEN {
+               if (!THIS->lexer_p_->lyric_state_b ())
+                       THIS->parser_error (_ ("have to be in Lyric mode for lyrics"));
+               $$ = new Hyphen_req;
+       }
+       ;
+
 close_request:
        close_request_parens {
                $$ = $1;
diff --git a/lily/parser.yy.orig b/lily/parser.yy.orig
new file mode 100644 (file)
index 0000000..78815d1
--- /dev/null
@@ -0,0 +1,1594 @@
+%{ // -*-Fundamental-*-
+
+/*
+  parser.yy -- Bison/C++ parser for mudela
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+           Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+/*
+       Ambiguities:
+
+       * \alternative
+
+       * use of '-' in various places
+
+*/
+
+
+#include <iostream.h>
+#include "lily-guile.hh"
+#include "notename-table.hh"
+#include "scalar.hh"
+#include "translation-property.hh"
+#include "lookup.hh"
+#include "misc.hh"
+#include "my-lily-lexer.hh"
+#include "paper-def.hh"
+#include "midi-def.hh"
+#include "main.hh"
+#include "file-path.hh"
+#include "keyword.hh"
+#include "debug.hh"
+#include "parseconstruct.hh"
+#include "dimensions.hh"
+#include "identifier.hh"
+#include "command-request.hh"
+#include "musical-request.hh"
+#include "my-lily-parser.hh"
+#include "context-specced-music.hh"
+#include "translator-group.hh"
+#include "score.hh"
+#include "music-list.hh"
+#include "duration-convert.hh"
+#include "change-translator.hh"
+#include "file-results.hh"
+#include "mudela-version.hh"
+#include "scope.hh"
+#include "relative-music.hh"
+#include "transposed-music.hh"
+#include "time-scaled-music.hh"
+#include "new-repeated-music.hh"
+#include "version.hh"
+#include "grace-music.hh"
+
+// mmm
+Mudela_version oldest_version ("1.0.20");
+Mudela_version version ( MAJOR_VERSION "." MINOR_VERSION "." PATCH_LEVEL );
+
+
+void
+print_mudela_versions (ostream &os)
+{
+  os << "Mudela versions: oldest  " << oldest_version.str () << " current " << version.str () <<endl;
+}
+// needed for bison.simple's malloc() and free()
+#include <malloc.h>
+
+#ifndef NDEBUG
+#define YYDEBUG 1
+#endif
+
+#define YYERROR_VERBOSE 1
+
+#define YYPARSE_PARAM my_lily_parser_l
+#define YYLEX_PARAM my_lily_parser_l
+#define THIS ((My_lily_parser *) my_lily_parser_l)
+
+#define yyerror THIS->parser_error
+#define ARRAY_SIZE(a,s)   if (a.size () != s) THIS->parser_error (_f("expecting %d arguments", s))
+
+%}
+
+
+%union {
+    Array<Interval>* intarr;
+    Array<Musical_pitch> *pitch_arr;
+    Link_array<Request> *reqvec;
+    Array<String> * strvec;
+    Array<int> *intvec;
+    Notename_table *chordmodifiertab;
+    Duration *duration;
+    Identifier *id;
+    Music *music;
+    Music_list *music_list;
+    Score *score;
+    Scope *scope;
+    Interval *interval;
+    Musical_req* musreq;
+    Music_output_def * outputdef;
+    Musical_pitch * pitch;
+    Midi_def* midi;
+    Moment *moment;
+    Notename_table *notenametab;
+    Paper_def *paper;
+    Real real;
+    Request * request;
+    Scalar *scalar;
+
+    String *string;
+    Tempo_req *tempo;
+    Translator* trans;
+    char c;
+    int i;
+    int ii[10];
+}
+%{
+
+int
+yylex (YYSTYPE *s,  void * v_l)
+{
+       My_lily_parser   *pars_l = (My_lily_parser*) v_l;
+       My_lily_lexer * lex_l = pars_l->lexer_p_;
+
+       lex_l->lexval_l = (void*) s;
+       return lex_l->yylex ();
+}
+
+
+%}
+
+%pure_parser
+
+/* tokens which are not keywords */
+
+%token TEXTSCRIPT
+%token ACCEPTS
+%token ALTERNATIVE
+%token BAR
+%token BREATHE
+%token CADENZA
+%token CHORDMODIFIERS
+%token CHORDS
+%token CLEF
+%token CM_T
+%token CONSISTS
+%token CONSISTSEND
+%token DURATION
+%token EXTENDER
+%token FONT
+%token GROUPING
+%token GRACE
+%token HEADER
+%token IN_T
+%token KEY
+%token KEYSIGNATURE
+%token LYRICS
+%token MARK
+%token MEASURES
+%token MIDI
+%token MM_T
+%token MUSICAL_PITCH
+%token NAME
+%token NOTENAMES
+%token NOTES
+%token PAPER
+%token PARTIAL
+%token PENALTY
+%token PROPERTY
+%token PT_T
+%token RELATIVE
+%token REMOVE
+%token REPEAT
+%token REPETITIONS
+%token SCM_T
+%token SCMFILE
+%token SCORE
+%token SCRIPT
+%token SHAPE
+%token SKIP
+%token SPANREQUEST
+%token TEMPO
+%token TIME_T
+%token TIMES
+%token TRANSLATOR
+%token TRANSPOSE
+%token TYPE
+%token CONTEXT
+%token VERSION
+
+/* escaped */
+%token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR
+
+%type <i>      dots exclamations questions
+%token <i>     DIGIT
+%token <pitch> NOTENAME_PITCH
+%token <pitch> TONICNAME_PITCH
+%token <pitch> CHORDMODIFIER_PITCH
+%token <id>    DURATION_IDENTIFIER
+%token <id>    IDENTIFIER
+%token <id>    NOTENAME_TABLE_IDENTIFIER
+%token <id>    MUSIC_IDENTIFIER
+%token <id>    REQUEST_IDENTIFIER
+%token <id>    REAL_IDENTIFIER
+%token <id>    STRING_IDENTIFIER
+%token <id>    TRANS_IDENTIFIER
+%token <id>    INT_IDENTIFIER
+%token <id>    SCORE_IDENTIFIER
+%token <id>    MIDI_IDENTIFIER
+%token <id>    PAPER_IDENTIFIER
+%token <real>  REAL
+%token <string>        DURATION RESTNAME
+%token <string>        STRING
+%token <i>     UNSIGNED
+
+
+%type <outputdef> output_def
+%type <scope>  mudela_header mudela_header_body
+%type <request>        open_request_parens close_request_parens open_request close_request
+%type <request> request_with_dir request_that_take_dir verbose_request
+%type <i>      sub_quotes sup_quotes
+%type <music>  simple_element  request_chord command_element Simple_music  Composite_music 
+%type <music>  Alternative_music Repeated_music
+%type <i>      abbrev_type
+%type <i>      int unsigned
+%type <i>      script_dir
+%type <i>      optional_modality
+%type <id>     identifier_init  
+%type <duration> steno_duration notemode_duration
+%type <duration> entered_notemode_duration explicit_duration
+%type <intvec> intastint_list int_list
+%type <reqvec>  pre_requests post_requests
+%type <request> gen_text_def
+%type <pitch>   explicit_musical_pitch steno_musical_pitch musical_pitch absolute_musical_pitch
+%type <pitch>   steno_tonic_pitch
+
+%type <pitch_arr>      pitch_list
+%type <music>  chord notemode_chord
+%type <pitch_arr>      chord_additions chord_subtractions chord_notes
+%type <pitch>  chord_addsub chord_note chord_inversion notemode_chord_inversion
+%type <midi>   midi_block midi_body
+%type <duration>       duration_length
+
+%type <scalar>  scalar
+%type <music>  Music  relative_music Sequential_music Simultaneous_music Music_sequence
+%type <music>  property_def translator_change
+%type <music_list> Music_list
+%type <paper>  paper_block paper_def_body
+%type <real>   real_expression real real_with_dimension
+%type <request> abbrev_command_req
+%type <request>        post_request 
+%type <request> command_req verbose_command_req
+%type <request>        extender_req
+%type <string> string
+%type <score>  score_block score_body
+%type <intarr> shape_array
+
+%type <string> script_abbreviation
+%type <trans>  translator_spec_block translator_spec_body
+%type <tempo>  tempo_request
+%type <notenametab> notenames_body notenames_block chordmodifiers_block
+
+
+
+
+%left '-' '+'
+%left '*' '/'
+%left UNARY_MINUS
+
+%%
+
+mudela:        /* empty */
+       | mudela toplevel_expression {}
+       | mudela assignment { }
+       | mudela error
+       | mudela check_version { }
+       ;
+
+toplevel_expression:
+       notenames_block                 {
+               THIS->lexer_p_->set_notename_table ($1);
+       }
+       | chordmodifiers_block                  {
+               THIS->lexer_p_->set_chordmodifier_table ($1);
+       }
+       | mudela_header {
+               delete header_global_p;
+               header_global_p = $1;
+       }
+       | score_block {
+               score_global_array.push ($1);
+       }
+       | paper_block {
+               Identifier * id = new
+                       Paper_def_identifier ($1, PAPER_IDENTIFIER);
+               THIS->lexer_p_->set_identifier ("$defaultpaper", id)
+       }
+       | midi_block {
+               Identifier * id = new
+                       Midi_def_identifier ($1, MIDI_IDENTIFIER);
+               THIS->lexer_p_->set_identifier ("$defaultmidi", id)
+       }
+       | embedded_scm { 
+       }
+       ;
+
+embedded_scm:
+       SCMFILE STRING semicolon {
+               read_lily_scm_file (*$2);
+               delete $2;
+       }
+       | SCM_T STRING semicolon {
+               gh_eval_str ($2->ch_l ());
+               delete $2;
+       };
+
+check_version:
+       VERSION STRING semicolon                {
+               Mudela_version ver (*$2);
+               if (!((ver >= oldest_version) && (ver <= version))) {
+                       if (THIS->ignore_version_b_) {
+                               THIS->here_input ().error (_f ("incorrect mudela version: %s (%s, %s)", ver.str (), oldest_version.str (), version.str ()));
+                       } else {
+                               THIS->fatal_error_i_ = 1;
+                               THIS->parser_error (_f ("incorrect mudela version: %s (%s, %s)", ver.str (), oldest_version.str (), version.str ()));
+                       }
+               }
+       }
+       ;
+
+
+chordmodifiers_block:
+       CHORDMODIFIERS '{' notenames_body '}'  {  $$ = $3; }
+       ;
+
+
+notenames_block:
+       NOTENAMES '{' notenames_body '}'  {  $$ = $3; }
+       ;
+
+
+
+notenames_body:
+       /**/    {
+               $$ = new Notename_table;
+       }
+       | NOTENAME_TABLE_IDENTIFIER     {
+               $$ = $1-> access_content_Notename_table(true);
+       }
+       | notenames_body STRING '=' explicit_musical_pitch {
+               (*$$)[*$2] = *$4;
+
+               delete $4;
+               delete $2;
+       }
+       ;
+
+mudela_header_body:
+       {
+               $$ = new Scope;
+               THIS->lexer_p_-> scope_l_arr_.push ($$);
+       }
+       | mudela_header_body assignment semicolon { 
+
+       }
+       ;
+
+mudela_header:
+       HEADER '{' mudela_header_body '}'       {
+               $$ = $3;
+               THIS->lexer_p_-> scope_l_arr_.pop ();           
+       }
+       ;
+
+
+/*
+       DECLARATIONS
+*/
+assignment:
+       STRING {
+               THIS->remember_spot ();
+       }
+       /* cont */ '=' identifier_init  {
+           THIS->lexer_p_->set_identifier (*$1, $4);
+           $4->init_b_ = THIS->init_parse_b_;
+           $4->set_spot (THIS->pop_spot ());
+       }
+       ;
+
+
+
+identifier_init:
+       score_block {
+               $$ = new Score_identifier ($1, SCORE_IDENTIFIER);
+
+       }
+       | chordmodifiers_block {
+               $$ = new Notename_table_identifier ($1, NOTENAME_TABLE_IDENTIFIER);
+       }
+       | notenames_block {
+               $$ = new Notename_table_identifier ($1, NOTENAME_TABLE_IDENTIFIER);
+       }
+       | paper_block {
+               $$ = new Paper_def_identifier ($1, PAPER_IDENTIFIER);
+       }
+       | midi_block {
+               $$ = new Midi_def_identifier ($1, MIDI_IDENTIFIER);
+
+       }
+       | translator_spec_block {
+               $$ = new Translator_identifier ($1, TRANS_IDENTIFIER);
+       }
+       | Music  {
+               $$ = new Music_identifier ($1, MUSIC_IDENTIFIER);
+       }
+
+       | post_request {
+               $$ = new Request_identifier ($1, REQUEST_IDENTIFIER);
+       }
+       | explicit_duration {
+               $$ = new Duration_identifier ($1, DURATION_IDENTIFIER);
+       }
+       | real {
+               $$ = new Real_identifier (new Real ($1), REAL_IDENTIFIER);
+       }
+       | string {
+               $$ = new String_identifier ($1, STRING_IDENTIFIER);
+       }
+       | int   {
+               $$ = new int_identifier (new int ($1), INT_IDENTIFIER);
+       }
+       ;
+
+translator_spec_block:
+       TRANSLATOR '{' translator_spec_body '}'
+               {
+               $$ = $3;
+       }
+       ;
+
+translator_spec_body:
+       TRANS_IDENTIFIER        {
+               $$ = $1->access_content_Translator (true);
+               $$-> set_spot (THIS->here_input ());
+       }
+       | TYPE STRING semicolon {
+               Translator* t = get_translator_l (*$2);
+               Translator_group * tg = dynamic_cast<Translator_group*> (t);
+
+               if (!tg)
+                       THIS->parser_error (_("Need a translator group for a context"));
+               
+               t = t->clone ();
+               t->set_spot (THIS->here_input ());
+               $$ = t;
+               delete $2;
+       }
+       | translator_spec_body STRING '=' identifier_init semicolon     { 
+               Identifier* id = $4;
+               String_identifier *s = dynamic_cast<String_identifier*> (id);
+               Real_identifier *r= dynamic_cast<Real_identifier*>(id);
+               int_identifier *i = dynamic_cast<int_identifier*> (id);
+       
+               String str;
+               if (s) str = *s->access_content_String (false); 
+               if (i) str = to_str (*i->access_content_int (false));
+               if (r) str = to_str (*r->access_content_Real (false));
+               if (!s && !i && !r)
+                       THIS->parser_error (_("Wrong type for property value"));
+
+               delete $4;
+               /* ugh*/
+               Translator_group * tr = dynamic_cast<Translator_group*>($$);
+               tr->set_property (*$2, str);
+       }
+       | translator_spec_body NAME STRING semicolon {
+               $$->type_str_ = *$3;
+               delete $3;
+       }
+       | translator_spec_body CONSISTS STRING semicolon {
+               dynamic_cast<Translator_group*> ($$)-> set_element (*$3, true);
+               delete $3;
+       }
+       | translator_spec_body CONSISTSEND STRING semicolon {
+               dynamic_cast<Translator_group*> ($$)-> set_element (*$3, true);
+               delete $3;
+       }
+       | translator_spec_body ACCEPTS STRING semicolon {
+               dynamic_cast<Translator_group*> ($$)-> set_acceptor (*$3, true);
+               delete $3;
+       }
+       | translator_spec_body REMOVE STRING semicolon {
+               dynamic_cast<Translator_group*> ($$)-> set_element (*$3, false);
+               delete $3;
+       }
+       ;
+
+/*
+       SCORE
+*/
+score_block:
+       SCORE { THIS->remember_spot ();
+       }
+       /*cont*/ '{' score_body '}'     {
+               $$ = $4;
+               $$->set_spot (THIS->pop_spot ());
+               if (!$$->def_p_arr_.size ())
+                       $$->add_output (THIS->default_paper_p ());
+
+       }
+       ;
+
+score_body:            {
+               $$ = new Score;
+       }
+       | SCORE_IDENTIFIER {
+               $$ = $1->access_content_Score (true);
+       }
+       | score_body mudela_header      {
+               $$->header_p_ = $2;
+       }
+       | score_body Music      {
+               if ($$->music_p_)
+                       $2->warning (_ ("More than one music block"));  
+               $$->music_p_ = $2;
+       }
+       | score_body output_def {
+               $$->add_output ($2);
+       }
+       | score_body error {
+
+       }
+       ;
+
+output_def:
+       paper_block {
+               $$ = $1;
+       }
+       |  midi_block           {
+               $$= $1;
+       }
+       ;
+
+intastint_list:
+       /* */   { $$ =new Array<int>; }
+       | intastint_list int '*' int    {
+               $$->push ($2); $$->push ($4);
+       }
+       | intastint_list int    {
+               $$->push ($2); $$->push (1);
+       }
+       ;       
+
+
+/*
+       PAPER
+*/
+paper_block:
+       PAPER '{' paper_def_body '}'    { 
+               $$ = $3;
+               THIS-> lexer_p_->scope_l_arr_.pop ();
+       }
+       ;
+
+
+optional_dot:
+       /* empty */
+       | '.'
+       ;
+
+paper_def_body:
+       /* empty */                     {
+               Paper_def *p = THIS->default_paper_p ();
+               THIS-> lexer_p_-> scope_l_arr_.push (p->scope_p_);
+               $$ = p;
+       }
+       | PAPER_IDENTIFIER      {
+               Paper_def *p = $1->access_content_Paper_def (true);
+               THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
+               $$ = p;
+       }
+       | paper_def_body int '=' FONT STRING            { // ugh, what a syntax
+               Lookup * l = new Lookup;
+               l->font_name_ = *$5;
+               delete $5;
+               $$->set_lookup ($2, l);
+       }
+       | paper_def_body assignment semicolon {
+
+       }
+       | paper_def_body translator_spec_block {
+               $$->assign_translator ($2);
+       }
+       | paper_def_body SHAPE '=' shape_array semicolon {
+               $$->shape_int_a_ = *$4;
+               delete $4;
+       }
+       | paper_def_body error {
+
+       }
+       ;
+
+
+real:
+       real_expression         { $$ = $1; }
+       ;
+
+
+real_with_dimension:
+       REAL CM_T       {
+               $$ = $1 CM;
+       }
+       | REAL PT_T     {
+               $$ = $1 PT;
+       }
+       | REAL IN_T     {
+               $$ = $1 INCH;
+       }
+       | REAL MM_T     {
+               $$ = $1 MM;
+       }
+       ;
+
+real_expression:
+       REAL            {
+               $$ = $1;
+       }
+       | real_with_dimension
+       | REAL_IDENTIFIER               {
+               $$= *$1->access_content_Real (false);
+       }
+       | '-'  real_expression %prec UNARY_MINUS {
+               $$ = -$2;
+       }
+       | real_expression '*' real_expression {
+               $$ = $1 * $3;
+       }
+       | real_expression '/' real_expression {
+               $$ = $1 / $3;
+       }
+       | real_expression '+' real_expression {
+               $$ = $1  + $3;
+       }
+       | real_expression '-' real_expression {
+               $$ = $1 - $3;
+       }
+       | '(' real_expression ')'       {
+               $$ = $2;
+       }
+       ;
+               
+
+shape_array:
+       /* empty */ {
+               $$ = new Array<Interval>;
+       }
+       | shape_array real real {
+               $$->push(Interval($2, $2 + $3));
+       };
+
+/*
+       MIDI
+*/
+midi_block:
+       MIDI
+
+       '{' midi_body '}'       { $$ = $3; }
+       ;
+
+midi_body: /* empty */                 {
+               $$ = THIS->default_midi_p ();
+       }
+       | MIDI_IDENTIFIER       {
+               $$ = $1-> access_content_Midi_def (true);
+       }
+       | midi_body translator_spec_block       {
+               $$-> assign_translator ($2);
+       }
+       | midi_body tempo_request semicolon {
+               $$->set_tempo ($2->dur_.length_mom (), $2->metronome_i_);
+               delete $2;
+       }
+       | midi_body error {
+
+       }
+       ;
+
+tempo_request:
+       TEMPO steno_duration '=' unsigned       {
+               $$ = new Tempo_req;
+               $$->dur_ = *$2;
+               delete $2;
+               $$-> metronome_i_ = $4;
+       }
+       ;
+
+Music_list: /* empty */ {
+               $$ = new Music_list;
+       }
+       | Music_list Music {
+               $$->add_music ($2);
+       }
+       | Music_list error {
+       }
+       ;
+
+
+Music:
+       Simple_music
+       | Composite_music
+       ;
+
+Alternative_music:
+       /* empty */ {
+               $$ = 0;
+       }
+       | ALTERNATIVE Music_sequence {
+               $$ = $2;
+       }
+       ;
+
+
+
+
+Repeated_music:
+       REPEAT STRING unsigned Music Alternative_music
+       {
+               Music_sequence* m = dynamic_cast <Music_sequence*> ($5);
+
+               New_repeated_music * r = new New_repeated_music ($4, $3 >? 1, m);
+               $$ = r;
+               r->fold_b_ = (*$2 == "fold");
+               r->semi_fold_b_ =  (*$2 == "semi");
+               delete $2;
+       }
+       ;
+
+Music_sequence: '{' Music_list '}'     {
+               $$ = new Music_sequence ($2);
+       }
+       ;
+
+Sequential_music: '{' Music_list '}'           {
+               $$ = new Sequential_music ($2);
+       }
+       ;
+
+Simultaneous_music: '<' Music_list '>' {
+               $$ = new Simultaneous_music ($2);
+       }
+       ;
+
+Simple_music:
+       request_chord           { $$ = $1; }
+       | MUSIC_IDENTIFIER { $$ = $1->access_content_Music (true); }
+       | property_def
+       | translator_change
+       | Simple_music '*' unsigned '/' unsigned        {
+               /* urg */
+               $$ = new Time_scaled_music ($3, $5, $1);
+       }
+       | Simple_music '*' unsigned              {
+               $$ = new Time_scaled_music ($3, 1, $1);
+       }
+       ;
+
+
+Composite_music:
+       CONTEXT STRING Music    {
+               Context_specced_music *csm =  new Context_specced_music ($3);
+
+               csm->translator_type_str_ = *$2;
+               csm->translator_id_str_ = "";
+               delete $2;
+
+               $$ = csm;
+       }
+       | GRACE Music {
+               $$ = new Grace_music ($2);
+       }
+       | CONTEXT STRING '=' STRING Music {
+               Context_specced_music *csm =  new Context_specced_music ($5);
+
+               csm->translator_type_str_ = *$2;
+               csm->translator_id_str_ = *$4;
+               delete $2;
+               delete $4;
+
+               $$ = csm;
+       }
+       | TIMES {
+               THIS->remember_spot ();
+       }
+       /* CONTINUED */ 
+               unsigned '/' unsigned Music     
+
+       {
+               $$ = new Time_scaled_music ($3, $5, $6);
+               $$->set_spot (THIS->pop_spot ());
+       }
+       | Repeated_music                { $$ = $1; }
+       | Simultaneous_music            { $$ = $1; }
+       | Sequential_music              { $$ = $1; }
+       | TRANSPOSE musical_pitch Music {
+               $$ = new Transposed_music ($3, *$2);
+               delete $2;
+       }
+       | TRANSPOSE steno_tonic_pitch Music {
+               $$ = new Transposed_music ($3, *$2);
+               delete $2;
+       }
+       | NOTES
+               { THIS->lexer_p_->push_note_state (); }
+       Music
+               { $$ = $3;
+                 THIS->lexer_p_->pop_state ();
+               }
+       | CHORDS
+               { THIS->lexer_p_->push_chord_state (); }
+       Music
+               {
+                 $$ = $3;
+                 THIS->lexer_p_->pop_state ();
+       }
+       | LYRICS
+               { THIS->lexer_p_->push_lyric_state (); }
+       Music
+               {
+                 $$ = $3;
+                 THIS->lexer_p_->pop_state ();
+       }
+       | relative_music        { $$ = $1; }
+       ;
+
+relative_music:
+       RELATIVE absolute_musical_pitch Music {
+               $$ = new Relative_octave_music ($3, *$2);
+               delete $2;
+       }
+       ;
+
+translator_change:
+       TRANSLATOR STRING '=' STRING  {
+               Change_translator * t = new Change_translator;
+               t-> change_to_type_str_ = *$2;
+               t-> change_to_id_str_ = *$4;
+
+               $$ = t;
+               $$->set_spot (THIS->here_input ());
+               delete $2;
+               delete $4;
+       }
+       ;
+
+property_def:
+       PROPERTY STRING '.' STRING '=' scalar   {
+               Translation_property *t = new Translation_property;
+
+               t-> var_str_ = *$4;
+               t-> value_ = *$6;
+
+               Context_specced_music *csm = new Context_specced_music (t);
+               $$ = csm;
+               $$->set_spot (THIS->here_input ());
+
+               csm-> translator_type_str_ = *$2;
+
+               delete $2;
+               delete $4;
+               delete $6;
+       }
+       ;
+
+scalar:
+       string          { $$ = new Scalar (*$1); delete $1; }
+       | int           { $$ = new Scalar ($1); }
+       ;
+
+
+request_chord:
+       pre_requests simple_element post_requests       {
+               Music_sequence *l = dynamic_cast<Music_sequence*>($2);
+               for (int i=0; i < $1->size(); i++)
+                       l->add_music ($1->elem(i));
+               for (int i=0; i < $3->size(); i++)
+                       l->add_music ($3->elem(i));
+               $$ = $2;
+               
+       }
+       | command_element
+       ;
+
+command_element:
+       command_req {
+               $$ = new Request_chord;
+               $$-> set_spot (THIS->here_input ());
+               $1-> set_spot (THIS->here_input ());
+               ((Simultaneous_music*)$$) ->add_music ($1);//ugh
+       }
+       ;
+
+command_req:
+       abbrev_command_req
+       | verbose_command_req semicolon { $$ = $1; }
+       ;
+
+abbrev_command_req:
+       extender_req {
+               $$ = $1;
+       }
+       | '|'                           {
+               $$ = new Barcheck_req;
+       }
+       | '~'   {
+               $$ = new Tie_req;
+       }
+       | '['           {
+               Span_req*b= new Span_req;
+               b->span_dir_ = START;
+               b->span_type_str_ = "beam";
+               $$ =b;
+       }
+       | ']'           {
+               Span_req*b= new Span_req;
+               b->span_dir_ = STOP;
+               b->span_type_str_ = "beam";
+               $$ = b;
+       }
+       | BREATHE {
+               $$ = new Breathing_sign_req;
+       }
+       ;
+
+
+verbose_command_req:
+       BAR STRING                      {
+               $$ = new Bar_req (*$2);
+               delete $2;
+       }
+       | MARK STRING {
+               $$ = new Mark_req (*$2);
+               delete $2;
+       }
+       | MARK unsigned {
+               $$ = new Mark_req (to_str ($2));
+       }
+       | TIME_T unsigned '/' unsigned  {
+               Time_signature_change_req *m = new Time_signature_change_req;
+               m->beats_i_ = $2;
+               m->one_beat_i_=$4;
+               $$ = m;
+       }
+       | PENALTY int   {
+               Break_req * b = new Break_req;
+               b->penalty_i_ = $2;
+               b-> set_spot (THIS->here_input ());
+               $$ = b;
+       }
+       | SKIP duration_length {
+               Skip_req * skip_p = new Skip_req;
+               skip_p->duration_ = *$2;
+               delete $2;
+               $$ = skip_p;
+       }
+       | tempo_request {
+               $$ = $1;
+       }
+       | CADENZA unsigned      {
+               $$ = new Cadenza_req ($2);
+       }
+       | PARTIAL duration_length       {
+               $$ = new Partial_measure_req ($2->length_mom ());
+               delete $2;
+       }
+       | CLEF STRING {
+               $$ = new Clef_change_req (*$2);
+               delete $2;
+       }
+       | KEY NOTENAME_PITCH optional_modality  {
+               Key_change_req *key_p= new Key_change_req;
+               key_p->pitch_arr_.push(*$2);
+               key_p->ordinary_key_b_ = true;
+               key_p->modality_i_ = $3;
+               $$ = key_p;
+               delete $2;
+       }
+       | KEYSIGNATURE pitch_list {
+               Key_change_req *key_p= new Key_change_req;
+               key_p->pitch_arr_ = *$2;
+               key_p->ordinary_key_b_ = false;
+               $$ = key_p;
+               delete $2;
+       }
+       | GROUPING intastint_list  {
+                 Measure_grouping_req * mr_p = new Measure_grouping_req;
+                 for (int i=0; i < $2->size();) 
+                   {
+                     mr_p->elt_length_arr_.push (Moment (1, $2->elem(i++)));
+                     mr_p->beat_i_arr_.push ($2->elem(i++));
+                   }
+
+
+               $$ = mr_p;
+               delete $2;
+       }
+       ;
+
+post_requests:
+       {
+               $$ = new Link_array<Request>;
+       }
+       | post_requests post_request {
+               $2->set_spot (THIS->here_input ());
+               $$->push ($2);
+       }
+       ;
+
+post_request:
+       verbose_request
+       | request_with_dir
+       | close_request
+       ;
+
+
+request_that_take_dir:
+       gen_text_def
+       | verbose_request
+       | script_abbreviation {
+               Identifier*i = THIS->lexer_p_->lookup_identifier ("dash-" + *$1);
+               Articulation_req *a = new Articulation_req;
+               a->articulation_str_ = *i->access_content_String (false);
+               delete $1;
+               $$ = a;
+       }
+       ;
+
+request_with_dir:
+       script_dir request_that_take_dir        {
+               if (Script_req * gs = dynamic_cast<Script_req*> ($2))
+                       gs->dir_ = Direction ($1);
+               else if ($1)
+                       $2->warning ("Can't specify direction for this request");
+               $$ = $2;
+       }
+       ;
+       
+verbose_request:
+       REQUEST_IDENTIFIER      {
+               $$ = (Request*)$1->access_content_Request (true);
+               $$->set_spot (THIS->here_input ());
+       }
+       | TEXTSCRIPT STRING STRING      {
+               Text_script_req *ts_p = new Text_script_req;
+               ts_p-> text_str_ = *$2;
+               ts_p-> style_str_ = *$3;
+               ts_p->set_spot (THIS->here_input ());
+               delete $3;
+               delete $2;
+               $$ = ts_p;
+       }
+       | SPANREQUEST int STRING {
+               Span_req * sp_p = new Span_req;
+               sp_p-> span_dir_  = Direction($2);
+               sp_p->span_type_str_ = *$3;
+               sp_p->set_spot (THIS->here_input ());
+               $$ = sp_p;
+       }
+       | abbrev_type   {
+               Tremolo_req* a = new Tremolo_req;
+               a->set_spot (THIS->here_input ());
+               a->type_i_ = $1;
+               $$ = a;
+       }
+       | SCRIPT STRING         { 
+               Articulation_req * a = new Articulation_req;
+               a->articulation_str_ = *$2;
+               a->set_spot (THIS->here_input ());
+               $$ = a;
+               delete $2;
+       }
+       ;
+
+optional_modality:
+       /* empty */     {
+               $$ = 0;
+       }
+       | int   {
+               $$ = $1;
+       }
+       ;
+
+sup_quotes:
+       '\'' {
+               $$ = 1;
+       }
+       | sup_quotes '\'' {
+               $$ ++;
+       }
+       ;
+
+sub_quotes:
+       ',' {
+               $$ = 1;
+       }
+       | sub_quotes ',' {
+               $$ ++ ;
+       }
+       ;
+
+steno_musical_pitch:
+       NOTENAME_PITCH  {
+               $$ = $1;
+       }
+       | NOTENAME_PITCH sup_quotes     {
+               $$ = $1;
+               $$->octave_i_ +=  $2;
+       }
+       | NOTENAME_PITCH sub_quotes      {
+               $$ = $1;
+               $$->octave_i_ += - $2;
+       }
+       ;
+
+steno_tonic_pitch:
+       TONICNAME_PITCH {
+               $$ = $1;
+       }
+       | TONICNAME_PITCH sup_quotes    {
+               $$ = $1;
+               $$->octave_i_ +=  $2;
+       }
+       | TONICNAME_PITCH sub_quotes     {
+               $$ = $1;
+               $$->octave_i_ += - $2;
+       }
+       ;
+
+explicit_musical_pitch:
+       MUSICAL_PITCH '{' int_list '}'  {/* ugh */
+               Array<int> &a = *$3;
+               ARRAY_SIZE(a,3);
+               $$ = new Musical_pitch;
+               $$->octave_i_ = a[0];
+               $$->notename_i_ = a[1];
+               $$->accidental_i_ = a[2];
+               delete &a;
+       }
+       ;
+
+musical_pitch:
+       steno_musical_pitch
+       | explicit_musical_pitch
+       ;
+
+explicit_duration:
+       DURATION '{' int_list '}'       {
+               $$ = new Duration;
+               Array<int> &a = *$3;
+               ARRAY_SIZE(a,2);
+                       
+               $$-> durlog_i_ = a[0];
+               $$-> dots_i_ = a[1];
+
+               delete &a;              
+       }
+       ;
+
+extender_req:
+       EXTENDER {
+               if (!THIS->lexer_p_->lyric_state_b ())
+                       THIS->parser_error (_ ("have to be in Lyric mode for lyrics"));
+               $$ = new Extender_req;
+       }
+       ;
+
+close_request:
+       close_request_parens {
+               $$ = $1;
+               dynamic_cast<Span_req*> ($$)->span_dir_ = START;
+       }
+       
+close_request_parens:
+       '('     {
+               Span_req* s= new Span_req;
+               $$ = s;
+               s->span_type_str_ = "slur";
+       }
+       | E_SMALLER {
+               Span_req*s =new Span_req;
+               $$ = s;
+               s->span_type_str_ = "crescendo";
+       }
+       | E_BIGGER {
+               Span_req*s =new Span_req;
+               $$ = s;
+               s->span_type_str_ = "decrescendo";
+       }
+       ;
+
+
+open_request:
+       open_request_parens {
+               $$ = $1;
+               dynamic_cast<Span_req*> ($$)->span_dir_ = STOP;
+       }
+       ;
+
+open_request_parens:
+       E_EXCLAMATION   {
+               Span_req *s =  new Span_req;
+               s->span_type_str_ = "crescendo";
+               $$ = s;
+       }
+       | ')'   {
+               Span_req* s= new Span_req;
+               $$ = s;
+               s->span_type_str_ = "slur";
+       }
+       ;
+
+gen_text_def:
+       string {
+               Text_script_req *t  = new Text_script_req;
+               $$ = t;
+               t->text_str_ = *$1;
+               delete $1;
+               $$->set_spot (THIS->here_input ());
+       }
+       | DIGIT {
+               Text_script_req* t  = new Text_script_req;
+               $$ = t;
+               t->text_str_ = to_str ($1);
+               t->style_str_ = "finger";
+               $$->set_spot (THIS->here_input ());
+       }
+       ;
+
+script_abbreviation:
+       '^'             {
+               $$ = new String ("hat");
+       }
+       | '+'           {
+               $$ = new String ("plus");
+       }
+       | '-'           {
+               $$ = new String ("dash");
+       }
+       | '|'           {
+               $$ = new String ("bar");
+       }
+       | '>'           {
+               $$ = new String ("larger");
+       }
+       | '.'           {
+               $$ = new String ("dot");
+       }
+       ;
+
+
+script_dir:
+       '_'     { $$ = DOWN; }
+       | '^'   { $$ = UP; }
+       | '-'   { $$ = CENTER; }
+       ;
+
+pre_requests:
+       {
+               $$ = new Link_array<Request>;
+       }
+       | pre_requests open_request {
+               $$->push ($2);
+       }
+       ;
+
+absolute_musical_pitch:
+       steno_musical_pitch     {
+               $$ = $1;
+       }
+       ;
+
+duration_length:
+       steno_duration {
+               $$ = $1;
+       }
+       | duration_length '*' unsigned {
+               $$->plet_.iso_i_ *= $3;
+       }
+       | duration_length '/' unsigned {
+               $$->plet_.type_i_ *= $3;
+       }
+       ;
+
+entered_notemode_duration:
+       dots            {
+               $$ = new Duration (THIS->default_duration_);
+               if ($1)
+                       $$->dots_i_  = $1;
+       }
+       | steno_duration        {
+               THIS->set_last_duration ($1);
+       }
+       ;
+
+notemode_duration:
+       entered_notemode_duration {
+               $$ = $1;
+       }
+       ;
+
+steno_duration:
+       unsigned                {
+               $$ = new Duration;
+               if (!Duration::duration_type_b ($1))
+                       THIS->parser_error (_f ("not a duration: %d", $1));
+               else {
+                       $$->durlog_i_ = Duration_convert::i2_type ($1);
+                    }
+       }
+       | DURATION_IDENTIFIER   {
+               $$ = $1->access_content_Duration (true);
+       }
+       | steno_duration '.'    {
+               $$->dots_i_ ++;
+       }
+       ;
+
+
+abbrev_type: 
+       ':'     {
+               $$ =0;
+       }
+       | ':' unsigned {
+               if (!Duration::duration_type_b ($2))
+                       THIS->parser_error (_f ("not a duration: %d", $2));
+               else if ($2 < 8)
+                       THIS->parser_error (_ ("can't abbreviate"));
+               $$ = $2;
+       }
+       ;
+
+
+simple_element:
+       musical_pitch exclamations questions notemode_duration  {
+               if (!THIS->lexer_p_->note_state_b ())
+                       THIS->parser_error (_ ("have to be in Note mode for notes"));
+
+
+               Note_req *n = new Note_req;
+               
+               n->pitch_ = *$1;
+               delete $1;
+               n->duration_ = *$4;
+               delete $4;
+               n->cautionary_b_ = $3 % 2;
+               n->forceacc_b_ = $2 % 2 || n->cautionary_b_;
+
+               Simultaneous_music*v = new Request_chord;
+               v->set_spot (THIS->here_input ());
+               n->set_spot (THIS->here_input ());
+
+               v->add_music (n);
+
+               $$ = v;
+       }
+       | RESTNAME notemode_duration            {
+               $$ = THIS->get_rest_element (*$1, $2);
+               delete $1;  // delete notename
+       }
+       | MEASURES notemode_duration    {
+               Multi_measure_rest_req* m = new Multi_measure_rest_req;
+               m->duration_ = *$2;
+               delete $2;
+
+               Simultaneous_music*velt_p = new Request_chord;
+               velt_p->set_spot (THIS->here_input ());
+               velt_p->add_music (m);
+               $$ = velt_p;
+       }
+       | REPETITIONS notemode_duration         {
+               Repetitions_req* r = new Repetitions_req;
+               r->duration_ = *$2;
+               delete $2;
+
+               Simultaneous_music*velt_p = new Request_chord;
+               velt_p->set_spot (THIS->here_input ());
+               velt_p->add_music (r);
+               $$ = velt_p;
+       }
+       | STRING notemode_duration                      {
+               if (!THIS->lexer_p_->lyric_state_b ())
+                       THIS->parser_error (_ ("have to be in Lyric mode for lyrics"));
+               $$ = THIS->get_word_element (*$1, $2);
+               delete $1;
+       }
+       | chord {
+               if (!THIS->lexer_p_->chord_state_b ())
+                       THIS->parser_error (_ ("have to be in Chord mode for chords"));
+               $$ = $1;
+       }
+       | '@' notemode_chord '@' {
+               if (!THIS->lexer_p_->note_state_b ())
+                       THIS->parser_error (_ ("have to be in Note mode for @chords"));
+               $$ = $2;
+       }
+       ;
+
+chord:
+       steno_tonic_pitch notemode_duration chord_additions chord_subtractions chord_inversion {
+                $$ = THIS->get_chord (*$1, $3, $4, $5, *$2);
+        };
+
+notemode_chord:
+       steno_musical_pitch notemode_duration chord_additions chord_subtractions notemode_chord_inversion {
+                $$ = THIS->get_chord (*$1, $3, $4, $5, *$2);
+        };
+
+
+chord_additions: 
+       {
+               $$ = new Array<Musical_pitch>;
+       } 
+       | '-' chord_notes {
+               $$ = $2;
+       }
+       ;
+
+chord_notes:
+       {
+               $$ = new Array<Musical_pitch>;
+       }
+       | chord_notes chord_addsub {
+               $$ = $1;
+               $$->push (*$2);
+       }
+       ;
+
+chord_subtractions: 
+       {
+               $$ = new Array<Musical_pitch>;
+       } 
+       | '^' chord_notes {
+               $$ = $2;
+       }
+       ;
+
+
+/*
+       forevery : X : optional_X sucks. Devise  a solution.
+*/
+
+
+chord_addsub:
+       chord_note optional_dot
+       | CHORDMODIFIER_PITCH optional_dot
+       ;
+
+chord_inversion:
+       {
+               $$ = 0;
+       }
+       | '/' steno_tonic_pitch {
+               $$ = $2
+       }
+       ;
+
+notemode_chord_inversion:
+       {
+               $$ = 0;
+       }
+       | '/' steno_musical_pitch {
+               $$ = $2
+       }
+       ;
+
+chord_note:
+       unsigned {
+               $$ = new Musical_pitch;
+               $$->notename_i_ = ($1 - 1) % 7;
+               $$->octave_i_ = $1 > 7 ? 1 : 0;
+               $$->accidental_i_ = 0;
+        } 
+       | unsigned '+' {
+               $$ = new Musical_pitch;
+               $$->notename_i_ = ($1 - 1) % 7;
+               $$->octave_i_ = $1 > 7 ? 1 : 0;
+               $$->accidental_i_ = 1;
+       }
+       | unsigned '-' {
+               $$ = new Musical_pitch;
+               $$->notename_i_ = ($1 - 1) % 7;
+               $$->octave_i_ = $1 > 7 ? 1 : 0;
+               $$->accidental_i_ = -1;
+       }
+        ;
+
+/*
+       UTILITIES
+ */
+pitch_list:                    {
+               $$ = new Array<Musical_pitch>;
+       }
+       | pitch_list musical_pitch      {
+               $$->push (*$2);
+               delete $2;
+       }
+       ;
+
+
+int_list:
+       /**/                    {
+               $$ = new Array<int>
+       }
+       | int_list int          {
+               $$->push ($2);          
+       }
+       ;
+
+unsigned:
+       UNSIGNED        {
+               $$ = $1;
+       }
+       | DIGIT {
+               $$ = $1;
+       };
+
+int:
+       unsigned {
+               $$ = $1;
+       }
+       | '-' unsigned {
+               $$ = -$2;
+       }
+       | INT_IDENTIFIER        {
+               $$ = *$1->access_content_int (false);
+       }
+       ;
+
+
+string:
+       STRING          {
+               $$ = $1;
+       }
+       | STRING_IDENTIFIER     {
+               $$ = $1->access_content_String (true);
+       }
+       | string '+' string {
+               *$$ += *$3;
+               delete $3;
+       }
+       ;
+
+
+
+
+dots:
+                       { $$ = 0; }
+       | dots '.'      { $$ ++; }
+       ;
+
+
+
+exclamations:
+               { $$ = 0; }
+       | exclamations '!'      { $$ ++; }
+       ;
+
+questions:
+               { $$ = 0; }
+       | questions '?' { $$ ++; }
+       ;
+
+
+semicolon:
+       ';'
+       ;
+%%
+
+void
+My_lily_parser::set_yydebug (bool b)
+{
+#ifdef YYDEBUG
+       yydebug = b;
+#endif
+}
+void
+My_lily_parser::do_yyparse ()
+{
+       yyparse ((void*)this);
+}
+
+
+
index dce0e249ebdeaa732a594507befcfe1cd5d8560e..fb9064e88afe7f1a2888742989eac815ef8b1b14 100644 (file)
@@ -189,6 +189,7 @@ StaffGroupContext= \translator {
        \consists "Separating_line_group_engraver";
        \consists "Lyric_engraver";
        \consists "Extender_engraver";
+       \consists "Hyphen_engraver";
 }
 
 \translator {
index c3bbd2edadf24eda57558cd79b8403c7e01b0b45..8c40d19377b915d4a5c666f1dbca30fa0baf4007 100644 (file)
@@ -154,6 +154,10 @@ rulethickness = \staffline;
 
 extender_height = 0.8*\staffline;
 
+hyphen_thickness = 0.05*\font_normal;
+hyphen_height = 0.2*\font_normal;
+hyphen_minimum_length = 0.25*\font_normal;
+
 % Multi-measure rests
 mmrest_x_minimum = 2.0*\staffheight;