4 Website: http://www.vultaire.net/software/jben/
5 License: GNU General Public License (GPL) version 2
6 (http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>
25 #include "file_utils.h"
27 #include "wx/tokenzr.h"
33 KDict
* KDict::kdictSingleton
= NULL
;
35 const KDict
*KDict::GetKDict() {
36 if(kdictSingleton
) return kdictSingleton
;
37 kdictSingleton
= new KDict
;
38 kdictSingleton
->LoadKanjidic();
39 kdictSingleton
->LoadKradfile();
40 kdictSingleton
->LoadRadkfile();
41 return kdictSingleton
;
44 void KDict::Destroy() {
46 delete kdictSingleton
;
47 kdictSingleton
= NULL
;
51 int KDict::LoadKanjidic(const char *filename
) {
54 int returnCode
=0xDEADBEEF;
56 ifstream
ifile(filename
, ios::ate
); /* "at end" to get our file size */
60 rawData
= new char[size
+1];
62 ifile
.read(rawData
, size
);
64 if(strlen(rawData
)!=size
)
66 "WARNING: kanjidic file size: %d, read-in string: %d\n",
71 /* Create the kanjidic object with our string data. */
72 this->KanjidicParser(rawData
);
74 returnCode
= KD_SUCCESS
;
77 returnCode
= KD_FAILURE
;
79 if(rawData
) delete[] rawData
;
83 int KDict::LoadKradfile(const char *filename
) {
84 int returnCode
= 0xDEADBEEF;
88 int KDict::LoadRadkfile(const char *filename
) {
89 int returnCode
= 0xDEADBEEF;
93 /* This could be sped up: copy the first UTF-8 character into a string, then
94 run a conversion on that. Trivial though. */
95 void KDict::KanjidicParser(char *kanjidicRawData
) {
96 char *token
= strtok(kanjidicRawData
, "\n");
99 if( (strlen(token
)>0) && (token
[0]!='#') ) {
100 UTF8ToWx(token
, wxToken
);
101 /* Convert token to proper format */
102 wxToken
= ConvertKanjidicEntry(wxToken
);
103 /* Add to hash table */
104 if(!kanjidicData
.assign(wxToken
[0], token
)) {
107 "Error assigning (%lc, %ls) to hash table!\n",
108 wxToken
[0], wxToken
.c_str());
112 token
= strtok(NULL
, "\n");
117 /* Currently: nothing here. */
120 /* This function returns a wxString containing the desired line of the
121 kanjidic hash table. A conversion from string to wxString is included
122 in this call since strings are only used for more compressed internal
123 storage. This is followed by a slight reformatting of the string for
124 better presentation. */
125 wxString
KDict::GetKanjidicStr(wxChar c
) const {
126 BoostHM
<wxChar
,string
>::iterator it
= kanjidicData
.find(c
);
127 if(it
==kanjidicData
.end()) return _T("");
129 UTF8ToWx(it
->second
, s
);
130 return ConvertKanjidicEntry(s
);
134 * Performs transformations on a KANJIDIC string for our internal usage.
135 * Currently, this includes the following:
136 * - Changing あ.いう notation to あ(いう), a la JWPce/JFC.
137 * - Changing -あい notation to 〜あい, also a la JWPce/JFC.
139 wxString
KDict::ConvertKanjidicEntry(const wxString
& s
) {
140 size_t index
, lastIndex
;
143 /* First conversion: あ.いう to あ(いう) */
144 index
= temp
.find(_T('.'), 0);
145 while(index
!=wxString::npos
) {
146 /* Proceed if the character preceding the "." is hiragana/katakana. */
147 if(IsFurigana(temp
[index
-1])) {
148 temp
[index
] = _T('(');
149 index
= temp
.find(_T(' '), index
+1);
150 if(index
==wxString::npos
) {
151 temp
.append(_T(')'));
154 temp
.insert(index
, _T(')'));
157 index
= temp
.find(_T('.'), lastIndex
+1);
160 /* Second conversion: - to 〜, when a neighboring character is hiragana/katakana */
161 index
= temp
.find(_T('-'), 0);
162 while(index
!=wxString::npos
) {
163 /* Proceed if the character before or after the "-" is hiragana/katakana. */
164 if(IsFurigana(temp
[index
-1]) || IsFurigana(temp
[index
+1]))
168 index
= temp
.find(_T('-'), lastIndex
+1);
171 /* Return the converted string */
175 wxString
KDict::KanjidicToHtml(const wxString
& kanjidicStr
) {
176 return KanjidicToHtml(kanjidicStr
,
177 jben
->prefs
->kanjidicOptions
,
178 jben
->prefs
->kanjidicDictionaries
);
181 wxString
KDict::KanjidicToHtml(const wxString
& kanjidicStr
,
182 long options
, long dictionaries
) {
183 /* return wxString(_T("<p>"))
185 .append(_T("</p>"));*/
189 wxString header
, onyomi
, kunyomi
, nanori
, radicalReading
, english
;
190 wxString dictionaryInfo
;
191 wxString lowRelevance
;
193 long grade
= -1, frequency
= -1, tmode
= 0;
195 wxString koreanRomanization
, pinyinRomanization
, crossReferences
, miscodes
;
196 wxString sTemp
, token
;
197 wxStringTokenizer
t(kanjidicStr
, _T(' '));
200 /* Special processing for the first 2 entries of the line. */
201 if(t
.CountTokens()>1) {
202 /* header = "<h1><font size=\"-6\">" + args[0] + "</font></h1>"; */
203 /*header.append(_T("<p style=\"font-size:32pt\">")) */
204 header
.append(_T("<p><font size=\"7\">"))
205 .append(t
.GetNextToken())
206 .append(_T("</font></p>"));
207 lowRelevance
.append(_T("<li>JIS code: 0x"))
208 .append(t
.GetNextToken())
209 .append(_T("</li>"));
212 /* NEW! Temporary code for loading in SODs and SODAs from KanjiCafe! */
213 if(options
& (KDO_SOD_STATIC
| KDO_SOD_ANIM
) != 0) {
214 wxCSConv
transcoder(_T("utf-8"));
215 if(transcoder
.IsOk()) {
217 /* Get a UTF8-encoded string for the kanji. */
218 WxToUTF8(kanjidicStr
[0], utfStr
);
221 /* Convert to a low-to-high-byte hex string. */
222 for(unsigned int i
=0;i
<utfStr
.length();i
++) {
224 wxString::Format(_T("%02x"),
225 (unsigned char)utfStr
[i
]));
229 /* Load static SOD, if present */
230 if((options
& KDO_SOD_STATIC
) != 0) {
232 fn
.AppendDir(_T("sods"));
233 fn
.AppendDir(_T("sod-utf8-hex"));
235 fn
.SetExt(_T("png"));
237 printf("DEBUG: Checking for existance of file \"%ls\"...\n", fn
.GetFullPath().c_str());
242 sod
.append(wxString::Format(
243 _T("<img src=\"%s\" />"), fn
.GetFullPath().c_str()
247 /* Load animated SOD, if present */
248 if((options
& KDO_SOD_ANIM
) != 0) {
250 fn
.AppendDir(_T("sods"));
251 fn
.AppendDir(_T("soda-utf8-hex"));
253 fn
.SetExt(_T("gif"));
255 printf("DEBUG: Checking for existance of file \"%ls\"...\n", fn
.GetFullPath().c_str());
260 if(sod
.length()>0) sod
.append(_T("<br />"));
261 sod
.append(wxString::Format(
262 _T("<img src=\"%s\" />"), fn
.GetFullPath().c_str()
266 /* Append the chart(s) in a paragraph object. */
268 header
.append(wxString::Format(
269 _T("<p>%s<br /><font size=\"1\">(Kanji stroke order graphics used under license from KanjiCafe.com.)</font></p>"), sod
.c_str()
273 fprintf(stderr
, "[%s:%d]: Bad transcoder selected!\n", __FILE__
, __LINE__
);
276 /* END OF EXPERIMENTAL NEW CODE */
278 while(t
.HasMoreTokens()) {
279 token
= t
.GetNextToken();
282 /* If a preceding character is detected, strip it */
283 if(c
== _T('(') || c
== _T('〜')) {
284 sTemp
= sTemp
.substr(1);
289 /* Onyomi reading detected */
290 /*if(onyomi.length()>0) onyomi.append(_T(" ")); */
291 if(onyomi
.length()>0) onyomi
.append(_T(" "));
292 onyomi
.append(token
); /* Copy the original string, including ()'s and 〜's */
295 else if(IsHiragana(c
)) {
296 /* Kunyomi reading detected */
297 if(kunyomi
.length()>0) kunyomi
.append(_T(" "));
298 kunyomi
.append(token
); /* Copy the original string, including ()'s and 〜's */
301 } else if(tmode
==1) {
303 /* Nanori reading detected */
304 if(nanori
.length()>0) nanori
.append(_T(" "));
305 nanori
.append(token
); /* Copy the original string, including ()'s and 〜's */
308 } else if(tmode
==2) {
310 /* Special radical reading detected */
311 if(radicalReading
.length()>0) radicalReading
.append(_T(" "));
312 radicalReading
.append(token
);
317 /* English meaning detected
318 Special handling is needed to take care of spaces, though.
319 We'll "cheat" and mess with our iterator a bit if a space is detected. */
320 while(t
.HasMoreTokens() && sTemp
[sTemp
.length()-1] != _T('}')) {
321 sTemp
.append(_T(" ")).append(t
.GetNextToken());
323 if(english
.length()>0) english
.append(_T(", "));
324 english
.append(sTemp
.substr(1,sTemp
.length()-2)); /* Strip the {} */
328 case _T('T'): /* Change "t mode" */
329 /* Note: substr() returns type wxStringBase, which disallows access to wxString::ToLong.
330 So, by making a copy of wxString and performing the conversion in the copy, we get around this.
331 This ugly kludge is repeated twice below for frequency and grade level. */
332 wxString(sTemp
.substr(1)).ToLong(&tmode
);
334 if(tmode
>2) printf("WARNING: T-mode set to %d.\nT-modes above 2 are not currently documented!", (int)tmode
);
337 case _T('B'): /* Bushu radical */
338 lowRelevance
.append(_T("<li>Bushu radical: ")).append(sTemp
.substr(1)).append(_T("</li>"));
340 case _T('C'): /* Classical radical */
341 lowRelevance
.append(_T("<li>Classical radical: ")).append(sTemp
.substr(1)).append(_T("</li>"));
343 case _T('F'): /* Frequency */
344 wxString(sTemp
.substr(1)).ToLong(&frequency
);
346 case _T('G'): /* Grade level */
347 wxString(sTemp
.substr(1)).ToLong(&grade
);
349 case _T('S'): /* Stroke count */
350 if(strokes
.length()==0) {
351 strokes
= sTemp
.substr(1);
352 } else if(!strokes
.find(_T(' '))!=wxString::npos
) {
353 strokes
.append(_T(" (Miscounts: "))
354 .append(sTemp
.substr(1))
357 strokes
= strokes
.substr(0, strokes
.length()-1)
359 .append(sTemp
.substr(1))
363 case _T('U'): /* Unicode value */
364 lowRelevance
.append(_T("<li>Unicode: 0x")).append(sTemp
.substr(1)).append(_T("</li>"));
366 /* From here, it's all dictionary codes */
368 if((dictionaries
& KDD_NJECD
)!=0)
369 dictionaryInfo
.append(_T("<li>New Japanese-English Character Dictionary (Halpern): "))
370 .append(sTemp
.substr(1)).append(_T("</li>"));
373 if((dictionaries
& KDD_MRJECD
)!=0)
374 dictionaryInfo
.append(_T("<li>Modern Reader's Japanese-English Character Dictionary (Nelson): "))
375 .append(sTemp
.substr(1)).append(_T("</li>"));
378 if((dictionaries
& KDD_NNJECD
)!=0)
379 dictionaryInfo
.append(_T("<li>The New Nelson's Japanese-English Character Dictionary: "))
380 .append(sTemp
.substr(1)).append(_T("</li>"));
384 /* This is a thorny issue. If we want to include a stock KANJIDIC, then we */
385 /* need to add encryption to the file and prevent copy/pasting of that data. */
386 /* I'll comply later on, but for now I'll use a stripped KANJIDIC. */
388 if((dictionaries
& KDD_SKIP
)!=0)
389 dictionaryInfo
.append(_T("<li>SKIP code: "))
390 .append(sTemp
.substr(1)).append(_T("</li>"));
393 case _T('I'): /* Spahn/Hadamitzky dictionaries */
394 if(sTemp
[1]==_T('N')) {
395 if((dictionaries
& KDD_KK
)!=0) {
396 dictionaryInfo
.append(_T("<li>Kanji & Kana (Spahn, Hadamitzky): "))
397 .append(sTemp
.substr(2)).append(_T("</li>"));
400 if((dictionaries
& KDD_KD
)!=0) {
401 dictionaryInfo
.append(_T("<li>Kanji Dictionary (Spahn, Hadamitzky): "))
402 .append(sTemp
.substr(1)).append(_T("</li>"));
407 if((dictionaries
& KDD_FC
)!=0) {
408 dictionaryInfo
.append(_T("<li>Four Corner code: "))
409 .append(sTemp
.substr(1)).append(_T("</li>"));
415 if((dictionaries
& KDD_MOROI
)!=0) {
416 dictionaryInfo
.append(_T("<li>Morohashi Daikanwajiten Index: "))
417 .append(sTemp
.substr(2)).append(_T("</li>"));
419 } else if(c2
==_T('P')) {
420 if((dictionaries
& KDD_MOROVP
)!=0) {
421 dictionaryInfo
.append(_T("<li>Morohashi Daikanwajiten Volume/Page: "))
422 .append(sTemp
.substr(2)).append(_T("</li>"));
427 if((dictionaries
& KDD_GRJC
)!=0) {
428 dictionaryInfo
.append(_T("<li>A Guide to Remembering Japanese Characters (Henshal): "))
429 .append(sTemp
.substr(1)).append(_T("</li>"));
433 if((dictionaries
& KDD_GKD
)!=0) {
434 dictionaryInfo
.append(_T("<li>Gakken Kanji Dictionary (\"A New Dictionary of Kanji Usage\"): "))
435 .append(sTemp
.substr(1)).append(_T("</li>"));
439 if((dictionaries
& KDD_RTK
)!=0) {
440 dictionaryInfo
.append(_T("<li>Remembering the Kanji (Heisig): "))
441 .append(sTemp
.substr(1)).append(_T("</li>"));
445 if((dictionaries
& KDD_JN
)!=0) {
446 dictionaryInfo
.append(_T("<li>Japanese Names (O'Neill): "))
447 .append(sTemp
.substr(1)).append(_T("</li>"));
454 if((dictionaries
& KDD_JBP
)!=0) {
455 dictionaryInfo
.append(_T("<li>Japanese for Busy People (AJLT): "))
456 .append(sTemp
.substr(2)).append(_T("</li>"));
460 if((dictionaries
& KDD_KWJLP
)!=0) {
461 dictionaryInfo
.append(_T("<li>The Kanji Way to Japanese Language Power (Crowley): "))
462 .append(sTemp
.substr(2)).append(_T("</li>"));
466 if((dictionaries
& KDD_JKF
)!=0) {
467 dictionaryInfo
.append(_T("<li>Japanese Kanji Flashcards (White Rabbit Press): "))
468 .append(sTemp
.substr(2)).append(_T("</li>"));
472 if((dictionaries
& KDD_KCKG
)!=0) {
473 dictionaryInfo
.append(_T("<li>Kodansha Compact Kanji Guide: "))
474 .append(sTemp
.substr(2)).append(_T("</li>"));
478 if((dictionaries
& KDD_GTRWJH
)!=0) {
479 dictionaryInfo
.append(_T("<li>A Guide To Reading and Writing Japanese (Hensall): "))
480 .append(sTemp
.substr(2)).append(_T("</li>"));
484 if((dictionaries
& KDD_KIC
)!=0) {
485 dictionaryInfo
.append(_T("<li>Kanji in Context (Nishiguchi and Kono): "))
486 .append(sTemp
.substr(2)).append(_T("</li>"));
490 if((dictionaries
& KDD_KLD
)!=0) {
491 dictionaryInfo
.append(_T("<li>Kanji Learner's Dictionary (Halpern): "))
492 .append(sTemp
.substr(2)).append(_T("</li>"));
496 if((dictionaries
& KDD_EK
)!=0) {
497 dictionaryInfo
.append(_T("<li>Essential Kanji (O'Neill): "))
498 .append(sTemp
.substr(2)).append(_T("</li>"));
502 if((dictionaries
& KDD_DR
)!=0) {
503 dictionaryInfo
.append(_T("<li>2001 Kanji (De Roo): "))
504 .append(sTemp
.substr(2)).append(_T("</li>"));
508 if((dictionaries
& KDD_GTRWJS
)!=0) {
509 dictionaryInfo
.append(_T("<li>A Guide to Reading and Writing Japanese (Sakade): "))
510 .append(sTemp
.substr(2)).append(_T("</li>"));
514 if((dictionaries
& KDD_TKC
)!=0) {
515 dictionaryInfo
.append(_T("<li>Tuttle Kanji Cards (Kask): "))
516 .append(sTemp
.substr(2)).append(_T("</li>"));
520 if(unhandled
.length()>0) unhandled
.append(_T(" "));
521 unhandled
.append(sTemp
);
525 /* Crossreferences and miscodes */
527 if(crossReferences
.length()>0) crossReferences
.append(_T(", "));
528 crossReferences
.append(sTemp
.substr(1));
531 if(miscodes
.length()>0) miscodes
.append(_T(", "));
532 miscodes
.append(sTemp
.substr(1));
534 /* Korean/Pinyin (Chinese) romanization */
536 if(koreanRomanization
.length()>0) koreanRomanization
.append(_T(", "));
537 koreanRomanization
.append(sTemp
.substr(1));
540 if(pinyinRomanization
.length()>0) pinyinRomanization
.append(_T(", "));
541 pinyinRomanization
.append(sTemp
.substr(1));
544 if(unhandled
.length()>0) unhandled
.append(_T(" "));
545 unhandled
.append(sTemp
);
549 } /* while(t.HasMoreTokens()) */
551 if(header
.length() > 0) result
.append(header
);
553 printf("DEBUG: header=[%ls]\n", header
.c_str());
555 result
.append(_T("<ul>"));
556 if((options
& KDO_READINGS
) != 0) {
557 if(onyomi
.length() > 0) result
.append(_T("<li>Onyomi Readings: ")).append(onyomi
).append(_T("</li>"));
558 if(kunyomi
.length() > 0) result
.append(_T("<li>Kunyomi Readings: ")).append(kunyomi
).append(_T("</li>"));
559 if(nanori
.length() > 0) result
.append(_T("<li>Nanori Readings: ")).append(nanori
).append(_T("</li>"));
560 if(radicalReading
.length() > 0) result
.append(_T("<li>Special Radical Reading: ")).append(radicalReading
).append(_T("</li>"));
562 if((options
& KDO_MEANINGS
) != 0) {
563 if(english
.length() > 0) result
.append(_T("<li>English Meanings: ")).append(english
).append(_T("</li>"));
565 if((options
& KDO_HIGHIMPORTANCE
) != 0) {
566 if(strokes
.length() > 0)
567 result
.append(_T("<li>Stroke count: ")).append(strokes
).append(_T("</li>"));
569 result
.append(_T("<li>Stroke count: not specified in KANJIDIC"));
570 result
.append(_T("<li>Grade Level: "));
571 if(grade
<=6 && grade
>= 1) { /* Jouyou (Grade #) */
572 result
.append(_T("Jouyou (Grade "))
573 .append(wxString::Format(_T("%d"), (int)grade
))
575 } else if(grade
==8) { /* Jouyou (General usage) */
576 result
.append(_T("Jouyou (General usage)"));
577 } else if(grade
==9) { /* Jinmeiyou (Characters for names) */
578 result
.append(_T("Jinmeiyou (Characters for names)"));
579 } else if(grade
==-1) { /* No flag specified in kanjidic string */
580 result
.append(_T("Unspecified"));
582 result
.append(_T("Unhandled grade level (Grade "))
583 .append(wxString::Format(_T("%d"), (int)grade
))
586 result
.append(_T("</li>"));
588 result
.append(_T("<li>Frequency Ranking: "))
589 .append(wxString::Format(_T("%d"), (int)frequency
))
590 .append(_T("</li>"));
591 else result
.append(_T("<li>Frequency Ranking: Unspecified</li>"));
593 if((options
& KDO_DICTIONARIES
) != 0) {
594 if(dictionaryInfo
.length()>0) result
.append(_T("<li>Dictionary Codes:<ul>")).append(dictionaryInfo
).append(_T("</ul></li>"));
596 if((options
& KDO_VOCABCROSSREF
) != 0) {
597 vector
<wxString
> *vList
= &(jben
->vocabList
->GetVocabList());
598 wxChar thisKanji
= kanjidicStr
[0];
599 vector
<wxString
> crossRefList
;
600 vector
<wxString
>::iterator vIt
;
601 for(vIt
=vList
->begin(); vIt
!=vList
->end(); vIt
++) {
602 if(vIt
->find(thisKanji
)!=wxString::npos
) {
603 crossRefList
.push_back(*vIt
);
606 if(crossRefList
.size()>0) {
607 result
.append(_T("<li>This kanji is used by words in your study list:<br><font size=\"7\">"));
608 vIt
= crossRefList
.begin();
610 for(++vIt
; vIt
!=crossRefList
.end(); vIt
++) {
611 result
.append(_T(" ")).append(*vIt
);
613 result
.append(_T("</font></li>"));
616 if((options
& KDO_LOWIMPORTANCE
) != 0) {
617 if(koreanRomanization
.length()>0) lowRelevance
.append(_T("<li>Korean romanization: ")).append(koreanRomanization
).append(_T("</li>"));
618 if(pinyinRomanization
.length()>0) lowRelevance
.append(_T("<li>Pinyin romanization: ")).append(pinyinRomanization
).append(_T("</li>"));
619 if(crossReferences
.length()>0) lowRelevance
.append(_T("<li>Cross reference codes: ")).append(crossReferences
).append(_T("</li>"));
620 if(miscodes
.length()>0) lowRelevance
.append(_T("<li>Miscodes: ")).append(miscodes
).append(_T("</li>"));
621 if(lowRelevance
.length()>0) result
.append(_T("<li>Extra Information:<ul>")).append(lowRelevance
).append(_T("</ul></li>"));
623 if((options
& KDO_UNHANDLED
) != 0) {
624 if(unhandled
.length()>0) result
.append(_T("<li>Unhandled: ")).append(unhandled
).append(_T("</li>"));
626 result
.append(_T("</ul>"));
631 int KDict::GetIntField(wxChar kanji
, const wxString
& marker
) const {
632 wxString markerStr
, kanjiEntry
, temp
;
637 markerStr
.Printf(_T(" %s"), marker
.c_str());
638 markerLen
=markerStr
.length();
640 kanjiEntry
= GetKanjidicStr(kanji
);
641 if(kanjiEntry
.length()>0) {
642 index
= kanjiEntry
.find(markerStr
);
643 if(index
!=wxString::npos
) {
644 temp
= kanjiEntry
.substr(
646 kanjiEntry
.find(_T(" "), index
+1) - index
- (markerLen
-1));
654 const BoostHM
<wxChar
,string
>* KDict::GetHashTable() const {
655 return &kanjidicData
;
664 wxString
KDict::GetOnyomiStr(wxChar c
) const {
665 return GetKanjidicReading(c
, KDR_Onyomi
);
668 wxString
KDict::GetKunyomiStr(wxChar c
) const {
669 return GetKanjidicReading(c
, KDR_Kunyomi
);
672 wxString
KDict::GetEnglishStr(wxChar c
) const {
673 return GetKanjidicReading(c
, KDR_English
);
676 wxString
KDict::GetKanjidicReading(wxChar c
, int readingType
) const {
678 wxString kanjidicStr
= GetKanjidicStr(c
);
681 wxString sTemp
, token
;
682 wxStringTokenizer
t(kanjidicStr
, _T(' '));
684 /* The first two tokens are guaranteed not to be what we're looking for. Skip them. */
685 if(t
.CountTokens()>1) {
689 while(t
.HasMoreTokens()) {
690 token
= t
.GetNextToken();
693 /* If a preceding character is detected, strip it */
694 if(c
== _T('(') || c
== _T('〜')) {
695 sTemp
= sTemp
.substr(1);
699 if(IsKatakana(c
) && readingType
==KDR_Onyomi
) {
700 /* Onyomi reading detected */
701 if(result
.length()>0) result
.append(_T(" "));
702 result
.append(token
); /* Copy the original string, including ()'s and 〜's */
705 else if(IsHiragana(c
) && readingType
==KDR_Kunyomi
) {
706 /* Kunyomi reading detected */
707 if(result
.length()>0) result
.append(_T(" "));
708 result
.append(token
); /* Copy the original string, including ()'s and 〜's */
712 if(c
== _T('{') && readingType
==KDR_English
) {
713 /* English meaning detected
714 Special handling is needed to take care of spaces, though.
715 We'll "cheat" and mess with our iterator a bit if a space is detected. */
716 while(t
.HasMoreTokens() && sTemp
[sTemp
.length()-1] != _T('}')) {
717 sTemp
.append(_T(" ")).append(t
.GetNextToken());
719 if(result
.length()>0) result
.append(_T(", "));
720 result
.append(sTemp
.substr(1,sTemp
.length()-2)); /* Strip the {} */
722 else if(c
==_T('T')) wxString(sTemp
.substr(1)).ToLong(&tmode
);