284 lines
5.9 KiB
JavaScript
284 lines
5.9 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,
|
|
depth,
|
|
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);
|
|
return resolve({
|
|
text: translatedText ? translatedText.join(' ').trim() : '',
|
|
testString
|
|
});
|
|
}
|
|
|
|
))
|
|
];
|
|
return Promise.all(translatePromises).then(([title, description, instructions, ...tests]) => {
|
|
|
|
const {
|
|
description: oldDescription = [],
|
|
instructions: oldInstructions = [],
|
|
files = {},
|
|
tests: oldTests = [],
|
|
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;
|
|
}
|
|
|
|
|
|
// const curriculum = {
|
|
// 'responsive-web-design': {}
|
|
// }
|
|
// getChallenges().forEach(block => {
|
|
// const {
|
|
// name,
|
|
// order,
|
|
// challenges,
|
|
// time = '',
|
|
// superBlock,
|
|
// superOrder,
|
|
// template = '',
|
|
// required = [],
|
|
// ...restBlock
|
|
// } = block;
|
|
// const blockDashedName = dasherize(name);
|
|
// const blockMeta = {
|
|
// name,
|
|
// dashedName: blockDashedName,
|
|
// order,
|
|
// time,
|
|
// template,
|
|
// required,
|
|
// superBlock,
|
|
// superOrder,
|
|
// challengeOrder: challenges.map(({ id, title }) => [id, title]),
|
|
// ...restBlock
|
|
// };
|
|
// const superOrderPrefix = `0${superOrder}`;
|
|
// const outputDir = path.resolve(
|
|
// __dirname,
|
|
// `./challenges/english/${superOrderPrefix}-${superBlock}/${blockDashedName}`
|
|
// );
|
|
// fs.ensureDirSync(outputDir);
|
|
|
|
// challenges.forEach(challenge => {
|
|
// const {
|
|
// description: oldDescription = [],
|
|
// files = {},
|
|
// tests = [],
|
|
// solutions = [],
|
|
// ...restChallenge
|
|
// } = challenge;
|
|
// const challengeMeta = omit(restChallenge, blackListedFieldNames);
|
|
// const challengeFileName = `${dasherize(challenge.title)}.english.md`;
|
|
// let description = '';
|
|
// let instructions = '';
|
|
|
|
// const hrIndex = findLastIndex(oldDescription, el =>
|
|
// (/^<hr\s?\/?>$/).test(el)
|
|
// );
|
|
|
|
// if (hrIndex && hrIndex !== -1) {
|
|
// description = oldDescription.slice(0, hrIndex).join('\n');
|
|
// instructions = oldDescription.slice(hrIndex + 1).join('\n');
|
|
// } else {
|
|
// description = oldDescription.join('\n');
|
|
// }
|