]> git.donarmstrong.com Git - lilypond.git/commitdiff
* input/regression/markup-note.ly: new file
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 17 May 2003 13:27:00 +0000 (13:27 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 17 May 2003 13:27:00 +0000 (13:27 +0000)
* input/regression/metronome-marking.ly: new file

* lily/metronome-engraver.cc: new file. Print \tempo markings.

* scm/new-markup.scm (note-markup): make a note glyph, useful for
metronome marks.

17 files changed:
ChangeLog
Documentation/user/refman.itely
input/regression/markup-note.ly [new file with mode: 0644]
input/regression/metronome-marking.ly [new file with mode: 0644]
lily/lexer.ll
lily/metronome-engraver.cc [new file with mode: 0644]
lily/parser.yy
lily/tempo-performer.cc
ly/engraver-init.ly
scm/grob-description.scm
scm/interface-description.scm
scm/lily.scm
scm/music-functions.scm
scm/music-types.scm
scm/new-markup.scm
scm/translator-property-description.scm
scripts/lilypond-book.py

index 4209da2636c86c2c201c2d0ed8885d5a73804449..7d56f42436a72e253ab109a1df2794de618df384 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2003-05-17  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
+
+       * input/regression/markup-note.ly: new file
+
+       * input/regression/metronome-marking.ly: new file
+
+       * lily/metronome-engraver.cc: new file. Print \tempo markings.
+
+       * scm/new-markup.scm (note-markup): make a note glyph, useful for
+       metronome marks.
+
 2003-05-17  Jan Nieuwenhuizen  <janneke@gnu.org>
 
        * Documentation/user/GNUmakefile: Compatibility fix for new
index e2d7547df957dac43e5825aef99083da40efc610..861874b0a40a565dcab1b3785544db0d6311f19f 100644 (file)
@@ -402,13 +402,10 @@ by replacing the @internalsref{Note_heads_engraver} by the
 @end example
 
 For example,
-
-@ignore
-@example[relative 0]
+@example
   \time 2/4
   c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2 
 @end example
-@end ignore
 
 @lilypond[noindent]
 \score{
diff --git a/input/regression/markup-note.ly b/input/regression/markup-note.ly
new file mode 100644 (file)
index 0000000..8f342f7
--- /dev/null
@@ -0,0 +1,43 @@
+\header {
+
+    texidoc = "The note markup function is used to make metronome
+ markings. It works for a variety of flag dot and duration settings."
+}
+\version "1.7.18"
+
+\score { \notes { c4^\markup {
+    \note #0 #0 #1
+    \note #1 #0 #1
+    \note #2 #0 #1
+    \note #3 #0 #1
+    \note #4 #0 #1
+    \note #5 #0 #1
+    \note #6 #0 #1
+
+    \note #0 #0 #-1
+    \note #1 #0 #-1
+    \note #2 #0 #-1
+    \note #3 #0 #-1
+    \note #4 #0 #-1
+    \note #5 #0 #-1
+    \note #6 #0 #-1
+
+    \note #0 #1 #-1
+    \note #1 #1 #-1
+    \note #2 #1 #-1
+    \note #3 #1 #-1
+    \note #4 #1 #-1
+    \note #5 #1 #-1
+    \note #6 #1 #-1
+
+    \note #0 #1 #1
+    \note #1 #1 #1
+    \note #2 #1 #1
+    \note #3 #1 #1
+    \note #4 #1 #1
+    \note #5 #1 #1
+    \note #6 #1 #1
+
+}
+
+} }
diff --git a/input/regression/metronome-marking.ly b/input/regression/metronome-marking.ly
new file mode 100644 (file)
index 0000000..1743b64
--- /dev/null
@@ -0,0 +1,17 @@
+
+\header {
+
+    texidoc = "@code{\tempo} directives are printed as metronome markings.
+
+THe marking is left aligned with the time signature, if there is one.
+"
+    
+    }
+
+\version "1.7.18"
+
+\score { \notes \relative c'' {   \tempo \breve = 100 c1 c1 \tempo 8.. = 50 c1 }
+\paper {  raggedright = ##t }
+
+     }
+        
index 332257ff807b8bea12d3b992f4e27534b75489a6..7fc5828206eef619feb4a24bec0ceeda232ee15c 100644 (file)
@@ -468,7 +468,10 @@ HYPHEN             --
                                return MARKUP_HEAD_SCM0_MARKUP1;
                        else if (tag == ly_symbol2scm ("scheme0-scheme1-markup2"))
                                return MARKUP_HEAD_SCM0_SCM1_MARKUP2;
+                       else if (tag == ly_symbol2scm ("scheme0-scheme1-scheme2"))
+                               return MARKUP_HEAD_SCM0_SCM1_SCM2;
                        else {
+                               programming_error ("No parser tag defined for this signature. Abort"); 
                                ly_display_scm (s);
                                assert(false);
                        }
diff --git a/lily/metronome-engraver.cc b/lily/metronome-engraver.cc
new file mode 100644 (file)
index 0000000..32d15ca
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+  mark-engraver.cc -- implement Metronome_mark_engraver
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1998--2003 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include <ctype.h>
+
+#include "bar-line.hh"
+#include "time-signature.hh"
+#include "engraver.hh"
+#include "engraver-group-engraver.hh"
+#include "item.hh"
+
+/**
+  put stuff over or next to  bars.  Examples: bar numbers, marginal notes,
+  rehearsal marks.
+ */
+class Metronome_mark_engraver : public Engraver
+{
+public:
+  TRANSLATOR_DECLARATIONS(Metronome_mark_engraver);
+protected:
+  Item* text_;
+  Grob *   bar_line_;
+  
+protected:
+  virtual void stop_translation_timestep ();
+  virtual void acknowledge_grob (Grob_info);
+  void create_items (Music*);
+  virtual bool try_music (Music *req);
+  virtual void start_translation_timestep ();
+  virtual void process_music ();
+  
+private:
+  Music * mark_req_;
+};
+
+Metronome_mark_engraver::Metronome_mark_engraver ()
+{
+  text_ =0;
+  mark_req_ = 0;
+}
+
+void
+Metronome_mark_engraver::acknowledge_grob (Grob_info inf)
+{
+  if (Bar_line::has_interface (inf.grob_))
+    {
+      bar_line_ = inf.grob_;
+    }
+  else if (text_ && Time_signature::has_interface (inf.grob_))
+    {
+      text_->set_parent (inf.grob_, X_AXIS);
+    }
+}
+
+void 
+Metronome_mark_engraver::stop_translation_timestep ()
+{
+  if (text_)
+    {
+      if (bar_line_ && !text_->get_parent (X_AXIS))
+       text_->set_parent (bar_line_, X_AXIS);
+      
+      text_->set_grob_property ("side-support-elements" , get_property ("stavesFound"));
+      typeset_grob (text_);
+      text_ =0;
+    }
+}
+
+
+void
+Metronome_mark_engraver::create_items (Music *rq)
+{
+  if (text_)
+    return;
+
+  SCM s = get_property ("MetronomeMark");
+  text_ = new Item (s);
+
+  announce_grob(text_, rq->self_scm());
+}
+
+void
+Metronome_mark_engraver::start_translation_timestep ()
+{
+  mark_req_ = 0;
+}
+
+bool
+Metronome_mark_engraver::try_music (Music* r)
+{
+  mark_req_ = r;
+  return true;
+}
+
+void
+Metronome_mark_engraver::process_music ()
+{
+  if (mark_req_)
+    {
+      create_items (mark_req_);
+
+      SCM proc = get_property ("metronomeMarkFormatter");
+      SCM result= scm_call_2 (proc, mark_req_->self_scm (),
+                             daddy_trans_->self_scm()); 
+      
+      text_->set_grob_property ("text", result);
+    }
+}
+
+ENTER_DESCRIPTION(Metronome_mark_engraver,
+/* descr */       "Engrave metro nome marking. This delegates the real work to the function in the metronomeMarkFormatter property",
+/* creats*/       "MetronomeMark",
+/* accepts */     "metronome-change-event",
+/* acks  */       "time-signature-interface bar-line-interface",
+/* reads */       "stavesFound metronomeMarkFormatter",
+/* write */       "");
index e9025b65c224fb00ad1cfdbfad95240901d4af97..09ace3518a03531a56b3676f92471569665ea256 100644 (file)
@@ -308,6 +308,7 @@ yylex (YYSTYPE *s,  void * v)
 %token <scm> MARKUP_HEAD_SCM0
 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
 %token <scm> MARKUP_HEAD_SCM0_SCM1 
+%token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2 
 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
 
 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
@@ -707,7 +708,7 @@ music_output_def_body:
 
 tempo_event:
        TEMPO steno_duration '=' bare_unsigned  {
-               $$ = MY_MAKE_MUSIC("TempoEvent");
+               $$ = MY_MAKE_MUSIC("MetronomeChangeEvent");
                $$->set_mus_property ("tempo-unit", $2);
                $$->set_mus_property ("metronome-count", gh_int2scm ( $4));
        }
@@ -2179,7 +2180,11 @@ full_markup:
                  THIS->lexer_->pop_state ();
                }
        ;
-       
+
+
+/*
+This should be done more dynamically if possible.
+*/ 
 markup:
        STRING {
                $$ = make_simple_markup ($1);
@@ -2205,6 +2210,9 @@ markup:
        | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup {
                $$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED);
        }
+       | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
+               $$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED);
+       }
        | MARKUP_IDENTIFIER {
                $$ = $1;
        }
