]> git.donarmstrong.com Git - lilypond.git/commitdiff
(Lilypond_snippet.notice_include):
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 8 Feb 2004 23:14:30 +0000 (23:14 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 8 Feb 2004 23:14:30 +0000 (23:14 +0000)
write .dep file.

22 files changed:
ChangeLog
Documentation/bibliography/engraving.bib
Documentation/user/appendices.itely
Documentation/user/introduction.itely
Documentation/user/refman.itely
VERSION
input/regression/lyric-hyphen-break.ly [new file with mode: 0644]
input/test/lyric-hyphen-retain.ly [new file with mode: 0644]
lily/coherent-ligature-engraver.cc
lily/hyphen-engraver.cc
lily/hyphen-spanner.cc [deleted file]
lily/include/hyphen-spanner.hh [deleted file]
lily/include/lyric-hyphen.hh [new file with mode: 0644]
lily/include/paper-column.hh
lily/lyric-hyphen.cc [new file with mode: 0644]
lily/new-part-combine-iterator.cc
lily/paper-column.cc
lily/system.cc
ly/engraver-init.ly
make/ly-rules.make
scm/define-grobs.scm
scripts/lilypond-book.py

index 8542b0a12c546b3e61c2eec75f9c5d95720015a0..363f126d07f830b2ec973d61703a4dc09f1db760 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2004-02-09  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+       * scripts/lilypond-book.py (Lilypond_snippet.notice_include):
+       write .dep file.
+
+2004-02-08  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+       * Documentation/user/refman.itely (Markup command definition): Doc
+       by Nicolas Sceaux. Rewrite by Han-Wen
+
+       * lily/lyric-hyphen.cc (brew_molecule): remove if hyphen is first
+       thing of the line.
+       (brew_molecule): only remove if hyphen is not at the end of line.
+       (set_spacing_rods): new function: minimum-length specifies
+       distance between syllables.
+
+       * scm/define-grobs.scm (all-grob-descriptions): add
+       Hyphen_spanner::set_spacing_rods to LyricHyphen
+
+       * input/regression/lyric-hyphen-break.ly: new file.
+
+       * input/test/lyric-hyphen-retain.ly: new file.
+
+       * lily/new-part-combine-iterator.cc (construct_children):
+       add Rest direction.
+
+2004-02-08  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+       * scripts/lilypond-book.py (Snippet.replacement_text): add method.
+
+       * Documentation/bibliography/engraving.bib (donemus1982):
+       update entry.
+
 2004-02-07  Jan Nieuwenhuizen  <janneke@gnu.org>
 
        * scripts/lilypond.py (option_definitions): Fix typo.
index b4383faa6e068e640592c6ad872471fdd4d6f6c3..0209a87ffdbdba42c737cddf21a63ac2f5f14f41 100644 (file)
@@ -192,11 +192,17 @@ of print. }
   note={Heussenstamm writes: Limited in scope, similar to \cite{Roemer84}}
 }
 
