From f78af06e84dec56edd7f7661b17c3cacd89d99b1 Mon Sep 17 00:00:00 2001 From: "Henry So, Jr." Date: Thu, 3 Mar 2016 23:57:16 -0500 Subject: [PATCH] Added \GreLastSyllableBeforeEUOUAE into the syllable before EUOUAE. Fixes #988. --- CHANGELOG.md | 2 + doc/Command_Index_gregorio.tex | 12 ++++- src/gregoriotex/gregoriotex-write.c | 82 ++++++++++++++++++++--------- tex/gregoriotex-syllable.tex | 9 ++++ 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5df9df243..4a3795b3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. As of v3.0.0 this project adheres to [Semantic Versioning](http://semver.org/). It follows [some conventions](http://keepachangelog.com/). [Unreleased][unreleased] +### Fixed +- Corrected the end-of-line shift for a ragged line break before `` blocks (see [#988](https://github.com/gregorio-project/gregorio/issues/988)). ## [4.1.0] - 2016-03-01 diff --git a/doc/Command_Index_gregorio.tex b/doc/Command_Index_gregorio.tex index ee5ff2de6..6a0eb53b4 100644 --- a/doc/Command_Index_gregorio.tex +++ b/doc/Command_Index_gregorio.tex @@ -558,6 +558,15 @@ \section{Gregorio Controls} \macroname{\textbackslash GreLastOfScore}{}{gregoriotex-main.tex} Macro to mark the syllable as the last of the score. +\macroname{\textbackslash GreLastSyllableBeforeEUOUAE}{\#1\#2}{gregoriotex-syllable.tex} +Indicates that this syllable is the last syllable before a EUOUAE block. + +\begin{argtable} + \#1 & integer & The identifier of the EUOUAE block.\\ + \#2 & \texttt{0} & There is no line break between this syllable and the EUOUAE block.\\ + & \texttt{1} & There is a line break between this syllable and the beginning of the EUOUAE block.\\ +\end{argtable} + \macroname{\textbackslash GreLinea}{\#1\#2\#3}{gregoriotex-signs.tex} Macro for typesetting a linea. @@ -633,7 +642,8 @@ \section{Gregorio Controls} \begin{argtable} \#1 & integer & The identifier of the EUOUAE block.\\ - \#2 & integer & 0 in the genral case, 1 if there is a line break between this macro and the beginning of the EUOUAE block.\\ + \#2 & \texttt{0} & There is no line break between this syllable and the EUOUAE block.\\ + & \texttt{1} & There is a line break between this syllable and the beginning of the EUOUAE block.\\ \end{argtable} \macroname{\textbackslash GreOriscusCavum}{\#1\#2\#3\#4\#5\#6}{gregoriotex-signs.tex} diff --git a/src/gregoriotex/gregoriotex-write.c b/src/gregoriotex/gregoriotex-write.c index 8aaca3530..004062ae4 100644 --- a/src/gregoriotex/gregoriotex-write.c +++ b/src/gregoriotex/gregoriotex-write.c @@ -3340,28 +3340,42 @@ static void write_first_syllable_text(FILE *f, const char *const syllable_type, } static __inline void scan_syllable_for_eol( - const gregorio_syllable *const syllable, - bool *eol_forces_custos, bool *eol_forces_custos_on) { + const gregorio_syllable *const syllable, char *const eol_forces_custos) +{ const gregorio_element *element; if (syllable->elements) { for (element = *(syllable->elements); element; element = element->next) { if (element->type == GRE_END_OF_LINE) { if (element->u.misc.unpitched.info.eol_forces_custos) { - *eol_forces_custos = true; - *eol_forces_custos_on = - element->u.misc.unpitched.info.eol_forces_custos_on; + *eol_forces_custos = element->u.misc.unpitched.info + .eol_forces_custos_on? '1' : '0'; } } } } } -static __inline void anticipate_event(FILE *f, gregorio_syllable *syllable) { +/* + * euouae_follows will be + * - '\0' if no euouae follows + * - '0' if euouae follows with no intervening linebreak + * - '1' if euouae follows with an intervening linebreak + * + * eol_forces_custos will be + * - '\0' if no linebreak follows or doesn't force a custos + * - '0' if a linebreak follows and forces custos off + * - '1' if a linebreak follows and forces custos on + */ +static __inline void anticipate_event(gregorio_syllable *syllable, + char *const euouae_follows, char *const eol_forces_custos, + short *const next_euouae_id) +{ static unsigned short euouae_id = 0; - bool eol_forces_custos = false; - bool eol_forces_custos_on = false; bool has_intervening_linebreak = false; + *euouae_follows = '\0'; + *eol_forces_custos = '\0'; + if (syllable->next_syllable) { for (syllable = syllable->next_syllable; syllable && syllable->elements && *(syllable->elements) @@ -3369,23 +3383,29 @@ static __inline void anticipate_event(FILE *f, gregorio_syllable *syllable) { syllable = syllable->next_syllable) { has_intervening_linebreak = true; /* we are at an end-of-line, so check if custos is forced */ - scan_syllable_for_eol(syllable, &eol_forces_custos, - &eol_forces_custos_on); + scan_syllable_for_eol(syllable, eol_forces_custos); } if (syllable) { - scan_syllable_for_eol(syllable, &eol_forces_custos, - &eol_forces_custos_on); + scan_syllable_for_eol(syllable, eol_forces_custos); if (syllable->euouae == EUOUAE_BEGINNING) { - syllable->euouae_id = ++euouae_id; - fprintf(f, "%%\n\\GreNextSyllableBeginsEUOUAE{%hu}{%c}%%\n", - euouae_id, has_intervening_linebreak ? '1' : '0'); + *next_euouae_id = syllable->euouae_id = ++euouae_id; + *euouae_follows = has_intervening_linebreak? '1' : '0'; } } - if (eol_forces_custos) { - fprintf(f, "%%\n\\GreUpcomingNewLineForcesCustos{%c}%%\n", - eol_forces_custos_on? '1' : '0'); - } + } +} + +static __inline void write_anticipated_event(FILE *f, const char euouae_follows, + const char eol_forces_custos, const short next_euouae_id) +{ + if (euouae_follows) { + fprintf(f, "%%\n\\GreNextSyllableBeginsEUOUAE{%hu}{%c}%%\n", + next_euouae_id, euouae_follows); + } + if (eol_forces_custos) { + fprintf(f, "%%\n\\GreUpcomingNewLineForcesCustos{%c}%%\n", + eol_forces_custos); } } @@ -3410,9 +3430,13 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, { gregorio_element *clef_change_element = NULL, *element; const char *syllable_type = NULL; - bool event_anticipated = false; + bool anticipated_event_written = false; bool end_of_word; bool end_of_line; + char euouae_follows; + char eol_forces_custos; + short next_euouae_id; + gregorio_not_null(syllable, write_syllable, return); end_of_word = syllable->position == WORD_END || syllable->position == WORD_ONE_SYLLABLE || !syllable->text @@ -3516,11 +3540,16 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, fprintf(f, "{0}"); } end_of_line = is_last_of_line(syllable); + anticipate_event(syllable, &euouae_follows, &eol_forces_custos, + &next_euouae_id); if (syllable->next_syllable) { fprintf(f, "{\\GreSetNextSyllable"); write_text(f, syllable->next_syllable->text); if (end_of_line) { fprintf(f, "\\GreLastOfLine"); + } else if (euouae_follows) { + fprintf(f, "\\GreLastSyllableBeforeEUOUAE{%hu}{%c}", + next_euouae_id, euouae_follows); } fprintf(f, "}{"); write_syllable_point_and_click(f, syllable, status); @@ -3530,6 +3559,9 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, fprintf(f, "{\\GreSetNextSyllable{}{}{}{}{}"); if (end_of_line) { fprintf(f, "\\GreLastOfLine"); + } else if (euouae_follows) { + fprintf(f, "\\GreLastSyllableBeforeEUOUAE{%hu}{%c}", + next_euouae_id, euouae_follows); } fprintf(f, "}{"); write_syllable_point_and_click(f, syllable, status); @@ -3673,8 +3705,9 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, case GRE_END_OF_LINE: if (!element->next) { - anticipate_event(f, syllable); - event_anticipated = true; + write_anticipated_event(f, euouae_follows, + eol_forces_custos, next_euouae_id); + anticipated_event_written = true; } /* here we suppose we don't have two linebreaks in the same * syllable */ @@ -3701,8 +3734,9 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, } } } - if (!event_anticipated) { - anticipate_event(f, syllable); + if (!anticipated_event_written) { + write_anticipated_event(f, euouae_follows, eol_forces_custos, + next_euouae_id); } fprintf(f, "}%%\n"); if (syllable->position == WORD_END diff --git a/tex/gregoriotex-syllable.tex b/tex/gregoriotex-syllable.tex index 16a5daaaf..93e7f91a9 100644 --- a/tex/gregoriotex-syllable.tex +++ b/tex/gregoriotex-syllable.tex @@ -774,6 +774,15 @@ \relax % }% +% #1 is the id of the euouae block (assigned by the C code) +% #2 is whether there is a line break between here and the actuall beginning of +% the euouae block. 1 if there is a linebreak, 0 in the general case. +\def\GreLastSyllableBeforeEUOUAE#1#2{% + \ifcase#2\ifcase\directlua{gregoriotex.is_ypos_different(#1)}\relax% + \GreLastOfLine% + \fi\fi % +}% + %% @desc Macro to make a few checks and call the right macros between %% \endbeforebar, \endofword, \endofsyllable %% @arg#1 next syllable type (#7 of \GreSyllable)