let's talk numbers
This commit is contained in:
parent
4a260f112f
commit
3b562116fd
165
src/voice.ts
165
src/voice.ts
@ -1,4 +1,4 @@
|
|||||||
|
import path from 'path';
|
||||||
|
|
||||||
interface Voice {
|
interface Voice {
|
||||||
directory: string;
|
directory: string;
|
||||||
@ -7,4 +7,167 @@ interface Voice {
|
|||||||
|
|
||||||
type Voices = { [name: string]: Voice };
|
type Voices = { [name: string]: Voice };
|
||||||
|
|
||||||
|
const LINES = {
|
||||||
|
NEGATIVE: 'negative',
|
||||||
|
POINT: 'point',
|
||||||
|
ZERO: 'zero',
|
||||||
|
ONE: 'one',
|
||||||
|
TWO: 'two',
|
||||||
|
THREE: 'three',
|
||||||
|
FOUR: 'four',
|
||||||
|
FIVE: 'five',
|
||||||
|
SIX: 'six',
|
||||||
|
SEVEN: 'seven',
|
||||||
|
EIGHT: 'eight',
|
||||||
|
NINE: 'nine',
|
||||||
|
TEN: 'ten',
|
||||||
|
ELEVEN: 'eleven',
|
||||||
|
TWELVE: 'twelve',
|
||||||
|
THIRTEEN: 'thirteen',
|
||||||
|
FIFTEEN: 'fifteen',
|
||||||
|
TEEN: 'teen',
|
||||||
|
TWENTY: 'twenty',
|
||||||
|
THIRTY: 'thirty',
|
||||||
|
FORTY: 'forty',
|
||||||
|
FIFTY: 'fifty',
|
||||||
|
SIXTY: 'sixty',
|
||||||
|
SEVENTY: 'seventy',
|
||||||
|
EIGHTY: 'eighty',
|
||||||
|
NINETY: 'ninety',
|
||||||
|
HUNDRED: 'hundred',
|
||||||
|
THOUSAND: 'thousand',
|
||||||
|
MILLION: 'million',
|
||||||
|
BILLION: 'billion',
|
||||||
|
TRILLION: 'trillion'
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatNumber(num: number): string {
|
||||||
|
const parts = num.toString().split(".");
|
||||||
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
return parts.join(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
function digitByDigit(str: string): string[] {
|
||||||
|
const tokens: string[] = [];
|
||||||
|
const input = str.replaceAll(',', '');
|
||||||
|
const map = [
|
||||||
|
LINES.ZERO,
|
||||||
|
LINES.ONE,
|
||||||
|
LINES.TWO,
|
||||||
|
LINES.THREE,
|
||||||
|
LINES.FOUR,
|
||||||
|
LINES.FIVE,
|
||||||
|
LINES.SIX,
|
||||||
|
LINES.SEVEN,
|
||||||
|
LINES.EIGHT,
|
||||||
|
LINES.NINE
|
||||||
|
]
|
||||||
|
for (let i = 0; i < input.length; i++) {
|
||||||
|
tokens.push(map[parseInt(input.charAt(i))]);
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tens(str: string): string[] {
|
||||||
|
if (str === '0') {
|
||||||
|
return [LINES.ZERO];
|
||||||
|
}
|
||||||
|
const tokens: string[] = [];
|
||||||
|
const num = parseInt(str);
|
||||||
|
const map = {
|
||||||
|
'2': LINES.TWENTY,
|
||||||
|
'3': LINES.THIRTY,
|
||||||
|
'4': LINES.FORTY,
|
||||||
|
'5': LINES.FIFTY,
|
||||||
|
'6': LINES.SIXTY,
|
||||||
|
'7': LINES.SEVENTY,
|
||||||
|
'8': LINES.EIGHTY,
|
||||||
|
'9': LINES.NINETY
|
||||||
|
};
|
||||||
|
const ones = str.charAt(str.length - 1);
|
||||||
|
if (num === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
else if (num >= 20) {
|
||||||
|
tokens.push(map[str.charAt(0)]);
|
||||||
|
if (ones !== '0') {
|
||||||
|
tokens.push(...digitByDigit(ones));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (num < 10) {
|
||||||
|
tokens.push(...digitByDigit(ones));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const weirdoNumberMap = [
|
||||||
|
[LINES.TEN],
|
||||||
|
[LINES.ELEVEN],
|
||||||
|
[LINES.TWELVE],
|
||||||
|
[LINES.THIRTEEN],
|
||||||
|
[LINES.FOUR, LINES.TEEN],
|
||||||
|
[LINES.FIFTEEN],
|
||||||
|
[LINES.SIX, LINES.TEEN],
|
||||||
|
[LINES.SEVEN, LINES.TEEN],
|
||||||
|
[LINES.EIGHT, LINES.TEEN],
|
||||||
|
[LINES.NINE, LINES.TEEN],
|
||||||
|
]
|
||||||
|
tokens.push(...weirdoNumberMap[num - 10]);
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hundreds(str: string): string[] {
|
||||||
|
const tokens: string[] = [];
|
||||||
|
if (str.length === 3 && str.charAt(0) !== '0') {
|
||||||
|
tokens.push(...digitByDigit(str.charAt(0)));
|
||||||
|
tokens.push(LINES.HUNDRED);
|
||||||
|
str = str.substring(1);
|
||||||
|
}
|
||||||
|
tokens.push(...tens(str));
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
function integer(str: string): string[] {
|
||||||
|
const tokens: string[] = [];
|
||||||
|
const numGroups = str.split(',');
|
||||||
|
const seperators = [LINES.TRILLION, LINES.BILLION, LINES.MILLION, LINES.THOUSAND];
|
||||||
|
if (numGroups.length > 5) {
|
||||||
|
return digitByDigit(str);
|
||||||
|
}
|
||||||
|
seperators.splice(0, seperators.length - numGroups.length + 1);
|
||||||
|
numGroups.forEach(g => {
|
||||||
|
if (g !== '000') {
|
||||||
|
tokens.push(...hundreds(g));
|
||||||
|
}
|
||||||
|
if (seperators.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const sep = seperators.shift();
|
||||||
|
if (g !== '000') {
|
||||||
|
tokens.push(sep);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
function voiceLines(voice: Voice, num: number): string[] {
|
||||||
|
if (Math.abs(num) > 999999999999999 || isNaN(num)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const tokens: string[] = [];
|
||||||
|
const str = formatNumber(num);
|
||||||
|
const parts = str.split('.');
|
||||||
|
if (parts[0].startsWith('-')) {
|
||||||
|
tokens.push(LINES.NEGATIVE);
|
||||||
|
parts[0] = parts[0].substring(1);
|
||||||
|
}
|
||||||
|
tokens.push(...integer(parts[0]));
|
||||||
|
if (parts.length > 1) {
|
||||||
|
tokens.push(LINES.POINT);
|
||||||
|
tokens.push(...digitByDigit(parts[1]));
|
||||||
|
}
|
||||||
|
return tokens.map(l => path.join(voice.directory, `${l}.${voice.extension}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
export default voiceLines;
|
||||||
|
export { voiceLines };
|
||||||
export type { Voice, Voices };
|
export type { Voice, Voices };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user