Worked on adding manual word entry to current wordlist
[sgc2.git] / MainPage.praat
blob3b5059d315839a85d0b5e3bf0956b636f50f2d85
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 > 0
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                                 if .numWordlists > 0
431                                         optionMenu: .wordlistText$, 1
432                                                 option: "---"
433                                                 for .w to .numWordlists
434                                                         select sgc.allWordLists
435                                                         .wordListName$ = Get value: .w, "Name"
436                                                         option: .wordListName$
437                                                 endfor
438                                                 option: "*"+.manualEntryText$+"*"
439                                 endif
440                         endif
441                         
442                         boolean (.showText$[0], .showValue[0])
443                         boolean (.showText$[1], .showValue[1])
444                         boolean (.showText$[2], .showValue[2])
445                         boolean (.showText$[3], .showValue[3])
446                         boolean (.showText$[4], .showValue[4])
447                         boolean (.showText$[5], .showValue[5])
448                         boolean (.showText$[6], .showValue[6])
449                         boolean (.showText$[7], .showValue[7])
450                         boolean (.showText$[8], .showValue[8])
451                         boolean (.showText$[9], .showValue[9])
452                         boolean (.showText$[10], .showValue[10])
453                         boolean (.showText$[11], .showValue[11])
454                         boolean (.showText$[12], .showValue[12])
455                         boolean (.showText$[13], .showValue[13])
456                         boolean (.showText$[14], .showValue[14])
457                         if .numLessons > 0
458                                 optionMenu: .partText$, 1
459                                         option: "---"
460                                         .j = 0
461                                         for .j to .numLessons
462                                                 option: .lessonName$['.j']
463                                         endfor
464                         endif
465                         optionMenu: .toneText$, 1
466                                 option: "---"
467                                 option: "0"
468                                 option: "1"
469                                 option: "2"
470                                 option: "3"
471                                 option: "4"
472                 clicked = endPause ("'.cancelText$'", "'.clearText$'", "'.allText$'", "'.prevWord$'", "'.nextWord$'", "'.continueText$'", 6, 1)
473                 
474                 select sgc.currentWordlist
475                 if clicked = 2
476                         for .i to sgc.numberOfWords
477                                 Set string value: .i, "Show", "-"
478                         endfor
479                         .allShown = 0
480                 elsif clicked = 3
481                         for .i to sgc.numberOfWords
482                                 Set string value: .i, "Show", "+"
483                         endfor
484                         .allShown = 1
485                 elsif clicked != 1
486                         # Handle added word lists
487                         .wordlistText$ = replace_regex$(.wordlistText$, "^(.)", "\l\1", 0)
488                         .wordlistText$ = replace_regex$(.wordlistText$, "\s", "_", 0)
489                         .tmp$ = '.wordlistText$'$
490                         if .tmp$ <> "---" and sgc.allWordLists > 0
491                                 select sgc.currentWordlist
492                                 # Add current wordlist name as  a lesson name
493                                 .originalWordList = -1
494                                 .numRows = Get number of rows
495                                 for .w to .numRows
496                                         select sgc.currentWordlist
497                                         .currentLesson$ = Get value: .w, "Lesson"
498                                         if .currentLesson$ = "" or .currentLesson$ = "-"
499                                                 Set string value: .w, "Lesson", wordlist$
500                                         endif
501                                 endfor
502                                 
503                                 # Get and merge the selected list
504                                 # Enter words by hand
505                                 if .tmp$ = "*"+.manualEntryText$+"*"
506                                         .man_clicked = 3
507                                         .currentFilePath$ = .exampleText$
508                                         .manualText$ = .manualEntryText$
509                                         .manPinyin$ = .pinyinText$
510                                         .manCharacter$ = .characterText$
511                                         .manTranslation$ = .translationText$
512                                         .manSound$ = .currentFilePath$
513                                         .manLesson$ = .manualText$
514                                         while .man_clicked > 1
515                                                 beginPause: .manualEntryText$
516                                                         text: .pinyinText$, .manPinyin$
517                                                         text: .characterText$, .manCharacter$ 
518                                                         text: .translationText$, .manTranslation$ 
519                                                         text: .exampleText$, .manSound$
520                                                         text: .manualText$, .manualText$
521                                                 .man_clicked = endPause("'.cancelText$'", "'.exampleText$'", "'.continueText$'", 3, 1)
522                                                 if .man_clicked > 1
523                                                         .tmp$ = replace_regex$(.pinyinText$, "\s", "_", 0)
524                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
525                                                         if '.tmp$'$ <> .pinyinText$ 
526                                                                 .manPinyin$ = '.tmp$'$
527                                                         else
528                                                                 # Quit
529                                                                 .man_clicked = 0
530                                                         endif
532                                                         .tmp$ = replace_regex$(.characterText$, "\s", "_", 0)
533                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
534                                                         if '.tmp$'$ <> .characterText$ 
535                                                                 .manCharacter$ = '.tmp$'$
536                                                         endif
537                                                         
538                                                         .tmp$ = replace_regex$(.translationText$, "\s", "_", 0)
539                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
540                                                         if '.tmp$'$ <> .translationText$ 
541                                                                 .manTranslation$ = '.tmp$'$
542                                                         endif
543                                                         
544                                                         .tmp$ = replace_regex$(.exampleText$, "\s", "_", 0)
545                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
546                                                         if '.tmp$'$ <> .characterText$ and '.tmp$'$ <> ""
547                                                                 .manSound$ = '.tmp$'$
548                                                         endif
549                                                         
550                                                         .tmp$ = replace_regex$(.manualText$, "\s", "_", 0)
551                                                         .tmp$ = replace_regex$(.tmp$, "^(.+)$", "\l\1", 0)
552                                                         .manLesson$ = '.tmp$'$
553                                                         
554                                                         if .man_clicked = 2
555                                                                 .manSound$ = chooseReadFile$(.exampleText$);
556                                                         elsif .man_clicked = 3
557                                                                 select sgc.currentWordlist
558                                                                 Append row
559                                                                 .numRows = Get number of rows
560                                                                 if .manPinyin$ <> ""
561                                                                         Set string value: .numRows, "Pinyin", .manPinyin$
562                                                                         Set string value: .numRows, "Character", .manCharacter$
563                                                                         Set string value: .numRows, "Translation", .manTranslation$
564                                                                         Set string value: .numRows, "Sound", .manSound$
565                                                                         Set string value: .numRows, "Lesson", .manLesson$
566                                                                 endif
567                                                                 .manualText$ = .manualEntryText$
568                                                                 .manPinyin$ = .pinyinText$
569                                                                 .manCharacter$ = .characterText$
570                                                                 .manTranslation$ = .translationText$
571                                                                 .manSound$ = .currentFilePath$
572                                                                 .manLesson$ = .manualText$                                                      
573                                                         endif
574                                                 endif
575                                         endwhile
576                                 else
577                                         # Existing lessons
578                                         select sgc.allWordLists
579                                         .wordlistNum = Search column: "Name", .tmp$
580                                         if .wordlistNum > 0
581                                                 .wordlistPath$ = Get value: .wordlistNum, "Directory"
582                                                 .wordlistPath$ = replace_regex$(.wordlistPath$, "[ ]", "&", 0)
583                                                 call read_wordlist "'.tmp$'" '.wordlistPath$'
584                                                 .newList = read_wordlist.wordlistID
585                                                 call merge_into_wordlist '.newList' '.tmp$'
586                                                 select .newList
587                                                 Remove
588                                                 # Add wordlistname to Lesson column
589                                                 select sgc.allWordLists
590                                                 .numRows = Get number of rows
591                                                 if .numRows > 1
592                                                         Remove row: .wordlistNum
593                                                 else
594                                                         Set string value: 1, "Name", "---"
595                                                 endif
596                                         endif
597                                 endif
598                                 # Gather Lesson names
599                                 select sgc.currentWordlist
600                                 Sort rows... Lesson Pinyin
601                                 if .lessonCol > 0
602                                         sgc.numberOfWords = Get number of rows
603                                         .lessonList$ = tab$
604                                         .numLessons = 0
605                                         .lessonName$ = ""
606                                         for .i to sgc.numberOfWords
607                                                 .currentLesson$ = Get value: .i, "Lesson"
608                                                 .matchLesson$ = tab$+.currentLesson$+tab$
609                                                 if .currentLesson$ <> "" and .currentLesson$ <> "-" and .currentLesson$ <> "?" and index(.lessonList$, .matchLesson$) <= 0
610                                                         .lessonList$ = .lessonList$ + .currentLesson$ + tab$
611                                                         .numLessons += 1
612                                                         .lessonName$['.numLessons'] = .currentLesson$
613                                                 endif
614                                                 .shown$ = Get value: .i, "Show"
615                                                 if .shown$ = "-"
616                                                         .allShown = 0
617                                                 endif
618                                         endfor
619                                 endif
620                         else                    
621                                 select sgc.currentWordlist
622                                 # Get selected Part BEFORE we do anything else
623                                 if .numLessons > 0
624                                         .tmp$ = replace_regex$(.partText$, "^(.)", "\l\1", 0)
625                                         .lessonSelected = '.tmp$' - 1
626                                 endif
627                                 if .lessonSelected > 0
628                                         .allShown = 1
629                                         .firstShown = -1
630                                         select sgc.currentWordlist
631                                         for .i to sgc.numberOfWords
632                                                 # Keep track of whether all are shown
633                                                 .shown$ = Get value: .i, "Show"
634                                                 if .shown$ = "-"
635                                                         .allShown = 0
636                                                 endif
637                                         endfor
639                                         for .i to sgc.numberOfWords
640                                                 # Lessons
641                                                 .currentLesson$ = Get value: .i, "Lesson"
642                                                 if .currentLesson$ = .lessonName$['.lessonSelected']
643                                                         Set string value: .i, "Show", "+"
644                                                 elsif .allShown = 1
645                                                         Set string value: .i, "Show", "-"
646                                                 endif
647                                         endfor
648                                         for .i to sgc.numberOfWords
649                                                 # Keep track of whether all are shown
650                                                 .shown$ = Get value: .i, "Show"
651                                                 if .firstShown <=0 and .shown$ <> "-"
652                                                         .firstShown = .i
653                                                 endif
654                                         endfor
655                                 else
656                                         for .i from 0 to .max
657                                                 .tmp$ = replace_regex$(.showVariable$['.i'], "^(.*)$", "\l\1", 0)
658                                                 .showValue['.i'] = '.tmp$'
659                                                 .showWord$['.i'] = "-"
660                                                 if .showValue['.i'] <> 0
661                                                         .showWord$['.i'] = "+"
662                                                 endif
663                                                 Set string value: .currentWord+.i, "Show", .showWord$['.i']
664                                         endfor
665                                 endif
666                         endif
667                         
668                         select sgc.currentWordlist
669                         .tmp$ = replace_regex$(.toneText$, "^(.)", "\l\1", 0)
670                         .toneSelected = '.tmp$' - 2
671                         if .toneSelected >= 0
672                                 select sgc.currentWordlist
673                                 for .i to sgc.numberOfWords
674                                         .currentPinyin$ = Get value: .i, "Pinyin"
675                                         if index_regex(.currentPinyin$, "[0-9]") <= 0
676                                                 call pinyin2numbers '.currentPinyin$'
677                                                 .currentPinyin$ = replace_regex$(pinyin2numbers.intermediatePinyin$, ".+", "\l&", 0)
678                                                 .currentPinyin$ = replace_regex$(.currentPinyin$, "[^a-zA-Z0-9]", "", 0)
679                                         endif
680                                         .tmp$ = Get value: .i, "Show"
681                                         if .tmp$ <> "-" and index(.currentPinyin$, "'.toneSelected'") > 0
682                                                 Set string value: .i, "Show", "+"
683                                         else
684                                                 Set string value: .i, "Show", "-"
685                                                 .allShown = 0
686                                         endif
687                                 endfor
688                         endif
689                         
690                         if clicked = 4
691                                 if .firstShown > 0
692                                         .currentWord = (.firstShown div .numWordsPerScreen) * .numWordsPerScreen + 1
693                                 elsif .toneSelected < 0
694                                         .currentWord -= .numWordsPerScreen
695                                 endif
696                                 if .currentWord <= 0
697                                         .currentWord = (sgc.numberOfWords div .numWordsPerScreen) * .numWordsPerScreen + 1
698                                 endif
699                         elsif clicked = 5
700                                 if .firstShown > 0
701                                         .currentWord = (.firstShown div .numWordsPerScreen) * .numWordsPerScreen + 1
702                                 elsif .toneSelected < 0
703                                         .currentWord += .numWordsPerScreen
704                                 endif
705                                 if .currentWord > sgc.numberOfWords
706                                         .currentWord = 1
707                                 endif
708                         endif
709                 endif
710                 # Reset and go to the first selected word (can shuffle list)
711                 if clicked = 6
712                         sgc.currentWord = -1
713                         call next_word
714                         call init_window
715                 endif
716         endwhile
717         
718     # Implement Cancel
719     if clicked = 1
720                 select sgc.currentWordlist
721                 Remove
722                 select .tmpOriginalWordlist
723                 Copy: wordlist$
724                 sgc.currentWordlist = selected()
725         endif
726         select .tmpOriginalWordlist
727         Remove
728     call Draw_button '.table$' '.label$' 0
729 endproc
731 ###############################################################
733 # Obligatory button Processing Routines
735 # These MUST be defined
737 ###############################################################
739 procedure processMainPageQuit .clickX .clickY .pressed$
740         call end_program
741 endproc
743 procedure processMainPageRefresh .clickX .clickY .pressed$
744         call clean_up_sound
745         call init_window
746 endproc
748 procedure processMainPageConfig .clickX .clickY .pressed$
749         call config_page
750 endproc
752 procedure processMainPageHelp .clickX .clickY .pressed$
753         call help_loop 'buttons$' init_window
754 endproc
756 procedure processMainPagePlay .clickX .clickY .pressed$
757         .table$ = "MainPage"
758         .label$ = "Play"
759         if recordedSound$ <> ""
760                 call play_sound 'sgc.recordedSound'
761                 mainPage.play = 0
762         endif
763         te.buttonPressValue = mainPage.play
764 endproc
766 procedure Set_Play_Button
767         mainPage.play = -1
768         if recordedSound$ <> ""
769                 mainPage.play = 0
770     endif       
771         call Draw_button MainPage Play 'mainPage.play'
772 endproc
774 procedure processMainPageRecord .clickX .clickY .pressed$
775         call count_syllables
776         .recordingTime = recordingTime
777         if count_syllables.number > 2
778                 .recordingTime = recordingTime + 1.0*ceiling((count_syllables.number - 2)/2)
779         endif
780     call record_sound '.recordingTime'
781     call recognizeTone
782         mainPage.play = 0
783         call Set_Play_Button
785     # Wipe screen
786     call wipeArea 'wipeContourArea$'
787    
788     call draw_tone_contour
789     # Write text (again)
790     call display_word_list_name
791     call display_text Black
792         call add_feedback_to_toneevaluation Feedback
793     call write_feedback Feedback
794         select Table Feedback
795         Remove
796         
797         # Do not exercise words that are going well (autoSelect)
798     if add_feedback_to_toneevaluation.result > 0
799                 if config.adaptiveLists > 0 and sgc.failedAttempts < 2
800                         # Deselect current word
801                         select sgc.currentWordlist
802                         .i = Search column: "Pinyin", sgc.pinyin$
803                         if .i > 0
804                                 Set string value: .i, "Show", "-"
805                         endif
806                 endif
807                 sgc.failedAttempts = 0
808     else
809                 sgc.failedAttempts += 1
810     endif
811 endproc
814 ###############################################################
816 # Miscelaneous supporting code
818 ###############################################################
820 # The example
821 procedure generate_example
822         select sgc.currentWordlist
823         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
824                 select sgc.currentWordlist
825                 .sound$ = Get value... 'sgc.currentWord' Sound
826                 call readPinyin 'sgc.currentWord'
827                 sgc.pinyin$ = readPinyin.pinyin$
828                 if .sound$ = "-" or .sound$ = ""
829                         .sound$ = sgc.pinyin$+".wav"
830                 endif
831                 if index_regex(.sound$, "^(/|~/|[A-Z]:\\)") > 0
832                         .soundFilePath$ = .sound$
833                 else
834                         .soundFilePath$ = localWordlistDir$+"/"+wordlistName$+"/"+.sound$
835                         .wordlistDirectory$ = ""
836                         if localWordlistDir$ <> "" and fileReadable("'localWordlistDir$'/'wordlistName$'")
837                                 .wordlistDirectory$ = "'localWordlistDir$'/'wordlistName$'"
838                         elsif sgc2wordlists$ <> "" and fileReadable("'sgc2wordlists$'/'wordlistName$'")
839                                 .wordlistDirectory$ = "'sgc2wordlists$'/'wordlistName$'"
840                         elsif globalwordlists$ <> "" and fileReadable("'globalwordlists$'/'wordlistName$'")
841                                 .wordlistDirectory$ = "'globalwordlists$'/'wordlistName$'"
842                         endif
843                         if .wordlistDirectory$ <> ""
844                                 .audioExampleList = Create Strings as file list... AudioList '.wordlistDirectory$'/'sgc.pinyin$'.*
845                                 .number_of_examples = Get number of strings
846                                 if .number_of_examples > 0
847                                         Randomize
848                                         .sound$ = Get string... 1
849                                         .soundFilePath$ = "'.wordlistDirectory$'/'.sound$'"
850                                 endif
851                                 Remove
852                         endif
853                 endif
854                 if fileReadable(.soundFilePath$) and config.useSoundExample
855                         .tmp = -1
856                         .tmp = nocheck Read from file... '.soundFilePath$'
857                         if .tmp != undefined and .tmp > 0
858                                 call play_sound '.tmp'
859                                 select .tmp
860                                 Remove
861                         endif
862                 elsif config.synthesis$ <> "" and config.synthesis$ <> "_DISABLED_"
863                         call synthesize_sound 'sgc.pinyin$'
864                 else
865                         call humToneContour 'sgc.pinyin$' 'config.register'
866                         call reset_viewport
867                 endif
868         endif
869         demoShow()
870 endproc
872 # Draw a tone contour
873 procedure draw_tone_contour
874         select sgc.currentWordlist
875         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
876                 .sound$ = Get value... 'sgc.currentWord' Sound
877                 call readPinyin 'sgc.currentWord'
878                 sgc.pinyin$ = readPinyin.pinyin$
879                 call drawToneContour 'sgc.pinyin$' 'config.register'
880                 call reset_viewport
881                 
882                 if te.recordedPitch > 0
883                         call drawSourceToneContour te.recordedPitch
884                 endif
885         endif
887 endproc
889 procedure recognizeTone
890         select sgc.currentWordlist
891         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
892                 .strict = 0
893                 if index_regex(config.strict$, "[^0-9]") <= 0
894                         .strict = ('config.strict$' >= sgc.highestLevel)
895                 endif
896                         
897                 .sound$ = Get value... 'sgc.currentWord' Sound
898                 call readPinyin 'sgc.currentWord'
899                 sgc.pinyin$ = readPinyin.pinyin$
900                 call align_recordedSound 'sgc.pinyin$'
901         call sgc_ToneProt 'recordedSound$' 'sgc.pinyin$' 'config.register' '.strict' 'config.language$'
902         # sgc_ToneProt manipulates the sound given. Reconnect
903         select Sound 'recordedSound$'
904         sgc.recordedSound = selected("Sound")
905                 call reset_viewport
906         endif
907 endproc
909 procedure write_feedback .table$
910     select Table '.table$'
911     .line1$ = Get value... 1 Text
912     .line2$ = Get value... 2 Text
913     .label$ = Get value... 3 Text
915         # convert numbers to Pinyin if needed
916         if not config.displayNumbers
917                 call numbers2pinyin '.line1$'
918                 .line1$ = numbers2pinyin.pinyin$
919         endif
921     .color$ = "Red"
922     if index(.line1$, "???") > 0
923         .color$ = "Black"
924     elsif .label$ = "Correct"
925         .color$ = "Green"
926         elsif config.strict$ = "'sgc.highestLevel'"
927                 .line2$ = .line2$ + " *"
928     endif
930         .currentFeedbackFontSize = 14
931         .maxHeight = 21 - 17
932         call adjustFontSizeOnHeight 'defaultFont$' '.currentFeedbackFontSize' '.maxHeight'
933         .currentFeedbackFontSize = adjustFontSizeOnHeight.newFontSize
934         
935         call wipeArea 'wipeFeedbackArea$'
936     call set_font_size '.currentFeedbackFontSize'
937     demo '.color$'
938     demo Text... 50 Centre 21 Bottom '.line1$'
939     demo Text... 50 Centre 17 Bottom '.line2$'
940         demoShow()
941         demo 'defaultFont$'
942     call set_font_size 'defaultFontSize'
943 endproc
945 # Text display
946 procedure display_text .color$
947         select sgc.currentWordlist
948         if sgc.currentWord < 0 or sgc.currentWord > sgc.numberOfWords+1
949                 call clean_up_sound
950         if config.shuffleLists
951                     Randomize rows
952         endif
953                 if sgc.currentWord < 0
954                         sgc.currentWord = sgc.numberOfWords
955                 else
956                         sgc.currentWord = 1
957                 endif
958         endif
959         
960         .changeCJKstyle = 0
961         if sgc.currentWord > 0 and sgc.currentWord <= sgc.numberOfWords
962                 .displayText$ = ""
963                 call readDisplayPinyin 'sgc.currentWord'
964                 .displayPinyin$ = readDisplayPinyin.pinyin$
965                 .displayChar$ = Get value... 'sgc.currentWord' Character
966                 .displayTrans$ = Get value... 'sgc.currentWord' Translation
967                 if .displayPinyin$ <> "-" and (config.displayPinyin or sgc.writeAll)
968                         if not config.displayNumbers
969                                 call numbers2pinyin '.displayPinyin$'
970                                 .displayPinyin$ = numbers2pinyin.pinyin$
971                         endif
972                         # Insert u umlaut
973                         .displayPinyin$ = replace_regex$(.displayPinyin$, "v", "\\u\X22", 0)
974                         .displayText$ = .displayText$ + .displayPinyin$
975                 endif
976                 if .displayChar$ <> "-" and (config.displayChar or sgc.writeAll)
977                         .displayText$ = .displayText$ + "  "+ .displayChar$
978                         .changeCJKstyle = 1
979                 endif
980                 if .displayTrans$ <> "-" and (config.displayTrans or sgc.writeAll)
981                         .displayText$ = .displayText$ + "  \s{%%"+ .displayTrans$ + "%}"
982                 endif
983         elsif sgc.currentWord = 0 or sgc.currentWord = sgc.numberOfWords+1
984                 call clean_up_sound
985                 .displayText$ = "---"
986         endif
988         # Adapt font size
989         call adjustFontSizeOnHeight 'defaultFont$' 24 15
990         .currentFontSize = adjustFontSizeOnHeight.newFontSize
991         call adjustFontSizeOnWidth 'defaultFont$' '.currentFontSize' 95 '.displayText$'
992         .currentFontSize = adjustFontSizeOnWidth.newFontSize
994         # Clear the writing area
995         call wipeArea 'wipePinyinArea$'
996         # Switch back to Chinese style CJK when in Japanese language mode
997         if .changeCJKstyle and config.language$ = "JA"
998                 CJK font style preferences: "Chinese"
999         endif
1000         # Actually display text
1001         demo '.color$'
1002         call set_font_size '.currentFontSize'
1003         demo Text... 50 Centre 26 Bottom '.displayText$'
1004         demoShow()
1005         demo Black
1006         demo 'defaultFont$'
1007         call set_font_size 'defaultFontSize'
1008         if .changeCJKstyle and config.language$ = "JA"
1009                 if config.language$ = "JA"
1010                         CJK font style preferences: "Japanese"
1011                 elsif config.language$ = "ZH"
1012                         CJK font style preferences: "Chinese"
1013                 endif
1014         endif
1015         # Switch back to Japanese style CJK when in Japanese language mode
1016         if .changeCJKstyle and config.language$ = "JA"
1017                 CJK font style preferences: "Japanese"
1018         endif
1019 endproc
1021 procedure numbers2pinyin .numberstext$
1022         .intermediatePinyin$ = .numberstext$
1023         # Add a `-quote between vowels
1024         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])([aeuiov])", "\1\2'\3", 0)
1025         # Move numbers to the nucleus vowel
1026         # To the vowel
1027         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([^aeuiov0-9]*)([0-9])", "\1\3\2", 0)
1028         # Either a/e
1029         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([ae])([aeuiov]*)([0-9])", "\1\3\2", 0)
1030         # Or the Oo in /ou/
1031         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(ou)([0-9])", "o\2u", 0)
1032         # or the second vowel
1033         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([uiov][aeuiov])([uiov])([0-9])", "\1\3\2", 0)
1034         
1035         # Convert all tones to special characters
1036         # Tone 1
1037         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "a1", "ā", 0)
1038         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e1", "ē", 0)
1039         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "u1", "ū", 0)
1040         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i1", "ī", 0)
1041         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o1", "ō", 0)
1042         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v1", "ǖ", 0)
1043         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "1", "\\-^", 0)
1044         
1045         # Tone 2
1046         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v2", "ǘ", 0)
1047         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([iaeou])2", "\\\1'", 0)
1048         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "2", "\\'^", 0)
1049         
1050         # Tone 3
1051         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "a3", "ǎ", 0)
1052         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e3", "ě", 0)
1053         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "u3", "ǔ", 0)
1054         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i3", "ǐ", 0)
1055         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o3", "ǒ", 0)
1056         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v3", "ǚ", 0)
1057         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "3", "\\N^", 0)
1059         # Tone 4
1060         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v4", "ǜ", 0)
1061         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([iaeou])4", "\\\1`", 0)
1062         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "4", "\\`^", 0)
1063         
1064         # Tone 0
1065         # Remove tone 0 symbol completely
1066         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "0", "", 0)
1067         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "a0", "å", 0)
1068         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e0", "e̊", 0)
1069         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "u0", "ů", 0)
1070         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i0", "i̊", 0)
1071         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o0", "o̊", 0)
1072         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v0", "ü̊", 0)
1073         #.intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "0", "\\0^", 0)
1074         
1075         # Pick best vowel symbols available in cases not caught before
1076         # Ugly clutch to get the 1, 3, 0 tone diacritics at least in the neighbourhood
1077         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i(\\[-N0]\^)", "i\\s{_ }\1", 0)
1078         # Insert u umlaut
1079         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "v", "\\u\X22", 0)
1081         .pinyin$ = .intermediatePinyin$
1082 endproc
1084 # NEEDS WORK AND TESTING!!
1085 # Convert unicode Pinyin into tone numbers
1086 procedure pinyin2numbers .pinyin$
1087         .intermediatePinyin$ = .pinyin$
1088         # Convert all special characters to numbers
1089         # Tone 1
1090         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iā)([iaeouü]*)", "a\11", 0)
1091         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iē)([iaeouü]*)", "e\11", 0)
1092         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iū)([iaeouü]*)", "u\11", 0)
1093         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iī)([iaeouü]*)", "i\11", 0)
1094         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iō)([iaeouü]*)", "o\11", 0)
1095         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǖ)([iaeouü]*)", "v\11", 0)
1096         
1097         # Tone 2
1098         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iá)([iaeouü]*)", "a\12", 0)
1099         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ié)([iaeouü]*)", "e\12", 0)
1100         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iú)([iaeouü]*)", "u\12", 0)
1101         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ií)([iaeouü]*)", "i\12", 0)
1102         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ió)([iaeouü]*)", "o\12", 0)
1103         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǘ)([iaeouü]*)", "v\12", 0)
1104         
1105         # Tone 3
1106         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǎ)([iaeouü]*)", "a\13", 0)
1107         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iě)([iaeouü]*)", "e\13", 0)
1108         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǔ)([iaeouü]*)", "u\13", 0)
1109         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǐ)([iaeouü]*)", "i\13", 0)
1110         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǒ)([iaeouü]*)", "o\13", 0)
1111         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǚ)([iaeouü]*)", "v\13", 0)
1113         # Tone 4
1114         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?ià)([iaeouü]*)", "a\14", 0)
1115         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iè)([iaeouü]*)", "e\14", 0)
1116         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iù)([iaeouü]*)", "u\14", 0)
1117         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iì)([iaeouü]*)", "i\14", 0)
1118         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iò)([iaeouü]*)", "o\14", 0)
1119         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iǜ)([iaeouü]*)", "v\14", 0)
1120         
1121         # Tone 0
1122         # Add tone 0
1123         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iå)([iaeouü]*)", "a\10", 0)
1124         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "e̊([iaeouü]*)", "e\10", 0)
1125         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "(?iů)([iaeouü]*)", "u\10", 0)
1126         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "i̊([iaeouü]*)", "i\10", 0)
1127         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "o̊([iaeouü]*)", "o\10", 0)
1128         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "ü̊([iaeouü]*)", "v\10", 0)
1130         # Syllables without a tone symbol are tone 0
1131         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov]+)([^0-9aeuiov]|\W|$)", "\10\2", 0)
1133         # Move numbers to the end of the syllable.
1134         # Syllables ending in n and start with g. Note that a syllable cannot start with an u or i
1135         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])(n)(g[aeuiov])", "\1\3\2\4", 0)
1136         # Syllables ending in (ng?) followed by something that is not a valid vowel 
1137         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])(ng?)([^aeuiov]|\W|$)", "\1\3\2\4", 0)
1138         # Syllables ending in r
1139         .intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "([aeuiov])([0-9])(r)([^aeuiov]|\W|$)", "\1\3\2\4", 0)
1140         # Remove quotes etc
1141         #.intermediatePinyin$ = replace_regex$(.intermediatePinyin$, "[\\'\\`]", "", 0)
1142         
1143         .numberstext$ = .intermediatePinyin$
1144 endproc
1146 procedure readDisplayPinyin .currentWord
1147         select sgc.currentWordlist
1148         .pinyin$ = Get value... '.currentWord' Pinyin
1149         # Everything to lowercase
1151         if index_regex(.pinyin$, "[0-9]") <= 0
1152                 call pinyin2numbers '.pinyin$'
1153                 .pinyin$ = pinyin2numbers.numberstext$
1154         endif 
1155 endproc
1157 procedure readPinyin .currentWord
1158         call readDisplayPinyin '.currentWord'
1159         .pinyin$ = replace_regex$(readDisplayPinyin.pinyin$, ".+", "\L&", 0)
1160         .pinyin$ = replace_regex$(.pinyin$, "[\\'\\` ]", "", 0)
1161 endproc
1163 # Includes
1164 include ToneProt/SGC_ToneProt.praat
1165 include ToneProt/DrawToneContour.praat
1166 include ToneProt/HumToneContour.praat
1167 include ToneProt/ToneRecognition.praat
1168 include ToneProt/ToneScript.praat
1169 include ToneProt/ToneRules.praat