/**********************************************************************
*
* This script is a locale aggregator and JSX generator, yielding
* locale-specific node modules that contain the section content
* keyed on section dir names.
*
* 1. find out which sections exist
* 2. find out how many different locales exist
* 3. for each locale:
*
* 1. for each section:
*
* 1. grab the associated locale
* 2. chunk the data for "should be preserved" vs.
* "should be processed as markdown".
* 3. join the chunks back up after converting the
* still acknowledged as markdown bits.
* 4. aggregate with a function wrapper to allow for
* JS bindings to a handler object.
*
* 2. dump the aggregated locale data as a content.js file
* 3. generate a locale-specific index.html
*
*
**********************************************************************/
var fs = require("fs-extra");
var path = require("path");
var marked = require("marked");
var chunk = require("./lib/chunk");
var jsxshim = require("./lib/jsx-shim");
var findLocales = require("./find-locales");
// make sure we know what our base location is
const BASEDIR = path.join(__dirname,"..");
// bundle all content in a specific locale for use by the app
const defaultLocale = "en-GB";
var locale = defaultLocale;
var lpos = process.argv.indexOf('--locale');
if (lpos !== -1) { locale = process.argv[lpos+1]; }
/**
* turn locale markdown into locale javascript data
*/
function processLocation(loc, section, number) {
var processed = { data: '', title: `Unknown title (${section})` };
try {
data = fs.readFileSync(loc).toString();
data = chunk(data);
data = data.map(block => {
// preserve is simple
if (!block.convert) {
var chunkData = block.data;
// -----------------------------------------------------------
// Inject the automation props into the components
// -----------------------------------------------------------
if (block.type === "gfx" || block.type === "div.figure") {
chunkData = chunkData
// Extend graphic elements with a knowledge of which section they are in.
.replace(/
tags inside tags.
d = d.replace(/(\r?\n)*/g,'')
.replace(/<\/code>(\r?\n)*<\/pre>/g,'
');
// And then title extraction/rewriting
d = d.replace(/]+>([^<]+)<\/h1>/,function(_,t) {
processed.title = t;
return ` `;
});
return d;
}).join('');
processed.data = data;
} catch (e) {
// console.warn(e);
}
return processed;
}
/**
* Form the content.js file content as a single string for file-writing.
*/
function formContentBundle(locale, content) {
var bcode = JSON.stringify(content, false, 2);
// general replacements to make content actually usable javascript:
bcode = bcode.replace(/"]*)>/g, "function(handler) { return ")
.replace(/this\.(\w)/g, "handler.$1")
.replace(/<\/section>"(,?)/g, " ; }$1\n")
.replace(/\\"/g,'"')
.replace(/\\n/g,'\n')
.replace(/>\n<')
.replace(/\\\\/g, '\\');
// all the components we want sections to be able to make use of:
var components = [
"Graphic",
"SectionHeader",
"BSplineGraphic",
"KnotController",
"WeightController",
"SliderSet"
];
// and finally, our bundle "code":
var bundle = [
`var React = require('react');`
].concat(
components.map(v => `var ${v} = require("../../components/${v}.jsx");`)
).concat([
``,
`SectionHeader.locale="${locale}";`,
``,
`module.exports = ${bcode};`,
``
]).join('\n');
return bundle;
}
/**
* Process the locale switcher component.
*/
function processLocaleSwitcher(locale, content) {
// We also need to localize the "LocaleSwitcher"
var localeCode = locale;
var loc = `./components/localized/LocaleSwitcher/content.${localeCode}.md`;
if (!fs.existsSync(loc)) {
localeCode = defaultLocale;
loc = `./components/localized/LocaleSwitcher/content.${localeCode}.md`;
}
var key = "locale-switcher";
var processed = processLocation(loc, key);
content[key] = {
locale: localeCode,
title: key,
getContent: "" + processed.data + " "
};
}
/**
* Write a content.js bundle to the filesystem
*/
function writeContentBundle(locale, content) {
var bundle = formContentBundle(locale, content);
// write the content.js file for bundling purposes
var dir = `./locales/${locale}`;
fs.ensureDirSync(dir);
fs.writeFileSync(`${dir}/content.js`, bundle);
// Write the actual locale directory and generate a locale-specific index.html
var html = fs.readFileSync('./index.template.html').toString();
var preface = "";
if (content.preface) {
preface = content.preface.getContent.replace(/ /, "$1
");
}
html = html.replace("", "\n");
html = html.replace("{{ PREFACE }}", preface);
html = html.replace("{{ locale }}", locale);
fs.ensureDirSync(locale);
fs.writeFileSync(`./${locale}/index.html`, html);
}
/**
* Process a single locale, with `en-GB` fallback for missing files.
*/
function processLocale(locale) {
// Get the section map. This will try to load .jsx code, which will fail,
// but the above shim makes a failure simply return an empty object instead.
// This is good: we only care about the keys, not the content.
var index = require(path.join(BASEDIR, "components/sections"));
var sections = Object.keys(index);
var content = { locale };
var processSection = (key, number) => {
// Grab locale file, or defaultLocale file if the chosen locale has
// has no translated content (yet)...
var localeCode = locale;
var loc = path.join(BASEDIR, `./components/sections/${key}/content.${localeCode}.md`);
if (!fs.existsSync(loc)) {
localeCode = defaultLocale;
loc = path.join(BASEDIR, `./components/sections/${key}/content.${localeCode}.md`);
}
// Read in the content.{lang}.md file
var processed = processLocation(loc, key, number);
content[key] = {
locale: localeCode,
title: processed.title,
getContent: `` + processed.data + " "
};
};
sections.forEach(processSection);
processLocaleSwitcher(locale, content);
writeContentBundle(locale, content);
}
// run all the things!
findLocales(locales => locales.forEach(processLocale));