@@ -1,7 +1,7 @@ | |||
/* | |||
* Copyright (C) 2005 to 2015 by Jonathan Duddington | |||
* 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 | |||
* it under the terms of the GNU General Public License as published by | |||
@@ -1149,27 +1149,27 @@ static const char *M_Variant(int value) | |||
if (((value % 100) > 10) && ((value % 100) < 20)) | |||
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)) | |||
return "1M"; | |||
break; | |||
case 2: // lang=cs,sk | |||
case NUM2_THOUSANDS_VAR2: // lang=cs,sk | |||
if ((value >= 2) && (value <= 4)) | |||
return "0MA"; | |||
break; | |||
case 3: // lang=pl | |||
case NUM2_THOUSANDS_VAR3: // lang=pl | |||
if ((teens == false) && (((value % 10) >= 2) && ((value % 10) <= 4))) | |||
return "0MA"; | |||
break; | |||
case 4: // lang=lt | |||
case NUM2_THOUSANDS_VAR4: // lang=lt | |||
if ((teens == true) || ((value % 10) == 0)) | |||
return "0MB"; | |||
if ((value % 10) == 1) | |||
return "0MA"; | |||
break; | |||
case 5: // lang=bs,hr,sr | |||
case NUM2_THOUSANDS_VAR5: // lang=bs,hr,sr | |||
if (teens == false) { | |||
if ((value % 10) == 1) | |||
return "1M"; | |||
@@ -1590,8 +1590,8 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, bool suppress_nul | |||
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 | |||
sprintf(ph_thousands, "%s%c%s%c", ph_digits, phonEND_WORD, ph_10T, phonEND_WORD); | |||
@@ -1963,8 +1963,8 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned | |||
} | |||
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 | |||
sprintf(ph_out, "%s%s%s%c%s", ph_zeros, ph_buf2, ph_buf, phonEND_WORD, ph_append); | |||
@@ -1977,7 +1977,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned | |||
decimal_count++; | |||
max_decimal_count = 2; | |||
switch (decimal_mode = (tr->langopts.numbers & 0xe000)) | |||
switch (decimal_mode = (tr->langopts.numbers & NUM_DFRACTION_BITS)) | |||
{ | |||
case NUM_DFRACTION_4: | |||
max_decimal_count = 5; |
@@ -1,7 +1,7 @@ | |||
/* | |||
* Copyright (C) 2005 to 2015 by Jonathan Duddington | |||
* 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 | |||
* it under the terms of the GNU General Public License as published by | |||
@@ -553,7 +553,7 @@ Translator *SelectTranslator(const char *name) | |||
tr->langopts.break_numbers = BREAK_LAKH_BN; | |||
if (name2 == L3('b', 'p', 'y')) { | |||
tr->langopts.numbers = 1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
tr->langopts.numbers2 = NUM2_SWAP_THOUSANDS; | |||
} | |||
@@ -568,7 +568,7 @@ Translator *SelectTranslator(const char *name) | |||
SetLetterBitsRange(tr, LETTERGP_B, 0x90, 0xbc); | |||
SetLetterBitsRange(tr, LETTERGP_C, 0x40, 0x6c); // consonant letters (not subjoined) | |||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words | |||
tr->langopts.numbers = 1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
} | |||
break; | |||
case L('c', 'y'): // Welsh | |||
@@ -631,7 +631,7 @@ Translator *SelectTranslator(const char *name) | |||
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 | |||
tr->langopts.break_numbers = BREAK_LAKH_DV; | |||
tr->langopts.numbers = 1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
} | |||
break; | |||
case L('e', 'n'): | |||
@@ -683,7 +683,7 @@ Translator *SelectTranslator(const char *name) | |||
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.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')) { | |||
// ancient greek | |||
@@ -913,7 +913,7 @@ Translator *SelectTranslator(const char *name) | |||
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.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 | |||
SetLetterVowel(tr, 'y'); | |||
@@ -1004,7 +1004,7 @@ Translator *SelectTranslator(const char *name) | |||
tr->letter_groups[1] = is_lettergroup_B; | |||
SetLetterVowel(tr, 'y'); | |||
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; | |||
case L('i', 't'): // Italian | |||
@@ -1133,7 +1133,7 @@ Translator *SelectTranslator(const char *name) | |||
} | |||
break; | |||
case L('k', 'y'): // Kyrgyx | |||
tr->langopts.numbers = 1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
break; | |||
case L('l', 'a'): // Latin | |||
{ | |||
@@ -1191,7 +1191,7 @@ Translator *SelectTranslator(const char *name) | |||
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.numbers2 = 0x8a; // variant numbers before thousands,milliards | |||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_THOUSANDS | NUM2_THOUSANDPLEX_VAR_MILLIARDS | NUM2_THOUSANDS_VAR2; | |||
} | |||
break; | |||
case L('m', 't'): // Maltese | |||
@@ -1199,7 +1199,7 @@ Translator *SelectTranslator(const char *name) | |||
tr->encoding = ESPEAKNG_ENCODING_ISO_8859_3; | |||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x100; // devoice at end of word | |||
tr->langopts.stress_rule = STRESSPOSN_2R; // penultimate | |||
tr->langopts.numbers = 1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
} | |||
break; | |||
case L('n', 'l'): // Dutch | |||
@@ -1238,7 +1238,7 @@ Translator *SelectTranslator(const char *name) | |||
tr->langopts.stress_rule = STRESSPOSN_2R; | |||
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.numbers2 = 0x200; // say "thousands" before its number | |||
tr->langopts.numbers2 = NUM2_SWAP_THOUSANDS; | |||
} | |||
break; | |||
case L('p', 'l'): // Polish | |||
@@ -1291,7 +1291,7 @@ Translator *SelectTranslator(const char *name) | |||
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.numbers2 = 0x1e; // variant numbers before all thousandplex | |||
tr->langopts.numbers2 = NUM2_THOUSANDPLEX_VAR_ALL; | |||
} | |||
break; | |||
case L('r', 'u'): // Russian | |||
@@ -1304,7 +1304,7 @@ Translator *SelectTranslator(const char *name) | |||
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.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; | |||
case L('s', 'k'): // Slovak | |||
@@ -1328,7 +1328,7 @@ Translator *SelectTranslator(const char *name) | |||
tr->langopts.decimal_sep = ','; | |||
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, 'r'); | |||
@@ -1371,7 +1371,7 @@ Translator *SelectTranslator(const char *name) | |||
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->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 | |||
break; | |||
case L('s', 'q'): // Albanian | |||
@@ -1446,10 +1446,10 @@ Translator *SelectTranslator(const char *name) | |||
tr->langopts.stress_rule = 13; // 1st syllable, unless 1st vowel is short and 2nd is long | |||
} else if (name2 == L('k', 'n')) { | |||
tr->letter_bits_offset = OFFSET_KANNADA; | |||
tr->langopts.numbers = 0x1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
} else if (name2 == L('t', 'e')) { | |||
tr->letter_bits_offset = OFFSET_TELUGU; | |||
tr->langopts.numbers = 0x1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
tr->langopts.numbers2 = NUM2_ORDINAL_DROP_VOWEL; | |||
} | |||
SetIndicLetters(tr); // call this after setting OFFSET_ | |||
@@ -1540,7 +1540,7 @@ Translator *SelectTranslator(const char *name) | |||
case L3('s', 'h', 'n'): | |||
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.numbers = 1; | |||
tr->langopts.numbers = NUM_DEFAULT; | |||
tr->langopts.break_numbers = BREAK_INDIVIDUAL; | |||
break; | |||
case L3('c', 'm', 'n'): // no break, just go to 'zh' case | |||
@@ -1564,7 +1564,7 @@ Translator *SelectTranslator(const char *name) | |||
if (name2 == L3('z', 'h', 'y')) { | |||
tr->langopts.textmode = true; | |||
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.break_numbers = BREAK_INDIVIDUAL; | |||
} | |||
@@ -1609,5 +1609,5 @@ static void Translator_Russian(Translator *tr) | |||
tr->langopts.stress_flags = S_NO_AUTO_2; | |||
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 | |||
} |
@@ -448,7 +448,7 @@ char *strchr_w(const char *s, int c) | |||
} | |||
// 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_iz[4] = { 0, 'i', 'z', 0 }; | |||
@@ -753,7 +753,7 @@ static int TranslateWord3(Translator *tr, char *word_start, WORD_TAB *wtab, char | |||
if (wflags & FLAG_TRANSLATOR2) | |||
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" | |||
} else if (found == false) { | |||
// word's pronunciation is not given in the dictionary list, although | |||
@@ -1026,7 +1026,7 @@ static int TranslateWord3(Translator *tr, char *word_start, WORD_TAB *wtab, char | |||
} | |||
} | |||
addPluralSuffixes(wflags, tr, last_char, &word_phonemes); | |||
addPluralSuffixes(wflags, tr, last_char, word_phonemes); | |||
wflags |= emphasize_allcaps; | |||
// determine stress pattern for this word |
@@ -1,7 +1,7 @@ | |||
/* | |||
* Copyright (C) 2005 to 2014 by Jonathan Duddington | |||
* 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 | |||
* it under the terms of the GNU General Public License as published by | |||
@@ -438,98 +438,67 @@ typedef struct { | |||
unsigned char *length_mods; | |||
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; | |||
#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; | |||
// Bit 2^n is set if 10^n separates a number grouping (max n=31). |