206 lines
4.1 KiB
JavaScript
206 lines
4.1 KiB
JavaScript
const fs = require('fs-extra');
|
|
const path = require('path');
|
|
const YAML = require('js-yaml');
|
|
const readDirP = require('readdirp-walk');
|
|
const { parseMarkdown } = require('@freecodecamp/challenge-md-parser');
|
|
const { Translate } = require('@google-cloud/translate');
|
|
|
|
const lang = 'pt';
|
|
const langFull = 'portuguese';
|
|
|
|
const outputDir = path.resolve(__dirname, `./challenges/${langFull}`);
|
|
fs.ensureDirSync(outputDir);
|
|
|
|
readDirP({
|
|
root: path.resolve(__dirname, './challenges/english')
|
|
}).on('data', translateChallenge);
|
|
|
|
async function translateChallenge(file) {
|
|
const { name, path: filePath, fullPath, stat } = file;
|
|
if (stat.isDirectory() || name === '.DS_Store') {
|
|
return null;
|
|
}
|
|
|
|
const blockName = getBlockNameFromPath(filePath);
|
|
const { fileName: superBlock } = superBlockInfoFromPath(filePath);
|
|
const outputFile = `${outputDir}/${superBlock}/${blockName}/${name.replace(
|
|
'english',
|
|
langFull
|
|
)}`;
|
|
if (fs.existsSync(outputFile)) {
|
|
return null;
|
|
}
|
|
|
|
const challenge = await parseMarkdown(fullPath);
|
|
const { title, description, instructions, tests } = challenge;
|
|
challenge['videoUrl'] = '';
|
|
if (challenge['guideUrl']) {
|
|
challenge['guideUrl'] = challenge['guideUrl'].replace('www', langFull);
|
|
}
|
|
const translatePromises = [
|
|
translateText(title),
|
|
translateText(description),
|
|
translateText(instructions),
|
|
...tests.map(
|
|
test =>
|
|
new Promise(async (resolve, reject) => {
|
|
const { testString, text } = test;
|
|
const translatedText = await translateText(text).catch(reject);
|
|
return resolve({
|
|
text: translatedText ? translatedText.join(' ').trim() : '',
|
|
testString
|
|
});
|
|
})
|
|
)
|
|
];
|
|
return Promise.all(translatePromises).then(
|
|
([title, description, instructions, ...tests]) => {
|
|
const { files = {}, solutions = [], ...challengeMeta } = challenge;
|
|
const md = `---
|
|
${YAML.dump(
|
|
Object.assign(challengeMeta, {
|
|
localeTitle: title ? title.join(' ').trim() : ''
|
|
}),
|
|
{ lineWidth: 10000 }
|
|
)}---
|
|
|
|
## Description
|
|
${description}
|
|
|
|
## Instructions
|
|
${instructions}
|
|
|
|
## Tests
|
|
<section id='tests'>
|
|
|
|
\`\`\`yml
|
|
${YAML.dump({ tests }, { lineWidth: 10000 })}
|
|
\`\`\`
|
|
|
|
</section>
|
|
|
|
## Challenge Seed
|
|
<section id='challengeSeed'>
|
|
${generateChallengeSeed(files)}
|
|
</section>
|
|
|
|
## Solution
|
|
<section id='solution'>
|
|
|
|
${
|
|
solutions.length === 0
|
|
? `\`\`\`js
|
|
// solution required
|
|
\`\`\``
|
|
: solutions
|
|
.map(
|
|
solution => `
|
|
\`\`\`js
|
|
${solution}
|
|
\`\`\`
|
|
`
|
|
)
|
|
.join('\n')
|
|
}
|
|
</section>
|
|
`;
|
|
|
|
console.log(outputFile);
|
|
fs.ensureFileSync(outputFile);
|
|
fs.writeFile(outputFile, md);
|
|
}
|
|
);
|
|
}
|
|
|
|
function generateChallengeSeed(files) {
|
|
return Object.keys(files)
|
|
.map(key => files[key])
|
|
.map(file => {
|
|
const { ext, contents = [], head = [], tail = [] } = file;
|
|
return `
|
|
<div id='${ext}-seed'>
|
|
|
|
\`\`\`${ext}
|
|
${contents}
|
|
\`\`\`
|
|
|
|
</div>
|
|
${
|
|
head.length
|
|
? `
|
|
### Before Test
|
|
<div id='${ext}-setup'>
|
|
|
|
\`\`\`${ext}
|
|
${head}
|
|
\`\`\`
|
|
|
|
</div>`
|
|
: ''
|
|
}
|
|
${
|
|
tail.length
|
|
? `
|
|
### After Test
|
|
<div id='${ext}-teardown'>
|
|
|
|
\`\`\`js
|
|
console.info('after the test');
|
|
\`\`\`
|
|
|
|
</div>`
|
|
: ''
|
|
}
|
|
`;
|
|
});
|
|
}
|
|
|
|
const createTranslateText = target => text => {
|
|
if (!text) {
|
|
return '';
|
|
}
|
|
const translate = new Translate();
|
|
|
|
return translate
|
|
.translate(text, target)
|
|
.then(results => {
|
|
let translations = results[0];
|
|
translations = Array.isArray(translations)
|
|
? translations
|
|
: [translations];
|
|
return translations;
|
|
})
|
|
.catch(err => {
|
|
console.log(err);
|
|
});
|
|
};
|
|
|
|
const translateText = createTranslateText(lang);
|
|
|
|
function superBlockInfoFromPath(filePath) {
|
|
const [maybeSuper] = filePath.split('/');
|
|
return superBlockInfo(maybeSuper);
|
|
}
|
|
|
|
function superBlockInfo(fileName) {
|
|
const [maybeOrder, ...superBlock] = fileName.split('-');
|
|
let order = parseInt(maybeOrder, 10);
|
|
if (isNaN(order)) {
|
|
return {
|
|
order: 0,
|
|
name: fileName
|
|
};
|
|
} else {
|
|
return {
|
|
order: order,
|
|
name: superBlock.join('-'),
|
|
fileName
|
|
};
|
|
}
|
|
}
|
|
|
|
function getBlockNameFromPath(filePath) {
|
|
const [, block] = filePath.split('/');
|
|
return block;
|
|
}
|