Skip to content

Commit

Permalink
feat: added markdown translation (rudimentary, see #1)
Browse files Browse the repository at this point in the history
  • Loading branch information
niftylettuce committed Jan 10, 2020
1 parent 4fbf2bb commit feb6a2f
Show file tree
Hide file tree
Showing 4 changed files with 1,190 additions and 1,003 deletions.
73 changes: 60 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![made with lass](https://img.shields.io/badge/made_with-lass-95CC28.svg)](https://lass.js.org)
[![license](https://img.shields.io/github/license/niftylettuce/mandarin.svg)](LICENSE)

> Automatic i18n phrase translation using Google Translate
> Automatic i18n markdown translation and i18n phrase translation using Google Translate
> _NOTE_: As of v1.0.0 we now use the official Node.js Google Translate package `@google-cloud/translate`
Expand Down Expand Up @@ -45,19 +45,40 @@ yarn add mandarin

const i18n = new I18N();

//
// OPTIONAL:
// see all commented options from this following link:
// https://googleapis.dev/nodejs/translate/5.0.1/v2_index.js.html
//
const clientConfig = {};

// you can also pass a custom `logger` option (it defaults to `console`)
const mandarin = new Mandarin({
i18n, // required
clientConfig // optional
// required
i18n,
//
// OPTIONAL:
// see all commented options from this following link:
// <https://googleapis.dev/nodejs/translate/5.0.1/v2_index.js.html>
//
clientConfig: {},
//
// OPTIONAL:
// Files to convert from `index.md` to `index-es.md`
// Or `README.md` to `README-ZH.md` for example
// <https://github.com/sindresorhus/globby>
//
markdown: {
patterns: [
'*.md',
'**/*.md',
'!*-*.md',
'!test',
'!coverage',
'!node_modules'
],
options: {
gitignore: true
}
}
});

//
// Translate Phrases
//
// with async/await
(async () => {
try {
Expand All @@ -80,6 +101,32 @@ yarn add mandarin
if (err) throw err;
console.log('done');
});

//
// Translate Markdown Files
//
// with async/await
(async () => {
try {
await mandarin.markdown();
} catch (err) {
console.log(err);
}
})();

// with promises and then/catch
mandarin
.markdown()
.then(() => {
console.log('done');
})
.catch(console.error);

// with callbacks
mandarin.markdown(err => {
if (err) throw err;
console.log('done');
});
```

2. This assumes that you have locale files already and a default locale file (e.g. `./locales/en.json` with phrases that need translated to other languages you support). Based off the defaults from [i18n][], you would automatically get your `en.json` file translated to the locales `es` (Spanish) and `zh` (Chinese).
Expand All @@ -88,9 +135,9 @@ yarn add mandarin

4. Specify the path to the JSON file and run your script that uses `mandarin`:

```sh
GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json" node app.js
```
```sh
GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json" node app.js
```


## Contributors
Expand Down
91 changes: 89 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
const path = require('path');
const fs = require('fs');
const { promisify } = require('util');

const _ = require('lodash');
const emoji = require('remark-emoji');
const globby = require('globby');
const modifyFilename = require('modify-filename');
const pMapSeries = require('p-map-series');
const pify = require('pify');
const remark = require('remark');
const remarkPresetGitHub = require('remark-preset-github');
const textr = require('remark-textr');
const { v2 } = require('@google-cloud/translate');

const writeFile = promisify(fs.writeFile);
const readFile = pify(fs.readFile);
const writeFile = pify(fs.writeFile);

class Mandarin {
constructor(config = {}) {
this.config = {
i18n: false,
logger: console,
//
// OPTIONAL:
// see all commented options from this following link:
// https://googleapis.dev/nodejs/translate/5.0.1/v2_index.js.html
//
clientConfig: {},
//
// Files to convert from `index.md` to `index-es.md`
// Or `README.md` to `README-ZH.md` for example
// https://github.com/sindresorhus/globby
//
markdown: {
patterns: [
'*.md',
'**/*.md',
'!*-*.md',
'!test',
'!coverage',
'!node_modules'
],
options: {
gitignore: true
}
},
...config
};

Expand All @@ -23,6 +53,63 @@ class Mandarin {
this.client = new v2.Translate(this.config.clientConfig);

this.translate = this.translate.bind(this);
this.markdown = this.markdown.bind(this);
this.parseMarkdownFile = this.parseMarkdownFile.bind(this);
this.getLocalizedMarkdownFileName = this.getLocalizedMarkdownFileName.bind(
this
);
}

getLocalizedMarkdownFileName(filePath, locale) {
return modifyFilename(filePath, (filename, extension) => {
const isUpperCase = filename.toUpperCase() === filename;
return `${filename}-${
isUpperCase ? locale.toUpperCase() : locale.toLowerCase()
}${extension}`;
});
}

async parseMarkdownFile(filePath) {
const markdown = await readFile(filePath);
// don't translate the main file.md file, only for other locales
const locales = this.config.i18n.config.locales.filter(
locale => locale !== this.config.i18n.config.defaultLocale
);
const files = await Promise.all(
locales.map(locale => {
return new Promise((resolve, reject) => {
remark()
.use(remarkPresetGitHub)
.use(emoji)
.use(textr, {
plugins: [phrase => this.config.i18n.api.t({ phrase, locale })]
})
.process(markdown, (err, content) => {
if (err) return reject(err);
resolve({ locale, content });
});
});
})
);
await Promise.all(
files.map(async file => {
await writeFile(
this.getLocalizedMarkdownFileName(filePath, file.locale),
file.content
);
})
);
}

async markdown() {
// if title is all uppercase then `-EN` otherwise `-en`
const filePaths = await globby(
this.config.markdown.patterns,
this.config.markdown.options
);
await Promise.all(
filePaths.map(filePath => this.parseMarkdownFile(filePath))
);
}

async translate() {
Expand Down
16 changes: 11 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mandarin",
"description": "Automatic i18n phrase translation using Google Translate",
"description": "Automatic i18n markdown translation and i18n phrase translation using Google Translate",
"version": "1.0.1",
"author": "Nick Baugh <niftylettuce@gmail.com> (http://niftylettuce.com/)",
"ava": {
Expand All @@ -20,14 +20,21 @@
"Nick Baugh <niftylettuce@gmail.com> (http://niftylettuce.com/)"
],
"dependencies": {
"@google-cloud/translate": "^5.0.2",
"@google-cloud/translate": "^5.1.4",
"globby": "^11.0.0",
"lodash": "^4.17.15",
"p-map-series": "^2.1.0"
"modify-filename": "^1.1.0",
"p-map-series": "^2.1.0",
"pify": "^4.0.1",
"remark": "^11.0.2",
"remark-emoji": "^2.0.2",
"remark-preset-github": "^0.0.16",
"remark-textr": "^3.0.4"
},
"devDependencies": {
"@commitlint/cli": "latest",
"@commitlint/config-conventional": "latest",
"@ladjs/i18n": "^1.2.1",
"@ladjs/i18n": "^3.0.1",
"ava": "latest",
"codecov": "latest",
"cross-env": "latest",
Expand All @@ -39,7 +46,6 @@
"lint-staged": "latest",
"nyc": "latest",
"remark-cli": "latest",
"remark-preset-github": "latest",
"xo": "latest"
},
"engines": {
Expand Down
Loading

0 comments on commit feb6a2f

Please sign in to comment.