michael@202: ; say.conf michael@202: ; michael@202: ; language configuration michael@202: ; michael@202: ; The new language routines produce strings of the form michael@202: ; prefix:[format:]data michael@202: ; that are matched against the rules in this file to produce michael@202: ; an output. michael@202: ; michael@202: ; The data is generally the string to be spelled (either a number, michael@202: ; an ascii string or a date/time in the format specified below). michael@202: ; It is available, in the right hand side of a rule, as variable ${SAY}. michael@202: ; michael@202: ; The format is optional and normally used only for date/time. michael@202: ; The prefix is used to select the pronunciation - standard michael@202: ; prefixes are michael@202: ; num used for numbers michael@202: ; enum used for enumerations michael@202: ; date for dates michael@202: ; time for times michael@202: ; datetime for dates and times michael@202: ; char for character strings michael@202: ; phonetic for phonetic strings michael@202: ; digit for digit strings michael@202: ; michael@202: ; but others can be used at will. michael@202: ; michael@202: ; Processing occurs as follows: michael@202: ; If the format is empty, or there is no format, the entire michael@202: ; string is matched against one of the pattern on the left hand side. michael@202: ; On the first match, the various comma-separated components on the right michael@202: ; hand side are pronounced, as follows: michael@202: ; + a component starting with a prefix: (i.e. with a ':' in it) michael@202: ; is re-processed according to these rules; michael@202: ; + a component without a ':' in it is considered a filename and michael@202: ; the corresponding file is played. michael@202: ; michael@202: ; If the format is non-empty, the format is split into its components michael@202: ; (individual characters, or filenames in single quotes), and then michael@202: ; filenames are played, whereas single characters are used to michael@202: ; generate a new string format:pat:data to be processed. michael@202: ; michael@202: ; DATES/AND TIMES assume that the date info is available in michael@202: ; the form YYYYMMDDHHmm.ss-dow-doy michael@202: ; with 4 digits for the year, 2 for month, day, hour, minutes, seconds, michael@202: ; one digit for the day-of-week, and 3 digits for the day-of-year. michael@202: ; michael@202: ; Example: michael@202: ; datetime::200604172030.00-4-102 michael@202: ; (typical format for a date) is first matched against the line michael@202: ; datetime::. => date:AdBY 'digits/at' IMp:${SAY} michael@202: ; which is normally present with the default format for dates. michael@202: ; In turn, the format string "AdBY 'digits/at' IMp" results in michael@202: ; the sequence michael@202: ; date:A:200604172030.00-4-102 michael@202: ; date:d:200604172030.00-4-102 michael@202: ; date:B:200604172030.00-4-102 michael@202: ; date:Y:200604172030.00-4-102 michael@202: ; digits/at michael@202: ; date:I:200604172030.00-4-102 michael@202: ; date:M:200604172030.00-4-102 michael@202: ; date:p:200604172030.00-4-102 michael@202: ; michael@202: ; michael@202: ; Remember, normally X Z N are special, and the search is michael@202: ; case insensitive, so you must use [X] [N] [Z] .. if you michael@202: ; want exact match. michael@202: michael@202: ; We start with the basic rules that might be more-or-less michael@202: ; language-independent michael@202: michael@202: [digit-base](!) ; base rule for digit strings michael@202: ; XXX incomplete yet michael@202: _digit:[0-9] => digits/${SAY} michael@202: _digit:[-] => letters/dash michael@202: _digit:[*] => letters/star michael@202: _digit:[@] => letters/at michael@202: _digit:[0-9]. => digit:${SAY:0:1}, digit:${SAY:1} michael@202: michael@202: [date-base](!) ; base rules for dates and times michael@202: ; the 'SAY' variable contains YYYYMMDDHHmm.ss-dow-doy michael@202: ; these rule map the strftime attributes. michael@202: _date:Y:. => num:${SAY:0:4} ; year, 19xx michael@202: _date:[Bb]:. => digits/mon-$[${SAY:4:2}-1] ; month name, 0..11 michael@202: _date:[Aa]:. => digits/day-${SAY:16:1} ; day of week michael@202: _date:[de]:. => num:${SAY:6:2} ; day of month michael@202: _date:[hH]:. => num:${SAY:8:2} ; hour michael@202: _date:[I]:. => num:$[${SAY:8:2} % 12] ; hour 0-12 michael@202: _date:[M]:. => num:${SAY:10:2} ; minute michael@202: ; XXX too bad the '?' function does not remove the quotes michael@202: ; _date:[pP]:. => digits/$[ ${SAY:10:2} > 12 ? "p-m" :: "a-m"] ; am pm michael@202: _date:[pP]:. => digits/p-m ; am pm michael@202: _date:[S]:. => num:${SAY:13:2} ; seconds michael@202: michael@202: [en-base](!) michael@202: _[n]um:0. => num:${SAY:1} michael@202: _[n]um:X => digits/${SAY} michael@202: _[n]um:1X => digits/${SAY} michael@202: _[n]um:[2-9]0 => digits/${SAY} michael@202: _[n]um:[2-9][1-9] => digits/${SAY:0:1}0, num:${SAY:1} michael@202: _[n]um:XXX => num:${SAY:0:1}, digits/hundred, num:${SAY:1} michael@202: michael@202: _[n]um:XXXX => num:${SAY:0:1}, digits/thousand, num:${SAY:1} michael@202: _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2} michael@202: _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:3} michael@202: michael@202: _[n]um:XXXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1} michael@202: _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/million, num:${SAY:2} michael@202: _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/million, num:${SAY:3} michael@202: michael@202: _[n]um:XXXXXXXXXX => num:${SAY:0:1}, digits/billion, num:${SAY:1} michael@202: _[n]um:XXXXXXXXXXX => num:${SAY:0:2}, digits/billion, num:${SAY:2} michael@202: _[n]um:XXXXXXXXXXXX => num:${SAY:0:3}, digits/billion, num:${SAY:3} michael@202: michael@202: ; enumeration michael@202: _e[n]um:X => digits/h-${SAY} michael@202: _e[n]um:1X => digits/h-${SAY} michael@202: _e[n]um:[2-9]0 => digits/h-${SAY} michael@202: _e[n]um:[2-9][1-9] => num:${SAY:0:1}0, digits/h-${SAY:1} michael@202: _e[n]um:[1-9]XX => num:${SAY:0:1}, digits/hundred, enum:${SAY:1} michael@202: michael@202: [it](digit-base,date-base) michael@202: _[n]um:0. => num:${SAY:1} michael@202: _[n]um:X => digits/${SAY} michael@202: _[n]um:1X => digits/${SAY} michael@202: _[n]um:[2-9]0 => digits/${SAY} michael@202: _[n]um:[2-9][1-9] => digits/${SAY:0:1}0, num:${SAY:1} michael@202: _[n]um:1XX => digits/hundred, num:${SAY:1} michael@202: _[n]um:[2-9]XX => num:${SAY:0:1}, digits/hundred, num:${SAY:1} michael@202: michael@202: _[n]um:1XXX => digits/thousand, num:${SAY:1} michael@202: _[n]um:[2-9]XXX => num:${SAY:0:1}, digits/thousands, num:${SAY:1} michael@202: _[n]um:XXXXX => num:${SAY:0:2}, digits/thousands, num:${SAY:2} michael@202: _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousands, num:${SAY:3} michael@202: michael@202: _[n]um:1XXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1} michael@202: _[n]um:[2-9]XXXXXX => num:${SAY:0:1}, digits/millions, num:${SAY:1} michael@202: _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2} michael@202: _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3} michael@202: michael@202: _datetime::. => date:AdBY 'digits/at' IMp:${SAY} michael@202: _date::. => date:AdBY:${SAY} michael@202: _time::. => date:IMp:${SAY} michael@202: michael@202: [en](en-base,date-base,digit-base) michael@202: _datetime::. => date:AdBY 'digits/at' IMp:${SAY} michael@202: _date::. => date:AdBY:${SAY} michael@202: _time::. => date:IMp:${SAY} michael@202: michael@202: [de](date-base,digit-base) michael@202: _[n]um:0. => num:${SAY:1} michael@202: _[n]um:X => digits/${SAY} michael@202: _[n]um:1X => digits/${SAY} michael@202: _[n]um:[2-9]0 => digits/${SAY} michael@202: _[n]um:[2-9][1-9] => digits/${SAY:1}-and, digits/${SAY:0:1}0 michael@202: _[n]um:1XX => digits/ein, digits/hundred, num:${SAY:1} michael@202: _[n]um:[2-9]XX => digits/${SAY:0:1}, digits/hundred, num:${SAY:1} michael@202: _[n]um:1XXX => digits/ein, digits/thousand, num:${SAY:1} michael@202: _[n]um:[2-9]XXX => digits/${SAY:0:1}, digits/thousand, num:${SAY:1} michael@202: _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2} michael@202: _[n]um:X00XXX => digits/${SAY:0:1}, digits/hundred, digits/thousand, num:${SAY:3} michael@202: _[n]um:XXXXXX => digits/${SAY:0:1}, digits/hundred, num:${SAY:1} michael@202: _[n]um:1XXXXXX => digits/eine, digits/million, num:${SAY:1} michael@202: _[n]um:[2-9]XXXXXX => digits/${SAY:0:1}, digits/millions, num:${SAY:1} michael@202: _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2} michael@202: _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3} michael@202: michael@202: _datetime::. => date:AdBY 'digits/at' IMp:${SAY} michael@202: _date::. => date:AdBY:${SAY} michael@202: _time::. => date:IMp:${SAY} michael@202: