Merge pull request #698 from Chalarangelo/feature/glossary-scripts

[FEATURE] Glossary scripts #690
This commit is contained in:
Angelos Chalaris
2018-08-02 10:49:28 +03:00
committed by GitHub
8 changed files with 295 additions and 9 deletions

View File

@ -15,6 +15,8 @@ script:
- npm run packager
- npm run tester
- npm run extractor
- npm run glossary:keymaker
- npm run glossary:librarian
after_success:
- chmod +x .travis/push.sh
- .travis/push.sh

143
glossary/README.md Normal file
View File

@ -0,0 +1,143 @@
# 30-seconds-of-code JavaScript Glossary
## Table of Contents
* [`Array`](#array)
* [`Boolean`](#boolean)
* [`Callback`](#callback)
* [`Cross-site scripting (XSS)`](#cross-site-scripting-xss)
* [`Currying`](#currying)
* [`DNS`](#dns)
* [`DOM`](#dom)
* [`Domain name`](#domain-name)
* [`Element`](#element)
* [`Event loop`](#event-loop)
* [`Functional programming`](#functional-programming)
* [`Functor`](#functor)
* [`HTTP and HTTPS`](#http-and-https)
* [`JSON`](#json)
* [`Object-oriented programming`](#object-oriented-programming)
* [`Promise`](#promise)
* [`Recursion`](#recursion)
* [`Regular expressions`](#regular-expressions)
* [`Selector`](#selector)
* [`String`](#string)
* [`Template literals`](#template-literals)
* [`Value vs reference`](#value-vs-reference)
### Array
Arrays are used to store multiple values in a single variable.
Arrays are ordered and each item in an array has a numeric index associated with it.
JavaScript arrays are zero-indexed, meaning the first element's index is 0.
### Boolean
Booleans are one of the primitive data types in JavaScript.
They represent logical data values and can only be `true` or `false`.
### Callback
A callback function, also known as a high-order function, is a function that is passed into another function as an argument, which is then executed inside the outer function.
Callbacks can be synchronous or asynchronous.
### Cross-site scripting (XSS)
XSS refers to client-side code injection where the attacker injects malicious scripts into a legitimate website or web application.
This is often achieved when the application does not validate user input and freely injects dynamic HTML content.
### Currying
Currying is a way of constructing functions that allows partial application of a function's arguments.
Practically, this means that a function is broken down into a series of functions, each one accepting part of the arguments.
### DNS
A DNS (Domain Name System) translates domain names to the IP addresses needed to find a particular computer service on a network.
### DOM
The DOM (Document Object Model) is a cross-platform API that treats HTML and XML documents as a tree structure consisting of nodes.
These nodes (such as elements and text nodes) are objects that can be programmatically manipulated and any visible changes made to them are reflected live in the document.
In a browser, this API is available to JavaScript where DOM nodes can be manipulated to change their styles, contents, placement in the document, or interacted with through event listeners.
### Domain name
A domain name is a website's address on the Internet, used primarily in URLs to identify the server for each webpage.
A domain name consists of a hierarchical sequence of names, separated by dots and ending with an extension.
### Element
A JavaScript representation of a DOM element commonly returned by `document.querySelector()` and `document.createElement()`.
They are used when creating content with JavaScript for display in the DOM that needs to be programatically generated.
### Event loop
The event loop handles all asynchronous callbacks.
Callbacks are queued in a loop, while other code runs, and will run one by one when the response for each one has been received.
The event loop allows JavaScript to perform non-blocking I/O operations, despite the fact that JavaScript is single-threaded.
### Functional programming
Functional programming is a paradigm in which programs are built in a declarative manner using pure functions that avoid shared state and mutable data.
Functions that always return the same value for the same input and don't produce side effects are the pillar of functional programming.
### Functor
A Functor is a data type common in functional programming that implements a `map` method.
The `map` method takes a function and applies it to the data in the Functor, returning a new instance of the Functor with the result.
JavaScript `Array`s are an example of the Functor data type.
### HTTP and HTTPS
The HyperText Transfer Protocol (HTTP) is the underlying network protocol that enables transfer of hypermedia documents on the Web, usually between a client and a server.
The HyperText Transfer Protocol Secure (HTTPS) is an encrypted version of the HTTP protocol, that uses SSL to encrypt all data transfered between a client and a server.
### JSON
JSON (JavaScript Object Notation) is a format for storing and exchanging data.
It closely resembles the JavaScript object syntax, however some data types, such as dates and functions, cannot be natively represented and need to be serialized first.
### Object-oriented programming
Object-oriented programming (OOP) is a programming paradigm based on the concept of objects, which may contain both data and procedures which can be use to operate on them.
JavaScript supports Object-oriented programming both via prototypes and classes.
### Promise
The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.
A Promise can be in one of these states: pending(initial state, neither fulfilled nor rejected), fulfilled(operation completed successfully), rejected(operation failed).
### Recursion
Recursion is the repeated application of a process.
In JavaScript, recursion involves functions that call themselves repeatedly until they reach a base condition.
The base condition breaks out of the recursion loop because otherwise the function would call itself indefinitely.
Recursion is very useful when working with nested data, especially when the nesting depth is dynamically defined or unkown.
### Regular expressions
Regular expressions (known as regex or regexp) are patterns used to match character combinations in strings.
JavaScript provides a regular expression implementation through the `RegExp` object.
### Selector
A CSS selector is a pattern that is used to select and/or style one or more elements in a document, based on certain rules.
The order in which CSS selectors apply styles to elements is based on the rules of CSS specificity.
### String
Strings are one of the primitive data types in JavaScript.
They are sequences of characters and are used to represent text.
### Template literals
Template literals are strings that allow embedded expressions.
They support multi-line strings, expression interpolation and nesting.
### Value vs reference
When passing a variable by value, a copy of the variable is made, meaning that any changes made to the contents of the variable will not be reflected in the original variable.
When passing a variable by reference, the memory address of the actual variable is passed to the function or variable, meaning that modifying the variable's contents will be reflected in the original variable.
In JavaScript primitive data types are passed by value while objects are passed by reference.

24
glossary/keyword_database Normal file
View File

@ -0,0 +1,24 @@
array
boolean
callback
cross-site-scripting-xss
currying
dns
dom
domain-name
element
event-loop
functional-programming
functor
http-and-https
json
keyword_database
object-oriented-programming
promise
readme
recursion
regular-expressions
selector
string
template-literals
value-vs-reference

View File

@ -23,6 +23,8 @@
"main": "dist/_30s.js",
"module": "dist/_30s.esm.js",
"scripts": {
"glossary:librarian": "node ./scripts/glossary/library.js",
"glossary:keymaker": "node ./scripts/glossary/keyword.js",
"builder": "node ./scripts/build.js",
"linter": "node ./scripts/lint.js",
"tagger": "node ./scripts/tag.js",

View File

@ -0,0 +1,21 @@
/*
This is the "keymaker" script that generates the glossary/keyword_database file.
Run using `npm run glossary:keymaker`.
*/
const fs = require('fs-extra');
const chalk = require('chalk');
const util = require('../util');
const glossaryFiles = util.getFilesInDir('./glossary', false);
try {
const output = glossaryFiles.reduce(
(accumulator, currentFilename) =>
accumulator.toLowerCase().replace(/\.[^/.]+$/, "") + "\n" +
currentFilename.toLowerCase().replace(/\.[^/.]+$/, ""));
fs.writeFileSync('glossary/keyword_database', output);
} catch (err) {
console.log(`${chalk.red('ERROR!')} During glossary keyword_database generation: ${err}`);
process.exit(1);
}

View File

@ -0,0 +1,56 @@
/*
This is the "librarian" script that generates the glossary/README file.
Run using `npm run glossary:librarian`.
*/
const fs = require('fs-extra');
const chalk = require('chalk');
const util = require('../util');
const glossaryFiles = util.getFilesInDir('./glossary', true, ['keyword_database', 'README.md']);
const fileTitles = [];
const getGlossaryTermMarkdownBlock = (fileName) => {
let fileContent = fs.readFileSync(fileName, 'utf8');
let title = fileContent.match(/###[^\n]*/)[0].replace('### ', '').trim();
// let description = fileContent.replace(title, '').trim();
fileTitles.push(title);
return fileContent.trim() + "\n";
};
const glossaryFilesContentReducer = (accumulator, currentFilename) => {
// handle first array item
if (accumulator === glossaryFiles[0]) {
return getGlossaryTermMarkdownBlock(accumulator) + "\n" + getGlossaryTermMarkdownBlock(currentFilename);
}
return accumulator + "\n" + getGlossaryTermMarkdownBlock(currentFilename);
};
const getTermLinkMarkdownBlock = (termTitle) => {
let anchor = util.getMarkDownAnchor(termTitle);
return `* [\`${termTitle}\`](#${anchor})` + "\n";
};
const glossaryTableOfContentsReducer = (accumulator, currentFile) => {
if (accumulator === fileTitles[0]) {
return getTermLinkMarkdownBlock(accumulator) + getTermLinkMarkdownBlock(currentFile);
}
return accumulator + getTermLinkMarkdownBlock(currentFile);
};
try {
const fileContents = glossaryFiles.reduce(glossaryFilesContentReducer);
const TOC = "## Table of Contents\n\n" + fileTitles.reduce(glossaryTableOfContentsReducer);
const README =
"# 30-seconds-of-code JavaScript Glossary\n\n" +
TOC +
"\n\n" +
fileContents;
fs.writeFileSync('glossary/README.md', README);
} catch (err) {
console.log(`${chalk.red('ERROR!')} During glossary README generation: ${err}`);
process.exit(1);
}

View File

@ -2,23 +2,48 @@ const fs = require('fs-extra'),
path = require('path'),
chalk = require('chalk'),
crypto = require('crypto');
// Synchronously read all snippets and sort them as necessary (case-insensitive)
const readSnippets = snippetsPath => {
let snippets = {};
const getMarkDownAnchor = (paragraphTitle) =>
paragraphTitle.trim().toLowerCase()
.replace(/[^\w\- ]+/g, '')
.replace(/\s/g, '-')
.replace(/\-+$/, '');
const getFilesInDir = (directoryPath, withPath, exclude = null) => {
try {
let snippetFilenames = fs.readdirSync(snippetsPath);
snippetFilenames.sort((a, b) => {
let directoryFilenames = fs.readdirSync(directoryPath);
directoryFilenames.sort((a, b) => {
a = a.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
if (withPath) {
// a hacky way to do conditional array.map
return directoryFilenames.reduce((fileNames, fileName) => {
if (exclude == null || !exclude.some(toExclude => fileName === toExclude))
fileNames.push(`${directoryPath}/${fileName}`);
return fileNames;
}, []);
}
return directoryFilenames;
} catch (err) {
console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`);
process.exit(1);
}
};
// Synchronously read all snippets and sort them as necessary (case-insensitive)
const readSnippets = snippetsPath => {
const snippetFilenames = getFilesInDir(snippetsPath, false);
let snippets = {};
try {
for (let snippet of snippetFilenames)
snippets[snippet] = fs.readFileSync(path.join(snippetsPath, snippet), 'utf8');
} catch (err) {
// Handle errors (hopefully not!)
console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`);
process.exit(1);
}
@ -108,4 +133,17 @@ const getTextualContent = str => {
}
return results[1];
};
module.exports = {readSnippets, readTags, optimizeNodes, capitalize, objectFromPairs, isTravisCI, hashData, shuffle, getCodeBlocks, getTextualContent};
module.exports = {
getMarkDownAnchor,
getFilesInDir,
readSnippets,
readTags,
optimizeNodes,
capitalize,
objectFromPairs,
isTravisCI,
hashData,
shuffle,
getCodeBlocks,
getTextualContent
};

View File

@ -1,5 +1,5 @@
/*
This is the web builder script that generates the README file.
This is the web builder script that generates the web files.
Run using `npm run webber`.
*/
// Load modules