Skip to content

Add en.json generator #803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
8 changes: 4 additions & 4 deletions contributor_docs/i18n_contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ p5.js-website/
],
```
4. Duplicate `en.yml` - stored under `src/data/` - and name it `language_abbreviation.yml`. For example, when the Spanish version was created it was named `es.yml`. Check [How the website works](#how-the-website-works) and [File Structure](#file-structure) for further information.
5. Duplicate `es.json` - stored under `src/data/reference/` - and name it `[language_abbreviation].json`.
5. Duplicate `en.json` - stored under `src/data/reference/` - and name it `[language_abbreviation].json`.
6. Duplicate `en` folder - stored under `src/data/examples` - and name it `language_abbreviation`.
7. Add a new menu entry in [`src/templates/partials/i18n.hbs`](https://github.com/processing/p5.js-website/blob/main/src/templates/partials/i18n.hbs#L8) like so `<li><a href='#' lang='[language_abbreviation]' data-lang='[language_abbreviation]'>[language_name]</a></li>`.

Expand Down Expand Up @@ -200,9 +200,9 @@ In some cases, the text translated from the original .hbs file (written in HTML)

* The reference works a bit differently. The pages are built in English based on the inline documentation in the p5.js source code. The English text is then swapped out with the appropriate translation using JS on the front-end.
* The inline API documentation is automatically extracted from the p5.js repository using [YUIdoc](https://yui.github.io/yuidoc/) and saved in a [JSON file](https://github.com/processing/p5.js-website/blob/main/src/templates/pages/reference/data.json).
* The translation files are created from the data.json file, but have a different structure (i.e. [es.json](https://github.com/processing/p5.js-website/blob/main/src/data/reference/es.json)).
* The top level keys in the JSON object correspond to the page headings, menu, footer, etc. You can see all the swaps in [this file](https://github.com/processing/p5.js-website/blob/main/src/templates/pages/reference/index.hbs#L60).
* The "p5" key in the JSON object contains individual keys for each reference entry, indexed by variable/function/object name.
* The translation files are created from the data.json file, but have a different structure (i.e. [en.json](https://github.com/processing/p5.js-website/blob/main/src/data/reference/en.json)).
* The first few keys in the JSON object correspond to the page headings, menu, footer, etc. You can see all the swaps in [this file](https://github.com/processing/p5.js-website/blob/main/src/templates/pages/reference/index.hbs#L60).
* The JSON object also contains a key for each p5 class (i.e. "p5.Color"), which holds information about the class itself and its methods and fields.
* Any entries in the JSON object which are not filled in will be left in English when the page is loaded.
* The translated versions of the JSON file need to be manually created and updated.
* This is a somewhat hacky solution and not ideal. However, it comes from balancing the desire to have documentation directly in the source code, with the unwieldiness of having multiple languages of documentation inline. It will be our working solution until a better one is found.
Expand Down
151 changes: 151 additions & 0 deletions getenJSON.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
This script generates the en.json file with the data from the data.json.
It's run by the Grunt task runner.
*/
function getenJSON() {
var fs = require('fs');
var data = fs.readFileSync('src/templates/pages/reference/data.json');
var dataJSON = JSON.parse(data);
var staticStrings = fs.readFileSync(
'src/templates/pages/reference/staticStrings.json'
);
var staticStringsJSON = JSON.parse(staticStrings);
var enJSON = {};

// static strings
for (var sstr in staticStringsJSON) {
enJSON[sstr] = staticStringsJSON[sstr];
}

// modules
for (var p5Module in dataJSON.modules) {
if (p5Module != 'p5.sound') {
enJSON[p5Module] = p5Module;
}
}

// classes: builds the p5 classes objects
for (var p5Class in dataJSON.classes) {
var entry = dataJSON['classes'][p5Class];
var classObj = buildClassObj(entry);
enJSON[entry.name] = classObj;
}

// classitems: adds methods and properties to their respective class object
for (var p5ItemIdx in dataJSON.classitems) {
var entry2 = dataJSON.classitems[p5ItemIdx];
// only consider the items that have a name
if (entry2.name) {
var itemObj = buildItemObj(entry2);
enJSON[entry2.class][entry2.name] = itemObj;
}
}

fs.writeFileSync(
'src/data/reference/en.json',
JSON.stringify(enJSON, null, 2),
err => {
if (err) {
console.error(err);
return;
}
}
);
}

function buildClassObj(p5Class) {
var classObj = {};

if (p5Class.description) {
classObj['description'] = getParagraphs(p5Class.description);
}

if (p5Class.return) {
classObj['returns'] = buildReturnObj(p5Class.return);
}

if (p5Class.params) {
classObj['params'] = buildParamsObj(p5Class.params);
}
return classObj;
}

function buildItemObj(p5Item) {
var itemObj = {};

if (p5Item.description) {
itemObj['description'] = getParagraphs(p5Item.description);
}
if (p5Item.return) {
itemObj['returns'] = buildReturnObj(p5Item.return);
}

if (p5Item.itemtype == 'method') {
if (p5Item.params) {
itemObj['params'] = buildParamsObj(p5Item.params);
}
if (p5Item.overloads) {
itemObj = getOverloads(p5Item, itemObj);
}
}
return itemObj;
}

function buildReturnObj(returns) {
return returns.type + ': ' + getText(returns.description);
}

function buildParamsObj(params) {
var paramsObj = {};

params.forEach(p => {
var descr = p.type;
if (p.description) {
descr += ': ';
}
if ('optional' in p && p['optional']) {
descr += ' (Optional) ';
}
descr += p.description;
paramsObj[p.name] = getText(descr);
});
return paramsObj;
}

function getOverloads(p5Item, itemObj) {
p5Item.overloads.forEach(o => {
if (o.params) {
var moreParams = buildParamsObj(o.params);
if (itemObj.params) {
for (var p in moreParams) {
if (!(p in itemObj.params)) {
itemObj['params'][p] = moreParams[p];
}
}
} else {
itemObj['params'] = moreParams;
}
}
});
return itemObj;
}

// returns the 'clean' version of the input text
function getText(str) {
return str
.trim()
.replace(/<p>|<\/p>|<br>/g, '')
.replace(/\n|\s+/g, ' ');
}

// returns an array containing the 'clean' versions of the text in the <p> tags of the input text
function getParagraphs(text) {
return text
.trim()
.replace(/<\/p>|<br>/g, '')
.replace(/\n|\s+/g, ' ')
.split(/<p>/)
.filter(x => x.length > 0);
}

module.exports = getenJSON;
Loading