public static void BinaryScrape(string fileName, string outputDir, params BinaryRange[] ranges)
        {
            Directory.CreateDirectory(outputDir);
            //List<string> language = new List<string>();
            //List<string> languageHeaders = new List<string>();
            StringBuilder language = new StringBuilder();
            StringBuilder normal   = new StringBuilder();

            using (Stream stream = File.OpenRead(fileName)) {
                foreach (BinaryRange range in ranges)
                {
                    //using (StreamWriter writer = new StreamWriter(Path.Combine(outputDir, BinaryFileName), false, Encoding.UTF8)) {
                    BinaryReader reader = new BinaryReader(stream, Constants.ShiftJIS);

                    long end = (range.End != 0 ? range.End : Math.Min(range.End, stream.Length));
                    stream.Position = range.Start;

                    while (stream.Position < end)
                    {
                        long   position = stream.Position;
                        string line;
                        try {
                            line = reader.ReadTerminatedString();
                        } catch { break; }
                        long reserved = (stream.Position - position);
                        long bytes    = reserved;
                        stream.SkipPadding(4);
                        reserved = MathUtils.Pad(reserved, 4);

                        StringScrapeType type = GetStringType(line);

                        string header = $"Bytes={reserved},Offset=0x{position:X8}";
                        bool   added  = AddResString(header, language, normal, line, line);
                        if (added)
                        {
                            Console.WriteLine($"{position:X8} = {bytes} B, \"{TextUtils.EscapeNormal(line, false)}\" Length={line.Length}");
                        }
                    }
                }
            }
            string normalPath = Path.Combine(outputDir, BinaryFileName);

            File.WriteAllText(normalPath, normal.ToString());
            if (language.Length != 0)
            {
                string path = Path.Combine(outputDir, BinaryLanguageFileName);
                File.WriteAllText(path, language.ToString());
            }
        }
        /*public static string GetResId(IMenuTemplateItem menuItem) {
         *      if (menuItem is MenuTemplateItemCommand command) {
         *              //if (command.MenuId != 0)
         *                      return $"${command.MenuId}${menuItem.MenuString}";
         *              //return menuItem.MenuString;
         *      }
         *      else {
         *              return $"$POPUP${menuItem.MenuString}";
         *      }
         * }
         * public static string GetResId(IMenuExTemplateItem menuItem) {
         *      if (menuItem is MenuExTemplateItemCommand command) {
         *              //var header = (MenuExItemTemplate) Constants.MenuExTemplateItem_header.GetValue(command);
         *              //if (header.dwMenuId != 0)
         *                      return $"${command.MenuId}${menuItem.MenuString}";
         *              //return menuItem.MenuString;
         *      }
         *      else {
         *              return $"$POPUP${menuItem.MenuString}";
         *      }
         * }*/

        private static bool AddResString(string commentLine, StringBuilder language, StringBuilder normal, string s,
                                         string resId)
        {
            StringScrapeType type = GetStringType(s);

            switch (type)
            {
            case StringScrapeType.Normal:
                if (commentLine != null)
                {
                    normal.AppendLine($"{Comment}{commentLine}");
                }
                normal.AppendLine($"{Comment}{TextUtils.EscapeNormal(s, false)}");
                normal.AppendLine(TextUtils.EscapeNormal(resId, false));
                normal.AppendLine(NotTranslated);
                normal.AppendLine();
                return(true);

            case StringScrapeType.Language:
                string id    = TranslatableRegex.Match(s).Value;
                string value = s.Substring(id.Length);

                if (commentLine != null)
                {
                    language.AppendLine($"{Comment}{commentLine}");
                }
                language.AppendLine($"{Comment}{TextUtils.EscapeNormal(value, false)}");
                language.AppendLine(id);
                language.AppendLine(NotTranslated);
                language.AppendLine();
                return(true);

            default:
                return(false);
            }
        }