diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a1dc9e66..618a99b1a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,8 +7,8 @@ Here's what you can do to help: - [Open issues](https://github.com/Chalarangelo/30-seconds-of-code/issues/new) for things you want to see added or modified. - Be part of the discussion by helping out with [existing issues](https://github.com/Chalarangelo/30-seconds-of-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-code/Lobby). - Submit [pull requests](https://github.com/Chalarangelo/30-seconds-of-code/pulls) with snippets you have created (see below for guidelines). -- Fix typos in existing snippets or run `npm run linter "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with). - Tag untagged snippets by running `npm run tagger` and adding the appropriate tag next to the script name in `tag_database`. +- Fix typos in existing snippets or run `npm run linter` to lint unlinted snippets (yes, this is something we actually want help with, as this can take quite a while to run). ### Snippet submission and Pull request guidelines diff --git a/README.md b/README.md index 190b57a2e..ead95c6f1 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ const arrayConcat = (arr, ...args) => arr.concat(...args); Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. ```js -const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); } +const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; // difference([1,2,3], [1,2]) -> [3] ``` @@ -133,7 +133,7 @@ const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. ```js -const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); } +const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; // intersection([1,2,3], [4,3,2]) -> [2,3] ``` @@ -144,7 +144,7 @@ const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.ha Create a `Set` with all values of `a` and `b` and convert to an array. ```js -const union = (a, b) => Array.from(new Set([...a, ...b])) +const union = (a, b) => Array.from(new Set([...a, ...b])); // union([1,2,3], [4,3,2]) -> [1,2,3,4] ``` @@ -216,10 +216,10 @@ Loop through the array, using `Array.shift()` to drop the first element of the a Returns the remaining elements. ```js -const dropElements = (arr,func) => { - while(arr.length > 0 && !func(arr[0])) arr.shift(); +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr.shift(); return arr; -} +}; // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] ``` @@ -231,8 +231,8 @@ Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive Omit `start` to start at the first element and/or `end` to finish at the last. ```js -const fillArray = (arr, value, start = 0, end = arr.length) => - arr.map((v,i) => i>=start && i + arr.map((v, i) => i >= start && i < end ? value : v); // fillArray([1,2,3,4],'8',1,3) -> [1,'8','8',4] ``` @@ -258,8 +258,8 @@ Omit the second element, `depth` to flatten only to a depth of `1` (single flatt ```js const flattenDepth = (arr, depth = 1) => - depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) - : arr.reduce((a,v) => a.concat(v),[]); + depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); // flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] ``` @@ -506,7 +506,7 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; -} +}; // e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} // elementIsVisibleInViewport(el) -> false (not fully visible) // elementIsVisibleInViewport(el, true) -> true (partially visible) @@ -664,7 +664,7 @@ async function sleepyWork() { If `n` is even, return `n/2`. Otherwise return `3n+1`. ```js -const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); +const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1); // collatz(8) --> 4 // collatz(5) --> 16 ``` @@ -795,7 +795,7 @@ const standardDeviation = (arr, usePopulation = false) => { arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); - } +}; // standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) // standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ``` @@ -1041,10 +1041,10 @@ If digit is found in teens pattern, use teens ordinal. ```js const toOrdinalSuffix = num => { const int = parseInt(num), digits = [(int % 10), (int % 100)], - ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], - tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; -} + ordinals = ['st', 'nd', 'rd', 'th'], oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0] - 1] : int + ordinals[3]; +}; // toOrdinalSuffix("123") -> "123rd" ``` diff --git a/scripts/lint-script.js b/scripts/lint-script.js index a53686ee5..3aba12d27 100644 --- a/scripts/lint-script.js +++ b/scripts/lint-script.js @@ -1,31 +1,44 @@ -var fs = require('fs-extra'); -var cp = require('child_process'); -var path = require('path'); - +/* + This is the linter script that lints snippets. + Run using `npm run linter`. +*/ +// Load modules +const fs = require('fs-extra'), cp = require('child_process'), path = require('path'); +// Set variables for paths var snippetsPath = './snippets'; -var snippetFilename = ''; - -console.time('Linter'); - -if(process.argv.length < 3){ - console.log('Please specify the filename of a snippet to be linted.'); - console.log('Example usage: npm run lint "snippet-file.md"'); - process.exit(0); -} -else { - snippetFilename = process.argv[2]; - let snippetData = fs.readFileSync(path.join(snippetsPath,snippetFilename),'utf8'); - try { +// Read files, lint each one individually and update +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; + }); + // Read each file, get its code, write it to a temporary file, pass it through + // semistandard, get the output from the file, update the original file. + for(let snippet of snippetFilenames){ + // Start a timer for the file + console.time(`Linter (${snippet})`); + // Synchronously read data from the snippet, get the code, write it to a temporary file + let snippetData = fs.readFileSync(path.join(snippetsPath,snippet),'utf8'); let originalCode = snippetData.slice(snippetData.indexOf('```js')+5,snippetData.lastIndexOf('```')); - fs.writeFileSync('currentSnippet.js',`${originalCode}`); - cp.exec('semistandard "currentSnippet.js" --fix',{},(error, stdOut, stdErr) => { - let lintedCode = fs.readFileSync('currentSnippet.js','utf8'); - fs.writeFile(path.join(snippetsPath,snippetFilename), `${snippetData.slice(0, snippetData.indexOf('```js')+5)+lintedCode+'```\n'}`); - console.timeEnd('Linter'); + fs.writeFileSync(`${snippet}.temp.js`,`${originalCode}`); + // Run semistandard asynchronously (only way this manages to run), get linted code + // and write back to the original snippet file. Remove temporary file + cp.exec(`semistandard "${snippet}.temp.js" --fix`,{},(error, stdOut, stdErr) => { + let lintedCode = fs.readFileSync(`${snippet}.temp.js`,'utf8'); + fs.writeFile(path.join(snippetsPath,snippet), `${snippetData.slice(0, snippetData.indexOf('```js')+5)+lintedCode+'```\n'}`); + fs.unlink(`${snippet}.temp.js`); + // Log a success message + console.log(`${chalk.red('SUCCESS!')} Linted snippet: ${snippet}`); + // Log the time taken for the file + console.timeEnd(`Linter (${snippet})`); }); } - catch (err){ - console.log('Error during snippet loading: '+err); - process.exit(1); - } +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During linting: ${err}`); + process.exit(1); } diff --git a/snippets/array-difference.md b/snippets/array-difference.md index 46469b1d6..208cb811e 100644 --- a/snippets/array-difference.md +++ b/snippets/array-difference.md @@ -3,6 +3,6 @@ Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. ```js -const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); } +const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; // difference([1,2,3], [1,2]) -> [3] ``` diff --git a/snippets/array-intersection.md b/snippets/array-intersection.md index 87c42378b..780ab1d85 100644 --- a/snippets/array-intersection.md +++ b/snippets/array-intersection.md @@ -3,6 +3,6 @@ Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. ```js -const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); } +const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; // intersection([1,2,3], [4,3,2]) -> [2,3] ``` diff --git a/snippets/array-union.md b/snippets/array-union.md index b417dcce7..6224227d1 100644 --- a/snippets/array-union.md +++ b/snippets/array-union.md @@ -3,6 +3,6 @@ Create a `Set` with all values of `a` and `b` and convert to an array. ```js -const union = (a, b) => Array.from(new Set([...a, ...b])) +const union = (a, b) => Array.from(new Set([...a, ...b])); // union([1,2,3], [4,3,2]) -> [1,2,3,4] ``` diff --git a/snippets/collatz-algorithm.md b/snippets/collatz-algorithm.md index 730bdd9e3..61614e5e0 100644 --- a/snippets/collatz-algorithm.md +++ b/snippets/collatz-algorithm.md @@ -3,7 +3,7 @@ If `n` is even, return `n/2`. Otherwise return `3n+1`. ```js -const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); +const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1); // collatz(8) --> 4 // collatz(5) --> 16 ``` diff --git a/snippets/drop-elements-in-array.md b/snippets/drop-elements-in-array.md index 0ad2ab5e9..236c5ab56 100644 --- a/snippets/drop-elements-in-array.md +++ b/snippets/drop-elements-in-array.md @@ -4,9 +4,9 @@ Loop through the array, using `Array.shift()` to drop the first element of the a Returns the remaining elements. ```js -const dropElements = (arr,func) => { - while(arr.length > 0 && !func(arr[0])) arr.shift(); +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr.shift(); return arr; -} +}; // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] ``` diff --git a/snippets/element-is-visible-in-viewport.md b/snippets/element-is-visible-in-viewport.md index 70ff83134..514aea5e6 100644 --- a/snippets/element-is-visible-in-viewport.md +++ b/snippets/element-is-visible-in-viewport.md @@ -12,7 +12,7 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; -} +}; // e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} // elementIsVisibleInViewport(el) -> false (not fully visible) // elementIsVisibleInViewport(el, true) -> true (partially visible) diff --git a/snippets/fill-array.md b/snippets/fill-array.md index a08c4362e..a5da15483 100644 --- a/snippets/fill-array.md +++ b/snippets/fill-array.md @@ -4,7 +4,7 @@ Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive Omit `start` to start at the first element and/or `end` to finish at the last. ```js -const fillArray = (arr, value, start = 0, end = arr.length) => - arr.map((v,i) => i>=start && i + arr.map((v, i) => i >= start && i < end ? value : v); // fillArray([1,2,3,4],'8',1,3) -> [1,'8','8',4] ``` diff --git a/snippets/flatten-array-up-to-depth.md b/snippets/flatten-array-up-to-depth.md index d28af98fb..b6e3805b6 100644 --- a/snippets/flatten-array-up-to-depth.md +++ b/snippets/flatten-array-up-to-depth.md @@ -7,7 +7,7 @@ Omit the second element, `depth` to flatten only to a depth of `1` (single flatt ```js const flattenDepth = (arr, depth = 1) => - depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) - : arr.reduce((a,v) => a.concat(v),[]); + depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); // flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] ``` diff --git a/snippets/ordinal-suffix-of-number.md b/snippets/ordinal-suffix-of-number.md index 4e849eff7..d3166928b 100644 --- a/snippets/ordinal-suffix-of-number.md +++ b/snippets/ordinal-suffix-of-number.md @@ -7,9 +7,9 @@ If digit is found in teens pattern, use teens ordinal. ```js const toOrdinalSuffix = num => { const int = parseInt(num), digits = [(int % 10), (int % 100)], - ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], - tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; -} + ordinals = ['st', 'nd', 'rd', 'th'], oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0] - 1] : int + ordinals[3]; +}; // toOrdinalSuffix("123") -> "123rd" ``` diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index e559972bb..5819579ad 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -11,7 +11,7 @@ const standardDeviation = (arr, usePopulation = false) => { arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); - } +}; // standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) // standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ```