Exemplo n.º 1
0
        public static void Main(string [] args)
        {
            var input_paths = new List<string> ();
            string output_path = "-";
            string generator_name = String.Empty;
            string source_root_path = null;
            string reduce_master_path = null;
            string reduce_retain_path = null;
            string android_input_strings_xml = null;
            string android_output_strings_xml = null;
            bool analyze = false;
            bool log = false;
            bool verbose = false;
            bool show_help = false;

            Generator generator = null;

            var options = new OptionSet {
                { "i|input=", "Input directory, search pattern, or file to parse (non-recursive)", v => input_paths.Add (v) },
                { "o|output=", "Output file for extracted string resources", v => output_path = v },
                { "r|source-root=", "Root directory of source code", v => source_root_path = v },
                { "g|generator=", String.Format ("Generator to use ({0})",
                    String.Join ("|", Generator.GeneratorNames)), v => generator_name = v },
                { "a|analyze", "Run the string analyzer after generation", v => analyze = v != null },
                { "reduce-master=", "Reduce a master localized PO file, " +
                    "keeping only strings defined by another unlocalized PO[T] file", v => reduce_master_path = v },
                { "reduce-retain=", "An unlocalized PO[T] file used to " +
                    "determine which strings from reduce-master should be retained", v => reduce_retain_path = v },
                { "android-input-strings-xml=", "Input file of unlocalized Android Strings.xml " +
                    "for preserving hand-maintained string resources", v => android_input_strings_xml = v },
                { "android-output-strings-xml=", "Output file of localized Android Strings.xml " +
                    "for preserving hand-maintained string resources", v => android_output_strings_xml = v },
                { "l|log", "Display logging", v => log = v != null },
                { "v|verbose", "Verbose logging", v => verbose = v != null },
                { "h|help", "Show this help message and exit", v => show_help = v != null }
            };

            try {
                options.Parse (args);

                if (show_help) {
                    Console.WriteLine ("Usage: vernacular [OPTIONS]+");
                    Console.WriteLine ();
                    Console.WriteLine ("Options:");
                    options.WriteOptionDescriptions (Console.Out);
                    return;
                }

                if (source_root_path != null) {
                    if (!Directory.Exists (source_root_path)) {
                        throw new OptionException ("invalid source-root", "source-root");
                    }

                    source_root_path = new DirectoryInfo (source_root_path).FullName;
                }

                generator = Generator.GetGeneratorForName (generator_name.ToLower ());
                if (generator == null) {
                    throw new OptionException ("invalid generator", "generator");
                }

                if (reduce_master_path != null && reduce_retain_path == null) {
                    throw new OptionException ("reduce-retain must be specified if reduce-master is", "reduce-retain");
                } else if (reduce_master_path == null && reduce_retain_path != null) {
                    throw new OptionException ("reduce-master must be specified if reduce-retain is", "reduce-master");
                } else if (reduce_master_path != null && reduce_retain_path != null) {
                    var reduce_master = new PoParser { SourceRootPath = source_root_path };
                    var reduce_retain = new PoParser { SourceRootPath = source_root_path };

                    reduce_master.Add (reduce_master_path);
                    reduce_retain.Add (reduce_retain_path);

                    generator.Reduce (reduce_master, reduce_retain);

                    generator.Generate (output_path);

                    return;
                }
            } catch (OptionException e) {
                Console.WriteLine ("vernacular: {0}", e.Message);
                Console.WriteLine ("Try `vernacular --help` for more information.");
                return;
            }

            var parser = new AggregateParser {
                SourceRootPath = source_root_path
            };

            if (verbose) {
                parser.LogLevel = 2;
            } else if (log) {
                parser.LogLevel = 1;
            }

            StringAnalyzer analyzer = null;

            if (analyze) {
                analyzer = new StringAnalyzer ();
            }

            foreach (var input_path in input_paths) {
                if (File.Exists (input_path)) {
                    parser.Add (input_path);
                    continue;
                }

                var search_pattern = "*";
                var dir = input_path;

                if (!Directory.Exists (dir)) {
                    search_pattern = Path.GetFileName (dir);
                    dir = Path.GetDirectoryName (dir);
                    if (!Directory.Exists (dir)) {
                        continue;
                    }
                }

                foreach (var path in Directory.EnumerateFiles (dir, search_pattern, SearchOption.TopDirectoryOnly)) {
                    parser.Add (path);
                }
            }

            foreach (var localized_string in parser.Parse ()) {
                generator.Add (localized_string);

                if (analyzer != null) {
                    analyzer.Add (localized_string);
                }
            }

            if (analyzer != null) {
                analyzer.Analyze ();
            }

            generator.Generate (output_path);

            if (generator is AndroidGenerator && android_input_strings_xml != null && android_output_strings_xml != null) {
                ((AndroidGenerator)generator).LocalizeManualStringsXml (android_input_strings_xml, android_output_strings_xml);
            }
        }
