private IEnumerable <object> GetReadingList(string readingsString, KanaTypeEnum kanaType) { string[] readings = readingsString.Split(new char[] { MultiValueFieldHelper.ValueSeparator }, StringSplitOptions.RemoveEmptyEntries); foreach (string reading in readings) { yield return(new KanjiReading() { HiraganaReading = KanaHelper.ToHiragana(reading.Trim()), ModifiedReading = GetModifiedReading(kanaType, reading.Trim()) }); } }
/// <summary> /// Subpart of TryReading. Attempts to find a match between the current kanji reading character /// and the current kana reading character. If found, iterates on TryReading. /// </summary> private IEnumerable <FuriganaSolution> ReadAsKana(FuriganaResourceSet r, VocabEntry v, int currentIndexKanji, int currentIndexKana, List <FuriganaPart> currentCut, char c) { char kc = v.KanaReading[currentIndexKana]; if (c == kc || KanaHelper.ToHiragana(c.ToString()) == KanaHelper.ToHiragana(kc.ToString())) { // What we are reading in the kanji reading matches the kana reading. // We can iterate with the same cut (no added furigana) because we are reading kana. foreach (FuriganaSolution result in TryReading(r, v, currentIndexKanji + 1, currentIndexKana + 1, currentCut)) { yield return(result); } } }
private string GetModifiedReading(KanaTypeEnum kanaType, string readingString) { switch (kanaType) { case KanaTypeEnum.Hiragana: return(KanaHelper.ToHiragana(readingString)); case KanaTypeEnum.Katakana: return(KanaHelper.ToKatakana(readingString)); case KanaTypeEnum.Romaji: return(KanaHelper.ToRomaji(readingString).ToLower()); default: return(null); } }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is string && parameter is KanjiReadingToListConversionType) { // Get the conversion type and deduce the associated reading type. KanjiReadingToListConversionType conversionType = (KanjiReadingToListConversionType)parameter; KanaTypeEnum kanaType = (conversionType == KanjiReadingToListConversionType.KunYomi ? Properties.Settings.Default.KunYomiReadingType : conversionType == KanjiReadingToListConversionType.OnYomi ? Properties.Settings.Default.OnYomiReadingType : Properties.Settings.Default.NanoriReadingType); List <KanjiReading> readingList = new List <KanjiReading>(); if (!string.IsNullOrWhiteSpace(value.ToString())) { string[] readings = value.ToString().Split( new char[] { MultiValueFieldHelper.ValueSeparator }, StringSplitOptions.RemoveEmptyEntries); foreach (string reading in readings) { readingList.Add(new KanjiReading() { HiraganaReading = KanaHelper.ToHiragana(reading.Trim()), ModifiedReading = GetModifiedReading(kanaType, reading.Trim()) }); } } return(readingList); } else { throw new ArgumentException( "This converter takes a reading string as a value and a " + "matching conversion type as a parameter."); } }
/// <summary> /// Reads and returns Kanji models. /// </summary> public IEnumerable <Kanji> Execute() { // Load the supplement file. List <Kanji> supplementaryKanji = new List <Kanji>(); foreach (string line in File.ReadAllLines(PathHelper.SupplementaryKanjiPath)) { if (string.IsNullOrWhiteSpace(line) || line.First() == ';') { continue; } char c = line.First(); string[] split = line.Split(SeparatorHelper.FileFieldSeparator); string[] readings = split[1].Split(SeparatorHelper.FileReadingSeparator); supplementaryKanji.Add(new Kanji() { Character = c, Readings = readings.ToList(), ReadingsWithNanori = readings.ToList(), IsRealKanji = false }); } // Load the KanjiDic2 file. XDocument xdoc = XDocument.Load(PathHelper.KanjiDic2Path); // Browse kanji nodes. foreach (XElement xkanji in xdoc.Root.Elements(XmlNode_Character)) { // For each kanji node, read values. Kanji kanji = new Kanji(); // Read the kanji character. kanji.Character = xkanji.Element(XmlNode_Literal).Value.First(); // In the reading/meaning node... XElement xreadingMeaning = xkanji.Element(XmlNode_ReadingMeaning); if (xreadingMeaning != null) { // Browse the reading group... XElement xrmGroup = xreadingMeaning.Element(XmlNode_ReadingMeaningGroup); if (xrmGroup != null) { // Read the readings and add them to the readings of the kanji. foreach (XElement xreading in xrmGroup.Elements(XmlNode_Reading) .Where(x => x.Attribute(XmlAttribute_ReadingType).Value == XmlAttributeValue_OnYomiReading || x.Attribute(XmlAttribute_ReadingType).Value == XmlAttributeValue_KunYomiReading)) { kanji.Readings.Add(KanaHelper.ToHiragana(xreading.Value)); } } } // See if there's a supplementary entry for this kanji. Kanji supp = supplementaryKanji.FirstOrDefault(k => k.Character == kanji.Character); if (supp != null) { // Supplementary entry found. Remove it from the list and add its readings to our current entry. kanji.Readings.AddRange(supp.Readings); supplementaryKanji.Remove(supp); } // Read the nanori readings var nanoriReadings = xreadingMeaning?.Elements(XmlNode_Nanori).Select(n => n.Value).ToList() ?? new List <string>(); kanji.ReadingsWithNanori = kanji.Readings.Union(nanoriReadings).Distinct().ToList(); // Return the kanji read and go to the next kanji node. yield return(kanji); xkanji.RemoveAll(); } // Return the remaining supplementary kanji as new kanji. foreach (Kanji k in supplementaryKanji) { yield return(k); } }
/// <summary> /// Reads the KanjiDic2 file and outputs kanji entities parsed from the file. /// </summary> /// <returns>Kanji entities parsed from the file.</returns> private IEnumerable <KanjiEntity> ReadKanjiDic2() { // Load the KanjiDic2 file. XDocument xdoc = XDocument.Load(PathHelper.KanjiDic2Path); // Browse kanji nodes. foreach (XElement xkanji in xdoc.Root.Elements(XmlNode_Character)) { // For each kanji node, read values. KanjiEntity kanji = new KanjiEntity(); // Read the kanji character. kanji.Character = xkanji.Element(XmlNode_Literal).Value; // In the code point node... XElement xcodePoint = xkanji.Element(XmlNode_CodePoint); if (xcodePoint != null) { // Try to read the unicode character value. XElement xunicode = xcodePoint.Elements(XmlNode_CodePointValue) .Where(x => x.ReadAttributeString(XmlAttribute_CodePointType) == XmlAttributeValue_CodePointUnicode) .FirstOrDefault(); if (xunicode != null) { string unicodeValueString = xunicode.Value; int intValue = 0; if (int.TryParse(unicodeValueString, System.Globalization.NumberStyles.HexNumber, ParsingHelper.DefaultCulture, out intValue)) { kanji.UnicodeValue = intValue; } } } // In the misc node... XElement xmisc = xkanji.Element(XmlNode_Misc); if (xmisc != null) { // Try to read the grade, stroke count, frequency and JLPT level. // Update: JLPT level is outdated in this file. Now using the JLPTKanjiList. XElement xgrade = xmisc.Element(XmlNode_Grade); XElement xstrokeCount = xmisc.Element(XmlNode_StrokeCount); XElement xfrequency = xmisc.Element(XmlNode_Frequency); //XElement xjlpt = xmisc.Element(XmlNode_JlptLevel); if (xgrade != null) { kanji.Grade = ParsingHelper.ParseShort(xgrade.Value); } if (xstrokeCount != null) { kanji.StrokeCount = ParsingHelper.ParseShort(xstrokeCount.Value); } if (xfrequency != null) { kanji.NewspaperRank = ParsingHelper.ParseInt(xfrequency.Value); } //if (xjlpt != null) kanji.JlptLevel = ParsingHelper.ParseShort(xjlpt.Value); } // Find the JLPT level using the dictionary. if (_jlptDictionary.ContainsKey(kanji.Character)) { kanji.JlptLevel = _jlptDictionary[kanji.Character]; } // Find the frequency rank using the dictionary. if (_frequencyRankDictionary.ContainsKey(kanji.Character)) { kanji.MostUsedRank = _frequencyRankDictionary[kanji.Character]; } // Find the WaniKani level using the dictionary. if (_waniKaniDictionary.ContainsKey(kanji.Character)) { kanji.WaniKaniLevel = _waniKaniDictionary[kanji.Character]; } // In the reading/meaning node... XElement xreadingMeaning = xkanji.Element(XmlNode_ReadingMeaning); if (xreadingMeaning != null) { // Read the nanori readings. kanji.Nanori = string.Empty; foreach (XElement xnanori in xreadingMeaning.Elements(XmlNode_Nanori)) { kanji.Nanori += xnanori.Value + MultiValueFieldHelper.ValueSeparator; } kanji.Nanori = kanji.Nanori.Trim(MultiValueFieldHelper.ValueSeparator); // Browse the reading group... XElement xrmGroup = xreadingMeaning.Element(XmlNode_ReadingMeaningGroup); if (xrmGroup != null) { // Read the on'yomi readings. kanji.OnYomi = string.Empty; foreach (XElement xonYomi in xrmGroup.Elements(XmlNode_Reading) .Where(x => x.Attribute(XmlAttribute_ReadingType).Value == XmlAttributeValue_OnYomiReading)) { kanji.OnYomi += xonYomi.Value + MultiValueFieldHelper.ValueSeparator; } kanji.OnYomi = KanaHelper.ToHiragana(kanji.OnYomi.Trim(MultiValueFieldHelper.ValueSeparator)); // Read the kun'yomi readings. kanji.KunYomi = string.Empty; foreach (XElement xkunYomi in xrmGroup.Elements(XmlNode_Reading) .Where(x => x.Attribute(XmlAttribute_ReadingType).Value == XmlAttributeValue_KunYomiReading)) { kanji.KunYomi += xkunYomi.Value + MultiValueFieldHelper.ValueSeparator; } kanji.KunYomi = kanji.KunYomi.Trim(MultiValueFieldHelper.ValueSeparator); // Browse the meanings... foreach (XElement xmeaning in xrmGroup.Elements(XmlNode_Meaning)) { // Get the language and meaning. XAttribute xlanguage = xmeaning.Attribute(XmlAttribute_MeaningLanguage); string language = xlanguage != null?xlanguage.Value.ToLower() : null; string meaning = xmeaning.Value; if (xlanguage == null || language.ToLower() == "en") { // Build a meaning. KanjiMeaning kanjiMeaning = new KanjiMeaning() { Kanji = kanji, Language = language, Meaning = meaning }; // Add the meaning to the kanji. kanji.Meanings.Add(kanjiMeaning); } } } } // Return the kanji read and go to the next kanji node. yield return(kanji); xkanji.RemoveAll(); } }