Bug in manual input of words
[sgc2.git] / MainPage.praat
blob13d6489c50539607a03ea632e08d74df620c424e
2 # SpeakGoodChinese 2.0
3
4 # Praat script handling buttons page
6 #     SpeakGoodChinese: MainPage.praat loads the code needed for the 
7 #     main, practice, page of SGC2 and the sound handling and recognition.
8 #     
9 #     Copyright (C) 2007-2010  R.J.J.H. van Son and 2010 the Netherlands Cancer Institute
10 #     The SpeakGoodChinese team are:
11 #     Guangqin Chen, Zhonyan Chen, Stefan de Koning, Eveline van Hagen, 
12 #     Rob van Son, Dennis Vierkant, David Weenink
13
14 #     This program is free software; you can redistribute it and/or modify
15 #     it under the terms of the GNU General Public License as published by
16 #     the Free Software Foundation; either version 2 of the License, or
17 #     (at your option) any later version.
18
19 #     This program is distributed in the hope that it will be useful,
20 #     but WITHOUT ANY WARRANTY; without even the implied warranty of
21 #     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 #     GNU General Public License for more details.
23
24 #     You should have received a copy of the GNU General Public License
25 #     along with this program; if not, write to the Free Software
26 #     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
27
28 # Includes at the bottom
30 ###############################################################
32 # Button Drawing Routines
34 ###############################################################
36 procedure DrawPrevious .color$ .x .y .size
37         demo '.color$'
38         .size *= 2/3
39         .fraction = 0
40         if sgc.numberOfDisplayedWords > 0
41                 .fraction = sgc.currentWordNum/sgc.numberOfDisplayedWords
42         endif
43         call drawProgressTriangle -1 .x .y .size .fraction '.color$' Green
44         .currentX = drawProgressTriangle.currentX
45         .endX = .currentX - 0.5
46         .lowY = .y - .size
47         .highY = .y + .size
48         .displayColor$ = .color$
49         if sgc.currentWordNum >= sgc.numberOfDisplayedWords
50                 .displayColor$ = "Green"
51         endif
52         demo Paint rectangle... '.displayColor$' '.currentX' '.endX' '.lowY' '.highY'
53 endproc
55 procedure DrawNext .color$ .x .y .size
56         demo '.color$'
57         .size *= 2/3
58         .fraction = 0
59         if sgc.numberOfDisplayedWords > 0
60                 .fraction = sgc.currentWordNum/sgc.numberOfDisplayedWords
61         endif
62         call drawProgressTriangle 1 .x .y .size .fraction '.color$' Green
63         .currentX = drawProgressTriangle.currentX
64         .endX = .currentX + 0.5
65         .lowY = .y - .size
66         .highY = .y + .size
67         .displayColor$ = .color$
68         if sgc.currentWordNum >= sgc.numberOfDisplayedWords
69                 .displayColor$ = "Green"
70         endif
71         demo Paint rectangle... '.displayColor$' '.currentX' '.endX' '.lowY' '.highY'
72 endproc
74 procedure DrawSelectWords .color$ .x .y .size
75         .currentFontSize = 48
76         .y -= .size/2 + 0.5
77         .maxHeight = 2*.size
78         call adjustFontSizeOnHeight 'defaultFont$' '.currentFontSize' '.maxHeight'
79         .currentFontSize = adjustFontSizeOnHeight.currentFontSize
80         call set_font_size '.currentFontSize'
81         demo Colour... '.color$'
82         demo Text... '.x' Centre '.y' Bottom \bu\bu\bu
83         call set_font_size 'defaultFontSize'
84 endproc
86 procedure DrawWordListUp .color$ .x .y .size
87     .xleft = .x - .size
88     .xright = .x + .size
89     .xmidleft = .x + 0.1
90     .xmidright = .x - 0.1
91     .ylow = .y
92     .yhigh = .y + .size
93         demo '.color$'
94         demo Line width... 3
95         demo Draw line... .xleft .ylow .xmidleft .yhigh
96         demo Draw line... .xright .ylow .xmidright .yhigh
97         demo Line width... 'defaultLineWidth'
98         demo Black
99 endproc
101 procedure DrawWordListDown .color$ .x .y .size
102     .xleft = .x - .size
103     .xright = .x + .size
104     .xmidleft = .x + 0.1
105     .xmidright = .x - 0.1
106     .yhigh = .y + .size
107     .ylow = .y
108         demo '.color$'
109         demo Line width... 3
110         demo Draw line... .xleft .yhigh .xmidleft .ylow
111         demo Draw line... .xright .yhigh .xmidright .ylow
112         demo Line width... 'defaultLineWidth'
113         demo Black
114 endproc
116 procedure drawTriangle .direction .x .y .size
117         # Make sure direction = +/- 1
118         if .direction = 0
119                 .direction = 1 
120         endif
121         .direction /= abs(.direction)
122         
123         .offset = 0.01
124         .currentHeight = .size
125         .currentX = .x - .direction*.size
126         
127         demo Line width... 2.0
129         while .currentHeight> 0
130                 .ystart = .y + .currentHeight
131                 .yend = .y - .currentHeight
132                 demo Draw line... .currentX .ystart .currentX .yend
133                 .currentHeight -= .offset *3/4
134                 .currentX += .direction*.offset * 1.5
135         endwhile
136         demo Line width... 'defaultLineWidth'
137 endproc
139 procedure drawProgressTriangle .direction .x .y .size .fraction .color1$ .color2$
140         # Make sure direction = +/- 1
141         if .direction = 0
142                 .direction = 1 
143         endif
144         .direction /= abs(.direction)
145         
146         .offset = 0.01
147         .currentHeight = .size
148         .startX = .x - .direction*.size
149         .currentX = .startX
150         
151         demo Line width... 2.0
153         while .currentHeight> 0
154                 # Implement progress bar in .color2$
155                 if .direction*(.currentX - .startX)/.size  <= 2*.fraction
156                         demo '.color2$'
157                 else
158                         demo '.color1$'
159                 endif
160                 
161                 .ystart = .y + .currentHeight
162                 .yend = .y - .currentHeight
163                 demo Draw line... .currentX .ystart .currentX .yend
164                 .currentHeight -= .offset *3/4
165                 .currentX += .direction*.offset * 1.5
166         endwhile
167         demo Line width... 'defaultLineWidth'
168         demo '.color1$'
169 endproc
171 ###############################################################
173 # Obligatory button Drawing Routines
175 # These MUST be defined
177 ###############################################################
179 procedure DrawRecord .color$ .x .y .size
180         .size /= 2
181     demo Paint circle... '.color$' '.x' '.y' '.size'
182 endproc
184 procedure DrawPlay .color$ .x .y .size
185         demo '.color$'
186         call drawTriangle 1 .x .y .size
187 endproc
189 procedure DrawQuit .color$ .x .y .size
190         demo Colour... '.color$'
191         .lineWidth = 0.5*.size**2
192         demo Line width... '.lineWidth'
193         .xstart = .x - .size
194         .ystart = .y + .size
195         .xend = .x + .size
196         .yend = .y - .size
197         demo Draw line... .xstart .ystart .xend .yend
198         .xstart = .x - .size
199         .ystart = .y - .size
200         .xend = .x + .size
201         .yend = .y + .size
202         demo Draw line... .xstart .ystart .xend .yend
203         demo Line width... 'defaultLineWidth'
204         demo Colour... Black
205 endproc
207 procedure DrawConfig .color$ .x .y .size
208         .size *= 1
209         .lineWidth = 0.4*.size
210         demo Arrow size... '.lineWidth'
211         .lineWidth = 0.4*.size**2
212         demo Line width... '.lineWidth'
213         .y += .size/2
214         .xstart = .x - .size
215         .xend = .x + .size
216         demo Draw arrow... .xstart .y .xend .y
217         demo Line width... 'defaultLineWidth'
218 endproc
220 procedure DrawRefresh .color$ .x .y .size
221         .lineWidth = 0.5*.size**2
222         .size /= 2
223         demo Line width... '.lineWidth'
224         demo Draw arc... '.x' '.y' '.size' 0 270
225         demo Line width... 'defaultLineWidth'
226 endproc
228 ###############################################################
230 # Button Processing Routines
232 ###############################################################
234 procedure processMainPageExample .clickX .clickY .pressed$
235         call generate_example
236 endproc
238 procedure processMainPagePrevious .clickX .clickY .pressed$
239         call clean_up_sound
240         call display_text Grey
241         call previous_word
242         # Draw the contour
243         call wipeArea 'wipeFeedbackArea$'
244         call init_window
245         call display_text Black
246         
247         sgc.failedAttempts = 0
248 endproc
250 procedure processMainPageNext .clickX .clickY .pressed$
251         call clean_up_sound
252         call display_text Grey
253         call next_word
254         call wipeArea 'wipeFeedbackArea$'
255         call init_window
256         # Draw the contour
257         call display_text Black
258 endproc
260 procedure processMainPageWordlistUp .clickX .clickY .pressed$
261         call wipeArea 'wipeFeedbackArea$'
262     call load_word_list "'localWordlistDir$'" -1
263         call init_window
264         call display_text Black
265 endproc
267 procedure processMainPageWordlistDown .clickX .clickY .pressed$
268         call wipeArea 'wipeFeedbackArea$'
269     call load_word_list "'localWordlistDir$'" 1
270         call init_window
271         call display_text Black
272 endproc
274 procedure processMainPageGRADE .clickX .clickY .pressed$
275         call setGrade '.pressed$'
276         # Redraw window
277         call init_window
278 endproc
280 procedure processMainPagePinYinArea .clickX .clickY .pressed$
281         # Redraw window
282         sgc.writeAll = 1
283         call display_text Red
284         sgc.writeAll = 0
285 endproc
287 # Select the words to practise. This is quite a complex piece of code
288 procedure processMainPageSelectWords .clickX .clickY .pressed$
289         .table$ = "MainPage"
290         .label$ = "SelectWords"
291     call Draw_button '.table$' '.label$' 1
293         # Get help text
294         call findLabel '.table$' '.label$'
295         .row = findLabel.row
296         select Table '.table$'
297         .helpText$ = Get value... '.row' Helptext
298         call convert_praat_to_latin1 '.helpText$'
299         .helpText$ = convert_praat_to_latin1.text$
300    
301     # Implement Cancel
302     select sgc.currentWordlist
303     .tmpOriginalWordlist = Copy: "Original_'wordlist$'"
305         # Remove current list from All wordlists table
306         select sgc.allWordLists
307         .rowNum = Search column: "Name", wordlistName$
308         if .rowNum > 0
309                 .numRows = Get number of rows
310                 if .numRows > 1
311                         Remove row: .rowNum
312                 else
313                         Set string value: 1, "Name", "---"
314                 endif
315         endif
316     
317     # Set current word
318         select sgc.currentWordlist
319         sgc.numberOfWords = Get number of rows
320     .currentWord = sgc.currentWord
321     if .currentWord <= 0 or .currentWord > sgc.numberOfWords or config.shuffleLists
322                 .currentWord = 1
323         endif
324     
325         # The texts
326         call get_feedback_text 'config.language$' AddWordlist
327         call convert_praat_to_latin1 'get_feedback_text.text$'
328         .wordlistText$ = convert_praat_to_latin1.text$
329         call get_feedback_text 'config.language$' Part
330         call convert_praat_to_latin1 'get_feedback_text.text$'
331         .partText$ = convert_praat_to_latin1.text$
332         call get_feedback_text 'config.language$' Tones
333         call convert_praat_to_latin1 'get_feedback_text.text$'
334         .toneText$ = convert_praat_to_latin1.text$
335         call get_feedback_text 'config.language$' Cancel
336         call convert_praat_to_latin1 'get_feedback_text.text$'
337         .cancelText$ = convert_praat_to_latin1.text$
338         call get_feedback_text 'config.language$' Clear
339         call convert_praat_to_latin1 'get_feedback_text.text$'
340         .clearText$ = convert_praat_to_latin1.text$
341         call get_feedback_text 'config.language$' All
342         call convert_praat_to_latin1 'get_feedback_text.text$'
343         .allText$ = convert_praat_to_latin1.text$
344         call get_feedback_text 'config.language$' Previous
345         call convert_praat_to_latin1 'get_feedback_text.text$'
346         .prevWord$ = convert_praat_to_latin1.text$
347         call get_feedback_text 'config.language$' Next
348         call convert_praat_to_latin1 'get_feedback_text.text$'
349         .nextWord$ = convert_praat_to_latin1.text$
350         call get_feedback_text 'config.language$' Continue
351         call convert_praat_to_latin1 'get_feedback_text.text$'
352         .continueText$ = convert_praat_to_latin1.text$
353         call get_feedback_text 'config.language$' Show
354         call convert_praat_to_latin1 'get_feedback_text.text$'
355         .showText$ = convert_praat_to_latin1.text$
357         call get_evaluation_text 'config.language$' Pinyin
358         .pinyinText$ = get_evaluation_text.text$
359         
360         call get_evaluation_text 'config.language$' Character
361         .characterText$ = get_evaluation_text.text$
362         
363         call get_evaluation_text 'config.language$' Example
364         .exampleText$ = get_evaluation_text.text$
365         
366         call get_evaluation_text 'config.language$' Translation
367         .translationText$ = get_evaluation_text.text$
368         
369         call get_evaluation_text 'config.language$' ManualEntry
370         .manualEntryText$ = get_evaluation_text.text$
371         
372         # Get lesson names
373         select sgc.currentWordlist
374         .lessonCol = Get column index: "Lesson"
375         if .lessonCol <= 0
376                 Append column: "Lesson"
377                 .lessonCol = Get column index: "Lesson"
378                 .numRows = Get number of rows
379                 for .w to .numRows
380                         Set string value: .w, "Lesson", "-"
381                 endfor
382         endif
383         .lessonList$ = tab$
384         .numLessons = 0
385         .lessonName$ = ""
386         # All shown keeps track whether all words are shown
387         # If so, selecting a lesson is preceded by a Clear All
388         .allShown = 0
389         # Sort words for consistent selection interface
390         if config.shuffleLists
391                 # Allow subdivision in lessons
392                 if .lessonCol > 0
393                         Sort rows... Lesson Pinyin
394                 else
395                         Sort rows... Pinyin
396                 endif
397         endif           
398         if .lessonCol > 0
399                 for .i to sgc.numberOfWords
400                         .currentLesson$ = Get value: .i, "Lesson"
401                         .matchLesson$ = tab$+.currentLesson$+tab$
402                         if .currentLesson$ <> "" and .currentLesson$ <> "-" and .currentLesson$ <> "?" and index(.lessonList$, .matchLesson$) <= 0
403                                 .lessonList$ = .lessonList$ + .currentLesson$ + tab$
404                                 .numLessons += 1
405                                 .lessonName$['.numLessons'] = .currentLesson$
406                         endif
407                         .shown$ = Get value: .i, "Show"
408                         if .shown$ = "-"
409                                 .allShown = 0
410                         endif
411                 endfor
412         endif
413         
414         clicked = -1
415         .numWordsPerScreen = 15
416         while clicked <> 6 and clicked <> 1
417                 .lessonSelected = -1
418                 .toneSelected = -1
419                 .firstShown = -1
420                 
421                 select sgc.currentWordlist
422                 .lessonCol = Get column index: "Lesson"
423                 # Sort words for consistent selection interface
424         if config.shuffleLists
425                         # Allow subdivision in lessons
426                         if .numLessons > 1
427                                 Sort rows... Lesson Pinyin
428                         else
429                                 Sort rows... Pinyin
430                         endif
431         endif           
432                 .max = .numWordsPerScreen - 1
433                 if .currentWord + .max > sgc.numberOfWords
434                         .max = sgc.numberOfWords - .currentWord
435                 endif
436                 for .i from 0 to .numWordsPerScreen - 1
437                         if .i <= .max
438                                 .currentPinyin$ = Get value: .currentWord+.i, "Pinyin"
439                                 if index_regex(.currentPinyin$, "[0-9]") <= 0
440                                         call pinyin2numbers '.currentPinyin$'
441                                         .currentPinyin$ = replace_regex$(pinyin2numbers.intermediatePinyin$, ".+", "\l&", 0)
442                                         .currentPinyin$ = replace_regex$(.currentPinyin$, "[^a-zA-Z0-9]", "", 0)
443                                 endif
444                                 .pinyin$[.i] = .currentPinyin$
446                                 .character$[.i] = Get value: .currentWord+.i, "Character"
447                                 .lessonNum$[.i] = ""
448                                 if .numLessons > 1
449                                         .lessonNum$[.i] = Get value: .currentWord+.i, "Lesson"
450                                         .lessonNum$[.i] = " : " + .lessonNum$[.i]
451                                 endif
452                                 .showText$[.i] = .pinyin$['.i']
453                                 if .character$['.i'] <> "-"
454                                         .showText$[.i] = .pinyin$['.i']+" ("+.character$['.i']+.lessonNum$['.i']+")"
455                                 elsif .lessonNum$['.i'] <> ""
456                                         .showText$[.i] = .pinyin$['.i']+" ( -"+.lessonNum$['.i']+")"
457                                 endif
458                                 .showValueText$[.i] = Get value: .currentWord+.i, "Show"
459                                 if .showValueText$[.i] = "-"
460                                         .showValue[.i] = 0
461                                 else
462                                         .showValue[.i] = 1
463                                 endif
464                                 .showVariable$[.i] = .pinyin$[.i]
465                                 .tmp$ = replace_regex$(.showVariable$[.i], "^(.+)$", "\l\1", 0)
466                                 '.tmp$' = .showValue[.i]
467                         else
468                                 .showText$[.i] = "-"
469                                 .showValue[.i] = 0
470                         endif
471                 endfor
473                 # The user text input window (beginPause .... endPause)
474                 beginPause(.helpText$)
475                         if sgc.allWordLists > 0
476                                 select sgc.allWordLists
477                                 .numWordlists = Get number of rows
478                                 optionMenu: .wordlistText$, 1
479                                         option: "---"
480                                         for .w to .numWordlists
481                                                 select sgc.allWordLists
482                                                 .wordListName$ = Get value: .w, "Name"
483                                                 option: .wordListName$
484                                         endfor
485                                         option: "*"+.manualEntryText$+"*"
486                         endif
487                         
488                         boolean (.showText$[0], .showValue[0])
489                         boolean (.showText$[1], .showValue[1])
490                         boolean (.showText$[2], .showValue[2])
491                         boolean (.showText$[3], .showValue[3])
492                         boolean (.showText$[4], .showValue[4])
493                         boolean (.showText$[5], .showValue[5])
494                         boolean (.showText$[6], .showValue[6])
495                         boolean (.showText$[7], .showValue[7])
496                         boolean (.showText$[8], .showValue[8])
497                         boolean (.showText$[9], .showValue[9])
498                         boolean (.showText$[10], .showValue[10])
499                         boolean (.showText$[11], .showValue[11])
500                         boolean (.showText$[12], .showValue[12])
501                         boolean (.showText$[13], .showValue[13])
502                         boolean (.showText$[14], .showValue[14])
503                         if .numLessons > 0
504                                 optionMenu: .partText$, 1
505                                         option: "---"
506                                         .j = 0
507                                         for .j to .numLessons
508                                                 option: .lessonName$['.j']
509                                         endfor
510                         endif
511                         optionMenu: .toneText$, 1
512                                 option: "---"
513                                 option: "0"
514                                 option: "1"
515                                 option: "2"
516                                 option: "3"
517                                 option: "4"
518                 clicked = endPause ("'.cancelText$'", "'.clearText$'", "'.allText$'", "'.prevWord$'", "'.nextWord$'", "'.continueText$'", 6, 1)
519                 
520                 select sgc.currentWordlist
521                 if clicked = 2
522                         for .i to sgc.numberOfWords
523                                 Set string value: .i, "Show", "-"
524                         endfor
525                         .allShown = 0
526                 elsif clicked = 3
527                         for .i to sgc.numberOfWords
528                                 Set string value: .i, "Show", "+"
529                         endfor
530                         .allShown = 1
531                 elsif clicked != 1
532                         # Handle added word lists
533                         .wordlistText$ = replace_regex$(.wordlistText$, "^(.)", "\l\1", 0)
534                         .wordlistText$ = replace_regex$(.wordlistText$, "\s", "_", 0)
535                         .tmp$ = '.wordlistText$'$
536                         if .tmp$ <> "---" and sgc.allWordLists > 0
537                                 select sgc.currentWordlist
538                                 # Add current wordlist name as  a lesson name
539                                 .originalWordList = -1
540                                 .numRows = Get number of rows
541                                 for .w to .numRows
542                                         select sgc.currentWordlist
543                                         .currentLesson$ = Get value: .w, "Lesson"
544                                         if .currentLesson$ = "" or .currentLesson$ = "-"
545                                                 Set string value: .w, "Lesson", wordlist$
546                                         endif
547                                 endfor
548                                 
549                                 # Get and merge the selected list
550                                 # Enter words by hand
551                                 if .tmp$ = "*"+.manualEntryText$+"*"
552                                         .man_clicked = 3
553                                         .currentFilePath$ = .exampleText$
554                                         .manualText$ = .manualEntryText$
555                                         .manPinyin$ = .pinyinText$
556                                         .manCharacter$ = .characterText$
557                                         .manTranslation$ = .translationText$
558                                         .manSound$ = .currentFilePath$
559                                         .manLesson$ = .manualText$
560                                         while .man_clicked > 1
561                                                 beginPause: .manualEntryText$
562                                                         text: .pinyinText$, .manPinyin$
563                                                         text: .characterText$, .manCharacter$ 
564                                                         text: .translationText$, .manTranslation$ 
565                                                         text: .exampleText$, .manSound$
566                                                         text: .manualText$, .manualText$
567                                                 .man_clicked = endPause("'.cancelText$'", "'.exampleText$'", "'.continueText$'", 3, 1)
568                                                 if .man_clicked > 1
569                                                         .tmp$ = replace_regex$(.pinyinText$, "\s", "_", 0)
570                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
571                                                         if '.tmp$'$ <> .pinyinText$ 
572                                                                 .manPinyin$ = '.tmp$'$
573                                                         else
574                                                                 # Quit
575                                                                 .man_clicked = 0
576                                                         endif
578                                                         .tmp$ = replace_regex$(.characterText$, "\s", "_", 0)
579                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
580                                                         if '.tmp$'$ <> .characterText$ 
581                                                                 .manCharacter$ = '.tmp$'$
582                                                         else
583                                                                 .manCharacter$ = ""
584                                                         endif
585                                                         
586                                                         .tmp$ = replace_regex$(.translationText$, "\s", "_", 0)
587                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
588                                                         if '.tmp$'$ <> .translationText$ 
589                                                                 .manTranslation$ = '.tmp$'$
590                                                         else
591                                                                 .manTranslation$ = ""
592                                                         endif
593                                                         
594                                                         .tmp$ = replace_regex$(.exampleText$, "\s", "_", 0)
595                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
596                                                         if '.tmp$'$ <> .characterText$ and '.tmp$'$ <> ""
597                                                                 .manSound$ = '.tmp$'$
598                                                         endif
599                                                         
600                                                         .tmp$ = replace_regex$(.manualText$, "\s", "_", 0)
601                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
602                                                         .manLesson$ = '.tmp$'$
603                                                         
604                                                         if .man_clicked = 2
605                                                                 .manSound$ = chooseReadFile$(.exampleText$);
606                                                         elsif .man_clicked = 3
607                                                                 # Clean up input string
608                                                                 .manPinyin$ = replace_regex$(.manPinyin$, "^[^a-z]+", "", 0)
609                                                                 select sgc.currentWordlist
610                                                                 Append row
611                                                                 .numRows = Get number of rows
612                                                                 if .manPinyin$ <> ""
613                                                                         Set string value: .numRows, "Pinyin", .manPinyin$
614                                                                         Set string value: .numRows, "Character", .manCharacter$
615                                                                         Set string value: .numRows, "Translation", .manTranslation$
616                                                                         Set string value: .numRows, "Sound", .manSound$
617                                                                         Set string value: .numRows, "Lesson", .manLesson$
618                                                                         Set string value: .numRows, "Show", "+"
619                                                                 endif
620                                                                 .manualText$ = .manualEntryText$
621                                                                 .manPinyin$ = .pinyinText$
622                                                                 .manCharacter$ = .characterText$
623                                                                 .manTranslation$ = .translationText$
624                                                                 .manSound$ = .currentFilePath$
625                                                                 .manLesson$ = .manualText$                                                      
626                                                         endif
627                                                 endif
628                                         endwhile                                        
629                                 else
630                                         # Existing lessons
631                                         select sgc.allWordLists
632                                         .wordlistNum = Search column: "Name", .tmp$
633                                         if .wordlistNum > 0
634                                                 .wordlistPath$ = Get value: .wordlistNum, "Directory"
635                                                 .wordlistPath$ = replace_regex$(.wordlistPath$, "[ ]", "&", 0)
636                                                 call read_wordlist "'.tmp$'" '.wordlistPath$'
637                                                 .newList = read_wordlist.wordlistID
638                                                 call merge_into_wordlist '.newList' '.tmp$'
639                                                 select .newList
640                                                 Remove
641                                                 # Add wordlistname to Lesson column
642                                                 select sgc.allWordLists
643                                                 .numRows = Get number of rows
644                                                 if .numRows > 1
645                                                         Remove row: .wordlistNum
646                                                 else
647                                                         Set string value: 1, "Name", "---"
648                                                 endif
649                                         endif
650                                 endif
651                                 # Gather Lesson names
652                                 select sgc.currentWordlist
653                                 Sort rows... Lesson Pinyin
654                                 if .lessonCol > 0
655                                         sgc.numberOfWords = Get number of rows
656                                         .lessonList$ = tab$
657                                         .numLessons = 0
658                                         .lessonName$ = ""
659                                         for .i to sgc.numberOfWords
660                                                 .currentLesson$ = Get value: .i, "Lesson"
661                                                 .matchLesson$ = tab$+.currentLesson$+tab$
662                                                 if .currentLesson$ <> "" and .currentLesson$ <> "-" and .currentLesson$ <> "?" and index(.lessonList$, .matchLesson$) <= 0
663                                                         .lessonList$ = .lessonList$ + .currentLesson$ + tab$
664                                                         .numLessons += 1
665                                                         .lessonName$['.numLessons'] = .currentLesson$
666                                                 endif
667                                                 .shown$ = Get value: .i, "Show"
668                                                 if .shown$ = "-"
669                                                         .allShown = 0
670                                                 endif
671                                         endfor
672                                 endif
673                         else                    
674                                 select sgc.currentWordlist
675                                 # Get selected Part BEFORE we do anything else
676                                 if .numLessons > 0
677                                         .tmp$ = replace_regex$(.partText$, "^(.)", "\l\1", 0)
678                                         .lessonSelected = '.tmp$' - 1
679                                 endif
680                                 if .lessonSelected > 0
681                                         .allShown = 1
682                                         .firstShown = -1
683                                         select sgc.currentWordlist
684                                         for .i to sgc.numberOfWords
685                                                 # Keep track of whether all are shown
686                                                 .shown$ = Get value: .i, "Show"
687                                                 if .shown$ = "-"
688                                                         .allShown = 0
689                                                 endif
690                                         endfor
692                                         for .i to sgc.numberOfWords
693                                                 # Lessons
694                                                 .currentLesson$ = Get value: .i, "Lesson"
695                                                 if .currentLesson$ = .lessonName$['.lessonSelected']
696                                                         Set string value: .i, "Show", "+"
697                                                 elsif .allShown = 1
698                                                         Set string value: .i, "Show", "-"
699                                                 endif
700                                         endfor
701                                         for .i to sgc.numberOfWords
702                                                 # Keep track of whether all are shown
703                                                 .shown$ = Get value: .i, "Show"
704                                                 if .firstShown <=0 and .shown$ <> "-"
705                                                         .firstShown = .i
706                                                 endif
707                                         endfor
708                                 else
709                                         for .i from 0 to .max
710                                                 .tmp$ = replace_regex$(.showVariable$['.i'], "^(.*)$", "\l\1", 0)
711                                                 .showValue['.i'] = '.tmp$'
712                                                 .showWord$['.i'] = "-"
713                                                 if .showValue['.i'] <> 0
714                                                         .showWord$['.i'] = "+"
715                                                 endif
716                                                 Set string value: .currentWord+.i, "Show", .showWord$['.i']
717                                         endfor
718                                 endif
719                         endif
720                         
721                         select sgc.currentWordlist
722                         .tmp$ = replace_regex$(.toneText$, "^(.)", "\l\1", 0)
723                         .toneSelected = '.tmp$' - 2
724                         if .toneSelected >= 0
725                                 select sgc.currentWordlist
726                                 for .i to sgc.numberOfWords
727                                         .currentPinyin$ = Get value: .i, "Pinyin"
728                                         if index_regex(.currentPinyin$, "[0-9]") <= 0
729                                                 call pinyin2numbers '.currentPinyin$'
730                                                 .currentPinyin$ = replace_regex$(pinyin2numbers.intermediatePinyin$, ".+", "\l&", 0)
731                                                 .currentPinyin$ = replace_regex$(.currentPinyin$, "[^a-zA-Z0-9]", "", 0)
732                                         endif
733                                         .tmp$ = Get value: .i, "Show"
734                                         if .tmp$ <> "-" and index(.currentPinyin$, "'.toneSelected'") > 0
735                                                 Set string value: .i, "Show", "+"
736                                         else
737                                                 Set string value: .i, "Show", "-"
738                                                 .allShown = 0
739                                         endif
740                                 endfor
741                         endif
742                         
743                         if clicked = 4
744                                 if .firstShown > 0
745                                         .currentWord = (.firstShown div .numWordsPerScreen) * .numWordsPerScreen + 1
746                                 elsif .toneSelected < 0
747                                         .currentWord -= .numWordsPerScreen
748                                 endif
749                                 if .currentWord <= 0
750                                         .currentWord = (sgc.numberOfWords div .numWordsPerScreen) * .numWordsPerScreen + 1
751                                 endif
752                         elsif clicked = 5
753                                 if .firstShown > 0
754                                         .currentWord = (.firstShown div .numWordsPerScreen) * .numWordsPerScreen + 1
755                                 elsif .toneSelected < 0
756                                         .currentWord += .numWordsPerScreen
757                                 endif
758                                 if .currentWord > sgc.numberOfWords
759                                         .currentWord = 1
760                                 endif
761                         endif
762                 endif
763                 # Reset and go to the first selected word (can shuffle list)
764                 if clicked = 6
765                         sgc.currentWord = -1
766                         call next_word
767                         call init_window
768                 endif
769         endwhile
770         
771     # Implement Cancel
772     if clicked = 1
773                 select sgc.currentWordlist
774                 Remove
775                 select .tmpOriginalWordlist
776                 Copy: wordlist$
777                 sgc.currentWordlist = selected()
778         else
779                 # Set the values of the number of words shown   
780                 select sgc.currentWordlist
781                 .numWords = Get number of rows
782                 sgc.currentWordNum = 1
783                 sgc.numberOfDisplayedWords = 0
784                 sgc.currentWord = 0
785                 for .i to .numWords
786                         .show$ = Get value: .i, "Show"
787                         if .show$ = "+"
788                                 if sgc.currentWord < 1
789                                         sgc.currentWord = .i
790                                 endif
791                                 sgc.numberOfDisplayedWords += 1
792                         endif
793                 endfor
794         endif
795         select .tmpOriginalWordlist
796         Remove
798     call Draw_button '.table$' '.label$' 0
799 endproc
801 ###############################################################
803 # Obligatory button Processing Routines
805 # These MUST be defined
807 ###############################################################
809 procedure processMainPageQuit .clickX .clickY .pressed$
810         call end_program
811 endproc
813 procedure processMainPageRefresh .clickX .clickY .pressed$
814         call clean_up_sound
815         call init_window
816 endproc
818 procedure processMainPageConfig .clickX .clickY .pressed$
819         call config_page
820 endproc
822 procedure processMainPageHelp .clickX .clickY .pressed$
823         call help_loop 'buttons$' init_window
824 endproc
826 procedure processMainPagePlay .clickX .clickY .pressed$
827         .table$ = "MainPage"
828         .label$ = "Play"
829         if recordedSound$ <> ""
830                 call play_sound 'sgc.recordedSound'
831                 mainPage.play = 0
832         endif
833         te.buttonPressValue = mainPage.play
834 endproc
836 procedure Set_Play_Button
837         mainPage.play = -1
838         if recordedSound$ <> ""
839                 mainPage.play = 0
840     endif       
841         call Draw_button MainPage Play 'mainPage.play'
842 endproc
844 procedure processMainPageRecord .clickX .clickY .pressed$
845         call count_syllables
846         .recordingTime = recordingTime
847         if count_syllables.number > 2
848                 .recordingTime = recordingTime + 1.0*ceiling((count_syllables.number - 2)/2)
849         endif
850     call record_sound '.recordingTime'
851     call recognizeTone
852         mainPage.play = 0
853         call Set_Play_Button
855     # Wipe screen
856     call wipeArea 'wipeContourArea$'
857    
858     call draw_tone_contour
859     # Write text (again)
860     call display_word_list_name
861     call display_text Black
862         call add_feedback_to_toneevaluation Feedback
863     call write_feedback Feedback
864         select Table Feedback
865         Remove
866         
867         # Do not exercise words that are going well (autoSelect)
868     if add_feedback_to_toneevaluation.result > 0
869                 if config.adaptiveLists > 0 and sgc.failedAttempts < 2
870                         # Deselect current word
871                         select sgc.currentWordlist
872                         .i = Search column: "Pinyin", sgc.pinyin$
873                         if .i > 0
874                                 Set string value: .i, "Show", "-"
875                         endif
876                 endif
877                 sgc.failedAttempts = 0
878     else
879                 sgc.failedAttempts += 1
880     endif
881 endproc
884 ###############################################################
886 # Miscelaneous supporting code
888 ###############################################################
890 # The example
891 procedure generate_example
892         select sgc.currentWordlist
893         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
894                 select sgc.currentWordlist
895                 .sound$ = Get value... 'sgc.currentWord' Sound
896                 call readPinyin 'sgc.currentWord'
897                 sgc.pinyin$ = readPinyin.pinyin$
898                 if .sound$ = "-" or .sound$ = ""
899                         .sound$ = sgc.pinyin$+".wav"
900                 endif
901                 if index_regex(.sound$, "^(/|~/|[A-Z]:\\)") > 0
902                         .soundFilePath$ = .sound$
903                 else
904                         .soundFilePath$ = localWordlistDir$+"/"+wordlistName$+"/"+.sound$
905                         .wordlistDirectory$ = ""
906                         if localWordlistDir$ <> "" and fileReadable("'localWordlistDir$'/'wordlistName$'")
907                                 .wordlistDirectory$ = "'localWordlistDir$'/'wordlistName$'"
908                         elsif sgc2wordlists$ <> "" and fileReadable("'sgc2wordlists$'/'wordlistName$'")
909                                 .wordlistDirectory$ = "'sgc2wordlists$'/'wordlistName$'"
910                         elsif globalwordlists$ <> "" and fileReadable("'globalwordlists$'/'wordlistName$'")
911                                 .wordlistDirectory$ = "'globalwordlists$'/'wordlistName$'"
912                         endif
913                         if .wordlistDirectory$ <> ""
914                                 .audioExampleList = Create Strings as file list... AudioList '.wordlistDirectory$'/'sgc.pinyin$'.*
915                                 .number_of_examples = Get number of strings
916                                 if .number_of_examples > 0
917                                         Randomize
918                                         .sound$ = Get string... 1
919                                         .soundFilePath$ = "'.wordlistDirectory$'/'.sound$'"
920                                 endif
921                                 Remove
922                         endif
923                 endif
924                 if fileReadable(.soundFilePath$) and config.useSoundExample
925                         .tmp = -1
926                         .tmp = nocheck Read from file... '.soundFilePath$'
927                         if .tmp != undefined and .tmp > 0
928                                 call play_sound '.tmp'
929                                 select .tmp
930                                 Remove
931                         endif
932                 elsif config.synthesis$ <> "" and config.synthesis$ <> "_DISABLED_"
933                         call synthesize_sound 'sgc.pinyin$'
934                 else
935                         call humToneContour 'sgc.pinyin$' 'config.register'
936                         call reset_viewport
937                 endif
938         endif
939         demoShow()
940 endproc
942 # Draw a tone contour
943 procedure draw_tone_contour
944         select sgc.currentWordlist
945         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
946                 .sound$ = Get value... 'sgc.currentWord' Sound
947                 call readPinyin 'sgc.currentWord'
948                 sgc.pinyin$ = readPinyin.pinyin$
949                 call drawToneContour 'sgc.pinyin$' 'config.register'
950                 call reset_viewport
951                 
952                 if te.recordedPitch > 0
953                         call drawSourceToneContour te.recordedPitch
954                 endif
955         endif
957 endproc
959 procedure recognizeTone
960         select sgc.currentWordlist
961         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
962                 .strict = 0
963                 if index_regex(config.strict$, "[^0-9]") <= 0
964                         .strict = ('config.strict$' >= sgc.highestLevel)
965                 endif
966                         
967                 .sound$ = Get value... 'sgc.currentWord' Sound
968                 call readPinyin 'sgc.currentWord'
969                 sgc.pinyin$ = readPinyin.pinyin$
970                 call align_recordedSound 'sgc.pinyin$'
971         call sgc_ToneProt 'recordedSound$' 'sgc.pinyin$' 'config.register' '.strict' 'config.language$'
972         # sgc_ToneProt manipulates the sound given. Reconnect
973         select Sound 'recordedSound$'
974         sgc.recordedSound = selected("Sound")
975                 call reset_viewport
976         endif
977 endproc
979 procedure write_feedback .table$
980     select Table '.table$'
981     .line1$ = Get value... 1 Text
982     .line2$ = Get value... 2 Text
983     .label$ = Get value... 3 Text
985         # convert numbers to Pinyin if needed
986         if not config.displayNumbers
987                 call numbers2pinyin '.line1$'
988                 .line1$ = numbers2pinyin.pinyin$
989         endif
991     .color$ = "Red"
992     if index(.line1$, "???") > 0
993         .color$ = "Black"
994     elsif .label$ = "Correct"
995         .color$ = "Green"
996         elsif config.strict$ = "'sgc.highestLevel'"
997                 .line2$ = .line2$ + " *"
998     endif
1000         .currentFeedbackFontSize = 14
1001         .maxHeight = 21 - 17
1002         call adjustFontSizeOnHeight 'defaultFont$' '.currentFeedbackFontSize' '.maxHeight'
1003         .currentFeedbackFontSize = adjustFontSizeOnHeight.newFontSize
1004         
1005         call wipeArea 'wipeFeedbackArea$'
1006     call set_font_size '.currentFeedbackFontSize'
1007     demo '.color$'
1008     demo Text... 50 Centre 21 Bottom '.line1$'
1009     demo Text... 50 Centre 17 Bottom '.line2$'
1010         demoShow()
1011         demo 'defaultFont$'
1012     call set_font_size 'defaultFontSize'
1013 endproc
1015 # Text display
1016 procedure display_text .color$
1017         select sgc.currentWordlist
1018         if sgc.currentWord < 0 or sgc.currentWord > sgc.numberOfWords+1
1019                 call clean_up_sound
1020         if config.shuffleLists
1021                     Randomize rows
1022         endif
1023                 if sgc.currentWord < 0
1024                         sgc.currentWord = sgc.numberOfWords
1025                 else
1026                         sgc.currentWord = 1
1027                 endif
1028         endif
1029         
1030         .changeCJKstyle = 0
1031         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
1032                 .displayText$ = ""
1033                 call readDisplayPinyin 'sgc.currentWord'
1034                 .displayPinyin$ = readDisplayPinyin.pinyin$
1035                 .displayChar$ = Get value... 'sgc.currentWord' Character
1036                 .displayTrans$ = Get value... 'sgc.currentWord' Translation
1037                 if .displayPinyin$ <> "-" and (config.displayPinyin or sgc.writeAll)
1038                         if not config.displayNumbers
1039                                 call numbers2pinyin '.displayPinyin$'
1040                                 .displayPinyin$ = numbers2pinyin.pinyin$
1041                         endif
1042                         # Insert u umlaut
1043                         .displayPinyin$ = replace_regex$(.displayPinyin$, "v", "\\u\X22", 0)
1044                         .displayText$ = .displayText$ + .displayPinyin$
1045                 endif
1046                 if .displayChar$ <> "-" and (config.displayChar or sgc.writeAll)
1047                         .displayText$ = .displayText$ + "  "+ .displayChar$
1048                         .changeCJKstyle = 1
1049                 endif
1050                 if .displayTrans$ <> "-" and (config.displayTrans or sgc.writeAll)
1051                         .displayText$ = .displayText$ + "  \s{%%"+ .displayTrans$ + "%}"
1052                 endif
1053         elsif sgc.currentWord = 0 or sgc.currentWord = sgc.numberOfWords+1
1054                 call clean_up_sound
1055                 .displayText$ = "---"
1056         endif
1058         # Adapt font size
1059         call adjustFontSizeOnHeight 'defaultFont$' 24 15
1060         .currentFontSize = adjustFontSizeOnHeight.newFontSize
1061         call adjustFontSizeOnWidth 'defaultFont$' '.currentFontSize' 95 '.displayText$'
1062         .currentFontSize = adjustFontSizeOnWidth.newFontSize
1064         # Clear the writing area
1065         call wipeArea 'wipePinyinArea$'
1066         # Switch back to Chinese style CJK when in Japanese language mode
1067         if .changeCJKstyle and config.language$ = "JA"
1068                 CJK font style preferences: "Chinese"
1069         endif
1070         # Actually display text
1071         demo '.color$'
1072         call set_font_size '.currentFontSize'
1073         demo Text... 50 Centre 26 Bottom '.displayText$'
1074         demoShow()
1075         demo Black
1076         demo 'defaultFont$'
1077         call set_font_size 'defaultFontSize'
1078         if .changeCJKstyle and config.language$ = "JA"
1079                 if config.language$ = "JA"
1080                         CJK font style preferences: "Japanese"
1081                 elsif config.language$ = "ZH"
1082                         CJK font style preferences: "Chinese"
1083                 endif
1084         endif
1085         # Switch back to Japanese style CJK when in Japanese language mode
1086         if .changeCJKstyle and config.language$ = "JA"
1087                 CJK font style preferences: "Japanese"
1088         endif
1089 endproc
1091 procedure numbers2pinyin .numberstext$
1092         .intermediatePinyin$ = .numberstext$
1093         # Add a `-quote between vowels
1094         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])([aeuiov])", "\1\2'\3", 0)
1095         # Move numbers to the nucleus vowel
1096         # To the vowel
1097         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([^aeuiov0-9]*)([0-9])", "\1\3\2", 0)
1098         # Either a/e
1099         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([ae])([aeuiov]*)([0-9])", "\1\3\2", 0)
1100         # Or the Oo in /ou/
1101         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(ou)([0-9])", "o\2u", 0)
1102         # or the second vowel
1103         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([uiov][aeuiov])([uiov])([0-9])", "\1\3\2", 0)
1104         
1105         # Convert all tones to special characters
1106         # Tone 1
1107         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "a1", "ā", 0)
1108         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e1", "ē", 0)
1109         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "u1", "ū", 0)
1110         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i1", "ī", 0)
1111         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o1", "ō", 0)
1112         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v1", "ǖ", 0)
1113         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "1", "\\-^", 0)
1114         
1115         # Tone 2
1116         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v2", "ǘ", 0)
1117         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([iaeou])2", "\\\1'", 0)
1118         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "2", "\\'^", 0)
1119         
1120         # Tone 3
1121         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "a3", "ǎ", 0)
1122         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e3", "ě", 0)
1123         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "u3", "ǔ", 0)
1124         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i3", "ǐ", 0)
1125         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o3", "ǒ", 0)
1126         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v3", "ǚ", 0)
1127         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "3", "\\N^", 0)
1129         # Tone 4
1130         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v4", "ǜ", 0)
1131         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([iaeou])4", "\\\1`", 0)
1132         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "4", "\\`^", 0)
1133         
1134         # Tone 0
1135         # Remove tone 0 symbol completely
1136         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "0", "", 0)
1137         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "a0", "å", 0)
1138         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e0", "e̊", 0)
1139         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "u0", "ů", 0)
1140         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i0", "i̊", 0)
1141         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o0", "o̊", 0)
1142         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v0", "ü̊", 0)
1143         #.intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "0", "\\0^", 0)
1144         
1145         # Pick best vowel symbols available in cases not caught before
1146         # Ugly clutch to get the 1, 3, 0 tone diacritics at least in the neighbourhood
1147         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i(\\[-N0]\^)", "i\\s{_ }\1", 0)
1148         # Insert u umlaut
1149         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v", "\\u\X22", 0)
1151         .pinyin$ = .intermediatePinyin$
1152 endproc
1154 # NEEDS WORK AND TESTING!!
1155 # Convert unicode Pinyin into tone numbers
1156 procedure pinyin2numbers .pinyin$
1157         .intermediatePinyin$ = .pinyin$
1158         # Convert all special characters to numbers
1159         # Tone 1
1160         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iā)([iaeouü]*)", "a\11", 0)
1161         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iē)([iaeouü]*)", "e\11", 0)
1162         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iū)([iaeouü]*)", "u\11", 0)
1163         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iī)([iaeouü]*)", "i\11", 0)
1164         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iō)([iaeouü]*)", "o\11", 0)
1165         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǖ)([iaeouü]*)", "v\11", 0)
1166         
1167         # Tone 2
1168         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iá)([iaeouü]*)", "a\12", 0)
1169         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ié)([iaeouü]*)", "e\12", 0)
1170         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iú)([iaeouü]*)", "u\12", 0)
1171         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ií)([iaeouü]*)", "i\12", 0)
1172         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ió)([iaeouü]*)", "o\12", 0)
1173         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǘ)([iaeouü]*)", "v\12", 0)
1174         
1175         # Tone 3
1176         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǎ)([iaeouü]*)", "a\13", 0)
1177         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iě)([iaeouü]*)", "e\13", 0)
1178         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǔ)([iaeouü]*)", "u\13", 0)
1179         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǐ)([iaeouü]*)", "i\13", 0)
1180         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǒ)([iaeouü]*)", "o\13", 0)
1181         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǚ)([iaeouü]*)", "v\13", 0)
1183         # Tone 4
1184         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ià)([iaeouü]*)", "a\14", 0)
1185         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iè)([iaeouü]*)", "e\14", 0)
1186         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iù)([iaeouü]*)", "u\14", 0)
1187         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iì)([iaeouü]*)", "i\14", 0)
1188         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iò)([iaeouü]*)", "o\14", 0)
1189         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǜ)([iaeouü]*)", "v\14", 0)
1190         
1191         # Tone 0
1192         # Add tone 0
1193         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iå)([iaeouü]*)", "a\10", 0)
1194         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e̊([iaeouü]*)", "e\10", 0)
1195         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iů)([iaeouü]*)", "u\10", 0)
1196         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i̊([iaeouü]*)", "i\10", 0)
1197         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o̊([iaeouü]*)", "o\10", 0)
1198         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "ü̊([iaeouü]*)", "v\10", 0)
1200         # Syllables without a tone symbol are tone 0
1201         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov]+)([^0-9aeuiov]|\W|$)", "\10\2", 0)
1203         # Move numbers to the end of the syllable.
1204         # Syllables ending in n and start with g. Note that a syllable cannot start with an u or i
1205         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])(n)(g[aeuiov])", "\1\3\2\4", 0)
1206         # Syllables ending in (ng?) followed by something that is not a valid vowel 
1207         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])(ng?)([^aeuiov]|\W|$)", "\1\3\2\4", 0)
1208         # Syllables ending in r
1209         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])(r)([^aeuiov]|\W|$)", "\1\3\2\4", 0)
1210         # Remove quotes etc
1211         #.intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "[\\'\\`]", "", 0)
1212         
1213         .numberstext$ = .intermediatePinyin$
1214 endproc
1216 procedure readDisplayPinyin .currentWord
1217         select sgc.currentWordlist
1218         .pinyin$ = Get value... '.currentWord' Pinyin
1219         # Everything to lowercase
1221         if index_regex(.pinyin$, "[0-9]") <= 0
1222                 call pinyin2numbers '.pinyin$'
1223                 .pinyin$ = pinyin2numbers.numberstext$
1224         endif 
1225 endproc
1227 procedure readPinyin .currentWord
1228         call readDisplayPinyin '.currentWord'
1229         .pinyin$ = replace_regex$(readDisplayPinyin.pinyin$, ".+", "\L&", 0)
1230         .pinyin$ = replace_regex$(.pinyin$, "[\\'\\` ]", "", 0)
1231         # Remove anything that is objectionable
1232         .pinyin$ = replace_regex$(.pinyin$, "[^\w']", "", 0)
1233 endproc
1235 # Includes
1236 include ToneProt/SGC_ToneProt.praat
1237 include ToneProt/DrawToneContour.praat
1238 include ToneProt/HumToneContour.praat
1239 include ToneProt/ToneRecognition.praat
1240 include ToneProt/ToneScript.praat
1241 include ToneProt/ToneRules.praat