diff options
Diffstat (limited to 'Build/source/texk/gregorio/gregorio-src/src/gregoriotex/gregoriotex-write.c')
-rw-r--r-- | Build/source/texk/gregorio/gregorio-src/src/gregoriotex/gregoriotex-write.c | 159 |
1 files changed, 105 insertions, 54 deletions
diff --git a/Build/source/texk/gregorio/gregorio-src/src/gregoriotex/gregoriotex-write.c b/Build/source/texk/gregorio/gregorio-src/src/gregoriotex/gregoriotex-write.c index ad358da55d9..c221d903e39 100644 --- a/Build/source/texk/gregorio/gregorio-src/src/gregoriotex/gregoriotex-write.c +++ b/Build/source/texk/gregorio/gregorio-src/src/gregoriotex/gregoriotex-write.c @@ -2534,20 +2534,31 @@ static int gregoriotex_syllable_first_type(gregorio_syllable *syllable) static __inline void write_low_choral_sign(FILE *const f, const gregorio_note *const note, int special) { - fprintf(f, "\\GreLowChoralSign{%d}{%s%s%s}{%d}%%\n", - pitch_value(note->u.note.pitch), - note->choral_sign_is_nabc? "\\GreNABCChar{" : "", - note->choral_sign, note->choral_sign_is_nabc? "}" : "", special); + if (note->choral_sign_is_nabc) { + fprintf(f, "\\GreLowChoralSign{%d}{\\GreNABCChar{", + pitch_value(note->u.note.pitch)); + tex_escape_text(f, note->choral_sign); + fprintf(f, "}}{%d}%%\n", special); + } else { + fprintf(f, "\\GreLowChoralSign{%d}{%s}{%d}%%\n", + pitch_value(note->u.note.pitch), note->choral_sign, + special); + } } static __inline void write_high_choral_sign(FILE *const f, const gregorio_note *const note, int pitch_offset) { - fprintf(f, "\\GreHighChoralSign{%d}{%s%s%s}{\\GreOCase%s}%%\n", - pitch_value(note->u.note.pitch + pitch_offset), - note->choral_sign_is_nabc? "\\GreNABCChar{" : "", - note->choral_sign, note->choral_sign_is_nabc? "}" : "", - note->gtex_offset_case); + if (note->choral_sign_is_nabc) { + fprintf(f, "\\GreHighChoralSign{%d}{\\GreNABCChar{", + pitch_value(note->u.note.pitch + pitch_offset)); + tex_escape_text(f, note->choral_sign); + fprintf(f, "}}{\\GreOCase%s}%%\n", note->gtex_offset_case); + } else { + fprintf(f, "\\GreHighChoralSign{%d}{%s}{\\GreOCase%s}%%\n", + pitch_value(note->u.note.pitch + pitch_offset), + note->choral_sign, note->gtex_offset_case); + } } static void gregoriotex_write_choral_sign(FILE *f, gregorio_glyph *glyph, @@ -3252,17 +3263,20 @@ static __inline void write_syllable_point_and_click(FILE *const f, } static void write_syllable_text(FILE *f, const char *const syllable_type, - const gregorio_character *text, bool ignored __attribute__((unused))) + const bool forced_center, const gregorio_character *text, + const bool ignored __attribute__((unused))) { if (syllable_type != NULL) { - fprintf(f, "%s{\\GreSetThisSyllable", syllable_type); + fprintf(f, "%s{%s\\GreSetThisSyllable", syllable_type, + forced_center? "\\GreGABCForceCenters" : ""); write_text(f, text); fprintf(f, "}"); } } static void write_first_syllable_text(FILE *f, const char *const syllable_type, - const gregorio_character *const text, bool end_of_word) + const bool forced_center, const gregorio_character *const text, + const bool end_of_word) { gregorio_not_null(syllable_type, write_first_syllable_text, return); if (text == NULL) { @@ -3273,13 +3287,8 @@ static void write_first_syllable_text(FILE *f, const char *const syllable_type, const gregorio_character *t; /* find out if there is a forced center -> has_forced_center */ - gregorio_center_determination center = CENTER_NOT_DETERMINED; - for (t = text; t; t = t->next_character) { - if (!t->is_character && t->cos.s.style == ST_FORCED_CENTER) { - center = CENTER_FULLY_DETERMINED; - break; - } - } + gregorio_center_determination center = forced_center? + CENTER_FULLY_DETERMINED : CENTER_NOT_DETERMINED; gregorio_rebuild_first_syllable(&text_with_initial, false); gregorio_rebuild_characters(&text_with_initial, center, false); @@ -3289,7 +3298,8 @@ static void write_first_syllable_text(FILE *f, const char *const syllable_type, gregorio_rebuild_characters(&text_without_initial, center, true); gregorio_set_first_word(&text_without_initial); - fprintf(f, "}{%s}{\\GreSetFirstSyllableText", syllable_type); + fprintf(f, "}{%s}{%s\\GreSetFirstSyllableText", syllable_type, + forced_center? "\\GreGABCForceCenters" : ""); fprintf(f, "{"); gregorio_write_first_letter_alignment_text(WTP_FIRST_SYLLABLE, @@ -3340,49 +3350,73 @@ 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, + unsigned 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'; + *next_euouae_id = 0; if (syllable->next_syllable) { for (syllable = syllable->next_syllable; syllable && syllable->elements && *(syllable->elements) && (*(syllable->elements))->type == GRE_END_OF_LINE; 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}%%\n", euouae_id); + *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); } } @@ -3403,13 +3437,17 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, unsigned char first_of_disc, gregoriotex_status *const status, const gregorio_score *const score, void (*const write_this_syllable_text) - (FILE *, const char *, const gregorio_character *, bool)) + (FILE *, const char *, bool, const gregorio_character *, bool)) { 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; + unsigned 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 @@ -3438,7 +3476,8 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, } else { fprintf(f, "%%\n%%\n\\GreNewLine %%\n%%\n%%\n"); } - write_this_syllable_text(f, NULL, syllable->text, end_of_word); + write_this_syllable_text(f, NULL, syllable->forced_center, + syllable->text, end_of_word); return; } /* @@ -3465,7 +3504,8 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, write_syllable(f, syllable, 2, status, score, write_syllable_text); fprintf(f, "}%%\n"); - write_this_syllable_text(f, NULL, syllable->text, end_of_word); + write_this_syllable_text(f, NULL, syllable->forced_center, + syllable->text, end_of_word); return; } } @@ -3477,16 +3517,16 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, && (syllable->elements)[0]->u.misc.unpitched.info.bar == B_DIVISIO_FINALIS) { handle_final_bar(f, "DivisioFinalis", syllable); - write_this_syllable_text(f, NULL, syllable->text, - end_of_word); + write_this_syllable_text(f, NULL, syllable->forced_center, + syllable->text, end_of_word); return; } if (!syllable->next_syllable && !syllable->text && (syllable->elements)[0]->u.misc.unpitched.info.bar == B_DIVISIO_MAIOR) { handle_final_bar(f, "DivisioMaior", syllable); - write_this_syllable_text(f, NULL, syllable->text, - end_of_word); + write_this_syllable_text(f, NULL, syllable->forced_center, + syllable->text, end_of_word); return; } } @@ -3505,7 +3545,8 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, syllable->next_syllable? syllable->next_syllable->text : NULL); syllable_type = "\\GreNoNoteSyllable"; } - write_this_syllable_text(f, syllable_type, syllable->text, end_of_word); + write_this_syllable_text(f, syllable_type, syllable->forced_center, + syllable->text, end_of_word); fprintf(f, "{}{\\Gre%s}", syllable->first_word ? "FirstWord" : "Unstyled"); if (end_of_word) { fprintf(f, "{1}"); @@ -3513,11 +3554,18 @@ 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"); + fprintf(f, "{%s\\GreSetNextSyllable", + syllable->next_syllable->forced_center? + "\\GreGABCNextForceCenters" : ""); 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); @@ -3557,8 +3605,9 @@ static void write_syllable(FILE *f, gregorio_syllable *syllable, size_t i; for (i = 0; i < element->nabc_lines; i++) { if (element->nabc[i]) { - fprintf(f, "\\GreNABCNeumes{%d}{%s}%%\n", (int)(i+1), - element->nabc[i]); + fprintf(f, "\\GreNABCNeumes{%d}{", (int)(i+1)); + tex_escape_text(f, element->nabc[i]); + fprintf(f, "}%%\n"); } } } @@ -3670,8 +3719,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 */ @@ -3698,8 +3748,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 |