@@ -761,95 +761,6 @@ int IsVowel(Translator *tr, int letter) | |||
return IsLetter(tr, letter, LETTERGP_VOWEL2); | |||
} | |||
static int Unpronouncable2(Translator *tr, char *word) | |||
{ | |||
int c; | |||
int end_flags; | |||
char ph_buf[N_WORD_PHONEMES]; | |||
ph_buf[0] = 0; | |||
c = word[-1]; | |||
word[-1] = ' '; // ensure there is a space before the "word" | |||
end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL); | |||
word[-1] = c; | |||
if ((end_flags == 0) || (end_flags & SUFX_UNPRON)) | |||
return 1; | |||
return 0; | |||
} | |||
int Unpronouncable(Translator *tr, char *word, int posn) | |||
{ | |||
/* Determines whether a word in 'unpronouncable', i.e. whether it should | |||
be spoken as individual letters. | |||
This function may be language specific. This is a generic version. | |||
*/ | |||
int c; | |||
int c1 = 0; | |||
int vowel_posn = 9; | |||
int index; | |||
int count; | |||
ALPHABET *alphabet; | |||
utf8_in(&c, word); | |||
if ((tr->letter_bits_offset > 0) && (c < 0x241)) { | |||
// Latin characters for a language with a non-latin alphabet | |||
return 0; // so we can re-translate the word as English | |||
} | |||
if (((alphabet = AlphabetFromChar(c)) != NULL) && (alphabet->offset != tr->letter_bits_offset)) { | |||
// Character is not in our alphabet | |||
return 0; | |||
} | |||
if (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 1) | |||
return 0; | |||
if (((c = *word) == ' ') || (c == 0) || (c == '\'')) | |||
return 0; | |||
index = 0; | |||
count = 0; | |||
for (;;) { | |||
index += utf8_in(&c, &word[index]); | |||
if ((c == 0) || (c == ' ')) | |||
break; | |||
if ((c == '\'') && ((count > 1) || (posn > 0))) | |||
break; // "tv'" but not "l'" | |||
if (count == 0) | |||
c1 = c; | |||
if ((c == '\'') && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 3)) { | |||
// don't count apostrophe | |||
} else | |||
count++; | |||
if (IsVowel(tr, c)) { | |||
vowel_posn = count; // position of the first vowel | |||
break; | |||
} | |||
if ((c != '\'') && !iswalpha(c)) | |||
return 0; | |||
} | |||
if ((vowel_posn > 2) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2)) { | |||
// Lookup unpronounable rules in *_rules | |||
return Unpronouncable2(tr, word); | |||
} | |||
if (c1 == tr->langopts.param[LOPT_UNPRONOUNCABLE]) | |||
vowel_posn--; // disregard this as the initial letter when counting | |||
if (vowel_posn > (tr->langopts.max_initial_consonants+1)) | |||
return 1; // no vowel, or no vowel in first few letters | |||
return 0; | |||
} | |||
int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *vowel_stress, int *vowel_count, int *stressed_syllable, int control) | |||
{ | |||
// control = 1, set stress to 1 for forced unstressed vowels |
@@ -41,7 +41,6 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int | |||
const char *GetTranslatedPhonemeString(int phoneme_mode); | |||
int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *vowel_stress, int *vowel_count, int *stressed_syllable, int control); | |||
int IsVowel(Translator *tr, int letter); | |||
int Unpronouncable(Translator *tr, char *word, int posn); | |||
void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int control); | |||
void AppendPhonemes(Translator *tr, char *string, int size, const char *ph); | |||
int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, char *end_phonemes, int word_flags, unsigned int *dict_flags); |
@@ -51,6 +51,8 @@ static int CheckDottedAbbrev(char *word1); | |||
static int NonAsciiNumber(int letter); | |||
static char *SpeakIndividualLetters(Translator *tr, char *word, char *phonemes, int spell_word, ALPHABET *current_alphabet, char word_phonemes[]); | |||
static int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALPHABET *current_alphabet); | |||
static int Unpronouncable(Translator *tr, char *word, int posn); | |||
static int Unpronouncable2(Translator *tr, char *word); | |||
int TranslateWord3(Translator *tr, char *word_start, WORD_TAB *wtab, char *word_out, bool *any_stressed_words, ALPHABET *current_alphabet, char word_phonemes[], size_t size_word_phonemes) | |||
{ | |||
@@ -1079,3 +1081,92 @@ static int NonAsciiNumber(int letter) | |||
} | |||
return -1; | |||
} | |||
static int Unpronouncable(Translator *tr, char *word, int posn) | |||
{ | |||
/* Determines whether a word in 'unpronouncable', i.e. whether it should | |||
be spoken as individual letters. | |||
This function may be language specific. This is a generic version. | |||
*/ | |||
int c; | |||
int c1 = 0; | |||
int vowel_posn = 9; | |||
int index; | |||
int count; | |||
ALPHABET *alphabet; | |||
utf8_in(&c, word); | |||
if ((tr->letter_bits_offset > 0) && (c < 0x241)) { | |||
// Latin characters for a language with a non-latin alphabet | |||
return 0; // so we can re-translate the word as English | |||
} | |||
if (((alphabet = AlphabetFromChar(c)) != NULL) && (alphabet->offset != tr->letter_bits_offset)) { | |||
// Character is not in our alphabet | |||
return 0; | |||
} | |||
if (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 1) | |||
return 0; | |||
if (((c = *word) == ' ') || (c == 0) || (c == '\'')) | |||
return 0; | |||
index = 0; | |||
count = 0; | |||
for (;;) { | |||
index += utf8_in(&c, &word[index]); | |||
if ((c == 0) || (c == ' ')) | |||
break; | |||
if ((c == '\'') && ((count > 1) || (posn > 0))) | |||
break; // "tv'" but not "l'" | |||
if (count == 0) | |||
c1 = c; | |||
if ((c == '\'') && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 3)) { | |||
// don't count apostrophe | |||
} else | |||
count++; | |||
if (IsVowel(tr, c)) { | |||
vowel_posn = count; // position of the first vowel | |||
break; | |||
} | |||
if ((c != '\'') && !iswalpha(c)) | |||
return 0; | |||
} | |||
if ((vowel_posn > 2) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2)) { | |||
// Lookup unpronounable rules in *_rules | |||
return Unpronouncable2(tr, word); | |||
} | |||
if (c1 == tr->langopts.param[LOPT_UNPRONOUNCABLE]) | |||
vowel_posn--; // disregard this as the initial letter when counting | |||
if (vowel_posn > (tr->langopts.max_initial_consonants+1)) | |||
return 1; // no vowel, or no vowel in first few letters | |||
return 0; | |||
} | |||
static int Unpronouncable2(Translator *tr, char *word) | |||
{ | |||
int c; | |||
int end_flags; | |||
char ph_buf[N_WORD_PHONEMES]; | |||
ph_buf[0] = 0; | |||
c = word[-1]; | |||
word[-1] = ' '; // ensure there is a space before the "word" | |||
end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL); | |||
word[-1] = c; | |||
if ((end_flags == 0) || (end_flags & SUFX_UNPRON)) | |||
return 1; | |||
return 0; | |||
} |