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');
 | 
						|
//     }
 |