Form1.cs 11.2 KB
using ConfigHelper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UILanguageTooles
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Config.PropertyBind("textBox_procjetdir", textBox_procjetdir, "Text", "TextChanged", "");
            Config.PropertyBind("textBox_lngdir", textBox_lngdir, "Text", "TextChanged", "");
            //
        }
        Dictionary<string, string[]> Currentlngdict;
        Dictionary<string, string> codeidlist;
        private void btn_analytis_Click(object sender, EventArgs e)
        {
            Currentlngdict = new ();
            codeidlist = new();

            var lngname = combo_lngsel.SelectedItem.ToString();
            if (!textBox_lngdir.Text.ToLower().StartsWith(textBox_procjetdir.Text.ToLower())) {
                MessageBox.Show("语言目录与项目目录不在同一目录");
                return;
            }
            Directory.CreateDirectory(textBox_lngdir.Text);
            var lngfile = Path.Combine(textBox_lngdir.Text, lngname + ".lngres");
            if (!File.Exists(lngfile))
            {
                File.WriteAllText(lngfile, "");
            }
            else {
                var fs = File.ReadAllLines(lngfile);
                fs.ToList().ForEach(l=> {
                    if (!string.IsNullOrWhiteSpace(l)) {
                        var h = l.Split('\t');
                        if (h.Length == 0)
                            return;
                        var d = new string[3];
                        for (int i = 0; i < 3; i++)
                        {
                            if (i == 2 && h.Length < 3)
                                break;
                            d[i] = h[i]; 
                        }
                        if (!string.IsNullOrWhiteSpace(d[1]) && string.IsNullOrEmpty(d[2]))
                        {
                            if (TranslateLibrary.Library[lngname].ContainsKey(d[1]))
                                d[2] = TranslateLibrary.Library[lngname][d[1]];
                        }

                        if (!Currentlngdict.ContainsKey(h[0]))
                        {
                            Currentlngdict.Add(h[0], d);
                            codeidlist.Add(h[0], h[1]);
                        }
                    }
                });
            }
            Analytics(lngname);

            var sortkey = Currentlngdict.Keys.ToList();
            sortkey.Sort((a, b) =>
            {
                int av = 50;
                int bv = 50;

                if (a.StartsWith("Res0"))
                {
                    av = int.Parse(a.Substring(3, 4)) + 1000;
                }
                if (b.StartsWith("Res0"))
                {
                    bv = int.Parse(b.Substring(3, 4)) + 1000;
                }
                if (a.EndsWith("_Text") )
                {
                    av= 0;
                }
                if (b.EndsWith("_Text"))
                {
                    bv = 0;
                }
                if (av == bv)
                    return string.Compare(a,b);
                return av> bv?1:-1;

            });

            var fl=Currentlngdict.Values.ToList();

            fl.ForEach(f => {
                if (f.Length > 2 && string.IsNullOrEmpty(f[2]))
                {
                    var r = Currentlngdict.Values.Where(v => v.Length > 2 && v[1] == f[1] && !string.IsNullOrWhiteSpace(v[2])).FirstOrDefault();
                    if (r != null)
                        f[2] = r[2];
  
                }                
            });

            var res = sortkey.Select(x=> { return string.Join("\t", Currentlngdict[x]); }).ToArray().Where(s=>HasChinese(s)).ToArray();
            if (checkBox_write.Checked)
                File.WriteAllLines(lngfile, res);

        }
        
        void Analytics(string lng) {
            
            string p = @"""""|""(.*?[^\\])""";

            Regex regex = new Regex(p, RegexOptions.ECMAScript);

            var csfiles = Directory.GetFiles(textBox_procjetdir.Text, "*.cs", SearchOption.AllDirectories);
            StringBuilder result = new StringBuilder();
            foreach (var csf in csfiles)
            {
                if (HasExcludetxt(excludeFile,csf))
                    continue;
                var faln = File.ReadAllLines(csf,Encoding.UTF8);
                bool hasChange = false;
                for (int i=0;i<faln.Length;i++) 
                {
                    var orgtxt = faln[i];
                    var rtxt = orgtxt.Trim();
                    if (rtxt.EndsWith("]"))
                        continue;
                    if (rtxt.StartsWith("//"))
                        continue;
                    if (HasExcludetxt(excludeline, rtxt))
                        continue;
                    int matchoffset = 0;
                    var m = regex.Match(orgtxt);
                    while (m.Success)
                    {
                        try
                        {
                            if (HasExcludetxt(excludetxt,m.Groups[1].Value))
                                continue;
                            if (!HasChinese(m.Groups[1].Value))
                                continue;

                            result.AppendLine(rtxt);
                            //result.AppendLine("\t" + m.Groups[0].Value);
                            for (int j = 1; j < m.Groups.Count; j++)
                            {
                                var code = orgtxt.Substring(0, m.Groups[j].Index-1).Trim();
                                if (code.EndsWith("$") || code.EndsWith("GetString("))
                                    continue;
                                var gtxt = m.Groups[j].Value;
                                if (!TranslateLibrary.Library[lng].TryGetValue(gtxt, out string re)) {

                                }
                                var crcmatch = Regex.Match(code, @"crc\s*\.\s*GetString\s*\(\s*(\S*?)\s*,\s*$");
                                string keyid;
                                if (crcmatch.Success)
                                {
                                    keyid = crcmatch.Groups[1].Value.Trim('"');
                                    if (keyid.StartsWith("L."))
                                        keyid=keyid.Substring(2);
                                     if (!codeidlist.ContainsKey(keyid))
                                        codeidlist.Add(keyid, gtxt);
                                     else if (codeidlist[keyid]!= gtxt)
                                        result.AppendLine("\t\tDupLine:"+ codeidlist[keyid]+"\t" + gtxt + "\t" + re);
                                }
                                else {
                                    hasChange = true;
                                    if (codeidlist.ContainsValue(gtxt))
                                        keyid = codeidlist.First(m => m.Value == gtxt).Key;
                                    else
                                        keyid = GetID(gtxt);
                                    faln[i] = faln[i].Insert(m.Groups[0].Index+ m.Groups[0].Length+ matchoffset, ")");
                                    faln[i] = faln[i].Insert(m.Groups[0].Index+ matchoffset, $"crc.GetString(\"{keyid}\",");
                                    matchoffset = faln[i].Length - orgtxt.Length;
                                    if (!codeidlist.ContainsKey(keyid))
                                        codeidlist.Add(keyid, gtxt);
                                }
                                var r = Currentlngdict.Values.Where(v => v.Length > 2 && v[0] == keyid).FirstOrDefault();
                                if (r != null)
                                    re = r[2];
                                result.AppendLine("\t\t" + gtxt + "\t" + re);
                                if (!Currentlngdict.ContainsKey(keyid))
                                    Currentlngdict.Add(keyid, new string[] { keyid, gtxt, re });
                            }

                        }
                        finally
                        {
                            m = m.NextMatch();
                        }
                    }
                }
                if (hasChange)
                {
                    var f= faln.ToList().Find(ll=>Regex.IsMatch(ll, @"^\s*using\s*OnlineStore\s*;\s*$"));
                    var fa = string.Join("\r\n", faln);
                    if (f == null)
                    {
                        fa = "using OnlineStore;\r\n" + fa;
                    }
                    if (checkBox_write.Checked)
                        File.WriteAllText(csf, fa);
                }
            }

            richTextBox_result.Text = result.ToString();
            id = 1;
        }
        int id = 1;
        public string GetID(string gtxt)
        {
            var keyid = "Res" + id.ToString("0000");
            var k = from key in codeidlist.Keys where key.StartsWith(keyid) select key;
            if (k.Count()>0)
            {
                id++;
                return GetID(gtxt);
            }      
            return keyid+"."+ GenerateChecksum(gtxt);

        }
        public static string GenerateChecksum(string input)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(input);
                byte[] hashBytes = md5.ComputeHash(inputBytes);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 4; i++)
                {
                    sb.Append(hashBytes[i].ToString("x2"));
                }
                return sb.ToString().Substring(0, 8);
            }
        }
        static bool HasChinese(string txt) {

            //for (int i = 0; i < txt.Length; i++)
            //{
            if (Regex.IsMatch(txt.ToString(), @"[\u4E00-\u9FA5]+"))
                return true;
            //}
            return false;
        }
        static bool HasExcludetxt(string[] list,string txt)
        {
            foreach (var ex in list) {
                if (txt.ToLower().IndexOf(ex.ToLower()) >= 0)
                    return true;
            }
            return false;
        }
        /// <summary>
        /// 包含以下字符不转换
        /// </summary>
        static string[] excludetxt = new string[] { "宋体", "新宋体", "微软雅黑", "【", "】" };
        /// <summary>
        /// 包含以下文件名不转换
        /// </summary>
        static string[] excludeFile = new string[] { ".Designer.cs", "Common.cs", "LoadCVSLibrary", "CodeResourceControl.cs", "ZoomPictureBox.cs", "Program.cs" };
        /// <summary>
        /// 代码行中包含以下文本不转换
        /// </summary>
        static string[] excludeline = new string[] {"throw", "LogUtil", ".log" , "LOGGER.", "LOGGER.", " const ", "OutDebug","VLog.", ".Info", ".Error", "AppSetting.", "Log.Warn", ".errlog" };

        private void Form1_Load(object sender, EventArgs e)
        {
            combo_lngsel.SelectedIndex = 0;
        }
    }
}