+ /*
+ first, we have to see how many footnotes are on this page.
+ we need to do this first so that we can line them up
+ */
+
+ Output_def *paper = pb->paper_;
+
+ if (!paper)
+ {
+ programming_error ("Cannot get footnotes because there is no valid paper block.");
+ return SCM_EOL;
+ }
+
+ SCM number_footnote_table = pb->top_paper ()->c_variable ("number-footnote-table");
+ if (!scm_is_pair (number_footnote_table))
+ number_footnote_table = SCM_EOL;
+ SCM numbering_function = paper->c_variable ("footnote-numbering-function");
+ SCM layout = paper->self_scm ();
+ SCM props = scm_call_1 (ly_lily_module_constant ("layout-extract-page-properties"),
+ paper->self_scm ());
+ Real padding = robust_scm2double (paper->c_variable ("footnote-padding"), 0.0);
+ Real number_raise = robust_scm2double (paper->c_variable ("footnote-number-raise"), 0.0);
+
+ vsize fn_count = get_footnote_count (lines);
+
+ // now, make the footnote stencils with the numbering function
+ SCM numbers = SCM_EOL;
+ SCM in_text_numbers = SCM_EOL;
+ bool do_numbering = to_boolean (paper->c_variable ("footnote-auto-numbering"));
+ // if there's no numbering, skip all this
+ /*
+ TODO: This recalculates numbering every time this function is called, including once
+ after the balloon prints are called. Although it is not a huge computational drain,
+ it'd be more elegant to turn this calculation off when it is no longer needed.
+
+ In a separate commit, it'd be nice to streamline the way that page layout property
+ is handled so that the process of building `config's in page-breaking does result
+ in duplicated work, either by making this process less complicated or (preferably)
+ by passing its results downstream.
+ */
+ if (do_numbering)
+ {
+ vector<SCM> footnote_number_markups; // Holds the numbering markups.
+ vector<Stencil *> footnote_number_stencils; // Holds translated versions of the stencilized numbering markups.
+ for (vsize i = 0; i < fn_count; i++)
+ {
+ SCM markup = scm_call_1 (numbering_function, scm_from_int (counter));
+ Stencil *s = unsmob_stencil (Text_interface::interpret_markup (layout, props, markup));
+ if (!s)
+ {
+ programming_error ("Your numbering function needs to return a stencil.");
+ markup = SCM_EOL;
+ s = new Stencil (Box (Interval (0,0), Interval (0,0)), SCM_EOL);
+ }
+ footnote_number_markups.push_back (markup);
+ footnote_number_stencils.push_back (s);
+ counter++;
+ }
+
+ // find the maximum X_AXIS length
+ Real max_length;
+ for (vsize i = 0; i < fn_count; i++)
+ max_length = max (max_length, footnote_number_stencils[i]->extent (X_AXIS).length ());
+
+ /*
+ translate each stencil such that it attains the correct maximum length and bundle the
+ footnotes into a scheme object.
+ */
+ SCM *tail = &numbers;
+ SCM *in_text_tail = &in_text_numbers;
+
+ for (vsize i = 0; i < fn_count; i++)
+ {
+ *in_text_tail = scm_cons (footnote_number_markups[i], SCM_EOL);
+ in_text_tail = SCM_CDRLOC (*in_text_tail);
+ footnote_number_stencils[i]->translate_axis (max_length - footnote_number_stencils[i]->extent (X_AXIS).length (), X_AXIS);
+ *tail = scm_cons (footnote_number_stencils[i]->smobbed_copy (), SCM_EOL);
+ tail = SCM_CDRLOC (*tail);
+ }
+ }
+ // build the footnotes
+