]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 3727: Allow header blocks and output definitions in \score to precede music
authorDavid Kastrup <dak@gnu.org>
Sat, 14 Dec 2013 19:59:30 +0000 (20:59 +0100)
committerDavid Kastrup <dak@gnu.org>
Thu, 19 Dec 2013 10:56:45 +0000 (11:56 +0100)
This addresses a frequent complaint of users.

input/regression/header-score-reordered.ly [new file with mode: 0644]
lily/parser.yy

diff --git a/input/regression/header-score-reordered.ly b/input/regression/header-score-reordered.ly
new file mode 100644 (file)
index 0000000..acbe127
--- /dev/null
@@ -0,0 +1,22 @@
+\version "2.19.0"
+\header {
+  texidoc="
+Header blocks may appear before and after the actual music in a score.
+"
+}
+
+\markup \vspace #3
+\markup { \bold Note: expect piece and opus. }
+\markup \vspace #3
+
+\score {
+  \header {
+    piece = "Piece correct (set in score)"
+    opus = "Opus incorrect (to be superseded at score level)"
+  }
+  \new Staff { c'1 }
+  \header {
+    % This should NOT overwrite the piece from above!
+    opus = "Opus correct (superseded at score level)"
+  }
+}
index f90dfd0799b5cea5c973fa05ea5950add6e7cec5..ee705a57617e0bcab39a2c7d94db880d2a8a15ad 100644 (file)
@@ -878,12 +878,58 @@ score_block:
        }
        ;
 
+score_headers:
+       /* empty */
+       {
+               $$ = SCM_EOL;
+       }
+       | score_headers
+       {
+               if (!scm_is_pair ($1)
+                   || !ly_is_module (scm_car ($1)))
+                       $1 = scm_cons (ly_make_module (false), $1);
+               parser->lexer_->add_scope (scm_car ($1));
+       } lilypond_header
+       {
+               $$ = $1;
+       }
+       | score_headers output_def
+       {
+                Output_def *od = unsmob_output_def ($2);
+               if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
+               {
+                       parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
+
+               }
+               else
+               {
+                       if (scm_is_pair ($1) && ly_is_module (scm_car ($1)))
+                               scm_set_cdr_x ($1, scm_cons ($2, scm_cdr ($1)));
+                       else
+                               $$ = scm_cons ($2, $1);
+               }
+       }
+       ;
+
+               
+
 score_body:
-       music {
+       score_headers music {
                SCM scorify = ly_lily_module_constant ("scorify-music");
-               $$ = scm_call_2 (scorify, $1, parser->self_scm ());
+               $$ = scm_call_2 (scorify, $2, parser->self_scm ());
 
-               unsmob_score ($$)->origin ()->set_spot (@$);
+               unsmob_score ($$)->origin ()->set_spot (@2);
+               if (scm_is_pair ($1) && ly_is_module (scm_car ($1)))
+               {
+                       unsmob_score ($$)->set_header (scm_car ($1));
+                       $1 = scm_cdr ($1);
+               }
+               for (SCM p = scm_reverse_x ($1, SCM_EOL);
+                    scm_is_pair (p); p = scm_cdr (p))
+               {
+                       unsmob_score ($$)->
+                               add_output_def (unsmob_output_def (scm_car (p)));
+               }
        }
        | embedded_scm_active {
                Score *score;