Files
PowerToys/src/modules/launcher/Wox.Infrastructure/Alphabet.cs
Jeremy Sinclair b2b2856e52 🚧 [Dev][Build] .NET 8 Upgrade (#28655)
* Upgraded projects to target .NET 8

* Updated .NET runtime package targets to use latest .NET 8 build

* Updated PowerToys Interop to target .NET 8

* Switch to use ArgumentNullException.ThrowIfNull

* ArgumentNullException.ThrowIfNull for CropAndLockViewModel

* Switching to ObjectDisposedException.ThrowIf

* Upgrade System.ComponentModel.Composition to 8.0

* ArgumentNullException.ThrowIfNull in Helper

* Switch to StartsWith using StringComparison.Ordinal

* Disabled CA1859, CA1716, SYSLIB1096 analyzers

* Update RIDs to reflect breaking changes in .NET 8

* Updated Microsoft NuGet packages to RC1

* Updated Analyzer package to latest .NET 8 preview package

* CA1854: Use TryGetValue instead of ContainsKey

* [Build] Update TFM to .NET 8 for publish profiles

* [Analyzers] Remove CA1309, CA1860-CA1865, CA1869, CA2208 from warning.

* [Analyzers] Fix for C26495

* [Analyzers] Disable CS1615, CS9191

* [CI] Target .NET 8 in YAML

* [CI] Add .NET preview version flag temporarily.

* [FileLocksmith] Update TFM to .NET 8

* [CI] Switch to preview agent

* [CI] Update NOTICE.md

* [CI] Update Release to target .NET 8 and use Preview agent

* [Analyzers] Disable CA1854

* Fix typo

* Updated Microsoft.CodeAnalysis.NetAnalyzers to latest preview

Updated packages to rc2

* [Analyzers][CPP] Turn off warning for 5271

* [Analyzers][CPP] Turn off warning for 26493

* [KeyboardListener] Add mutex include to resolve error

* [PT Run][Folder] Use static SearchValues to resolve CA1870

* [PowerLauncher] Fix TryGetValue

* [MouseJumpSettings] Use ArgumentNullException.ThrowIfNull

* [Build] Disable parallel dotnet tool restore

* [Build] No cache of dotnet tool packages

* [Build] Temporarily move .NET 8 SDK task before XAML formatting

* [Build][Temp] Try using .NET 7 prior to XAML formatting and then switch to .NET 8 after

* [Build] Use .NET 6 for XAML Styler

* [CI] Updated NOTICE.md

* [FancyZones] Update TFM to .NET 8

* [EnvVar] Update TFM to .NET 8 and update RID

* [EnvVar] Use ArgumentNullException.ThrowIfNull

* [Dev] Updated packages to .NET 8 RTM version

* [Dev] Updated Microsoft.CodeAnalysis.NetAnalyzers to latest

* [CI] Updated NOTICE.md with latest package versions

* Fix new utility target fameworks and runtimeids

* Don't use preview images anymore

* [CI] Add script to update VCToolsVersion environment variable

* [CI] Add Step to Verify VCToolsVersion

* [CI] Use latest flag for vswhere to set proper VCToolsVersion

* Add VCToolsVersion checking to release.yml

* Remove net publishing from local/ PR CI builds

* Revert "Remove net publishing from local/ PR CI builds"

This reverts commit f469778996.

* Only publish necessary projects

* Add verbosity to release pipelines builds of PowerTOys

* Set VCToolsVersion for publish.cmd when called from installer

* [Installer] Moved project publish logic to MSBuild Task

* [CI] Revert using publish.cmd

* [CI] Set VCToolsVersion and unset ClearDevCommandPromptEnvVars property

* Installer publishes for x64 too

* Revert "Add verbosity to release pipelines builds of PowerTOys"

This reverts commit 654d4a7f78.

* [Dev] Update CodeAnalysis library to non-preview package

* Remove unneeded warning removal

* Fix Notice.md

* Rename VCToolsVersion file and task name

* Remove unneeded mutex header include

---------

Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2023-11-22 12:46:59 -05:00

213 lines
6.2 KiB
C#

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using hyjiacan.py4n;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure.UserSettings;
using Wox.Plugin.Logger;
namespace Wox.Infrastructure;
public class Alphabet : IAlphabet
{
private readonly PinyinFormat _pinyinFormat =
PinyinFormat.CAPITALIZE_FIRST_LETTER |
PinyinFormat.WITH_V |
PinyinFormat.WITHOUT_TONE;
private ConcurrentDictionary<string, string[][]> _pinyinCache;
private WoxJsonStorage<Dictionary<string, string[][]>> _pinyinStorage;
private PowerToysRunSettings _settings;
private Dictionary<string, string[][]> __cache;
public void Initialize(PowerToysRunSettings settings)
{
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
InitializePinyinHelpers();
}
private void InitializePinyinHelpers()
{
Stopwatch.Normal("|Wox.Infrastructure.Alphabet.Initialize|Preload pinyin cache", () =>
{
_pinyinStorage = new WoxJsonStorage<Dictionary<string, string[][]>>("Pinyin");
SetPinyinCacheAsDictionary(__cache = _pinyinStorage.Load());
// force pinyin library static constructor initialize
Pinyin4Net.GetPinyin('一', _pinyinFormat);
});
Log.Info($"Number of preload pinyin combination<{_pinyinCache.Count}>", GetType());
}
public string Translate(string stringToTranslate)
{
return ConvertChineseCharactersToPinyin(stringToTranslate);
}
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(string.Empty, 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;
}
GetPinyinCacheAsDictionary();
_pinyinStorage.Save();
}
private static readonly string[] _emptyStringArray = Array.Empty<string>();
private static readonly string[][] _empty2DStringArray = Array.Empty<string[]>();
/// <summary>
/// replace chinese character with pinyin, non chinese character won't be modified
/// <param name="word"> should be word or sentence, instead of single character. e.g. 微软 </param>
/// </summary>
[Obsolete("Not accurate, eg 音乐 will not return yinyue but returns yinle ")]
public string[] Pinyin(string word)
{
if (!_settings.ShouldUsePinyin)
{
return _emptyStringArray;
}
var pinyin = word.Select(c =>
{
string result = c.ToString();
if (PinyinUtil.IsHanzi(c))
{
var pinyins = Pinyin4Net.GetPinyin(c);
result = pinyins[0];
}
return result;
}).ToArray();
return pinyin;
}
/// <summary>
/// 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 possibly pinyin combination
/// e.g. 音乐 will return yinyue and yinle
/// <param name="characters"> should be word or sentence, instead of single character. e.g. 微软 </param>
/// </summary>
public string[][] PinyinCombination(string characters)
{
if (!_settings.ShouldUsePinyin || string.IsNullOrEmpty(characters))
{
return _empty2DStringArray;
}
if (!_pinyinCache.TryGetValue(characters, out string[][] value))
{
var allPinyins = new List<string[]>();
foreach (var c in characters)
{
if (PinyinUtil.IsHanzi(c))
{
var pinyins = Pinyin4Net.GetPinyin(c, _pinyinFormat);
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 value;
}
}
public string Acronym(string[] pinyin)
{
var acronym = string.Join(string.Empty, 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.Any(PinyinUtil.IsHanzi);
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;
}
private Dictionary<string, string[][]> GetPinyinCacheAsDictionary()
{
return new Dictionary<string, string[][]>(_pinyinCache);
}
private void SetPinyinCacheAsDictionary(Dictionary<string, string[][]> usage)
{
_pinyinCache = new ConcurrentDictionary<string, string[][]>(usage);
}
}