index b963d593e86581f91aa8e0ae195f513117070f9e..c699aea225fdd6ebf922d1a5b0b65ede9648dd44 100644 (file)
@@ -81,5 +81,5 @@ Tempo_performer::try_music (Music* req)
 
 
 ENTER_DESCRIPTION (Tempo_performer, "","",
-                  "tempo-event",
+                  "metronome-change-event",
                   "","","" );
index 1c85c4c44b0bfa7822ad250147b7ccf9d0c3c0d4..7151edd13ea81128c2a199f2728ec07ff241e04f 100644 (file)
@@ -350,6 +350,7 @@ ScoreContext = \translator {
        \consists "Output_property_engraver"
        \consists "System_start_delimiter_engraver"
        \consists "Mark_engraver"       
+       \consists "Metronome_mark_engraver"     
        \consists "Break_align_engraver"
        \consists "Spacing_engraver"
        \consists "Vertical_align_engraver"
@@ -452,7 +453,7 @@ ScoreContext = \translator {
 
        %%
        bassFigureFormatFunction = #make-bass-figure-markup
-
+       metronomeMarkFormatter = #make-metronome-markup
 
        \grobdescriptions #all-grob-descriptions
 }
index eb9fd179e1a05623e36321bb5e525b282ce4c383..18a53ca20035b0509ed7b6bdd479b0b045ec1f42 100644 (file)
 
     (RehearsalMark
      . (
-       (molecule-callback . ,Text_item::brew_molecule)
+       (molecule-callback . ,brew-new-markup-molecule)
        (X-offset-callbacks . (,Self_alignment_interface::aligned_on_self))
        (Y-offset-callbacks . (,Side_position_interface::aligned_side)) 
        (self-alignment-X . 0)
-
+       (break-align-symbol . time-signature)
        (direction . 1)
        (breakable . #t)
        (font-family . roman)
        (padding . 0.8)
        (meta . ((interfaces . (text-interface side-position-interface font-interface mark-interface self-alignment-interface item-interface ))))
        ))
-    
+     (MetronomeMark
+     . (
+       (molecule-callback . ,brew-new-markup-molecule)
+       (Y-offset-callbacks . (,Side_position_interface::aligned_side)) 
+       (direction . 1)
+       (breakable . #t)
+       (font-family . roman)
+       (break-visibility . ,end-of-line-invisible)
+       (padding . 0.8)
+       (meta . ((interfaces . (text-interface side-position-interface font-interface metronome-mark-interface item-interface))))
+       ))
     (MeasureGrouping
      . (
        (Y-offset-callbacks . (,Side_position_interface::out_of_staff 
index 300785f770dfe5c2514eaa4947d8c7c38f9edcfd..25370f169afd30e4520e0a798450830aa8808258 100644 (file)
@@ -49,6 +49,12 @@ are interesting enough to maintain a hara-kiri staff."
  '(
    ))
 
+(ly:add-interface
+ 'metronome-mark-interface
+ "a rehearsal mark"
+ '(
+   ))
+
 ;;; todo: this is not typesetting info. Move to interpretation.
 (ly:add-interface
  'tablature-interface
index 26df1eef066028060aa3e7e604297bbe46852c2d..0c5cda7036d4f34a1e96bbe5258c1e6ee8cdd0fe 100644 (file)
@@ -226,6 +226,21 @@ L1 is copied, L2 not.
 )
 
 
+(define-public (range x y)
+  "Produce a list of integers starting at Y with X elements."
+  (if (<= x 0)
+      '()
+      (cons y (range (- x 1)  (+ y 1)))
+
+      )
+  )
+
+(define-public (interval-length x)
+  "Length of the number-pair X, when an interval"
+  (max 0 (- (cdr x) (car x)))
+  )
+  
+
 (define (other-axis a)
   (remainder (+ a 1) 2))
   
index 4129d94be046e8171265450fb776b06af9f503c6..5ca516c5bcbb4544520ea317bd39bd88f799b044 100644 (file)
                 (number->string (ly:get-mus-property mus 'denominator))
                 ))
 
+;; metronome marks
+(define-public (make-metronome-markup event context)
+  (let*
+      ((dur  (ly:get-mus-property event 'tempo-unit))
+       (count (ly:get-mus-property event 'metronome-count))
+       (note-mark     (make-note-markup (ly:duration-log dur)
+                                       (ly:duration-dot-count dur)
+                                       1)
+                     )
+       )
+
+    (make-line-markup
+     (list
+      note-mark
+      (make-simple-markup  "=")
+      (make-simple-markup (number->string count))
+      
+  ))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define-public (music-map function music)
index 6f97df349e13758eeab1caa27caaf349fdccf741..e44981c1764d7f49995c4ac6d4ddcc955bf5b977 100644 (file)
@@ -538,11 +538,11 @@ For example, transposed music.")
        (types . (general-music string-number-event event))
        )) 
 
-    (TempoEvent
+    (MetronomeChangeEvent
      . (
        (description .  "Change tempo setting (in beats per minute).")
        (internal-class-name . "Event")
-       (types . (general-music tempo-event event))
+       (types . (general-music metronome-change-event tempo-event event))
        ))
     
     (TextScriptEvent
index 1c3020c45b49c4742758119debd57cc8a9cb6b72..248047def9e973ad7304052e5faf3a43e8f4dc73 100644 (file)
@@ -201,26 +201,77 @@ for the reader.
   (let*
       (
        (log (car rest))
-       (dots (cadr rest))
+       (dot-count (cadr rest))
        (dir (caddr rest))
-       (font (ly:get-font grob props))
+       (font (ly:get-font grob (cons '((font-family .  music)) props)))
+       (stemlen (max 3 (- log 1)))
        (headgl
-       (ly:find-glyph-by-name font (string-append "noteheads-" (number->string log))))
-       (flaggl (if (> log 2)
-                  (ly:find-glyph-by-name
-                   font
-                   (string-append "flags-" (number->string log)
-                                  (if (dir > 0) "u" "d"))) #f))
-       (stemth 0.13)
-       (stemgl (ly:round-filled-box (cons
-                                    (cons 0.0 stemth)
-                                    (cons 0.0 (+ 3.0 0.75)))))
-       )
+       (ly:find-glyph-by-name font (string-append "noteheads-" (number->string (min log 2)))))
 
+       (stemth 0.13)
+       (stemy (* dir stemlen))
+       (attachx (if (> dir 0) (- (cdr (ly:molecule-get-extent headgl X)) stemth)
+                   0))
+       (attachy (* dir 0.28))
+       (stemgl (if (> log 0)
+                  (ly:round-filled-box (cons
+                                    (cons attachx (+ attachx  stemth))
+                                    (cons (min stemy attachy)
+                                          (max stemy attachy)))
+                                   (/ stemth 3)
+                                   ) #f))
+       (dot (ly:find-glyph-by-name font "dots-dot"))
+       (dotwid  (interval-length (ly:molecule-get-extent dot X)))
+       (dots (if (> dot-count 0)
+                (reduce
+                 (lambda (x y)
+                   (ly:molecule-add x y))
+                 (map (lambda (x)
+                        (ly:molecule-translate-axis
+                         dot  (* (+ 1 (* 2 x)) dotwid) X) )
+                      (range dot-count 1)))
+                #f
+                ))
+       
+       (flaggl (if (> log 2)
+                  (ly:molecule-translate
+                   (ly:find-glyph-by-name
+                    font
+                    (string-append "flags-"
+                                   (if (> dir 0) "u" "d")
+                                   (number->string log)
+                                   ))
+                   (cons (+ attachx (/ stemth 2)) stemy))
+
+                   #f)))
+    
+    (if flaggl
+       (set! stemgl (ly:molecule-add flaggl stemgl)))
 
+    (if (ly:molecule? stemgl)
+       (set! stemgl (ly:molecule-add stemgl headgl))
+        (set! stemgl headgl)
+       )
+    
+    (if (ly:molecule? dots)
+       (set! stemgl
+             (ly:molecule-add
+              (ly:molecule-translate-axis
+               dots
+               (+
+                (if (and (> dir 0) (> log 2))
+                    (* 1.5 dotwid) 0)
+                ;; huh ? why not necessary?
+               ;(cdr (ly:molecule-get-extent headgl X))
+                     dotwid
+                )
+               X)
+              stemgl 
+              )
+             ))
 
-    #f
-  ))
+    stemgl
+    ))
 
 (define-public (normal-size-super-markup grob props . rest)
   (ly:molecule-translate-axis (interpret-markup
index 94b7cb445c77e63d6155c9c6fb4834c6b291ce7a..ce325a021e0ecd4a8c5806dfdc2041fa5e8364e3 100644 (file)
@@ -297,6 +297,9 @@ the start of the music.
 whether a melisma is active. This can be used to signal melismas on
 top of those automatically detected. ")
 (translator-property-description 'melismaEngraverBusy boolean? "See melismaBusy. This is set automatically.")
+(translator-property-description 'metronomeMarkFormatter procedure?
+                                "How to produce a metronome markup.
+Called with 2 arguments,  event and context.")
 (translator-property-description 'midiInstrument string? "Name of the
 MIDI instrument to use ")
 (translator-property-description 'midiMinimumVolume number? "[DOCUMENT-ME]")
index 5d1b35d46cbad88bade76ee48ed6f9c3c34fd044..981611d984702503d223f1d85007758a7325c38d 100644 (file)
@@ -1345,6 +1345,8 @@ def write_deps (fn, target, chunks):
        read_files = []
 
 def check_texidoc (chunks):
+       ## TODO: put file name in front of texidoc. 
+       ##
        n = []
         for c in chunks:
                if c[0] == 'lilypond':