11using System ;
22using System . Collections . Concurrent ;
3- using System . Collections . Generic ;
4- using System . Linq ;
53using System . Text ;
64using JetBrains . Annotations ;
75using Flow . Launcher . Infrastructure . UserSettings ;
86using ToolGood . Words . Pinyin ;
7+ using System . Collections . Generic ;
8+ using System . Collections . ObjectModel ;
99
1010namespace Flow . Launcher . Infrastructure
1111{
1212 public class PinyinAlphabet : IAlphabet
1313 {
14- private ConcurrentDictionary < string , ( string translation , TranslationMapping map ) > _pinyinCache =
15- new ConcurrentDictionary < string , ( string translation , TranslationMapping map ) > ( ) ;
14+ private readonly ConcurrentDictionary < string , ( string translation , TranslationMapping map ) > _pinyinCache =
15+ new ( ) ;
1616
1717 private Settings _settings ;
1818
@@ -23,20 +23,22 @@ public void Initialize([NotNull] Settings settings)
2323
2424 public bool ShouldTranslate ( string stringToTranslate )
2525 {
26- return WordsHelper . HasChinese ( stringToTranslate ) ;
26+ return _settings . UseDoublePinyin ?
27+ ( WordsHelper . HasChinese ( stringToTranslate ) && stringToTranslate . Length % 2 == 0 ) :
28+ WordsHelper . HasChinese ( stringToTranslate ) ;
2729 }
2830
2931 public ( string translation , TranslationMapping map ) Translate ( string content )
3032 {
3133 if ( _settings . ShouldUsePinyin )
3234 {
33- if ( ! _pinyinCache . ContainsKey ( content ) )
35+ if ( ! _pinyinCache . TryGetValue ( content , out var value ) )
3436 {
3537 return BuildCacheFromContent ( content ) ;
3638 }
3739 else
3840 {
39- return _pinyinCache [ content ] ;
41+ return value ;
4042 }
4143 }
4244 return ( content , null ) ;
@@ -57,9 +59,10 @@ public bool ShouldTranslate(string stringToTranslate)
5759 {
5860 if ( content [ i ] >= 0x3400 && content [ i ] <= 0x9FD5 )
5961 {
60- map . AddNewIndex ( i , resultBuilder . Length , resultList [ i ] . Length + 1 ) ;
62+ string dp = _settings . UseDoublePinyin ? ToDoublePin ( resultList [ i ] . ToLower ( ) ) : resultList [ i ] ;
63+ map . AddNewIndex ( i , resultBuilder . Length , dp . Length + 1 ) ;
6164 resultBuilder . Append ( ' ' ) ;
62- resultBuilder . Append ( resultList [ i ] ) ;
65+ resultBuilder . Append ( dp ) ;
6366 pre = true ;
6467 }
6568 else
@@ -86,5 +89,111 @@ public bool ShouldTranslate(string stringToTranslate)
8689 return ( content , null ) ;
8790 }
8891 }
92+
93+ #region Double Pinyin
94+
95+ private static readonly ReadOnlyDictionary < string , string > special = new ( new Dictionary < string , string > ( ) {
96+ { "a" , "aa" } ,
97+ { "ai" , "ai" } ,
98+ { "an" , "an" } ,
99+ { "ang" , "ah" } ,
100+ { "ao" , "ao" } ,
101+ { "e" , "ee" } ,
102+ { "ei" , "ei" } ,
103+ { "en" , "en" } ,
104+ { "er" , "er" } ,
105+ { "o" , "oo" } ,
106+ { "ou" , "ou" }
107+ } ) ;
108+
109+
110+ private static readonly ReadOnlyDictionary < string , string > first = new ( new Dictionary < string , string > ( ) {
111+ { "ch" , "i" } ,
112+ { "sh" , "u" } ,
113+ { "zh" , "v" }
114+ } ) ;
115+
116+
117+ private static readonly ReadOnlyDictionary < string , string > second = new ( new Dictionary < string , string > ( )
118+ {
119+ { "ua" , "x" } ,
120+ { "ei" , "w" } ,
121+ { "e" , "e" } ,
122+ { "ou" , "z" } ,
123+ { "iu" , "q" } ,
124+ { "ve" , "t" } ,
125+ { "ue" , "t" } ,
126+ { "u" , "u" } ,
127+ { "i" , "i" } ,
128+ { "o" , "o" } ,
129+ { "uo" , "o" } ,
130+ { "ie" , "p" } ,
131+ { "a" , "a" } ,
132+ { "ong" , "s" } ,
133+ { "iong" , "s" } ,
134+ { "ai" , "d" } ,
135+ { "ing" , "k" } ,
136+ { "uai" , "k" } ,
137+ { "ang" , "h" } ,
138+ { "uan" , "r" } ,
139+ { "an" , "j" } ,
140+ { "en" , "f" } ,
141+ { "ia" , "x" } ,
142+ { "iang" , "l" } ,
143+ { "uang" , "l" } ,
144+ { "eng" , "g" } ,
145+ { "in" , "b" } ,
146+ { "ao" , "c" } ,
147+ { "v" , "v" } ,
148+ { "ui" , "v" } ,
149+ { "un" , "y" } ,
150+ { "iao" , "n" } ,
151+ { "ian" , "m" }
152+ } ) ;
153+
154+ private static string ToDoublePin ( string fullPinyin )
155+ {
156+ // Assuming s is valid
157+ StringBuilder doublePin = new StringBuilder ( ) ;
158+
159+ if ( fullPinyin . Length <= 3 && ( fullPinyin [ 0 ] == 'a' || fullPinyin [ 0 ] == 'e' || fullPinyin [ 0 ] == 'o' ) )
160+ {
161+ if ( special . TryGetValue ( fullPinyin , out var value ) )
162+ {
163+ return value ;
164+ }
165+ }
166+
167+ // zh, ch, sh
168+ if ( fullPinyin . Length >= 2 && first . ContainsKey ( fullPinyin [ ..2 ] ) )
169+ {
170+ doublePin . Append ( first [ fullPinyin [ ..2 ] ] ) ;
171+
172+ if ( second . TryGetValue ( fullPinyin [ 2 ..] , out string tmp ) )
173+ {
174+ doublePin . Append ( tmp ) ;
175+ }
176+ else
177+ {
178+ doublePin . Append ( fullPinyin [ 2 ..] ) ;
179+ }
180+ }
181+ else
182+ {
183+ doublePin . Append ( fullPinyin [ 0 ] ) ;
184+
185+ if ( second . TryGetValue ( fullPinyin [ 1 ..] , out string tmp ) )
186+ {
187+ doublePin . Append ( tmp ) ;
188+ }
189+ else
190+ {
191+ doublePin . Append ( fullPinyin [ 1 ..] ) ;
192+ }
193+ }
194+
195+ return doublePin . ToString ( ) ;
196+ }
197+ #endregion
89198 }
90199}
0 commit comments