diff --git a/JL.Core.Tests/LookupTests.cs b/JL.Core.Tests/LookupTests.cs index f3f7d2d5..e1bcd317 100644 --- a/JL.Core.Tests/LookupTests.cs +++ b/JL.Core.Tests/LookupTests.cs @@ -63,7 +63,7 @@ public void LookupText_始まる() ( matchedText: "始まる", dict: DictUtils.Dicts.Values.First(static dict => dict.Type is DictType.JMdict), - frequencies: new List { new("VN (Nazeka)", 759) }, + frequencies: new List { new("VN (Nazeka)", 759, false) }, primarySpelling: "始まる", deconjugatedMatchedText: "始まる", readings: new[] { "はじまる" }, diff --git a/JL.Core/Anki/Mining.cs b/JL.Core/Anki/Mining.cs index b70f09e3..6b5f435d 100644 --- a/JL.Core/Anki/Mining.cs +++ b/JL.Core/Anki/Mining.cs @@ -1,20 +1,196 @@ using System.Globalization; +using System.Text; using JL.Core.Audio; using JL.Core.Dicts; using JL.Core.Lookup; using JL.Core.Network; +using JL.Core.Statistics; using JL.Core.Utilities; namespace JL.Core.Anki; public static class Mining { - public static async Task Mine(Dictionary miningParams, LookupResult lookupResult) + private static Dictionary GetMiningParameters(LookupResult lookupResult, string currentText, string? selectedDefinitions, int currentCharPosition, bool replaceLineBreakWithBrTag) + { + Dictionary miningParams = new() + { + [JLField.LocalTime] = DateTime.Now.ToString("s", CultureInfo.InvariantCulture), + [JLField.SourceText] = replaceLineBreakWithBrTag ? currentText.ReplaceLineEndings("
") : currentText, + [JLField.Sentence] = JapaneseUtils.FindSentence(currentText, currentCharPosition), + [JLField.DictionaryName] = lookupResult.Dict.Name, + [JLField.MatchedText] = lookupResult.MatchedText, + [JLField.DeconjugatedMatchedText] = lookupResult.DeconjugatedMatchedText, + [JLField.PrimarySpelling] = lookupResult.PrimarySpelling, + [JLField.PrimarySpellingWithOrthographyInfo] = lookupResult.PrimarySpellingOrthographyInfoList is not null + ? string.Create(CultureInfo.InvariantCulture, $"{lookupResult.PrimarySpelling} ({string.Join(", ", lookupResult.PrimarySpellingOrthographyInfoList)})") + : lookupResult.PrimarySpelling + }; + + if (lookupResult.Readings is not null) + { + string readings = string.Join(", ", lookupResult.Readings); + miningParams[JLField.Readings] = readings; + + miningParams[JLField.ReadingsWithOrthographyInfo] = lookupResult.ReadingsOrthographyInfoList is not null + ? LookupResultUtils.ReadingsToText(lookupResult.Readings, lookupResult.ReadingsOrthographyInfoList) + : readings; + } + + if (lookupResult.AlternativeSpellings is not null) + { + string alternativeSpellings = string.Join(", ", lookupResult.AlternativeSpellings); + miningParams[JLField.AlternativeSpellings] = alternativeSpellings; + + miningParams[JLField.AlternativeSpellingsWithOrthographyInfo] = lookupResult.AlternativeSpellingsOrthographyInfoList is not null + ? LookupResultUtils.ReadingsToText(lookupResult.AlternativeSpellings, lookupResult.AlternativeSpellingsOrthographyInfoList) + : alternativeSpellings; + } + + if (lookupResult.Frequencies is not null) + { + string? formattedFreq = LookupResultUtils.FrequenciesToText(lookupResult.Frequencies, true); + if (formattedFreq is not null) + { + miningParams[JLField.Frequencies] = formattedFreq; + miningParams[JLField.RawFrequencies] = string.Join(", ", lookupResult.Frequencies + .Where(static f => f.Freq is > 0 and < int.MaxValue) + .Select(static f => f.Freq)); + } + } + + if (lookupResult.FormattedDefinitions is not null) + { + string formattedDefinitions = replaceLineBreakWithBrTag + ? lookupResult.FormattedDefinitions.ReplaceLineEndings("
") + : lookupResult.FormattedDefinitions; + + miningParams[JLField.Definitions] = formattedDefinitions; + + if (selectedDefinitions is null) + { + miningParams[JLField.SelectedDefinitions] = formattedDefinitions; + } + } + + if (selectedDefinitions is not null) + { + miningParams[JLField.SelectedDefinitions] = replaceLineBreakWithBrTag + ? selectedDefinitions.ReplaceLineEndings("
") + : selectedDefinitions; + } + + if (lookupResult.EdictId > 0) + { + miningParams[JLField.EdictId] = lookupResult.EdictId.ToString(CultureInfo.InvariantCulture); + } + + if (lookupResult.DeconjugationProcess is not null) + { + miningParams[JLField.DeconjugationProcess] = lookupResult.DeconjugationProcess; + } + + if (lookupResult.KanjiComposition is not null) + { + miningParams[JLField.KanjiComposition] = lookupResult.KanjiComposition; + } + + if (lookupResult.KanjiStats is not null) + { + miningParams[JLField.KanjiStats] = lookupResult.KanjiStats; + } + + if (lookupResult.StrokeCount > 0) + { + miningParams[JLField.StrokeCount] = lookupResult.StrokeCount.ToString(CultureInfo.InvariantCulture); + } + + if (lookupResult.KanjiGrade > -1) + { + miningParams[JLField.KanjiGrade] = lookupResult.KanjiGrade.ToString(CultureInfo.InvariantCulture); + } + + if (lookupResult.OnReadings is not null) + { + miningParams[JLField.OnReadings] = string.Join(", ", lookupResult.OnReadings); + } + + if (lookupResult.KunReadings is not null) + { + miningParams[JLField.KunReadings] = string.Join(", ", lookupResult.KunReadings); + } + + if (lookupResult.NanoriReadings is not null) + { + miningParams[JLField.NanoriReadings] = string.Join(", ", lookupResult.NanoriReadings); + } + + if (lookupResult.RadicalNames is not null) + { + miningParams[JLField.RadicalNames] = string.Join(", ", lookupResult.RadicalNames); + } + + return miningParams; + } + + public static async Task MineToFile(LookupResult lookupResult, string currentText, string? selectedDefinitions, int currentCharPosition) + { + string filePath; + JLField[] jlFields; + if (DictUtils.s_wordDictTypes.Contains(lookupResult.Dict.Type)) + { + filePath = Path.Join(Utils.ResourcesPath, "mined_words.txt"); + jlFields = JLFieldUtils.JLFieldsForWordDicts; + } + else if (DictUtils.s_nameDictTypes.Contains(lookupResult.Dict.Type)) + { + filePath = Path.Join(Utils.ResourcesPath, "mined_names.txt"); + jlFields = JLFieldUtils.JLFieldsForNameDicts; + } + else if (DictUtils.s_kanjiDictTypes.Contains(lookupResult.Dict.Type)) + { + filePath = Path.Join(Utils.ResourcesPath, "mined_kanjis.txt"); + jlFields = JLFieldUtils.JLFieldsForKanjiDicts; + } + else + { + filePath = Path.Join(Utils.ResourcesPath, "mined_others.txt"); + jlFields = JLFieldUtils.JLFieldsForWordDicts; + } + + Dictionary miningParameters = GetMiningParameters(lookupResult, currentText, selectedDefinitions, currentCharPosition, false); + StringBuilder lineToMine = new(); + for (int i = 1; i < jlFields.Length; i++) + { + JLField jlField = jlFields[i]; + if (jlField is JLField.Audio or JLField.Image) + { + continue; + } + + string? jlFieldContent = miningParameters.GetValueOrDefault(jlField)?.ReplaceLineEndings("\\n").Replace("\t", " ", StringComparison.Ordinal).Trim(); + if (!string.IsNullOrEmpty(jlFieldContent)) + { + _ = lineToMine.Append(CultureInfo.InvariantCulture, $"{jlField.GetDescription()}: ") + .Append(jlFieldContent) + .Append(i < jlFields.Length - 1 ? '\t' : '\n'); + } + } + + await File.AppendAllTextAsync(filePath, lineToMine.ToString(), Encoding.UTF8).ConfigureAwait(false); + + Stats.IncrementStat(StatType.CardsMined); + + Utils.Frontend.Alert(AlertLevel.Success, string.Create(CultureInfo.InvariantCulture, $"Mined {lookupResult.PrimarySpelling}")); + Utils.Logger.Information("Mined {FoundSpelling}", lookupResult.PrimarySpelling); + } + + public static async Task Mine(LookupResult lookupResult, string currentText, string? selectedDefinitions, int currentCharPosition) { if (!CoreConfig.AnkiIntegration) { Utils.Frontend.Alert(AlertLevel.Error, "Please setup mining first in the preferences"); - return false; + return; } Dictionary? ankiConfigDict = await AnkiConfig.ReadAnkiConfig().ConfigureAwait(false); @@ -22,7 +198,7 @@ public static async Task Mine(Dictionary miningParams, Lo if (ankiConfigDict is null) { Utils.Frontend.Alert(AlertLevel.Error, "Please setup mining first in the preferences"); - return false; + return; } AnkiConfig? ankiConfig; @@ -49,7 +225,7 @@ public static async Task Mine(Dictionary miningParams, Lo if (ankiConfig is null) { Utils.Frontend.Alert(AlertLevel.Error, "Please setup mining first in the preferences"); - return false; + return; } Dictionary userFields = ankiConfig.Fields; @@ -102,6 +278,8 @@ public static async Task Mine(Dictionary miningParams, Lo { "allowDuplicate", CoreConfig.AllowDuplicateCards } }; + Dictionary miningParams = GetMiningParameters(lookupResult, currentText, selectedDefinitions, currentCharPosition, true); + Dictionary fields = ConvertFields(userFields, miningParams); Note note = new(ankiConfig.DeckName, ankiConfig.ModelName, fields, options, ankiConfig.Tags, audio, null, image); @@ -111,7 +289,7 @@ public static async Task Mine(Dictionary miningParams, Lo { Utils.Frontend.Alert(AlertLevel.Error, string.Create(CultureInfo.InvariantCulture, $"Mining failed for {lookupResult.PrimarySpelling}")); Utils.Logger.Error("Mining failed for {FoundSpelling}", lookupResult.PrimarySpelling); - return false; + return; } if (needsAudio && (audioData is null || Utils.GetMd5String(audioData) is Networking.Jpod101NoAudioMd5Hash)) @@ -131,7 +309,7 @@ public static async Task Mine(Dictionary miningParams, Lo await AnkiConnect.Sync().ConfigureAwait(false); } - return true; + Stats.IncrementStat(StatType.CardsMined); } /// diff --git a/JL.Core/Dicts/Options/AvailableDictOptions.cs b/JL.Core/Dicts/Options/AvailableDictOptions.cs index 407008ef..00d53659 100644 --- a/JL.Core/Dicts/Options/AvailableDictOptions.cs +++ b/JL.Core/Dicts/Options/AvailableDictOptions.cs @@ -108,3 +108,8 @@ public readonly record struct UseDBOption(bool Value) { [JsonIgnore] public static readonly DictType[] ValidDictTypes = DictUtils.s_dictTypesWithDBSupport; } + +public readonly record struct ShowPitchAccentWithDottedLines(bool Value) +{ + [JsonIgnore] public static readonly DictType[] ValidDictTypes = { DictType.PitchAccentYomichan }; +} diff --git a/JL.Core/Dicts/Options/DictOptions.cs b/JL.Core/Dicts/Options/DictOptions.cs index 85bc0d4d..7a02c81f 100644 --- a/JL.Core/Dicts/Options/DictOptions.cs +++ b/JL.Core/Dicts/Options/DictOptions.cs @@ -21,6 +21,7 @@ public sealed class DictOptions public AntonymOption? Antonym { get; } public LoanwordEtymologyOption? LoanwordEtymology { get; } public UseDBOption? UseDB { get; } + public ShowPitchAccentWithDottedLines? ShowPitchAccentWithDottedLines { get; } public DictOptions ( @@ -42,7 +43,8 @@ public DictOptions LoanwordEtymologyOption? loanwordEtymology = null, RelatedTermOption? relatedTerm = null, AntonymOption? antonym = null, - UseDBOption? useDB = null + UseDBOption? useDB = null, + ShowPitchAccentWithDottedLines? showPitchAccentWithDottedLines = null ) { NewlineBetweenDefinitions = newlineBetweenDefinitions; @@ -64,5 +66,6 @@ public DictOptions RelatedTerm = relatedTerm; Antonym = antonym; UseDB = useDB; + ShowPitchAccentWithDottedLines = showPitchAccentWithDottedLines; } } diff --git a/JL.Core/Freqs/FreqUtils.cs b/JL.Core/Freqs/FreqUtils.cs index 94bfaa92..58ab2fc8 100644 --- a/JL.Core/Freqs/FreqUtils.cs +++ b/JL.Core/Freqs/FreqUtils.cs @@ -20,25 +20,25 @@ public static class FreqUtils "VN (Nazeka)", new Freq(FreqType.Nazeka, "VN (Nazeka)", Path.Join(Utils.ResourcesPath, "freqlist_vns.json"), - true, 1, 57273, false, new FreqOptions(new UseDBOption(false))) + true, 1, 57273, false, new FreqOptions(new UseDBOption(false), new HigherValueMeansHigherFrequencyOption(false))) }, { "Narou (Nazeka)", new Freq(FreqType.Nazeka, "Narou (Nazeka)", Path.Join(Utils.ResourcesPath, "freqlist_narou.json"), - false, 2, 75588, false, new FreqOptions(new UseDBOption(false))) + false, 2, 75588, false, new FreqOptions(new UseDBOption(false), new HigherValueMeansHigherFrequencyOption(false))) }, { "Novel (Nazeka)", new Freq(FreqType.Nazeka, "Novel (Nazeka)", Path.Join(Utils.ResourcesPath, "freqlist_novels.json"), - false, 3, 114348, false, new FreqOptions(new UseDBOption(false))) + false, 3, 114348, false, new FreqOptions(new UseDBOption(false), new HigherValueMeansHigherFrequencyOption(false))) } }; - internal static readonly FreqType[] s_freqTypesWithDBSupport = { + internal static readonly FreqType[] s_allFreqDicts = { FreqType.Nazeka, FreqType.Yomichan, FreqType.YomichanKanji diff --git a/JL.Core/Freqs/Options/AvailableFreqOptions.cs b/JL.Core/Freqs/Options/AvailableFreqOptions.cs index b95710ab..f799f292 100644 --- a/JL.Core/Freqs/Options/AvailableFreqOptions.cs +++ b/JL.Core/Freqs/Options/AvailableFreqOptions.cs @@ -3,5 +3,10 @@ namespace JL.Core.Freqs.Options; public readonly record struct UseDBOption(bool Value) { - [JsonIgnore] public static readonly FreqType[] ValidFreqTypes = FreqUtils.s_freqTypesWithDBSupport; + [JsonIgnore] public static readonly FreqType[] ValidFreqTypes = FreqUtils.s_allFreqDicts; +} + +public readonly record struct HigherValueMeansHigherFrequencyOption(bool Value) +{ + [JsonIgnore] public static readonly FreqType[] ValidFreqTypes = FreqUtils.s_allFreqDicts; } diff --git a/JL.Core/Freqs/Options/FreqOptions.cs b/JL.Core/Freqs/Options/FreqOptions.cs index 71c42a4e..96654495 100644 --- a/JL.Core/Freqs/Options/FreqOptions.cs +++ b/JL.Core/Freqs/Options/FreqOptions.cs @@ -2,9 +2,11 @@ namespace JL.Core.Freqs.Options; public sealed class FreqOptions { public UseDBOption? UseDB { get; } + public HigherValueMeansHigherFrequencyOption? HigherValueMeansHigherFrequency { get; } - public FreqOptions(UseDBOption? useDB = null) + public FreqOptions(UseDBOption? useDB = null,HigherValueMeansHigherFrequencyOption? higherValueMeansHigherFrequency = null) { UseDB = useDB; + HigherValueMeansHigherFrequency = higherValueMeansHigherFrequency; } } diff --git a/JL.Core/JL.Core.csproj b/JL.Core/JL.Core.csproj index 55afd99a..e24f4478 100644 --- a/JL.Core/JL.Core.csproj +++ b/JL.Core/JL.Core.csproj @@ -11,9 +11,9 @@ - + - + diff --git a/JL.Core/Lookup/LookupFrequencyResult.cs b/JL.Core/Lookup/LookupFrequencyResult.cs index 707fc346..64902bbb 100644 --- a/JL.Core/Lookup/LookupFrequencyResult.cs +++ b/JL.Core/Lookup/LookupFrequencyResult.cs @@ -5,9 +5,12 @@ public sealed class LookupFrequencyResult public string Name { get; } public int Freq { get; } - internal LookupFrequencyResult(string name, int freq) + public bool HigherValueMeansHigherFrequency { get; } + + internal LookupFrequencyResult(string name, int freq, bool higherValueMeansHigherFrequency) { Name = name; Freq = freq; + HigherValueMeansHigherFrequency = higherValueMeansHigherFrequency; } } diff --git a/JL.Core/Lookup/LookupResultUtils.cs b/JL.Core/Lookup/LookupResultUtils.cs new file mode 100644 index 00000000..11995040 --- /dev/null +++ b/JL.Core/Lookup/LookupResultUtils.cs @@ -0,0 +1,157 @@ +using System.Globalization; +using System.Text; + +namespace JL.Core.Lookup; +public class LookupResultUtils +{ + internal static string? ProcessDeconjugationProcess(List>? processList) + { + if (processList is null) + { + return null; + } + + StringBuilder deconjugation = new(); + bool first = true; + + for (int i = 0; i < processList.Count; i++) + { + List form = processList[i]; + + StringBuilder formText = new(); + int added = 0; + + for (int j = form.Count - 1; j >= 0; j--) + { + string info = form[j]; + + if (info is "") + { + continue; + } + + if (info.StartsWith('(') && info.EndsWith(')') && j is not 0) + { + continue; + } + + if (added > 0) + { + _ = formText.Append('→'); + } + + ++added; + _ = formText.Append(info); + } + + if (formText.Length is not 0) + { + _ = first + ? deconjugation.Append(CultureInfo.InvariantCulture, $"~{formText}") + : deconjugation.Append(CultureInfo.InvariantCulture, $"; {formText}"); + } + + first = false; + } + + return deconjugation.Length is 0 ? null : deconjugation.ToString(); + } + + public static string GradeToText(int grade) + { + string gradeText = grade switch + { + >= 1 and <= 6 => string.Create(CultureInfo.InvariantCulture, $"{grade} (Kyouiku)"), + 8 => string.Create(CultureInfo.InvariantCulture, $"{grade} (Jouyou)"), + <= 10 => string.Create(CultureInfo.InvariantCulture, $"{grade} (Jinmeiyou)"), + _ => "Hyougai" + }; + + return gradeText; + } + + public static string? FrequenciesToText(List frequencies, bool forMining) + { + if (!forMining && frequencies.Count is 1 && frequencies[0].Freq is > 0 and < int.MaxValue) + { + return string.Create(CultureInfo.InvariantCulture, $"#{frequencies[0].Freq}"); + } + + if (frequencies.Count > 0) + { + int freqResultCount = 0; + StringBuilder sb = new(); + foreach (LookupFrequencyResult lookupFreqResult in frequencies) + { + if (lookupFreqResult.Freq is > 0 and < int.MaxValue) + { + _ = sb.Append(CultureInfo.InvariantCulture, $"{lookupFreqResult.Name}: {lookupFreqResult.Freq}, "); + ++freqResultCount; + } + } + + if (freqResultCount > 0) + { + return sb.Remove(sb.Length - 2, 2).ToString(); + } + } + + return null; + } + + public static string ReadingsToText(string[] readings, string[]?[] rOrthographyInfoList) + { + StringBuilder sb = new(); + + for (int index = 0; index < readings.Length; index++) + { + _ = sb.Append(readings[index]); + + if (index < rOrthographyInfoList.Length) + { + string[]? rOrthographyInfo = rOrthographyInfoList[index]; + if (rOrthographyInfo is not null) + { + _ = sb.Append(CultureInfo.InvariantCulture, $" ({string.Join(", ", rOrthographyInfo)})"); + } + } + + if (index != readings.Length - 1) + { + _ = sb.Append(", "); + } + } + + return sb.ToString(); + } + + public static string AlternativeSpellingsToText(string[] alternativeSpellings, string[]?[] aOrthographyInfoList) + { + StringBuilder sb = new(); + + _ = sb.Append('('); + + for (int index = 0; index < alternativeSpellings.Length; index++) + { + _ = sb.Append(alternativeSpellings[index]); + + if (index < aOrthographyInfoList.Length) + { + string[]? aOrthographyInfo = aOrthographyInfoList[index]; + if (aOrthographyInfo is not null) + { + _ = sb.Append(CultureInfo.InvariantCulture, $" ({string.Join(", ", aOrthographyInfo)})"); + } + } + + if (index != alternativeSpellings.Length - 1) + { + _ = sb.Append(", "); + } + } + + _ = sb.Append(')'); + + return sb.ToString(); + } +} diff --git a/JL.Core/Lookup/LookupUtils.cs b/JL.Core/Lookup/LookupUtils.cs index d1fb2f46..6f7b0d07 100644 --- a/JL.Core/Lookup/LookupUtils.cs +++ b/JL.Core/Lookup/LookupUtils.cs @@ -1,7 +1,5 @@ using System.Collections.Concurrent; using System.Diagnostics; -using System.Globalization; -using System.Text; using JL.Core.Deconjugation; using JL.Core.Dicts; using JL.Core.Dicts.CustomNameDict; @@ -36,14 +34,14 @@ public static class LookupUtils s_lastLookupTime = preciseTimeNow; - ConcurrentBag lookupResults = new(); - List dbFreqs = FreqUtils.FreqDicts.Values.Where(static f => f is { Active: true, Type: not FreqType.YomichanKanji } && (f.Options?.UseDB?.Value ?? false) && f.Ready).ToList(); _ = DictUtils.SingleDictTypeDicts.TryGetValue(DictType.PitchAccentYomichan, out Dict? pitchDict); bool pitchDictIsActive = pitchDict?.Active ?? false; bool useDBForPitchDict = pitchDictIsActive && (pitchDict!.Options?.UseDB?.Value ?? false) && pitchDict.Ready; + ConcurrentBag lookupResults = new(); + if (CoreConfig.KanjiMode) { _ = Parallel.ForEach(DictUtils.Dicts.Values.ToList(), dict => @@ -355,7 +353,20 @@ private static List SortLookupResults(IEnumerable lo return 1; }) - .ThenBy(static lookupResult => lookupResult.Frequencies?.Count > 0 ? lookupResult.Frequencies[0].Freq : int.MaxValue) + .ThenBy(static lookupResult => + { + if (lookupResult.Frequencies?.Count > 0) + { + LookupFrequencyResult freqResult = lookupResult.Frequencies[0]; + return !freqResult.HigherValueMeansHigherFrequency + ? freqResult.Freq + : freqResult.Freq is int.MaxValue + ? int.MaxValue + : int.MaxValue - freqResult.Freq; + } + + return int.MaxValue; + }) //.ThenBy(static lookupResult => //{ // int index = lookupResult.Readings is not null @@ -443,8 +454,6 @@ private static (bool tryLongVowelConversion, int succAttempt) GetWordResultsHelp private static Dictionary GetWordResults(List textList, List textInHiraganaList, List> deconjugationResultsList, Dict dict, bool useDB, GetRecordsFromDB? getRecordsFromDB) { - Dictionary results = new(); - Dictionary>? dbWordDict = null; Dictionary>? dbVerbDict = null; @@ -456,6 +465,7 @@ private static Dictionary GetWordResults(List results = new(); int succAttempt = 0; for (int i = 0; i < textList.Count; i++) { @@ -495,13 +505,11 @@ private static Dictionary GetWordResults(List GetValidDeconjugatedResults(Dict dict, Form deconjugationResult, IList dictResults) { - List resultsList = new(); + string? lastTag = deconjugationResult.Tags.Count > 0 + ? deconjugationResult.Tags[^1] + : null; - string lastTag = ""; - if (deconjugationResult.Tags.Count > 0) - { - lastTag = deconjugationResult.Tags.Last(); - } + List resultsList = new(); switch (dict.Type) { @@ -512,8 +520,7 @@ private static List GetValidDeconjugatedResults(Dict dict, Form dec { JmdictRecord dictResult = (JmdictRecord)dictResults[i]; - if (deconjugationResult.Tags.Count is 0 - || dictResult.WordClasses.SelectMany(static pos => pos).Contains(lastTag)) + if (lastTag is null || dictResult.WordClasses.SelectMany(static pos => pos).Contains(lastTag)) { resultsList.Add(dictResult); } @@ -529,8 +536,7 @@ private static List GetValidDeconjugatedResults(Dict dict, Form dec { CustomWordRecord dictResult = (CustomWordRecord)dictResults[i]; - if (deconjugationResult.Tags.Count is 0 - || dictResult.WordClasses.Contains(lastTag)) + if (lastTag is null || dictResult.WordClasses.Contains(lastTag)) { resultsList.Add(dictResult); } @@ -568,8 +574,7 @@ private static List GetValidDeconjugatedResults(Dict dict, Form dec { EpwingYomichanRecord dictResult = (EpwingYomichanRecord)dictResults[i]; - if (deconjugationResult.Tags.Count is 0 || - (dictResult.WordClasses?.Contains(lastTag) ?? false)) + if (lastTag is null || (dictResult.WordClasses?.Contains(lastTag) ?? false)) { resultsList.Add(dictResult); } @@ -585,7 +590,7 @@ private static List GetValidDeconjugatedResults(Dict dict, Form dec && (jmdictWordClassResult.Readings?.Contains(dictResult.Reading ?? string.Empty) ?? string.IsNullOrEmpty(dictResult.Reading))) { - if (jmdictWordClassResult.WordClasses.Contains(lastTag)) + if (lastTag is not null && jmdictWordClassResult.WordClasses.Contains(lastTag)) { resultsList.Add(dictResult); break; @@ -626,7 +631,7 @@ private static List GetValidDeconjugatedResults(Dict dict, Form dec && (jmdictWordClassResult.Readings?.Contains(dictResult.Reading ?? "") ?? string.IsNullOrEmpty(dictResult.Reading))) { - if (jmdictWordClassResult.WordClasses.Contains(lastTag)) + if (lastTag is not null && jmdictWordClassResult.WordClasses.Contains(lastTag)) { resultsList.Add(dictResult); break; @@ -905,7 +910,7 @@ private static List BuildJmdictResult( deconjugatedMatchedText: wordResult.DeconjugatedMatchedText, edictId: jmdictResult.Id, alternativeSpellings: jmdictResult.AlternativeSpellings, - deconjugationProcess: ProcessDeconjugationProcess(wordResult.Processes?[i]), + deconjugationProcess: LookupResultUtils.ProcessDeconjugationProcess(wordResult.Processes?[i]), frequencies: GetWordFrequencies(jmdictResult, frequencyDicts), primarySpellingOrthographyInfoList: jmdictResult.PrimarySpellingOrthographyInfo, readingsOrthographyInfoList: jmdictResult.ReadingsOrthographyInfo, @@ -1094,7 +1099,7 @@ private static List BuildEpwingYomichanResult( primarySpelling: epwingResult.PrimarySpelling, matchedText: wordResult.MatchedText, deconjugatedMatchedText: wordResult.DeconjugatedMatchedText, - deconjugationProcess: ProcessDeconjugationProcess(wordResult.Processes?[i]), + deconjugationProcess: LookupResultUtils.ProcessDeconjugationProcess(wordResult.Processes?[i]), frequencies: GetWordFrequencies(epwingResult, frequencyDicts), dict: wordResult.Dict, readings: epwingResult.Reading is not null @@ -1152,7 +1157,7 @@ private static ConcurrentBag BuildEpwingNazekaResult( alternativeSpellings: epwingResult.AlternativeSpellings, matchedText: wordResult.MatchedText, deconjugatedMatchedText: wordResult.DeconjugatedMatchedText, - deconjugationProcess: ProcessDeconjugationProcess(wordResult.Processes?[i]), + deconjugationProcess: LookupResultUtils.ProcessDeconjugationProcess(wordResult.Processes?[i]), frequencies: GetWordFrequencies(epwingResult, frequencyDicts), dict: wordResult.Dict, readings: epwingResult.Reading is not null @@ -1211,7 +1216,7 @@ private static ConcurrentBag BuildCustomWordResult( matchedText: wordResult.MatchedText, deconjugatedMatchedText: wordResult.DeconjugatedMatchedText, deconjugationProcess: customWordDictResult.HasUserDefinedWordClass - ? ProcessDeconjugationProcess(wordResult.Processes?[i]) + ? LookupResultUtils.ProcessDeconjugationProcess(wordResult.Processes?[i]) : null, dict: wordResult.Dict, readings: customWordDictResult.Readings, @@ -1256,7 +1261,7 @@ private static ConcurrentBag BuildCustomNameResult( primarySpelling: customNameDictResult.PrimarySpelling, matchedText: customNameResult.Value.MatchedText, deconjugatedMatchedText: customNameResult.Value.DeconjugatedMatchedText, - frequencies: new List { new(customNameResult.Value.Dict.Name, -freq) }, + frequencies: new List { new(customNameResult.Value.Dict.Name, -freq, false) }, dict: customNameResult.Value.Dict, readings: customNameDictResult.Reading is not null ? new[] { customNameDictResult.Reading } @@ -1288,13 +1293,13 @@ private static List GetWordFrequencies(IGetFrequency reco { if (freqDictsFromDB?.TryGetValue(freq.Name, out Dictionary>? freqDict) ?? false) { - freqsList.Add(new LookupFrequencyResult(freq.Name, record.GetFrequencyFromDB(freqDict))); + freqsList.Add(new LookupFrequencyResult(freq.Name, record.GetFrequencyFromDB(freqDict), freq.Options?.HigherValueMeansHigherFrequency?.Value ?? false)); } } else { - freqsList.Add(new LookupFrequencyResult(freq.Name, record.GetFrequency(freq))); + freqsList.Add(new LookupFrequencyResult(freq.Name, record.GetFrequency(freq), freq.Options?.HigherValueMeansHigherFrequency?.Value ?? false)); } } @@ -1325,7 +1330,7 @@ private static List GetYomichanKanjiFrequencies(string ka int frequency = freqResultList.FirstOrDefault().Frequency; if (frequency is not 0) { - freqsList.Add(new LookupFrequencyResult(kanjiFreq.Name, frequency)); + freqsList.Add(new LookupFrequencyResult(kanjiFreq.Name, frequency, false)); } } } @@ -1339,63 +1344,10 @@ private static List GetKanjidicFrequencies(string kanji, if (frequency is not 0) { - freqsList.Add(new LookupFrequencyResult("KANJIDIC2", frequency)); + freqsList.Add(new LookupFrequencyResult("KANJIDIC2", frequency, false)); } freqsList.AddRange(GetYomichanKanjiFrequencies(kanji)); return freqsList; } - - private static string? ProcessDeconjugationProcess(List>? processList) - { - if (processList is null) - { - return null; - } - - StringBuilder deconjugation = new(); - bool first = true; - - for (int i = 0; i < processList.Count; i++) - { - List form = processList[i]; - - StringBuilder formText = new(); - int added = 0; - - for (int j = form.Count - 1; j >= 0; j--) - { - string info = form[j]; - - if (info is "") - { - continue; - } - - if (info.StartsWith('(') && info.EndsWith(')') && j is not 0) - { - continue; - } - - if (added > 0) - { - _ = formText.Append('→'); - } - - ++added; - _ = formText.Append(info); - } - - if (formText.Length is not 0) - { - _ = first - ? deconjugation.Append(CultureInfo.InvariantCulture, $"~{formText}") - : deconjugation.Append(CultureInfo.InvariantCulture, $"; {formText}"); - } - - first = false; - } - - return deconjugation.Length is 0 ? null : deconjugation.ToString(); - } } diff --git a/JL.Windows/ConfigManager.cs b/JL.Windows/ConfigManager.cs index 6c2d75dd..a7e1ec9f 100644 --- a/JL.Windows/ConfigManager.cs +++ b/JL.Windows/ConfigManager.cs @@ -170,6 +170,7 @@ internal static class ConfigManager public static bool GlobalHotKeys { get; private set; } = false; public static bool StopIncreasingTimeStatWhenMinimized { get; private set; } = true; public static bool StripPunctuationBeforeCalculatingCharacterCount { get; private set; } = true; + public static bool MineToFileInsteadOfAnki { get; private set; } = true; #endregion @@ -256,6 +257,7 @@ public static void ApplyPreferences() GlobalHotKeys = GetValueFromConfig(config, GlobalHotKeys, nameof(GlobalHotKeys), bool.TryParse); StopIncreasingTimeStatWhenMinimized = GetValueFromConfig(config, StopIncreasingTimeStatWhenMinimized, nameof(StopIncreasingTimeStatWhenMinimized), bool.TryParse); StripPunctuationBeforeCalculatingCharacterCount = GetValueFromConfig(config, StripPunctuationBeforeCalculatingCharacterCount, nameof(StripPunctuationBeforeCalculatingCharacterCount), bool.TryParse); + MineToFileInsteadOfAnki = GetValueFromConfig(config, MineToFileInsteadOfAnki, nameof(MineToFileInsteadOfAnki), bool.TryParse); CheckForJLUpdatesOnStartUp = GetValueFromConfig(config, CheckForJLUpdatesOnStartUp, nameof(CheckForJLUpdatesOnStartUp), bool.TryParse); AlwaysOnTop = GetValueFromConfig(config, AlwaysOnTop, nameof(AlwaysOnTop), bool.TryParse); mainWindow.Topmost = AlwaysOnTop; @@ -825,6 +827,7 @@ public static void LoadPreferences(PreferencesWindow preferenceWindow) preferenceWindow.GlobalHotKeysCheckBox.IsChecked = GlobalHotKeys; preferenceWindow.StopIncreasingTimeStatWhenMinimizedCheckBox.IsChecked = StopIncreasingTimeStatWhenMinimized; preferenceWindow.StripPunctuationBeforeCalculatingCharacterCountCheckBox.IsChecked = StripPunctuationBeforeCalculatingCharacterCount; + preferenceWindow.MineToFileInsteadOfAnkiCheckBox.IsChecked = MineToFileInsteadOfAnki; preferenceWindow.AlwaysOnTopCheckBox.IsChecked = AlwaysOnTop; preferenceWindow.RequireLookupKeyPressCheckBox.IsChecked = RequireLookupKeyPress; preferenceWindow.DisableHotkeysCheckBox.IsChecked = DisableHotkeys; @@ -1121,6 +1124,8 @@ public static async Task SavePreferences(PreferencesWindow preferenceWindow) preferenceWindow.StopIncreasingTimeStatWhenMinimizedCheckBox.IsChecked.ToString(); settings[nameof(StripPunctuationBeforeCalculatingCharacterCount)].Value = preferenceWindow.StripPunctuationBeforeCalculatingCharacterCountCheckBox.IsChecked.ToString(); + settings[nameof(MineToFileInsteadOfAnki)].Value = + preferenceWindow.MineToFileInsteadOfAnkiCheckBox.IsChecked.ToString(); settings[nameof(CheckForJLUpdatesOnStartUp)].Value = preferenceWindow.CheckForJLUpdatesOnStartUpCheckBox.IsChecked.ToString(); diff --git a/JL.Windows/GUI/EditDictionaryWindow.xaml.cs b/JL.Windows/GUI/EditDictionaryWindow.xaml.cs index e28204b4..b0d6ad46 100644 --- a/JL.Windows/GUI/EditDictionaryWindow.xaml.cs +++ b/JL.Windows/GUI/EditDictionaryWindow.xaml.cs @@ -5,6 +5,7 @@ using JL.Core.Dicts.Options; using JL.Core.Utilities; using JL.Windows.GUI.UserControls; +using JL.Windows.Utilities; using Microsoft.Data.Sqlite; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using Path = System.IO.Path; @@ -85,6 +86,19 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) DictOptions options = _dictOptionsControl.GetDictOptions(_dict.Type); + if (_dict.Type is DictType.PitchAccentYomichan) + { + bool oldDottedLinesOption = _dict.Options?.ShowPitchAccentWithDottedLines?.Value ?? true; + bool newDottedLinesOption = options.ShowPitchAccentWithDottedLines?.Value ?? true; + + if (oldDottedLinesOption != newDottedLinesOption) + { + PopupWindowUtils.StrokeDashArray = newDottedLinesOption + ? new DoubleCollection() { 1, 1 } + : new DoubleCollection() { 1, 0 }; + } + } + if (_dict.Options?.Examples?.Value != options.Examples?.Value) { _dict.Contents.Clear(); diff --git a/JL.Windows/GUI/PopupWindow.xaml.cs b/JL.Windows/GUI/PopupWindow.xaml.cs index e72a6078..1397e87d 100644 --- a/JL.Windows/GUI/PopupWindow.xaml.cs +++ b/JL.Windows/GUI/PopupWindow.xaml.cs @@ -6,6 +6,7 @@ using System.Windows.Media; using Caching; using JL.Core; +using JL.Core.Anki; using JL.Core.Audio; using JL.Core.Dicts; using JL.Core.Lookup; @@ -549,7 +550,7 @@ public StackPanel PrepareResultStackPanel(LookupResult result, int index, int re && (pitchDictIsActive || (result.KunReadings is null && result.OnReadings is null))) { string readingsText = showROrthographyInfo && result.ReadingsOrthographyInfoList is not null - ? PopupWindowUtils.ReadingsToText(result.Readings, result.ReadingsOrthographyInfoList) + ? LookupResultUtils.ReadingsToText(result.Readings, result.ReadingsOrthographyInfoList) : string.Join(", ", result.Readings); if (MiningMode) @@ -656,7 +657,7 @@ public StackPanel PrepareResultStackPanel(LookupResult result, int index, int re if (result.AlternativeSpellings is not null) { string alternativeSpellingsText = showAOrthographyInfo && result.AlternativeSpellingsOrthographyInfoList is not null - ? PopupWindowUtils.AlternativeSpellingsToText(result.AlternativeSpellings, result.AlternativeSpellingsOrthographyInfoList) + ? LookupResultUtils.AlternativeSpellingsToText(result.AlternativeSpellings, result.AlternativeSpellingsOrthographyInfoList) : string.Create(CultureInfo.InvariantCulture, $"({string.Join(", ", result.AlternativeSpellings)})"); if (MiningMode) @@ -726,7 +727,7 @@ public StackPanel PrepareResultStackPanel(LookupResult result, int index, int re if (result.Frequencies is not null) { - string? freqText = PopupWindowUtils.FrequenciesToText(result.Frequencies, false); + string? freqText = LookupResultUtils.FrequenciesToText(result.Frequencies, false); if (freqText is not null) { @@ -1027,7 +1028,7 @@ public StackPanel PrepareResultStackPanel(LookupResult result, int index, int re TextBlock gradeTextBlock = new() { Name = nameof(result.KanjiGrade), - Text = string.Create(CultureInfo.InvariantCulture, $"Grade: {PopupWindowUtils.GradeToText(result.KanjiGrade)}"), + Text = string.Create(CultureInfo.InvariantCulture, $"Grade: {LookupResultUtils.GradeToText(result.KanjiGrade)}"), Foreground = ConfigManager.DefinitionsColor, FontSize = ConfigManager.DefinitionsFontSize, Margin = new Thickness(2, 2, 2, 2), @@ -1239,7 +1240,14 @@ private async void PrimarySpelling_PreviewMouseUp(object sender, MouseButtonEven HidePopup(); - await PopupWindowUtils.Mine(LastLookupResults[listViewItemIndex], _currentText, selectedDefinitions, _currentCharPosition).ConfigureAwait(false); + if (ConfigManager.MineToFileInsteadOfAnki) + { + await Mining.MineToFile(LastLookupResults[listViewItemIndex], _currentText, selectedDefinitions, _currentCharPosition).ConfigureAwait(false); + } + else + { + await Mining.Mine(LastLookupResults[listViewItemIndex], _currentText, selectedDefinitions, _currentCharPosition).ConfigureAwait(false); + } } private void ShowAddNameWindow() @@ -1621,7 +1629,14 @@ public async Task HandleHotKey(KeyGesture keyGesture) HidePopup(); - await PopupWindowUtils.Mine(LastLookupResults[index], _currentText, selectedDefinitions, _currentCharPosition).ConfigureAwait(false); + if (ConfigManager.MineToFileInsteadOfAnki) + { + await Mining.MineToFile(LastLookupResults[index], _currentText, selectedDefinitions, _currentCharPosition).ConfigureAwait(false); + } + else + { + await Mining.Mine(LastLookupResults[index], _currentText, selectedDefinitions, _currentCharPosition).ConfigureAwait(false); + } } } diff --git a/JL.Windows/GUI/PreferencesWindow.xaml b/JL.Windows/GUI/PreferencesWindow.xaml index 04e012fd..d7c9c3b5 100644 --- a/JL.Windows/GUI/PreferencesWindow.xaml +++ b/JL.Windows/GUI/PreferencesWindow.xaml @@ -1477,6 +1477,17 @@ + + + + + + + + + diff --git a/JL.Windows/GUI/UserControls/DictOptionsControl.xaml.cs b/JL.Windows/GUI/UserControls/DictOptionsControl.xaml.cs index 377b14b8..ec651751 100644 --- a/JL.Windows/GUI/UserControls/DictOptionsControl.xaml.cs +++ b/JL.Windows/GUI/UserControls/DictOptionsControl.xaml.cs @@ -145,6 +145,12 @@ public DictOptions GetDictOptions(DictType type) useDBOption = new UseDBOption(UseDBCheckBox.IsChecked!.Value); } + ShowPitchAccentWithDottedLines? showPitchAccentWithDottedLines = null; + if (ShowPitchAccentWithDottedLines.ValidDictTypes.Contains(type)) + { + showPitchAccentWithDottedLines = new ShowPitchAccentWithDottedLines(ShowPitchAccentWithDottedLinesCheckBox.IsChecked!.Value); + } + DictOptions options = new( newlineOption, examplesOption, @@ -164,7 +170,8 @@ public DictOptions GetDictOptions(DictType type) loanwordEtymology, relatedTermOption, antonymOption, - useDBOption); + useDBOption, + showPitchAccentWithDottedLines); return options; } @@ -306,6 +313,14 @@ public void GenerateDictOptionsElements(DictType dictType) showDictOptions = true; } + ShowPitchAccentWithDottedLines? showPitchAccentWithDottedLines = null; + if (ShowPitchAccentWithDottedLines.ValidDictTypes.Contains(dictType)) + { + ShowPitchAccentWithDottedLinesCheckBox.IsChecked = true; + ShowPitchAccentWithDottedLinesCheckBox.Visibility = Visibility.Visible; + showDictOptions = true; + } + if (showDictOptions) { OptionsTextBlock.Visibility = Visibility.Visible; @@ -450,6 +465,13 @@ public void GenerateDictOptionsElements(Dict dict) showDictOptions = true; } + if (ShowPitchAccentWithDottedLines.ValidDictTypes.Contains(dict.Type)) + { + ShowPitchAccentWithDottedLinesCheckBox.IsChecked = dict.Options?.ShowPitchAccentWithDottedLines?.Value ?? true; + ShowPitchAccentWithDottedLinesCheckBox.Visibility = Visibility.Visible; + showDictOptions = true; + } + if (showDictOptions) { OptionsTextBlock.Visibility = Visibility.Visible; diff --git a/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml b/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml index d179e940..9914a154 100644 --- a/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml +++ b/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml @@ -18,6 +18,13 @@ HorizontalAlignment="Left" Style="{StaticResource TextBlockDefault}" /> + + + + diff --git a/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml.cs b/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml.cs index 1602b5c6..0b898382 100644 --- a/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml.cs +++ b/JL.Windows/GUI/UserControls/FreqOptionsControl.xaml.cs @@ -20,7 +20,13 @@ public FreqOptions GetFreqOptions(FreqType type) useDBOption = new UseDBOption(UseDBCheckBox.IsChecked!.Value); } - FreqOptions options = new(useDBOption); + HigherValueMeansHigherFrequencyOption? higherValueMeansHigherFrequencyOption = null; + if (HigherValueMeansHigherFrequencyOption.ValidFreqTypes.Contains(type)) + { + higherValueMeansHigherFrequencyOption = new HigherValueMeansHigherFrequencyOption(HigherValueMeansHigherFrequencyCheckBox.IsChecked!.Value); + } + + FreqOptions options = new(useDBOption, higherValueMeansHigherFrequencyOption); return options; } @@ -35,6 +41,13 @@ public void GenerateFreqOptionsElements(FreqType freqType) showFreqOptions = true; } + if (HigherValueMeansHigherFrequencyOption.ValidFreqTypes.Contains(freqType)) + { + HigherValueMeansHigherFrequencyCheckBox.IsChecked = false; + HigherValueMeansHigherFrequencyCheckBox.Visibility = Visibility.Visible; + showFreqOptions = true; + } + if (showFreqOptions) { OptionsTextBlock.Visibility = Visibility.Visible; @@ -52,6 +65,13 @@ public void GenerateFreqOptionsElements(Freq freq) showFreqOptions = true; } + if (HigherValueMeansHigherFrequencyOption.ValidFreqTypes.Contains(freq.Type)) + { + HigherValueMeansHigherFrequencyCheckBox.IsChecked = freq.Options?.HigherValueMeansHigherFrequency?.Value ?? false; + HigherValueMeansHigherFrequencyCheckBox.Visibility = Visibility.Visible; + showFreqOptions = true; + } + if (showFreqOptions) { OptionsTextBlock.Visibility = Visibility.Visible; diff --git a/JL.Windows/Utilities/PopupWindowUtils.cs b/JL.Windows/Utilities/PopupWindowUtils.cs index 9a2b56c6..46492eec 100644 --- a/JL.Windows/Utilities/PopupWindowUtils.cs +++ b/JL.Windows/Utilities/PopupWindowUtils.cs @@ -1,15 +1,11 @@ using System.Globalization; -using System.Text; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; -using JL.Core.Anki; using JL.Core.Dicts; using JL.Core.Dicts.PitchAccent; -using JL.Core.Lookup; -using JL.Core.Statistics; using JL.Core.Utilities; using JL.Windows.GUI; @@ -17,105 +13,7 @@ namespace JL.Windows.Utilities; internal static class PopupWindowUtils { - private static readonly DoubleCollection s_strokeDashArray = new() { 1, 1 }; - - public static string GradeToText(int grade) - { - string gradeText = grade switch - { - >= 1 and <= 6 => string.Create(CultureInfo.InvariantCulture, $"{grade} (Kyouiku)"), - 8 => string.Create(CultureInfo.InvariantCulture, $"{grade} (Jouyou)"), - <= 10 => string.Create(CultureInfo.InvariantCulture, $"{grade} (Jinmeiyou)"), - _ => "Hyougai" - }; - - return gradeText; - } - - public static string? FrequenciesToText(List frequencies, bool forMining) - { - if (!forMining && frequencies.Count is 1 && frequencies[0].Freq is > 0 and < int.MaxValue) - { - return string.Create(CultureInfo.InvariantCulture, $"#{frequencies[0].Freq}"); - } - - if (frequencies.Count > 0) - { - int freqResultCount = 0; - StringBuilder sb = new(); - foreach (LookupFrequencyResult lookupFreqResult in frequencies) - { - if (lookupFreqResult.Freq is > 0 and < int.MaxValue) - { - _ = sb.Append(CultureInfo.InvariantCulture, $"{lookupFreqResult.Name}: {lookupFreqResult.Freq}, "); - ++freqResultCount; - } - } - - if (freqResultCount > 0) - { - return sb.Remove(sb.Length - 2, 2).ToString(); - } - } - - return null; - } - - public static string ReadingsToText(string[] readings, string[]?[] rOrthographyInfoList) - { - StringBuilder sb = new(); - - for (int index = 0; index < readings.Length; index++) - { - _ = sb.Append(readings[index]); - - if (index < rOrthographyInfoList.Length) - { - string[]? rOrthographyInfo = rOrthographyInfoList[index]; - if (rOrthographyInfo is not null) - { - _ = sb.Append(CultureInfo.InvariantCulture, $" ({string.Join(", ", rOrthographyInfo)})"); - } - } - - if (index != readings.Length - 1) - { - _ = sb.Append(", "); - } - } - - return sb.ToString(); - } - - public static string AlternativeSpellingsToText(string[] alternativeSpellings, string[]?[] aOrthographyInfoList) - { - StringBuilder sb = new(); - - _ = sb.Append('('); - - for (int index = 0; index < alternativeSpellings.Length; index++) - { - _ = sb.Append(alternativeSpellings[index]); - - if (index < aOrthographyInfoList.Length) - { - string[]? aOrthographyInfo = aOrthographyInfoList[index]; - if (aOrthographyInfo is not null) - { - _ = sb.Append(CultureInfo.InvariantCulture, $" ({string.Join(", ", aOrthographyInfo)})"); - } - } - - if (index != alternativeSpellings.Length - 1) - { - _ = sb.Append(", "); - } - } - - _ = sb.Append(')'); - - return sb.ToString(); - } + public static DoubleCollection StrokeDashArray { get; set; } = new() { 1, 1 }; public static Grid CreatePitchAccentGrid(string primarySpelling, string[]? alternativeSpellings, string[]? readings, string[] splitReadingsWithRInfo, double leftMargin, Dict dict, Dictionary>? pitchRecordDict) @@ -177,7 +75,7 @@ public static Grid CreatePitchAccentGrid(string primarySpelling, string[]? alter { StrokeThickness = 2, Stroke = DictOptionManager.PitchAccentMarkerColor, - StrokeDashArray = s_strokeDashArray + StrokeDashArray = StrokeDashArray }; bool lowPitch = false; @@ -305,126 +203,4 @@ public static void ShowMiningModeResults(PopupWindow popupWindow) SetPopupAutoHideTimer(); } } - - public static async Task Mine(LookupResult lookupResult, string currentText, string? selectedDefinitions, int currentCharPosition) - { - Dictionary miningParams = new() - { - [JLField.LocalTime] = DateTime.Now.ToString("s", CultureInfo.InvariantCulture), - [JLField.SourceText] = currentText, - [JLField.Sentence] = JapaneseUtils.FindSentence(currentText, currentCharPosition), - [JLField.DictionaryName] = lookupResult.Dict.Name, - [JLField.MatchedText] = lookupResult.MatchedText, - [JLField.DeconjugatedMatchedText] = lookupResult.DeconjugatedMatchedText, - [JLField.PrimarySpelling] = lookupResult.PrimarySpelling, - [JLField.PrimarySpellingWithOrthographyInfo] = lookupResult.PrimarySpellingOrthographyInfoList is not null - ? string.Create(CultureInfo.InvariantCulture, $"{lookupResult.PrimarySpelling} ({string.Join(", ", lookupResult.PrimarySpellingOrthographyInfoList)})") - : lookupResult.PrimarySpelling - }; - - if (lookupResult.Readings is not null) - { - string readings = string.Join(", ", lookupResult.Readings); - miningParams[JLField.Readings] = readings; - - miningParams[JLField.ReadingsWithOrthographyInfo] = lookupResult.ReadingsOrthographyInfoList is not null - ? ReadingsToText(lookupResult.Readings, lookupResult.ReadingsOrthographyInfoList) - : readings; - } - - if (lookupResult.AlternativeSpellings is not null) - { - string alternativeSpellings = string.Join(", ", lookupResult.AlternativeSpellings); - miningParams[JLField.AlternativeSpellings] = alternativeSpellings; - - miningParams[JLField.AlternativeSpellingsWithOrthographyInfo] = lookupResult.AlternativeSpellingsOrthographyInfoList is not null - ? ReadingsToText(lookupResult.AlternativeSpellings, lookupResult.AlternativeSpellingsOrthographyInfoList) - : alternativeSpellings; - } - - if (lookupResult.Frequencies is not null) - { - string? formattedFreq = FrequenciesToText(lookupResult.Frequencies, true); - if (formattedFreq is not null) - { - miningParams[JLField.Frequencies] = formattedFreq; - miningParams[JLField.RawFrequencies] = string.Join(", ", lookupResult.Frequencies - .Where(static f => f.Freq is > 0 and < int.MaxValue) - .Select(static f => f.Freq)); - } - } - - if (lookupResult.FormattedDefinitions is not null) - { - string formattedDefinitions = lookupResult.FormattedDefinitions.Replace("\n", "
", StringComparison.Ordinal); - miningParams[JLField.Definitions] = formattedDefinitions; - - if (selectedDefinitions is null) - { - miningParams[JLField.SelectedDefinitions] = formattedDefinitions; - } - } - - if (selectedDefinitions is not null) - { - miningParams[JLField.SelectedDefinitions] = selectedDefinitions.Replace("\n", "
", StringComparison.Ordinal); - } - - if (lookupResult.EdictId > 0) - { - miningParams[JLField.EdictId] = lookupResult.EdictId.ToString(CultureInfo.InvariantCulture); - } - - if (lookupResult.DeconjugationProcess is not null) - { - miningParams[JLField.DeconjugationProcess] = lookupResult.DeconjugationProcess; - } - - if (lookupResult.KanjiComposition is not null) - { - miningParams[JLField.KanjiComposition] = lookupResult.KanjiComposition; - } - - if (lookupResult.KanjiStats is not null) - { - miningParams[JLField.KanjiStats] = lookupResult.KanjiStats; - } - - if (lookupResult.StrokeCount > 0) - { - miningParams[JLField.StrokeCount] = lookupResult.StrokeCount.ToString(CultureInfo.InvariantCulture); - } - - if (lookupResult.KanjiGrade > -1) - { - miningParams[JLField.KanjiGrade] = lookupResult.KanjiGrade.ToString(CultureInfo.InvariantCulture); - } - - if (lookupResult.OnReadings is not null) - { - miningParams[JLField.OnReadings] = string.Join(", ", lookupResult.OnReadings); - } - - if (lookupResult.KunReadings is not null) - { - miningParams[JLField.KunReadings] = string.Join(", ", lookupResult.KunReadings); - } - - if (lookupResult.NanoriReadings is not null) - { - miningParams[JLField.NanoriReadings] = string.Join(", ", lookupResult.NanoriReadings); - } - - if (lookupResult.RadicalNames is not null) - { - miningParams[JLField.RadicalNames] = string.Join(", ", lookupResult.RadicalNames); - } - - bool mined = await Mining.Mine(miningParams, lookupResult).ConfigureAwait(false); - - if (mined) - { - Stats.IncrementStat(StatType.CardsMined); - } - } }