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