From 3370901a4dcec5826728dda9bcbe02efb2d77b5e Mon Sep 17 00:00:00 2001 From: Glen Prideaux Date: Mon, 5 Jul 1999 15:05:33 +0200 Subject: [PATCH] patch::: 1.1.52.gp2 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 --- Documentation/tex/refman.yo | 15 + Documentation/tex/refman.yo.orig | 2213 ++++++++++++++++++++++++++ NEWS | 9 +- VERSION | 2 +- input/test/hyphen.ly | 11 + lily/hyphen-engraver.cc | 121 ++ lily/hyphen-spanner.cc | 96 ++ lily/include/hyphen-engraver.hh | 53 + lily/include/hyphen-spanner.hh | 40 + lily/include/lily-proto.hh | 1 + lily/include/ly-symbols.hh | 3 + lily/include/ly-symbols.hh.orig | 76 + lily/include/musical-request.hh | 6 + lily/include/musical-request.hh.orig | 148 ++ lily/lexer.ll | 4 +- lily/parser.yy | 13 + lily/parser.yy.orig | 1594 +++++++++++++++++++ ly/engraver.ly | 1 + ly/params.ly | 4 + 19 files changed, 4407 insertions(+), 3 deletions(-) create mode 100644 Documentation/tex/refman.yo.orig create mode 100644 input/test/hyphen.ly create mode 100644 lily/hyphen-engraver.cc create mode 100644 lily/hyphen-spanner.cc create mode 100644 lily/include/hyphen-engraver.hh create mode 100644 lily/include/hyphen-spanner.hh create mode 100644 lily/include/ly-symbols.hh.orig create mode 100644 lily/include/musical-request.hh.orig create mode 100644 lily/parser.yy.orig diff --git a/Documentation/tex/refman.yo b/Documentation/tex/refman.yo index 719770e081..b8aefcb0e8 100644 --- a/Documentation/tex/refman.yo +++ b/Documentation/tex/refman.yo @@ -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 index 0000000000..719770e081 --- /dev/null +++ b/Documentation/tex/refman.yo.orig @@ -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() + +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 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 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' ~ +) + +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 + } +) + +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( + % 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 } % 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 8b17eca679..fd4812c871 100644 --- 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 c0bc37e1b0..a69ab678e9 100644 --- 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 index 0000000000..149b02d9b4 --- /dev/null +++ b/input/test/hyphen.ly @@ -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 index 0000000000..013c9620b6 --- /dev/null +++ b/lily/hyphen-engraver.cc @@ -0,0 +1,121 @@ +/* + hyphen-engraver.cc -- implement Hyphen_engraver + + (c) 1999 Glen Prideaux +*/ + +#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 (i.elem_l_)) + { + Rhythmic_req * rh = dynamic_cast (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 (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 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 index 0000000000..8636dbb756 --- /dev/null +++ b/lily/hyphen-spanner.cc @@ -0,0 +1,96 @@ +/* + hyphen-spanner.cc -- implement Hyphen_spanner + + source file of the GNU LilyPond music typesetter + + (c) 1999 Glen Prideaux + + (adapted from extender-spanner) +*/ + +/* + TODO: too complicated implementation. Why the dx_drul?. + */ + +#include +#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 index 0000000000..6ab2eb59bc --- /dev/null +++ b/lily/include/hyphen-engraver.hh @@ -0,0 +1,53 @@ +/* + hyphen-engraver.hh -- declare Hyphen_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1999 Glen Prideaux +*/ + +#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 past_lyrics_pq_; + Array now_lyrics_; + Array 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 index 0000000000..e1316252c9 --- /dev/null +++ b/lily/include/hyphen-spanner.hh @@ -0,0 +1,40 @@ +/* + hyphen-spanner.hh -- part of GNU LilyPond + + (c) 1999 Glen Prideaux +*/ + +#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 dx_f_drul_; +}; + +#endif // HYPHEN_SPANNER_HH + diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index 97d9d57970..94f9be43dc 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -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; diff --git a/lily/include/ly-symbols.hh b/lily/include/ly-symbols.hh index 07890e4c10..444da6f181 100644 --- a/lily/include/ly-symbols.hh +++ b/lily/include/ly-symbols.hh @@ -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 index 0000000000..07890e4c10 --- /dev/null +++ b/lily/include/ly-symbols.hh.orig @@ -0,0 +1,76 @@ +/* + ly-symbols.hh -- declare SCM symbols. + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#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 */ + diff --git a/lily/include/musical-request.hh b/lily/include/musical-request.hh index 2c220138a9..88d5f6fbce 100644 --- a/lily/include/musical-request.hh +++ b/lily/include/musical-request.hh @@ -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 index 0000000000..2c220138a9 --- /dev/null +++ b/lily/include/musical-request.hh.orig @@ -0,0 +1,148 @@ +/* + musical-request.hh -- declare Musical requests + + source file of the GNU LilyPond music typesetter + + (c) 1997--1999 Han-Wen Nienhuys +*/ + + +#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 diff --git a/lily/lexer.ll b/lily/lexer.ll index e9a0c10371..8c340af25c 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -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) = ' '; diff --git a/lily/parser.yy b/lily/parser.yy index 78815d1cd2..5af4fb7ed8 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -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 post_request %type command_req verbose_command_req %type extender_req +%type hyphen_req %type string %type score_block score_body %type 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 index 0000000000..78815d1cd2 --- /dev/null +++ b/lily/parser.yy.orig @@ -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 + Jan Nieuwenhuizen +*/ + +/* + Ambiguities: + + * \alternative + + * use of '-' in various places + +*/ + + +#include +#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 () < + +#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* intarr; + Array *pitch_arr; + Link_array *reqvec; + Array * strvec; + Array *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 dots exclamations questions +%token DIGIT +%token NOTENAME_PITCH +%token TONICNAME_PITCH +%token CHORDMODIFIER_PITCH +%token DURATION_IDENTIFIER +%token IDENTIFIER +%token NOTENAME_TABLE_IDENTIFIER +%token MUSIC_IDENTIFIER +%token REQUEST_IDENTIFIER +%token REAL_IDENTIFIER +%token STRING_IDENTIFIER +%token TRANS_IDENTIFIER +%token INT_IDENTIFIER +%token SCORE_IDENTIFIER +%token MIDI_IDENTIFIER +%token PAPER_IDENTIFIER +%token REAL +%token DURATION RESTNAME +%token STRING +%token UNSIGNED + + +%type output_def +%type mudela_header mudela_header_body +%type open_request_parens close_request_parens open_request close_request +%type request_with_dir request_that_take_dir verbose_request +%type sub_quotes sup_quotes +%type simple_element request_chord command_element Simple_music Composite_music +%type Alternative_music Repeated_music +%type abbrev_type +%type int unsigned +%type script_dir +%type optional_modality +%type identifier_init +%type steno_duration notemode_duration +%type entered_notemode_duration explicit_duration +%type intastint_list int_list +%type pre_requests post_requests +%type gen_text_def +%type explicit_musical_pitch steno_musical_pitch musical_pitch absolute_musical_pitch +%type steno_tonic_pitch + +%type pitch_list +%type chord notemode_chord +%type chord_additions chord_subtractions chord_notes +%type chord_addsub chord_note chord_inversion notemode_chord_inversion +%type midi_block midi_body +%type duration_length + +%type scalar +%type Music relative_music Sequential_music Simultaneous_music Music_sequence +%type property_def translator_change +%type Music_list +%type paper_block paper_def_body +%type real_expression real real_with_dimension +%type abbrev_command_req +%type post_request +%type command_req verbose_command_req +%type extender_req +%type string +%type score_block score_body +%type shape_array + +%type script_abbreviation +%type translator_spec_block translator_spec_body +%type tempo_request +%type 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 (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 (id); + Real_identifier *r= dynamic_cast(id); + int_identifier *i = dynamic_cast (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($$); + tr->set_property (*$2, str); + } + | translator_spec_body NAME STRING semicolon { + $$->type_str_ = *$3; + delete $3; + } + | translator_spec_body CONSISTS STRING semicolon { + dynamic_cast ($$)-> set_element (*$3, true); + delete $3; + } + | translator_spec_body CONSISTSEND STRING semicolon { + dynamic_cast ($$)-> set_element (*$3, true); + delete $3; + } + | translator_spec_body ACCEPTS STRING semicolon { + dynamic_cast ($$)-> set_acceptor (*$3, true); + delete $3; + } + | translator_spec_body REMOVE STRING semicolon { + dynamic_cast ($$)-> 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; } + | 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; + } + | 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 ($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($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; + } + | 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 ($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 &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 &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_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_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; + } + | 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; + } + | '-' chord_notes { + $$ = $2; + } + ; + +chord_notes: + { + $$ = new Array; + } + | chord_notes chord_addsub { + $$ = $1; + $$->push (*$2); + } + ; + +chord_subtractions: + { + $$ = new Array; + } + | '^' 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; + } + | pitch_list musical_pitch { + $$->push (*$2); + delete $2; + } + ; + + +int_list: + /**/ { + $$ = new Array + } + | 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); +} + + + diff --git a/ly/engraver.ly b/ly/engraver.ly index dce0e249eb..fb9064e88a 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -189,6 +189,7 @@ StaffGroupContext= \translator { \consists "Separating_line_group_engraver"; \consists "Lyric_engraver"; \consists "Extender_engraver"; + \consists "Hyphen_engraver"; } \translator { diff --git a/ly/params.ly b/ly/params.ly index c3bbd2edad..8c40d19377 100644 --- a/ly/params.ly +++ b/ly/params.ly @@ -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; -- 2.39.2