diff --git a/README.md b/README.md index 329416bde..2940b3e8d 100644 --- a/README.md +++ b/README.md @@ -256,16 +256,16 @@ ## Adapter -### call - -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. - +### call + +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. + ```js const call = (key, ...args) => context => context[key](...args); -``` - +``` +
Examples @@ -277,23 +277,23 @@ const map = call.bind(null, 'map'); Promise.resolve([1, 2, 3]) .then(map(x => 2 * x)) .then(console.log); //[ 2, 4, 6 ] -``` +```

[⬆ Back to top](#table-of-contents) -### collectInto - -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. - +### collectInto + +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. + ```js const collectInto = fn => (...args) => fn(args); -``` - +``` +
Examples @@ -303,23 +303,23 @@ let p1 = Promise.resolve(1); let p2 = Promise.resolve(2); let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3)); Pall(p1, p2, p3).then(console.log); -``` +```

[⬆ Back to top](#table-of-contents) -### flip - -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. - +### flip + +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. + ```js const flip = fn => (...args) => fn(args.pop(), ...args); -``` - +``` +
Examples @@ -331,7 +331,7 @@ let mergePerson = mergeFrom.bind(null, a); mergePerson(b); // == b b = {}; Object.assign(b, a); // == b -``` +```
@@ -393,16 +393,16 @@ delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s
[⬆ Back to top](#table-of-contents) -### spreadOver - -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. - +### spreadOver + +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. + ```js const spreadOver = fn => argsArr => fn(...argsArr); -``` - +``` +
Examples @@ -410,7 +410,7 @@ const spreadOver = fn => argsArr => fn(...argsArr); const arrayMax = spreadOver(Math.max); arrayMax([1, 2, 3]); // 3 arrayMax([1, 2, 4]); // 4 -``` +```
@@ -1102,8 +1102,8 @@ console.log(pulled); // [ 'b', 'd' ] QuickSort an Array (ascending sort by default). -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 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. If the parameter `desc` is truthy, return array sorts in descending order. ```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). -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()`. Run the callback with the input type as an argument in either of these situations. @@ -4194,4 +4194,3 @@ validateNumber('10'); // true ## 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/).* - diff --git a/scripts/build.js b/scripts/build.js index a6e6d607d..b1e49a0a5 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -3,51 +3,64 @@ Run using `npm run builder`. */ // Load modules -const fs = require('fs-extra'), - path = require('path'), - chalk = require('chalk'); -// Set variables for paths -const snippetsPath = './snippets', - staticPartsPath = './static-parts'; -// Set variables for script -let snippets = {}, - startPart = '', +const fs = require('fs-extra'); +const path = require('path'); +const chalk = require('chalk'); + +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)); -// Start the timer of the script + console.time('Builder'); + // Synchronously read all snippets and sort them as necessary (case-insensitive) try { - let snippetFilenames = fs.readdirSync(snippetsPath); - snippetFilenames.sort((a, b) => { - a = a.toLowerCase(); - b = b.toLowerCase(); - if (a < b) return -1; - if (a > b) return 1; - return 0; - }); + 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 (let snippet of snippetFilenames) - snippets[snippet] = fs.readFileSync(path.join(snippetsPath, snippet), 'utf8'); + for (const name of snippetFilenames) { + snippets[name] = fs.readFileSync(path.join(SNIPPETS_PATH, name), 'utf8'); + } } catch (err) { - // Handle errors (hopefully not!) 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(staticPartsPath, 'README-start.md'), 'utf8'); - endPart = fs.readFileSync(path.join(staticPartsPath, 'README-end.md'), 'utf8'); + 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) { - // Handle errors (hopefully not!) console.log(`${chalk.red('ERROR!')} During static part loading: ${err}`); process.exit(1); } + // Load tag data from the database try { tagDbData = objectFromPairs( @@ -58,48 +71,62 @@ try { .map(v => v.split(':').slice(0, 2)) ); } catch (err) { - // Handle errors (hopefully not!) 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]) + .filter(v => v) + .sort((a, b) => a.localeCompare(b)) + ) + ]; + // Add the start static part output += `${startPart + '\n'}`; - // Loop over tags and snippets to create the table of contents let uncategorizedOutput = ''; - for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))] - .filter(v => v) - .sort((a, b) => a.localeCompare(b))) { - if (capitalize(tag, true) == 'Uncategorized') { - uncategorizedOutput += `### _${capitalize( - tag, - true - )}_\n\n
\nView contents\n\n`; - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + + // 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] === tag)) { uncategorizedOutput += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`; + } uncategorizedOutput += '\n
\n\n'; } else { - output += `### ${capitalize(tag, true)}\n\n
\nView contents\n\n`; - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + output += `### ${ + emojis[tag] || '' + } ${capitalizedTag}\n\n
\nView contents\n\n`; + for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`; + } output += '\n
\n\n'; } } + output += uncategorizedOutput; uncategorizedOutput = ''; + // Loop over tags and snippets to create the list of snippets - for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))] - .filter(v => v) - .sort((a, b) => a.localeCompare(b))) { - if (capitalize(tag, true) == 'Uncategorized') { - uncategorizedOutput += `## _${capitalize(tag, true)}_\n`; - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + 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] === tag)) { uncategorizedOutput += `\n${snippets[taggedSnippet[0] + '.md'] + '\n
[⬆ back to top](#table-of-contents)\n\n'}`; + } } else { - output += `## ${capitalize(tag, true)}\n`; - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { + output += `---\n ## ${emojis[tag] || ''} ${capitalizedTag}\n`; + for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { let data = snippets[taggedSnippet[0] + '.md']; data = data.slice(0, data.lastIndexOf('```js')) + @@ -111,17 +138,16 @@ try { } } } + output += uncategorizedOutput; // Add the ending static part output += `\n${endPart + '\n'}`; // Write to the README file fs.writeFileSync('README.md', output); } catch (err) { - // Handle errors (hopefully not!) console.log(`${chalk.red('ERROR!')} During README generation: ${err}`); process.exit(1); } -// Log a success message + console.log(`${chalk.green('SUCCESS!')} README file generated!`); -// Log the time taken console.timeEnd('Builder');