Merge pull request #424 from atomiks/emojis

Add emojis to README categories
This commit is contained in:
Angelos Chalaris
2017-12-30 19:09:58 +02:00
committed by GitHub
2 changed files with 113 additions and 88 deletions

View File

@ -256,16 +256,16 @@
## Adapter ## Adapter
### call ### call
Given a key and a set of arguments, call them when given a context. Primarily useful in composition. Given a key and a set of arguments, call them when given a context. Primarily useful in composition.
Use a closure to call a stored key with stored arguments. Use a closure to call a stored key with stored arguments.
```js ```js
const call = (key, ...args) => context => context[key](...args); const call = (key, ...args) => context => context[key](...args);
``` ```
<details> <details>
<summary>Examples</summary> <summary>Examples</summary>
@ -277,23 +277,23 @@ const map = call.bind(null, 'map');
Promise.resolve([1, 2, 3]) Promise.resolve([1, 2, 3])
.then(map(x => 2 * x)) .then(map(x => 2 * x))
.then(console.log); //[ 2, 4, 6 ] .then(console.log); //[ 2, 4, 6 ]
``` ```
</details> </details>
<br>[⬆ Back to top](#table-of-contents) <br>[⬆ Back to top](#table-of-contents)
### collectInto ### collectInto
Changes a function that accepts an array into a variadic function. Changes a function that accepts an array into a variadic function.
Given a function, return a closure that collects all inputs into an array-accepting function. Given a function, return a closure that collects all inputs into an array-accepting function.
```js ```js
const collectInto = fn => (...args) => fn(args); const collectInto = fn => (...args) => fn(args);
``` ```
<details> <details>
<summary>Examples</summary> <summary>Examples</summary>
@ -303,23 +303,23 @@ let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2); let p2 = Promise.resolve(2);
let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3)); let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3));
Pall(p1, p2, p3).then(console.log); Pall(p1, p2, p3).then(console.log);
``` ```
</details> </details>
<br>[⬆ Back to top](#table-of-contents) <br>[⬆ Back to top](#table-of-contents)
### flip ### flip
Flip takes a function as an argument, then makes the first argument the last Flip takes a function as an argument, then makes the first argument the last
Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest. Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest.
```js ```js
const flip = fn => (...args) => fn(args.pop(), ...args); const flip = fn => (...args) => fn(args.pop(), ...args);
``` ```
<details> <details>
<summary>Examples</summary> <summary>Examples</summary>
@ -331,7 +331,7 @@ let mergePerson = mergeFrom.bind(null, a);
mergePerson(b); // == b mergePerson(b); // == b
b = {}; b = {};
Object.assign(b, a); // == b Object.assign(b, a); // == b
``` ```
</details> </details>
@ -393,16 +393,16 @@ delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s
<br>[⬆ Back to top](#table-of-contents) <br>[⬆ Back to top](#table-of-contents)
### spreadOver ### spreadOver
Takes a variadic function and returns a closure that accepts an array of arguments to map to the inputs of the function. Takes a variadic function and returns a closure that accepts an array of arguments to map to the inputs of the function.
Use closures and the spread operator (`...`) to map the array of arguments to the inputs of the function. Use closures and the spread operator (`...`) to map the array of arguments to the inputs of the function.
```js ```js
const spreadOver = fn => argsArr => fn(...argsArr); const spreadOver = fn => argsArr => fn(...argsArr);
``` ```
<details> <details>
<summary>Examples</summary> <summary>Examples</summary>
@ -410,7 +410,7 @@ const spreadOver = fn => argsArr => fn(...argsArr);
const arrayMax = spreadOver(Math.max); const arrayMax = spreadOver(Math.max);
arrayMax([1, 2, 3]); // 3 arrayMax([1, 2, 3]); // 3
arrayMax([1, 2, 4]); // 4 arrayMax([1, 2, 4]); // 4
``` ```
</details> </details>
@ -1102,8 +1102,8 @@ console.log(pulled); // [ 'b', 'd' ]
QuickSort an Array (ascending sort by default). QuickSort an Array (ascending sort by default).
Use recursion. Use recursion.
Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it. Use `Array.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it.
If the parameter `desc` is truthy, return array sorts in descending order. If the parameter `desc` is truthy, return array sorts in descending order.
```js ```js
@ -1702,7 +1702,7 @@ const httpsRedirect = () => {
Run the callback whenever the user input type changes (`mouse` or `touch`). Useful for enabling/disabling code depending on the input device. This process is dynamic and works with hybrid devices (e.g. touchscreen laptops). Run the callback whenever the user input type changes (`mouse` or `touch`). Useful for enabling/disabling code depending on the input device. This process is dynamic and works with hybrid devices (e.g. touchscreen laptops).
Use two event listeners. Assume `mouse` input initially and bind a `touchstart` event listener to the document. Use two event listeners. Assume `mouse` input initially and bind a `touchstart` event listener to the document.
On `touchstart`, add a `mousemove` event listener to listen for two consecutive `mousemove` events firing within 20ms, using `performance.now()`. On `touchstart`, add a `mousemove` event listener to listen for two consecutive `mousemove` events firing within 20ms, using `performance.now()`.
Run the callback with the input type as an argument in either of these situations. Run the callback with the input type as an argument in either of these situations.
@ -4194,4 +4194,3 @@ validateNumber('10'); // true
## Credits ## Credits
*Icons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).* *Icons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).*

View File

@ -3,51 +3,64 @@
Run using `npm run builder`. Run using `npm run builder`.
*/ */
// Load modules // Load modules
const fs = require('fs-extra'), const fs = require('fs-extra');
path = require('path'), const path = require('path');
chalk = require('chalk'); const chalk = require('chalk');
// Set variables for paths
const snippetsPath = './snippets', const SNIPPETS_PATH = './snippets';
staticPartsPath = './static-parts'; const STATIC_PARTS_PATH = './static-parts';
// Set variables for script
let snippets = {}, const snippets = {};
startPart = '', const emojis = {
adapter: '🔌',
array: '📚',
browser: '🖥️',
date: '⏱️',
function: '🎛️',
logic: '🔮',
math: '➗',
media: '📺',
node: '📦',
object: '🗃️',
string: '📜',
utility: '💎'
};
let startPart = '',
endPart = '', endPart = '',
output = '', output = '',
tagDbData = {}; tagDbData = {};
// Load helper functions (these are from existing snippets in 30 seconds of code!) // 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 objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {});
const capitalize = (str, lowerRest = false) => const capitalize = (str, lowerRest = false) =>
str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
// Start the timer of the script
console.time('Builder'); console.time('Builder');
// Synchronously read all snippets and sort them as necessary (case-insensitive) // Synchronously read all snippets and sort them as necessary (case-insensitive)
try { try {
let snippetFilenames = fs.readdirSync(snippetsPath); const snippetFilenames = fs
snippetFilenames.sort((a, b) => { .readdirSync(SNIPPETS_PATH)
a = a.toLowerCase(); .sort((a, b) => a.toLowerCase() - b.toLowerCase());
b = b.toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
// Store the data read from each snippet in the appropriate object // Store the data read from each snippet in the appropriate object
for (let snippet of snippetFilenames) for (const name of snippetFilenames) {
snippets[snippet] = fs.readFileSync(path.join(snippetsPath, snippet), 'utf8'); snippets[name] = fs.readFileSync(path.join(SNIPPETS_PATH, name), 'utf8');
}
} catch (err) { } catch (err) {
// Handle errors (hopefully not!)
console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`); console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`);
process.exit(1); process.exit(1);
} }
// Load static parts for the README file // Load static parts for the README file
try { try {
startPart = fs.readFileSync(path.join(staticPartsPath, 'README-start.md'), 'utf8'); startPart = fs.readFileSync(path.join(STATIC_PARTS_PATH, 'README-start.md'), 'utf8');
endPart = fs.readFileSync(path.join(staticPartsPath, 'README-end.md'), 'utf8'); endPart = fs.readFileSync(path.join(STATIC_PARTS_PATH, 'README-end.md'), 'utf8');
} catch (err) { } catch (err) {
// Handle errors (hopefully not!)
console.log(`${chalk.red('ERROR!')} During static part loading: ${err}`); console.log(`${chalk.red('ERROR!')} During static part loading: ${err}`);
process.exit(1); process.exit(1);
} }
// Load tag data from the database // Load tag data from the database
try { try {
tagDbData = objectFromPairs( tagDbData = objectFromPairs(
@ -58,48 +71,62 @@ try {
.map(v => v.split(':').slice(0, 2)) .map(v => v.split(':').slice(0, 2))
); );
} catch (err) { } catch (err) {
// Handle errors (hopefully not!)
console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`); console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`);
process.exit(1); process.exit(1);
} }
// Create the output for the README file // Create the output for the README file
try { try {
const tags = [
...new Set(
Object.entries(tagDbData)
.map(t => t[1])
.filter(v => v)
.sort((a, b) => a.localeCompare(b))
)
];
// Add the start static part // Add the start static part
output += `${startPart + '\n'}`; output += `${startPart + '\n'}`;
// Loop over tags and snippets to create the table of contents
let uncategorizedOutput = ''; let uncategorizedOutput = '';
for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))]
.filter(v => v) // Loop over tags and snippets to create the table of contents
.sort((a, b) => a.localeCompare(b))) { for (const tag of tags) {
if (capitalize(tag, true) == 'Uncategorized') { const capitalizedTag = capitalize(tag, true);
uncategorizedOutput += `### _${capitalize(
tag, if (capitalizedTag === 'Uncategorized') {
true uncategorizedOutput += `### _${capitalizedTag}_\n\n<details>\n<summary>View contents</summary>\n\n`;
)}_\n\n<details>\n<summary>View contents</summary>\n\n`; for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) {
for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag))
uncategorizedOutput += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`; uncategorizedOutput += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`;
}
uncategorizedOutput += '\n</details>\n\n'; uncategorizedOutput += '\n</details>\n\n';
} else { } else {
output += `### ${capitalize(tag, true)}\n\n<details>\n<summary>View contents</summary>\n\n`; output += `### ${
for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) emojis[tag] || ''
} ${capitalizedTag}\n\n<details>\n<summary>View contents</summary>\n\n`;
for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) {
output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`; output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`;
}
output += '\n</details>\n\n'; output += '\n</details>\n\n';
} }
} }
output += uncategorizedOutput; output += uncategorizedOutput;
uncategorizedOutput = ''; uncategorizedOutput = '';
// Loop over tags and snippets to create the list of snippets // Loop over tags and snippets to create the list of snippets
for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))] for (const tag of tags) {
.filter(v => v) const capitalizedTag = capitalize(tag, true);
.sort((a, b) => a.localeCompare(b))) {
if (capitalize(tag, true) == 'Uncategorized') { if (capitalizedTag == 'Uncategorized') {
uncategorizedOutput += `## _${capitalize(tag, true)}_\n`; uncategorizedOutput += `---\n ## _${capitalizedTag}_\n`;
for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) {
uncategorizedOutput += `\n${snippets[taggedSnippet[0] + '.md'] + uncategorizedOutput += `\n${snippets[taggedSnippet[0] + '.md'] +
'\n<br>[⬆ back to top](#table-of-contents)\n\n'}`; '\n<br>[⬆ back to top](#table-of-contents)\n\n'}`;
}
} else { } else {
output += `## ${capitalize(tag, true)}\n`; output += `---\n ## ${emojis[tag] || ''} ${capitalizedTag}\n`;
for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) {
let data = snippets[taggedSnippet[0] + '.md']; let data = snippets[taggedSnippet[0] + '.md'];
data = data =
data.slice(0, data.lastIndexOf('```js')) + data.slice(0, data.lastIndexOf('```js')) +
@ -111,17 +138,16 @@ try {
} }
} }
} }
output += uncategorizedOutput; output += uncategorizedOutput;
// Add the ending static part // Add the ending static part
output += `\n${endPart + '\n'}`; output += `\n${endPart + '\n'}`;
// Write to the README file // Write to the README file
fs.writeFileSync('README.md', output); fs.writeFileSync('README.md', output);
} catch (err) { } catch (err) {
// Handle errors (hopefully not!)
console.log(`${chalk.red('ERROR!')} During README generation: ${err}`); console.log(`${chalk.red('ERROR!')} During README generation: ${err}`);
process.exit(1); process.exit(1);
} }
// Log a success message
console.log(`${chalk.green('SUCCESS!')} README file generated!`); console.log(`${chalk.green('SUCCESS!')} README file generated!`);
// Log the time taken
console.timeEnd('Builder'); console.timeEnd('Builder');