#include "quiz.h" #include "trans.h" static char *z; extern char *translate_syllable (); extern char calc_tone (); char * translate ( input ) char *input; { static char buf[ MAX_STRING ]; char *oldz; char *bp; char *extra; z = input; bp = buf; *bp = '\0'; while ( *z != '\0' ) { oldz = z; extra = translate_syllable (); if ( extra != NULL ) { strcat ( buf , extra ); strcat ( buf , " " ); } if ( z == oldz ) break; /* algorithm failed - give up */ } return ( buf ); } /* * Does not yet handle: * * TAH! NAI (TAW_TAH_HAHN NAW_NOO AH YAW_YAHK) * also final consonant seems to be optional * */ static char * translate_syllable () { static char buf[ 10 ]; char *initial = NULL; char *vowel = NULL; char *final = NULL; char tone = 'c'; char initial_char = '\0'; char final_char = '\0'; char tone_mark = '\0'; if ( *z == TC_EH ) { z++; if ( *z == TC_EH ) { z++; initial_consonant ( &initial , &initial_char , &tone_mark ); if ( *z == TC_SHORT_AH ) { vowel = "AA!"; z++; } else { vowel = "AA"; final_consonant ( &final , &final_char ); } } else { initial_consonant ( &initial , &initial_char , &tone_mark ); switch ( *z ) { case TC_AW : z++; if ( *z == TC_SHORT_AH ) { z++; vowel = "UH!"; } else vowel = "UH"; break; case TC_SHORT_AH : z++; vowel = "EH!"; break; case TC_LONG_AH : z++; if ( *z == TC_SHORT_AH ) { z++; vowel = "AW!"; } else { vowel = "AO!"; final_consonant ( &final , &final_char ); } break; case TC_IH : z++; vowel = "UH"; final_consonant ( &final , &final_char ); break; case TC_EE : if ( *(z+1) == TC_YAW_YAHK ) { z += 2; if ( *z == TC_SHORT_AH ) { z++; vowel = "IA!"; } else { vowel = "IA"; final_consonant ( &final , &final_char ); } } else vowel = NULL; /* error really */ break; case TC_LONG_EU : if ( *(z+1) == TC_AW ) { z += 2; if ( *z == TC_SHORT_AH ) { z++; vowel = "EUA!"; } else { vowel = "EUA"; final_consonant ( &final , &final_char ); } } else vowel = NULL; /* error really */ break; default : vowel = "EH"; final_consonant ( &final , &final_char ); break; } } } else if ( *z == TC_OH ) { z++; initial_consonant ( &initial , &initial_char , &tone_mark ); if ( *z == TC_SHORT_AH ) { z++; vowel = "OH!"; } else { vowel = "OH"; final_consonant ( &final , &final_char ); } } else if ( *z == TC_AI20 || *z == TC_AI ) { z++; initial_consonant ( &initial , &initial_char , &tone_mark ); vowel = "AI!"; final_consonant ( &final , &final_char ); } else { initial_consonant ( &initial , &initial_char , &tone_mark ); if ( *z == TC_WAW && isconsonant( *(z+1) ) ) { z++; vowel = "UA"; final_consonant ( &final , &final_char ); } else if ( *z == TC_RAW_REUA && *(z+1) == TC_RAW_REUA ) { vowel = "AH!"; final_consonant ( &final , &final_char ); } else { switch ( *z ) { case TC_SHORT_AH : z++; vowel = "AH!"; break; case TC_SHORT_AH_ABOVE : z++; if ( *z == TC_WAW ) { z++; vowel = "UA!"; } else { vowel = "AH!"; final_consonant ( &final , &final_char ); } break; case TC_LONG_AH : z++; if ( *z == TC_WAW ) { z++; vowel = "AO"; } else if ( *z == TC_YAW_YAHK ) { z++; vowel = "AI"; } else { vowel = "AH"; final_consonant ( &final , &final_char ); } break; case TC_AHM : z++; vowel = "AH!M"; break; case TC_IH : z++; vowel = "IH!"; final_consonant ( &final , &final_char ); break; case TC_EE : z++; vowel = "EE"; final_consonant ( &final , &final_char ); break; case TC_SHORT_EU : z++; vowel = "EU!"; final_consonant ( &final , &final_char ); break; case TC_LONG_EU : z++; vowel = "EU"; final_consonant ( &final , &final_char ); break; case TC_SHORT_OO : z++; vowel = "OO!"; final_consonant ( &final , &final_char ); break; case TC_LONG_OO : z++; vowel = "OO"; final_consonant ( &final , &final_char ); break; case TC_AW : z++; vowel = "AW"; final_consonant ( &final , &final_char ); break; default : if ( isconsonant(*z) && ! isaftervowel( *(z+1) ) ) { vowel = "OH!"; final_consonant ( &final , &final_char ); } else { vowel = "AH!"; } break; } } } tone = calc_tone ( initial , initial_char , tone_mark , vowel , final , final_char ); strcpy ( buf , "(x)" ); buf[1] = tone; if ( initial != NULL ) strcat ( buf , initial ); if ( vowel != NULL ) strcat ( buf , vowel ); if ( final != NULL ) strcat ( buf , final ); return ( buf ); } static initial_consonant ( phoneme , c , tone_mark ) char **phoneme; char *c; char *tone_mark; { char dummy; *phoneme = NULL; *c = *z; switch ( *z++ ) { case TC_GAW : if ( *z == TC_LAW_LEENG ) { z++; *phoneme = "GL"; } else if ( *z == TC_RAW_REUA ) { z++; *phoneme = "GR"; } else *phoneme = "G"; break; case TC_KAW_KAI : case TC_KAW_KUAT : case TC_KAW_KWAI : case TC_KAW_KOHN : case TC_KAW_RAH_KAHNG : if ( *z == TC_LAW_LEENG ) { z++; *phoneme = "KL"; } else if ( *z == TC_RAW_REUA ) { z++; *phoneme = "KR"; } else *phoneme = "K"; break; case TC_NGAW : *phoneme = "NG"; break; case TC_JAW : *phoneme = "J"; break; case TC_CHAW : case TC_CHAW_CHANG : case TC_CHAW_CHUH : *phoneme = "CH"; break; case TC_SAW : case TC_SAW_SAH_LAH : case TC_SAW_REU_SEE : case TC_SAW_SEUA : *phoneme = "S"; break; case TC_YAW_YEENG : case TC_YAW_YAHK : *phoneme = "Y"; break; case TC_DAW_CHAH_DAH : case TC_DAW_DEHK : *phoneme = "D"; break; case TC_DTAW_BPAH_DTAHK : case TC_DTAW_DTAO : *phoneme = "DT"; break; case TC_TAW_TAHN : case TC_TAW_MOHN_TOH : case TC_TAW_POO_TAO : case TC_TAW_TOONG : case TC_TAW_TAH_HAHN : case TC_TAW_TOHNG : *phoneme = "T"; break; case TC_NAW_NEHN : case TC_NAW_NOO : *phoneme = "N"; break; case TC_BAW : *phoneme = "B"; break; case TC_BPAW : *phoneme = "BP"; break; case TC_PAW : case TC_PAW_PAHN : case TC_PAW_SAHM_PAO : *phoneme = "P"; break; case TC_FAW_HIGH : case TC_FAW : *phoneme = "F"; break; case TC_MAW : *phoneme = "M"; break; case TC_RAW_REUA : *phoneme = "R"; break; case TC_LAW_LEENG : case TC_LAW_JOOH_LAH : *phoneme = "L"; break; case TC_WAW : *phoneme = "W"; break; case TC_AW : *phoneme = "AW"; break; case TC_HAW : if ( isconsonant ( *z ) && ! isaftervowel ( *(z+1) ) ) initial_consonant ( phoneme , &dummy , tone_mark ); else *phoneme = "H"; break; case TC_HAH : *phoneme = "H"; break; } switch ( *z ) { case TC_MAI_EHK : case TC_MAI_TOH : case TC_MAI_DTREE : case TC_MAI_JATTAWA : *tone_mark = *z++; break; default : *tone_mark = '\0'; } } static final_consonant ( phoneme , c , tone_mark ) char **phoneme; char *c; char *tone_mark; { /* check if user put tone mark in wrong spot */ switch ( *z ) { case TC_MAI_EHK : case TC_MAI_TOH : case TC_MAI_DTREE : case TC_MAI_JATTAWA : *tone_mark = *z++; break; default : break; /* dont overide the old value then */ } *c = *z; if ( isconsonant( z[0] ) && ! isaftervowel( z[1] ) ) { switch ( *z++ ) { case TC_GAW : case TC_KAW_KAI : case TC_KAW_KUAT : case TC_KAW_KWAI : case TC_KAW_KOHN : case TC_KAW_RAH_KAHNG : *phoneme = "K"; break; case TC_NGAW : *phoneme = "NG"; break; case TC_JAW : case TC_CHAW : case TC_CHAW_CHANG : case TC_SAW : case TC_CHAW_CHUH : case TC_DAW_CHAH_DAH : case TC_DTAW_BPAH_DTAHK : case TC_TAW_TAHN : case TC_TAW_MOHN_TOH : case TC_TAW_POO_TAO : case TC_DAW_DEHK : case TC_DTAW_DTAO : case TC_TAW_TOONG : case TC_TAW_TAH_HAHN : case TC_TAW_TOHNG : case TC_SAW_SAH_LAH : case TC_SAW_REU_SEE : case TC_SAW_SEUA : *phoneme = "T"; break; case TC_NAW_NEHN : case TC_YAW_YEENG : case TC_NAW_NOO : case TC_RAW_REUA : case TC_LAW_LEENG : case TC_LAW_JOOH_LAH : *phoneme = "N"; break; case TC_BAW : case TC_BPAW : case TC_PAW : case TC_PAW_PAHN : case TC_PAW_SAHM_PAO : *phoneme = "P"; break; case TC_FAW : *phoneme = "F"; break; case TC_MAW : *phoneme = "M"; break; case TC_YAW_YAHK : case TC_WAW : *phoneme = NULL; break; case TC_FAW_HIGH : case TC_HAW : case TC_HAH : case TC_AW : *phoneme = ""; /* silent */ break; default : *phoneme = NULL; break; } } else *phoneme = NULL; } static char calc_tone ( initial , initial_char , tone_mark , vowel , final , final_char ) char *initial; char initial_char; char tone_mark; char *vowel; char *final; char final_char; { char tone; int long_vowel; tone = 'c'; if ( initial == NULL || initial[0] == '\0' ) return ( tone ); if ( vowel == NULL || vowel[0] == '\0' ) return ( tone ); long_vowel = ( vowel[ strlen ( vowel ) - 1 ] != '!' ); if ( tone_mark == TC_MAI_DTREE ) tone = 'r'; else if ( ishigh( initial_char ) ) { if ( tone_mark == TC_MAI_TOH ) { tone = 'f'; } else if ( final == NULL || final[0] == '\0' ) { if ( long_vowel ) { if ( tone_mark == '\0' ) { tone = 'r'; } else if ( tone_mark == TC_MAI_EHK ) { tone = 'l'; } } else { if ( tone_mark == '\0' ) { tone = 'l'; } } } else { switch ( final[0] ) { case 'A' : if ( final[1] != 'I' || final[1] == 'O' ) tone = 'r'; break; case 'M' : case 'N' : case 'W' : case 'Y' : tone = 'r'; break; case 'K' : case 'P' : case 'T' : tone = 'l'; break; } } } else if ( ismiddle( initial_char ) ) { if ( tone_mark == TC_MAI_EHK ) { tone = 'l'; } else if ( tone_mark == TC_MAI_TOH ) { tone = 'f'; } else { if ( final == NULL || final[0] == '\0' ) { if ( long_vowel ) { if ( tone_mark == '\0' ) { tone = 'c'; } else { } } else { if ( tone_mark == '\0' ) { tone = 'l'; } else { } } } else { switch ( final[0] ) { case 'A' : if ( final[1] == 'O' || final[1] == 'I' ) { if ( islow( final_char ) ) { tone = 'c'; } } break; case 'M' : case 'N' : case 'W' : case 'Y' : if ( islow( final_char ) ) { tone = 'c'; } break; case 'K' : case 'P' : case 'T' : tone = 'l'; break; } } } } else if ( islow( initial_char ) ) { if ( tone_mark == TC_MAI_EHK ) { tone = 'f'; } else if ( tone_mark == TC_MAI_TOH ) { tone = 'h'; } else if ( tone_mark == '\0' ) { if ( long_vowel ) { if ( final == NULL || final[0] == '\0' ) { tone = 'c'; } else { switch ( final[0] ) { case 'K' : case 'P' : case 'T' : tone = 'f'; break; } } } else { if ( final == NULL || final[0] == '\0' ) { tone = 'h'; } else { switch ( final[0] ) { case 'K' : case 'P' : case 'T' : tone = 'h'; break; case 'A' : if ( final[1] == 'O' || final[1] == 'I' ) { if ( islow( final_char ) ) { tone = 'c'; } } break; case 'M' : case 'N' : case 'W' : case 'Y' : if ( islow( final_char ) ) { tone = 'c'; } break; } } } } } return ( tone ); }