/*
This is the builder script that generates the README file.
Run using `npm run builder`.
*/
// Load modules
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
// Load helper functions (these are from existing snippets in 30 seconds of code!)
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) {
console.log(`${chalk.green('NOBUILD')} README build terminated, parent commit is a Travis build!`);
process.exit(0);
}
const SNIPPETS_PATH = './snippets';
const STATIC_PARTS_PATH = './static-parts';
const snippets = {};
const EMOJIS = {
adapter: '🔌',
array: '📚',
browser: '🌐',
date: '⏱️',
function: '🎛️',
logic: '🔮',
math: '➗',
media: '📺',
node: '📦',
object: '🗃️',
string: '📜',
utility: '🔧'
};
let startPart = '',
endPart = '',
output = '',
tagDbData = {};
// Load helper functions (these are from existing snippets in 30 seconds of code!)
const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {});
const capitalize = (str, lowerRest = false) =>
str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
console.time('Builder');
// Synchronously read all snippets and sort them as necessary (case-insensitive)
try {
const snippetFilenames = fs
.readdirSync(SNIPPETS_PATH)
.sort((a, b) => a.toLowerCase() - b.toLowerCase());
// Store the data read from each snippet in the appropriate object
for (const name of snippetFilenames) {
snippets[name] = fs.readFileSync(path.join(SNIPPETS_PATH, name), 'utf8');
}
} catch (err) {
console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`);
process.exit(1);
}
// Load static parts for the README file
try {
startPart = fs.readFileSync(path.join(STATIC_PARTS_PATH, 'README-start.md'), 'utf8');
endPart = fs.readFileSync(path.join(STATIC_PARTS_PATH, 'README-end.md'), 'utf8');
} catch (err) {
console.log(`${chalk.red('ERROR!')} During static part loading: ${err}`);
process.exit(1);
}
// Load tag data from the database
try {
tagDbData = objectFromPairs(
fs
.readFileSync('tag_database', 'utf8')
.split('\n')
.slice(0, -1)
.map(v => {
let data = v.split(':').slice(0, 2);
data[1] = data[1].split(',').map(t => t.trim());
return data;
})
);
} catch (err) {
console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`);
process.exit(1);
}
// Create the output for the README file
try {
const tags = [
...new Set(
Object.entries(tagDbData)
.map(t => t[1][0])
.filter(v => v)
.sort((a, b) => a.localeCompare(b))
)
];
// Add the start static part
output += `${startPart + '\n'}`;
let uncategorizedOutput = '';
// Loop over tags and snippets to create the table of contents
for (const tag of tags) {
const capitalizedTag = capitalize(tag, true);
if (capitalizedTag === 'Uncategorized') {
uncategorizedOutput += `### _${capitalizedTag}_\n\n\nView contents
\n\n`;
for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) {
uncategorizedOutput += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()}${taggedSnippet[1].includes('advanced')?'-':''})\n`;
}
uncategorizedOutput += '\n \n\n';
} else {
output += `### ${
EMOJIS[tag] || ''
} ${capitalizedTag}\n\n\nView contents
\n\n`;
for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) {
output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()}${taggedSnippet[1].includes('advanced')?'-':''})\n`;
}
output += '\n \n\n';
}
}
output += uncategorizedOutput;
uncategorizedOutput = '';
// Loop over tags and snippets to create the list of snippets
for (const tag of tags) {
const capitalizedTag = capitalize(tag, true);
// 
if (capitalizedTag == 'Uncategorized') {
uncategorizedOutput += `---\n ## _${capitalizedTag}_\n`;
for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) {
uncategorizedOutput += `\n${snippets[taggedSnippet[0] + '.md'] +
'\n
[⬆ back to top](#table-of-contents)\n\n'}`;
}
} else {
output += `---\n ## ${EMOJIS[tag] || ''} ${capitalizedTag}\n`;
for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) {
let data = snippets[taggedSnippet[0] + '.md'];
// Add advanced tag
if(taggedSnippet[1].includes('advanced')){
data = data.split(/\r?\n/);
data[0] = data[0] +' ';
data = data.join('\n');
}
data =
data.slice(0, data.lastIndexOf('```js')) +
'\nExamples
\n\n' +
data.slice(data.lastIndexOf('```js'), data.lastIndexOf('```')) +
data.slice(data.lastIndexOf('```')) +
'\n \n';
output += `\n${data + '\n
[⬆ Back to top](#table-of-contents)\n\n'}`;
}
}
}
output += uncategorizedOutput;
// Add the ending static part
output += `\n${endPart + '\n'}`;
// Write to the README file
fs.writeFileSync('README.md', output);
} catch (err) {
console.log(`${chalk.red('ERROR!')} During README generation: ${err}`);
process.exit(1);
}
console.log(`${chalk.green('SUCCESS!')} README file generated!`);
console.timeEnd('Builder');