/* | /* | ||||
* Copyright (C) 2005 to 2015 by Jonathan Duddington | * Copyright (C) 2005 to 2015 by Jonathan Duddington | ||||
* email: [email protected] | * email: [email protected] | ||||
* Copyright (C) 2015-2016 Reece H. Dunn | |||||
* Copyright (C) 2015-2016, 2020 Reece H. Dunn | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
if (((value % 100) > 10) && ((value % 100) < 20)) | if (((value % 100) > 10) && ((value % 100) < 20)) | ||||
teens = true; | teens = true; | ||||
switch ((translator->langopts.numbers2 >> 6) & 0x7) | |||||
switch (translator->langopts.numbers2 & NUM2_THOUSANDS_VAR_BITS) | |||||
{ | { | ||||
case 1: // lang=ru use singular for xx1 except for x11 | |||||
case NUM2_THOUSANDS_VAR1: // lang=ru use singular for xx1 except for x11 | |||||
if ((teens == false) && ((value % 10) == 1)) | if ((teens == false) && ((value % 10) == 1)) | ||||
return "1M"; | return "1M"; | ||||
break; | break; | ||||
case 2: // lang=cs,sk | |||||
case NUM2_THOUSANDS_VAR2: // lang=cs,sk | |||||
if ((value >= 2) && (value <= 4)) | if ((value >= 2) && (value <= 4)) | ||||
return "0MA"; | return "0MA"; | ||||
break; | break; | ||||
case 3: // lang=pl | |||||
case NUM2_THOUSANDS_VAR3: // lang=pl | |||||
if ((teens == false) && (((value % 10) >= 2) && ((value % 10) <= 4))) | if ((teens == false) && (((value % 10) >= 2) && ((value % 10) <= 4))) | ||||
return "0MA"; | return "0MA"; | ||||
break; | break; | ||||
case 4: // lang=lt | |||||
case NUM2_THOUSANDS_VAR4: // lang=lt | |||||
if ((teens == true) || ((value % 10) == 0)) | if ((teens == true) || ((value % 10) == 0)) | ||||
return "0MB"; | return "0MB"; | ||||
if ((value % 10) == 1) | if ((value % 10) == 1) | ||||
return "0MA"; | return "0MA"; | ||||
break; | break; | ||||
case 5: // lang=bs,hr,sr | |||||
case NUM2_THOUSANDS_VAR5: // lang=bs,hr,sr | |||||
if (teens == false) { | if (teens == false) { | ||||
if ((value % 10) == 1) | if ((value % 10) == 1) | ||||
return "1M"; | return "1M"; | ||||
LookupNum2(tr, hundreds/10, thousandplex, x, ph_digits); | LookupNum2(tr, hundreds/10, thousandplex, x, ph_digits); | ||||
} | } | ||||
if (tr->langopts.numbers2 & 0x200) | |||||
sprintf(ph_thousands, "%s%c%s%c", ph_10T, phonEND_WORD, ph_digits, phonEND_WORD); // say "thousands" before its number, not after | |||||
if (tr->langopts.numbers2 & NUM2_SWAP_THOUSANDS) | |||||
sprintf(ph_thousands, "%s%c%s%c", ph_10T, phonEND_WORD, ph_digits, phonEND_WORD); | |||||
else | else | ||||
sprintf(ph_thousands, "%s%c%s%c", ph_digits, phonEND_WORD, ph_10T, phonEND_WORD); | sprintf(ph_thousands, "%s%c%s%c", ph_digits, phonEND_WORD, ph_10T, phonEND_WORD); | ||||
} | } | ||||
LookupNum3(tr, value, ph_buf, suppress_null, thousandplex, prev_thousands | ordinal | decimal_point); | LookupNum3(tr, value, ph_buf, suppress_null, thousandplex, prev_thousands | ordinal | decimal_point); | ||||
if ((thousandplex > 0) && (tr->langopts.numbers2 & 0x200)) | |||||
sprintf(ph_out, "%s%s%c%s%s", ph_zeros, ph_append, phonEND_WORD, ph_buf2, ph_buf); // say "thousands" before its number | |||||
if ((thousandplex > 0) && (tr->langopts.numbers2 & NUM2_SWAP_THOUSANDS)) | |||||
sprintf(ph_out, "%s%s%c%s%s", ph_zeros, ph_append, phonEND_WORD, ph_buf2, ph_buf); | |||||
else | else | ||||
sprintf(ph_out, "%s%s%s%c%s", ph_zeros, ph_buf2, ph_buf, phonEND_WORD, ph_append); | sprintf(ph_out, "%s%s%s%c%s", ph_zeros, ph_buf2, ph_buf, phonEND_WORD, ph_append); | ||||
decimal_count++; | decimal_count++; | ||||
max_decimal_count = 2; | max_decimal_count = 2; | ||||
switch (decimal_mode = (tr->langopts.numbers & 0xe000)) | |||||
switch (decimal_mode = (tr->langopts.numbers & NUM_DFRACTION_BITS)) | |||||
{ | { | ||||
case NUM_DFRACTION_4: | case NUM_DFRACTION_4: | ||||
max_decimal_count = 5; | max_decimal_count = 5; |
/* | /* | ||||
* Copyright (C) 2005 to 2015 by Jonathan Duddington | * Copyright (C) 2005 to 2015 by Jonathan Duddington | ||||
* email: [email protected] | * email: [email protected] | ||||
* Copyright (C) 2015-2016 Reece H. Dunn | |||||
* Copyright (C) 2015-2016, 2020 Reece H. Dunn | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
tr->langopts.break_numbers = BREAK_LAKH_BN; | tr->langopts.break_numbers = BREAK_LAKH_BN; | ||||
if (name2 == L3('b', 'p', 'y')) { | if (name2 == L3('b', 'p', 'y')) { | ||||
tr->langopts.numbers = 1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
tr->langopts.numbers2 = NUM2_SWAP_THOUSANDS; | tr->langopts.numbers2 = NUM2_SWAP_THOUSANDS; | ||||
} | } | ||||
SetLetterBitsRange(tr, LETTERGP_B, 0x90, 0xbc); | SetLetterBitsRange(tr, LETTERGP_B, 0x90, 0xbc); | ||||
SetLetterBitsRange(tr, LETTERGP_C, 0x40, 0x6c); // consonant letters (not subjoined) | SetLetterBitsRange(tr, LETTERGP_C, 0x40, 0x6c); // consonant letters (not subjoined) | ||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words | tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words | ||||
tr->langopts.numbers = 1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
} | } | ||||
break; | break; | ||||
case L('c', 'y'): // Welsh | case L('c', 'y'): // Welsh | ||||
tr->langopts.stress_flags = S_MID_DIM | S_FINAL_DIM; // use 'diminished' for unstressed final syllable | tr->langopts.stress_flags = S_MID_DIM | S_FINAL_DIM; // use 'diminished' for unstressed final syllable | ||||
SetLetterBitsRange(tr, LETTERGP_B, 0x26, 0x30); // vowel signs, and virama | SetLetterBitsRange(tr, LETTERGP_B, 0x26, 0x30); // vowel signs, and virama | ||||
tr->langopts.break_numbers = BREAK_LAKH_DV; | tr->langopts.break_numbers = BREAK_LAKH_DV; | ||||
tr->langopts.numbers = 1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
} | } | ||||
break; | break; | ||||
case L('e', 'n'): | case L('e', 'n'): | ||||
tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels | tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels | ||||
tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA; | tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA; | ||||
tr->langopts.numbers2 = 0x2 | NUM2_MULTIPLE_ORDINAL | NUM2_ORDINAL_NO_AND; // variant form of numbers before thousands | |||||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_THOUSANDS | NUM2_MULTIPLE_ORDINAL | NUM2_ORDINAL_NO_AND; | |||||
if (name2 == L3('g', 'r', 'c')) { | if (name2 == L3('g', 'r', 'c')) { | ||||
// ancient greek | // ancient greek | ||||
tr->langopts.accents = 1; | tr->langopts.accents = 1; | ||||
tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_HUNDRED_AND | NUM_OMIT_1_HUNDRED | NUM_DECIMAL_COMMA | NUM_THOUS_SPACE | NUM_DFRACTION_2 | NUM_ROMAN_CAPITALS; | tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_HUNDRED_AND | NUM_OMIT_1_HUNDRED | NUM_DECIMAL_COMMA | NUM_THOUS_SPACE | NUM_DFRACTION_2 | NUM_ROMAN_CAPITALS; | ||||
tr->langopts.numbers2 = 0xa + NUM2_THOUSANDS_VAR5; // variant numbers before thousands,milliards | |||||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_THOUSANDS | NUM2_THOUSANDPLEX_VAR_MILLIARDS | NUM2_THOUSANDS_VAR5; | |||||
tr->langopts.our_alphabet = OFFSET_CYRILLIC; // don't say "cyrillic" before letter names | tr->langopts.our_alphabet = OFFSET_CYRILLIC; // don't say "cyrillic" before letter names | ||||
SetLetterVowel(tr, 'y'); | SetLetterVowel(tr, 'y'); | ||||
tr->letter_groups[1] = is_lettergroup_B; | tr->letter_groups[1] = is_lettergroup_B; | ||||
SetLetterVowel(tr, 'y'); | SetLetterVowel(tr, 'y'); | ||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SINGLE_AND | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_1900; | tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SINGLE_AND | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_1900; | ||||
tr->langopts.numbers2 = 0x2; | |||||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_THOUSANDS; | |||||
} | } | ||||
break; | break; | ||||
case L('i', 't'): // Italian | case L('i', 't'): // Italian | ||||
} | } | ||||
break; | break; | ||||
case L('k', 'y'): // Kyrgyx | case L('k', 'y'): // Kyrgyx | ||||
tr->langopts.numbers = 1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
break; | break; | ||||
case L('l', 'a'): // Latin | case L('l', 'a'): // Latin | ||||
{ | { | ||||
tr->langopts.stress_rule = STRESSPOSN_3R; // antipenultimate | tr->langopts.stress_rule = STRESSPOSN_3R; // antipenultimate | ||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_DFRACTION_2; | tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_DFRACTION_2; | ||||
tr->langopts.numbers2 = 0x8a; // variant numbers before thousands,milliards | |||||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_THOUSANDS | NUM2_THOUSANDPLEX_VAR_MILLIARDS | NUM2_THOUSANDS_VAR2; | |||||
} | } | ||||
break; | break; | ||||
case L('m', 't'): // Maltese | case L('m', 't'): // Maltese | ||||
tr->encoding = ESPEAKNG_ENCODING_ISO_8859_3; | tr->encoding = ESPEAKNG_ENCODING_ISO_8859_3; | ||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x100; // devoice at end of word | tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x100; // devoice at end of word | ||||
tr->langopts.stress_rule = STRESSPOSN_2R; // penultimate | tr->langopts.stress_rule = STRESSPOSN_2R; // penultimate | ||||
tr->langopts.numbers = 1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
} | } | ||||
break; | break; | ||||
case L('n', 'l'): // Dutch | case L('n', 'l'): // Dutch | ||||
tr->langopts.stress_rule = STRESSPOSN_2R; | tr->langopts.stress_rule = STRESSPOSN_2R; | ||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | 0x80000; | tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | 0x80000; | ||||
tr->langopts.numbers = NUM_OMIT_1_HUNDRED | NUM_HUNDRED_AND; | tr->langopts.numbers = NUM_OMIT_1_HUNDRED | NUM_HUNDRED_AND; | ||||
tr->langopts.numbers2 = 0x200; // say "thousands" before its number | |||||
tr->langopts.numbers2 = NUM2_SWAP_THOUSANDS; | |||||
} | } | ||||
break; | break; | ||||
case L('p', 'l'): // Polish | case L('p', 'l'): // Polish | ||||
tr->encoding = ESPEAKNG_ENCODING_ISO_8859_2; | tr->encoding = ESPEAKNG_ENCODING_ISO_8859_2; | ||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_3 | NUM_AND_UNITS | NUM_ROMAN; | tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_3 | NUM_AND_UNITS | NUM_ROMAN; | ||||
tr->langopts.numbers2 = 0x1e; // variant numbers before all thousandplex | |||||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_ALL; | |||||
} | } | ||||
break; | break; | ||||
case L('r', 'u'): // Russian | case L('r', 'u'): // Russian | ||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable | tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable | ||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words. Need to allow "bw'" prefix | tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words. Need to allow "bw'" prefix | ||||
tr->langopts.numbers = NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_DFRACTION_2 | NUM_AND_HUNDRED; | tr->langopts.numbers = NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_DFRACTION_2 | NUM_AND_HUNDRED; | ||||
tr->langopts.numbers2 = 0x200; // say "thousands" before its number | |||||
tr->langopts.numbers2 = NUM2_SWAP_THOUSANDS; | |||||
} | } | ||||
break; | break; | ||||
case L('s', 'k'): // Slovak | case L('s', 'k'): // Slovak | ||||
tr->langopts.decimal_sep = ','; | tr->langopts.decimal_sep = ','; | ||||
if (name2 == L('c', 's')) | if (name2 == L('c', 's')) | ||||
tr->langopts.numbers2 = 0x108; // variant numbers before milliards | |||||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_MILLIARDS | NUM2_THOUSANDS_VAR4; | |||||
SetLetterVowel(tr, 'y'); | SetLetterVowel(tr, 'y'); | ||||
SetLetterVowel(tr, 'r'); | SetLetterVowel(tr, 'r'); | ||||
tr->langopts.param[LOPT_IT_LENGTHEN] = 1; // remove lengthen indicator from unstressed syllables | tr->langopts.param[LOPT_IT_LENGTHEN] = 1; // remove lengthen indicator from unstressed syllables | ||||
tr->letter_bits[(int)'r'] |= 0x80; // add 'r' to letter group 7, vowels for Unpronouncable test | tr->letter_bits[(int)'r'] |= 0x80; // add 'r' to letter group 7, vowels for Unpronouncable test | ||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | NUM_DFRACTION_2 | NUM_ORDINAL_DOT | NUM_ROMAN; | tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | NUM_DFRACTION_2 | NUM_ORDINAL_DOT | NUM_ROMAN; | ||||
tr->langopts.numbers2 = 0x100; // plural forms of millions etc | |||||
tr->langopts.numbers2 = NUM2_THOUSANDS_VAR4; | |||||
tr->langopts.thousands_sep = ' '; // don't allow dot as thousands separator | tr->langopts.thousands_sep = ' '; // don't allow dot as thousands separator | ||||
break; | break; | ||||
case L('s', 'q'): // Albanian | case L('s', 'q'): // Albanian | ||||
tr->langopts.stress_rule = 13; // 1st syllable, unless 1st vowel is short and 2nd is long | tr->langopts.stress_rule = 13; // 1st syllable, unless 1st vowel is short and 2nd is long | ||||
} else if (name2 == L('k', 'n')) { | } else if (name2 == L('k', 'n')) { | ||||
tr->letter_bits_offset = OFFSET_KANNADA; | tr->letter_bits_offset = OFFSET_KANNADA; | ||||
tr->langopts.numbers = 0x1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
} else if (name2 == L('t', 'e')) { | } else if (name2 == L('t', 'e')) { | ||||
tr->letter_bits_offset = OFFSET_TELUGU; | tr->letter_bits_offset = OFFSET_TELUGU; | ||||
tr->langopts.numbers = 0x1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
tr->langopts.numbers2 = NUM2_ORDINAL_DROP_VOWEL; | tr->langopts.numbers2 = NUM2_ORDINAL_DROP_VOWEL; | ||||
} | } | ||||
SetIndicLetters(tr); // call this after setting OFFSET_ | SetIndicLetters(tr); // call this after setting OFFSET_ | ||||
case L3('s', 'h', 'n'): | case L3('s', 'h', 'n'): | ||||
tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches() | tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches() | ||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable | tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable | ||||
tr->langopts.numbers = 1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
tr->langopts.break_numbers = BREAK_INDIVIDUAL; | tr->langopts.break_numbers = BREAK_INDIVIDUAL; | ||||
break; | break; | ||||
case L3('c', 'm', 'n'): // no break, just go to 'zh' case | case L3('c', 'm', 'n'): // no break, just go to 'zh' case | ||||
if (name2 == L3('z', 'h', 'y')) { | if (name2 == L3('z', 'h', 'y')) { | ||||
tr->langopts.textmode = true; | tr->langopts.textmode = true; | ||||
tr->langopts.listx = 1; // compile zh_listx after zh_list | tr->langopts.listx = 1; // compile zh_listx after zh_list | ||||
tr->langopts.numbers = 1; | |||||
tr->langopts.numbers = NUM_DEFAULT; | |||||
tr->langopts.numbers2 = NUM2_ZERO_TENS; | tr->langopts.numbers2 = NUM2_ZERO_TENS; | ||||
tr->langopts.break_numbers = BREAK_INDIVIDUAL; | tr->langopts.break_numbers = BREAK_INDIVIDUAL; | ||||
} | } | ||||
tr->langopts.stress_flags = S_NO_AUTO_2; | tr->langopts.stress_flags = S_NO_AUTO_2; | ||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED; | tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED; | ||||
tr->langopts.numbers2 = 0x2 + NUM2_THOUSANDS_VAR1; // variant numbers before thousands | |||||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_THOUSANDS | NUM2_THOUSANDS_VAR1; // variant numbers before thousands | |||||
} | } |
} | } | ||||
// append plural suffixes depending on preceding letter | // append plural suffixes depending on preceding letter | ||||
void addPluralSuffixes(int flags, Translator *tr, char last_char, char *word_phonemes) | |||||
static void addPluralSuffixes(int flags, Translator *tr, char last_char, char *word_phonemes) | |||||
{ | { | ||||
char word_zz[4] = { 0, 'z', 'z', 0 }; | char word_zz[4] = { 0, 'z', 'z', 0 }; | ||||
char word_iz[4] = { 0, 'i', 'z', 0 }; | char word_iz[4] = { 0, 'i', 'z', 0 }; | ||||
if (wflags & FLAG_TRANSLATOR2) | if (wflags & FLAG_TRANSLATOR2) | ||||
return 0; | return 0; | ||||
addPluralSuffixes(wflags, tr, last_char, &word_phonemes); | |||||
addPluralSuffixes(wflags, tr, last_char, word_phonemes); | |||||
return dictionary_flags[0] & FLAG_SKIPWORDS; // for "b.c.d" | return dictionary_flags[0] & FLAG_SKIPWORDS; // for "b.c.d" | ||||
} else if (found == false) { | } else if (found == false) { | ||||
// word's pronunciation is not given in the dictionary list, although | // word's pronunciation is not given in the dictionary list, although | ||||
} | } | ||||
} | } | ||||
addPluralSuffixes(wflags, tr, last_char, &word_phonemes); | |||||
addPluralSuffixes(wflags, tr, last_char, word_phonemes); | |||||
wflags |= emphasize_allcaps; | wflags |= emphasize_allcaps; | ||||
// determine stress pattern for this word | // determine stress pattern for this word |
/* | /* | ||||
* Copyright (C) 2005 to 2014 by Jonathan Duddington | * Copyright (C) 2005 to 2014 by Jonathan Duddington | ||||
* email: [email protected] | * email: [email protected] | ||||
* Copyright (C) 2015-2017 Reece H. Dunn | |||||
* Copyright (C) 2015-2017, 2020 Reece H. Dunn | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
unsigned char *length_mods; | unsigned char *length_mods; | ||||
unsigned char *length_mods0; | unsigned char *length_mods0; | ||||
#define NUM_THOUS_SPACE 0x4 | |||||
#define NUM_DECIMAL_COMMA 0x8 | |||||
#define NUM_SWAP_TENS 0x10 | |||||
#define NUM_AND_UNITS 0x20 | |||||
#define NUM_HUNDRED_AND 0x40 | |||||
#define NUM_SINGLE_AND 0x80 | |||||
#define NUM_SINGLE_STRESS 0x100 | |||||
#define NUM_SINGLE_VOWEL 0x200 | |||||
#define NUM_OMIT_1_HUNDRED 0x400 | |||||
#define NUM_1900 0x800 | |||||
#define NUM_ALLOW_SPACE 0x1000 | |||||
#define NUM_DFRACTION_1 0x2000 | |||||
#define NUM_DFRACTION_2 0x4000 | |||||
#define NUM_DFRACTION_3 0x6000 | |||||
#define NUM_DFRACTION_4 0x8000 | |||||
#define NUM_DFRACTION_5 0xa000 | |||||
#define NUM_DFRACTION_6 0xc000 | |||||
#define NUM_DFRACTION_7 0xe000 // lang=si, alternative form of number for decimal fraction digits (except the last) | |||||
#define NUM_ORDINAL_DOT 0x10000 | |||||
#define NUM_NOPAUSE 0x20000 | |||||
#define NUM_AND_HUNDRED 0x40000 | |||||
#define NUM_THOUSAND_AND 0x80000 | |||||
#define NUM_VIGESIMAL 0x100000 | |||||
#define NUM_OMIT_1_THOUSAND 0x200000 | |||||
#define NUM_ZERO_HUNDRED 0x400000 | |||||
#define NUM_HUNDRED_AND_DIGIT 0x800000 | |||||
#define NUM_ROMAN 0x1000000 | |||||
#define NUM_ROMAN_CAPITALS 0x2000000 | |||||
#define NUM_ROMAN_AFTER 0x4000000 | |||||
#define NUM_ROMAN_ORDINAL 0x8000000 | |||||
#define NUM_SINGLE_STRESS_L 0x10000000 | |||||
// bits0-1=which numbers routine to use. | |||||
// bit2= thousands separator must be space | |||||
// bit3= , decimal separator, not . | |||||
// bit4=use three-and-twenty rather than twenty-three | |||||
// bit5='and' between tens and units | |||||
// bit6=add "and" after hundred or thousand | |||||
// bit7=don't have "and" both after hundreds and also between tens and units | |||||
// bit8=only one primary stress in tens+units | |||||
// bit9=only one vowel betwen tens and units | |||||
// bit10=omit "one" before "hundred" | |||||
// bit11=say 19** as nineteen hundred | |||||
// bit12=allow space as thousands separator (in addition to langopts.thousands_sep) | |||||
// bits13-15 post-decimal-digits 0=single digits, 1=(LANG=it) 2=(LANG=pl) 3=(LANG=ro) | |||||
// bit16= dot after number indicates ordinal | |||||
// bit17= don't add pause after a number | |||||
// bit18= 'and' before hundreds | |||||
// bit19= 'and' after thousands if there are no hundreds | |||||
// bit20= vigesimal number, if tens are not found | |||||
// bit21= omit "one" before "thousand" | |||||
// bit22= say "zero" before hundred | |||||
// bit23= add "and" after hundreds and thousands, only if there are digits and no tens | |||||
// bit24= recognize roman numbers | |||||
// bit25= Roman numbers only if upper case | |||||
// bit26= say "roman" after the number, not before | |||||
// bit27= Roman numbers are ordinal numbers | |||||
// bit28= only one primary stress in tens+units (on the tens) | |||||
#define NUM_DEFAULT 0x00000001 // enable number processing; use if no other NUM_ option is specified | |||||
#define NUM_THOUS_SPACE 0x00000004 // thousands separator must be space | |||||
#define NUM_DECIMAL_COMMA 0x00000008 // , decimal separator, not . | |||||
#define NUM_SWAP_TENS 0x00000010 // use three-and-twenty rather than twenty-three | |||||
#define NUM_AND_UNITS 0x00000020 // 'and' between tens and units | |||||
#define NUM_HUNDRED_AND 0x00000040 // add "and" after hundred or thousand | |||||
#define NUM_SINGLE_AND 0x00000080 // don't have "and" both after hundreds and also between tens and units | |||||
#define NUM_SINGLE_STRESS 0x00000100 // only one primary stress in tens+units | |||||
#define NUM_SINGLE_VOWEL 0x00000200 // only one vowel betwen tens and units | |||||
#define NUM_OMIT_1_HUNDRED 0x00000400 // omit "one" before "hundred" | |||||
#define NUM_1900 0x00000800 // say 19** as nineteen hundred | |||||
#define NUM_ALLOW_SPACE 0x00001000 // allow space as thousands separator (in addition to langopts.thousands_sep) | |||||
#define NUM_DFRACTION_BITS 0x0000e000 // post-decimal-digits 0=single digits, 1=(LANG=it) 2=(LANG=pl) 3=(LANG=ro) | |||||
#define NUM_ORDINAL_DOT 0x00010000 // dot after number indicates ordinal | |||||
#define NUM_NOPAUSE 0x00020000 // don't add pause after a number | |||||
#define NUM_AND_HUNDRED 0x00040000 // 'and' before hundreds | |||||
#define NUM_THOUSAND_AND 0x00080000 // 'and' after thousands if there are no hundreds | |||||
#define NUM_VIGESIMAL 0x00100000 // vigesimal number, if tens are not found | |||||
#define NUM_OMIT_1_THOUSAND 0x00200000 // omit "one" before "thousand" | |||||
#define NUM_ZERO_HUNDRED 0x00400000 // say "zero" before hundred | |||||
#define NUM_HUNDRED_AND_DIGIT 0x00800000 // add "and" after hundreds and thousands, only if there are digits and no tens | |||||
#define NUM_ROMAN 0x01000000 // recognize roman numbers | |||||
#define NUM_ROMAN_CAPITALS 0x02000000 // Roman numbers only if upper case | |||||
#define NUM_ROMAN_AFTER 0x04000000 // say "roman" after the number, not before | |||||
#define NUM_ROMAN_ORDINAL 0x08000000 // Roman numbers are ordinal numbers | |||||
#define NUM_SINGLE_STRESS_L 0x10000000 // only one primary stress in tens+units (on the tens) | |||||
#define NUM_DFRACTION_1 0x00002000 | |||||
#define NUM_DFRACTION_2 0x00004000 | |||||
#define NUM_DFRACTION_3 0x00006000 | |||||
#define NUM_DFRACTION_4 0x00008000 | |||||
#define NUM_DFRACTION_5 0x0000a000 | |||||
#define NUM_DFRACTION_6 0x0000c000 | |||||
#define NUM_DFRACTION_7 0x0000e000 // lang=si, alternative form of number for decimal fraction digits (except the last) | |||||
int numbers; | int numbers; | ||||
#define NUM2_THOUSANDS_VAR1 0x40 | |||||
#define NUM2_THOUSANDS_VAR2 0x80 | |||||
#define NUM2_THOUSANDS_VAR3 0xc0 | |||||
#define NUM2_THOUSANDS_VAR4 0x100 | |||||
#define NUM2_THOUSANDS_VAR5 0x140 | |||||
#define NUM2_SWAP_THOUSANDS 0x200 | |||||
#define NUM2_ORDINAL_NO_AND 0x800 | |||||
#define NUM2_MULTIPLE_ORDINAL 0x1000 | |||||
#define NUM2_NO_TEEN_ORDINALS 0x2000 | |||||
#define NUM2_MYRIADS 0x4000 | |||||
#define NUM2_ENGLISH_NUMERALS 0x8000 | |||||
#define NUM2_PERCENT_BEFORE 0x10000 | |||||
#define NUM2_OMIT_1_HUNDRED_ONLY 0x20000 | |||||
#define NUM2_ORDINAL_AND_THOUSANDS 0x40000 | |||||
#define NUM2_ORDINAL_DROP_VOWEL 0x80000 // currently only for tens and units | |||||
#define NUM2_ZERO_TENS 0x100000 | |||||
// bits 1-4 use variant form of numbers before thousands,millions,etc. | |||||
// bits 6-8 use different forms of thousand, million, etc (M MA MB) | |||||
// bit9=(LANG=rw) say "thousand" and "million" before its number, not after | |||||
// bit11=(LANG=es,an) don't say 'and' between tens and units for ordinal numbers | |||||
// bit12=(LANG=el,es) use ordinal form of hundreds and tens as well as units | |||||
// bit13=(LANG=pt) don't use 11-19 numbers to make ordinals | |||||
// bit14=(LANG=ko) use myriads (groups of 4 digits) not thousands (groups of 3) | |||||
// bit15=(LANG=ne) speak (non-replaced) English numerals in English | |||||
// bit16=(LANG=si) say "%" before the number | |||||
// bit17=(LANG=ml) omit "one" before hundred only if there are no previous digits | |||||
// bit18=(LANG=ta) same variant for ordinals and thousands (#o = #a) | |||||
// bit19=(LANG=te) drop final vowel from cardial number before adding ordinal suffix | |||||
// bit20=(LANG=zh) say zero tens | |||||
#define NUM2_THOUSANDPLEX_VAR_BITS 0x0000001e // use variant form of numbers before thousands, millions, etc. | |||||
#define NUM2_THOUSANDS_VAR_BITS 0x000001c0 // use different forms of thousand, million, etc (M MA MB) | |||||
#define NUM2_SWAP_THOUSANDS 0x00000200 // say "thousand" and "million" before its number, not after | |||||
#define NUM2_ORDINAL_NO_AND 0x00000800 // don't say 'and' between tens and units for ordinal numbers | |||||
#define NUM2_MULTIPLE_ORDINAL 0x00001000 // use ordinal form of hundreds and tens as well as units | |||||
#define NUM2_NO_TEEN_ORDINALS 0x00002000 // don't use 11-19 numbers to make ordinals | |||||
#define NUM2_MYRIADS 0x00004000 // use myriads (groups of 4 digits) not thousands (groups of 3) | |||||
#define NUM2_ENGLISH_NUMERALS 0x00008000 // speak (non-replaced) English numerals in English | |||||
#define NUM2_PERCENT_BEFORE 0x00010000 // say "%" before the number | |||||
#define NUM2_OMIT_1_HUNDRED_ONLY 0x00020000 // omit "one" before hundred only if there are no previous digits | |||||
#define NUM2_ORDINAL_AND_THOUSANDS 0x00040000 // same variant for ordinals and thousands (#o = #a) | |||||
#define NUM2_ORDINAL_DROP_VOWEL 0x00080000 // drop final vowel from cardial number before adding ordinal suffix (currently only tens and units) | |||||
#define NUM2_ZERO_TENS 0x00100000 // say zero tens | |||||
#define NUM2_THOUSANDPLEX_VAR_THOUSANDS 0x00000002 | |||||
#define NUM2_THOUSANDPLEX_VAR_MILLIARDS 0x00000008 | |||||
#define NUM2_THOUSANDPLEX_VAR_ALL 0x0000001e | |||||
#define NUM2_THOUSANDS_VAR1 0x00000040 | |||||
#define NUM2_THOUSANDS_VAR2 0x00000080 | |||||
#define NUM2_THOUSANDS_VAR3 0x000000c0 | |||||
#define NUM2_THOUSANDS_VAR4 0x00000100 // plural forms for millions, etc. | |||||
#define NUM2_THOUSANDS_VAR5 0x00000140 | |||||
int numbers2; | int numbers2; | ||||
// Bit 2^n is set if 10^n separates a number grouping (max n=31). | // Bit 2^n is set if 10^n separates a number grouping (max n=31). |