-@Book {donemes1900,
-  year =  {1900},
+@Book {donemus1982,
+  year =  {1982},
   title = {Uitgeven van muziek},
   author = {Donemus},
   publisher= {Donemus Amsterdam},
+
+  note = {Manual on copying for composers and copyists at the Dutch
+ publishing house Donemus. Besides general comments on copying, it
+ also contains a lot of hands-on advice for making performance
+ material for modern pieces.}
+
 }
 
 
index c648ac7a65ba45779a1e0955bfdf4f2f0046f51c..eb0229825de4f51082e2914b53828c88e7bd08b8 100644 (file)
@@ -12,7 +12,7 @@
 @node Chord name chart
 @section Chord name chart
 
-@lilypondfile[notexidoc]{chord-names-jazz.ly}
+@lilypondfile{chord-names-jazz.ly}
 
 @node MIDI instruments
 @section MIDI instruments
index 5e9af3ffb0fb505a57d89e978ba6dc202202a88c..ae051f57209c0fbe994290f085eb353572e07211 100644 (file)
@@ -63,7 +63,7 @@ analogy, each plug-in is also called @code{engraver}.
 In the following example, we see how we start out with a note head
 engraver.
 
-@lilypond[notexidoc]
+@lilypond[]
 \include "engraver-example.lyinc"
 
 \score { \topVoice
@@ -93,7 +93,7 @@ engraver.
 
 Then a @code{Staff_symbol_engraver} adds the staff:
 
-@lilypond[notexidoc]
+@lilypond[]
 \include "engraver-example.lyinc"
 
 \score { \topVoice
@@ -122,7 +122,7 @@ Then a @code{Staff_symbol_engraver} adds the staff:
 
  The @code{Clef_engraver} defines a reference point for the staff:
 
-@lilypond[notexidoc]
+@lilypond[]
 \include "engraver-example.lyinc"
 
 \score { \topVoice
@@ -148,7 +148,7 @@ Then a @code{Staff_symbol_engraver} adds the staff:
 
 And the @code{Stem_engraver} adds stems:
 
-@lilypond[notexidoc]
+@lilypond[]
 \include "engraver-example.lyinc"
 
 \score { \topVoice
@@ -178,7 +178,7 @@ By adding engravers for beams, slurs, accents, accidentals, bar lines,
 time signature, and key signature, we get a complete piece of
 notation.
 
-@lilypond[notexidoc]
+@lilypond[]
 \include "engraver-example.lyinc"
 
 \score { \topVoice }
@@ -189,7 +189,7 @@ notation.
 This system works well for monophonic music, but what about
 polyphony? In polyphonic notation, many voices can share a staff.
 
-@lilypond[notexidoc]
+@lilypond[]
 \include "engraver-example.lyinc"
 \score { \context Staff << \topVoice \\ \botVoice >> }
 @end lilypond
@@ -203,7 +203,7 @@ case of polyphony, a single Staff context contains more than one Voice
 context.  In polyphonic notation, many voices can share a staff:
 Similarly, more Staff contexts can be put into a single Score context.
 
-@lilypond[notexidoc]
+@lilypond[]
 \include "engraver-example.lyinc"
 \score {
 << \new Staff << \topVoice \\ \botVoice >>
index edab5ee2c3a12bd46c289bebd8231e6de1c8713c..2aa79478bebe908bdf1a8316f2562aa35f6cc271 100644 (file)
@@ -2030,7 +2030,7 @@ different characteristics of the performance. They are added to a note
 by adding a dash and  the character signifying the
 articulation. They are demonstrated here:
 
-@lilypondfile[notexidoc]{script-abbreviations.ly}
+@lilypondfile[]{script-abbreviations.ly}
 
 The meanings of these shorthands can be changed: see
 @file{ly/script-init.ly} for examples.
@@ -2083,7 +2083,7 @@ eg.
 @cindex coda
 @cindex varcoda
 
-@lilypondfile[notexidoc]{script-chart.ly}
+@lilypondfile[]{script-chart.ly}
 
 
 @refcommands
@@ -3335,6 +3335,8 @@ next one. Such a line is called an extender line, and it is entered as
 Internals: @internalsref{LyricEvent}, @internalsref{HyphenEvent}, and
 @internalsref{ExtenderEvent}.
 
+Examples: @inputfileref{input/test,lyric-hyphen-retain.ly}
+
 @refbugs
 
 The definition of lyrics mode is too complex.
@@ -3432,6 +3434,7 @@ in @inputfileref{input/regression,lyric-combine-new.ly}.
 A complete example of a SATB score setup is in the file
 @inputfileref{input/template,satb.ly}.
 
+
 @refcommands
 
 @code{\melisma}, @code{\melismaEnd}
@@ -4191,7 +4194,7 @@ beginning of each line. This is illustrated in the following example,
 whose source is available as
 @inputfileref{input/test,bar-number-regular-interval.ly}:
 
-@lilypondfile[notexidoc]{bar-number-regular-interval.ly}
+@lilypondfile[]{bar-number-regular-interval.ly}
 
 
 @seealso
@@ -4569,7 +4572,7 @@ filtered. For example,
 @end example
 would yield
 
-@lilypondfile[notexidoc]{tag-filter.ly}
+@lilypondfile[]{tag-filter.ly}
 
 The argument of the @code{\tag} command should be a symbol, or a list
 of symbols, for example,
@@ -5344,7 +5347,7 @@ and @code{\finalis} at proper places in the input.  Some editions use
 Therefore, @code{gregorian-init.ly} also defines @code{\virgula} and
 @code{\caesura}:
 
-@lilypondfile[notexidoc]{divisiones.ly}
+@lilypondfile[]{divisiones.ly}
 
 @refcommands
 
@@ -7347,7 +7350,7 @@ The following example (from
 @inputfileref{input/regression,cluster.ly}) shows what the result
 looks like:
 
-@lilypondfile[notexidoc]{cluster.ly}
+@lilypondfile[]{cluster.ly}
 
 By default, @internalsref{Cluster_spanner_engraver} is in the
 @internalsref{Voice} context.  This allows putting ordinary notes and
@@ -7530,6 +7533,7 @@ treatment of the difference between translation and layout.
 * Applyoutput::                 
 * Font selection::              
 * Text markup::                 
+* Common text markup commands::  
 @end menu
 
 
@@ -8063,6 +8067,14 @@ For clarity, you can also do this for single arguments, e.g.
 
 @cindex font size, texts
 
+
+
+
+
+@node Common text markup commands
+@subsection Common text markup commands
+
+
 The following size commands set absolute sizes:
 
 @cindex @code{\teeny}
@@ -8232,9 +8244,6 @@ allegro = \markup { \bold \large { Allegro } }
 \notes { a^\allegro b c d }
 @end verbatim
 
-The markup mechanism is extensible.  Refer to
-@file{scm/new-markup.scm} for more information.
-
 
 Some objects have alignment procedures of their own, which cancel out
 any effects of alignments applied to their markup arguments as a
@@ -8251,6 +8260,7 @@ all markup commands.
 
 Init files:  @file{scm/new-markup.scm}.
 
+
 @refbugs
 
 @cindex kerning
@@ -8267,7 +8277,211 @@ field. Titles are made by La@TeX{}, so La@TeX{} commands should be used
 for formatting.
 
 
+@menu
+* Markup construction in scheme::  
+* Markup command definition::   
+@end menu
+
+@node Markup construction in scheme
+@subsubsection Markup construction in scheme
+
+@cindex defining markup commands 
+
+The @code{markup} macro builds markup expressions in Scheme while
+providing a LilyPond-like syntax. For example,
+@example
+(markup #:column (#:line (#:bold #:italic "hello" #:raise 0.4 "world")
+                  #:bigger #:line ("foo" "bar" "baz")))
+@end example
+
+@noindent
+is equivalent to:
+@example
+\markup \column < @{ \bold \italic "hello" \raise #0.4 "world" @}
+                  \bigger @{ foo bar baz @} >
+@end example
+
+@noindent
+This example exposes the main translation rules between regular
+LilyPond markup syntax and scheme markup syntax, which are summed up
+is this table:
+@multitable @columnfractions .5 .5
+@item @b{LilyPond} @tab @b{Scheme}
+@item @code{\command} @tab @code{#:command}
+@item @code{\variable} @tab @code{variable}
+@item @code{@{ ... @}} @tab @code{#:line ( ... )}
+@item @code{\center < ... >} @tab @code{#:center ( ... )}
+@item @code{string} @tab @code{"string"}
+@item @code{#scheme-arg} @tab @code{scheme-arg}
+@end multitable
+
+Besides, the whole scheme language is accessible inside the
+@code{markup} macro: thus, one may use function calls inside
+@code{markup} in order to manipulate character strings for
+instance. This proves useful when defining new markup commands (see
+@ref{Markup command definition}).
+
+@refbugs
+
+One can not feed the @code{#:line} (resp @code{#:center},
+@code{#:column}) command with a variable or the result of a function
+call. Eg:
+@lisp
+(markup #:line (fun-that-returns-markups))
+@end lisp
+is illegal. One should use the @code{make-line-markup} (resp
+@code{make-center-markup}, @code{make-column-markup}) function
+instead:
+@lisp
+(markup (make-line-markup (fun-that-returns-markups)))
+@end lisp
+
+@node Markup command definition
+@subsubsection Markup command definition
+
+New markup commands can be defined thanks to the @code{def-markup-command} scheme macro.
+@lisp
+(def-markup-command (@emph{command-name} @emph{paper} @emph{props} @emph{arg1} @emph{arg2} ...) (@emph{arg1-type?} @emph{arg2-type?} ...)
+  ..command body..)
+
+    @emph{argi}: i@emph{th} command argument
+    @emph{argi-type?}: a type predicate for the i@emph{th} argument
+    @emph{paper}: the `paper' definition
+    @emph{props}: a list of alists, containing all active properties. 
+@end lisp
+
+As a simple example, we show how to add a @code{\smallcaps} command,
+which selects @TeX{}'s small caps font.  Normally, we could select the
+small caps font as follows:
+
+@verbatim
+  \markup { \override #'(font-shape . caps)  Text-in-caps }
+@end verbatim
+
+This selects the caps font by setting the @code{font-shape} property to
+@code{#'caps} for interpreting @code{Text-in-caps}.
+
+To make the above available as @code{\smallcaps} command, we have to
+define a function using @code{def-markup-command}. The command should
+take a single argument, of markup type. Therefore, the start of the
+definition should read
+@example
+  (def-markup-command (smallcaps paper props argument) (markup?)
+@end example
+
+@noindent
+
+What follows is the content of the command: we should interpret
+the @code{argument} as a markup, i.e.
+
+@example
+    (interpret-markup paper  @dots{} argument)
+@end example
+
+@noindent
+This interpretation should add @code{'(font-shape . caps)} to the active
+properties, so we substitute the the following for the @dots{} in the
+above example:
+
+@example
+ (cons (list '(font-shape . caps) ) props)
+@end example
+
+@noindent
+The variable @code{props} is a list of alists, and we prepend to it by
+consing a list with the extra setting.
+
+However, suppose that we are using a font that does not have a
+small-caps variant. In that case, we have to fake the small caps font,
+by setting a string in upcase, with the first letter a little larger.
+
+The @code{smallcaps} command first splits its string argument into
+tokens separated by spaces (@code{(string-split str #\Space)}); for
+each token, a markup is built with the first letter made large and
+upcased (@code{#:large (string-upcase (substring s 0 1))}), and a
+second markup built with the following letters made tiny and upcased
+(@code{#:tiny (string-upcase (substring s 1))}). As LilyPond
+introduces a space between markups on a line, the second markup is
+translated to the left (@code{#:translate (cons -0.6 0) ...}). Then,
+the markups built for each token are put in a line
+(@code{(make-line-markup ...)}). Finally, the resulting markup is
+passed to the @code{interpret-markup} function, with the @code{paper}
+and @code{props} arguments.
+
+@example
+#(def-markup-command (smallcaps paper props str) (string?)
+   "Print the string argument in small caps. Syntax: \\smallcaps #\"string\""
+   (interpret-markup paper props
+    (make-line-markup
+     (map (lambda (s)
+            (if (= (string-length s) 0)
+                s
+                (markup #:large (string-upcase (substring s 0 1))
+                        #:translate (cons -0.6 0)
+                        #:tiny (string-upcase (substring s 1)))))
+          (string-split str #\Space)))))
+@end example
+
+Finally, suppose that we are typesetting a recitative in an opera, and
+we would like to define a command that will show character names in a
+custom manner. Names should be printed with small caps and translated a
+bit to the left and top.  We will define a @code{\character} command
+that takes into account the needed translation, and uses the newly
+defined @code{\smallcaps} command:
+
+@verbatim
+#(def-markup-command (character paper props name) (string?)
+   "Print the character name in small caps, translated to the left and
+   top. Syntax: \\character #\"name\""
+   (interpret-markup paper props 
+    (markup "" #:translate (cons -4 2) #:smallcaps name)))
+@end verbatim
+
+There is one complication that needs explanation: texts above and below
+the staff are moved vertically to be at a certain distance (the
+@code{padding} property) from the staff and the notes. To make sure
+that this mechanism does not annihilate the vertical effect of our
+@code{#:translate}, we add an empty string (@code{""}) before the
+translated text.  Now the @code{""} will be put above the notes, and the
+@code{name} is moved in relation to that empty string. The net effect is
+that the text is moved to the upper left.
 
+The final result is as follows:
+@verbatim
+\score {
+    \notes { \fatText
+        c''^\markup \character #"Cleopatra"
+        e'^\markup \character #"Giulio Cesare"
+    }
+}
+@end verbatim
+
+@lilypond[raggedright]
+#(def-markup-command (smallcaps paper props str) (string?)
+   "Print the string argument in small caps. Syntax: \\smallcaps #\"string\""
+   (interpret-markup paper props
+    (make-line-markup
+     (map (lambda (s)
+            (if (= (string-length s) 0)
+                s
+                (markup #:large (string-upcase (substring s 0 1))
+                        #:translate (cons -0.6 0)
+                        #:tiny (string-upcase (substring s 1)))))
+          (string-split str #\Space)))))
+
+#(def-markup-command (character paper props name) (string?)
+   "Print the character name in small caps, translated to the left and
+   top. Syntax: \\character #\"name\""
+   (interpret-markup paper props 
+    (markup "" #:translate (cons -4 0) #:smallcaps name)))
+
+\score {
+    \notes { \fatText
+        c''^\markup \character #"Cleopatra"
+        e'^\markup \character #"Giulio Cesare"
+    }
+}
+@end lilypond
 
 
 
diff --git a/VERSION b/VERSION
index 8241cb053edca54cd24204e4bf73b9fa06b7e2f9..35298bbb4757175251004a6dbf648664a7172e84 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,6 +1,6 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
 MINOR_VERSION=1
-PATCH_LEVEL=19
-MY_PATCH_LEVEL=hwn1
+PATCH_LEVEL=20
+MY_PATCH_LEVEL=
 
diff --git a/input/regression/lyric-hyphen-break.ly b/input/regression/lyric-hyphen-break.ly
new file mode 100644 (file)
index 0000000..98de343
--- /dev/null
@@ -0,0 +1,35 @@
+
+
+\header {
+
+    texidoc = "Hyphens only print at the beginning of the line, when
+they go past the first note. "
+
+    }
+
+\score {
+<<    \notes \new Staff \relative c'' { \time 1/4 c16[ c c  c]
+\time 1/4
+c16[ c c c]
+\time 1/4
+r c16[ c c]
+
+}
+    \lyrics \new LyricsVoice {
+       bla16 -- bla -- bla -- bla --
+       bla -- bla -- bla -- bla8 --
+              bla16 -- bla -- bla 
+       }>>
+    \paper   {
+       indent = 0.0 \cm
+       linewidth =  3.4 \cm
+
+       \translator {
+           \StaffContext \remove "Time_signature_engraver"
+       }
+       
+    }
+      
+}
+
+       
diff --git a/input/test/lyric-hyphen-retain.ly b/input/test/lyric-hyphen-retain.ly
new file mode 100644 (file)
index 0000000..28a42df
--- /dev/null
@@ -0,0 +1,49 @@
+
+
+\header {
+
+texidoc = "In tight situations, hyphens are removed, except at the
+end of the line.  Normally, lyrics aren't set this tight, but by
+tuning down @code{padding} of in @code{SeparationItem}, syllables are put closer together, and hyphens may disappear.
+
+In some languages (eg. German and Hungarian).  hyphens should not
+disappear, since spelling depends on hyphenation. In this case,
+hyphens can be forced to remain by setting @code{minimum-length} on
+the LyricHyphen grob.
+"
+
+}
+
+\score {
+<<    \notes \new Staff \relative c'' { \time 1/4 c16[ c c  c]
+\time 1/4
+c16[ c c c]
+\time 1/4
+c16[ c c c]
+
+}
+    \lyrics \new LyricsVoice \with {
+       % Otherwise lyrics are so far apart that hyphens don't disappear
+       SeparationItem \set #'padding = #0.0
+       }{ bla -- bla -- bla -- bla --
+          bla -- bla -- bla -- bla --
+
+          \property LyricsVoice . LyricHyphen \set #'minimum-length = #0.7
+          \property LyricsVoice . LyricHyphen \set #'spacing-procedure =
+                  #Hyphen_spanner::set_spacing_rods
+
+          bla -- bla -- bla -- bla 
+       }>>
+    \paper   {
+       indent = 0.0 \cm
+       linewidth =  3.4 \cm
+
+       \translator {
+           \StaffContext \remove "Time_signature_engraver"
+       }
+       
+    }
+      
+}
+
+       
index 19bc0a15a397fba7f8b15a8b7858ca89c875f573..a7e8247d6713a9bac016c9338f9f1bfcecae3a3a 100644 (file)
@@ -79,7 +79,7 @@
  */
 #if 0 // experimental code to collapse spacing after ligature
       SCM incr_scm = lc->get_grob_property ("forced-spacing");
-      if (incr_scm != SCM_EOL) /* (Paper_column::musical_b (l)) */
+      if (incr_scm != SCM_EOL) /* (Paper_column::is_musical (l)) */
        {
          me->warning (_f ("gotcha: ptr=%ul", lc));//debug
          ly_display_scm (lc->self_scm ());
index 1010dc08ab0675762936c988ab260aa7bb7a3ac3..15f472cadcd1b3e37c2e9c7f5b781fb85e4765c0 100644 (file)
@@ -9,9 +9,9 @@
 */
 
 #include "warn.hh"
-#include "hyphen-spanner.hh"
 #include "item.hh"
 #include "engraver.hh"
+#include "spanner.hh"
 
 class Hyphen_engraver : public Engraver
 {
diff --git a/lily/hyphen-spanner.cc b/lily/hyphen-spanner.cc
deleted file mode 100644 (file)
index 09699d7..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-  hyphen-spanner.cc -- implement Hyphen_spanner
-
-  source file of the GNU LilyPond music typesetter
-
-  (c) 1999--2004 Glen Prideaux <glenprideaux@iname.com>
-
- (adapted from lyric-extender)
-*/
-
-#include <math.h>
-
-#include "box.hh"
-#include "lookup.hh"
-#include "molecule.hh"
-#include "paper-def.hh"
-#include "hyphen-spanner.hh"
-#include "paper-column.hh"
-#include "spanner.hh"
-#include "item.hh"
-
-
-MAKE_SCHEME_CALLBACK (Hyphen_spanner,brew_molecule,1)
-SCM 
-Hyphen_spanner::brew_molecule (SCM smob)
-{
-  Spanner * sp = unsmob_spanner (smob);
-  Drul_array<Item*> bounds (sp->get_bound (LEFT),
-                           sp->get_bound (RIGHT));
-  
-  Grob * common = bounds[LEFT]->common_refpoint (bounds[RIGHT], X_AXIS);
-
-  Interval span_points;
-  Direction d = LEFT;
-  do
-    {
-      Interval iv = bounds[d]->extent (common, X_AXIS);
-
-      span_points[d] = iv.is_empty ()
-       ? bounds[d]->relative_coordinate (common, X_AXIS)
-       : iv[-d];
-    }
-  while (flip (&d) != LEFT);
-  
-  Real lt = sp->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
-  Real th = robust_scm2double (sp->get_grob_property ("thickness"), 1) * lt ;
-  Real h = robust_scm2double (sp->get_grob_property ("height"), 0.5);
-
-  // interval?
-  
-  Real dp = robust_scm2double (sp->get_grob_property ("dash-period"), 1.0);
-  Real dl = robust_scm2double (sp->get_grob_property ("length"), .5 );
-
-  if (dp < dl)
-    dp = 1.5 * dl;
-
-  Real l = span_points.length ();
-  int n = int (ceil (l/dp - 0.5));
-  if (n <= 0)
-    n = 1;
-
-  Real space_left = l - dl - (n-1)* dp;
-
-  /*
-    If there is not enough space, the hyphen should disappear.
-   */
-  if (space_left < 0)
-    return SCM_EOL;
-  
-  Box b (Interval (0, dl), Interval (h,h+th));
-  Molecule dash_mol (Lookup::round_filled_box (b, 0.8 * lt));
-
-  Molecule total;
-  for (int i = 0; i < n; i++)
-    {
-      Molecule m (dash_mol);
-      m.translate_axis (span_points[LEFT] + i * dp + space_left / 2, X_AXIS);
-      total.add_molecule (m);
-    }
-
-  total.translate_axis ( -sp->relative_coordinate (common, X_AXIS), X_AXIS);
-  return total.smobbed_copy ();
-}
-
-
-ADD_INTERFACE (Hyphen_spanner, "lyric-hyphen-interface",
-              "A centred hyphen is a simple line between lyrics used to divide syllables",
-              "thickness height dash-period length");
-
-
diff --git a/lily/include/hyphen-spanner.hh b/lily/include/hyphen-spanner.hh
deleted file mode 100644 (file)
index cd713c4..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-  hyphen-spanner.hh -- part of GNU LilyPond
-
-  (c) 1999--2004 Glen Prideaux <glenprideaux@iname.com>
-*/
-
-#ifndef HYPHEN_SPANNER_HH
-#define HYPHEN_SPANNER_HH
-
-#include "spanner.hh"
-
-struct Hyphen_spanner 
-{
-public:
-  DECLARE_SCHEME_CALLBACK(set_spacing_rods, (SCM));
-  void set_textitem (Direction, Grob*);
-  bool has_interface (Grob*);
-  DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM ));
-};
-
-#endif // HYPHEN_SPANNER_HH
-
diff --git a/lily/include/lyric-hyphen.hh b/lily/include/lyric-hyphen.hh
new file mode 100644 (file)
index 0000000..ce04811
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+  hyphen-spanner.hh -- part of GNU LilyPond
+
+  (c) 1999--2004 Glen Prideaux <glenprideaux@iname.com>
+*/
+
+#ifndef HYPHEN_SPANNER_HH
+#define HYPHEN_SPANNER_HH
+
+#include "spanner.hh"
+
+struct Hyphen_spanner 
+{
+public:
+  DECLARE_SCHEME_CALLBACK(set_spacing_rods, (SCM));
+  bool has_interface (Grob*);
+  DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM ));
+};
+
+#endif // HYPHEN_SPANNER_HH
+
index f44ea9ac151661343fcc08c9925293a3783b2bf5..43be74ba7efd69e119de3afa83a4b8b9ee8c7651 100644 (file)
@@ -7,8 +7,8 @@
 */
 
 
-#ifndef P_COL_HH
-#define P_COL_HH
+#ifndef PAPER_COLUMN_HH
+#define PAPER_COLUMN_HH
 
 #include "item.hh"
 #include "rod.hh"
@@ -34,12 +34,12 @@ public:
   DECLARE_SCHEME_CALLBACK(before_line_breaking, (SCM));
   
   Paper_column (SCM);
-  static bool musical_b (Grob *);
+  static bool is_musical (Grob *);
   static Moment when_mom (Grob*);
 
-  static bool used_b (Grob*) ;
+  static bool is_used (Grob*) ;
   void set_rank (int);
 };
      
-#endif // P_COL_HH
+#endif // PAPER_COLUMN_HH
 
diff --git a/lily/lyric-hyphen.cc b/lily/lyric-hyphen.cc
new file mode 100644 (file)
index 0000000..6fdd1e4
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+  hyphen-spanner.cc -- implement Hyphen_spanner
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2003--2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include <math.h>
+
+#include "box.hh"
+#include "lookup.hh"
+#include "molecule.hh"
+#include "paper-def.hh"
+#include "paper-column.hh"
+#include "spanner.hh"
+#include "item.hh"
+#include "lyric-hyphen.hh"
+#include "moment.hh"
+
+MAKE_SCHEME_CALLBACK (Hyphen_spanner,brew_molecule,1)
+SCM 
+Hyphen_spanner::brew_molecule (SCM smob)
+{
+  Spanner * me = unsmob_spanner (smob);
+  Drul_array<Item*> bounds (me->get_bound (LEFT),
+                           me->get_bound (RIGHT));
+
+  if (bounds[LEFT]->break_status_dir ()
+      && Paper_column::when_mom (bounds[LEFT]) == Paper_column::when_mom (bounds[RIGHT]->get_column()))
+    return SCM_EOL;
+  
+  Grob * common = bounds[LEFT]->common_refpoint (bounds[RIGHT], X_AXIS);
+
+  Interval span_points;
+  Direction d = LEFT;
+  do
+    {
+      Interval iv = bounds[d]->extent (common, X_AXIS);
+
+      span_points[d] = iv.is_empty ()
+       ? bounds[d]->relative_coordinate (common, X_AXIS)
+       : iv[-d];
+    }
+  while (flip (&d) != LEFT);
+  
+  Real lt = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
+  Real th = robust_scm2double (me->get_grob_property ("thickness"), 1) * lt ;
+  Real h = robust_scm2double (me->get_grob_property ("height"), 0.5);
+
+  // interval?
+  
+  Real dp = robust_scm2double (me->get_grob_property ("dash-period"), 1.0);
+  Real dl = robust_scm2double (me->get_grob_property ("length"), .5 );
+
+  if (dp < dl)
+    dp = 1.5 * dl;
+
+  Real l = span_points.length ();
+  int n = int (ceil (l/dp - 0.5));
+  if (n <= 0)
+    n = 1;
+
+  Real space_left = l - dl - (n-1)* dp;
+
+  /*
+    If there is not enough space, the hyphen should disappear, but not
+    at the end of the line.
+   */
+  if (space_left < 0.0
+      && !bounds[RIGHT]->break_status_dir ())
+    return SCM_EOL;
+
+  space_left = space_left >? 0.0;
+  
+  Box b (Interval (0, dl), Interval (h,h+th));
+  Molecule dash_mol (Lookup::round_filled_box (b, 0.8 * lt));
+
+  Molecule total;
+  for (int i = 0; i < n; i++)
+    {
+      Molecule m (dash_mol);
+      m.translate_axis (span_points[LEFT] + i * dp + space_left / 2, X_AXIS);
+      total.add_molecule (m);
+    }
+
+  total.translate_axis ( -me->relative_coordinate (common, X_AXIS), X_AXIS);
+  return total.smobbed_copy ();
+}
+
+
+MAKE_SCHEME_CALLBACK (Hyphen_spanner,set_spacing_rods,1);
+SCM
+Hyphen_spanner::set_spacing_rods (SCM smob)
+{
+  Grob*me = unsmob_grob (smob);
+
+  Rod r;
+  Spanner*sp = dynamic_cast<Spanner*> (me);
+  r.distance_ =
+    robust_scm2double (me->get_grob_property ("minimum-length"), 0);
+  Direction d=LEFT;
+  do {
+    r.item_l_drul_[d] = sp->get_bound (d);
+    r.distance_ += r.item_l_drul_[d]->extent (r.item_l_drul_[d], X_AXIS)[-d];
+  } while (flip (&d) != LEFT);
+
+  r.add_to_cols ();
+  return SCM_UNSPECIFIED;
+}
+
+ADD_INTERFACE (Hyphen_spanner, "lyric-hyphen-interface",
+              "A centred hyphen is a simple line between lyrics used to divide syllables",
+              "thickness height dash-period minimum-length length");
+
+
index ee4ede13ad43ad2402b6a5770ecc05b1c6c7156c..ceae7e03b5160769e3abba974f1384ea8585a184 100644 (file)
@@ -312,6 +312,7 @@ New_pc_iterator::construct_children ()
     "DynamicLineSpanner",
     "Tie",
     "Dots",
+    "Rest",
     "Slur",
     "TextScript",
     "Script",
index 60fd60a59f1b59b369624d234154f58bf2ba9f77..eab40b4975caee25fbf3b9c990d5addb0f147d82 100644 (file)
@@ -86,7 +86,7 @@ Paper_column::when_mom (Grob*me)
 }
 
 bool
-Paper_column::musical_b (Grob *me)
+Paper_column::is_musical (Grob *me)
 {
   SCM m = me->get_grob_property ("shortest-starter-duration");
   Moment s (0);
@@ -100,7 +100,7 @@ Paper_column::musical_b (Grob *me)
   
 
 bool
-Paper_column::used_b (Grob*me)
+Paper_column::is_used (Grob*me)
 {
   return gh_pair_p (me->get_grob_property ("elements")) ||  Item::breakable_b (me)
     || gh_pair_p (me->get_grob_property ("bounded-by-me"))
index dc7bba5b15f6d985c2083a7a36d5152f2aedc824..3a0f2dbaa339d0744f575778c0d31121370c6c25 100644 (file)
@@ -602,7 +602,7 @@ System::columns ()const
        seem empty. We need to retain breakable columns, in case
        someone forced a breakpoint.
       */
-      if (!bfound || !Paper_column::used_b (acs[i]))
+      if (!bfound || !Paper_column::is_used (acs[i]))
        acs.del (i);
     }
   return acs;
index 5663553a91d1d736aec5cf8c5c84073a50c9adb5..aecfe99c24e7637073b9381aefd820e52996c3fd 100644 (file)
@@ -343,7 +343,7 @@ printing of a single line of lyrics.  "
     \consists "Stanza_number_engraver"
     \consists "Vocal_name_engraver"
     \consists "Skip_event_swallow_translator"
-    SeparationItem \set #'padding = #0.5
+    SeparationItem \set #'padding = #0.2
 }
 
 \translator {
index d513ae3dcf9422c65e3facea28a7d9b40f9f7198..174dee86eb85889b90b596c6e8544ccc9d5b8500 100644 (file)
@@ -10,7 +10,7 @@ $(outdir)/%.latex: %.doc
 # it is not, for --srcdir builds
 $(outdir)/%.texi: %.tely
        if [ -f $@ ]; then chmod a+w $@; fi
-       time $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) --verbose $(LILYPOND_BOOK_FLAGS) $<
+       $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) --verbose $(LILYPOND_BOOK_FLAGS) $<
        chmod -w $@
 
 $(outdir)/%.texi: $(outdir)/%.tely
index 95d8bb545d12cea4305bf04b32f7a67d543c2be4..89dc980d67093c109b97a6de6325e57f77ceaad0 100644 (file)
        (height . 0.42)
        (dash-period . 10.0)
        (length . 0.66)
-       (minimum-length .  0.5) 
+       (spacing-procedure . ,Hyphen_spanner::set_spacing_rods)
        (molecule-callback . ,Hyphen_spanner::brew_molecule)
        (Y-extent-callback . ,Grob::point_dimension_callback)
        (meta . ((interfaces . (lyric-interface lyric-hyphen-interface
index 85c39d2ad3f579ab8149952aee9229a4dabade7a..fe1157ccbd32350480e9d468580480137375d8a4 100644 (file)
@@ -156,9 +156,11 @@ snippet_res = {
        'lilypond_block': r'''(?ms)^(?P<match>@lilypond(\[(?P<options>[^]]*)\])?\s(?P<code>.*?)@end lilypond)\s''',
        'lilypond_file': '(?m)^(?P<match>@lilypondfile(\[(?P<options>[^]]*)\])?{(?P<filename>[^}]+)})',
        'multiline_comment': r"(?sm)^\s*(?!@c\s+)(?P<code>@ignore\s.*?@end ignore)\s",
-       'singleline_comment': r"(?m)^.*?(?P<match>(?P<code>@c([ \t][^\n]*|)\n))",
-       'verb': r'''(?P<code>@code{.*?})''',
-       'verbatim': r'''(?s)(?P<code>@example\s.*?@end example\s)''',
+       'singleline_comment': r"(?m)^.*(?P<match>(?P<code>@c([ \t][^\n]*|)\n))",
+
+# don't do this: fucks up with @code{@{}
+#      'verb': r'''(?P<code>@code{.*?})''',
+       'verbatim': r'''(?s)(?P<code>@example\s.*?@end\s+example\s)''',
        },
        }
 
@@ -377,7 +379,8 @@ def split_options (option_string):
 class Chunk:
        def replacement_text (self):
                return ''
-
+       def is_outdated (self):
+               return 0
 
 class Substring (Chunk):
        def __init__ (self, source, start, end):
@@ -386,8 +389,6 @@ class Substring (Chunk):
                self.end = end
        def replacement_text (self):
                return self.source [self.start:self.end]
-       def outdated_p (self):
-               return 0
        
 class Snippet (Chunk):
        def __init__ (self, type, match, format):
@@ -396,6 +397,9 @@ class Snippet (Chunk):
                self.hash = 0
                self.options = []
                self.format = format
+       def replacement_text (self):
+               return self.match.group (0)
+       
        def substring (self, s):
                return self.match.group (s)
        def filter_code (self):
@@ -404,12 +408,15 @@ class Snippet (Chunk):
                return  `self.__class__`  +  " type =  " + self.type
 
 class Include_snippet (Snippet):
+       def processed_filename (self):
+               f = self.substring ('filename')
+               return os.path.splitext (f)[0] + format2ext[format]
+               
        def replacement_text (self):
                s = self.match.group (0)
                f = self.substring ('filename')
-               nf = os.path.splitext (f)[0] + format2ext[format]
-               
-               return re.sub (f, nf, s)
+       
+               return re.sub (f, self.processed_filename (), s)
 
 class Lilypond_snippet (Snippet):
        def __init__ (self, type, match, format):
@@ -446,7 +453,7 @@ class Lilypond_snippet (Snippet):
                outf = open (self.basename () + '.ly', 'w')
                outf.write (self.full_ly ())
 
-       def outdated_p (self):
+       def is_outdated (self):
                base = self.basename ()
                if os.path.exists (base + '.ly') \
                   and os.path.exists (base + '.tex') \
@@ -691,6 +698,7 @@ format2ext = {
        LATEX: '.tex',
        }
 
+       
 def do_file (input_filename):
        #ugh
        global format
@@ -714,7 +722,7 @@ def do_file (input_filename):
        ly.progress (_ ("Dissecting..."))
        snippet_types = (
                'lilypond_block',
-               'verb',
+#              'verb',
                'verbatim',
                'singleline_comment',
                'multiline_comment',
@@ -760,7 +768,7 @@ def do_file (input_filename):
        if filter_cmd:
                pass # todo
        elif process_cmd:
-               outdated = filter (lambda x: x.__class__ == Lilypond_snippet and x.outdated_p (),
+               outdated = filter (lambda x: x.__class__ == Lilypond_snippet and x.is_outdated (),
                                   chunks)
                ly.progress (_ ("Writing snippets..."))
                map (Lilypond_snippet.write_ly, outdated)
@@ -787,9 +795,24 @@ def do_file (input_filename):
                
        output_file.writelines ([s.replacement_text () for s in chunks])
 
-       ## UGH. how do you do dynamic_cast/typecheck in Python?
+
+       included_files = []
+       def notice_include (target, snip):
+               included_files.append (snip.match.group ('filename'))
+               included_files.append (os.path.join (output_name, snip.processed_filename ()))
+
+       [notice_include (output_filename, x) for x in
+        
+        ## UGH. how do you do dynamic_cast/typecheck in Python?
+        filter (lambda x: x.__class__ == Include_snippet, chunks)]
+
+       target = re.sub (r'^\./','', output_filename)
+       open (os.path.split (output_filename)[1] + '.dep', 'w').write ('%s: %s\n' % (target,
+                                                                                    string.join (included_files)))
+       
        map (process_include, filter (lambda x: x.__class__ == Include_snippet, chunks))
 
+
 def do_options ():
        global format, output_name
        global filter_cmd, process_cmd, verbose_p
@@ -853,6 +876,5 @@ def main ():
        ly.setup_environment ()
        if files:
                do_file (files[0])
-
 if __name__ == '__main__':
        main ()