From 8727b6e6d083f3f9bad0f8043ecf97956ce6c386 Mon Sep 17 00:00:00 2001 From: Mike Mitterer Date: Fri, 25 Aug 2017 15:34:26 +0200 Subject: [PATCH] feature: xgettext is Depreciated - mkl10n writes the POT-File --- README.md | 10 +- bin/argparser/Config.dart | 209 ++++++++++ bin/argparser/Options.dart | 55 +++ bin/mkl10n.dart | 378 ++++++------------ lib/locale/messages.dart | 25 +- lib/parser.dart | 11 + lib/parser/Lexer.dart | 50 ++- lib/parser/Parser.dart | 65 ++- lib/parser/Statement.dart | 8 +- lib/parser/Token.dart | 2 +- lib/parser/pot.dart | 115 +++++- locale/de/LC_MESSAGES/messages.json | 25 +- locale/de/LC_MESSAGES/messages.po | 219 +++------- locale/messages.json | 25 +- .../LC_MESSAGES/messages.gettext.pot | 183 +++++++++ locale/templates/LC_MESSAGES/messages.pot | 195 ++------- locale/templates/potheader.tpl | 17 + pubspec.yaml | 2 + samples/cmdline/lib/cmdline/Options.dart | 16 +- samples/cmdline/lib/locale/messages.dart | 2 +- .../locale/de/LC_MESSAGES/messages.json | 2 +- .../cmdline/locale/de/LC_MESSAGES/messages.po | 8 +- samples/cmdline/locale/messages.json | 2 +- .../LC_MESSAGES/messages.gettext.pot | 43 ++ .../locale/templates/LC_MESSAGES/messages.pot | 23 +- .../cmdline/locale/templates/potheader.tpl | 17 + test/unit/_resources/login.dart.txt | 15 +- test/unit/l10n/L10NTranslation_test.dart | 2 +- test/unit/parser/Parser_test.dart | 39 +- 29 files changed, 1029 insertions(+), 734 deletions(-) create mode 100644 bin/argparser/Config.dart create mode 100644 bin/argparser/Options.dart create mode 100644 locale/templates/LC_MESSAGES/messages.gettext.pot create mode 100644 locale/templates/potheader.tpl create mode 100644 samples/cmdline/locale/templates/LC_MESSAGES/messages.gettext.pot create mode 100644 samples/cmdline/locale/templates/potheader.tpl diff --git a/README.md b/README.md index 0e09deb..d9bb6a5 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,14 @@ l10n / (gettext-oriented) PO-File Generator ------------------------------------------- > Helps to localize your application -Before your start: +## Important +Since v1.x xgettext creates `locale/templates/LC_MESSAGES/messages.gettext.pot` for testing purposes only!!! +`mkl10n` doesnt use xgettext anymore - instead the `l10n.parser`-package creates it's own `.pot`-File! + +## Before your start: - [A Quick Gettext Tutorial](http://www.labri.fr/perso/fleury/posts/programming/a-quick-gettext-tutorial.html) -## Windows +### Windows **Sorry guys** - this is App is tested under Mac-OSX but should work on Linux without problems. ## Install @@ -15,7 +19,7 @@ $ pub global activate l10n ## System requirements Install the following cmdline-Applications: -* xgettext +* xgettext (**Depreciated** since 1.x!) * msginit * msgmerge diff --git a/bin/argparser/Config.dart b/bin/argparser/Config.dart new file mode 100644 index 0000000..e3671d7 --- /dev/null +++ b/bin/argparser/Config.dart @@ -0,0 +1,209 @@ +part of l10n.app; + +/** + * Defines default-configurations. + * Most of these configs can be overwritten by commandline args. + */ +class Config { + final Logger _logger = new Logger("mkl10llocale.Config"); + + static const String _KEY_LOCALE_DIR = "localeDir"; + static const String _KEY_TEMPLATES_DIR = "templatesDir"; + static const String _KEY_HEADER_TEMPLATE = "headertemplate"; + static const String _KEY_POT_DIR = "potdir"; + static const String _KEY_POT_FILENAME = "potfile"; + static const String _KEY_PO_FILENAME = "pofile"; + static const String _KEY_JSON_FILENAME = "jsonfilename"; + static const String _KEY_DART_FILENAME = "dartfilename"; + static const String _KEY_LIB_PREFIX = "libprefix"; + static const String _KEY_LOGLEVEL = "loglevel"; + static const String _KEY_LOCALES = "locales"; + static const String _KEY_DART_PATH = "dartpath"; + static const String _KEY_SYSTEM_LOCALE = "systemlocale"; + static const String _KEY_EXCLUDE_DIRS = "exclude_dirs"; + + final ArgResults _argResults; + final Map _settings = new Map(); + + Config(this._argResults,final String systemLocale) { + + _settings[_KEY_LOCALE_DIR] = 'locale'; + _settings[_KEY_TEMPLATES_DIR] = 'templates'; + _settings[_KEY_HEADER_TEMPLATE] = 'potheader.tpl'; + _settings[_KEY_POT_DIR] = 'templates/LC_MESSAGES'; + + _settings[_KEY_POT_FILENAME] = 'messages.pot'; + _settings[_KEY_PO_FILENAME] = 'messages.po'; + + _settings[_KEY_JSON_FILENAME] = 'messages.json'; + _settings[_KEY_DART_FILENAME] = 'messages.dart'; + + _settings[_KEY_LIB_PREFIX] = 'l10n'; + _settings[_KEY_LOGLEVEL] = 'info'; + + + _settings[_KEY_DART_PATH] = 'lib'; + + _settings[_KEY_LOCALES] = Intl.shortLocale(systemLocale); + _settings[_KEY_SYSTEM_LOCALE] = systemLocale; + + _settings[_KEY_EXCLUDE_DIRS] = ''; + + initializeDateFormatting(_settings[_KEY_SYSTEM_LOCALE],null); + + _overwriteSettingsWithConfigFile(); + _overwriteSettingsWithArgResults(); + } + + List get dirstoscan => _argResults.rest; + + /// Something like: locale/templates/LC_MESSAGES + String get potdir => "${_settings[_KEY_LOCALE_DIR]}/${_settings[_KEY_POT_DIR]}"; + + /// Where the pot-header-template is stored + String get templatesdir => "${_settings[_KEY_LOCALE_DIR]}/${_settings[_KEY_TEMPLATES_DIR]}"; + + /// Filename for Header-Template + String get headerTemplateFile => "$templatesdir/${_settings[_KEY_HEADER_TEMPLATE]}"; + + /// Something like: locale/templates/LC_MESSAGES/messages.pot + String get potfile => "$potdir/${_settings[_KEY_POT_FILENAME]}"; + + /// Something like: locale/en/LC_MESSAGES/messages.po + String getPOFile(final String locale) => "${_settings[_KEY_LOCALE_DIR]}/$locale/LC_MESSAGES/${_settings[_KEY_PO_FILENAME]}"; + + /// Something like: locale/messages.json + String get jsonfile => "${_settings[_KEY_LOCALE_DIR]}/${_settings[_KEY_JSON_FILENAME]}"; + + /// Something like: locale/messages.dart + String get dartfile => "${_settings[_KEY_DART_PATH]}/${_settings[_KEY_LOCALE_DIR]}/${_settings[_KEY_DART_FILENAME]}"; + + String get libprefix => _settings[_KEY_LIB_PREFIX]; + + String get loglevel => _settings[_KEY_LOGLEVEL]; + + String get locales => _settings[_KEY_LOCALES]; + + String get systemLocale => _settings[_KEY_SYSTEM_LOCALE]; + + List get excludeDirs => _settings[_KEY_EXCLUDE_DIRS].split(new RegExp(r",\s*")); + + String get configfile => ".mkl10n.yaml"; + + Map get settings { + final Map settings = new Map(); + + settings[translate(l10n("Config-File"))] = configfile; + + settings["POT-File"] = potfile; + settings["Header-Template"] = headerTemplateFile; + settings["PO-File"] = getPOFile(""); + settings["JSON-File"] = jsonfile; + settings["DART-File"] = dartfile; + settings["libprefix (${Config._KEY_LIB_PREFIX})"] = libprefix; + settings["loglevel"] = loglevel; + settings["locales"] = locales; + settings["System-Locale"] = systemLocale; + + if(dirstoscan.length > 0) { + settings[translate(l10n("Dirs to scan"))] = dirstoscan.join(", "); + } + settings[translate(l10n("Dirs to exclude")) + + " (${Config._KEY_EXCLUDE_DIRS})"] = excludeDirs.join(", "); + + return settings; + } + + void printSettings(final Map settings) { + Validate.notEmpty(settings); + + int getMaxKeyLength() { + int length = 0; + settings.keys.forEach((final String key) => length = max(length,key.length)); + return length; + } + + final int maxKeyLength = getMaxKeyLength(); + + String prepareKey(final String key) { + return "${key[0].toUpperCase()}${key.substring(1)}:".padRight(maxKeyLength + 1); + } + + print(translate(l10n("Settings:"))); + settings.forEach((final String key,final String value) { + print(" ${prepareKey(key)} $value"); + }); + + print(""); + + // You will see this comment in the .po/.pot-File + print(translate(l10n("External commands:"))); + [ xgettext, msginit, msgmerge ].forEach((final ShellCommand command) { + String exe = translate(l10n("not installed!")); + try { + exe = command.executable; + + } on StateError catch(_) {} + + print(" ${(command.name + ':').padRight(maxKeyLength + 1)} ${exe}"); + }); + } + + // -- private ------------------------------------------------------------- + + _overwriteSettingsWithArgResults() { + + /// Makes sure that path does not end with a / + String checkPath(final String arg) { + String path = arg; + if(path.endsWith("/")) { + path = path.replaceFirst(new RegExp("/\$"),""); + } + return path; + } + + if(_argResults[Options._ARG_LOGLEVEL] != null) { + _settings[_KEY_LOGLEVEL] = _argResults[Options._ARG_LOGLEVEL]; + } + + if(_argResults[Options._ARG_LIB_PREFIX] != null) { + _settings[_KEY_LIB_PREFIX] = _argResults[Options._ARG_LIB_PREFIX]; + } + + if(_argResults[Options._ARG_LOCALE_DIR] != null) { + _settings[_KEY_LOCALE_DIR] = "${checkPath(_argResults[Options._ARG_LOCALE_DIR])}/${_settings[_KEY_LOCALE_DIR]}"; + } + + if(_argResults[Options._ARG_LOCALES] != null) { + _settings[_KEY_LOCALES] = _argResults[Options._ARG_LOCALES]; + } + + if(_argResults[Options._ARG_DART_PATH] != null) { + _settings[_KEY_DART_PATH] = checkPath(_argResults[Options._ARG_DART_PATH]); + } + + if(_argResults[Options._ARG_DART_PATH] != null) { + _settings[_KEY_DART_PATH] = checkPath(_argResults[Options._ARG_DART_PATH]); + } + + if(_argResults[Options._ARG_EXCLUDE] != null) { + _settings[_KEY_EXCLUDE_DIRS] = checkPath(_argResults[Options._ARG_EXCLUDE]); + } + } + + void _overwriteSettingsWithConfigFile() { + final File file = new File(configfile); + if(!file.existsSync()) { + return; + } + final yaml.YamlMap map = yaml.loadYaml(file.readAsStringSync()); + _settings.keys.forEach((final String key) { + if(map != null && map.containsKey(key)) { + _settings[key] = map[key]; + print("Found $key in $configfile: ${map[key]}"); + } + }); + } + + +} \ No newline at end of file diff --git a/bin/argparser/Options.dart b/bin/argparser/Options.dart new file mode 100644 index 0000000..0cc103c --- /dev/null +++ b/bin/argparser/Options.dart @@ -0,0 +1,55 @@ +part of l10n.app; + +/// Commandline params for this [Application] +class Options { + static const _ARG_LOCALES = 'locales'; + static const _ARG_HELP = 'help'; + static const _ARG_LOGLEVEL = 'loglevel'; + static const _ARG_SETTINGS = 'settings'; + static const _ARG_LIB_PREFIX = 'libprefix'; + static const _ARG_LOCALE_DIR = 'localedir'; + static const _ARG_DART_PATH = 'dartpath'; + static const _ARG_EXCLUDE = 'exclude'; + + final ArgParser _parser; + + Options() : _parser = Options._createOptions(); + + ArgResults parse(final List args) { + Validate.notNull(args); + return _parser.parse(args); + } + + void showUsage() { + print(translate(l10n("Usage: mkl10n [options] "))); + _parser.usage.split("\n").forEach((final String line) { + print(" $line"); + }); + + print(""); + print(translate(l10n("Example:"))); + print(" " + translate(l10n("mkl10n . - Generates lib/locale/messages.dart"))); + print(" " + translate(l10n("mkl10n -l en,de . - Generates translation for en + de"))); + print(""); + } + + // -- private ------------------------------------------------------------- + + static ArgParser _createOptions() { + final ArgParser parser = new ArgParser() + + ..addFlag(_ARG_HELP, abbr: 'h', negatable: false, help: translate(l10n("Shows this message"))) + ..addFlag(_ARG_SETTINGS, abbr: 's', negatable: false, help: translate(l10n("Prints settings"))) + + ..addOption(_ARG_LOCALES, abbr: 'l', help: translate(l10n("locales - separated by colon, Sample: --locales en,de,es"))) + ..addOption(_ARG_LOGLEVEL, abbr: 'v', help: "[ finer | debug | info | warning ]") + ..addOption(_ARG_LIB_PREFIX, abbr: 'p', help: translate(l10n("Libprefix for generated DART-File (library .locale;)"))) + ..addOption(_ARG_LOCALE_DIR, abbr: 'd', help: translate(l10n("Defines where to place your locale-Dir"))) + ..addOption(_ARG_DART_PATH, abbr: 'a', help: translate(l10n("Where should the DART-File go? (/locale/messages.dart)"))) + ..addOption(_ARG_EXCLUDE, abbr: 'x', help: translate(l10n("Exclude folders from scaning"))) + ; + + return parser; + } + +} \ No newline at end of file diff --git a/bin/mkl10n.dart b/bin/mkl10n.dart index d44fcf6..f05e3e3 100755 --- a/bin/mkl10n.dart +++ b/bin/mkl10n.dart @@ -20,71 +20,67 @@ import 'package:logging_handlers/logging_handlers_shared.dart'; import 'package:l10n/l10n.dart'; import 'package:l10n/locale/messages.dart'; +import 'package:l10n/parser.dart'; + +part 'argparser/Config.dart'; +part 'argparser/Options.dart'; part 'commands/ShellCommand.dart'; part 'commands/commands.dart'; class Application { - final Logger _logger = new Logger("mkl10llocale.Application"); - - static const _ARG_LOCALES = 'locales'; - static const _ARG_HELP = 'help'; - static const _ARG_LOGLEVEL = 'loglevel'; - static const _ARG_SETTINGS = 'settings'; - static const _ARG_LIB_PREFIX = 'libprefix'; - static const _ARG_LOCALE_DIR = 'localedir'; - static const _ARG_DART_PATH = 'dartpath'; - static const _ARG_EXCLUDE = 'exclude'; + final Logger _logger = new Logger("l10n.Application"); - ArgParser _parser; + /// Commandline options + final Options _options = new Options(); - Application() : _parser = Application._createOptions(); - - void run(List args,final String locale) { + Future run(List args,final String locale) async { Validate.notBlank(locale); try { - final ArgResults argResults = _parser.parse(args); + final ArgResults argResults = _options.parse(args); final Config config = new Config(argResults,locale); _configLogging(config.loglevel); - if (argResults[_ARG_HELP] || (config.dirstoscan.length == 0 && args.length == 0)) { - _showUsage(); + if (argResults[Options._ARG_HELP] || (config.dirstoscan.length == 0 && args.length == 0)) { + _options.showUsage(); - } else if(argResults[_ARG_SETTINGS]) { - _printSettings(config.settings); + } else if(argResults[Options._ARG_SETTINGS]) { + config.printSettings(config.settings); } else { - _createPOTFile(config.potfile).then((final File potfile) { + await _createPOTHeaderTemplate(config.headerTemplateFile); + final File potfile = await _createPOTFile(config.potfile); + await _scanDirsAndFillPOTWithXGetText(config.dirstoscan,config.potfile, config.excludeDirs); - _scanDirsAndFillPOT(config.dirstoscan,config.potfile, config.excludeDirs).then((_) { + await _scanDirsAndFillPOTWithParser(config.dirstoscan, + config.potfile, config.headerTemplateFile,config.excludeDirs); - final List locales = config.locales.split(','); + final List locales = config.locales.split(','); - // accumulated JSON (the one ine locale) - final Map> json = new HashMap>(); + // accumulated JSON (the one ine locale) + final Map> json = new HashMap>(); - // _createJson returns ASYNC - so we wait until all locale JSON-Files are created - final List futuresForJson = new List(); - locales.forEach( (final String locale) { - final File pofile = _preparePOFile(locale, potfile,config.getPOFile(locale)); + // _createJson returns ASYNC - so we wait until all locale JSON-Files are created + final List futuresForJson = new List(); + locales.forEach( (final String locale) { + final File pofile = _preparePOFile(locale, potfile,config.getPOFile(locale)); - _mergePO(pofile,potfile); - futuresForJson.add( _createJson(locale,pofile).then((final Map jsonForLocale) => json[locale] = jsonForLocale)); - }); - Future.wait(futuresForJson).then((_) { - _createMergedJson(json,config.jsonfile); - _createDartFile(json,config.dartfile,libPrefix: config.libprefix); - }); - }); + _mergePO(pofile,potfile); + futuresForJson.add( _createJson(locale,pofile).then((final Map jsonForLocale) => json[locale] = jsonForLocale)); + }); + Future.wait(futuresForJson).then((_) { + _createMergedJson(json,config.jsonfile); + _createDartFile(json,config.dartfile,libPrefix: config.libprefix); }); + } } on FormatException { - _showUsage(); + _options.showUsage(); } } @@ -157,13 +153,51 @@ class Application { } /// Make sure that the POT-File exists before xgettext - Future _createPOTFile(final String potfile) { + Future _createPOTFile(final String potfile) async { final File file = new File(potfile); + final File fileGetText = new File(potfile.replaceFirst(new RegExp(r"\.pot$"), ".gettext.pot")); + + await fileGetText.create(recursive: true); return file.create(recursive: true); + + + } + + /// If the header-Template does not exist - it will be created + Future _createPOTHeaderTemplate(final String templateName) async { + final File file = new File(templateName); + final String template = ''' + # SOME DESCRIPTIVE TITLE. + # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER + # This file is distributed under the same license as the PACKAGE package. + # FIRST AUTHOR , YEAR. + # + msgid "" + msgstr "" + "Project-Id-Version: PACKAGE VERSION\\n" + "Report-Msgid-Bugs-To: \\n" + "POT-Creation-Date: {date}\\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI\\n" + "Last-Translator: FULL NAME \\n" + "Language-Team: LANGUAGE \\n" + "Language: \\n" + "MIME-Version: 1.0\\n" + "Content-Type: text/plain; charset=UTF-8\\n" + "Content-Transfer-Encoding: 8bit\\n" + '''.replaceAll(new RegExp(r"^\s*",multiLine: true), "") + .replaceFirst(new RegExp(r"\n$",multiLine: true), ""); + + if(! await file.exists()) { + await file.create(recursive: true); + await file.writeAsString(template,flush: true); + } } /// Iterates through dirs and adds the result to the POT-File - Future _scanDirsAndFillPOT(final List dirstoscan, final String potfile, final List dirsToExclude) { + Future _scanDirsAndFillPOTWithXGetText(final List dirstoscan, + String potfile, final List dirsToExclude) { + + potfile = potfile.replaceFirst(new RegExp(r"\.pot$"), ".gettext.pot"); final Future future = new Future(() { for (final String dir in dirstoscan) { _iterateThroughDirSync(dir, dirsToExclude, (final File file) { @@ -186,6 +220,40 @@ class Application { return future; } + /// Iterates through dirs and adds the result to the POT-File + Future _scanDirsAndFillPOTWithParser(final List dirstoscan, + final String potfile, final String headerTemplate, final List dirsToExclude) { + + final Lexer lexer = new Lexer(); + final Parser parser = new Parser(); + final POT pot = new POT(); + + final Future future = new Future(() async { + for (final String dir in dirstoscan) { + _iterateThroughDirSync(dir, dirsToExclude, (final File file) { + _logger.finer(" -> ${file.path}"); + + final String filename = file.path; + + final String source = new File(filename).readAsStringSync(); + final List tokens = lexer.scan(source); + final List statements = parser.parse(filename, tokens); + final List blocks = collectPOTBlocks(statements); + + if(blocks.length > 0) { + _logger.finer(" #${blocks.length} Translation-Blocks found in ${filename}"); + pot.addBlocks(blocks); + } + }); + } + + await pot.write(potfile,headerTemplate); + return true; + }); + + return future; + } + /// Goes through the files void _iterateThroughDirSync(final String dir, final List dirsToExclude, void callback(final File file)) { _logger.info("Scanning: $dir"); @@ -196,7 +264,7 @@ class Application { final Directory directory = new Directory(dir); if (directory.existsSync()) { directory.listSync(recursive: true).where((final FileSystemEntity entity) { - _logger.fine("Entity: ${entity}"); + _logger.finer("Entity: ${entity}"); bool isUsableFile = (entity != null && FileSystemEntity.isFileSync(entity.path) && ( entity.path.endsWith(".dart") || entity.path.endsWith(".DART")) || entity.path.endsWith(".html") ); @@ -210,7 +278,8 @@ class Application { } if(entity.path.startsWith(".pub/") || entity.path.startsWith("./.pub/") || - entity.path.startsWith("build/") || entity.path.startsWith("./build/")){ + entity.path.startsWith(".git/") || entity.path.startsWith("./.git/") || + entity.path.startsWith("build/") || entity.path.startsWith("./build/")){ return false; } @@ -231,70 +300,9 @@ class Application { } } - void _showUsage() { - print(translate(l10n("Usage: mkl10n [options] "))); - _parser.usage.split("\n").forEach((final String line) { - print(" $line"); - }); - - print(""); - print(translate(l10n("Example:"))); - print(" " + translate(l10n("mkl10n . - Generates lib/locale/messages.dart"))); - print(" " + translate(l10n("mkl10n -l en,de . - Generates translation for en + de"))); - print(""); - } - - void _printSettings(final Map settings) { - Validate.notEmpty(settings); - - int getMaxKeyLength() { - int length = 0; - settings.keys.forEach((final String key) => length = max(length,key.length)); - return length; - } - - final int maxKeyLength = getMaxKeyLength(); - - String prepareKey(final String key) { - return "${key[0].toUpperCase()}${key.substring(1)}:".padRight(maxKeyLength + 1); - } - - print(translate(l10n("Settings:"))); - settings.forEach((final String key,final String value) { - print(" ${prepareKey(key)} $value"); - }); - - print(""); - - // You will see this comment in the .po/.pot-File - print(translate(l10n("External commands:"))); - [ xgettext, msginit, msgmerge ].forEach((final ShellCommand command) { - String exe = translate(l10n("not installed!")); - try { - exe = command.executable; - - } on StateError catch(_) {} - - print(" ${(command.name + ':').padRight(maxKeyLength + 1)} ${exe}"); - }); - } - - static ArgParser _createOptions() { - final ArgParser parser = new ArgParser() - ..addFlag(_ARG_HELP, abbr: 'h', negatable: false, help: translate(l10n("Shows this message"))) - ..addFlag(_ARG_SETTINGS, abbr: 's', negatable: false, help: translate(l10n("Prints settings"))) - ..addOption(_ARG_LOCALES, abbr: 'l', help: translate(l10n("locales - separated by colon, Sample: --locales en,de,es"))) - ..addOption(_ARG_LOGLEVEL, abbr: 'v', help: "[ info | debug | warning ]") - ..addOption(_ARG_LIB_PREFIX, abbr: 'p', help: translate(l10n("Libprefix for generated DART-File (library .locale;)"))) - ..addOption(_ARG_LOCALE_DIR, abbr: 'd', help: translate(l10n("Defines where to place your locale-Dir"))) - ..addOption(_ARG_DART_PATH, abbr: 'a', help: translate(l10n("Where should the DART-File go? (/locale/messages.dart)"))) - ..addOption(_ARG_EXCLUDE, abbr: 'x', help: translate(l10n("Exclude folders from scaning"))) - ; - return parser; - } /// Creates .json-File in the same location where the .po file is Future> _createJson(final String locale,final File pofile) { @@ -365,6 +373,10 @@ class Application { // now control the logging. // Turn off all logging first switch(loglevel) { + case "finer": + Logger.root.level = Level.FINER; + break; + case "fine": case "debug": Logger.root.level = Level.FINE; @@ -382,168 +394,6 @@ class Application { } } -/** - * Defines default-configurations. - * Most of these configs can be overwritten by commandline args. - */ -class Config { - final Logger _logger = new Logger("mkl10llocale.Config"); - - static const String _KEY_LOCALE_DIR = "localeDir"; - static const String _KEY_TEMPLATES_DIR = "templatesDir"; - static const String _KEY_POT_FILENAME = "potfile"; - static const String _KEY_PO_FILENAME = "pofile"; - static const String _KEY_JSON_FILENAME = "jsonfilename"; - static const String _KEY_DART_FILENAME = "dartfilename"; - static const String _KEY_LIB_PREFIX = "libprefix"; - static const String _KEY_LOGLEVEL = "loglevel"; - static const String _KEY_LOCALES = "locales"; - static const String _KEY_DART_PATH = "dartpath"; - static const String _KEY_SYSTEM_LOCALE = "systemlocale"; - static const String _KEY_EXCLUDE_DIRS = "exclude_dirs"; - - final ArgResults _argResults; - final Map _settings = new Map(); - - Config(this._argResults,final String systemLocale) { - - _settings[_KEY_LOCALE_DIR] = 'locale'; - _settings[_KEY_TEMPLATES_DIR] = 'templates/LC_MESSAGES'; - - _settings[_KEY_POT_FILENAME] = 'messages.pot'; - _settings[_KEY_PO_FILENAME] = 'messages.po'; - - _settings[_KEY_JSON_FILENAME] = 'messages.json'; - _settings[_KEY_DART_FILENAME] = 'messages.dart'; - - _settings[_KEY_LIB_PREFIX] = 'l10n'; - _settings[_KEY_LOGLEVEL] = 'info'; - - - _settings[_KEY_DART_PATH] = 'lib'; - - _settings[_KEY_LOCALES] = Intl.shortLocale(systemLocale); - _settings[_KEY_SYSTEM_LOCALE] = systemLocale; - - _settings[_KEY_EXCLUDE_DIRS] = ''; - - initializeDateFormatting(_settings[_KEY_SYSTEM_LOCALE],null); - - _overwriteSettingsWithConfigFile(); - _overwriteSettingsWithArgResults(); - } - - List get dirstoscan => _argResults.rest; - - /// Something like: locale/templates/LC_MESSAGES - String get potdir => "${_settings[_KEY_LOCALE_DIR]}/${_settings[_KEY_TEMPLATES_DIR]}"; - - /// Something like: locale/templates/LC_MESSAGES/messages.pot - String get potfile => "$potdir/${_settings[_KEY_POT_FILENAME]}"; - - /// Something like: locale/en/LC_MESSAGES/messages.po - String getPOFile(final String locale) => "${_settings[_KEY_LOCALE_DIR]}/$locale/LC_MESSAGES/${_settings[_KEY_PO_FILENAME]}"; - - /// Something like: locale/messages.json - String get jsonfile => "${_settings[_KEY_LOCALE_DIR]}/${_settings[_KEY_JSON_FILENAME]}"; - - /// Something like: locale/messages.dart - String get dartfile => "${_settings[_KEY_DART_PATH]}/${_settings[_KEY_LOCALE_DIR]}/${_settings[_KEY_DART_FILENAME]}"; - - String get libprefix => _settings[_KEY_LIB_PREFIX]; - - String get loglevel => _settings[_KEY_LOGLEVEL]; - - String get locales => _settings[_KEY_LOCALES]; - - String get systemLocale => _settings[_KEY_SYSTEM_LOCALE]; - - List get excludeDirs => _settings[_KEY_EXCLUDE_DIRS].split(new RegExp(r",\s*")); - - String get configfile => ".mkl10n.yaml"; - - Map get settings { - final Map settings = new Map(); - - settings[translate(l10n("Config-File"))] = configfile; - - settings["POT-File"] = potfile; - settings["PO-File"] = getPOFile(""); - settings["JSON-File"] = jsonfile; - settings["DART-File"] = dartfile; - settings["libprefix (${Config._KEY_LIB_PREFIX})"] = libprefix; - settings["loglevel"] = loglevel; - settings["locales"] = locales; - settings["System-Locale"] = systemLocale; - - if(dirstoscan.length > 0) { - settings[translate(l10n("Dirs to scan"))] = dirstoscan.join(", "); - } - settings[translate(l10n("Dirs to exclude")) - + " (${Config._KEY_EXCLUDE_DIRS})"] = excludeDirs.join(", "); - - return settings; - } - - // -- private ------------------------------------------------------------- - - _overwriteSettingsWithArgResults() { - - /// Makes sure that path does not end with a / - String checkPath(final String arg) { - String path = arg; - if(path.endsWith("/")) { - path = path.replaceFirst(new RegExp("/\$"),""); - } - return path; - } - - if(_argResults[Application._ARG_LOGLEVEL] != null) { - _settings[_KEY_LOGLEVEL] = _argResults[Application._ARG_LOGLEVEL]; - } - - if(_argResults[Application._ARG_LIB_PREFIX] != null) { - _settings[_KEY_LIB_PREFIX] = _argResults[Application._ARG_LIB_PREFIX]; - } - - if(_argResults[Application._ARG_LOCALE_DIR] != null) { - _settings[_KEY_LOCALE_DIR] = "${checkPath(_argResults[Application._ARG_LOCALE_DIR])}/${_settings[_KEY_LOCALE_DIR]}"; - } - - if(_argResults[Application._ARG_LOCALES] != null) { - _settings[_KEY_LOCALES] = _argResults[Application._ARG_LOCALES]; - } - - if(_argResults[Application._ARG_DART_PATH] != null) { - _settings[_KEY_DART_PATH] = checkPath(_argResults[Application._ARG_DART_PATH]); - } - - if(_argResults[Application._ARG_DART_PATH] != null) { - _settings[_KEY_DART_PATH] = checkPath(_argResults[Application._ARG_DART_PATH]); - } - - if(_argResults[Application._ARG_EXCLUDE] != null) { - _settings[_KEY_EXCLUDE_DIRS] = checkPath(_argResults[Application._ARG_EXCLUDE]); - } - } - - void _overwriteSettingsWithConfigFile() { - final File file = new File(configfile); - if(!file.existsSync()) { - return; - } - final yaml.YamlMap map = yaml.loadYaml(file.readAsStringSync()); - _settings.keys.forEach((final String key) { - if(map != null && map.containsKey(key)) { - _settings[key] = map[key]; - print("Found $key in $configfile: ${map[key]}"); - } - }); - } - - -} - void main(List arguments) { findSystemLocale().then((final String locale) { diff --git a/lib/locale/messages.dart b/lib/locale/messages.dart index 0a4b896..23d3001 100644 --- a/lib/locale/messages.dart +++ b/lib/locale/messages.dart @@ -10,41 +10,24 @@ import 'package:l10n/l10n.dart'; final L10NTranslate translate = new L10NTranslate.withTranslations( { "de": { - "\"\n\"Hallo,\\n\"\n\" dies ist ein {{what}}": "", "\"\n\"Hallo\\n\"\n\"Test": "", - "Angular way7": "", - "Angular way8": "", "Config-File": "Konfigurationsfile", "Defines where to place your locale-Dir": "Definiert das locale-Verzeichnis", "Dirs to exclude": "Ignoriere Verzeichnisse", - "Dirs to scan": "", + "Dirs to scan": "Ignoriere Verzeichnisse", "Example:": "Beispiele:", "Exclude folders from scaning": "", "External commands:": "Externe Befehle:", - "Hallo Mike": "", - "Hallo Mike II": "", - "Hallo {{?}}": "", - "Hallo {{l10n}}": "", - "Hallo {{name}}": "", - "Hallo {{name}}, du bist jetzt {{age}} Jahre alt": "", - "Hallo, dies ist ein {{what}}": "", - "Hallo, {{name}}": "", - "Hello {{what}}": "", "Libprefix for generated DART-File (library .locale;)": "Prefix für die generiert Library (library .locale;)", "locales - separated by colon, Sample: --locales en,de,es": "locales - getrennt durch Beistrich, Beispiel: --locales en,de,es", - "Mike + {{name}}": "", - "mkl10n -l en,de . - Generates translation for en + de": "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de", - "mkl10n . - Generates lib/locale/messages.dart": "mkl10nlocale . - Erstellt lib/locale/messages.dart", - "mkl10nlocale -l en,de . - Generates translation for en + de": "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de", - "mkl10nlocale . - Generates lib/locale/messages.dart": "mkl10nlocale . - Erstellt lib/locale/messages.dart", + "mkl10n -l en,de . - Generates translation for en + de": "mkl10n -l en,de . - Erstellt die Übersetzungen für en + de", + "mkl10n . - Generates lib/locale/messages.dart": "mkl10n . - Erstellt lib/locale/messages.dart", "not installed!": "", "Prints settings": "Zeigt die Settings an", "Settings:": "Einstellungen:", "Shows this message": "", "Test1": "", - "This is a test": "", - "Usage: mkl10n [options] ": "Verwendung: mkl10nlocale [optionen] ", - "Usage: mkl10nlocale [options] ": "Verwendung: mkl10nlocale [optionen] ", + "Usage: mkl10n [options] ": "Verwendung: mkl10n [optionen] ", "Where should the DART-File go? (/locale/messages.dart)": "Wo soll das generierte Dart-File (messages.dart) erstellt werden" } }); diff --git a/lib/parser.dart b/lib/parser.dart index 4adc818..c2fd5c8 100644 --- a/lib/parser.dart +++ b/lib/parser.dart @@ -17,10 +17,21 @@ * limitations under the License. */ +/** + * Parses .dart and HTML-Files for l10n translatable strings and comments + * to generate a POT-File + * + * More on POT Files: + * https://www.crossdart.info/p/angular/1.1.2+2/application.dart.html + */ library l10n.parser; +import 'dart:async'; +import 'dart:io'; import 'dart:math' as math; +import 'package:intl/intl.dart'; import 'package:logging/logging.dart'; +import 'package:optional/optional.dart'; import 'package:validate/validate.dart'; part 'parser/Lexer.dart'; diff --git a/lib/parser/Lexer.dart b/lib/parser/Lexer.dart index 3af1fa5..610d786 100644 --- a/lib/parser/Lexer.dart +++ b/lib/parser/Lexer.dart @@ -22,8 +22,6 @@ part of l10n.parser; const int _EOF = -1; class Lexer { - final Logger _logger = new Logger('l10n.parser.Lexer'); - /// Current position in source int _offset = 0; @@ -43,7 +41,11 @@ class Lexer { final List tokens = new List(); + // Reset everything in case of reusing the Lexer _source = source; + _offset = 0; + _character = ''; + if(_source.isEmpty) { _offset = _EOF; } else { @@ -51,10 +53,11 @@ class Lexer { } // Many tokens are a single character, like operators and (). - final String charTokens = "\n()"; + final String charTokens = "\n(),"; final List tokenTypes = [ - TokenType.LINE, TokenType.LEFT_PAREN, TokenType.RIGHT_PAREN + TokenType.LINE, TokenType.LEFT_BRACKET, TokenType.RIGHT_BRACKET, + TokenType.COLON ]; String token = ""; @@ -101,15 +104,21 @@ class Lexer { } else if (_isNext('_(')) { _skip('_('); - state = TokenizeState.L10N; + //state = TokenizeState.L10N; + tokens.add(new Token("_(", TokenType.L10N)); + token = ""; } else if (_isNext('l10n(')) { _skip('l10n('); - state = TokenizeState.L10N; + //state = TokenizeState.L10N; + tokens.add(new Token("l10(", TokenType.L10N)); + token = ""; } else if (_isNext('gettext(')) { _skip('gettext('); - state = TokenizeState.L10N; + //state = TokenizeState.L10N; + tokens.add(new Token("gettext(", TokenType.L10N)); + token = ""; } else if (charTokens.indexOf(c) != -1) { tokens.add(new Token(c, tokenTypes[charTokens.indexOf(c)])); @@ -160,7 +169,12 @@ class Lexer { case TokenizeState.STRING_DOUBLE_QUOTE: case TokenizeState.STRING_SINGLE_QUOTE: - if (c == '"' || c == "'") { + if (c == '"' && !_isPrev('\\')) { + tokens.add(new Token(token, TokenType.STRING)); + token = ""; + state = TokenizeState.DEFAULT; + } + else if (c == "'" && !_isPrev('\\')) { tokens.add(new Token(token, TokenType.STRING)); token = ""; state = TokenizeState.DEFAULT; @@ -248,6 +262,17 @@ class Lexer { return _source.substring(tempOffset,tempOffset + nrOfCharacters) == expected; } + bool _isPrev(final String expected) { + final int nrOfCharacters = expected.length; + final int tempOffset = _offset - 1 - nrOfCharacters; + + if(tempOffset < 0) { + return false; + } + + return _source.substring(tempOffset,tempOffset + nrOfCharacters) == expected; + } + String _readNext() { if(_offset == _EOF) { _character = ''; @@ -305,10 +330,15 @@ class Lexer { if(_isNext("'''")) { _skip("'''"); stringClosed = true; - } else if(_isNext('"""')) { + } + else if(_isNext('"""')) { _skip('"""'); stringClosed = true; - }else if (c == '"' || c == "'") { + } + else if (c == '"' && _isPrev('\\') == false) { + stringClosed = true; + } + else if (c == "'" && _isPrev('\\') == false) { stringClosed = true; } else { diff --git a/lib/parser/Parser.dart b/lib/parser/Parser.dart index 2f59571..5cece84 100644 --- a/lib/parser/Parser.dart +++ b/lib/parser/Parser.dart @@ -25,6 +25,9 @@ part of l10n.parser; class Parser { final List _tokens = new List(); + /// Current Token-Position + int _offset = 0; + /** * The top-level function to start parsing. This will keep consuming * tokens and routing to the other parse functions for the different @@ -36,34 +39,88 @@ class Parser { List parse(final String filename, final List tokens) { final List statements = new List(); + // Reset in case of reuse + _offset = 0; + this._tokens.clear(); this._tokens.addAll(tokens); - int line = 0; - _tokens.forEach((final Token token) { + int line = 1; + for(Optional oToken = _peek(); oToken.isPresent && _offset < _tokens.length; oToken = _peek()) { + Token token = oToken.value; switch(token.type) { case TokenType.COMMENT: statements.add(new CommentStatement(line, token.text)); line += math.max(1,token.text.split("\n").length); + _read(); break; case TokenType.L10N: - statements.add(new L10NStatement(filename, line, token.text)); + // Singular + if(_isNext([TokenType.STRING, TokenType.RIGHT_BRACKET ])) { + token = _read().value; + statements.add(new L10NStatement(filename, line, [token.text])); + } + // Plural + else if(_isNext([TokenType.STRING, TokenType.COLON, TokenType.STRING, TokenType.RIGHT_BRACKET ])) { + final List params = new List(); + + // String, Colon, String + params.add(_read().value.text);_read();params.add(_read().value.text); + + statements.add( + new L10NStatement(filename, line, params)); + } + _read(); break; case TokenType.LINE: statements.add(new NewLineStatement(line)); line++; + _read(); break; default: + _read(); } - }); + }; return statements; } + // - private ----------------------------------------------------------------------------------- + /// Peek the current [Token] + /// Avoiding null - so [Optional] is a good option + Optional _peek() => _offset < _tokens.length ? + new Optional.of(_tokens[_offset]) : new Optional.empty(); + /// Returns the next [Token] + /// + /// In case of EOF it returns an empty [Optional] + Optional _read() { + _offset++; + if (_offset < _tokens.length) { + return new Optional.of(_tokens[_offset]); + } + return new Optional.empty(); + } + + /// Compares the next tokens + bool _isNext(final List types) { + Validate.notEmpty(types); + + final int endPosition = _offset + 1 + types.length; + if(endPosition >= _tokens.length) { + return false; + } + for(int index = 0;(index + _offset + 1) < endPosition; index++) { + if(types[index] != _tokens[(index + _offset + 1)].type) { + //print("T1 ${types[index]}, T2 ${_tokens[(index + _offset + 1)].type}"); + return false; + } + } + return true; + } } \ No newline at end of file diff --git a/lib/parser/Statement.dart b/lib/parser/Statement.dart index f202260..7aff745 100644 --- a/lib/parser/Statement.dart +++ b/lib/parser/Statement.dart @@ -48,17 +48,19 @@ class CommentStatement extends Statement { } class L10NStatement extends Statement { - final String msgid; final List params; final String filename; - L10NStatement(this.filename, final int line, final String this.msgid) - : params = msgid.split(","), super(line); + L10NStatement(this.filename, final int line, final List params) + : params = new List.from(params), super(line); @override void accept(final Visitor visitor) { visitor.visitL10n(this); } + + /// First param is always the msgid + String get msgid => params.first; } class NewLineStatement extends Statement { diff --git a/lib/parser/Token.dart b/lib/parser/Token.dart index a7137eb..5a1e529 100644 --- a/lib/parser/Token.dart +++ b/lib/parser/Token.dart @@ -31,7 +31,7 @@ part of l10n.parser; enum TokenType { EOF, WORD, NUMBER, STRING, STRING_BLOCK, LINE, COMMENT, - LEFT_PAREN, RIGHT_PAREN, SEMI_COLON, + LEFT_BRACKET, RIGHT_BRACKET, COLON, L10N } diff --git a/lib/parser/pot.dart b/lib/parser/pot.dart index b0bfb8c..5efe1e1 100644 --- a/lib/parser/pot.dart +++ b/lib/parser/pot.dart @@ -89,9 +89,13 @@ List collectPOTBlocks(final List statements) { return blocks; } +/// Creates the POT-File class POT { + final Logger _logger = new Logger('l10n.parser.POT'); + final Map mergedBlocks = new Map(); + void addBlocks(final List blocks) { blocks.forEach((final POTBlock block) { if(!mergedBlocks.containsKey(block.statement.msgid)) { @@ -102,4 +106,113 @@ class POT { mergedPOTBlock.merge(block.comments, block.statement); }); } -} \ No newline at end of file + + Future write(final String potFile, final String potTemplateHeader) async { + final String header = await _getHeader(potTemplateHeader); + final File file = new File(potFile); + + if(await file.exists()) { + await file.delete(); + } + + + _logger.fine(header); + _logger.fine(""); + + await file.writeAsString(header + "\n\n",flush: true); + + mergedBlocks.values.forEach((final MergedPOTBlock block) { + // Shows its output only it the loglevel is set to Level.FINE + block.visit(WritePOTVisitor(_logger, file)); + }); + + } + + // - private ----------------------------------------------------------------------------------- + + /// Reads the template-Header and replaces {date} with the current date + Future _getHeader(final String potTemplateHeader) async { + final File file = new File(potTemplateHeader); + Validate.isTrue(file.existsSync(),"${potTemplateHeader} does not exist!"); + + String template = await file.readAsString(); + template = template.replaceAll("{date}", + new DateFormat("yyyy-MM-dd HH:mm").format(new DateTime.now())); + + return template; + } +} + +/// Writes the POT-File +POTVisitor WritePOTVisitor(final Logger logger, final File file) { + return (final List comments, + final List statements) { + + final StringBuffer buffer = new StringBuffer(); + + comments.forEach((final CommentStatement statement) { + final List lines = statement.comment.split(new RegExp(r"\n")); + lines.forEach((final String line) { + buffer.writeln("#. ${line.trimLeft()}"); + }); + }); + statements.forEach((final L10NStatement statement) { + buffer.writeln("#: ${statement.filename}:${statement.line}"); + }); + + // All Statements have the same msgid - so we pick the first one + final L10NStatement statement = statements.first; + + buffer.writeln('msgid "${statement.msgid}"'); + + if(statement.params.length > 1) { + buffer.writeln('msgid_plural "${statement.params[1]}"'); + } + + buffer.writeln('msgstr ""'); + buffer.writeln(); + + logger.fine(buffer.toString().replaceFirst(new RegExp(r"\n$"), "")); + file.writeAsStringSync(buffer.toString(),mode: FileMode.WRITE_ONLY_APPEND,flush: true); + }; + } + +/// Prints all the POT-Blocks +/// +/// +/// final List tokens = lexer.scan(source); +/// +/// final List statements = parser.parse(filename, tokens); +/// final List blocks = collectPOTBlocks(statements); +/// +/// pot.addBlocks(blocks); +/// pot.addBlocks(blocks); +/// +/// pot.mergedBlocks.values.forEach((final MergedPOTBlock block) { +/// block.visit(PrintPOTVisitor); +/// }); +/// +void LogPOTVisitor( + final List comments, + final List statements) { + + final Logger _logger = new Logger("test.unit.parser._TestPrintPOTVisitor"); + + comments.forEach((final CommentStatement statement) { + final List lines = statement.comment.split(new RegExp(r"\n")); + lines.forEach((final String line) => _logger.fine("#. ${line.trimLeft()}")); + }); + statements.forEach((final L10NStatement statement) { + _logger.fine("#: ${statement.filename}:${statement.line}"); + }); + + // All Statements have the same msgid - so we pick the first one + final L10NStatement statement = statements.first; + + _logger.fine('msgid "${statement.msgid}"'); + if(statement.params.length > 1) { + _logger.fine('msgid_plural "${statement.params[1]}"'); + } + _logger.fine('msgstr ""'); + _logger.fine(''); +} diff --git a/locale/de/LC_MESSAGES/messages.json b/locale/de/LC_MESSAGES/messages.json index 81736c7..896442e 100644 --- a/locale/de/LC_MESSAGES/messages.json +++ b/locale/de/LC_MESSAGES/messages.json @@ -1,40 +1,23 @@ { "de": { - "\"\n\"Hallo,\\n\"\n\" dies ist ein {{what}}": "", "\"\n\"Hallo\\n\"\n\"Test": "", - "Angular way7": "", - "Angular way8": "", "Config-File": "Konfigurationsfile", "Defines where to place your locale-Dir": "Definiert das locale-Verzeichnis", "Dirs to exclude": "Ignoriere Verzeichnisse", - "Dirs to scan": "", + "Dirs to scan": "Ignoriere Verzeichnisse", "Example:": "Beispiele:", "Exclude folders from scaning": "", "External commands:": "Externe Befehle:", - "Hallo Mike": "", - "Hallo Mike II": "", - "Hallo {{?}}": "", - "Hallo {{l10n}}": "", - "Hallo {{name}}": "", - "Hallo {{name}}, du bist jetzt {{age}} Jahre alt": "", - "Hallo, dies ist ein {{what}}": "", - "Hallo, {{name}}": "", - "Hello {{what}}": "", "Libprefix for generated DART-File (library .locale;)": "Prefix für die generiert Library (library .locale;)", "locales - separated by colon, Sample: --locales en,de,es": "locales - getrennt durch Beistrich, Beispiel: --locales en,de,es", - "Mike + {{name}}": "", - "mkl10n -l en,de . - Generates translation for en + de": "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de", - "mkl10n . - Generates lib/locale/messages.dart": "mkl10nlocale . - Erstellt lib/locale/messages.dart", - "mkl10nlocale -l en,de . - Generates translation for en + de": "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de", - "mkl10nlocale . - Generates lib/locale/messages.dart": "mkl10nlocale . - Erstellt lib/locale/messages.dart", + "mkl10n -l en,de . - Generates translation for en + de": "mkl10n -l en,de . - Erstellt die Übersetzungen für en + de", + "mkl10n . - Generates lib/locale/messages.dart": "mkl10n . - Erstellt lib/locale/messages.dart", "not installed!": "", "Prints settings": "Zeigt die Settings an", "Settings:": "Einstellungen:", "Shows this message": "", "Test1": "", - "This is a test": "", - "Usage: mkl10n [options] ": "Verwendung: mkl10nlocale [optionen] ", - "Usage: mkl10nlocale [options] ": "Verwendung: mkl10nlocale [optionen] ", + "Usage: mkl10n [options] ": "Verwendung: mkl10n [optionen] ", "Where should the DART-File go? (/locale/messages.dart)": "Wo soll das generierte Dart-File (messages.dart) erstellt werden" } } \ No newline at end of file diff --git a/locale/de/LC_MESSAGES/messages.po b/locale/de/LC_MESSAGES/messages.po index 859d1d4..5e32ec2 100644 --- a/locale/de/LC_MESSAGES/messages.po +++ b/locale/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: L 10N4Dart\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-23 10:34+0200\n" +"POT-Creation-Date: 2017-08-25 15:16\n" "PO-Revision-Date: 2017-08-21 11:22+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,206 +17,85 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: example/index.html:9 example/index.html:11 -msgid "Angular way7" -msgstr "" - -#. Hallo Kommentar aus HTML1 -#. Hallo Kommentar aus HTML -#: example/index.html:11 -msgid "Angular way8" -msgstr "" - -#: bin/mkl10n.dart:460 bin/mkl10n.dart:467 bin/mkl10n.dart:468 +#: bin/argparser/Config.dart:96 msgid "Config-File" msgstr "Konfigurationsfile" -#: bin/mkl10nlocale.dart:273 bin/mkl10nlocale.dart:277 -#: bin/mkl10nlocale.dart:274 bin/mkl10nlocale.dart:279 -#: bin/mkl10nlocale.dart:281 bin/mkl10n.dart:283 bin/mkl10n.dart:290 -#: bin/mkl10n.dart:291 -msgid "Defines where to place your locale-Dir" -msgstr "Definiert das locale-Verzeichnis" +#: bin/argparser/Config.dart:109 +#, fuzzy +msgid "Dirs to scan" +msgstr "Ignoriere Verzeichnisse " -#: bin/mkl10n.dart:474 bin/mkl10n.dart:481 bin/mkl10n.dart:482 +#: bin/argparser/Config.dart:111 msgid "Dirs to exclude" msgstr "Ignoriere Verzeichnisse " -#: bin/mkl10nlocale.dart:443 bin/mkl10nlocale.dart:447 -#: bin/mkl10nlocale.dart:444 bin/mkl10nlocale.dart:450 -#: bin/mkl10nlocale.dart:452 bin/mkl10nlocale.dart:454 -#: bin/mkl10nlocale.dart:455 bin/mkl10nlocale.dart:457 bin/mkl10n.dart:472 -#: bin/mkl10n.dart:479 bin/mkl10n.dart:480 -msgid "Dirs to scan" -msgstr "" - -#: bin/mkl10nlocale.dart:231 bin/mkl10n.dart:233 bin/mkl10n.dart:240 -#: bin/mkl10n.dart:241 -msgid "Example:" -msgstr "Beispiele:" - -#: bin/mkl10n.dart:285 bin/mkl10n.dart:292 bin/mkl10n.dart:293 -msgid "Exclude folders from scaning" -msgstr "" +#: bin/argparser/Config.dart:132 +msgid "Settings:" +msgstr "Einstellungen:" -#. You will see this comment in the according .po/.pot-File #. You will see this comment in the .po/.pot-File -#: bin/mkl10nlocale.dart:252 bin/mkl10nlocale.dart:256 -#: bin/mkl10nlocale.dart:253 bin/mkl10nlocale.dart:258 -#: bin/mkl10nlocale.dart:260 bin/mkl10n.dart:262 bin/mkl10n.dart:269 -#: bin/mkl10n.dart:270 +#: bin/argparser/Config.dart:140 msgid "External commands:" msgstr "Externe Befehle:" -#: test/unit/l10n/L10NTranslation_test.dart:160 -msgid "" -"Hallo\n" -"Test" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:35 -msgid "Hallo Mike" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:43 -msgid "Hallo Mike II" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:52 -msgid "Hallo {{?}}" +#: bin/argparser/Config.dart:142 +msgid "not installed!" msgstr "" -#: test/unit/l10n/L10NTranslation_test.dart:63 -#: test/unit/l10n/L10NTranslation_test.dart:78 -msgid "Hallo {{l10n}}" -msgstr "" +#: bin/argparser/Options.dart:24 +#, fuzzy +msgid "Usage: mkl10n [options] " +msgstr "Verwendung: mkl10n [optionen] " -#: test/unit/l10n/L10NTranslation_test.dart:40 -#: test/unit/l10n/L10NTranslation_test.dart:49 -#: test/unit/l10n/L10NTranslation_test.dart:58 -msgid "Hallo {{name}}" -msgstr "" +#: bin/argparser/Options.dart:30 +msgid "Example:" +msgstr "Beispiele:" -#: test/unit/l10n/L10N_test.dart:65 -msgid "Hallo {{name}}, du bist jetzt {{age}} Jahre alt" -msgstr "" +#: bin/argparser/Options.dart:31 +#, fuzzy +msgid "mkl10n . - Generates lib/locale/messages.dart" +msgstr "mkl10n . - Erstellt lib/locale/messages.dart" -#. Im deutschen wird bei der Übersetzung ein \n eingefügt. -#. Ob der Key (msgid) ein \n enthält oder nicht ist egal -#: test/unit/l10n/L10NTranslation_test.dart:121 -msgid "" -"Hallo,\n" -" dies ist ein {{what}}" -msgstr "" +#: bin/argparser/Options.dart:32 +#, fuzzy +msgid "mkl10n -l en,de . - Generates translation for en + de" +msgstr "mkl10n -l en,de . - Erstellt die Übersetzungen für en + de" -#. default locale is en -#. - Fallback to EN -#. default locale is en -#. - Fallback to EN -#: test/unit/l10n/L10NTranslation_test.dart:109 -#: test/unit/l10n/L10NTranslation_test.dart:116 -#: test/unit/l10n/L10NTranslation_test.dart:127 -msgid "Hallo, dies ist ein {{what}}" +#: bin/argparser/Options.dart:41 +msgid "Shows this message" msgstr "" -#. Does not exist at all - brings back default message -#: test/unit/l10n/L10NTranslation_test.dart:130 -msgid "Hallo, {{name}}" -msgstr "" +#: bin/argparser/Options.dart:42 test/unit/l10n/L10NTranslation_test.dart:139 +msgid "Prints settings" +msgstr "Zeigt die Settings an" -#: test/unit/l10n/L10N_test.dart:61 -msgid "Hello {{what}}" -msgstr "" +#: bin/argparser/Options.dart:44 +msgid "locales - separated by colon, Sample: --locales en,de,es" +msgstr "locales - getrennt durch Beistrich, Beispiel: --locales en,de,es" -#: bin/mkl10nlocale.dart:272 bin/mkl10nlocale.dart:276 -#: bin/mkl10nlocale.dart:273 bin/mkl10nlocale.dart:278 -#: bin/mkl10nlocale.dart:280 bin/mkl10n.dart:282 bin/mkl10n.dart:289 -#: bin/mkl10n.dart:290 +#: bin/argparser/Options.dart:46 msgid "Libprefix for generated DART-File (library .locale;)" msgstr "Prefix für die generiert Library (library .locale;)" -#: test/unit/l10n/L10NTranslation_test.dart:64 -#: test/unit/l10n/L10NTranslation_test.dart:79 -#: test/unit/l10n/L10NTranslation_test.dart:83 -msgid "Mike + {{name}}" -msgstr "" - -#: bin/mkl10nlocale.dart:268 test/unit/l10n/L10NTranslation_test.dart:139 -#: bin/mkl10nlocale.dart:272 bin/mkl10nlocale.dart:269 -#: bin/mkl10nlocale.dart:274 bin/mkl10nlocale.dart:276 bin/mkl10n.dart:278 -#: bin/mkl10n.dart:285 bin/mkl10n.dart:286 -msgid "Prints settings" -msgstr "Zeigt die Settings an" +#: bin/argparser/Options.dart:47 +msgid "Defines where to place your locale-Dir" +msgstr "Definiert das locale-Verzeichnis" -#: bin/mkl10nlocale.dart:246 bin/mkl10nlocale.dart:250 -#: bin/mkl10nlocale.dart:247 bin/mkl10nlocale.dart:252 bin/mkl10n.dart:254 -#: bin/mkl10n.dart:261 bin/mkl10n.dart:262 -msgid "Settings:" -msgstr "Einstellungen:" +#: bin/argparser/Options.dart:48 +msgid "Where should the DART-File go? (/locale/messages.dart)" +msgstr "Wo soll das generierte Dart-File (messages.dart) erstellt werden" -#: bin/mkl10nlocale.dart:267 bin/mkl10nlocale.dart:271 -#: bin/mkl10nlocale.dart:268 bin/mkl10nlocale.dart:273 -#: bin/mkl10nlocale.dart:275 bin/mkl10n.dart:277 bin/mkl10n.dart:284 -#: bin/mkl10n.dart:285 -msgid "Shows this message" +#: bin/argparser/Options.dart:49 +msgid "Exclude folders from scaning" msgstr "" #: test/unit/l10n/L10NTranslation_test.dart:134 msgid "Test1" msgstr "" -#. print((l10n("This is a test").message)); -#: example/mini.dart:16 -msgid "This is a test" -msgstr "" - -#: bin/mkl10n.dart:227 bin/mkl10n.dart:234 bin/mkl10n.dart:235 -#, fuzzy -msgid "Usage: mkl10n [options] " -msgstr "Verwendung: mkl10nlocale [optionen] " - -#: bin/mkl10nlocale.dart:223 bin/mkl10nlocale.dart:227 -#: bin/mkl10nlocale.dart:224 bin/mkl10nlocale.dart:225 -msgid "Usage: mkl10nlocale [options] " -msgstr "Verwendung: mkl10nlocale [optionen] " - -#: bin/mkl10nlocale.dart:274 bin/mkl10nlocale.dart:278 -#: bin/mkl10nlocale.dart:275 bin/mkl10nlocale.dart:280 -#: bin/mkl10nlocale.dart:282 bin/mkl10n.dart:284 bin/mkl10n.dart:291 -#: bin/mkl10n.dart:292 -msgid "Where should the DART-File go? (/locale/messages.dart)" -msgstr "Wo soll das generierte Dart-File (messages.dart) erstellt werden" - -#: bin/mkl10nlocale.dart:270 bin/mkl10nlocale.dart:274 -#: bin/mkl10nlocale.dart:271 bin/mkl10nlocale.dart:276 -#: bin/mkl10nlocale.dart:278 bin/mkl10n.dart:280 bin/mkl10n.dart:287 -#: bin/mkl10n.dart:288 -msgid "locales - separated by colon, Sample: --locales en,de,es" -msgstr "locales - getrennt durch Beistrich, Beispiel: --locales en,de,es" - -#: bin/mkl10n.dart:235 bin/mkl10n.dart:242 bin/mkl10n.dart:243 -#, fuzzy -msgid "mkl10n -l en,de . - Generates translation for en + de" -msgstr "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de" - -#: bin/mkl10n.dart:234 bin/mkl10n.dart:241 bin/mkl10n.dart:242 -#, fuzzy -msgid "mkl10n . - Generates lib/locale/messages.dart" -msgstr "mkl10nlocale . - Erstellt lib/locale/messages.dart" - -#: bin/mkl10nlocale.dart:233 -#, fuzzy -msgid "mkl10nlocale -l en,de . - Generates translation for en + de" -msgstr "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de" - -#: bin/mkl10nlocale.dart:232 -#, fuzzy -msgid "mkl10nlocale . - Generates lib/locale/messages.dart" -msgstr "mkl10nlocale . - Erstellt lib/locale/messages.dart" - -#: bin/mkl10nlocale.dart:254 bin/mkl10nlocale.dart:258 -#: bin/mkl10nlocale.dart:255 bin/mkl10nlocale.dart:260 -#: bin/mkl10nlocale.dart:262 bin/mkl10n.dart:264 bin/mkl10n.dart:271 -#: bin/mkl10n.dart:272 -msgid "not installed!" +#: test/unit/l10n/L10NTranslation_test.dart:160 +msgid "" +"Hallo\n" +"Test" msgstr "" diff --git a/locale/messages.json b/locale/messages.json index 81736c7..896442e 100644 --- a/locale/messages.json +++ b/locale/messages.json @@ -1,40 +1,23 @@ { "de": { - "\"\n\"Hallo,\\n\"\n\" dies ist ein {{what}}": "", "\"\n\"Hallo\\n\"\n\"Test": "", - "Angular way7": "", - "Angular way8": "", "Config-File": "Konfigurationsfile", "Defines where to place your locale-Dir": "Definiert das locale-Verzeichnis", "Dirs to exclude": "Ignoriere Verzeichnisse", - "Dirs to scan": "", + "Dirs to scan": "Ignoriere Verzeichnisse", "Example:": "Beispiele:", "Exclude folders from scaning": "", "External commands:": "Externe Befehle:", - "Hallo Mike": "", - "Hallo Mike II": "", - "Hallo {{?}}": "", - "Hallo {{l10n}}": "", - "Hallo {{name}}": "", - "Hallo {{name}}, du bist jetzt {{age}} Jahre alt": "", - "Hallo, dies ist ein {{what}}": "", - "Hallo, {{name}}": "", - "Hello {{what}}": "", "Libprefix for generated DART-File (library .locale;)": "Prefix für die generiert Library (library .locale;)", "locales - separated by colon, Sample: --locales en,de,es": "locales - getrennt durch Beistrich, Beispiel: --locales en,de,es", - "Mike + {{name}}": "", - "mkl10n -l en,de . - Generates translation for en + de": "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de", - "mkl10n . - Generates lib/locale/messages.dart": "mkl10nlocale . - Erstellt lib/locale/messages.dart", - "mkl10nlocale -l en,de . - Generates translation for en + de": "mkl10nlocale -l en,de . - Erstellt die Übersetzungen für en + de", - "mkl10nlocale . - Generates lib/locale/messages.dart": "mkl10nlocale . - Erstellt lib/locale/messages.dart", + "mkl10n -l en,de . - Generates translation for en + de": "mkl10n -l en,de . - Erstellt die Übersetzungen für en + de", + "mkl10n . - Generates lib/locale/messages.dart": "mkl10n . - Erstellt lib/locale/messages.dart", "not installed!": "", "Prints settings": "Zeigt die Settings an", "Settings:": "Einstellungen:", "Shows this message": "", "Test1": "", - "This is a test": "", - "Usage: mkl10n [options] ": "Verwendung: mkl10nlocale [optionen] ", - "Usage: mkl10nlocale [options] ": "Verwendung: mkl10nlocale [optionen] ", + "Usage: mkl10n [options] ": "Verwendung: mkl10n [optionen] ", "Where should the DART-File go? (/locale/messages.dart)": "Wo soll das generierte Dart-File (messages.dart) erstellt werden" } } \ No newline at end of file diff --git a/locale/templates/LC_MESSAGES/messages.gettext.pot b/locale/templates/LC_MESSAGES/messages.gettext.pot new file mode 100644 index 0000000..f11be8d --- /dev/null +++ b/locale/templates/LC_MESSAGES/messages.gettext.pot @@ -0,0 +1,183 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-08-25 15:16+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: bin/argparser/Config.dart:96 +msgid "Config-File" +msgstr "" + +#: bin/argparser/Config.dart:109 +msgid "Dirs to scan" +msgstr "" + +#: bin/argparser/Config.dart:111 +msgid "Dirs to exclude" +msgstr "" + +#: bin/argparser/Config.dart:132 +msgid "Settings:" +msgstr "" + +#. You will see this comment in the .po/.pot-File +#: bin/argparser/Config.dart:140 +msgid "External commands:" +msgstr "" + +#: bin/argparser/Config.dart:142 +msgid "not installed!" +msgstr "" + +#: bin/argparser/Options.dart:24 +msgid "Usage: mkl10n [options] " +msgstr "" + +#: bin/argparser/Options.dart:30 +msgid "Example:" +msgstr "" + +#: bin/argparser/Options.dart:31 +msgid "mkl10n . - Generates lib/locale/messages.dart" +msgstr "" + +#: bin/argparser/Options.dart:32 +msgid "mkl10n -l en,de . - Generates translation for en + de" +msgstr "" + +#: bin/argparser/Options.dart:41 +msgid "Shows this message" +msgstr "" + +#: bin/argparser/Options.dart:42 test/unit/l10n/L10NTranslation_test.dart:139 +msgid "Prints settings" +msgstr "" + +#: bin/argparser/Options.dart:44 +msgid "locales - separated by colon, Sample: --locales en,de,es" +msgstr "" + +#: bin/argparser/Options.dart:46 +msgid "Libprefix for generated DART-File (library .locale;)" +msgstr "" + +#: bin/argparser/Options.dart:47 +msgid "Defines where to place your locale-Dir" +msgstr "" + +#: bin/argparser/Options.dart:48 +msgid "Where should the DART-File go? (/locale/messages.dart)" +msgstr "" + +#: bin/argparser/Options.dart:49 +msgid "Exclude folders from scaning" +msgstr "" + +#: test/unit/l10n/L10NTranslation_test.dart:40 +#: test/unit/l10n/L10NTranslation_test.dart:49 +#: test/unit/l10n/L10NTranslation_test.dart:58 +msgid "Hallo {{name}}" +msgstr "" + +#: test/unit/l10n/L10NTranslation_test.dart:63 +#: test/unit/l10n/L10NTranslation_test.dart:78 +msgid "Hallo {{l10n}}" +msgstr "" + +#: test/unit/l10n/L10NTranslation_test.dart:64 +#: test/unit/l10n/L10NTranslation_test.dart:79 +#: test/unit/l10n/L10NTranslation_test.dart:83 +msgid "Mike + {{name}}" +msgstr "" + +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#. default locale is en +#. - Fallback to EN +#: test/unit/l10n/L10NTranslation_test.dart:109 +#: test/unit/l10n/L10NTranslation_test.dart:116 +#: test/unit/l10n/L10NTranslation_test.dart:127 +msgid "Hallo, dies ist ein {{what}}" +msgstr "" + +#. Im deutschen wird bei der Übersetzung ein \n eingefügt. +#. Ob der Key (msgid) ein \n enthält oder nicht ist egal +#: test/unit/l10n/L10NTranslation_test.dart:121 +msgid "" +"Hallo,\n" +" dies ist ein {{what}}" +msgstr "" + +#. Does not exist at all - brings back default message +#: test/unit/l10n/L10NTranslation_test.dart:130 +msgid "Hallo, {{name}}" +msgstr "" + +#: test/unit/l10n/L10NTranslation_test.dart:134 +msgid "Test1" +msgstr "" + +#: test/unit/l10n/L10NTranslation_test.dart:160 +msgid "" +"Hallo\n" +"Test" +msgstr "" + +#: test/unit/l10n/L10N_test.dart:35 +msgid "Hallo Mike" +msgstr "" + +#: test/unit/l10n/L10N_test.dart:43 +msgid "Hallo Mike II" +msgstr "" + +#: test/unit/l10n/L10N_test.dart:52 +msgid "Hallo {{?}}" +msgstr "" + +#: test/unit/l10n/L10N_test.dart:61 +msgid "Hello {{what}}" +msgstr "" + +#: test/unit/l10n/L10N_test.dart:65 +msgid "Hallo {{name}}, du bist jetzt {{age}} Jahre alt" +msgstr "" diff --git a/locale/templates/LC_MESSAGES/messages.pot b/locale/templates/LC_MESSAGES/messages.pot index 1c72e42..f7c2d7f 100644 --- a/locale/templates/LC_MESSAGES/messages.pot +++ b/locale/templates/LC_MESSAGES/messages.pot @@ -3,215 +3,94 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-23 10:37+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"POT-Creation-Date: 2017-08-25 15:16\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" +"Content-Transfer-Encoding: 8bit\n" -#: example/index.html:9 example/index.html:11 -msgid "Angular way7" -msgstr "" - -#. Hallo Kommentar aus HTML1 -#. Hallo Kommentar aus HTML -#: example/index.html:11 -msgid "Angular way8" -msgstr "" - -#: bin/mkl10n.dart:460 bin/mkl10n.dart:467 bin/mkl10n.dart:468 +#: ./bin/argparser/Config.dart:96 msgid "Config-File" msgstr "" -#: bin/mkl10nlocale.dart:273 bin/mkl10nlocale.dart:277 -#: bin/mkl10nlocale.dart:274 bin/mkl10nlocale.dart:279 -#: bin/mkl10nlocale.dart:281 bin/mkl10n.dart:283 bin/mkl10n.dart:290 -#: bin/mkl10n.dart:291 -msgid "Defines where to place your locale-Dir" -msgstr "" - -#: bin/mkl10n.dart:474 bin/mkl10n.dart:481 bin/mkl10n.dart:482 -msgid "Dirs to exclude" -msgstr "" - -#: bin/mkl10nlocale.dart:443 bin/mkl10nlocale.dart:447 -#: bin/mkl10nlocale.dart:444 bin/mkl10nlocale.dart:450 -#: bin/mkl10nlocale.dart:452 bin/mkl10nlocale.dart:454 -#: bin/mkl10nlocale.dart:455 bin/mkl10nlocale.dart:457 bin/mkl10n.dart:472 -#: bin/mkl10n.dart:479 bin/mkl10n.dart:480 +#: ./bin/argparser/Config.dart:109 msgid "Dirs to scan" msgstr "" -#: bin/mkl10nlocale.dart:231 bin/mkl10n.dart:233 bin/mkl10n.dart:240 -#: bin/mkl10n.dart:241 -msgid "Example:" +#: ./bin/argparser/Config.dart:111 +msgid "Dirs to exclude" msgstr "" -#: bin/mkl10n.dart:285 bin/mkl10n.dart:292 bin/mkl10n.dart:293 -msgid "Exclude folders from scaning" +#: ./bin/argparser/Config.dart:132 +msgid "Settings:" msgstr "" -#. You will see this comment in the according .po/.pot-File #. You will see this comment in the .po/.pot-File -#: bin/mkl10nlocale.dart:252 bin/mkl10nlocale.dart:256 -#: bin/mkl10nlocale.dart:253 bin/mkl10nlocale.dart:258 -#: bin/mkl10nlocale.dart:260 bin/mkl10n.dart:262 bin/mkl10n.dart:269 -#: bin/mkl10n.dart:270 +#: ./bin/argparser/Config.dart:140 msgid "External commands:" msgstr "" -#: test/unit/l10n/L10NTranslation_test.dart:160 -msgid "" -"Hallo\n" -"Test" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:35 -msgid "Hallo Mike" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:43 -msgid "Hallo Mike II" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:52 -msgid "Hallo {{?}}" -msgstr "" - -#: test/unit/l10n/L10NTranslation_test.dart:63 -#: test/unit/l10n/L10NTranslation_test.dart:78 -msgid "Hallo {{l10n}}" -msgstr "" - -#: test/unit/l10n/L10NTranslation_test.dart:40 -#: test/unit/l10n/L10NTranslation_test.dart:49 -#: test/unit/l10n/L10NTranslation_test.dart:58 -msgid "Hallo {{name}}" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:65 -msgid "Hallo {{name}}, du bist jetzt {{age}} Jahre alt" -msgstr "" - -#. Im deutschen wird bei der Übersetzung ein \n eingefügt. -#. Ob der Key (msgid) ein \n enthält oder nicht ist egal -#: test/unit/l10n/L10NTranslation_test.dart:121 -msgid "" -"Hallo,\n" -" dies ist ein {{what}}" -msgstr "" - -#. default locale is en -#. - Fallback to EN -#. default locale is en -#. - Fallback to EN -#: test/unit/l10n/L10NTranslation_test.dart:109 -#: test/unit/l10n/L10NTranslation_test.dart:116 -#: test/unit/l10n/L10NTranslation_test.dart:127 -msgid "Hallo, dies ist ein {{what}}" -msgstr "" - -#. Does not exist at all - brings back default message -#: test/unit/l10n/L10NTranslation_test.dart:130 -msgid "Hallo, {{name}}" -msgstr "" - -#: test/unit/l10n/L10N_test.dart:61 -msgid "Hello {{what}}" +#: ./bin/argparser/Config.dart:142 +msgid "not installed!" msgstr "" -#: bin/mkl10nlocale.dart:272 bin/mkl10nlocale.dart:276 -#: bin/mkl10nlocale.dart:273 bin/mkl10nlocale.dart:278 -#: bin/mkl10nlocale.dart:280 bin/mkl10n.dart:282 bin/mkl10n.dart:289 -#: bin/mkl10n.dart:290 -msgid "Libprefix for generated DART-File (library .locale;)" +#: ./bin/argparser/Options.dart:24 +msgid "Usage: mkl10n [options] " msgstr "" -#: test/unit/l10n/L10NTranslation_test.dart:64 -#: test/unit/l10n/L10NTranslation_test.dart:79 -#: test/unit/l10n/L10NTranslation_test.dart:83 -msgid "Mike + {{name}}" +#: ./bin/argparser/Options.dart:30 +msgid "Example:" msgstr "" -#: bin/mkl10nlocale.dart:268 test/unit/l10n/L10NTranslation_test.dart:139 -#: bin/mkl10nlocale.dart:272 bin/mkl10nlocale.dart:269 -#: bin/mkl10nlocale.dart:274 bin/mkl10nlocale.dart:276 bin/mkl10n.dart:278 -#: bin/mkl10n.dart:285 bin/mkl10n.dart:286 -msgid "Prints settings" +#: ./bin/argparser/Options.dart:31 +msgid "mkl10n . - Generates lib/locale/messages.dart" msgstr "" -#: bin/mkl10nlocale.dart:246 bin/mkl10nlocale.dart:250 -#: bin/mkl10nlocale.dart:247 bin/mkl10nlocale.dart:252 bin/mkl10n.dart:254 -#: bin/mkl10n.dart:261 bin/mkl10n.dart:262 -msgid "Settings:" +#: ./bin/argparser/Options.dart:32 +msgid "mkl10n -l en,de . - Generates translation for en + de" msgstr "" -#: bin/mkl10nlocale.dart:267 bin/mkl10nlocale.dart:271 -#: bin/mkl10nlocale.dart:268 bin/mkl10nlocale.dart:273 -#: bin/mkl10nlocale.dart:275 bin/mkl10n.dart:277 bin/mkl10n.dart:284 -#: bin/mkl10n.dart:285 +#: ./bin/argparser/Options.dart:41 msgid "Shows this message" msgstr "" -#: test/unit/l10n/L10NTranslation_test.dart:134 -msgid "Test1" +#: ./bin/argparser/Options.dart:42 +#: ./test/unit/l10n/L10NTranslation_test.dart:139 +msgid "Prints settings" msgstr "" -#. print((l10n("This is a test").message)); -#: example/mini.dart:16 -msgid "This is a test" +#: ./bin/argparser/Options.dart:44 +msgid "locales - separated by colon, Sample: --locales en,de,es" msgstr "" -#: bin/mkl10n.dart:227 bin/mkl10n.dart:234 bin/mkl10n.dart:235 -msgid "Usage: mkl10n [options] " +#: ./bin/argparser/Options.dart:46 +msgid "Libprefix for generated DART-File (library .locale;)" msgstr "" -#: bin/mkl10nlocale.dart:223 bin/mkl10nlocale.dart:227 -#: bin/mkl10nlocale.dart:224 bin/mkl10nlocale.dart:225 -msgid "Usage: mkl10nlocale [options] " +#: ./bin/argparser/Options.dart:47 +msgid "Defines where to place your locale-Dir" msgstr "" -#: bin/mkl10nlocale.dart:274 bin/mkl10nlocale.dart:278 -#: bin/mkl10nlocale.dart:275 bin/mkl10nlocale.dart:280 -#: bin/mkl10nlocale.dart:282 bin/mkl10n.dart:284 bin/mkl10n.dart:291 -#: bin/mkl10n.dart:292 +#: ./bin/argparser/Options.dart:48 msgid "Where should the DART-File go? (/locale/messages.dart)" msgstr "" -#: bin/mkl10nlocale.dart:270 bin/mkl10nlocale.dart:274 -#: bin/mkl10nlocale.dart:271 bin/mkl10nlocale.dart:276 -#: bin/mkl10nlocale.dart:278 bin/mkl10n.dart:280 bin/mkl10n.dart:287 -#: bin/mkl10n.dart:288 -msgid "locales - separated by colon, Sample: --locales en,de,es" -msgstr "" - -#: bin/mkl10n.dart:235 bin/mkl10n.dart:242 bin/mkl10n.dart:243 -msgid "mkl10n -l en,de . - Generates translation for en + de" -msgstr "" - -#: bin/mkl10n.dart:234 bin/mkl10n.dart:241 bin/mkl10n.dart:242 -msgid "mkl10n . - Generates lib/locale/messages.dart" +#: ./bin/argparser/Options.dart:49 +msgid "Exclude folders from scaning" msgstr "" -#: bin/mkl10nlocale.dart:233 -msgid "mkl10nlocale -l en,de . - Generates translation for en + de" +#: ./test/unit/l10n/L10NTranslation_test.dart:134 +msgid "Test1" msgstr "" -#: bin/mkl10nlocale.dart:232 -msgid "mkl10nlocale . - Generates lib/locale/messages.dart" +#: ./test/unit/l10n/L10NTranslation_test.dart:160 +msgid "Hallo\nTest" msgstr "" -#: bin/mkl10nlocale.dart:254 bin/mkl10nlocale.dart:258 -#: bin/mkl10nlocale.dart:255 bin/mkl10nlocale.dart:260 -#: bin/mkl10nlocale.dart:262 bin/mkl10n.dart:264 bin/mkl10n.dart:271 -#: bin/mkl10n.dart:272 -msgid "not installed!" -msgstr "" diff --git a/locale/templates/potheader.tpl b/locale/templates/potheader.tpl new file mode 100644 index 0000000..0ff33c7 --- /dev/null +++ b/locale/templates/potheader.tpl @@ -0,0 +1,17 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: {date}\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 2f3cd16..c3ae0cd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,8 @@ dependencies: yaml: ^2.1.0 + optional: ^1.2.0 + dev_dependencies: grinder: any test: any diff --git a/samples/cmdline/lib/cmdline/Options.dart b/samples/cmdline/lib/cmdline/Options.dart index 995289c..cdf6337 100644 --- a/samples/cmdline/lib/cmdline/Options.dart +++ b/samples/cmdline/lib/cmdline/Options.dart @@ -25,14 +25,14 @@ class Options { print(" $line"); }); - // Noch ein Kommentar - print(translate(l10n("loglevel"))); - - // print(""); - // print("Sample:"); - // print(""); - // print(" 'Generates the static site in your 'web-folder': '$APPNAME -g'"); - // print(""); + print(""); + print("Sample:"); + print(""); + print(" 'Generates the static site in your 'web-folder': '$APPNAME -g'"); + print(" 'Tests the loglevel-translation': '" + + translate(l10n("loglevel")) + "'"); + + print(""); } // -- private ------------------------------------------------------------- diff --git a/samples/cmdline/lib/locale/messages.dart b/samples/cmdline/lib/locale/messages.dart index d6ebce7..da5f539 100644 --- a/samples/cmdline/lib/locale/messages.dart +++ b/samples/cmdline/lib/locale/messages.dart @@ -14,7 +14,7 @@ final L10NTranslate translate = new L10NTranslate.withTranslations( { "Config folder": "Konfigurationsordner", "Dirs to scan": "Scan-Directories", "Locale": "", - "loglevel": "" + "loglevel": "LL Translated" } }); diff --git a/samples/cmdline/locale/de/LC_MESSAGES/messages.json b/samples/cmdline/locale/de/LC_MESSAGES/messages.json index c1eb7d9..af63b2c 100644 --- a/samples/cmdline/locale/de/LC_MESSAGES/messages.json +++ b/samples/cmdline/locale/de/LC_MESSAGES/messages.json @@ -4,6 +4,6 @@ "Config folder": "Konfigurationsordner", "Dirs to scan": "Scan-Directories", "Locale": "", - "loglevel": "" + "loglevel": "LL Translated" } } \ No newline at end of file diff --git a/samples/cmdline/locale/de/LC_MESSAGES/messages.po b/samples/cmdline/locale/de/LC_MESSAGES/messages.po index 201f2cb..a10c51f 100644 --- a/samples/cmdline/locale/de/LC_MESSAGES/messages.po +++ b/samples/cmdline/locale/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: L 10N4Dart\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-24 14:05+0200\n" +"POT-Creation-Date: 2017-08-25 15:25\n" "PO-Revision-Date: 2017-08-23 12:50+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -18,11 +18,9 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Everything within l10n(...) will be in your .po File -#. Noch ein Kommentar -#: lib/cmdline/Config.dart:41 lib/cmdline/Options.dart:28 -#: lib/cmdline/Options.dart:29 +#: lib/cmdline/Config.dart:41 lib/cmdline/Options.dart:32 msgid "loglevel" -msgstr "" +msgstr "LL Translated" #. 'translate' will translate your ID/String #: lib/cmdline/Config.dart:44 diff --git a/samples/cmdline/locale/messages.json b/samples/cmdline/locale/messages.json index c1eb7d9..af63b2c 100644 --- a/samples/cmdline/locale/messages.json +++ b/samples/cmdline/locale/messages.json @@ -4,6 +4,6 @@ "Config folder": "Konfigurationsordner", "Dirs to scan": "Scan-Directories", "Locale": "", - "loglevel": "" + "loglevel": "LL Translated" } } \ No newline at end of file diff --git a/samples/cmdline/locale/templates/LC_MESSAGES/messages.gettext.pot b/samples/cmdline/locale/templates/LC_MESSAGES/messages.gettext.pot new file mode 100644 index 0000000..bf39bd3 --- /dev/null +++ b/samples/cmdline/locale/templates/LC_MESSAGES/messages.gettext.pot @@ -0,0 +1,43 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-08-25 15:25+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Everything within l10n(...) will be in your .po File +#. Noch ein Kommentar +#. Everything within l10n(...) will be in your .po File +#: lib/cmdline/Config.dart:41 lib/cmdline/Options.dart:29 +#: lib/cmdline/Options.dart:32 lib/cmdline/Options.dart:33 +msgid "loglevel" +msgstr "" + +#. 'translate' will translate your ID/String +#: lib/cmdline/Config.dart:44 +msgid "Config folder" +msgstr "" + +#: lib/cmdline/Config.dart:45 +msgid "Config file" +msgstr "" + +#: lib/cmdline/Config.dart:46 +msgid "Locale" +msgstr "" + +#: lib/cmdline/Config.dart:49 +msgid "Dirs to scan" +msgstr "" diff --git a/samples/cmdline/locale/templates/LC_MESSAGES/messages.pot b/samples/cmdline/locale/templates/LC_MESSAGES/messages.pot index 2cb0296..bd62e1f 100644 --- a/samples/cmdline/locale/templates/LC_MESSAGES/messages.pot +++ b/samples/cmdline/locale/templates/LC_MESSAGES/messages.pot @@ -3,40 +3,39 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-24 14:05+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"POT-Creation-Date: 2017-08-25 15:25\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" #. Everything within l10n(...) will be in your .po File -#. Noch ein Kommentar -#: lib/cmdline/Config.dart:41 lib/cmdline/Options.dart:28 -#: lib/cmdline/Options.dart:29 +#: ./lib/cmdline/Config.dart:41 +#: ./lib/cmdline/Options.dart:32 msgid "loglevel" msgstr "" #. 'translate' will translate your ID/String -#: lib/cmdline/Config.dart:44 +#: ./lib/cmdline/Config.dart:44 msgid "Config folder" msgstr "" -#: lib/cmdline/Config.dart:45 +#: ./lib/cmdline/Config.dart:45 msgid "Config file" msgstr "" -#: lib/cmdline/Config.dart:46 +#: ./lib/cmdline/Config.dart:46 msgid "Locale" msgstr "" -#: lib/cmdline/Config.dart:49 +#: ./lib/cmdline/Config.dart:49 msgid "Dirs to scan" msgstr "" + diff --git a/samples/cmdline/locale/templates/potheader.tpl b/samples/cmdline/locale/templates/potheader.tpl new file mode 100644 index 0000000..0ff33c7 --- /dev/null +++ b/samples/cmdline/locale/templates/potheader.tpl @@ -0,0 +1,17 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: {date}\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" \ No newline at end of file diff --git a/test/unit/_resources/login.dart.txt b/test/unit/_resources/login.dart.txt index 0c7c888..1bbea99 100644 --- a/test/unit/_resources/login.dart.txt +++ b/test/unit/_resources/login.dart.txt @@ -61,18 +61,23 @@ class LoginDialog extends MaterialDialog { print(translate(l10n("Test 1"))); - // Dart Kommentar - print(translate(l10n("Test 2"))); + // Plural-Test + print(translate(l10n("Test 2","Test 2 - Plural Name: {name}"))); /// Dart Kommentar II - print(translate(_( "Test 3" 'Test 3.1' ))); + print(translate(_( "Test 3" ))); /* Dart Kommentar III */ - print(translate(_("Test 4"))); + print(translate(_("Test \"4\""))); print(translate(_("Test (5)"))); } + // Must not appear in scan + void l10n(final String fakeFunction) { + print(fakeFunction) + } + // - private ---------------------------------------------------------------------------------- // - template ---------------------------------------------------------------------------------- @@ -98,7 +103,7 @@ class LoginDialog extends MaterialDialog { - _('Test 10:' " " '12345678aA16#') + _('Test 10: 12345678aA16#')
diff --git a/test/unit/l10n/L10NTranslation_test.dart b/test/unit/l10n/L10NTranslation_test.dart index 22bdf97..9e5b71e 100644 --- a/test/unit/l10n/L10NTranslation_test.dart +++ b/test/unit/l10n/L10NTranslation_test.dart @@ -136,7 +136,7 @@ main() { test('> Translate with locale/messages.dart', () { translate.locale = "de"; - expect(translate(l10n("Prints settings")),"Zeigt die aktuellen settings an"); + expect(translate(l10n("Prints settings")),"Zeigt die Settings an"); }); // end of 'Translate with locale/messages.dart' test test('> SubTranslation', () { diff --git a/test/unit/parser/Parser_test.dart b/test/unit/parser/Parser_test.dart index 9ce85bd..1465789 100644 --- a/test/unit/parser/Parser_test.dart +++ b/test/unit/parser/Parser_test.dart @@ -24,34 +24,24 @@ class _TestPrintVisitor extends Visitor { @override void visitL10n(final L10NStatement statement) { _logger.fine("#: ${filename}:${statement.line}"); + _logger.fine('msgid "${statement.msgid}"'); + if(statement.params.length > 1) { + _logger.fine('msgid_plural "${statement.params[1]}"'); + } + _logger.fine('msgstr ""'); _logger.fine(''); } } -void _TestPrintPOTVisitor( - final List comments, - final List statements) { - - final Logger _logger = new Logger("test.unit.parser._TestPrintPOTVisitor"); - - comments.forEach((final CommentStatement statement) { - final List lines = statement.comment.split(new RegExp(r"\n")); - lines.forEach((final String line) => _logger.fine("#. ${line.trimLeft()}")); - }); - statements.forEach((final L10NStatement statement) { - _logger.fine("#: ${statement.filename}:${statement.line}"); - }); - _logger.fine('msgid "${statements.first.msgid}"'); - _logger.fine('msgstr ""'); - _logger.fine(''); -} main() async { //final Logger _logger = new Logger("test.unit.parser"); - - configLogging(); + + // If you want to see some log outptut set "defaultLogLevel:" + // to Level.FINE or Level.FINER + configLogging(defaultLogLevel: Level.FINER); final String source = new File("test/unit/_resources/login.dart.txt").readAsStringSync(); @@ -69,7 +59,8 @@ main() async { final int nrOfFunctions = tokens.where((final Token token) => token.type == TokenType.L10N).length; - expect(nrOfComments, equals(14)); + // 14 - but one is a function declaration! + expect(nrOfComments, equals(15)); expect(nrOfFunctions, equals(12)); }); // end of 'Test' test }); @@ -84,11 +75,12 @@ main() async { final Parser parser = new Parser(); final List tokens = lexer.scan(source); - + // _logTokes(tokens); + final List statements = parser.parse(filename, tokens); expect(statements.where((final Statement statement) - => !(statement is NewLineStatement)).length, equals(26)); + => !(statement is NewLineStatement)).length, equals(27)); final Visitor visitor = new _TestPrintVisitor(filename); @@ -129,7 +121,8 @@ main() async { pot.addBlocks(blocks); pot.mergedBlocks.values.forEach((final MergedPOTBlock block) { - block.visit(_TestPrintPOTVisitor); + // Shows its output only it the loglevel is set to Level.FINE + block.visit(LogPOTVisitor); }); expect(blocks.length, 12);