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