|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defvar pl-table nil) |
|
|
|
(define (allaligns phones letters) |
|
"(cummulate phones lets) |
|
Aligns all possible ways for these strings." |
|
(cond |
|
((null letters) |
|
|
|
(if phones |
|
(format t "wrong end: %s\n" word)) |
|
nil) |
|
((null phones) |
|
nil) |
|
(t |
|
(if (< (length phones) (length letters)) |
|
(begin |
|
(cummulate '_epsilon_ (car letters)) |
|
(allaligns phones (cdr letters)))) |
|
(cummulate (car phones) (car letters)) |
|
(allaligns (cdr phones) (cdr letters))))) |
|
|
|
(define (valid-pair phone letter) |
|
"(valid-pair phone letter) |
|
If predefined to be valid." |
|
(let ((entry1 (assoc_string letter pl-table))) |
|
(if entry1 |
|
(assoc_string phone (cdr entry1)) |
|
nil))) |
|
|
|
(define (valid-pair-e phone nphone letter) |
|
"(valid-pair-e phone letter) |
|
Special cases for when epsilon may be inserted before letter." |
|
(let ((ll (assoc_string letter pl-table)) |
|
(pp (intern (string-append phone "-" nphone)))) |
|
(assoc_string pp (cdr ll)))) |
|
|
|
(define (find-aligns phones letters) |
|
"(find-aligns phones letters) |
|
Find all feasible alignments." |
|
(let ((r nil)) |
|
(cond |
|
((and (null (cdr phones)) (null (cdr letters)) |
|
(equal? (car phones) (car letters)) |
|
(equal? '# (car phones))) |
|
(list (list (cons '# '#)))) |
|
(t |
|
(if (valid-pair '_epsilon_ (car letters)) |
|
(set! r (mapcar |
|
(lambda (p) |
|
(cons (cons '_epsilon_ (car letters)) p)) |
|
(find-aligns phones (cdr letters))))) |
|
(if (valid-pair (car phones) (car letters)) |
|
(set! r |
|
(append r |
|
(mapcar |
|
(lambda (p) |
|
(cons (cons (car phones) (car letters)) p)) |
|
(find-aligns (cdr phones) (cdr letters)))))) |
|
|
|
(if (valid-pair-e (car phones) (car (cdr phones)) (car letters)) |
|
(set! r |
|
(append r |
|
(mapcar |
|
(lambda (p) |
|
(cons (cons (intern (format nil "%s-%s" |
|
(car phones) |
|
(car (cdr phones)))) |
|
(car letters)) p)) |
|
(find-aligns (cdr (cdr phones)) |
|
(cdr letters)))))) |
|
r)))) |
|
|
|
(define (findallaligns phones letters) |
|
(let ((a (find-aligns phones letters))) |
|
(if (null a) |
|
(begin |
|
(set! failedaligns (+ 1 failedaligns)) |
|
(format t "failed: %l %l\n" letters phones))) |
|
a)) |
|
|
|
(define (cummulate phone letter) |
|
"(cummulate phone letter) |
|
record the alignment of this phone and letter." |
|
(if (or (equal? phone letter) |
|
(and (not (equal? phone '#)) |
|
(not (equal? letter '#)))) |
|
(let ((entry1 (assoc_string letter pl-table)) |
|
score) |
|
(if (equal? phone '_epsilon_) |
|
(set! score 0.1) |
|
(set! score 1)) |
|
(if entry1 |
|
(let ((entry2 (assoc_string phone (cdr entry1)))) |
|
(if entry2 |
|
(set-cdr! entry2 (+ score (cdr entry2))) |
|
(set-cdr! entry1 (cons (cons phone 1) (cdr entry1))))) |
|
(set! pl-table |
|
(cons |
|
(cons letter |
|
(list (cons phone score))) |
|
pl-table))) |
|
t))) |
|
|
|
(define (score-pair phone letter) |
|
"(score-pair phone letter) |
|
Give score for this particular phone letter pair." |
|
(let ((entry1 (assoc_string letter pl-table))) |
|
(if entry1 |
|
(let ((entry2 (assoc_string phone (cdr entry1)))) |
|
(if entry2 |
|
(cdr entry2) |
|
0)) |
|
0))) |
|
|
|
(define (cummulate-aligns aligns) |
|
(mapcar |
|
(lambda (a) |
|
(mapcar |
|
(lambda (p) |
|
(cummulate (car p) (cdr p))) |
|
a)) |
|
aligns) |
|
t) |
|
|
|
(define (cummulate-pairs trainfile) |
|
"(cummulate-pairs trainfile) |
|
Build cummulatation table from allowable alignments in trainfile." |
|
(set! failedaligns 0) |
|
(set! allaligns 0) |
|
(if (not pl-table) |
|
(set! pl-table |
|
(mapcar |
|
(lambda (l) |
|
(cons (car l) (mapcar (lambda (c) (cons c 0)) (cdr l)))) |
|
allowables))) |
|
(let ((fd (fopen trainfile "r")) |
|
(c 0) (d 0) |
|
(entry)) |
|
(while (not (equal? (set! entry (readfp fd)) (eof-val))) |
|
(if (equal? c 1000) |
|
(begin |
|
(format t "ENTRY: %d %l\n" (set! d (+ 1000 d)) entry) |
|
(set! c 0))) |
|
(set! word (car entry)) |
|
(cummulate-aligns |
|
(findallaligns |
|
(enworden (car (cdr (cdr entry)))) |
|
(enworden (wordexplode (car entry))))) |
|
(set! allaligns (+ 1 allaligns)) |
|
(format t "aligned %d\n" allaligns) |
|
(set! c (+ 1 c))) |
|
(fclose fd) |
|
(format t "failedaligns %d/%d\n" failedaligns allaligns) |
|
)) |
|
|
|
(define (find_best_alignment phones letters) |
|
"(find_best_alignment phones letters) |
|
Find the alignement containg the most frequent alignment pairs." |
|
|
|
(set! fba_best_score 0) |
|
(set! fba_best nil) |
|
(find-best-align phones letters nil 0) |
|
fba_best |
|
) |
|
|
|
|
|
(define (find-best-align phones letters path score) |
|
"(find-best-align phones letters) |
|
Find all feasible alignments." |
|
(cond |
|
((null letters) |
|
(if (> score fba_best_score) |
|
(begin |
|
(set! fba_best_score score) |
|
(set! fba_best (reverse path)))) |
|
nil) |
|
(t |
|
(if (valid-pair '_epsilon_ (car letters)) |
|
(find-best-align phones (cdr letters) |
|
(cons (cons '_epsilon_ (car letters)) path) |
|
(+ score (score-pair '_epsilon_ (car letters))))) |
|
(if (valid-pair (car phones) (car letters)) |
|
(find-best-align (cdr phones) (cdr letters) |
|
(cons (cons (car phones) (car letters))path) |
|
(+ score (score-pair (car phones) (car letters))))) |
|
(if (valid-pair-e (car phones) (car (cdr phones)) (car letters)) |
|
(find-best-align (cdr (cdr phones)) (cdr letters) |
|
(cons (cons (intern (format nil "%s-%s" |
|
(car phones) |
|
(car (cdr phones)))) |
|
(car letters)) |
|
path) |
|
(+ score (score-pair |
|
(intern (format nil "%s-%s" |
|
(car phones) |
|
(car (cdr phones)))) |
|
(car letters)))))))) |
|
|
|
(define (align_and_score phones letters path score) |
|
"(align_and_score phones lets) |
|
Aligns all possible ways for these strings." |
|
(cond |
|
((null letters) |
|
(if (> score fba_best_score) |
|
(begin |
|
(set! fba_best_score score) |
|
(set! fba_best (reverse path)))) |
|
nil) |
|
(t |
|
(if (< (length phones) (length letters)) |
|
(align_and_score |
|
phones |
|
(cdr letters) |
|
(cons '_epsilon_ path) |
|
(+ score |
|
(score-pair '_epsilon_ (car letters))))) |
|
(align_and_score |
|
(cdr phones) |
|
(cdr letters) |
|
(cons (car phones) path) |
|
(+ score |
|
(score-pair (car phones) (car letters))))))) |
|
|
|
(define (aligndata file ofile) |
|
(let ((fd (fopen file "r")) |
|
(ofd (fopen ofile "w")) |
|
(c 1) |
|
(entry)) |
|
(while (not (equal? (set! entry (readfp fd)) (eof-val))) |
|
(set! lets (enworden (wordexplode (car entry)))) |
|
(set! bp (find_best_alignment |
|
(enworden (car (cdr (cdr entry)))) |
|
lets)) |
|
(if (not bp) |
|
(format t "align failed: %l\n" entry) |
|
(save_info (car (cdr entry)) bp ofd)) |
|
(set! c (+ 1 c))) |
|
(fclose fd) |
|
(fclose ofd))) |
|
|
|
(define (enworden lets) |
|
(cons '# (reverse (cons '# (reverse lets))))) |
|
|
|
(define (wordexplode lets) |
|
(if (consp lets) |
|
lets |
|
(symbolexplode lets))) |
|
|
|
(define (save_info pos bp ofd) |
|
"(save_info pos bp ofd) |
|
Cut out one expensive step and 50M of diskspace and just save it |
|
in a simpler format." |
|
(format ofd "( ( ") |
|
(mapcar |
|
(lambda (l) |
|
(if (not (string-equal "#" (cdr l))) |
|
(format ofd "%l " (cdr l)))) |
|
bp) |
|
(format ofd ") %l" pos) |
|
(mapcar |
|
(lambda (l) |
|
(if (not (string-equal "#" (car l))) |
|
(format ofd " %s" (car l)))) |
|
bp) |
|
(format ofd " )\n")) |
|
|
|
(define (normalise-table pl-table) |
|
"(normalise-table pl-table) |
|
Change scores into probabilities." |
|
(mapcar |
|
(lambda (s) |
|
(let ((sum (apply + (mapcar cdr (cdr s))))) |
|
(mapcar |
|
(lambda (p) |
|
(if (equal? sum 0) |
|
(set-cdr! p 0) |
|
(set-cdr! p (/ (cdr p) sum)))) |
|
(cdr s)))) |
|
pl-table) |
|
t) |
|
|
|
(define (save-table pre) |
|
(normalise-table pl-table) |
|
(set! fd (fopen (string-append pre "pl-tablesp.scm") "w")) |
|
(format fd "(set! pl-table '\n") |
|
(pprintf pl-table fd) |
|
(format fd ")\n") |
|
(fclose fd) |
|
t) |
|
|
|
(define (build-feat-file alignfile featfile) |
|
"(build-feat-file alignfile featfile) |
|
Build a feature file from the given align file. The feature |
|
file contain predicted phone, and letter with 3 preceding and |
|
3 succeeding letters." |
|
(let ((fd (fopen alignfile "r")) |
|
(ofd (fopen featfile "w")) |
|
(entry) |
|
(pn) |
|
(sylpos 1)) |
|
(while (not (equal? (set! entry (readfp fd)) (eof-val))) |
|
|
|
(set! lets (append '(0 0 0 0 #) (wordexplode (car entry)) |
|
'(# 0 0 0 0))) |
|
(set! phones (cdr (cdr entry))) |
|
(set! pn 5) |
|
(mapcar |
|
(lambda (p) |
|
(format ofd |
|
"%s %s %s %s %s %s %s %s %s %s %s\n" |
|
p |
|
(nth (- pn 4) lets) |
|
(nth (- pn 3) lets) |
|
(nth (- pn 2) lets) |
|
(nth (- pn 1) lets) |
|
(nth pn lets) |
|
(nth (+ pn 1) lets) |
|
(nth (+ pn 2) lets) |
|
(nth (+ pn 3) lets) |
|
(nth (+ pn 4) lets) |
|
(cond |
|
((not (consp (car (cdr entry)))) |
|
(car (cdr entry))) |
|
((not (consp (caar (cdr entry)))) |
|
(caar (cdr entry))) |
|
(t nil)) |
|
|
|
|
|
|
|
) |
|
(set! pn (+ 1 pn))) |
|
phones)) |
|
(fclose fd) |
|
(fclose ofd)) |
|
) |
|
|
|
(define (merge_models name filename allowables) |
|
"(merge_models name filename) |
|
Merge the models into a single list of cart trees as a variable |
|
named by name, in filename." |
|
(require 'cart_aux) |
|
(let (trees fd) |
|
(set! trees nil) |
|
(set! lets (mapcar car allowables)) |
|
(while lets |
|
(if (probe_file (format nil "lts.%s.tree" (car lets))) |
|
(begin |
|
(format t "%s\n" (car lets)) |
|
(set! tree (car (load (format nil "lts.%s.tree" (car lets)) t))) |
|
(set! tree (cart_simplify_tree2 tree nil)) |
|
(set! trees |
|
(cons (list (car lets) tree) trees)))) |
|
(set! lets (cdr lets))) |
|
(set! trees (reverse trees)) |
|
(set! fd (fopen filename "w")) |
|
(format fd ";; LTS rules \n") |
|
(format fd "(set! %s '(\n" name) |
|
(mapcar |
|
(lambda (tree) (pprintf tree fd)) |
|
trees) |
|
(format fd "))\n") |
|
(fclose fd)) |
|
) |
|
|
|
(define (lts_testset file cartmodels) |
|
"(lts_testset file cartmodels) |
|
Test an aligned lexicon file against a set of cart trees. Prints out |
|
The number of letters correct (for each letter), total number of |
|
letters correct and the total number of words correct. cartmodels is |
|
the structure as saved by merge_models." |
|
(let ((fd (fopen file "r")) |
|
(entry) |
|
(wordcount 0) |
|
(correctwords 0) |
|
(phonecount 0) |
|
(correctphones 0)) |
|
(while (not (equal? (set! entry (readfp fd)) (eof-val))) |
|
(let ((letters (enworden (wordexplode (car entry)))) |
|
(phones (enworden (cdr (cdr entry)))) |
|
(pphones)) |
|
(set! wordcount (+ 1 wordcount)) |
|
(set! pphones (gen_cartlts letters (car (cdr entry)) cartmodels)) |
|
|
|
|
|
|
|
|
|
|
|
(if (equal? (ph-normalize pphones) (ph-normalize phones)) |
|
(set! correctwords (+ 1 correctwords)) |
|
(or nil |
|
(format t "failed %l %l %l %l\n" (car entry) (car (cdr entry)) phones pphones))) |
|
(count_correct_letters |
|
(cdr letters) |
|
(cdr phones) |
|
(cdr pphones)) |
|
(set! phonecount (+ (length (cdr (cdr letters))) phonecount)) |
|
)) |
|
(fclose fd) |
|
(mapcar |
|
(lambda (linfo) |
|
(format t "%s %d correct %d (%2.2f)\n" |
|
(car linfo) (car (cdr linfo)) |
|
(car (cdr (cdr linfo))) |
|
(/ (* (car (cdr (cdr linfo))) 100) (car (cdr linfo)))) |
|
(set! correctphones (+ correctphones (car (cdr (cdr linfo)))))) |
|
correct_letter_table) |
|
(format t "phones %d correct %d (%2.2f)\n" |
|
phonecount correctphones (/ (* correctphones 100) phonecount)) |
|
(format t "words %d correct %d (%2.2f)\n" |
|
wordcount correctwords (/ (* correctwords 100) wordcount)) |
|
(format t "tree model has %d nodes\n" |
|
(apply + (mapcar (lambda (a) (cart_tree_node_count (car (cdr a)))) |
|
cartmodels))) |
|
)) |
|
|
|
(define (cart_tree_node_count tree) |
|
"(tree_node_count tree) |
|
Count the number nodes (questions and leafs) in the given CART tree." |
|
(cond |
|
((cdr tree) |
|
(+ 1 |
|
(cart_tree_node_count (car (cdr tree))) |
|
(cart_tree_node_count (car (cdr (cdr tree)))))) |
|
(t |
|
1))) |
|
|
|
(defvar correct_letter_table |
|
(mapcar |
|
(lambda (l) (list l 0 0)) |
|
'(a b c d e f g h i j k l m n o p q r s t u v w x y z)) |
|
"correct_letter_table |
|
List used to cummulate the number of correct (and incorrect) letter to |
|
phone predictions. This list will be extended if there are more letters |
|
in your alphabet, though it doesn't take a fairly western european |
|
view of the alphabet, but you can change this yourself is necessary.") |
|
|
|
(define (count_correct_letters lets phs pphs) |
|
"(count_correct_letters lets phs pphs) |
|
Count which letters have the correct phone prediction. Cummulate this |
|
is a per letter table." |
|
(cond |
|
((or (null phs) (null pphs) (null lets)) |
|
(format t "misaligned entry\n") |
|
nil) |
|
((and (null (cdr lets)) (null (cdr phs)) (null (cdr pphs))) |
|
nil) |
|
(t |
|
(let ((letinfo (assoc_string (car lets) correct_letter_table))) |
|
(if (not letinfo) |
|
(set! correct_letter_table |
|
(append correct_letter_table |
|
(list (set! letinfo (list (car lets) 0 0)))))) |
|
(set-car! (cdr letinfo) (+ 1 (car (cdr letinfo)))) |
|
(if (equal? (car phs) (car pphs)) |
|
(set-car! (cdr (cdr letinfo)) (+ 1 (car (cdr (cdr letinfo)))))) |
|
(count_correct_letters (cdr lets) (cdr phs) (cdr pphs)))))) |
|
|
|
(define (ph-normalize ph) |
|
(cond |
|
((null ph) nil) |
|
((string-equal "_epsilon_" (car ph)) |
|
(ph-normalize (cdr ph))) |
|
((string-matches (car ph) ".*-.*") |
|
(cons |
|
(string-before (car ph) "-") |
|
(cons |
|
(string-after (car ph) "-") |
|
(ph-normalize (cdr ph))))) |
|
(t |
|
(cons (car ph) (ph-normalize (cdr ph)))))) |
|
|
|
(define (make_let_utt_p letters pos) |
|
"(make_let_utt letters) |
|
Build an utterances from th4ese letters." |
|
(let ((utt (Utterance Text ""))) |
|
(utt.relation.create utt 'LTS) |
|
(utt.relation.create utt 'LETTER) |
|
(utt.relation.create utt 'PHONE) |
|
|
|
(mapcar |
|
(lambda (l) |
|
(let ((lsi (utt.relation.append utt 'LETTER))) |
|
(item.set_name lsi l) |
|
(item.set_feat lsi "pos" pos))) |
|
letters) |
|
utt)) |
|
|
|
(define (gen_vilts letters pos cartmodels ngram) |
|
"(get_vilts letters pos cartmodels ngram) |
|
Use cart plus ngrams in viterbi search." |
|
(require 'lts) |
|
(let ((utt (make_let_utt_p letters pos))) |
|
(set! gen_vit_params |
|
(list |
|
(list 'Relation "LETTER") |
|
(list 'return_feat "phone") |
|
(list 'p_word "#") |
|
(list 'pp_word "0") |
|
(list 'ngramname ngram) |
|
|
|
(list 'cand_function 'lts_cand_function))) |
|
(Gen_Viterbi utt) |
|
(mapcar |
|
(lambda (lsi) |
|
(intern (item.feat lsi "phone"))) |
|
(utt.relation.items utt 'LETTER)))) |
|
|
|
(define (gen_cartlts letters pos cartmodels) |
|
"(get_cartlts letters cartmodels) |
|
Generate the full list of predicted phones, including |
|
epsilon and unexpanded multi-phones." |
|
(require 'lts) |
|
(let ((utt (make_let_utt_p letters pos))) |
|
(enworden |
|
(mapcar |
|
(lambda (lsi) |
|
(let ((tree (car (cdr (assoc_string (item.name lsi) cartmodels)))) |
|
(p)) |
|
(if (not tree) |
|
(begin |
|
(format t "failed to find tree for %s\n" (item.name lsi)) |
|
nil) |
|
(begin |
|
(set! p (wagon_predict lsi tree)) |
|
(item.set_feat lsi "val" p) |
|
p)))) |
|
(reverse (cdr (reverse (cdr (utt.relation.items utt 'LETTER))))))))) |
|
|
|
(define (reduce_lexicon entryfile exceptionfile lts_function) |
|
"(reduce_lexicon entryfile exceptionfile lts_function) |
|
Look up each word in entryfile using the current lexicon, if the entry |
|
doesn't match save it in the exception file. This is a way of reducing |
|
the lexicon based on a letter to sound model (and lexical stress |
|
model, if appropriate)." |
|
(let ((fd (fopen entryfile "r")) |
|
(ofd (fopen exceptionfile "w")) |
|
(entry) |
|
(wordcount 0) |
|
(correctwords 0)) |
|
(while (not (equal? (set! entry (readfp fd)) (eof-val))) |
|
(if (and (consp entry) |
|
(> (length entry) 1)) |
|
(let ((lts (lts_function (car entry) (car (cdr entry)))) |
|
(encount (lex.entrycount (car entry)))) |
|
(set! wordcount (+ 1 wordcount)) |
|
(if (and (equal? (nth 2 entry) (nth 2 lts)) |
|
(< encount 2)) |
|
(set! correctwords (+ 1 correctwords)) |
|
(format ofd "%l\n" entry)) |
|
))) |
|
(fclose fd) |
|
(fclose ofd) |
|
(format t "words %d correct %d (%2.2f)\n" |
|
wordcount correctwords (/ (* correctwords 100) wordcount)) |
|
)) |
|
|
|
(define (dump-flat-entries infile outfile ltype) |
|
(let ((ifd (fopen infile "r")) |
|
(ofd (fopen outfile "w")) |
|
clength |
|
entry) |
|
|
|
|
|
|
|
|
|
|
|
(while (not (equal? (set! entry (readfp ifd)) (eof-val))) |
|
(cond |
|
((not (consp entry)) |
|
t) |
|
((string-equal ltype "utf8") |
|
(set! clength (length (utf8explode (car entry))))) |
|
(t |
|
(set! clength (length (car entry))))) |
|
(cond |
|
((not (consp entry)) |
|
t) |
|
((and |
|
|
|
(not (string-matches (car entry) ".*'.*")) |
|
(car (cddr entry))) |
|
(begin |
|
(cond |
|
((string-equal ltype "utf8") |
|
(format ofd |
|
"( %l %l (" |
|
(utf8explode (car entry)) |
|
(cadr entry))) |
|
((string-equal ltype "asis") |
|
(format ofd |
|
"( \"%s\" %l (" |
|
(car entry) |
|
(cadr entry))) |
|
(t |
|
(format ofd |
|
"( \"%s\" %l (" |
|
(downcase (car entry)) |
|
(cadr entry)))) |
|
(if (consp (car (car (cddr entry)))) |
|
(begin |
|
(mapcar |
|
(lambda (syl) |
|
(mapcar |
|
(lambda (seg) |
|
(cond |
|
((string-matches seg "[aeiouAEIOU@].*") |
|
(format ofd "%s " (string-append seg (cadr syl)))) |
|
(t |
|
(format ofd "%s " seg)))) |
|
(car syl))) |
|
(car (cddr entry)))) |
|
(begin |
|
(mapcar |
|
(lambda (p) |
|
(format ofd "%s " p)) |
|
(car (cddr entry))) |
|
)) |
|
(format ofd "))\n"))) |
|
(t nil))) |
|
(fclose ifd) |
|
(fclose ofd))) |
|
|
|
(define (dump-lets-phones infile) |
|
"(dump-lets-phones infile) |
|
Dump all the letters to alllets.out and phones to allphones.out for processing. |
|
This expects an external script to sort and uniquify them. This is done |
|
in scheme so we can get utf8/non-utf8 to be easy." |
|
(let ((ifd (fopen infile "r")) |
|
(lfd (fopen "alllets.out" "w")) |
|
(apfd (fopen "allphones.out" "w")) |
|
(pfd (fopen "let2phones.out" "w")) |
|
entry) |
|
(while (not (equal? (set! entry (readfp ifd)) (eof-val))) |
|
(mapcar |
|
(lambda (l) |
|
(format lfd "%s\n" l) |
|
(format pfd "%s " l) |
|
(mapcar |
|
(lambda (p) (format pfd "%s " p)) |
|
(car (cddr entry))) |
|
(format pfd "\n")) |
|
(wordexplode (car entry))) |
|
(mapcar |
|
(lambda (p) (format apfd "%s " p)) |
|
(car (cddr entry))) |
|
(format apfd "\n") |
|
) |
|
(fclose ifd) |
|
(fclose lfd) |
|
(fclose pfd) |
|
(fclose apfd) |
|
t)) |
|
|
|
(define (dump-flat-entries-all infile outfile) |
|
"(dump-flat-entries-all infile outfile) |
|
Do this for *all* entries not just ones with more than three chars." |
|
(let ((ifd (fopen infile "r")) |
|
(ofd (fopen outfile "w")) |
|
entry) |
|
(readfp ifd) |
|
(while (not (equal? (set! entry (readfp ifd)) (eof-val))) |
|
(if (consp entry) |
|
(begin |
|
(format ofd |
|
"( \"%s\" %s (" |
|
(downcase (car entry)) |
|
(cadr entry)) |
|
(mapcar |
|
(lambda (syl) |
|
(mapcar |
|
(lambda (seg) |
|
(cond |
|
|
|
|
|
((string-matches seg "[aeiouAEIOU@].*") |
|
(format ofd "%s " (string-append seg (cadr syl)))) |
|
(t |
|
(format ofd "%s " seg)))) |
|
(car syl))) |
|
(car (cddr entry))) |
|
(format ofd "))\n")))) |
|
(fclose ifd) |
|
(fclose ofd))) |
|
|
|
(provide 'lts_build) |
|
|
|
|