lilypond-devel
[Top][All Lists]

Re: [PATCH] New margin handling - final version (updated)

 From: Michael Käppler Subject: Re: [PATCH] New margin handling - final version (updated) Date: Sat, 26 Sep 2009 09:26:46 +0200 User-agent: Thunderbird 2.0.0.12 (X11/20071114)

```
```
```This comment reveals a larger issue than the code it comments, so I
suggest to move it away from lilypond-book.py and rewrite it in Git
commit message and/or an issue on the tracker.
```
```Here you are.

Valentin, can you please open a new issue on the tracker for this?
I suggest the following message:

```
Lilypond-book writes some \paper settings to the output files for further processing, e.g. it sets for default an estimated line-width. There is also a left_padding set by default, for which lilypond-book output the following line: #(define line-width (- line-width (* left_padding mm))). This is ugly, first because it requires a line-width default and second because it could be integrated in one line. To sum up, lilypond-book should compute one line-width instead of handling different constructs that exclude each other. (Look around lilypond-book.py:614)
```
Regards,
Michael
```
```>From c6a065824ad99c7611ec37561c5f399ccb79b8d5 Mon Sep 17 00:00:00 2001
Date: Sat, 12 Sep 2009 01:47:00 +0200
Subject: [PATCH] Introduce new handling for paper margin settings.

* Make default margins accessible in ly/paper-defaults-init.ly

* Introduce a new method: Output_def::normalize (). It checks,
whether left-margin, right-margin and/or line-width are set.
Afterwards it computes missing values or takes defaults, if
necessary. There is no need to specify line-width manually now.

* Make right-margin work

* If only line-width is set, the current behaviour persists.
(Systems are centered)

* Output a warning if the margin values don't fit with each other or
systems run off the page due to improper settings

* Modify lilypond-book to set a default line-width in case there
is no other to base on left-padding (This is ugly, though)
---
input/regression/paper-margins-consistency.ly  |   19 +++++
input/regression/paper-margins-left-margin.ly  |   13 +++
input/regression/paper-margins-line-width.ly   |   13 +++
input/regression/paper-margins-no-checks.ly    |   18 +++++
input/regression/paper-margins-overrun.ly      |   18 +++++
input/regression/paper-margins-right-margin.ly |   13 +++
input/regression/paper-margins.ly              |   14 ++++
lily/book.cc                                   |    1 +
lily/include/output-def.hh                     |    3 +-
lily/output-def.cc                             |   97 ++++++++++++++++++++++-
lily/paper-book.cc                             |   11 +++-
ly/paper-defaults-init.ly                      |    8 ++-
scm/page.scm                                   |    6 +-
scm/paper.scm                                  |   18 ++---
scripts/lilypond-book.py                       |   11 +++
15 files changed, 239 insertions(+), 24 deletions(-)
create mode 100644 input/regression/paper-margins-consistency.ly
create mode 100644 input/regression/paper-margins-left-margin.ly
create mode 100644 input/regression/paper-margins-line-width.ly
create mode 100644 input/regression/paper-margins-no-checks.ly
create mode 100644 input/regression/paper-margins-overrun.ly
create mode 100644 input/regression/paper-margins-right-margin.ly
create mode 100644 input/regression/paper-margins.ly

diff --git a/input/regression/paper-margins-consistency.ly
b/input/regression/paper-margins-consistency.ly
new file mode 100644
index 0000000..237cd68
--- /dev/null
+++ b/input/regression/paper-margins-consistency.ly
@@ -0,0 +1,19 @@
+\version "2.13.4"
+
+#(ly:set-option 'warning-as-error #f)
+
+  texidoc = "Margin values must fit the line-width, that means: paper-width =
+  line-width + left-margin + right-margin. In case they do not, default margins
+  are set and a warning is printed."
+}
+
+someNotes = \relative c' { \repeat unfold 40 { c4 d e f }}
+
+\paper {
+  left-margin = 20 \mm
+  right-margin = 40 \mm
+  line-width = 100 \mm
+}
+
+\score { \someNotes }
diff --git a/input/regression/paper-margins-left-margin.ly
b/input/regression/paper-margins-left-margin.ly
new file mode 100644
index 0000000..bcae7c9
--- /dev/null
+++ b/input/regression/paper-margins-left-margin.ly
@@ -0,0 +1,13 @@
+\version "2.13.4"
+
+  texidoc = "Here only left-margin is given, right-margin will remain default."
+}
+
+someNotes = \relative c' { \repeat unfold 40 { c4 d e f }}
+
+\paper {
+  left-margin = 40 \mm
+}
+
+\score { \someNotes }
diff --git a/input/regression/paper-margins-line-width.ly
b/input/regression/paper-margins-line-width.ly
new file mode 100644
index 0000000..b741e6e
--- /dev/null
+++ b/input/regression/paper-margins-line-width.ly
@@ -0,0 +1,13 @@
+\version "2.13.4"
+
+  texidoc = "If only line-width is given, systems are vertically centered."
+}
+
+someNotes = \relative c' { \repeat unfold 40 { c4 d e f }}
+
+\paper {
+  line-width = 100 \mm
+}
+
+\score { \someNotes }
diff --git a/input/regression/paper-margins-no-checks.ly
b/input/regression/paper-margins-no-checks.ly
new file mode 100644
index 0000000..e3ab459
--- /dev/null
+++ b/input/regression/paper-margins-no-checks.ly
@@ -0,0 +1,18 @@
+\version "2.13.4"
+
+  texidoc = "All checks can be avoided by setting check-consistency to ##f in
\paper."
+}
+
+someNotes = \relative c' { \repeat unfold 40 { c4 d e f }}
+
+\paper {
+  left-margin = 20 \mm
+  right-margin = 40 \mm
+  line-width = 200 \mm
+  check-consistency = ##f
+}
+
+\score { \someNotes }
+
+
diff --git a/input/regression/paper-margins-overrun.ly
b/input/regression/paper-margins-overrun.ly
new file mode 100644
--- /dev/null
+++ b/input/regression/paper-margins-overrun.ly
@@ -0,0 +1,18 @@
+\version "2.13.4"
+
+#(ly:set-option 'warning-as-error #f)
+
+  texidoc = "Normally, margin settings must not cause systems to run off the
page."
+}
+
+#(set-default-paper-size "a4")
+
+someNotes = \relative c' { \repeat unfold 40 { c4 d e f }}
+
+\paper {
+  left-margin = 20 \mm
+  line-width = 200 \mm
+}
+
+\score { \someNotes }
diff --git a/input/regression/paper-margins-right-margin.ly
b/input/regression/paper-margins-right-margin.ly
new file mode 100644
index 0000000..6b50659
--- /dev/null
+++ b/input/regression/paper-margins-right-margin.ly
@@ -0,0 +1,13 @@
+\version "2.13.4"
+
+  texidoc = "Here only right-margin is given, left-margin will remain default."
+}
+
+someNotes = \relative c' { \repeat unfold 40 { c4 d e f }}
+
+\paper {
+  right-margin = 40 \mm
+}
+
+\score { \someNotes }
diff --git a/input/regression/paper-margins.ly
b/input/regression/paper-margins.ly
new file mode 100644
index 0000000..25e92b8
--- /dev/null
+++ b/input/regression/paper-margins.ly
@@ -0,0 +1,14 @@
+\version "2.13.4"
+
+  texidoc = "Paper margin settings do not have to be complete. Missing values
are
+  added automatically. If no paper settings are specified, default values are
+  used."
+}
+
+someNotes = \relative c' { \repeat unfold 40 { c4 d e f }}
+
+\paper { }
+
+\score { \someNotes }
+
diff --git a/lily/book.cc b/lily/book.cc
index 303af1b..86eeda1 100644
--- a/lily/book.cc
+++ b/lily/book.cc
@@ -277,6 +277,7 @@ Book::process (Output_def *default_paper,
}
else
{
+      paper_book->paper_->normalize ();
/* Process scores */
/* Render in order of parsing.  */
for (SCM s = scm_reverse (scores_); scm_is_pair (s); s = scm_cdr (s))
diff --git a/lily/include/output-def.hh b/lily/include/output-def.hh
index b683cc6..9e28d18 100644
--- a/lily/include/output-def.hh
+++ b/lily/include/output-def.hh
@@ -58,13 +58,14 @@ public:
SCM c_variable (string id) const;
SCM lookup_variable (SCM sym) const;
void set_variable (SCM sym, SCM val);
+  void normalize ();
Real get_dimension (SCM symbol) const;
};
SCM get_font_table (Output_def *def);
void assign_context_def (Output_def *m, SCM transdef);
SCM find_context_def (Output_def const *m, SCM name);

-Interval line_dimensions_int (Output_def*def, int);
+Interval line_dimensions_int (Output_def *def, int);

Font_metric *select_encoded_font (Output_def *layout, SCM chain);
diff --git a/lily/output-def.cc b/lily/output-def.cc
index f9fbda9..8ee7952 100644
--- a/lily/output-def.cc
+++ b/lily/output-def.cc
@@ -11,6 +11,7 @@
#include "context-def.hh"
#include "file-path.hh"
#include "global-context.hh"
+#include "international.hh"
#include "interval.hh"
#include "main.hh"
#include "output-def.hh"
@@ -29,7 +30,7 @@ Output_def::Output_def ()
parent_ = 0;

smobify_self ();
-
+
scope_ = ly_make_anonymous_module (false);
}

@@ -75,7 +76,7 @@ assign_context_def (Output_def * m, SCM transdef)
{
SCM sym = tp->get_context_name ();
m->set_variable (sym, transdef);
-    }
+    }
}

/* find the translator for NAME. NAME must be a symbol. */
@@ -109,10 +110,10 @@ Output_def::lookup_variable (SCM sym) const
SCM var = ly_module_lookup (scope_, sym);
if (SCM_VARIABLEP (var) && SCM_VARIABLE_REF (var) != SCM_UNDEFINED)
return SCM_VARIABLE_REF (var);
-
+
if (parent_)
return parent_->lookup_variable (sym);
-
+
return SCM_UNDEFINED;
}

@@ -128,7 +129,93 @@ Output_def::set_variable (SCM sym, SCM val)
scm_module_define (scope_, sym, val);
}

-
+void
+Output_def::normalize ()
+{
+  Real paper_width;
+  SCM scm_paper_width = c_variable ("paper-width");
+
+  Real left_margin, left_margin_default;
+  SCM scm_left_margin_default = c_variable ("left-margin-default");
+  SCM scm_left_margin = c_variable ("left-margin");
+
+  Real right_margin, right_margin_default;
+  SCM scm_right_margin_default = c_variable ("right-margin-default");
+  SCM scm_right_margin = c_variable ("right-margin");
+
+  if (scm_paper_width == SCM_UNDEFINED
+      || scm_left_margin_default == SCM_UNDEFINED
+      || scm_right_margin_default == SCM_UNDEFINED)
+    {
+      programming_error ("called normalize() on paper with missing settings");
+      return;
+    }
+  else
+    {
+      paper_width = scm_to_double (scm_paper_width);
+      left_margin_default = scm_to_double (scm_left_margin_default);
+      right_margin_default = scm_to_double (scm_right_margin_default);
+    }
+
+  Real line_width;
+  Real line_width_default = paper_width - left_margin_default -
right_margin_default;
+  SCM scm_line_width = c_variable ("line-width");
+
+  if (scm_line_width == SCM_UNDEFINED)
+    {
+      left_margin = ((scm_left_margin == SCM_UNDEFINED) ? left_margin_default
: scm_to_double(scm_left_margin));
+      right_margin = ((scm_right_margin == SCM_UNDEFINED) ?
right_margin_default : scm_to_double(scm_right_margin));
+      line_width = paper_width - left_margin - right_margin;
+    }
+  else
+    {
+      line_width = scm_to_double (scm_line_width);
+      if (scm_left_margin == SCM_UNDEFINED)
+        {
+          if (scm_right_margin == SCM_UNDEFINED) // Vertically center systems
if only line-width is given
+            {
+              left_margin = (paper_width - line_width) / 2;
+              right_margin = left_margin;
+            }
+          else
+            {
+              right_margin = scm_to_double (scm_right_margin);
+              left_margin = paper_width - line_width - right_margin;
+            }
+        }
+      else
+        {
+          left_margin = scm_to_double (scm_left_margin);
+          right_margin = ((scm_right_margin == SCM_UNDEFINED)
+                           ? (paper_width - line_width - left_margin)
+                           : scm_to_double (scm_right_margin));
+        }
+    }
+
+  if (to_boolean (c_variable ("check-consistency")))
+    {
+      // Consistency checks. If values don't match, set defaults.
+      if (abs(paper_width - line_width - left_margin - right_margin) > 1e-6)
+        {
+          line_width = line_width_default;
+          left_margin = left_margin_default;
+          right_margin = right_margin_default;
+          warning (_ ("margins do not fit with line-width, setting default
values"));
+        }
+      else if ((left_margin < 0) || (right_margin < 0))
+        {
+          line_width = line_width_default;
+          left_margin = left_margin_default;
+          right_margin = right_margin_default;
+          warning (_ ("systems run off the page due to improper paper
settings, setting default values"));
+        }
+    }
+
+  set_variable (ly_symbol2scm ("left-margin"), scm_from_double (left_margin));
+  set_variable (ly_symbol2scm ("right-margin"), scm_from_double
(right_margin));
+  set_variable (ly_symbol2scm ("line-width"), scm_from_double (line_width));
+}
+
/* FIXME.  This is broken until we have a generic way of
putting lists inside the \layout block.  */
Interval
diff --git a/lily/paper-book.cc b/lily/paper-book.cc
index 3db1321..12a7f09 100644
--- a/lily/paper-book.cc
+++ b/lily/paper-book.cc
@@ -159,12 +159,21 @@ Paper_book::output (SCM output_channel)
{
int first_page_number = robust_scm2int (paper_->c_variable
("first-page-number"), 1);
int first_performance_number = 0;
+
+  /* FIXME: We need a line-width for ps output (framework-ps.scm:92). If we
don't have any, we take the paper-width
+     unless we know better which line-width to choose (e.g. if there are
\bookparts with different line-widths)
+     and why we need it at all. */
+
+  if (paper_->c_variable ("line-width") == SCM_UNDEFINED)
+    paper_->set_variable (ly_symbol2scm ("line-width"), paper_->c_variable
("paper-width"));
+
if (!output_aux (output_channel,
true,
&first_page_number,
&first_performance_number))
return;
-
+
+
SCM scopes = SCM_EOL;
diff --git a/ly/paper-defaults-init.ly b/ly/paper-defaults-init.ly
index 1ee92ed..4db5459 100644
--- a/ly/paper-defaults-init.ly
+++ b/ly/paper-defaults-init.ly
@@ -86,11 +86,17 @@

\include "titling-init.ly"

+  check-consistency = ##t
+
top-margin = 5 \mm
bottom-margin = 6 \mm
+
+  left-margin-default = 10 \mm
+  right-margin-default = 10 \mm
+
foot-separation = 4 \mm

first-page-number = #1
-  print-first-page-number =##f
+  print-first-page-number = ##f
}
diff --git a/scm/page.scm b/scm/page.scm
index ca4e0d8..959402c 100644
--- a/scm/page.scm
+++ b/scm/page.scm
@@ -184,11 +184,7 @@
(let*
((paper-height (ly:output-def-lookup layout 'paper-height))
(paper-width (ly:output-def-lookup layout 'paper-width))
-       (lmargin (ly:output-def-lookup layout 'left-margin #f))
-       (left-margin (if lmargin
-                      lmargin
-                      (/ (- paper-width
-                            (ly:output-def-lookup layout 'line-width)) 2)))
+       (left-margin (ly:output-def-lookup layout 'left-margin))
(bottom-edge (- paper-height
(ly:output-def-lookup layout 'bottom-margin)) )
(top-margin (ly:output-def-lookup layout 'top-margin))
diff --git a/scm/paper.scm b/scm/paper.scm
index 01fa8c0..1eb3b59 100644
--- a/scm/paper.scm
+++ b/scm/paper.scm
@@ -16,6 +16,7 @@
indent
ledger-line-thickness
left-margin
+                    left-margin-default
line-thickness
line-width
mm
@@ -23,6 +24,7 @@
paper-width
pt
right-margin
+                    right-margin-default
short-indent
staff-height
staff-space
@@ -207,23 +209,17 @@ size. SZ is in points"
("f4" . (cons (* 210 mm) (* 330 mm)))
))

-;; todo: take dimension arguments.
+; todo: take dimension arguments.

(define (set-paper-dimensions m w h)
"M is a module (i.e. layout->scope_ )"
-  (let* ((mm (eval 'mm m)))
+  (begin
+    ;; page layout - what to do with (printer specific!) margin settings?
(module-define! m 'paper-width w)
(module-define! m 'paper-height h)
-    (module-define! m 'line-width (- w
-                                    (ly:modules-lookup (list m) 'left-margin
(* 10 mm))
-                                    (ly:modules-lookup (list m) 'right-margin
(* 10 mm))))
-
(module-define! m 'indent (/ w 14))
-    (module-define! m 'short-indent 0)
-
-    ;; page layout - what to do with (printer specific!) margin settings?
-
-    ))
+    (module-define! m 'short-indent 0))
+    (module-remove! m 'line-width))

(define (internal-set-paper-size module name landscape?)
(define (swap x)
diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py
index 8223864..9e7f929 100644
--- a/scripts/lilypond-book.py
+++ b/scripts/lilypond-book.py
@@ -1116,6 +1116,17 @@ class LilypondSnippet (Snippet):
if not INDENT in self.option_dict:
self.option_dict[INDENT] = '0\\mm'

+        # Set a default line-width if there is none. We need this, because
+       # lilypond-book has set left-padding by default and therefore does
+       # #(define line-width (- line-width (* 3 mm)))
+       # TODO: Junk this ugly hack if the code gets rewritten to concatenate
+       # all settings before writing them in the \paper block.
+        if not LINE_WIDTH in self.option_dict:
+           if not QUOTE in self.option_dict:
+               if not LILYQUOTE in self.option_dict:
+                   self.option_dict[LINE_WIDTH] = "#(- paper-width \
+left-margin-default right-margin-default)"
+
def compose_ly (self, code):
if FRAGMENT in self.option_dict:
body = FRAGMENT_LY
--
1.6.0.2

```