layout tweaking.
* input/les-nereides.ly (theScore): Add \book.
* input/test/title-markup.ly: Add \book.
* scm/page-layout.scm (ly:optimal-page-breaks): Debugging output
only if 'verbose.
* lily/include/paper-book.hh (PAGE_LAYOUT): Remove.
* lily/paper-outputter.cc (output_line): Remove PAGE_LAYOUT check.
* tex/lilyponddefs.tex (lilypondstart, lybox, lyitem):
* scm/output-tex.scm (start-system): Update for page layout by
LilyPond.
* scm/output-ps.scm (start-system): Previously (new-start-system).
* lily/paper-outputter.cc (output_header): Uniquify list of fonts
passed to define-fonts.
* lily/paper-column.cc:
* lily/system.cc (get_line):
* ly/property-init.ly (newpage):
* scm/define-grob-properties.scm:
* scm/output-ps.scm:
* scm/output-tex.scm: Remove between-system-string kludge.
* scm/output-ps.scm (define-fonts, font-command,
font-load-encoding): Handle ENCODING = #f.
* scm/output-tex.scm (output-scopes): Check if variable is bound.
2004-04-10 Jan Nieuwenhuizen <janneke@gnu.org>
+ Page layout for SCOREs enclosed in a BOOK:
+
+ * scripts/lilypond.py: Remove LaTeX titling kludge. Remove page
+ layout tweaking.
+
+ * input/les-nereides.ly (theScore): Add \book.
+
+ * input/test/title-markup.ly: Add \book.
+
+ * scm/page-layout.scm (ly:optimal-page-breaks): Debugging output
+ only if 'verbose.
+
+ * lily/include/paper-book.hh (PAGE_LAYOUT): Remove.
+
+ * lily/paper-outputter.cc (output_line): Remove PAGE_LAYOUT check.
+
+ * tex/lilyponddefs.tex (lilypondstart, lybox, lyitem):
+ * scm/output-tex.scm (start-system): Update for page layout by
+ LilyPond.
+
+ * scm/output-ps.scm (start-system): Previously (new-start-system).
+
+ * lily/paper-outputter.cc (output_header): Uniquify list of fonts
+ passed to define-fonts.
+
+ * lily/paper-column.cc:
+ * lily/system.cc (get_line):
+ * ly/property-init.ly (newpage):
+ * scm/define-grob-properties.scm:
+ * scm/output-ps.scm:
+ * scm/output-tex.scm: Remove between-system-string kludge.
+
* scm/output-ps.scm (define-fonts, font-command,
font-load-encoding): Handle ENCODING = #f.
@node Top, , ,
@top
-@unnumbered New features in 2.2 since 2.0
+@unnumbered New features in 2.3 since 2.2
@itemize @bullet
+@item The toplevel block @code{book} introduces page layout.
+A @code{book} groups @code{score} blocks into one page layout entity.
+Page layout consists of markup titles, headers and footers, and page
+breaking. Two page breaking algorithms are available, the classic
+ragged pages (the default), and optimal page breaking
+
+@example
+\paper @{
+ %% Select page breaking function.
+ %% #(define page-breaking ly:ragged-page-breaks)
+ #(define page-breaking ly:optimal-page-breaks)
+@}
+\book @{
+ \score @{ ... @}
+ \score @{ ... @}
+@}
+@end example
+
+The @code{lilypond} program does not generate La@TeX{} titles or page
+layout. If you need La@TeX{} titles, you can use the
+@code{lilypond-book} program.
+
@item The meaning of the @code{|} in the input can be redefined, by
assigning a music expression to @code{pipeSymbol}.
to the top of the page). You can avoid that by setting the variable
@code{lastpagefill} in LilyPond's @code{\paper} block.
+@c FIXME: broken by page layout
It is possible to fine-tune the vertical offset further by defining the
macro @code{\lilypondscoreshift}:
s8\!
}
-
-\score{
+theScore = \score{
\context PianoStaff <<
\context Staff=treble <<
\treble
}
}
}
-
+
+\book{
+ \score { \theScore }
+}
+
%%% Local variables:
%%% LilyPond-indent-level:4
%%% End:
\version "2.2.0"
%{
- Experimental markup titles are available in direct PostScript output:
+ Markup titles also available for direct PostScript output:
export GS_LIB=$(pwd)/mf/out:/usr/share/texmf/fonts/type1/bluesky/cm
lilypond-bin -fps input/title/title-markup.ly
-
-PostScript fonts: WIP.
+ PostScript fonts: WIP.
* Nonstandardised install directory / how to locate a ps font?
* Nonstandardised filenames?
\paper{
#(define page-breaking ly:optimal-page-breaks)
- fonts = #(make-century-schoolbook-tree 1.0)
+ %% Ughr, this breaks TeX output...
+ %% fonts = #(make-century-schoolbook-tree 1.0)
inputencoding = #"latin1"
}
%% bookTitle = \markup { \fill-line < \huge\bold \title > > }
}
-\score {
- \context Staff \notes \relative c' {
- c2-\sizeTest c2-\spaceTest
- }
- \paper {
- %% #(paper-set-staff-size (* 11.0 pt))
- }
-}
-
-\header {
- %% Override automatic score title
- %% scoreTitle = \markup { "Tweetje" }
- opus = "opus 1"
- piece = "Second"
-}
-
-\score {
- \context Staff \notes \relative c' {
- %% stress page breaking:
- %% 35 keep on 3 pages
- %% 36 spread evenly over 4 pages
- \repeat unfold 36 { a b c d \break }
- c1
+\book {
+
+ \score {
+ \context Staff \notes \relative c' {
+ c2-\sizeTest c2-\spaceTest
+ }
+ \paper {
+ %% #(paper-set-staff-size (* 11.0 pt))
+ }
}
- \paper {
+
+ \score {
+ \context Staff \notes \relative c' {
+ %% stress page breaking:
+ %% 35 keep on 3 pages
+ %% 36 spread evenly over 4 pages
+ \repeat unfold 36 { a b c d \break }
+ c1
+ }
+ \header {
+ %% Override automatic score title
+ %% scoreTitle = \markup { "Tweetje" }
+ opus = "opus 1"
+ piece = "Second"
+ }
+ \paper {
+ }
}
-}
+}
\ No newline at end of file
SCM index_set_cell (SCM cell, Direction d, SCM val);
SCM ly_snoc (SCM s, SCM list);
-SCM ly_split_list (SCM s, SCM list);
-SCM ly_unique (SCM list);
+SCM ly_split_list (SCM s, SCM lst);
+SCM ly_unique (SCM lst);
+SCM ly_list_qsort_uniq_x (SCM lst);
#include "protected-scm.hh"
#include "smobs.hh"
-#define PAGE_LAYOUT "ps"
-
class Paper_book
{
+ DECLARE_SMOBS (Paper_book, )
+
public:
Array<SCM> headers_;
Array<SCM> global_headers_;
Stencil* title (int);
void output (String);
void classic_output (String);
- DECLARE_SMOBS (Paper_book, )
};
DECLARE_UNSMOB (Paper_book, paper_book)
class Paper_outputter
{
bool verbatim_scheme_b_;
-public:
- SCM output_func_;
+public:
SCM output_module_;
Protected_scm file_;
-
String basename_;
+
Paper_outputter (String nm);
~Paper_outputter ();
void dump_scheme (SCM);
-
void output_metadata (Paper_def*, SCM);
void output_music_output_def (Music_output_def* odef);
void output_scheme (SCM scm);
return scm_reverse_x (unique, SCM_EOL);
}
+
+static int
+scm_default_compare (void const *a, void const *b)
+{
+ SCM pa = *(SCM*) a;
+ SCM pb = *(SCM*) b;
+ if (pa == pb)
+ return 0;
+ return pa < pb ? -1 : 1;
+}
+
+/* Modify LST in place: qsort it. */
+SCM
+ly_list_qsort_uniq_x (SCM lst)
+{
+ int len = scm_ilength (lst);
+ SCM *arr = new SCM[len];
+ int k = 0;
+ for (SCM s = lst; SCM_NNULLP (s); s = SCM_CDR (s))
+ arr[k++] = SCM_CAR (s);
+
+ assert (k == len);
+ qsort (arr, len, sizeof (SCM), &scm_default_compare);
+
+ SCM *tail = &lst;
+ for (int i = 0; i < len; i++)
+ if (!i || arr[i] != arr[i - 1])
+ {
+ SCM_SETCAR (*tail, arr[i]);
+ tail = SCM_CDRLOC (*tail);
+ }
+
+ *tail = SCM_EOL;
+ delete[] arr;
+
+ return lst;
+}
+
+
/* tail add */
SCM
ly_snoc (SCM s, SCM list)
out->output_scheme (scm_list_1 (ly_symbol2scm ("end-output")));
- /*
- Ugh
- */
- for (int i =pages->size (); i--;)
- delete pages->elem(i);
+ /* Ugh. */
+ for (int i = pages->size (); i--;)
+ delete pages->elem (i);
delete pages;
-
progress_indication ("\n");
}
Paper_outputter *out = papers_.top ()->get_paper_outputter (outname);
out->output_header (papers_.top (), scopes (count - 1), 0);
+ Offset o (0, 0);
int line_count = SCM_VECTOR_LENGTH ((SCM) scores_.top ());
for (int i = 0; i < line_count; i++)
out->output_line (scm_vector_ref ((SCM) scores_.top (), scm_int2num (i)),
- 0, i == line_count - 1);
+ &o, i == line_count - 1);
out->output_scheme (scm_list_1 (ly_symbol2scm ("end-output")));
progress_indication ("\n");
" non-adjacent numbers.\n"
"\n"
,
- "between-cols between-system-string when bounded-by-me "
+ "between-cols when bounded-by-me "
"shortest-playing-duration shortest-starter-duration");
void
Paper_def::Paper_def ()
{
+ /* Do not remove this statement, scm_make_hash_table may trigger GC. */
scaled_fonts_ = SCM_EOL;
- /*
- don't remove above statement, scm_make_hash_table may trigger GC.
- */
scaled_fonts_ = scm_c_make_hash_table (11);
}
-Paper_def::~Paper_def ()
-{
-}
-
Paper_def::Paper_def (Paper_def const&src)
: Music_output_def (src)
{
+ /* Do not remove this statement, scm_make_hash_table may trigger GC. */
scaled_fonts_ = SCM_EOL;
- /*
- don't remove above statement, scm_make_hash_table may trigger GC.
- */
scaled_fonts_ = scm_c_make_hash_table (11);
}
+Paper_def::~Paper_def ()
+{
+}
+
void
Paper_def::derived_mark ()
{
return ly_scm2double (val) / sc;
}
-/*
- FIXME. This is broken until we have a generic way of
- putting lists inside the \paper block.
- */
+/* FIXME. This is broken until we have a generic way of
+ putting lists inside the \paper block. */
Interval
Paper_def::line_dimensions_int (int n) const
{
return Interval (ind, lw);
}
-
-
-
Paper_outputter*
-Paper_def::get_paper_outputter (String outname) const
+Paper_def::get_paper_outputter (String outname) const
{
progress_indication (_f ("paper output to `%s'...",
outname == "-" ? String ("<stdout>") : outname));
- progress_indication("\n");
-
global_input_file->target_strings_.push (outname);
Paper_outputter * po = new Paper_outputter (outname);
Path p = split_path (outname);
return po;
}
-
-
-Font_metric *
+Font_metric*
Paper_def::find_scaled_font (Font_metric *f, Real m, SCM input_enc_name)
{
SCM sizes = scm_hashq_ref (scaled_fonts_, f->self_scm (), SCM_BOOL_F);
return unsmob_metrics (ly_cdr (met));
}
else
- {
- sizes = SCM_EOL;
- }
+ sizes = SCM_EOL;
-
- /*
- Hmm. We're chaining font - metrics. Should consider wether to merge
- virtual-font and scaled_font.
- */
+ /* Hmm. We're chaining font - metrics. Should consider whether to
+ merge virtual-font and scaled_font. */
SCM val = SCM_EOL;
if (Virtual_font_metric * vf = dynamic_cast<Virtual_font_metric*> (f))
{
- /*
- For fontify_atom (), the magnification and name must be known
- at the same time. That's impossible for
+ /* For fontify_atom (), the magnification and name must be known
+ at the same time. That's impossible for
Scaled (Virtual_font (Font1,Font2))
so we replace by
- Virtual_font (Scaled (Font1), Scaled (Font2))
-
- */
- SCM l = SCM_EOL;
- SCM *t = &l;
+ Virtual_font (Scaled (Font1), Scaled (Font2)) */
+ SCM lst = SCM_EOL;
+ SCM *t = &lst;
for (SCM s = vf->get_font_list (); is_pair (s); s = ly_cdr (s))
{
- Font_metric*scaled
- = find_scaled_font (unsmob_metrics (ly_car (s)), m, input_enc_name);
+ Font_metric *scaled = find_scaled_font (unsmob_metrics (ly_car (s)),
+ m, input_enc_name);
*t = scm_cons (scaled->self_scm (), SCM_EOL);
t = SCM_CDRLOC(*t);
}
- vf = new Virtual_font_metric (l);
+ vf = new Virtual_font_metric (lst);
val = vf->self_scm ();
}
else
input_enc_name = scm_variable_ref (var);
}
m /= ly_scm2double (scm_variable_ref (scale_var));
- val = Modified_font_metric::make_scaled_font_metric (input_enc_name, f, m);
+ val = Modified_font_metric::make_scaled_font_metric (input_enc_name,
+ f, m);
}
sizes = scm_acons (scm_make_real (m), val, sizes);
scm_gc_unprotect_object (val);
-
scm_hashq_set_x (scaled_fonts_, f->self_scm (), sizes);
-
return unsmob_metrics (val);
}
-
-/*
- Return alist to translate internally used fonts back to real-world
- coordinates. */
+/* Return alist to translate internally used fonts back to real-world
+ coordinates. */
SCM
Paper_def::font_descriptions () const
{
LY_DEFINE (ly_paper_def_p, "ly:paper-def?",
- 1, 0,0, (SCM def),
+ 1, 0, 0, (SCM def),
"Is @var{def} a paper definition?")
{
Paper_def *op = dynamic_cast<Paper_def*> (unsmob_music_output_def (def));
source file of the GNU LilyPond music typesetter
(c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
- Jan Nieuwenhuizen <janneke@gnu.org>
+ Jan Nieuwenhuizen <janneke@gnu.org>
*/
-#include <time.h>
#include <math.h>
+#include <time.h>
-#include "dimensions.hh"
-#include "virtual-methods.hh"
-#include "paper-outputter.hh"
-#include "stencil.hh"
#include "array.hh"
-#include "string-convert.hh"
-#include "warn.hh"
+#include "dimensions.hh"
#include "font-metric.hh"
-#include "main.hh"
-#include "scm-hash.hh"
-#include "lily-version.hh"
-#include "paper-def.hh"
#include "input-file-results.hh"
+#include "input-smob.hh"
+#include "lily-guile.hh"
+#include "lily-version.hh"
#include "ly-module.hh"
+#include "main.hh"
#include "paper-book.hh"
+#include "paper-def.hh"
#include "paper-line.hh"
-#include "input-smob.hh" // output_expr
+#include "paper-outputter.hh"
+#include "scm-hash.hh"
+#include "stencil.hh"
+#include "string-convert.hh"
+#include "warn.hh"
-Paper_outputter::Paper_outputter (String name)
+Paper_outputter::Paper_outputter (String filename)
{
if (safe_global_b)
scm_define (ly_symbol2scm ("safe-mode?"), SCM_BOOL_T);
- file_ = scm_open_file (scm_makfrom0str (name.to_str0 ()),
+ file_ = scm_open_file (scm_makfrom0str (filename.to_str0 ()),
scm_makfrom0str ("w"));
- if (output_format_global == PAGE_LAYOUT)
+ String module_name = "scm output-" + output_format_global;
+ if (safe_global_b)
{
- output_func_ = SCM_EOL;
- String name = "scm output-" + output_format_global;
- if (safe_global_b)
- {
- /* In safe mode, start from a GUILE safe-module and import
- all symbols from the output module. */
- scm_c_use_module ("ice-9 safe");
- SCM msm = scm_primitive_eval (ly_symbol2scm ("make-safe-module"));
- output_module_ = scm_call_0 (msm);
- ly_import_module (output_module_,
- scm_c_resolve_module (name.to_str0 ()));
- }
- else
- output_module_ = scm_c_resolve_module (name.to_str0 ());
-
- /* FIXME: output-lib should be module, that can be imported. */
+ /* In safe mode, start from a GUILE safe-module and import
+ all symbols from the output module. */
+ scm_c_use_module ("ice-9 safe");
+ SCM msm = scm_primitive_eval (ly_symbol2scm ("make-safe-module"));
+ output_module_ = scm_call_0 (msm);
+ ly_import_module (output_module_,
+ scm_c_resolve_module (module_name.to_str0 ()));
+ }
+ else
+ output_module_ = scm_c_resolve_module (module_name.to_str0 ());
+
+ /* FIXME: output-lib should be module, that can be imported. */
#define IMPORT_LESS 1 // only import the list of IMPORTS
#if IMPORT_LESS
- scm_c_use_module ("lily");
- scm_c_use_module ("ice-9 regex");
- scm_c_use_module ("srfi srfi-13");
+ scm_c_use_module ("lily");
+ scm_c_use_module ("ice-9 regex");
+ scm_c_use_module ("srfi srfi-1");
+ scm_c_use_module ("srfi srfi-13");
#endif
- char const *imports[] = {
- "lilypond-version", /* from lily */
- "ly:output-def-scope",
- "ly:gulp-file",
- "ly:number->string",
- "ly:ragged-page-breaks",
- "ly:optimal-page-breaks",
-
- "ly:number-pair->string", /* output-lib.scm */
- "ly:numbers->string",
- "ly:inexact->string",
-
- "assoc-get",
+ char const *imports[] = {
+ "lilypond-version", /* from lily */
+ "ly:output-def-scope",
+ "ly:gulp-file",
+ "ly:number->string",
+ "ly:ragged-page-breaks",
+ "ly:optimal-page-breaks",
+
+ "ly:number-pair->string", /* output-lib.scm */
+ "ly:numbers->string",
+ "ly:inexact->string",
+
+ "assoc-get",
#if IMPORT_LESS
- "string-index", /* from srfi srfi-13 */
- "string-join",
- "regexp-substitute/global", /* from (ice9 regex) */
+ "remove", /* from srfi srfi-1 */
+ "string-index", /* from srfi srfi-13 */
+ "string-join",
+ "regexp-substitute/global", /* from (ice9 regex) */
#endif
- 0,
- };
+ 0,
+ };
- for (int i = 0; imports[i]; i++)
- {
- SCM s = ly_symbol2scm (imports[i]);
- scm_module_define (output_module_, s, scm_primitive_eval (s));
- }
-#ifndef IMPORT_LESS // rather crude, esp for safe-mode let's not
- SCM m = scm_set_current_module (output_module_);
- /* not present in current module*/
- scm_c_use_module ("ice-9 regex");
- scm_c_use_module ("srfi srfi-13");
- /* Need only a few of these, see above
- scm_c_use_module ("lily"); */
- scm_set_current_module (m);
-#endif
- }
- else
+ for (int i = 0; imports[i]; i++)
{
- output_func_
- = scm_call_1 (ly_scheme_function ("find-dumper"),
- scm_makfrom0str (output_format_global.to_str0 ()));
- output_module_ = SCM_EOL;
+ SCM s = ly_symbol2scm (imports[i]);
+ scm_module_define (output_module_, s, scm_primitive_eval (s));
}
+#ifndef IMPORT_LESS // rather crude, esp for safe-mode let's not
+ SCM m = scm_set_current_module (output_module_);
+ /* not present in current module*/
+ scm_c_use_module ("ice-9 regex");
+ scm_c_use_module ("srfi srfi-13");
+ /* Need only a few of these, see above
+ scm_c_use_module ("lily"); */
+ scm_set_current_module (m);
+#endif
}
Paper_outputter::~Paper_outputter ()
void
Paper_outputter::output_scheme (SCM scm)
{
- if (output_format_global == PAGE_LAYOUT)
- scm_display (scm_eval (scm, output_module_), file_);
- else
- scm_call_2 (output_func_, scm, file_);
+ scm_display (scm_eval (scm, output_module_), file_);
}
void
output_scheme (scm_list_1 (ly_symbol2scm ("header-end")));
- /*
- TODO: maybe have Scheme extract the fonts directly from \paper?
-
- Alternatively, we could simply load the fonts on demand in the
- output, and do away with this define-fonts step.
- */
+ /* TODO: maybe have Scheme extract the fonts directly from \paper ?
+
+ Alternatively, we could simply load the fonts on demand in the
+ output, and do away with this define-fonts step. */
+ SCM fonts = paper->font_descriptions ();
output_scheme (scm_list_3 (ly_symbol2scm ("define-fonts"),
paper->self_scm (),
- ly_quote_scm (paper->font_descriptions ())));
+ //FIXME:
+ ly_quote_scm (ly_list_qsort_uniq_x (fonts))));
}
void
dim[Y_AXIS] = 50 CM;
}
- if (output_format_global != PAGE_LAYOUT)
- output_scheme (scm_list_3 (ly_symbol2scm ("start-system"),
- scm_make_real (dim[X_AXIS]),
- scm_make_real (dim[Y_AXIS])));
- else
- {
- output_scheme (scm_list_3 (ly_symbol2scm ("new-start-system"),
- ly_quote_scm (ly_offset2scm (*origin)),
- ly_quote_scm (ly_offset2scm (dim))));
- (*origin)[Y_AXIS] += dim[Y_AXIS];
- }
+ output_scheme (scm_list_3 (ly_symbol2scm ("start-system"),
+ ly_quote_scm (ly_offset2scm (*origin)),
+ ly_quote_scm (ly_offset2scm (dim))));
- SCM between = SCM_EOL;
for (SCM s = pl->stencils (); is_pair (s); s = ly_cdr (s))
- {
- Stencil *stil = unsmob_stencil (ly_car (s));
- if (stil)
- output_expr (stil->get_expr (), Offset (0,0));
- /* Only if !PAGE_LAYOUT */
- else if (ly_caar (s) == ly_symbol2scm ("between-system-string"))
- between = ly_cdar (s);
- }
+ output_expr (unsmob_stencil (ly_car (s))->get_expr (), Offset (0, 0));
- if (is_last)
- output_scheme (scm_list_1 (ly_symbol2scm ("stop-last-system")));
- else
- {
- output_scheme (scm_list_1 (ly_symbol2scm ("stop-system")));
- if (output_format_global != PAGE_LAYOUT && between != SCM_EOL)
- output_scheme (between);
- }
+ output_scheme (scm_list_2 (ly_symbol2scm ("stop-system"),
+ ly_bool2scm (is_last)));
+
+ (*origin)[Y_AXIS] += dim[Y_AXIS];
}
void
if (!safe_module)
{
safe_module = scm_primitive_eval (ly_symbol2scm ("safe-module"));
- if (output_format_global == PAGE_LAYOUT)
- ly_import_module (safe_module, scm_c_resolve_module ("lily"));
+ ly_import_module (safe_module, scm_c_resolve_module ("lily"));
}
answer = scm_eval (form, safe_module);
}
int
System::spanner_count () const
{
- int k =0;
- for (SCM s = get_property ("all-elements");
- is_pair (s); s = ly_cdr (s))
- {
- if (dynamic_cast<Spanner*> (unsmob_grob (ly_car (s))))
- k++;
- }
-
- return k;
-}
-
-
-int
-scm_default_compare (const void * a, const void *b)
-{
- SCM pa = *(SCM *)a;
- SCM pb = *(SCM *)b;
-
- if (pa < pb)
- return -1;
- else if (pa > pb)
- return 1;
- else
- return 0;
-}
-
-/*
- modify L in place: sort it
-*/
-SCM
-uniquify_list (SCM l)
-{
- int len = scm_ilength (l);
- SCM * arr = new SCM[len];
int k = 0;
- for (SCM s = l; SCM_NNULLP (s); s = SCM_CDR (s))
- arr[k++] = SCM_CAR (s);
-
- assert (k == len);
- qsort (arr, len, sizeof (SCM), &scm_default_compare);
-
- k = 0;
- SCM *tail = &l;
-
- for (int i = 0; i < len ; i++)
- {
- if (i && arr[i] == arr[i-1])
- continue;
-
- SCM_SETCAR (*tail, arr[i]);
- tail = SCM_CDRLOC(*tail);
- }
-
- *tail = SCM_EOL;
- delete[] arr;
-
- return l;
+ for (SCM s = get_property ("all-elements"); is_pair (s); s = ly_cdr (s))
+ if (dynamic_cast<Spanner*> (unsmob_grob (ly_car (s))))
+ k++;
+ return k;
}
void
/* Because the this->get_property (all-elements) contains items in 3
versions, handle_broken_dependencies () will leave duplicated
items in all-elements. Strictly speaking this is harmless, but
- it leads to duplicated symbols in the output. uniquify_list ()
+ it leads to duplicated symbols in the output. ly_list_qsort_uniq_x ()
makes sure that no duplicates are in the list. */
for (int i = 0; i < line_count; i++)
{
SCM all = broken_intos_[i]->get_property ("all-elements");
- all = uniquify_list (all);
+ all = ly_list_qsort_uniq_x(all);
}
#endif
-/*
- Find the loose columns in POSNS, and drape them around the columns
- specified in BETWEEN-COLS. */
-void
+/* Find the loose columns in POSNS, and drape them around the columns
+ specified in BETWEEN-COLS. */
+static void
set_loose_columns (System* which, Column_x_positions const *posns)
{
for (int i = 0; i < posns->loose_cols_.size (); i++)
break;
- Item * l=dynamic_cast<Item*> (unsmob_grob (ly_car (between)));
- Item * r=dynamic_cast<Item*> (unsmob_grob (ly_cdr (between)));
+ Item *le = dynamic_cast<Item*> (unsmob_grob (ly_car (between)));
+ Item *re = dynamic_cast<Item*> (unsmob_grob (ly_cdr (between)));
- if (!(l && r))
+ if (!(le && re))
break ;
- if (!left && l)
+ if (!left && le)
{
- left = l->get_column ();
+ left = le->get_column ();
if (!left->get_system ())
left = left->find_prebroken_piece (RIGHT);
}
divide_over ++;
- loose = right = r->get_column ();
+ loose = right = re->get_column ();
}
while (1);
if (!right->get_system ())
right = right->find_prebroken_piece (LEFT);
- /*
- We divide the remaining space of the column over the left and
- right side. At the moment, we
-
- */
- Grob * common = right->common_refpoint (left, X_AXIS);
+ /* Divide the remaining space of the column over the left and
+ right side. At the moment, FIXME */
+ Grob *common = right->common_refpoint (left, X_AXIS);
Real rx = right->extent (common, X_AXIS)[LEFT];
Real lx = left->extent (common, X_AXIS)[RIGHT];
Real total_dx = rx - lx;
Interval cval =col->extent (col, X_AXIS);
- /*
-
- We put it in the middle. This is not an ideal solution -- the
- break alignment code inserts a fixed space before the clef
- (about 1 SS), while the space following the clef is
- flexible. In tight situations, the clef will almost be on top
- of the following note.
-
- */
- Real dx = rx-lx - cval.length ();
+ /* Put it in the middle. This is not an ideal solution -- the
+ break alignment code inserts a fixed space before the clef
+ (about 1 SS), while the space following the clef is flexible.
+ In tight situations, the clef will almost be on top of the
+ following note. */
+ Real dx = rx - lx - cval.length ();
if (total_dx < 2* cval.length ())
{
- /*
- todo: this is discontinuous. I'm too tired to
- invent a sliding mechanism. Duh.
-
- TODO.
- */
+ /* TODO: this is discontinuous. I'm too tired to
+ invent a sliding mechanism. Duh. */
dx *= 0.25;
}
else
dx *= 0.5;
col->system_ = which;
- col->translate_axis (- col->relative_coordinate (common, X_AXIS), X_AXIS);
+ col->translate_axis (-col->relative_coordinate (common, X_AXIS), X_AXIS);
col->translate_axis (lx + dx - cval[LEFT], X_AXIS);
}
}
This might seem inefficient, but Stencils are cached per grob
anyway. */
SCM all = get_property ("all-elements");
- all = uniquify_list (all);
+ all = ly_list_qsort_uniq_x (all);
this->get_stencil ();
for (SCM s = all; is_pair (s); s = ly_cdr (s))
stencils = scm_cons (my_stencil, stencils);
}
- if (output_format_global != PAGE_LAYOUT)
- {
- SCM lastcol = ly_car (get_property ("columns"));
- Grob *g = unsmob_grob (lastcol);
-
- SCM between = ly_symbol2scm ("between-system-string");
- SCM inter = g->internal_get_property (between);
- if (is_string (inter))
- stencils = scm_cons (scm_cons (between, inter), stencils);
- }
-
Interval x (extent (this, X_AXIS));
Interval y (extent (this, Y_AXIS));
Paper_line *pl = new Paper_line (Offset (x.length (), y.length ()),
ADD_INTERFACE (System,"system-interface",
"This is the toplevel object: each object in a score "
"ultimately has a System object as its X and Y parent. ",
- "between-system-string all-elements columns")
+ "all-elements columns")
newpage = \notes
{
\break
- % urg, only works for TeX output
- \context Score \applyoutput
- #(outputproperty-compatibility (make-type-checker 'paper-column-interface)
- 'between-system-string "\\newpage")
+ %% FIXME: page break penalty should tickle into Paper_line
+ %% \context Score \applyoutput
+ %%#(outputproperty-compatibility (make-type-checker 'paper-column-interface)
+ %% 'between-system-string "\\newpage")
}
% dynamic ly:dir? text script, articulation script ly:dir?
called before line breaking, but after splitting breakable items at
potential line breaks.")
(between-cols ,pair? "Where to attach a loose column to")
- (between-system-string ,string? "string
- to dump between two systems. Useful for forcing page breaks.")
(bracket-thick ,number? "width of a system start bracket.")
(break-align-symbol ,symbol? "This key is used for aligning and
spacing breakable items.")
(add-font
node
'((font-encoding . math))
- `((* factor 10) . #(,(delay (ly:font-load "msam10")))))
+ `(,(* factor 10) . #(,(delay (ly:font-load "msam10")))))
(for-each
(lambda (x)
tuplet
polygon
draw-line
- between-system-string
define-origin
no-origin
start-page
(ly:numbers->string
(list x y width height blotdiam)) " draw_round_box"))
-(define (new-start-system origin dim)
+(define (start-system origin dim)
(string-append
"\n" (ly:number-pair->string origin) " start-system\n"
"{\n"
(ly:numbers->string (list breapth width depth height))
" draw_box" ))
-(define (stop-system)
+(define (stop-system last?)
"} stop-system\n")
-(define stop-last-system stop-system)
-
(define (symmetric-x-triangle thick w h)
(string-append
(ly:numbers->string (list h w thick))
tuplet
polygon
draw-line
- between-system-string
define-origin
no-origin
start-page
stop-page
- )
- )
+ ))
(use-modules (ice-9 regex)
(ice-9 string-fun)
(regexp-substitute/global
#f "_" (output-tex-string (symbol->string sym)) 'pre "X" 'post) )
+(define (string->param string)
+ (string-append "{" string "}"))
+
+(define (number->param number)
+ (string->param (ly:number->string number)))
+
+(define (number-pair->param o)
+ (string-append (number->param (car o)) (number->param (cdr o))))
+
(define (tex-string-def prefix key str)
(if (equal? "" (sans-surrounding-whitespace (output-tex-string str)))
(string-append "\\let\\" prefix (symbol->tex-key key) "\\undefined%\n")
- (string-append "\\def\\" prefix (symbol->tex-key key) "{" (output-tex-string str) "}%\n")
- ))
+ (string-append "\\def\\" prefix (symbol->tex-key key)
+ "{" (output-tex-string str) "}%\n")))
(define (tex-number-def prefix key number)
- (string-append "\\def\\" prefix (symbol->tex-key key) "{" number "}%\n"))
+ (string-append
+ "\\def\\" prefix (symbol->tex-key key) (string->param number) "%\n"))
(define (output-paper-def pd)
(apply
(ly:number->string x) " \\outputscale "))
(define (placebox x y s)
- (string-append "\\lyitem{"
- (ly:number->string y) "}{"
- (ly:number->string x) "}{"
- s "}%\n"))
+ (string-append
+ "\\lyitem" (number->param x) (number->param y) (string->param s) "%\n"))
(define (bezier-sandwich l thick)
(embedded-ps (list 'bezier-sandwich `(quote ,l) thick)))
-(define (start-system wd ht)
- (string-append "\\leavevmode\n"
- "\\scoreshift = " (number->dim (* ht 0.5)) "\n"
- "\\lilypondifundefined{lilypondscoreshift}%\n"
- " {}%\n"
- " {\\advance\\scoreshift by -\\lilypondscoreshift}%\n"
- "\\lybox{"
- (ly:number->string wd) "}{"
- (ly:number->string ht) "}{%\n"))
-
-(define (stop-system)
- "}%\n%\n\\interscoreline\n%\n")
-(define (stop-last-system)
- "}%\n")
+(define (start-system origin dim)
+ (string-append
+ "\\leavevmode\n"
+ "\\lybox" (number-pair->param origin) (number-pair->param dim)
+ "{%\n"))
+
+(define (stop-system last?)
+ (if last?
+ "}%\n"
+ ;; FIXME: still used by lilypond.py for --preview
+ "}%\n%\n\\interscoreline\n%\n"))
(define (horizontal-line x1 x2 th)
(filledbox (- x1) (- x2 x1) (* .5 th) (* .5 th )))
(let*
((mapping #f))
- ;; TODO: we'd better do this for PS only
- ;; LaTeX gets in the way, and we need to remap
- ;; nonprintable chars.
-
- ; (assoc-get 'char-mapping (ly:font-encoding-alist font))))
+ ;; TODO: we'd better do this for PS only
+ ;; LaTeX gets in the way, and we need to remap
+ ;; nonprintable chars.
+
+ ;; (assoc-get 'char-mapping (ly:font-encoding-alist font))))
(string-append "\\hbox{\\" (font-command font) "{}"
(output-tex-string
(define (draw-line thick fx fy tx ty)
(embedded-ps (list 'draw-line thick fx fy tx ty)))
-;; TODO: this should be a default, which is overriden in PS
-(define (between-system-string string)
- string
- )
(define (define-origin file line col)
(if (procedure? point-and-click)
(string-append "\\special{src:" ;;; \\string ?
(define (no-origin) "")
(define (start-page)
- "\n%\\vbox{\n")
+ "\n\\vbox to 0pt{\n")
(define (stop-page last?)
(if last?
- "\n%}\n"
- "\n%}\n\\newpage\n"))
+ "\\vss\n}\n\\vfill\n"
+ "\\vss\n}\n\\vfill\\newpage\n"))
;; CDR: junk dummy node
(breaks (cdr (reverse (map robust-line-number path)))))
- (format (current-error-port) "ESTIMATE: ~S\n"
- (/ book-height text-height))
- (format (current-error-port) "breaks: ~S\n" breaks)
- ;; TODO: if solution is bad return no breaks and revert to
- ;; ragged bottom
- (force-output (current-error-port))
+ (if (ly:get-option 'verbose)
+ (begin
+ (format (current-error-port) "Estimated page count: ~S\n"
+ (/ book-height text-height))
+ (format (current-error-port) "breaks: ~S\n" breaks)
+ (force-output (current-error-port))))
+ ;; TODO: if solution is bad return no breaks and revert to
+ ;; ragged bottom
(list->vector breaks)))
},
}
-PREAMBLE_LY = r'''%% Generated by %(program_name)s
-%% Options: [%(option_string)s]
+PREAMBLE_LY = r'''%%%% Generated by %(program_name)s
+%%%% Options: [%(option_string)s]
%(preamble_string)s
\paper {%(paper_string)s
}
#!@PYTHON@
+# lilypond.py -- frontend for lilypond-bin
#
-# lilypond.py -- Run LilyPond, add titles to bare score, generate printable
-# document
-# Invokes: lilypond-bin, latex (or pdflatex), dvips, ps2pdf, gs
-#
# source file of the GNU LilyPond music typesetter
#
# (c) 1998--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
# Jan Nieuwenhuizen <janneke@gnu.org>
+#
+# Run lilypond-bin, generate printable document
+# Invokes: lilypond-bin, latex (or pdflatex), dvips, ps2pdf, gs
+#
-# This is the third incarnation of ly2dvi, now renamed lilypond.
+# This is the third incarnation of ly2dvi, renamed to lilypond.
#
-# Earlier incarnations of lilypond were written by
-# Jeffrey B. Reed<daboys@austin.rr.com> (Python version)
+# Earlier incarnations of ly2dvi were written by
+# Jeffrey B. Reed<daboys@austin.rr.com> (Python versioan)
# Jan Arne Fagertun <Jan.A.Fagertun@@energy.sintef.no> (Bourne shell script)
#
'''
TODO:
+ * cleanup
+
* figure out which set of command line options should make lilypond:
na: create tex only?
etc.
- * move versatile taglines,
-
- \header {
- beginfooter=\mutopiaPD
- endfooter=\tagline -> 'lily was here <version>'
- }
-
- lilytagline (->lily was here), usertagline, copyright, lily-version
- etc.
-
- * head/header tagline/endfooter
-
* dvi from lilypond .tex output? This is hairy, because we create dvi
from lilypond .tex *and* header output.
- * multiple \score blocks?
-
- * Introduce verbosity levels
-
- 0 = QUIET: mute all command output, no lilypond progress
- 1 = BRIEF: mute all command output, only lilypond progress
- 2a = NORMAL: show only LilyPond command output, show lilypond progress
- 2b = NORMAL: show command output, show lilypond progress
- 3 = VERBOSE: show command output, run lilypond --verbose
- 4 = DEBUGGING: show all command output, run lilypond --verbose, print
- environment and all kinds of client side debugging stuff
-
- Currently, we only have 1 and 4, but we kludge to have 2a and 4.
'''
import operator
preview_resolution = 90
debug_p = 0
+TEX_PREAMBLE = '%%%% Generated by %(program_name)s (v%(program_version)s)' \
+ % vars ()
+
## FIXME
## do -P or -p by default?
##help_summary = _ ("Run LilyPond using LaTeX for titling")
-help_summary = _ ("Run LilyPond, add titles, generate printable document.")
+help_summary = _ ("Run LilyPond, generate printable document.")
copyright = ('Han-Wen Nienhuys <hanwen@cs.uu.nl',
'Jan Nieuwenhuizen <janneke@gnu.org')
lilypond_binary = 'lilypond-bin'
-layout_fields = ['dedication', 'title', 'subtitle', 'subsubtitle',
- 'footer', 'head', 'composer', 'arranger', 'instrument',
- 'opus', 'piece', 'metre', 'meter', 'poet', 'texttranslator']
-
-
-# init to empty; values here take precedence over values in the file
-
-## TODO: change name.
+## Init to empty; values here take precedence over values in the file
extra_init = {
'language' : [],
'latexheaders' : [],
- 'latexpackages' : ['geometry'],
-
- # for geometry v3
- 'latexoptions' : ['compat2'],
-
- 'papersize' : [],
- 'pagenumber' : [1],
- 'textheight' : [],
- 'linewidth' : [],
+ 'latexoptions' : [],
+ 'latexpackages' : [],
'orientation' : [],
+ 'papersize' : [],
'unit' : ['pt'],
}
-extra_fields = extra_init.keys ()
-fields = layout_fields + extra_fields
+header_fields = extra_init.keys ()
include_path = ['.']
lily_p = 1
def escape_shell (x):
return re.sub ("(\s|[`'\"\\\\])", r'\\\1',x)
-
def run_lilypond (files, dep_prefix):
+
def make_include_option (x):
return '-I %s' % escape_shell (x)
-
- opts = ''
- opts = opts + ' ' + string.join (map (make_include_option, include_path))
+
+ opts = ' ' + string.join (map (make_include_option, include_path))
+
+ ## UGHr
if pseudo_filter_p:
- opts = opts + ' --output=lelie'
+ opts += ' --output=lelie'
if paper_p:
- opts = opts + ' ' + string.join (map (lambda x : '-H ' + x,
- fields))
+ opts += ' ' + string.join (map (lambda x : '--header=' + x,
+ header_fields))
else:
opts = opts + ' --no-paper'
-
if pdftex_p:
opts = opts + ' -f pdftex'
-
if safe_mode_p:
opts = opts + ' --safe-mode'
-
if track_dependencies_p:
opts = opts + " --dependencies"
if dep_prefix:
# search only the first 10k
s = s[:10240]
- for x in extra_fields:
+ for x in header_fields:
m = re.search (r'\\def\\lilypondpaper%s{([^}]*)}'%x, s)
if m:
set_setting (extra, x, m.group (1))
ly.progress ('\n')
def find_tex_files_for_base (base, extra):
- '''
- Find the \header fields dumped from BASE.
- '''
-
- headerfiles = {}
- for f in layout_fields:
- fn = base + '.' + f
- if os.path.exists (fn):
- headerfiles[f] = fn
if os.path.exists (base +'.dep'):
dependency_files.append (base + '.dep')
- for f in extra_fields:
+ for f in header_fields:
fn =base + '.' + f
if os.path.exists (fn):
extra[f].append (open (fn).read ())
- return (base + tex_extension, headerfiles)
+ return (base + tex_extension, {})
def find_tex_files (files, extra):
def one_latex_definition (defn, first):
s = '\n'
- for (k,v) in defn[1].items ():
+ for (k, v) in defn[1].items ():
val = open (v).read ()
if (string.strip (val)):
- s = s + r'''\def\lilypond%s{%s}''' % (k, val)
+ s += r'''\def\lilypond%s{%s}''' % (k, val)
else:
- s = s + r'''\let\lilypond%s\relax''' % k
- s = s + '\n'
+ s += r'''\let\lilypond%s\relax''' % k
+ s += '\n'
- if first:
- s = s + '\\def\\mustmakelilypondtitle{}\n'
- else:
- s = s + '\\def\\mustmakelilypondpiecetitle{}\n'
-
- s = s + '\\input %s\n' % defn[0] # The final \n seems important here. It ensures that the footers and taglines end up on the right page.
+ s += '%%PREVIEW%%\n'
+ s += '\\input %s\n' % defn[0]
return s
-
-ly_paper_to_latexpaper = {
- 'letter' : 'letterpaper',
- 'a3' : 'a3paper',
- 'a4' : 'a4paper',
- 'a5' : 'a5paper',
- 'a6' : 'a6paper',
- 'legal' : 'legalpaper',
- 'tabloid' : 'papersize={11in,17in}',
-}
-
-#TODO: should set textheight (enlarge) depending on papersize.
def global_latex_preamble (extra):
'''construct preamble from EXTRA,'''
- s = ""
- s = s + '% generation tag\n'
+
+ s = TEX_PREAMBLE
+ s += '\n'
options = ''
if extra['latexoptions']:
options = options + ',' + extra['latexoptions'][-1]
- s = s + '\\documentclass[%s]{article}\n' % options
+ s += '\\documentclass[%s]{article}\n' % options
if safe_mode_p:
- s = s + '\\nofiles\n'
+ s += '\\nofiles\n'
if extra['language']:
- s = s + r'\usepackage[%s]{babel}' \
+ s += r'\usepackage[%s]{babel}' \
% extra['language'][-1] + '\n'
- s = s + '\\usepackage{%s}\n' \
+ s += '\\usepackage{%s}\n' \
% string.join (extra['latexpackages'], ',')
if extra['latexheaders']:
- s = s + '\\include{%s}\n' \
+ s += '\\include{%s}\n' \
% string.join (extra['latexheaders'], '}\n\\include{')
unit = extra['unit'][-1]
-
- papersize = ''
- if extra['papersize']:
- try:
- papersize = ly_paper_to_latexpaper[extra['papersize'][0]] + ','
- except KeyError:
- ly.warning (_ ("invalid value: `%s'") % `extra['papersize'][0]`)
- pass
-
- textheight = ''
- if extra['textheight']:
- textheight = ',textheight=%f%s' % (extra['textheight'][0], unit)
-
- orientation = 'portrait'
- if extra['orientation']:
- orientation = extra['orientation'][0]
-
- # set sane geometry width (a4-width) for linewidth = -1.
- maxlw = max (extra['linewidth'] + [-1])
- if maxlw < 0:
- # who the hell is 597 ?
- linewidth = '597pt'
- else:
- linewidth = '%d%s' % (maxlw, unit)
- s = s + '\geometry{%swidth=%s%s,bottom=11mm,headsep=2mm,top=12mm,headheight=2mm,footskip=5mm,%s}\n' % (papersize, linewidth, textheight, orientation)
-
-
- if 'twoside' in extra['latexoptions'] :
- s = s + '\geometry{twosideshift=4mm}\n'
-
- s = s + r'''
+ # FIXME, must (only) from lilypond-bin
+ s += r'''
\usepackage[latin1]{inputenc}
-\input{titledefs}
+\pagestyle{empty}
+%%PREVIEW%%
+%% Nullify [La]TeX page layout settings, page layout by LilyPond.
+\pagestyle{empty}
+\topmargin-1in
+%% FIXME: empirical computer science: page is ca 5mm too low.
+\advance\topmargin-5mm
+\headheight0pt\headsep0pt
+\oddsidemargin-1in
+\evensidemargin\oddsidemargin
+\parindent 0pt
'''
-
- if extra['pagenumber'] and extra['pagenumber'][-1] and extra['pagenumber'][-1] != 'no':
- s = s + '\setcounter{page}{%d}\n' % (extra['pagenumber'][-1])
- s = s + '\\pagestyle{plain}\n'
- else:
- s = s + '\\pagestyle{empty}\n'
-
-
return s
def global_latex_definition (tfiles, extra):
'''construct preamble from EXTRA, dump Latex stuff for each
lily output file in TFILES after that, and return the Latex file constructed. '''
-
-
s = global_latex_preamble (extra) + '\\begin{document}\n'
- s = s + '\\parindent 0pt\n'
- s = s + '\\thispagestyle{firstpage}\n'
+ s += '\\parindent 0pt'
first = 1
for t in tfiles:
- s = s + one_latex_definition (t, first)
+ s += one_latex_definition (t, first)
first = 0
-
-
- s = s + '\n\\thispagestyle{lastpage}\n'
- s = s + '\\end{document}'
-
+ s += '\\end{document}\n'
return s
def run_latex (files, outbase, extra):
-
'''Construct latex file, for FILES and EXTRA, dump it into
-OUTBASE.latex. Run LaTeX on it.
-
-RETURN VALUE
-
-None
- '''
+OUTBASE.latex. Run LaTeX on it.
+'''
latex_fn = outbase + '.latex'
preview_base = ly.strip_extension (score[0], '.tex')
preview_fn = preview_base + '.preview.tex'
s = global_latex_definition ((score,), extra)
- s = re.sub ('thispagestyle{firstpage}',
- r'''thispagestyle{empty}%
- \\def\\interscoreline{\\endinput}''', s)
- s = re.sub ('thispagestyle{lastpage}',
- r'''thispagestyle{empty}%
- \\def\\interscoreline{\\endinput}''', s)
+ s = re.sub ('%%PREVIEW%%',
+ r'''\def\interscoreline{\endinput}''', s)
f = open (preview_fn, 'w')
f.write (s)
f.close ()
def run_dvips (outbase, extra):
-
-
'''Run dvips using the correct options taken from EXTRA,
leaving a PS file in OUTBASE.ps
-
-RETURN VALUE
-
-None.
'''
- opts = ''
- if extra['papersize']:
- opts = opts + ' -t%s' % extra['papersize'][0]
-
+ #FIXME: papersize, orientation must come from lilypond-bin
+ opts = ' -t%s' % extra['papersize'][0]
if extra['orientation'] and extra['orientation'][0] == 'landscape':
opts = opts + ' -tlandscape'
-
if 'PDF' in targets:
where = ly.read_pipe ('kpsewhich feta20.pfa').strip()
if name in os.listdir (d):
return os.path.join (d, name)
-# Added as functionality to lilypond, because lilypond may well need to do this
-# in future too.
-PS = '%!PS-Adobe'
def find_pfa_fonts (name):
+ PS = '%!PS-Adobe'
s = open (name).read ()
if s[:len (PS)] != PS:
# no ps header?
-% lilyponddefs.tex
-%
-% Include file for LilyPond.
-%
-% This file defines various macros to acommodate lilypond output.
-%
-% It should run with plain TeX, LaTeX, pdftex, and texinfo.
-%
-% To avoid interferences, lilyponddefs.tex should be loaded within a group.
-% To load it only once, most of the definitions must be global.
-%
-% The overall structure of a file created by LilyPond is as follows:
-%
-% <lilypond parameter definitions>
-% \ifx\lilypondstart \undefined
-% \input lilyponddefs
-% \fi
-% \lilypondstart
-% <font setup and note output>
-% \lilypondend
-%
-% No footers and headers are provided for the stand-alone run (i.e., for
-% directly saying `latex <LilyPond output>'.
-%
-%
-% Avoid \par while reading this file.
+%%% lilyponddefs.tex -- TeX macros for LilyPond output.
+%%%
+%%% source file of the GNU LilyPond music typesetter
+%%%
+%%% (c) 1998--2004 Jan Nieuwenhuizen <janneke@gnu.org>
+%%% Han-Wen Nienhuys <hanwen@cs.uu.nl>
+%%% Mats Bengtsson <mats.bengtsson@s3.kth.se>
+%%%
+%% Avoid \par while reading this file.
\edef\lilyponddefsELC{\the\endlinechar}%
\endlinechar -1\relax
-% the next three macros are taken from LaTeX
-\long\gdef\lilypondfirst#1#2{#1}
+%% This runs with plain TeX, LaTeX, pdftex, and texinfo.
+%%
+%% To avoid interferences, lilyponddefs.tex must be loaded within a group.
+%% It is loaded only once, so the definitions must be global.
+%%
+%% The overall structure of a file created by LilyPond is as follows:
+%%
+%% <lilypond parameter definitions>
+%% \ifx\lilypondstart \undefined
+%% \input lilyponddefs
+%% \fi
+%% \lilypondstart
+%% <font setup and note output>
+%% \lilypondend
-\long\gdef\lilypondsecond#1#2{#2}
+\newdimen\outputscale
+%% Handy macros from the LaTeX manual.
+\long\gdef\lilypondfirst#1#2{#1}
+\long\gdef\lilypondsecond#1#2{#2}
\gdef\lilypondifundefined#1{
\expandafter\ifx\csname#1\endcsname\relax
\expandafter\lilypondfirst
\gdef\lilypondstart{
\begingroup
\catcode `\@=11\relax
- % \@nodocument is defined as \relax after `\begin{document}'
+ %% \@nodocument is defined as \relax after `\begin{document}'
\lilypondifundefined{@nodocument}
{
- % either plain TeX or texinfo or not at the beginning of LaTeX input
- \def\x{\endgroup}
- }
+ %% either plain TeX or texinfo or not at the beginning of LaTeX input
+ \def\x{\endgroup}}
{
- % provide a proper LaTeX preamble (for A4 paper format)
+ %% FIXME: a4
+ %% provide a proper LaTeX preamble (for A4 paper format)
\def\x{
\endgroup
\def\lilyponddocument{}
\documentclass[a4paper]{article}
- \nofiles
+ %% safe-mode
+ \nofiles
+ %% Nullify [La]TeX page layout settings, page layout by LilyPond.
\pagestyle{empty}
- % \begin is defined as \outer in texinfo, thus we use \csname
- \csname begin\endcsname{document}
- % center staves horizontally on page
- \ifdim\lilypondpaperlinewidth\lilypondpaperunit > 0pt
- \hsize\lilypondpaperlinewidth\lilypondpaperunit
- % we abuse \scoreshift temporarily
- \scoreshift \paperwidth
- \advance\scoreshift -\the\hsize
- \scoreshift 0.5\scoreshift
- \advance\scoreshift -1in
- \oddsidemargin \scoreshift
- \evensidemargin \scoreshift
- \fi
+ \topmargin-1in
+ %% FIXME: empirical computer science: page is ca 5mm too low.
+ \advance\topmargin-5mm
+ \headheight0pt\headsep0pt
+ \oddsidemargin-1in
+ \evensidemargin\oddsidemargin
\parindent 0pt
- }
- }
-
- \x
-
- \lilypondifundefined{mustmakelilypondtitle}
- {}
- {\makelilypondtitle}
-
- \lilypondifundefined{mustmakelilypondpiecetitle}
- {}
- {\makelilypondpiecetitle}
-}
+ %% TEXINFO workaround: \begin is defined as \outer, use \csname.
+ \csname begin\endcsname{document}}}
+ \x}
\gdef\lilypondend{
\lilypondifundefined{lilypondbook}
- {\lilypondifundefined{lilypondpaperlastpagefill}
- {\vskip 0pt plus \lilypondpaperinterscorelinefill00 fill}
- {}
- }
- {}
-
+ {\lilypondifundefined{lilypondpaperlastpagefill}
+ {\vskip 0pt plus\lilypondpaperinterscorelinefill00 fill}
+ {}}
+ {}
\begingroup
\lilypondifundefined{lilyponddocument}
- {
- \def\x{\endgroup}
- }
- {
- \def\x{
- \endgroup
- \csname end\endcsname{document}
- }
- }
-
- \x
-}
+ {\def\x{\endgroup}}
+ {\def\x{\endgroup\csname end\endcsname{document}}}
+ \x}
-% this is an inversed \loop ... \repeat macro
+%% Inversed \loop ... \repeat macro
\def\lilypondloop#1\lilypondrepeat{
\def\lilypondbody{#1}
\lilyponditerate
\lilypondnext
}
-% the following macro is executed only once
+%% Include \special only once.
\gdef\lilypondspecial{
\special{header=music-drawing-routines.ps}
\gdef\lilypondspecial{}
}
-% the feta characters
+%% The feta characters.
\input feta20
\global\font\fetasixteen = feta16
\gdef\fetafont{\fetasixteen}
\gdef\fetachar#1{\hbox{\fetasixteen#1}}
-\gdef\botalign#1{
- \vbox to 0pt{\vss #1}
-}
-\gdef\leftalign#1{
- \hbox to 0pt{#1\hss}
-}
+\gdef\topalign#1{\vbox to 0pt{\hbox{#1}\vss}}
+\gdef\leftalign#1{\hbox to 0pt{#1\hss}}
\gdef\lyitem#1#2#3{
- \botalign{
- \hbox{\raise #1\outputscale
- \leftalign{\kern #2\outputscale #3}}
- }
-}
+ \topalign{\raise#2\outputscale\leftalign{\kern#1\outputscale#3}}}
-\gdef\lybox#1#2#3{
- \hbox to #1\outputscale {
- \lower\scoreshift \vbox to #2\outputscale {
- \hbox{#3}
- \vss
- }
- \hss
- }
-}
+\gdef\XXXlybox#1#2#3#4#5{
+ \vbox to #4\outputscale{
+ \hbox to #3\outputscale{
+ \leftalign{\kern#1\outputscale\lower#2\outputscale\topalign{#5}}}
+ \hss}\vss}
-\gdef\lyvrule#1#2#3#4{
- \kern #1\outputscale
- \vrule width #2\outputscale depth #3\outputscale height #4\outputscale
-}
+%% FIXME: no dimensions, should fix at toplevel
+\gdef\lybox#1#2#3#4#5{
+ \leftalign{\kern#1\outputscale\lower#2\outputscale\topalign{#5}}}
-% Attempt to keep lilypiecetitle together with the piece:
-%
-% TODO: figure this out.
-\gdef\myfilbreak{}%\par\vfil\penalty200\vfilneg}
+\gdef\lyvrule#1#2#3#4{
+ \kern#1\outputscale
+ \vrule width #2\outputscale depth #3\outputscale height #4\outputscale}
\lilypondifundefined{lilypondpaperinterscorelinefill}
{\gdef\lilypondpaperinterscorelinefill{0}}
{\gdef\lilypondpaperinterscorelinefill{1}}
-%% Allow overriding of interscoreline, eg for lilypond --preview
+%% Allow overriding of interscoreline, e.g. for lilypond.py's --preview
\lilypondifundefined{interscoreline}
-{\gdef\interscoreline{
- \vskip \lilypondpaperinterscoreline \lilypondpaperunit
- plus \lilypondpaperinterscorelinefill fill
-}}{}
+{\gdef\interscoreline{}}{}
-% Are we using PDFTeX? If so, use pdf definitions.
-% MiKTeX checks \pdfoutput the wrong way, thus we use \csname.
+%% Include postscript definitions unless using PDFTeX,
+%% in that case use pdf definitions.
+%% MiKTeX workaround: use \csname.
\lilypondifundefined{lilypondpostscript}
- {
- \lilypondifundefined{pdfoutput}
- {\input lily-ps-defs }
- {
- \pdfoutput = 1
- \input lily-pdf-defs %
- }
- }
- {}
-
-\newdimen\outputscale
-\newdimen\scoreshift
+{\lilypondifundefined{pdfoutput}
+ {\input lily-ps-defs }
+ {\pdfoutput = 1
+ \input lily-pdf-defs }}
+{}
-% Restore newline functionality (disabled to avoid \par).
+%% Restore newline functionality (disabled to avoid \par).
\endlinechar \lilyponddefsELC
\endinput
-% EOF
+%% end lilyponddefs.tex