{"_id":"@adlk/i18next-parser","_rev":"1-4f4b182e7ce1733e53f7d4a8f4007472","name":"@adlk/i18next-parser","dist-tags":{"latest":"1.0.0-beta34"},"versions":{"1.0.0-beta34":{"author":{"name":"Karel Ledru"},"description":"Command Line tool for i18next","name":"@adlk/i18next-parser","version":"1.0.0-beta34","license":"MIT","main":"dist/index.js","public":true,"bin":{"i18next":"./bin/cli.js"},"scripts":{"test":"mocha --require babel-register --require babel-polyfill 'test/**/*.test.js'","watch":"./node_modules/babel-cli/bin/babel.js src -d dist -w","prepare":"./node_modules/babel-cli/bin/babel.js src -d dist"},"repository":{"type":"git","url":"git+https://github.com/adlk/i18next-parser.git"},"dependencies":{"acorn":"^5.5.3","broccoli-plugin":"^1.3.0","cheerio":"^1.0.0-rc.2","colors":"~1.2.0-rc0","commander":"~2.9.0","concat-stream":"~1.6.0","eol":"^0.9.1","fs-extra":"^6.0.1","gulp-sort":"^2.0.0","rsvp":"^4.8.2","through2":"~2.0.3","vinyl":"~2.0.1","vinyl-fs":"^3.0.2","yamljs":"^0.3.0"},"optionalDependencies":{},"engines":{"node":">=0.10.22"},"devDependencies":{"acorn-es7":"^0.1.0","acorn-jsx":"^4.1.1","acorn-stage3":"^0.6.0","babel-cli":"^6.26.0","babel-plugin-add-module-exports":"^0.2.1","babel-plugin-transform-object-rest-spread":"^6.26.0","babel-polyfill":"^6.26.0","babel-preset-env":"^1.6.1","babel-register":"^6.26.0","broccoli":"^1.1.4","broccoli-funnel":"^2.0.1","chai":"^4.1.2","gulp":"^4.0.0","mocha":"^5.0.0","sinon":"^6.2.0","typescript":"^3.0.3"},"keywords":["gulpplugin","i18next","parser","commandline"],"gitHead":"2d5b0eb7f649ae2babea58ad0b662b77d8f31b3e","bugs":{"url":"https://github.com/adlk/i18next-parser/issues"},"homepage":"https://github.com/adlk/i18next-parser#readme","_id":"@adlk/i18next-parser@1.0.0-beta34","_npmVersion":"6.4.1","_nodeVersion":"10.14.0","_npmUser":{"name":"adlk","email":"stefan@adlk.io"},"dist":{"integrity":"sha512-KWXp+LxS/kMJQwX0ae9cxfLOtCy24ehe374nvGBmlXXaSNbs7yxpgyJAaZBvI4iYe890PUfn+4hE04L93fhbSQ==","shasum":"b441cb4b39a1b49fd452cbb742a30cf5fae8b9fa","tarball":"https://registry.npmjs.org/@adlk/i18next-parser/-/i18next-parser-1.0.0-beta34.tgz","fileCount":22,"unpackedSize":375317,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcvyMfCRA9TVsSAnZWagAAt08P/j/NfxH6fJmFMDL/Z+f1\nYj/JWRFZ4viAom47ND7/d/fLcR/JlDyUjQ2xZVfqyqaBy1Qdc/aqPfVQA4Lz\n+a3O/vkmqTWNMbhXsVeW5R90TbOn9Hz5T1z06DWC5NDnQbWU0003ytWEnguC\nlJhpSfrkOq9K9WvIMZGf3gxe+Hd06coxlW9cNR9bb6qwwm1eD0UNbxzYcm6B\ngliFL+6gQPj9JA4PcteTyia52YNqXqQM2V16kHRqjT31NYiYFOA1UMU2C6aM\nD3xTiJ3XHj0eiVr//+8V6WXfqOUxk2bEG80RPAgJy7ou4HDb7kqtJ2CRKK57\nZBauBPyVKNMoUt+5cYJh8JH9euG04hzAZ3yYWUkTrrAafATPRKCAD8niFIaR\nEhUxry6PW4M1wgkCi0Ffhceip55O4CGXfLRk9gz6VztYQ5BWBXPIU/er67kj\n5QQ+6WAmPwe1ZdcWNuWy+nL7ETczE44Z3djeVIzYzv8ak26wwsjyiMBIcuHc\nRZSYjB1RjpQkqPiycULQzbD8uHxjVsErW8q3dVFcFy/4NsAvdD8149rkhaL5\n077fzVTkkrVNjMC2y31wlp2QwCNvyBM1C5HGmI/JR9znvCwx/GtFqXGCZNsv\nARcoM7HHsn2bMkX6eac3j6ZnULyru8pFckPbwJpzjM18P54pFtfPhNxKyMhr\nutrL\r\n=uK7k\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+HUP3SWxnKJsu4mxpvtzpdi741v4tE2oZ9uxJ6S1QFwIhANtnbJLiBxby64lHRPR5iZGdokTJkogE61u0y3rBYTyp"}]},"maintainers":[{"name":"adlk","email":"stefan@adlk.io"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/i18next-parser_1.0.0-beta34_1556030238175_0.94596970740635"},"_hasShrinkwrap":false}},"time":{"created":"2019-04-23T14:37:17.960Z","1.0.0-beta34":"2019-04-23T14:37:18.294Z","modified":"2022-04-04T11:31:26.965Z"},"maintainers":[{"name":"adlk","email":"stefan@adlk.io"}],"description":"Command Line tool for i18next","homepage":"https://github.com/adlk/i18next-parser#readme","keywords":["gulpplugin","i18next","parser","commandline"],"repository":{"type":"git","url":"git+https://github.com/adlk/i18next-parser.git"},"author":{"name":"Karel Ledru"},"bugs":{"url":"https://github.com/adlk/i18next-parser/issues"},"license":"MIT","readme":"# i18next Parser [![Build Status](https://travis-ci.org/i18next/i18next-parser.svg?branch=master)](https://travis-ci.org/i18next/i18next-parser)\n\n[![NPM](https://nodei.co/npm/i18next-parser.png?downloads=true&stars=true)](https://www.npmjs.com/package/i18next-parser)\n\nWhen translating an application, maintaining the translation catalog by hand is painful. This package parses your code and automates this process.\n\nFinally, if you want to make this process even less painful, I invite you to check [Locize](https://locize.com/). They are a sponsor of this project. Actually, if you use this package and like it, supporting me on [Patreon](https://www.patreon.com/karelledru) would mean a great deal!\n\n<p>\n  <a href=\"https://www.patreon.com/karelledru\" target=\"_blank\">\n    <img src=\"https://c5.patreon.com/external/logo/become_a_patron_button.png\" alt=\"Become a Patreon\">\n  </a>\n</p>\n\n## Features\n\n- Choose your weapon: A CLI, a standalone parser or a stream transform\n- 5 built in lexers: Javascript, JSX, HTML, Handlebars, and TypeScript+tsx\n- Creates one catalog file per locale and per namespace\n- Backs up the old keys your code doesn't use anymore in `namespace_old.json` catalog\n- Restores keys from the `_old` file if the one in the translation file is empty\n- Supports i18next features:\n  - **Context**: keys of the form `key_context`\n  - **Plural**: keys of the form `key_plural` and `key_plural_0`\n- Tested on Node 6+\n\n## DISCLAIMER: `1.0.0-beta`\n\n`1.x` is currently in beta. You can follow the pre-releases [here](https://github.com/i18next/i18next-parser/releases). It is a deep rewrite of this package that solves many issues, the main one being that it was slowly becoming unmaintainable. The [migration](docs/migration.md) contains all the breaking changes. Everything that follows is related to `1.x`. If you rely on a `0.x.x` version, you can still find the old documentation on its dedicated [branch](https://github.com/i18next/i18next-parser/tree/0.x.x).\n\n\n## Usage\n\n### CLI\n\nYou can use the CLI with the package installed locally but if you want to use it from anywhere, you better install it globally:\n\n```\nyarn global add i18next-parser@next\nnpm install -g i18next-parser@next\ni18next 'app/**/*.{js,hbs}' 'lib/**/*.{js,hbs}' [-oc]\n```\n\nMultiple globbing patterns are supported to specify complex file selections. You can learn how to write globs [here](https://github.com/isaacs/node-glob). Note that glob must be wrapped with single quotes when passed as arguments.\n\n**IMPORTANT NOTE**: If you pass the globs as CLI argument, they must be relative to where you run the command (aka relative to `process.cwd()`). If you pass the globs via the `input` option of the config file, they must be relative to the config file.\n\n- **-c, --config <path>**: Path to the config file (default: i18next-parser.config.js).\n- **-o, --output <path>**: Path to the output directory (default: locales/$LOCALE/$NAMESPACE.json).\n- **-S, --silent**: Disable logging to stdout.\n\n### Gulp\n\nSave the package to your devDependencies:\n\n```\nyarn add -D i18next-parser@next\nnpm install --save-dev i18next-parser@next\n```\n\n[Gulp](http://gulpjs.com/) defines itself as the streaming build system. Put simply, it is like Grunt, but performant and elegant.\n\n```javascript\nconst i18nextParser = require('i18next-parser').gulp;\n\ngulp.task('i18next', function() {\n  gulp.src('app/**')\n    .pipe(new i18nextParser({\n      locales: ['en', 'de'],\n      output: 'locales/$LOCALE/$NAMESPACE.json'\n    }))\n    .pipe(gulp.dest('./'));\n});\n```\n\n**IMPORTANT**: `output` is required to know where to read the catalog from. You might think that `gulp.dest()` is enough though it does not inform the transform where to read the existing catalog from.\n\n### Broccoli\n\nSave the package to your devDependencies:\n\n```\nyarn add -D i18next-parser@next\nnpm install --save-dev i18next-parser@next\n```\n\n[Broccoli.js](https://github.com/broccolijs/broccoli) defines itself as a fast, reliable asset pipeline, supporting constant-time rebuilds and compact build definitions.\n\n```javascript\n\nconst Funnel = require('broccoli-funnel')\nconst i18nextParser = require('i18next-parser').broccoli;\n\nconst appRoot = 'broccoli'\n\nlet i18n = new Funnel(appRoot, {\n  files: ['handlebars.hbs', 'javascript.js'],\n  annotation: 'i18next-parser'\n})\n\ni18n = new i18nextParser([i18n], {\n  output: 'broccoli/locales/$LOCALE/$NAMESPACE.json'\n})\n\nmodule.exports = i18n\n```\n\n## Options\n\nUsing a config file gives you fine-grained control over how i18next-parser treats your files. Here's an example config showing all config options with their defaults.\n\n```js\n// i18next-parser.config.js\n\nmodule.exports = {\n  contextSeparator: '_',\n  // Key separator used in your translation keys\n\n  createOldCatalogs: true,\n  // Save the \\_old files\n\n  defaultNamespace: 'translation',\n  // Default namespace used in your i18next config\n\n  defaultValue: '',\n  // Default value to give to empty keys\n\n  indentation: 2,\n  // Indentation of the catalog files\n\n  keepRemoved: false,\n  // Keep keys from the catalog that are no longer in code\n\n  keySeparator: '.',\n  // Key separator used in your translation keys\n  // If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.\n\n  // see below for more details\n  lexers: {\n    hbs: ['HandlebarsLexer'],\n    handlebars: ['HandlebarsLexer'],\n\n    htm: ['HTMLLexer'],\n    html: ['HTMLLexer'],\n\n    js: ['JavascriptLexer'], // if you're writing jsx inside .js files, change this to JsxLexer\n    jsx: ['JsxLexer'],\n    mjs: ['JavascriptLexer'],\n\n    ts: ['TypescriptLexer'],\n    tsx: ['TypescriptLexer'],\n\n    default: ['JavascriptLexer']\n  },\n\n  lineEnding: 'auto',\n  // Control the line ending. See options at https://github.com/ryanve/eol\n\n  locales: ['en', 'fr'],\n  // An array of the locales in your applications\n\n  namespaceSeparator: ':',\n  // Namespace separator used in your translation keys\n  // If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.\n\n  output: 'locales/$LOCALE/$NAMESPACE.json',\n  // Supports $LOCALE and $NAMESPACE injection\n  // Supports JSON (.json) and YAML (.yml) file formats\n  // Where to write the locale files relative to process.cwd()\n\n  input: undefined,\n  // An array of globs that describe where to look for source files\n  // relative to the location of the configuration file\n\n  reactNamespace: false,\n  // For react file, extract the defaultNamespace - https://react.i18next.com/components/translate-hoc.html\n  // Ignored when parsing a `.jsx` file and namespace is extracted from that file.\n\n  sort: false,\n  // Whether or not to sort the catalog\n\n  useKeysAsDefaultValue: false,\n  // Whether to use the keys as the default value; ex. \"Hello\": \"Hello\", \"World\": \"World\"\n  // The option `defaultValue` will not work if this is set to true\n\n  verbose: false\n  // Display info about the parsing including some stats\n}\n```\n\n### Lexers\n\nThe `lexers` option let you configure which Lexer to use for which extension. Here is the default:\n\nNote the presence of a `default` which will catch any extension that is not listed.\nThere are 5 lexers available: `HandlebarsLexer`, `HTMLLexer`, `JavascriptLexer`,\n`JsxLexer`, and `TypescriptLexer`. Each has configurations of its own.\nIf you need to change the defaults, you can do it like so:\n\n#### Javascript\nThe Javascript lexer uses [Acorn](https://github.com/acornjs/acorn) to walk through your code and extract references\ntranslation functions. If your code uses features not supported natively by Acorn, you can enable support through\n`injectors` and `plugins` configuration. Note that you must install these additional dependencies yourself through\n`yarn` or `npm`; they are not included in this package. This is an example configuration that adds all non-jsx plugins supported by acorn\nat the time of writing:\n```javascript\nconst injectAcornStaticClassPropertyInitializer = require('acorn-static-class-property-initializer/inject');\nconst injectAcornStage3 = require('acorn-stage3/inject');\nconst injectAcornEs7 = require('acorn-es7');\n\n// ...\n  js: [{\n    lexer: 'JavascriptLexer'\n    functions: ['t'], // Array of functions to match\n\n    // acorn config (for more information on the acorn options, see here: https://github.com/acornjs/acorn#main-parser)\n    acorn: {\n      injectors: [\n          injectAcornStaticClassPropertyInitializer,\n          injectAcornStage3,\n          injectAcornEs7,\n        ],\n      plugins: {\n        // The presence of these plugin options is important -\n        // without them, the plugins will be available but not\n        // enabled.\n        staticClassPropertyInitializer: true,\n        stage3: true,\n        es7: true,\n      }\n    }\n  }],\n// ...\n```\n\nIf you receive an error that looks like this:\n```bash\nTypeError: baseVisitor[type] is not a function\n# rest of stack trace...\n```\nThe problem is likely that you are missing a plugin that supports a feature that your code uses.\n\nThe default configuration is below:\n\n```js\n{\n  // JavascriptLexer default config (js, mjs)\n  js: [{\n    lexer: 'JavascriptLexer'\n    functions: ['t'], // Array of functions to match\n\n    // acorn config (for more information on the acorn options, see here: https://github.com/acornjs/acorn#main-parser)\n    acorn: {\n      sourceType: 'module',\n      ecmaVersion: 9, // forward compatibility\n      // Allows additional acorn plugins via the exported injector functions\n      injectors: [],\n      plugins: {},\n    }\n  }],\n}\n```\n\n#### Jsx\nThe JSX lexer builds off of the Javascript lexer, and additionally requires the `acorn-jsx` plugin. To use it, add `acorn-jsx` to your dev dependencies:\n```bash\nnpm install -D acorn-jsx\n# or\nyarn add -D acorn-jsx\n```\n\nDefault configuration:\n```js\n{\n  // JsxLexer default config (jsx)\n  // JsxLexer can take all the options of the JavascriptLexer plus the following\n  jsx: [{\n    lexer: 'JsxLexer',\n    attr: 'i18nKey', // Attribute for the keys\n\n    // acorn config (for more information on the acorn options, see here: https://github.com/acornjs/acorn#main-parser)\n    acorn: {\n      sourceType: 'module',\n      ecmaVersion: 9, // forward compatibility\n      injectors: [],\n      plugins: {},\n    }\n  }],\n}\n```\n#### Ts(x)\nThe Typescript lexer builds off of the JSX lexer, and additionally requires Typescript. To use it, add both `typescript` and `acorn-jsx` to your dev dependencies:\n```bash\nnpm install -D typescript acorn-jsx\n# or\nyarn add -D typescript acorn-jsx\n```\nIf you need additional plugins, you can install them in the same way as described in the Javascript lexer configuration.\n\nDefault configuration:\n```js\n{\n  // TypescriptLexer default config (ts/x)\n  // TypescriptLexer can take all the options of the JsxLexer in addition to\n  // optional tsOptions to pass as compilerOptions to TypeScript.\n  ts: [{\n    lexer: 'TypescriptLexer',\n    attr: 'i18nKey', // Attribute for the keys\n\n    // compiler options (https://www.typescriptlang.org/docs/handbook/compiler-options.html)\n    // note that jsx MUST be set to Preserve, or your strings will not be extracted.\n    tsOptions: {\n      jsx: 'Preserve',\n      target: 'esnext'\n    },\n  }]\n}\n```\n\n#### Handlebars\n```js\n{\n  // HandlebarsLexer default config (hbs, handlebars)\n  handlebars: [{\n    lexer: 'HandlebarsLexer',\n    functions: ['t'] // Array of functions to match\n  }]\n}\n```\n#### Html\n```js\n{\n  // HtmlLexer default config (htm, html)\n  html: [{\n    lexer: 'HtmlLexer',\n    attr: 'data-i18n' // Attribute for the keys\n    optionAttr: 'data-i18n-options' // Attribute for the options\n  }]\n}\n```\n\n## Events\n\nThe transform emits a `reading` event for each file it parses:\n\n`.pipe( i18next().on('reading', (file) => {}) )`\n\nThe transform emits a `error:json` event if the JSON.parse on json files fail:\n\n`.pipe( i18next().on('error:json', (path, error) => {}) )`\n\nThe transform emits a `warning:variable` event if the file has a key that contains a variable:\n\n`.pipe( i18next().on('warning:variable', (path, key) => {}) )`\n\n\n\n## Contribute\n\nAny contribution is welcome. Please [read the guidelines](docs/development.md) first.\n\nThanks a lot to all the previous [contributors](https://github.com/i18next/i18next-parser/graphs/contributors).\n\nIf you use this package and like it, supporting me on [Patreon](https://www.patreon.com/karelledru) is another great way to contribute!\n\n<p>\n  <a href=\"https://www.patreon.com/karelledru\" target=\"_blank\">\n    <img src=\"https://c5.patreon.com/external/logo/become_a_patron_button.png\" alt=\"Become a Patreon\">\n  </a>\n</p>\n\n--------------\n\n## Gold Sponsors\n\n<p>\n  <a href=\"https://locize.com/\" target=\"_blank\">\n    <img src=\"https://raw.githubusercontent.com/i18next/i18next/master/assets/locize_sponsor_240.gif\" width=\"240px\">\n  </a>\n</p>\n","readmeFilename":"README.md"}