mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #183 from taooceros/PinyinLibraryChange
Pinyin library change
This commit is contained in:
commit
aa3177d2d3
5 changed files with 69 additions and 183 deletions
|
|
@ -1,178 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using hyjiacan.util.p4n;
|
||||
using hyjiacan.util.p4n.format;
|
||||
using JetBrains.Annotations;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
|
||||
namespace Flow.Launcher.Infrastructure
|
||||
{
|
||||
public interface IAlphabet
|
||||
{
|
||||
string Translate(string stringToTranslate);
|
||||
}
|
||||
|
||||
public class Alphabet : IAlphabet
|
||||
{
|
||||
private readonly HanyuPinyinOutputFormat Format = new HanyuPinyinOutputFormat();
|
||||
private ConcurrentDictionary<string, string[][]> PinyinCache;
|
||||
private BinaryStorage<Dictionary<string, string[][]>> _pinyinStorage;
|
||||
private Settings _settings;
|
||||
|
||||
public void Initialize([NotNull] Settings settings)
|
||||
{
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
InitializePinyinHelpers();
|
||||
}
|
||||
|
||||
private void InitializePinyinHelpers()
|
||||
{
|
||||
Format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||
|
||||
Stopwatch.Normal("|Flow Launcher.Infrastructure.Alphabet.Initialize|Preload pinyin cache", () =>
|
||||
{
|
||||
_pinyinStorage = new BinaryStorage<Dictionary<string, string[][]>>("Pinyin");
|
||||
|
||||
lock(_pinyinStorage)
|
||||
{
|
||||
var loaded = _pinyinStorage.TryLoad(new Dictionary<string, string[][]>());
|
||||
|
||||
PinyinCache = new ConcurrentDictionary<string, string[][]>(loaded);
|
||||
}
|
||||
|
||||
// force pinyin library static constructor initialize
|
||||
PinyinHelper.toHanyuPinyinStringArray('T', Format);
|
||||
});
|
||||
Log.Info($"|Flow Launcher.Infrastructure.Alphabet.Initialize|Number of preload pinyin combination<{PinyinCache.Count}>");
|
||||
}
|
||||
|
||||
public string Translate(string str)
|
||||
{
|
||||
return ConvertChineseCharactersToPinyin(str);
|
||||
}
|
||||
|
||||
public string ConvertChineseCharactersToPinyin(string source)
|
||||
{
|
||||
if (!_settings.ShouldUsePinyin)
|
||||
return source;
|
||||
|
||||
if (string.IsNullOrEmpty(source))
|
||||
return source;
|
||||
|
||||
if (!ContainsChinese(source))
|
||||
return source;
|
||||
|
||||
var combination = PinyinCombination(source);
|
||||
|
||||
var pinyinArray=combination.Select(x => string.Join("", x));
|
||||
var acronymArray = combination.Select(Acronym).Distinct();
|
||||
|
||||
var joinedSingleStringCombination = new StringBuilder();
|
||||
var all = acronymArray.Concat(pinyinArray);
|
||||
all.ToList().ForEach(x => joinedSingleStringCombination.Append(x));
|
||||
|
||||
return joinedSingleStringCombination.ToString();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (!_settings.ShouldUsePinyin)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock(_pinyinStorage)
|
||||
{
|
||||
_pinyinStorage.Save(PinyinCache.ToDictionary(i => i.Key, i => i.Value));
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] EmptyStringArray = new string[0];
|
||||
private static string[][] Empty2DStringArray = new string[0][];
|
||||
|
||||
/// <summmary>
|
||||
/// replace chinese character with pinyin, non chinese character won't be modified
|
||||
/// Because we don't have words dictionary, so we can only return all possiblie pinyin combination
|
||||
/// e.g. 音乐 will return yinyue and yinle
|
||||
/// <param name="characters"> should be word or sentence, instead of single character. e.g. 微软 </param>
|
||||
/// </summmary>
|
||||
public string[][] PinyinCombination(string characters)
|
||||
{
|
||||
if (!_settings.ShouldUsePinyin || string.IsNullOrEmpty(characters))
|
||||
{
|
||||
return Empty2DStringArray;
|
||||
}
|
||||
|
||||
if (!PinyinCache.ContainsKey(characters))
|
||||
{
|
||||
var allPinyins = new List<string[]>();
|
||||
foreach (var c in characters)
|
||||
{
|
||||
var pinyins = PinyinHelper.toHanyuPinyinStringArray(c, Format);
|
||||
if (pinyins != null)
|
||||
{
|
||||
var r = pinyins.Distinct().ToArray();
|
||||
allPinyins.Add(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
var r = new[] { c.ToString() };
|
||||
allPinyins.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
var combination = allPinyins.Aggregate(Combination).Select(c => c.Split(';')).ToArray();
|
||||
PinyinCache[characters] = combination;
|
||||
return combination;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PinyinCache[characters];
|
||||
}
|
||||
}
|
||||
|
||||
public string Acronym(string[] pinyin)
|
||||
{
|
||||
var acronym = string.Join("", pinyin.Select(p => p[0]));
|
||||
return acronym;
|
||||
}
|
||||
|
||||
public bool ContainsChinese(string word)
|
||||
{
|
||||
if (!_settings.ShouldUsePinyin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (word.Length > 40)
|
||||
{
|
||||
//Skip strings that are too long string for Pinyin conversion.
|
||||
return false;
|
||||
}
|
||||
|
||||
var chinese = word.Select(PinyinHelper.toHanyuPinyinStringArray)
|
||||
.Any(p => p != null);
|
||||
return chinese;
|
||||
}
|
||||
|
||||
private string[] Combination(string[] array1, string[] array2)
|
||||
{
|
||||
if (!_settings.ShouldUsePinyin)
|
||||
{
|
||||
return EmptyStringArray;
|
||||
}
|
||||
|
||||
var combination = (
|
||||
from a1 in array1
|
||||
from a2 in array2
|
||||
select $"{a1};{a2}"
|
||||
).ToArray();
|
||||
return combination;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -53,10 +53,10 @@
|
|||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="NLog.Schema" Version="4.7.0-rc1" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />
|
||||
<PackageReference Include="Pinyin4DotNet" Version="2016.4.23.4" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
||||
<PackageReference Include="System.Runtime" Version="4.3.1" />
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="2.5.13" />
|
||||
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.0.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
65
Flow.Launcher.Infrastructure/PinyinAlphabet.cs
Normal file
65
Flow.Launcher.Infrastructure/PinyinAlphabet.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using ToolGood.Words.Pinyin;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Flow.Launcher.Infrastructure
|
||||
{
|
||||
public interface IAlphabet
|
||||
{
|
||||
string Translate(string stringToTranslate);
|
||||
}
|
||||
|
||||
public class PinyinAlphabet : IAlphabet
|
||||
{
|
||||
private ConcurrentDictionary<string, string> _pinyinCache = new ConcurrentDictionary<string, string>();
|
||||
private Settings _settings;
|
||||
|
||||
public void Initialize([NotNull] Settings settings)
|
||||
{
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
|
||||
public string Translate(string content)
|
||||
{
|
||||
if (_settings.ShouldUsePinyin)
|
||||
{
|
||||
if (!_pinyinCache.ContainsKey(content))
|
||||
{
|
||||
if (WordsHelper.HasChinese(content))
|
||||
{
|
||||
var result = WordsHelper.GetPinyin(content, ";");
|
||||
result = GetFirstPinyinChar(result) + result.Replace(";", "");
|
||||
_pinyinCache[content] = result;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return _pinyinCache[content];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFirstPinyinChar(string content)
|
||||
{
|
||||
return string.Concat(content.Split(';').Select(x => x.First()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ namespace Flow.Launcher
|
|||
private SettingWindowViewModel _settingsVM;
|
||||
private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo);
|
||||
private readonly Portable _portable = new Portable();
|
||||
private readonly Alphabet _alphabet = new Alphabet();
|
||||
private readonly PinyinAlphabet _alphabet = new PinyinAlphabet();
|
||||
private StringMatcher _stringMatcher;
|
||||
|
||||
[STAThread]
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ namespace Flow.Launcher
|
|||
{
|
||||
private readonly SettingWindowViewModel _settingsVM;
|
||||
private readonly MainViewModel _mainVM;
|
||||
private readonly Alphabet _alphabet;
|
||||
private readonly PinyinAlphabet _alphabet;
|
||||
|
||||
#region Constructor
|
||||
|
||||
public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, Alphabet alphabet)
|
||||
public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet)
|
||||
{
|
||||
_settingsVM = settingsVM;
|
||||
_mainVM = mainVM;
|
||||
|
|
@ -76,7 +76,6 @@ namespace Flow.Launcher
|
|||
_settingsVM.Save();
|
||||
PluginManager.Save();
|
||||
ImageLoader.Save();
|
||||
_alphabet.Save();
|
||||
}
|
||||
|
||||
public void ReloadAllPluginData()
|
||||
|
|
|
|||
Loading…
Reference in a new issue