{"id":17965358,"url":"https://github.com/t2ym/gulp-i18n-preprocess","last_synced_at":"2026-05-11T03:03:28.905Z","repository":{"id":57257832,"uuid":"50918792","full_name":"t2ym/gulp-i18n-preprocess","owner":"t2ym","description":"Preprocess Polymer templates and extract UI strings to JSON for build-time I18N with i18n-behavior","archived":false,"fork":false,"pushed_at":"2017-07-03T06:20:08.000Z","size":114,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-10T03:10:16.140Z","etag":null,"topics":["html-template","i18n","polymer","preprocess"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/t2ym.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-02T12:23:03.000Z","updated_at":"2016-11-15T00:12:10.000Z","dependencies_parsed_at":"2022-08-25T21:22:45.452Z","dependency_job_id":null,"html_url":"https://github.com/t2ym/gulp-i18n-preprocess","commit_stats":null,"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fgulp-i18n-preprocess","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fgulp-i18n-preprocess/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fgulp-i18n-preprocess/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fgulp-i18n-preprocess/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/t2ym","download_url":"https://codeload.github.com/t2ym/gulp-i18n-preprocess/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247070927,"owners_count":20878586,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html-template","i18n","polymer","preprocess"],"created_at":"2024-10-29T12:41:54.348Z","updated_at":"2026-05-11T03:03:28.840Z","avatar_url":"https://github.com/t2ym.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/t2ym/gulp-i18n-preprocess.svg?branch=master)](https://travis-ci.org/t2ym/gulp-i18n-preprocess)\n[![Coverage Status](https://coveralls.io/repos/github/t2ym/gulp-i18n-preprocess/badge.svg?branch=master\u0026build=50)](https://coveralls.io/github/t2ym/gulp-i18n-preprocess?branch=master)\n[![npm](https://img.shields.io/npm/v/gulp-i18n-preprocess.svg)](https://www.npmjs.com/package/gulp-i18n-preprocess)\n\n# gulp-i18n-preprocess\n\nPreprocess Polymer templates and extract UI strings to JSON for build-time I18N with [i18n-behavior](https://github.com/t2ym/i18n-behavior)\n\n![Build-Time I18N](https://raw.githubusercontent.com/wiki/t2ym/gulp-i18n-preprocess/BuildTimeI18nFlow.gif)\n\n## Features\n\n- Preprocess Polymer templates to replace hard-coded UI strings with {{annotated}} variables\n- Extract hard-coded UI strings to JSON \n- Embed the JSON to the target preprocessed templates as default strings\n- Export the JSON as files\n- Scan custom element HTMLs for constructing repository for I18N target attributes\n- Build-time functionalities in [gulp-i18n-preprocess](https://github.com/t2ym/gulp-i18n-preprocess) are in sync with those in [i18n-behavior](https://github.com/t2ym/i18n-behavior) at run-time\n\n## Install\n\n```\n    npm install --save-dev gulp-i18n-preprocess\n```\n\n[Quick Tour](#quick-tour) with [polymer-starter-kit-i18n](https://github.com/t2ym/polymer-starter-kit-i18n)\n\n## Workflow\n\nBuild tasks from source to dist:\n\n### 1. Scan task\n\n  - Scan source HTMLs for custom elements\n  - Construct localizable attributes repository\n\n### 2. Preprocess task\n\n  - Preprocess source HTMLs\n  - Extract UI texts to JSON as default\n  - Replace them with {{annotations}}\n  - Embed default texts in HTMLs as JSON\n  - Externalize default texts to JSON files\n  - Put them in dist\n\n### 3. (Optional) Import XLIFF task with [xliff-conv](https://github.com/t2ym/xliff-conv)\n\n### 4. Leverage task with [gulp-i18n-leverage](https://github.com/t2ym/gulp-i18n-leverage) \n\n  - Update localized JSON files by merging differences in default JSON from the previous build\n  - Put them in dist\n  - Merge all the UI texts into bundles object\n\n### 5. Bundles task with `fs.writeFileSync()`\n\n  - Generate default bundled JSON file `bundle.json` from the bundles object\n  - Generate per-locale bundled JSON files `bundle.*.json` from the bundles object\n  - Put them in dist\n\n### 6. (Optional) Export XLIFF task with [xliff-conv](https://github.com/t2ym/xliff-conv)\n\n### 7. Feedback task\n\n  - Update default and localized JSON files in source to commit them later by a developer or a build system\n\n## Usage\n\n### Default options\n\nSample to show default options:\n\n```javascript\n    var gulp = require('gulp');\n    var i18nPreprocess = require('gulp-i18n-preprocess');\n\n    gulp.task('preprocess', function () {\n      // default options values\n      var options = {\n        replacingText: false, // does not replace strings with {{annotations}}\n        jsonSpace: 2, // JSON stringification parameter for formatting\n        srcPath: 'app', // base source path\n        force: false, // does not force preprocessing when i18n-behavior.html is not imported\n        dropHtml: false, // does not drop the preprocessed HTML for output\n        dropJson: false, // does not drop the extracted JSON files for output\n        constructAttributesRepository: false, // does not construct localizable attributes repository\n        attributesRepositoryPath: null // does not specify the path to i18n-attr-repo.html\n      };\n\n      return gulp.src([ 'app/elements/**/*.html' ])\n        .pipe(i18nPreprocess(options))\n        .pipe(gulp.dest('dist/elements'));\n    });\n```\n\n### Scan task\n\n#### Note: Target HTMLs must import [i18n-behavior.html](https://github.com/t2ym/i18n-behavior) directly.\n\n#### Input: \n  - Custom element HTMLs in source\n\n#### Output: \n  - attributesRepository object in gulpfile.js\n\n```javascript\n    var gulp = require('gulp');\n    var i18nPreprocess = require('gulp-i18n-preprocess');\n\n    // Global object to store localizable attributes repository\n    var attributesRepository = {};\n\n    // Scan HTMLs and construct localizable attributes repository\n    gulp.task('scan', function () {\n      return gulp.src([ 'app/elements/**/*.html' ]) // input custom element HTMLs\n        .pipe(i18nPreprocess({\n          constructAttributesRepository: true, // construct attributes repository\n          attributesRepository: attributesRepository, // output object\n          srcPath: 'app', // path to source root\n          attributesRepositoryPath: \n            'bower_components/i18n-behavior/i18n-attr-repo.html', // path to i18n-attr-repo.html\n          dropHtml: true // drop HTMLs\n        })) \n        .pipe(gulp.dest('dist/elements')); // no outputs; dummy output path\n    });\n```\n\n### Preprocess task\n\n#### Note: Target custom element HTMLs must import [i18n-behavior.html](https://github.com/t2ym/i18n-behavior) directly.\n\n#### Input: \n  - Custom element HTMLs\n  - Non-custom-element HTMLs in source\n\n#### Output: \n  - Preprocessed HTMLs and default JSON files in dist\n\n```javascript\n    var gulp = require('gulp');\n    var merge = require('merge-stream');\n    var i18nPreprocess = require('gulp-i18n-preprocess');\n\n    // Global object to store localizable attributes repository\n    var attributesRepository; // constructed attributes repository\n\n    // Other standard pipes such as crisper / minification / uglification are omitted for explanation\n    gulp.task('preprocess', function () {\n      var elements = gulp.src([ 'app/elements/**/*.html' ]) // input custom element HTMLs\n        .pipe(i18nPreprocess({\n          replacingText: true, // replace UI texts with {{annotations}}\n          jsonSpace: 2, // JSON format with 2 spaces\n          srcPath: 'app', // path to source root\n          attributesRepository: attributesRepository // input attributes repository\n        }))\n        .pipe(gulp.dest('dist/elements')); // output preprocessed HTMLs and default JSON files to dist\n\n      var html = gulp.src([ 'app/**/*.html', '!app/{elements,test}/**/*.html' ]) // non-custom-element HTMLs\n        .pipe(i18nPreprocess({\n          replacingText: true, // replace UI texts with {{annotations}}\n          jsonSpace: 2, // JSON format with 2 spaces\n          srcPath: 'app', // path to source root\n          force: true, // force processing even without direct i18n-behavior.html import\n          attributesRepository: attributesRepository // input attributes repository\n         }))\n        .pipe(gulp.dest('dist'));\n\n      return merge(elements, html);\n    });\n```\n\n### Leverage task with [gulp-i18n-leverage](https://github.com/t2ym/gulp-i18n-leverage)\n\n#### Input:\n  - Current localized JSON files in source\n  - Current default JSON files in source\n  - Next default JSON files in dist\n\n#### Output:\n  - Next localized JSON files in dist\n  - Bundles object in gulpfile.js\n\n```javascript\n    var gulp = require('gulp');\n    var i18nLeverage = require('gulp-i18n-leverage');\n\n    var bundles = {};\n\n    gulp.task('leverage', function () {\n      return gulp.src([ 'app/**/locales/*.json' ]) // input localized JSON files in source\n        .pipe(i18nLeverage({\n          jsonSpace: 2, // JSON format with 2 spaces\n          srcPath: 'app', // path to source root\n          distPath: 'dist', // path to dist root to fetch next default JSON files\n          bundles: bundles // output bundles object\n        }))\n        .pipe(gulp.dest('dist')); // path to output next localized JSON files\n    });\n```\n\n### Bundles task\n\n#### Input: \n  - Bundles object in gulpfile.js\n\n#### Output: \n  - Bundles JSON files in dist\n\n```javascript\n    var gulp = require('gulp');\n    var fs = require('fs');\n    var JSONstringify = require('json-stringify-safe');\n\n    var bundles; // constructed bundles\n\n    gulp.task('bundles', function (callback) {\n      var DEST_DIR = 'dist';\n      var localesPath = DEST_DIR + '/locales';\n\n      try {\n        fs.mkdirSync(localesPath);\n      }\n      catch (e) {}\n      for (var lang in bundles) {\n        bundles[lang].bundle = true;\n        if (lang) {\n          fs.writeFileSync(localesPath + '/bundle.' + lang + '.json', \n                            JSONstringify(bundles[lang], null, 2));\n        }\n        else {\n          fs.writeFileSync(DEST_DIR + '/bundle.json', \n                            JSONstringify(bundles[lang], null, 2));\n        }\n      }\n      callback();\n    });\n```\n\n### Feedback task\n\n#### Note: Target custom element HTMLs must import [i18n-behavior.html](https://github.com/t2ym/i18n-behavior) directly.\n\n#### Input:\n  - Next localized JSON files in dist\n  - Custom element HTMLs\n  - Non-custom-element HTMLs\n\n#### Output:\n  - Overwritten localized JSON files in source\n  - Overwritten default JSON files in source\n\nOutputs are ready to commit in the repository\n\n```javascript\n    var gulp = require('gulp');\n    var merge = require('merge-stream');\n    var i18nPreprocess = require('gulp-i18n-preprocess');\n\n    // Only applicable to development builds; Skip it in production builds\n    gulp.task('feedback', function () {\n      // Copy from dist\n      var locales = gulp.src([ 'dist/**/locales/*.json', '!dist/locales/bundle.*.json'])\n        .pipe(gulp.dest('app'));\n\n      // Regenerate default JSON files\n      var elementDefault = gulp.src([ 'app/elements/**/*.html' ])\n        .pipe(i18nPreprocess({\n          replacingText: false,\n          jsonSpace: 2,\n          srcPath: 'app',\n          dropHtml: true,\n          attributesRepository: attributesRepository\n        }))\n        .pipe(gulp.dest('app/elements'));\n\n      // Regenerate default JSON files for non-custom-element HTMLs, i.e., i18n-dom-bind\n      var appDefault = gulp.src([ 'app/**/*.html', '!app/{elements,test}/**/*.html' ])\n        .pipe(i18nPreprocess({\n          replacingText: false,\n          jsonSpace: 2,\n          srcPath: 'app',\n          force: true,\n          dropHtml: true,\n          attributesRepository: attributesRepository\n        }))\n        .pipe(gulp.dest('app'));\n\n      return merge(locales, elementDefault, appDefault);\n    });\n```\n\n### Integrate with Polymer CLI project templates by `polymer-build` library (highly experimental)\n\n#### Notes:\n  - As of [`polymer-build 0.4.0`](https://github.com/Polymer/polymer-build), `polymer-build` library is pre-release and subject to change.\n  - As of [`Polymer CLI 0.13.0`](https://github.com/Polymer/polymer-cli), the private API `userTransformers` is deprecated and no longer available.\n\n#### Set up `package.json` and the dependent packages of the following `gulpfile.js`\n\n```sh\n    npm init # if package.json is missing\n    npm install --save-dev gulp gulp-debug gulp-grep-contents \\\n      gulp-i18n-add-locales gulp-i18n-leverage gulp-i18n-preprocess \\\n      gulp-if gulp-ignore gulp-match gulp-merge gulp-size gulp-sort gulp-util \\\n      json-stringify-safe strip-bom through2 xliff-conv polymer-build plylog merge-stream\n```\n\n#### Gulp Filters:\n  - scan - Scan HTMLs and construct localizable attributes repository\n  - basenameSort - Sort source files according to their base names; Bundle files come first.\n  - dropDefaultJSON - Drop default JSON files to avoid overwriting new ones \n  - preprocess - Preprocess Polymer templates for I18N\n  - tmpJSON - Store extracted JSON in the temporary folder .tmp\n  - importXliff - Import XLIFF into JSON\n  - leverage - Merge changes in default JSON into localized JSON\n  - exportXliff - Generate bundles and export XLIFF\n  - feedback - Update JSON and XLIFF in sources\n  - debug - Show the list of processed files including untouched ones\n  - size - Show the total size of the processed files\n\n#### Gulp Tasks:\n  - `gulp locales --targets=\"{space separated list of target locales}\"`\n  - `gulp default` - Build with `polymer-build` library for `gulp`\n\n#### [gulpfile.js](https://gist.github.com/t2ym/c37990e422d4a19774ba1d749510c1b8#file-gulpfile-js): Put it in the root folder of the project\n```javascript\n    'use strict';\n\n    var gulp = require('gulp');\n    var gutil = require('gulp-util');\n    var debug = require('gulp-debug');\n    var gulpif = require('gulp-if');\n    var gulpignore = require('gulp-ignore');\n    var gulpmatch = require('gulp-match');\n    var sort = require('gulp-sort');\n    var grepContents = require('gulp-grep-contents');\n    var size = require('gulp-size');\n    var merge = require('gulp-merge');\n    var through = require('through2');\n    var path = require('path');\n    var stripBom = require('strip-bom');\n    var JSONstringify = require('json-stringify-safe');\n    var i18nPreprocess = require('gulp-i18n-preprocess');\n    var i18nLeverage = require('gulp-i18n-leverage');\n    var XliffConv = require('xliff-conv');\n    var i18nAddLocales = require('gulp-i18n-add-locales');\n\n    const logging = require('plylog');\n    const mergeStream = require('merge-stream');\n\n    const isPolymerCLI = global._babelPolyfill;\n\n    // Global object to store localizable attributes repository\n    var attributesRepository = {};\n\n    // Bundles object\n    var prevBundles = {};\n    var bundles = {};\n\n    var title = 'I18N transform';\n    var tmpDir = '.tmp';\n\n    var xliffOptions = {};\n\n    // Scan HTMLs and construct localizable attributes repository\n    var scan = gulpif('*.html', i18nPreprocess({\n      constructAttributesRepository: true, // construct attributes repository\n      attributesRepository: attributesRepository, // output object\n      srcPath: '.', // path to source root\n      attributesRepositoryPath: \n        'bower_components/i18n-behavior/i18n-attr-repo.html', // path to i18n-attr-repo.html\n      dropHtml: false // do not drop HTMLs\n    }));\n\n    var basenameSort = sort({\n      comparator: function(file1, file2) {\n        var base1 = path.basename(file1.path).replace(/^bundle[.]/, ' bundle.');\n        var base2 = path.basename(file2.path).replace(/^bundle[.]/, ' bundle.');\n        return base1.localeCompare(base2);\n      }\n    });\n\n    var dropDefaultJSON = gulpignore([ 'src/**/*.json', '!**/locales/*.json' ]);\n\n    var preprocess = gulpif('*.html', i18nPreprocess({\n      replacingText: true, // replace UI texts with {{annotations}}\n      jsonSpace: 2, // JSON format with 2 spaces\n      srcPath: '.', // path to source root\n      attributesRepository: attributesRepository // input attributes repository\n    }));\n\n    var tmpJSON = gulpif([ 'src/**/*.json', '!src/**/locales/*' ], gulp.dest(tmpDir));\n\n    var unbundleFiles = [];\n    var importXliff = through.obj(function (file, enc, callback) {\n      // bundle files must come earlier\n      unbundleFiles.push(file);\n      callback();\n    }, function (callback) {\n      var match;\n      var file;\n      var bundleFileMap = {};\n      var xliffConv = new XliffConv(xliffOptions);\n      while (unbundleFiles.length \u003e 0) {\n        file = unbundleFiles.shift();\n        if (path.basename(file.path).match(/^bundle[.]json$/)) {\n          prevBundles[''] = JSON.parse(stripBom(String(file.contents)));\n          bundleFileMap[''] = file;\n        }\n        else if (match = path.basename(file.path).match(/^bundle[.]([^.\\/]*)[.]json$/)) {\n          prevBundles[match[1]] = JSON.parse(stripBom(String(file.contents)));\n          bundleFileMap[match[1]] = file;\n        }\n        else if (match = path.basename(file.path).match(/^bundle[.]([^.\\/]*)[.]xlf$/)) {\n          xliffConv.parseXliff(String(file.contents), { bundle: prevBundles[match[1]] }, function (output) {\n            if (bundleFileMap[match[1]]) {\n              bundleFileMap[match[1]].contents = new Buffer(JSONstringify(output, null, 2));\n            }\n          });\n        }\n        else if (gulpmatch(file, '**/locales/*.json') \u0026\u0026\n                 (match = path.basename(file.path, '.json').match(/^([^.]*)[.]([^.]*)/))) {\n          if (prevBundles[match[2]] \u0026\u0026 prevBundles[match[2]][match[1]]) {\n            file.contents = new Buffer(JSONstringify(prevBundles[match[2]][match[1]], null, 2));\n          }\n        }\n        this.push(file);\n      }\n      callback();\n    });\n\n    var leverage = gulpif([ 'src/**/locales/*.json', '!**/locales/bundle.*.json' ], i18nLeverage({\n      jsonSpace: 2, // JSON format with 2 spaces\n      srcPath: '', // path to source root\n      distPath: '/' + tmpDir, // path to dist root to fetch next default JSON files\n      bundles: bundles // output bundles object\n    }));\n\n    var bundleFiles = [];\n    var exportXliff = through.obj(function (file, enc, callback) {\n      bundleFiles.push(file);\n      callback();\n    }, function (callback) {\n      var file;\n      var cwd = bundleFiles[0].cwd;\n      var base = bundleFiles[0].base;\n      var xliffConv = new XliffConv(xliffOptions);\n      var srcLanguage = 'en';\n      var promises = [];\n      var self = this;\n      var lang;\n      while (bundleFiles.length \u003e 0) {\n        file = bundleFiles.shift();\n        if (!gulpmatch(file, [ '**/bundle.json', '**/locales/bundle.*.json', '**/xliff/bundle.*.xlf' ])) {\n          this.push(file);\n        }\n      }\n      for (lang in bundles) {\n        bundles[lang].bundle = true;\n        this.push(new gutil.File({\n          cwd: cwd,\n          base: base,\n          path: lang ? path.join(cwd, 'locales', 'bundle.' + lang + '.json')\n                     : path.join(cwd, 'bundle.json'),\n          contents: new Buffer(JSONstringify(bundles[lang], null, 2))\n        }));\n      }\n      for (lang in bundles) {\n        if (lang) {\n          (function (destLanguage) {\n            promises.push(new Promise(function (resolve, reject) {\n              xliffConv.parseJSON(bundles, {\n                srcLanguage: srcLanguage,\n                destLanguage: destLanguage\n              }, function (output) {\n                self.push(new gutil.File({\n                  cwd: cwd,\n                  base: base,\n                  path: path.join(cwd, 'xliff', 'bundle.' + destLanguage + '.xlf'),\n                  contents: new Buffer(output)\n                }));\n                resolve();\n              });\n            }));\n          })(lang);\n        }\n      }\n      Promise.all(promises).then(function (outputs) {\n        callback();\n      });\n    });\n\n    var feedback = gulpif([ '**/bundle.json', '**/locales/*.json', '**/src/**/*.json', '**/xliff/bundle.*.xlf' ], gulp.dest('.'));\n\n    var config = {\n      // list of target locales to add\n      locales: gutil.env.targets ? gutil.env.targets.split(/ /) : []\n    }\n\n    // Gulp task to add locales to I18N-ready elements and pages\n    // Usage: gulp locales --targets=\"{space separated list of target locales}\"\n    gulp.task('locales', function() {\n      var elements = gulp.src([ 'src/**/*.html' ], { base: '.' })\n        .pipe(grepContents(/i18n-behavior.html/))\n        .pipe(grepContents(/\u003cdom-module /));\n\n      var pages = gulp.src([ 'index.html' ], { base: '.' })\n        .pipe(grepContents(/is=['\"]i18n-dom-bind['\"]/));\n\n      return merge(elements, pages)\n        .pipe(i18nAddLocales(config.locales))\n        .pipe(gulp.dest('.'))\n        .pipe(debug({ title: 'Add locales:'}))\n    });\n\n    if (isPolymerCLI) {\n      module.exports = {\n        transformers: [\n          scan,\n          basenameSort,\n          dropDefaultJSON,\n          preprocess,\n          tmpJSON,\n          importXliff,\n          leverage,\n          exportXliff,\n          feedback,\n          debug({ title: title }),\n          size({ title: title })\n        ]\n      };\n    }\n    else {\n      const polymer = require('polymer-build');\n      //const optimize = require('polymer-build/lib/optimize').optimize;\n      //const precache = require('polymer-build/lib/sw-precache');\n      const PolymerProject = polymer.PolymerProject;\n      const fork = polymer.forkStream;\n      const polymerConfig = require('./polymer.json');\n\n      //logging.setVerbose();\n\n      let project = new PolymerProject({\n        root: process.cwd(),\n        entrypoint: polymerConfig.entrypoint,\n        shell: polymerConfig.shell\n      });\n\n      gulp.task('default', () =\u003e {\n        // process source files in the project\n        let sources = project.sources()\n          .pipe(project.splitHtml())\n          // I18N processes\n          .pipe(scan)\n          .pipe(basenameSort)\n          .pipe(dropDefaultJSON)\n          .pipe(preprocess)\n          .pipe(tmpJSON)\n          .pipe(importXliff)\n          .pipe(leverage)\n          .pipe(exportXliff)\n          .pipe(feedback)\n          .pipe(debug({ title: title }))\n          .pipe(size({ title: title }))\n          // add compilers or optimizers here!\n          .pipe(project.rejoinHtml());\n\n        // process dependencies\n        let dependencies = project.dependencies()\n          .pipe(project.splitHtml())\n          // add compilers or optimizers here!\n          .pipe(project.rejoinHtml());\n\n        // merge the source and dependencies streams to we can analyze the project\n        let allFiles = mergeStream(sources, dependencies)\n          .pipe(project.analyze);\n\n        // fork the stream in case downstream transformers mutate the files\n        // this fork will vulcanize the project\n        let bundled = fork(allFiles)\n          .pipe(project.bundle)\n          // write to the bundled folder\n          .pipe(gulp.dest('build/bundled'));\n\n        let unbundled = fork(allFiles)\n          // write to the unbundled folder\n          .pipe(gulp.dest('build/unbundled'));\n\n        return mergeStream(bundled, unbundled);\n      });\n    }\n```\n\n## API\n\n`i18nPreprocess(options)`\n\n### `options` object\n\n- replacingText: Boolean, default: false - If true, UI texts are replaced with {{annotations}}\n- jsonSpace: Number, default: 2 - JSON stringification parameter for formatting\n- srcPath: String, default: 'app' - Path to source root\n- force: Boolean, default: false - Force preprocessing even if `i18n-behavior.html` or `i18n-element.html` is not imported\n- dropHtml: Boolean, default: false - If true, drop the preprocessed HTML for output\n- dropJson: Boolean, default: false - If true, drop the extracted JSON files for output\n- constructAttributesRepository: Boolean, default: false - If true, construct localizable attributes repository\n- attributesRepository: Object, default: {} - Input/Output - attributes respository object\n- attributesRepositoryPath: String, default: null - Path to bower_components/i18n-behavior/i18n-attr-repo.html\n- targetVersion: Number, default: 0 - Values: 1 for Polymer 1.x, 2 for Polymer 2.x, 0 for automatic detection by `i18n-behavior.html` or `i18n-element.html` import\n\n## Quick Tour\n\n### Quick deployment of [`polymer-starter-kit-i18n`](https://github.com/t2ym/polymer-starter-kit-i18n)\n\n```\n    npm install -g polymer-cli\n    npm install -g generator-polymer-init-i18n-starter-kit\n    mkdir i18n-starter-kit\n    cd i18n-starter-kit\n    polymer init i18n-starter-kit\n    # Add Locales\n    npm run build locales -- --targets=\"de es fr ja zh-Hans\"\n    # Build\n    npm run build\n    # Translate XLIFF ./xliff/bundle.*.xlf\n    # Build and Merge Translation\n    npm run build\n    # App with Run-time I18N on http://localhost:8080\n    polymer serve\n    # App with Build-time I18N on http://localhost:8080\n    polymer serve build/bundled\n```\n\n### Change language\n\n##### 1. Press F12 to open debugger console on the browser\n\n##### 2. Navigate to the elements or DOM tab in the debugger\n\n##### 3. Change `lang` attribute of `html` element from \"en\" to other locales such as \"ja\"\n\n```html\n    \u003chtml lang=\"ja\"\u003e\n```\n\n### Update UI strings\n\n##### 1. Change any UI strings in the following HTMLs\n\n```\n    i18n-starter-kit/src/*.html\n```\n\n##### 2. Merge changes into JSON files\n\n```\n    cd i18n-starter-kit\n    npm run build\n```\n\n##### 3. Check diffs\n\n```\n    git diff\n```\n\n## License\n\n[BSD-2-Clause](https://github.com/t2ym/gulp-i18n-preprocess/blob/master/LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft2ym%2Fgulp-i18n-preprocess","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ft2ym%2Fgulp-i18n-preprocess","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft2ym%2Fgulp-i18n-preprocess/lists"}