include $(depth)/make/stepmake.make
TITLE=Lilypond musicxml2ly Regression Tests
+MXL_FILES := $(call src-wildcard,*.mlx)
+EXTRA_DIST_FILES += $(MXL_FILES)
\ No newline at end of file
--- /dev/null
+\version "2.11.34"
+
+\header {
+ texidoc = "The number of pages in a score can be forced by setting
+@code{page-count} in the (book-level) paper block."
+}
+
+#(set-default-paper-size "a6")
+
+\book {
+ \paper { page-count = 2}
+ \score { {c'1 c'1} }
+}
\ No newline at end of file
--- /dev/null
+\version "2.11.34"
+
+\header {
+ texidoc = "The number of pages in a score can be forced by setting
+@code{page-count} in the (book-level) paper block. If there are too
+few systems for the number of pages, we append blank pages."
+}
+
+#(set-default-paper-size "a6")
+
+\book {
+ \paper { page-count = 3}
+ \score { {c'1 c'1} }
+}
\ No newline at end of file
--- /dev/null
+\version "2.11.34"
+
+\header {
+ texidoc = "The number of pages in a score can be forced by setting
+@code{page-count} in the (book-level) paper block. Even if there are
+too many systems for that number of pages, we will squeeze them in."
+}
+
+#(set-default-paper-size "a6")
+
+\book {
+ \paper { page-count = 1}
+ \score { { \repeat unfold 10 {c'1 \break} } }
+}
\ No newline at end of file
for (vsize i = 0; i + 1 < breaks.size (); i++)
{
int r = Paper_column::get_rank (cols[breaks[i]]);
- if (r > end)
+ if (r >= end)
break;
if (r >= start)
int min_den = INT_MAX;
int min_index = -1;
- Moment beat_pos;
for (vsize i = 1; i < infos_.size (); i++)
{
Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_;
int
Constrained_breaking::max_system_count (vsize start, vsize end)
{
- vsize brk = (end >= start_.size ()) ? breaks_.size () : starting_breakpoints_[end];
+ vsize brk = (end >= start_.size ()) ? breaks_.size () - 1 : starting_breakpoints_[end];
return brk - starting_breakpoints_[start];
}
bool is_last () const;
Real page_height (int page_number, bool last) const;
Real page_top_space () const;
+ vsize system_count () const;
protected:
Paper_book *book_;
bool ragged_;
bool ragged_last_;
Real page_top_space_;
+ vsize system_count_;
vector<Line_division> current_configurations_;
vector<Break_position> current_chunks_;
vsize end = last_break_position ();
vsize max_sys_count = max_system_count (0, end);
vsize first_page_num = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
+ SCM forced_page_count = book_->paper_->c_variable ("page-count");
- /* find out the ideal number of pages */
- message (_ ("Finding the ideal number of pages..."));
set_to_ideal_line_configuration (0, end);
-
- Page_spacing_result best = space_systems_on_best_pages (0, first_page_num);
- vsize page_count = best.systems_per_page_.size ();
+
+ Page_spacing_result best;
+ vsize page_count = robust_scm2int (forced_page_count, 1);
Line_division ideal_line_division = current_configuration (0);
Line_division best_division = ideal_line_division;
+ vsize min_sys_count = 1;
+ vsize ideal_sys_count = system_count ();
+
+ if (!scm_is_integer (forced_page_count))
+ {
+ /* find out the ideal number of pages */
+ message (_ ("Finding the ideal number of pages..."));
+
+ best = space_systems_on_best_pages (0, first_page_num);
+ page_count = best.systems_per_page_.size ();
- vsize ideal_sys_count = best.system_count ();
- vsize min_sys_count = ideal_sys_count - best.systems_per_page_.back ();
+ ideal_sys_count = best.system_count ();
+ min_sys_count = ideal_sys_count - best.systems_per_page_.back ();
- if (page_count > 1 && best.systems_per_page_[page_count - 2] > 1)
- min_sys_count -= best.systems_per_page_[page_count - 2];
+ if (page_count > 1 && best.systems_per_page_[page_count - 2] > 1)
+ min_sys_count -= best.systems_per_page_[page_count - 2];
+ }
+ else
+ best = space_systems_on_n_pages (0, page_count, first_page_num);
if (page_count == 1)
message (_ ("Fitting music on 1 page..."));
+ else if (scm_is_integer (forced_page_count))
+ message (_f ("Fitting music on %d pages...", (int)page_count));
else
message (_f ("Fitting music on %d or %d pages...", (int)page_count-1, (int)page_count));
vsize min_p_count = min_page_count (i, first_page_num);
Page_spacing_result cur;
- if (min_p_count > page_count)
- continue;
- else if (min_p_count == page_count)
+ if (min_p_count == page_count)
cur = space_systems_on_n_pages (i, page_count, first_page_num);
else
cur = space_systems_on_n_or_one_more_pages (i, page_count-1, first_page_num);
Page_breaking::Page_breaking (Paper_book *pb, Break_predicate is_break)
{
book_ = pb;
+ system_count_ = 0;
ragged_ = to_boolean (pb->paper_->c_variable ("ragged-bottom"));
ragged_last_ = to_boolean (pb->paper_->c_variable ("ragged-last-bottom"));
page_top_space_ = robust_scm2double (pb->paper_->c_variable ("page-top-space"), 0);
return page_top_space_;
}
+vsize
+Page_breaking::system_count () const
+{
+ return system_count_;
+}
+
/* translate indices into breaks_ into start-end parameters for the line breaker */
void
Page_breaking::line_breaker_args (vsize sys,
Line_division lower_bound,
Line_division upper_bound)
{
+ system_count_ = system_count;
current_chunks_ = chunk_list (start, end);
current_start_breakpoint_ = start;
current_end_breakpoint_ = end;
current_start_breakpoint_ = start;
current_end_breakpoint_ = end;
clear_line_details_cache ();
+ system_count_ = 0;
Line_division div;
for (vsize i = 0; i+1 < current_chunks_.size (); i++)
}
else
div.push_back (1);
+
+ system_count_ += div.back ();
}
current_configurations_.clear ();
current_configurations_.push_back (div);
Page_breaking::space_systems_on_n_pages (vsize configuration, vsize n, vsize first_page_num)
{
Page_spacing_result ret;
- assert (n >= min_page_count (configuration, first_page_num));
cache_line_details (configuration);
- if (n > cached_line_details_.size ())
- return Page_spacing_result ();
- if (n == 1)
+ bool valid_n = (n >= min_page_count (configuration, first_page_num)
+ && n <= cached_line_details_.size ());
+
+ if (!valid_n)
+ programming_error ("number of pages is out of bounds");
+
+ if (n == 1 && valid_n)
ret = space_systems_on_1_page (cached_line_details_,
page_height (first_page_num, is_last ()),
ragged () || (is_last () && ragged_last ()));
- else if (n == 2)
+ else if (n == 2 && valid_n)
ret = space_systems_on_2_pages (configuration, first_page_num);
else
{
cache_line_details (configuration);
vsize min_p_count = min_page_count (configuration, first_page_num);
+ bool valid_n = n >= min_p_count || n <= cached_line_details_.size ();
+
+ if (!valid_n)
+ programming_error ("both page counts are out of bounds");
- if (n == 1)
+ if (n == 1 && valid_n)
{
bool rag = ragged () || (is_last () && ragged_last ());
Real height = page_height (first_page_num, is_last ());
{
Page_spacer ps (cached_line_details_, first_page_num, this);
- if (n >= min_p_count)
+ if (n >= min_p_count || !valid_n)
n_res = ps.solve (n);
- if (n < cached_line_details_.size ())
+ if (n < cached_line_details_.size () || !valid_n)
m_res = ps.solve (n+1);
}
resize (page_count);
Page_spacing_result ret;
- ret.force_.resize (page_count);
- ret.systems_per_page_.resize (page_count);
vsize system = lines_.size () - 1;
- vsize tack_onto_the_end = 0;
+ vsize extra_systems = 0;
+ vsize extra_pages = 0;
if (isinf (state_.at (system, page_count-1).demerits_))
{
if (i)
{
- tack_onto_the_end = system - i;
+ extra_systems = system - i;
system = i;
}
else
- return Page_spacing_result (); /* couldn't salvage it -- probably going to crash */
+ {
+ /* try chopping off pages from the end */
+ vsize j;
+ for (j = page_count; j && isinf (state_.at (system, j-1).demerits_); j--)
+ ;
+
+ if (j)
+ {
+ extra_pages = page_count - j;
+ page_count = j;
+ }
+ else
+ return Page_spacing_result (); /* couldn't salvage it -- probably going to crash */
+ }
}
+ ret.force_.resize (page_count);
+ ret.systems_per_page_.resize (page_count);
ret.penalty_ = state_.at (system, page_count-1).penalty_
+ lines_.back ().page_penalty_ + lines_.back ().turn_penalty_;
if (p == 0)
ret.systems_per_page_[p] = system + 1;
else
- ret.systems_per_page_[p] = system - ps.prev_ + tack_onto_the_end;
+ ret.systems_per_page_[p] = system - ps.prev_;
system = ps.prev_;
}
+
+ if (extra_systems)
+ {
+ ret.systems_per_page_.back () += extra_systems;
+ ret.demerits_ += 200000;
+ }
+ if (extra_pages)
+ {
+ ret.force_.insert (ret.force_.end (), extra_pages, 200000);
+ ret.systems_per_page_.insert (ret.systems_per_page_.end (), extra_pages, 0);
+ ret.demerits_ += 200000;
+ }
+
+
ret.demerits_ += ret.penalty_;
return ret;
}
NAME = lilypond
MODULE_NAME = po
DOMAIN = $(NAME)
-EXTRA_DIST_FILES = TODO
+EXTRA_DIST_FILES = TODO README
STEPMAKE_TEMPLATES=podir
include $(depth)/make/stepmake.make
--- /dev/null
+LilyPond program strings translation
+
+Addresses
+=========
+
+Free Translation Project (FTP)
+ http://translationproject.org
+
+LilyPond page on FTP
+ http://translationproject.org/domain/lilypond.html
+
+FTP coordinator
+ <coordinator (at) translationproject (dot) org>
+
+
+Instructions
+============
+
+Program strings are translated in PO files in this directory.
+
+This kind of translation is managed through the Free Translation
+Project (FTP) -- see rationale below.
+
+The only changes that should be made to this directory are
+
+1) applying changes made on the FTP. These changes should be
+automatically notified to lilypond-devel@gnu.org list by the FTP
+robot; you can also see LilyPond page on FTP.
+
+
+2) updating lilypond.pot: run 'make po-replace' at toplevel, clean up
+lilypond.pot header to make it look like its previous state, commit
+only lilypond.pot to Git and reset all .po files, roll a tarball with
+'make dist', upload it somewhere on the web (or wait for the release),
+and send a notification to FTP coordinator with a link to the tarball.
+
+
+Rationale
+=========
+Why should we use the FTP?
+
+The FTP is designed to make software usable in more languages and
+reduce software packagers work and responsability for translations, as
+it organizes translations by language teams, rather than by packages.
+This benefits to both users and developers; for example, translators
+often volunteer without the developers need to spend time and energy
+to find them, and all translation maintaining issues can be discussed
+by the language team.
+
+In a short-circuit method, translators usually send their work
+directly to the developers who commit it to the sources. The FTP is
+not significantly slower, it can even be made as quick; for example,
+translators in 4 languages updated 2.11.34 PO between 2 and 8 days
+after I sent the notification update.
+
+We still don't use FTP for translating the documentation, because it
+has currently no infrastructure for this.
+
+
+Common issues
+=============
+
+-- I'd like to commit fixes in .po for all languages
+(e.g. punctuation, formatting), is it possible?
+
+This should be avoided. If it really saves translators' time, apply
+changes to Git and notice both FTP coordinator (so he can apply the
+changes to FTP too) and LilyPond translation meister (at
+lilypond-devel@gnu.org).
+
+
+-- The translation in my language could be improved, how can I propose
+changes?
+
+Prepare a polite request with your changes in diff format, or better
+with inline comments to the original translation, and send it to the
+translator assigned to LilyPond in your language, with CC to your
+language team (you cand find their email addresses on LilyPond FTP
+page).
+
+If you get no reply within a reasonable timescale (2 weeks or so), or
+a negative reply, and if you still think your suggestions are
+worthwhile, please notice the developers at lilypond-devel@gnu.org.
+We can always discuss with FTP coordinators to see what we can do.
+
+
+For any other question, ask LilyPond translation meister at
+lilypond-devel@gnu.org.
TODO
+See also README for general instructions.
+
FIX OR STANDARDISE TARGETS
* extract translatable strings from source code to `po/out/': at toplevel, do:
MAKEFILE_MD5=`find $srcdir -name GNUmakefile | grep -v '^./GNUmakefile$' | sort | md5sum | cut -b 1-32`
CONFIGURE_INPUT_MD5=`cat $srcdir/config.make.in $srcdir/config.hh.in $srcdir/GNUmakefile.in | md5sum | cut -b 1-32`
-
+CONFIGURE_OPTIONS_MD5=`echo "$@" | tr ' ' '\n' | sed 's/ */ /g' | grep '.' | sort -u | md5sum | cut -b 1-32`
CONFIGURE_CHECKSUM_FILE=configure.checksum
-CONFIGURE_CHECKSUM="$MAKEFILE_MD5$CONFIGURE_INPUT_MD5"
+CONFIGURE_CHECKSUM="$MAKEFILE_MD5$CONFIGURE_INPUT_MD5$CONFIGURE_OPTIONS_MD5"
if test `cat $CONFIGURE_CHECKSUM_FILE` = "$CONFIGURE_CHECKSUM" ; then
exit 0