From 508ba0284d552c84f99272238ab4f74f9ca14246 Mon Sep 17 00:00:00 2001
From: Valentin Villenave <valentin@localhost.(none)>
Date: Sun, 19 Oct 2008 12:43:39 +0200
Subject: [PATCH] new showFirstLength feature

This commit implements a showFirstLength property, that does
the opposite of showLastLength (both properties may be set,
in this case the beginning and the end of the piece are printed,
with a double barline as a separator).

When only showFirstLength is set, the 'length property is
overriden (except if already shorter than the specified first
length) and therefore the compilation will be much faster.

This new feature may be very convenient, e.g. to print the
index of a book containing only the beginning of each \score.
---
 .../skiptypesetting-show-last-or-first.ly          |   27 +++++
 input/regression/skiptypesetting-show-last.ly      |   18 ---
 scm/music-functions.scm                            |  110 ++++++++++++++------
 3 files changed, 107 insertions(+), 48 deletions(-)
 create mode 100644 input/regression/skiptypesetting-show-last-or-first.ly
 delete mode 100644 input/regression/skiptypesetting-show-last.ly

diff --git a/input/regression/skiptypesetting-show-last-or-first.ly b/input/regression/skiptypesetting-show-last-or-first.ly
new file mode 100644
index 0000000..432298b
--- /dev/null
+++ b/input/regression/skiptypesetting-show-last-or-first.ly
@@ -0,0 +1,27 @@
+\header {
+
+  texidoc = "@code{showLastLength} will only show the last bit of a score;
+@code{showFirstLength} will only show the beginning."
+
+  }
+
+\version "2.11.63"
+  
+  
+music = {
+  c1 d e f g a
+}
+
+showLastLength = R1*3
+
+\new Staff \music
+
+showLastLength = ""
+showFirstLength = R1*2
+
+\new Staff \music
+
+showLastLength = R1*2
+showFirstLength = R1
+
+\new Staff \music
diff --git a/input/regression/skiptypesetting-show-last.ly b/input/regression/skiptypesetting-show-last.ly
deleted file mode 100644
index def23fc..0000000
--- a/input/regression/skiptypesetting-show-last.ly
+++ /dev/null
@@ -1,18 +0,0 @@
-\header {
-
-  texidoc = "@code{showLastLength} will only show the last bit of a score"
-
-  }
-
-\version "2.11.51"
-
-showLastLength = R1*3
-\paper {
-  ragged-right = ##T
-}
-
-{
-  c1 c1
-  c1 c1
-  c1 c1
-}
diff --git a/scm/music-functions.scm b/scm/music-functions.scm
index 490cafe..ac8d9a2 100644
--- a/scm/music-functions.scm
+++ b/scm/music-functions.scm
@@ -823,40 +823,90 @@ Syntax:
 	(ly:music-length music))
   music)
 
-(define (skip-to-last music parser)
-
-  "Replace MUSIC by
-
-<< { \\set skipTypesetting = ##t
-     LENGTHOF(\\showLastLength)
-     \\set skipTypesetting = ##t  }
+(define (skip-this mus)
+  "set skipTypesetting, make SkipMusic of the given MUS length,
+   and then unset skipTypesetting."
+          (make-sequential-music
+           (list
+            (context-spec-music (make-property-set 'skipTypesetting #t)
+              'Score)
+            (make-music 'SkipMusic 'duration
+            (ly:make-duration 0 0
+             (ly:moment-main-numerator mus)
+             (ly:moment-main-denominator mus)))
+            (context-spec-music (make-property-set 'skipTypesetting #f)
+              'Score))))
+
+(define (unskip-this mus)
+ "unset skipTypesetting if set, make SkipMusic of the given MUS length,
+   and then set skipTypesetting."
+          (make-sequential-music
+           (list
+            (context-spec-music (make-property-set 'skipTypesetting #f)
+              'Score)
+            (make-music 'SkipMusic 'duration
+            (ly:make-duration 0 0
+             (ly:moment-main-numerator mus)
+             (ly:moment-main-denominator mus)))
+            (context-spec-music (make-property-set 'skipTypesetting #t)
+              'Score))))
+
+(define (skip-as-needed music parser)
+    "Replace MUSIC by
+    << {  \\set skipTypesetting = ##f
+    LENGTHOF(\\showFirstLength)
+     \\set skipTypesetting = ##t
+    LENGTHOF(\\showLastLength) }
     MUSIC >>
-
-if appropriate.
- "
+    if appropriate.
+    
+    When only showFirstLength is set,
+    the 'length property of the music is
+    overridden to speed up compiling."
   (let*
-      ((show-last  (ly:parser-lookup parser 'showLastLength)))
+      ((show-last  (ly:parser-lookup parser 'showLastLength))
+       (show-first  (ly:parser-lookup parser 'showFirstLength)))
+   (cond
     
-    (if (ly:music? show-last)
-	(let*
+      ;; both properties may be set.
+    ((and (ly:music? show-first) (ly:music? show-last))
+       (let*
+        ((orig-length (ly:music-length music))
+	       (skip-length (ly:moment-sub orig-length (ly:music-length show-last)))
+         (begin-length (ly:music-length show-first)))
+         (make-simultaneous-music
+          (list
+           (make-sequential-music
+            (list
+             (skip-this skip-length)
+             ;; let's draw a separator between the beginning and the end
+             (make-music 'PropertySet 'value "||"
+                         'symbol 'whichBar)))
+           (unskip-this begin-length)
+           music))))
+
+       ;; we may only want to print the last length
+    ((ly:music? show-last)
+     (let*
 	    ((orig-length (ly:music-length music))
 	     (skip-length (ly:moment-sub orig-length (ly:music-length show-last))))
-
-	  (make-simultaneous-music
-	   (list
-	    (make-sequential-music
-	     (list
-	      (context-spec-music (make-property-set 'skipTypesetting #t)
-				  'Score)
-	      (make-music 'SkipMusic 'duration
-			  (ly:make-duration
-			   0 0
-			   (ly:moment-main-numerator skip-length)
-			   (ly:moment-main-denominator skip-length)))
-	      (context-spec-music (make-property-set 'skipTypesetting #f)
-				  'Score)))
-	    music)))
-	music)))
+       (make-simultaneous-music
+        (list
+         (skip-this skip-length)
+         music))))
+
+       ;; we may only want to print the beginning; in this case
+       ;; only the first length will be processed (much faster).
+    ((ly:music? show-first)
+      (let*
+       ((orig-length (ly:music-length music))
+        (begin-length (ly:music-length show-first)))
+          ;; the first length must not exceed the original length.
+        (if (ly:moment<? begin-length orig-length)
+         (set! (ly:music-property music 'length)
+          (ly:music-length show-first)))
+        music))
+	  (else music))))
     
 
 (define-public toplevel-music-functions
@@ -872,7 +922,7 @@ if appropriate.
    (lambda (x parser) (music-map cue-substitute x))
  
    (lambda (x parser)
-     (skip-to-last x parser)
+     (skip-as-needed x parser)
    )))
 
 
-- 
1.6.0.2

