--- /dev/null
+\version "2.11.63"
+
+\header {
+ lsrtags = "paper-and-layout"
+ texidocs = "@code{\\bookpart} can be used to split a book into several parts.
+Each part last page can be affected by @code{ragged-bottom-last}.
+"
+ doctitle = "Book parts"
+}
+
+#(set-default-paper-size "a6")
+
+\book {
+ %% book-level paper, which is inherited by all bookparts
+ \paper { ragged-last-bottom = ##t }
+ %% book-level header, which is inherited by the first bookpart
+ \header { title = "Book title" }
+ %% first book part
+ \bookpart {
+ \header { subtitle = "First part" }
+ \markup { The first book part }
+ \markup \wordwrap { with ragged-last-bottom (see the space below this text) }
+ }
+ %% an other book part
+ \bookpart {
+ \header { subtitle = "Second part" }
+ { c' }
+ }
+}
-\version "2.11.55"
+\version "2.11.63"
\header {
texidoc = "A book can be split into several parts with different paper settings,
/* If this part is the first child of parent, copy its header */
if (ly_is_module (parent->header_) && (scm_is_null (parent->bookparts_)))
{
- header_ = ly_make_anonymous_module (false);
- ly_module_copy (header_, parent->header_);
+ SCM tmp_header = ly_make_anonymous_module (false);
+ ly_module_copy (tmp_header, parent->header_);
+ if (ly_is_module (header_))
+ ly_module_copy (tmp_header, header_);
+ header_ = tmp_header;
}
}
+/* Before an explicit \bookpart is encountered, scores are added to the book.
+ * But once a bookpart is added, the previous scores shall be collected into
+ * a new bookpart.
+ */
void
-Book::add_bookpart ()
+Book::add_scores_to_bookpart ()
{
if (scm_is_pair (scores_))
{
- warning ("add_bookpart");
/* If scores have been added to this book, add them to a child
* book part */
Book *part = new Book;
void
Book::add_bookpart (SCM b)
{
- add_bookpart ();
+ add_scores_to_bookpart ();
Book *part = unsmob_book (b);
part->set_parent (this);
bookparts_ = scm_cons (b, bookparts_);
return process (default_paper, default_layout, 0);
}
+void
+Book::process_bookparts (Paper_book *output_paper_book, Output_def *paper, Output_def *layout)
+{
+ add_scores_to_bookpart ();
+ for (SCM p = scm_reverse (bookparts_); scm_is_pair (p); p = scm_cdr (p))
+ {
+ if (Book *book = unsmob_book (scm_car (p)))
+ {
+ Paper_book *paper_book_part = book->process (paper, layout, output_paper_book);
+ if (paper_book_part)
+ output_paper_book->add_bookpart (paper_book_part->self_scm ());
+ }
+ }
+}
+
+void
+Book::process_score (SCM s, Paper_book *output_paper_book, Output_def *layout)
+{
+ if (Score *score = unsmob_score (scm_car (s)))
+ {
+ SCM outputs = score
+ ->book_rendering (output_paper_book->paper_, layout);
+
+ while (scm_is_pair (outputs))
+ {
+ Music_output *output = unsmob_music_output (scm_car (outputs));
+
+ if (Performance *perf = dynamic_cast<Performance *> (output))
+ output_paper_book->add_performance (perf->self_scm ());
+ else if (Paper_score *pscore = dynamic_cast<Paper_score *> (output))
+ {
+ if (ly_is_module (score->get_header ()))
+ output_paper_book->add_score (score->get_header ());
+ output_paper_book->add_score (pscore->self_scm ());
+ }
+
+ outputs = scm_cdr (outputs);
+ }
+ }
+ else if (Text_interface::is_markup_list (scm_car (s))
+ || unsmob_page_marker (scm_car (s)))
+ output_paper_book->add_score (scm_car (s));
+ else
+ assert (0);
+
+}
+
/* Concatenate all score or book part outputs into a Paper_book
*/
Paper_book *
if (scm_is_pair (bookparts_))
{
/* Process children book parts */
- add_bookpart ();
- for (SCM p = scm_reverse (bookparts_); scm_is_pair (p); p = scm_cdr (p))
- {
- if (Book *book = unsmob_book (scm_car (p)))
- {
- Paper_book *paper_book_part = book
- ->process (paper, default_layout, paper_book);
- if (paper_book_part)
- paper_book->add_bookpart (paper_book_part->self_scm ());
- }
- }
+ process_bookparts (paper_book, paper, default_layout);
}
else
{
/* Process scores */
- /* Render in order of parsing. */
+ /* Render in order of parsing. */
for (SCM s = scm_reverse (scores_); scm_is_pair (s); s = scm_cdr (s))
- {
- if (Score *score = unsmob_score (scm_car (s)))
- {
- SCM outputs = score
- ->book_rendering (paper_book->paper_, default_layout);
-
- while (scm_is_pair (outputs))
- {
- Music_output *output = unsmob_music_output (scm_car (outputs));
-
- if (Performance *perf = dynamic_cast<Performance *> (output))
- paper_book->add_performance (perf->self_scm ());
- else if (Paper_score *pscore = dynamic_cast<Paper_score *> (output))
- {
- if (ly_is_module (score->get_header ()))
- paper_book->add_score (score->get_header ());
- paper_book->add_score (pscore->self_scm ());
- }
-
- outputs = scm_cdr (outputs);
- }
- }
- else if (Text_interface::is_markup_list (scm_car (s))
- || unsmob_page_marker (scm_car (s)))
- paper_book->add_score (scm_car (s));
- else
- assert (0);
- }
+ {
+ process_score (s, paper_book, default_layout);
+ }
}
return paper_book;
VIRTUAL_COPY_CONSTRUCTOR(Book, Book);
Book ();
void add_score (SCM);
- void add_bookpart ();
void add_bookpart (SCM);
- void set_parent (Book *parent);
- bool error_found ();
Paper_book *process (Output_def *def_paper,
Output_def *def_layout);
Paper_book *process (Output_def *default_paper,
Output_def *default_layout,
Paper_book *parent_part);
void set_keys ();
+
+protected:
+ void set_parent (Book *parent);
+ void add_scores_to_bookpart ();
+ bool error_found ();
+ void process_score (SCM score,
+ Paper_book *output_paper_book,
+ Output_def *layout);
+ void process_bookparts (Paper_book *output_paper_book,
+ Output_def *paper,
+ Output_def *layout);
};
DECLARE_UNSMOB (Book, book);
Stencil book_title ();
Stencil score_title (SCM);
+ void classic_output (SCM output_channel);
+ void output (SCM output_channel);
+
+protected:
void classic_output_aux (SCM output,
int *first_performance_number);
- void classic_output (SCM output_channel);
void output_aux (SCM output_channel,
- bool is_first,
bool is_last,
int *first_page_number,
int *first_performance_number);
- void output (SCM output_channel);
};
DECLARE_UNSMOB (Paper_book, paper_book)
break_into_pieces (0, end, current_configuration (0));
message (_ ("Computing page breaks..."));
- vsize first_page_num = robust_scm2int (book_->paper_->c_variable ("part-first-page-number"), 1);
+ vsize first_page_num = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
Page_spacing_result res = pack_systems_on_least_pages (0, first_page_num);
SCM lines = systems ();
return make_pages (res.systems_per_page_, lines);
{
vsize end = last_break_position ();
vsize max_sys_count = max_system_count (0, end);
- vsize first_page_num = robust_scm2int (book_->paper_->c_variable ("part-first-page-number"), 1);
+ vsize first_page_num = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
SCM forced_page_count = book_->paper_->c_variable ("page-count");
set_to_ideal_line_configuration (0, end);
SCM book = book_->self_scm ();
int first_page_number
- = robust_scm2int (book_->paper_->c_variable ("part-first-page-number"), 1);
+ = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
bool last_part = ly_scm2bool (book_->paper_->c_variable ("part-is-last"));
SCM ret = SCM_EOL;
SCM label_page_table = book_->top_paper ()->c_variable ("label-page-table");
if (start > 0 && best.demerits_ < state_[start-1].demerits_)
continue;
- int p_num = robust_scm2int (book_->paper_->c_variable ("part-first-page-number"), 1);
+ int p_num = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
if (start > 0)
{
/* except possibly for the first page, enforce the fact that first_page_number_
/* this should only actually modify first-page-number if
auto-first-page-number was true. */
- book_->paper_->set_variable (ly_symbol2scm ("part-first-page-number"),
+ book_->paper_->set_variable (ly_symbol2scm ("first-page-number"),
scm_from_int (soln[0].first_page_number_));
return Page_breaking::make_pages (lines_per_page, systems);
}
void
Paper_book::output_aux (SCM output_channel,
- bool is_first,
bool is_last,
int *first_page_number,
int *first_performance_number)
if (scm_is_pair (bookparts_))
{
- bool is_first_part = is_first;
for (SCM p = scm_reverse (bookparts_); scm_is_pair (p); p = scm_cdr (p))
if (Paper_book *pbookpart = unsmob_paper_book (scm_car (p)))
{
bool is_last_part = (is_last && !scm_is_pair (scm_cdr (p)));
pbookpart->output_aux (output_channel,
- is_first_part,
is_last_part,
first_page_number,
first_performance_number);
- is_first_part = false;
}
}
else
{
if (scores_ == SCM_EOL)
return;
- paper_->set_variable (ly_symbol2scm ("part-first-page-number"),
+ paper_->set_variable (ly_symbol2scm ("first-page-number"),
scm_long2num (*first_page_number));
- paper_->set_variable (ly_symbol2scm ("part-is-first"),
- ly_bool2scm (is_first));
paper_->set_variable (ly_symbol2scm ("part-is-last"),
ly_bool2scm (is_last));
/* Generate all stencils to trigger font loads. */
int first_page_number = robust_scm2int (paper_->c_variable ("first-page-number"), 1);
int first_performance_number = 0;
output_aux (output_channel,
- true,
true,
&first_page_number,
&first_performance_number);