Exemplo n.º 2
0
        public static int Main (string[] args)
        {
            var input_paths = new List<string> ();
            string output_path = "-";
            string generator_name = String.Empty;
            string source_root_path = null;
            string reduce_master_path = null;
            string reduce_retain_path = null;
            string android_input_strings_xml = null;
            string android_output_strings_xml = null;
            string analyer_config_path = null;
            LocalizationMetadata metadata = null;
            bool generate_pot = false;
            bool exclude_po_header = false;
            bool analyze = false;
            bool analyzer_warn_as_error = false;
            bool log = false;
            bool verbose = false;
            bool retain_order = false;
            bool show_help = false;
            bool count_words = false;
            int word_count = 0;

            Generator generator = null;

            var options = new OptionSet {
                { "i|input=", "Input directory, search pattern, or file to parse (non-recursive)", v => input_paths.Add (v) },
                { "o|output=", "Output file for extracted string resources", v => output_path = v },
                { "r|source-root=", "Root directory of source code", v => source_root_path = v },
                { "g|generator=", String.Format ("Generator to use ({0})",
                    String.Join ("|", Generator.GeneratorNames)), v => generator_name = v },
                { "retain-order", "Retain the original input string order when generating. " +
                    "Default behavior is to sort strings for better diff support.", v => retain_order = v != null },
                { "a|analyze", "Run the string analyzer after generation", v => analyze = v != null },
                { "analyzer-config=", "Path to a configuration file for the analyzer; use with --analyze", v => analyer_config_path = v },
                { "analyzer-warnaserror", "Treat analyzer warnings as errors", v => analyzer_warn_as_error = v != null },
                { "reduce-master=", "Reduce a master localized PO file, " +
                    "keeping only strings defined by another unlocalized PO[T] file", v => reduce_master_path = v },
                { "reduce-retain=", "An unlocalized PO[T] file used to " +
                    "determine which strings from reduce-master should be retained", v => reduce_retain_path = v },
                { "android-input-strings-xml=", "Input file of unlocalized Android Strings.xml " +
                    "for preserving hand-maintained string resources", v => android_input_strings_xml = v },
                { "android-output-strings-xml=", "Output file of localized Android Strings.xml " +
                    "for preserving hand-maintained string resources", v => android_output_strings_xml = v },
                { "pot", v => generate_pot = v != null },
                { "exclude-po-header", v => exclude_po_header = v != null },
                { "l|log", "Display logging", v => log = v != null },
                { "m|meta=", "Add localization metadata (key=value)", v => {
                    var parts = v.Split (new [] { '=' }, 2);
                    if (parts != null && parts.Length == 2) {
                        if (metadata == null) {
                            metadata = new LocalizationMetadata ();
                        }

                        metadata.Add (parts[0].Trim (), parts[1].Trim ());
                    }
                } },
                { "wc", "Count words to translate, output goes in the po header and in the console (with -v)", v => count_words = v != null},
                { "v|verbose", "Verbose logging", v => verbose = v != null },
                { "h|help", "Show this help message and exit", v => show_help = v != null }
            };

            try {
                options.Parse (args);

                if (show_help) {
                    Console.WriteLine ("Usage: vernacular [OPTIONS]+");
                    Console.WriteLine ();
                    Console.WriteLine ("Options:");
                    options.WriteOptionDescriptions (Console.Out);
                    return 1;
                }

                if (source_root_path != null) {
                    if (!Directory.Exists (source_root_path)) {
                        throw new OptionException ("invalid source-root", "source-root");
                    }

                    source_root_path = new DirectoryInfo (source_root_path).FullName;
                }

                generator = Generator.GetGeneratorForName (generator_name.ToLower ());
                if (generator == null) {
                    throw new OptionException ("invalid generator", "generator");
                }

                generator.RetainStringOrder = retain_order;

                if (generator is PoGenerator) {
                    ((PoGenerator)generator).PotMode = generate_pot;
                    ((PoGenerator)generator).ExcludeHeaderMetadata = exclude_po_header;
                }

                if (reduce_master_path != null && reduce_retain_path == null) {
                    throw new OptionException ("reduce-retain must be specified if reduce-master is", "reduce-retain");
                } else if (reduce_master_path == null && reduce_retain_path != null) {
                    throw new OptionException ("reduce-master must be specified if reduce-retain is", "reduce-master");
                } else if (reduce_master_path != null && reduce_retain_path != null) {
                    var reduce_master = new PoParser { SourceRootPath = source_root_path };
                    var reduce_retain = new PoParser { SourceRootPath = source_root_path };

                    reduce_master.Add (reduce_master_path);
                    reduce_retain.Add (reduce_retain_path);

                    generator.Reduce (reduce_master, reduce_retain);

                    generator.Generate (output_path);

                    return 0;
                }
            } catch (OptionException e) {
                Console.WriteLine ("vernacular: {0}", e.Message);
                Console.WriteLine ("Try `vernacular --help` for more information.");
                return 1;
            }

            var parser = new AggregateParser {
                SourceRootPath = source_root_path
            };

            if (verbose) {
                parser.LogLevel = 2;
            } else if (log) {
                parser.LogLevel = 1;
            }

            StringAnalyzer analyzer = null;

            if (analyze) {
                try {
                    analyzer = new StringAnalyzer (analyer_config_path, analyzer_warn_as_error);
                } catch {
                    return 1;
                }
            }

            foreach (var input_path in input_paths) {
                if (File.Exists (input_path)) {
                    parser.Add (input_path);
                    continue;
                }

                var search_pattern = "*";
                var dir = input_path;

                if (!Directory.Exists (dir)) {
                    search_pattern = Path.GetFileName (dir);
                    dir = Path.GetDirectoryName (dir);
                    if (!Directory.Exists (dir)) {
                        continue;
                    }
                }

                foreach (var path in Directory.EnumerateFiles (dir, search_pattern, SearchOption.TopDirectoryOnly)) {
                    parser.Add (path);
                }
            }

            if (metadata != null) {
                generator.Add (metadata);
            }

            foreach (var localization_unit in parser.Parse ()) {
                var localized_string = localization_unit as LocalizedString;
                if (count_words && localized_string!=null) {
                    var separators = new char[] {'.', '?', '!', ' ', ';', ':', ','};
                    if(localized_string.UntranslatedSingularValue != null) {
                        word_count +=
                            localized_string.UntranslatedSingularValue.Split(separators, StringSplitOptions.RemoveEmptyEntries).
                                Count();
                    }
                    if (localized_string.UntranslatedPluralValue != null) {
                        word_count +=
                            localized_string.UntranslatedPluralValue.Split(separators, StringSplitOptions.RemoveEmptyEntries).Count();
                    }
                }
                generator.Add (localization_unit);

                if (analyzer != null) {
                    analyzer.Add (localized_string);
                }
            }

            if (analyzer != null) {
                var error_count = analyzer.Analyze ();
                if (error_count > 0) {
                    Console.WriteLine ("The analyzer reported {0} errors. Generation skipped.", error_count);
                    return 1;
                }
            }

            if (count_words) {
                    var word_count_metadata = new LocalizationMetadata ();
                    word_count_metadata.Add ("Word-Count", word_count.ToString (CultureInfo.InvariantCulture));
                    generator.Add (word_count_metadata);
            }

            generator.Generate (output_path);

            if (generator is AndroidGenerator && android_input_strings_xml != null && android_output_strings_xml != null) {
                ((AndroidGenerator)generator).LocalizeManualStringsXml (android_input_strings_xml, android_output_strings_xml);
            }

            if (verbose && count_words) {
                Console.WriteLine("Total of words in untranslated messages: {0} words.", word_count);
            }

            return 0;
        }