From dcb458c225534895f69f4c05137809d20d6a79b9 Mon Sep 17 00:00:00 2001
From: =?utf8?q?=C3=89tienne=20Beaul=C3=A9?= <beauleetienne0@gmail.com>
Date: Fri, 4 Aug 2017 02:21:44 -0300
Subject: [PATCH] Add '-dcrop' option to ps and svg backends

This change allows the output of scores in the format provided by the
'-dpreview' option but including all systems, not just the first.

This would allow for easier SVG use in HTML, without the need for
cropping snippets. Further, SVG is an HTML standard, and its vector
nature makes its use unparalleled for the web. This change would allow
SVG use in 'lilypond-book' in the future.
---
 Documentation/changes.tely        |  4 ++++
 Documentation/usage/running.itely |  6 +++++-
 lily/paper-book.cc                | 19 +++++++++++++++++++
 scm/framework-ps.scm              | 16 ++++++++++++++++
 scm/framework-svg.scm             |  8 ++++++++
 scm/lily.scm                      |  3 +++
 6 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/Documentation/changes.tely b/Documentation/changes.tely
index 482bbbdd65..3428a08494 100644
--- a/Documentation/changes.tely
+++ b/Documentation/changes.tely
@@ -61,6 +61,10 @@ which scares away people.
 
 @end ignore
 
+@item
+An argument, @code{-dcrop}, has been added, formatting @code{SVG} and
+@code{PDF} output without margins or page-breaks.
+
 @item
 It is now possible to move systems with reference to their current
 position using the @code{extra-offset} subproperty of
diff --git a/Documentation/usage/running.itely b/Documentation/usage/running.itely
index 4eeabc80dc..1fe748d93a 100644
--- a/Documentation/usage/running.itely
+++ b/Documentation/usage/running.itely
@@ -505,6 +505,10 @@ in case an SVG viewer is unable to handle them.  When using
 block.  See @ruser{Extracting fragments of music}.  No fragments are
 extracted though if used with the @option{-dno-print-pages} option.
 
+@item @code{crop}
+@tab @code{#f}
+@tab Match the size of the normal output to the typeset image.
+
 @item @code{datadir}
 @tab
 @tab Prefix for data files (read-only).
@@ -672,7 +676,7 @@ To suppress the usual output, use the @option{-dprint-pages} or
 @item @code{print-pages}
 @tab @code{#t}
 @tab Generate full pages, the default.  @option{-dno-print-pages} is
-useful in combination with @option{-dpreview}.
+useful in combination with @option{-dpreview} or @option{-dcrop}.
 
 @item @code{profile-property-accesses}
 @tab @code{#f}
diff --git a/lily/paper-book.cc b/lily/paper-book.cc
index c17ed576f1..f1787e9955 100644
--- a/lily/paper-book.cc
+++ b/lily/paper-book.cc
@@ -219,6 +219,25 @@ Paper_book::output (SCM output_channel)
         warning (_f ("program option -dpreview not supported by backend `%s'",
                      get_output_backend_name ()));
     }
+
+  if (get_program_option ("crop"))
+    {
+      SCM framework
+        = ly_module_lookup (mod, ly_symbol2scm ("output-crop-framework"));
+
+      if (scm_is_true (framework))
+        {
+          SCM func = scm_variable_ref (framework);
+          scm_call_4 (func,
+                      output_channel,
+                      self_scm (),
+                      scopes,
+                      dump_fields ());
+        }
+      else
+        warning (_f ("program option -dcrop not supported by backend `%s'",
+                     get_output_backend_name ()));
+    }
 }
 
 void
diff --git a/scm/framework-ps.scm b/scm/framework-ps.scm
index 2cd9b5edc6..a9c5de2823 100644
--- a/scm/framework-ps.scm
+++ b/scm/framework-ps.scm
@@ -866,6 +866,22 @@ mark {ly~a_stream} /CLOSE pdfmark
                         #t
                         )))
 
+(define-public (output-crop-framework basename book scopes fields)
+  (let* ((paper (ly:paper-book-paper book))
+         (systems (relevant-book-systems book)))
+    (dump-stencil-as-EPS paper
+                         (stack-stencils Y DOWN 0.0
+                                         (map paper-system-stencil
+                                              (reverse (reverse systems))))
+                         (format #f "~a.cropped" basename)
+                         #t)
+    (postprocess-output book framework-ps-module
+                        (cons "png" (ly:output-formats))
+                        (format #f "~a.cropped" basename)
+                        (format #f "~a.cropped.eps" basename)
+                        #t
+                        )))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define (output-width-height defs)
diff --git a/scm/framework-svg.scm b/scm/framework-svg.scm
index a4cf2e9960..85cbe1c2c1 100644
--- a/scm/framework-svg.scm
+++ b/scm/framework-svg.scm
@@ -197,3 +197,11 @@ src: url('~a');
                                   (map paper-system-stencil
                                        (reverse to-dump-systems)))
                   (format #f "~a.preview.svg" basename))))
+
+(define (output-crop-framework basename book scopes fields)
+  (let* ((paper (ly:paper-book-paper book))
+         (systems (relevant-book-systems book))
+         (page-stencils (stack-stencils Y DOWN 0.0
+                                        (map paper-system-stencil
+                                             (reverse (reverse systems))))))
+    (dump-preview paper page-stencils (format #f "~a.cropped.svg" basename))))
diff --git a/scm/lily.scm b/scm/lily.scm
index 4b3c9c7e1c..5e727f1a58 100644
--- a/scm/lily.scm
+++ b/scm/lily.scm
@@ -228,6 +228,9 @@ EPS backend.")
     (clip-systems
      #f
      "Generate cut-out snippets of a score.")
+    (crop
+     #f
+     "Match the size of the normal output to the typeset image.")
     (datadir
      #f
      "LilyPond prefix for data files (read-only).")
-- 
2.39.5