Added a simple web builder
This commit is contained in:
BIN
docs/favicon.png
Normal file
BIN
docs/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
1045
docs/index.html
Normal file
1045
docs/index.html
Normal file
File diff suppressed because it is too large
Load Diff
140
docs/prism.css
Normal file
140
docs/prism.css
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* PrismJS 1.9.0
|
||||||
|
http://prismjs.com/download.html?themes=prism&languages=clike+javascript */
|
||||||
|
/**
|
||||||
|
* prism.js default theme for JavaScript, CSS and HTML
|
||||||
|
* Based on dabblet (http://dabblet.com)
|
||||||
|
* @author Lea Verou
|
||||||
|
*/
|
||||||
|
|
||||||
|
code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
color: black;
|
||||||
|
background: none;
|
||||||
|
text-shadow: 0 1px white;
|
||||||
|
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre;
|
||||||
|
word-spacing: normal;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
-moz-tab-size: 4;
|
||||||
|
-o-tab-size: 4;
|
||||||
|
tab-size: 4;
|
||||||
|
|
||||||
|
-webkit-hyphens: none;
|
||||||
|
-moz-hyphens: none;
|
||||||
|
-ms-hyphens: none;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||||
|
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||||
|
text-shadow: none;
|
||||||
|
background: #b3d4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||||
|
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||||
|
text-shadow: none;
|
||||||
|
background: #b3d4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code blocks */
|
||||||
|
pre[class*="language-"] {
|
||||||
|
padding: 1em;
|
||||||
|
margin: .5em 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(pre) > code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
background: #f5f2f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline code */
|
||||||
|
:not(pre) > code[class*="language-"] {
|
||||||
|
padding: .1em;
|
||||||
|
border-radius: .3em;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.comment,
|
||||||
|
.token.prolog,
|
||||||
|
.token.doctype,
|
||||||
|
.token.cdata {
|
||||||
|
color: slategray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.punctuation {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.namespace {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.property,
|
||||||
|
.token.tag,
|
||||||
|
.token.boolean,
|
||||||
|
.token.number,
|
||||||
|
.token.constant,
|
||||||
|
.token.symbol,
|
||||||
|
.token.deleted {
|
||||||
|
color: #905;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.selector,
|
||||||
|
.token.attr-name,
|
||||||
|
.token.string,
|
||||||
|
.token.char,
|
||||||
|
.token.builtin,
|
||||||
|
.token.inserted {
|
||||||
|
color: #690;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.operator,
|
||||||
|
.token.entity,
|
||||||
|
.token.url,
|
||||||
|
.language-css .token.string,
|
||||||
|
.style .token.string {
|
||||||
|
color: #a67f59;
|
||||||
|
background: hsla(0, 0%, 100%, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.atrule,
|
||||||
|
.token.attr-value,
|
||||||
|
.token.keyword {
|
||||||
|
color: #07a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.function {
|
||||||
|
color: #DD4A68;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.regex,
|
||||||
|
.token.important,
|
||||||
|
.token.variable {
|
||||||
|
color: #e90;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.important,
|
||||||
|
.token.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.token.italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.entity {
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
5
docs/prism.js
Normal file
5
docs/prism.js
Normal file
File diff suppressed because one or more lines are too long
48
package-lock.json
generated
48
package-lock.json
generated
@ -65,6 +65,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
|
||||||
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4="
|
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4="
|
||||||
},
|
},
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "0.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
|
||||||
|
"integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk="
|
||||||
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94="
|
||||||
|
},
|
||||||
"anymatch": {
|
"anymatch": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
|
||||||
@ -450,6 +460,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.1.tgz",
|
||||||
"integrity": "sha512-689HrwGw8Rbk1xtV9C4dY6TPJAvIYZbRbnKSAtfJ7tHqICFGoZ0PCWYjxfmerRyxBG0o3sbG3pe7N8vqPwIHuQ==",
|
"integrity": "sha512-689HrwGw8Rbk1xtV9C4dY6TPJAvIYZbRbnKSAtfJ7tHqICFGoZ0PCWYjxfmerRyxBG0o3sbG3pe7N8vqPwIHuQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"chalk": "0.5.1",
|
||||||
"commander": "2.6.0",
|
"commander": "2.6.0",
|
||||||
"date-fns": "1.29.0",
|
"date-fns": "1.29.0",
|
||||||
"lodash": "4.17.4",
|
"lodash": "4.17.4",
|
||||||
@ -457,6 +468,27 @@
|
|||||||
"spawn-command": "0.0.2-1",
|
"spawn-command": "0.0.2-1",
|
||||||
"supports-color": "3.2.3",
|
"supports-color": "3.2.3",
|
||||||
"tree-kill": "1.2.0"
|
"tree-kill": "1.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "1.1.0",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"has-ansi": "0.1.0",
|
||||||
|
"strip-ansi": "0.3.0",
|
||||||
|
"supports-color": "0.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"supports-color": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"configstore": {
|
"configstore": {
|
||||||
@ -1353,6 +1385,14 @@
|
|||||||
"function-bind": "1.1.1"
|
"function-bind": "1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"has-ansi": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
|
||||||
|
"integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "0.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"has-flag": {
|
"has-flag": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
|
||||||
@ -2854,6 +2894,14 @@
|
|||||||
"safe-buffer": "5.1.1"
|
"safe-buffer": "5.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "0.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"strip-bom": {
|
"strip-bom": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
"builder": "node ./scripts/build-script.js",
|
"builder": "node ./scripts/build-script.js",
|
||||||
"linter": "node ./scripts/lint-script.js",
|
"linter": "node ./scripts/lint-script.js",
|
||||||
"tagger": "node ./scripts/tag-script.js",
|
"tagger": "node ./scripts/tag-script.js",
|
||||||
|
"webber": "node ./scripts/web-script.js",
|
||||||
"start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\""
|
"start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\""
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
81
scripts/web-script.js
Normal file
81
scripts/web-script.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
This is the builder script that generates the README file.
|
||||||
|
Run using `npm run builder`.
|
||||||
|
*/
|
||||||
|
// Load modules
|
||||||
|
const fs = require('fs-extra'), path = require('path'), chalk = require('chalk'),
|
||||||
|
md = require('markdown-it')();
|
||||||
|
// Set variables for paths
|
||||||
|
const snippetsPath = './snippets', staticPartsPath = './static-parts', docsPath = './docs';
|
||||||
|
// Set variables for script
|
||||||
|
let snippets = {}, 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;
|
||||||
|
});
|
||||||
|
// 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');
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Load static parts for the index.html file
|
||||||
|
try {
|
||||||
|
startPart = fs.readFileSync(path.join(staticPartsPath,'index-start.html'),'utf8');
|
||||||
|
endPart = fs.readFileSync(path.join(staticPartsPath,'index-end.html'),'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(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).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 index.html file
|
||||||
|
try {
|
||||||
|
// Add the start static part
|
||||||
|
output += `${startPart+'\n'}`;
|
||||||
|
// Loop over tags and snippets to create the table of contents
|
||||||
|
for(let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){
|
||||||
|
output +=`<h3>`+md.render(`${capitalize(tag, true)}\n`).replace(/<p>/g,'').replace(/<\/p>/g,'')+`</h3>`;
|
||||||
|
for(let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag))
|
||||||
|
output += md.render(`[${taggedSnippet[0]}](#${taggedSnippet[0].toLowerCase()})\n`).replace(/<p>/g,'').replace(/<\/p>/g,'').replace(/<a/g,'<a class="sublink-1"');
|
||||||
|
output += '\n';
|
||||||
|
}
|
||||||
|
output += `</nav><main class="col-sm-12 col-md-8 col-lg-9" style="height: 100%;overflow-y: auto; background: #eee;">`;
|
||||||
|
// 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))){
|
||||||
|
output +=md.render(`## ${capitalize(tag, true)}\n`).replace(/<h2>/g,'<h2 style="text-align:center;">');
|
||||||
|
for(let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag))
|
||||||
|
output += '<div class="card fluid"><div class="section double-padded">' + md.render(`\n${snippets[taggedSnippet[0]+'.md']}`).replace(/<h3/g,`<h3 id="${taggedSnippet[0].toLowerCase()}"`).replace(/<\/h3>/g,'</h3></div><div class="section double-padded">') + '</div></div><br/>';
|
||||||
|
}
|
||||||
|
// Add the ending static part
|
||||||
|
output += `\n${endPart+'\n'}`;
|
||||||
|
// Write to the index.html file
|
||||||
|
fs.writeFileSync(path.join(docsPath,'index.html'), output);
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During index.html generation: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Log a success message
|
||||||
|
console.log(`${chalk.green('SUCCESS!')} index.html file generated!`);
|
||||||
|
// Log the time taken
|
||||||
|
console.timeEnd('Builder');
|
||||||
6
static-parts/index-end.html
Normal file
6
static-parts/index-end.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<footer><p><strong>30 seconds of code</strong> is licensed under the <a href="https://github.com/Chalarangelo/30-seconds-of-code/blob/master/LICENSE">CC0-1.0</a> license.<br/>Icons made by <a href="https://www.flaticon.com/authors/smashicons">Smashicons</a> from <a href="https://www.flaticon.com/">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/">CC 3.0 BY</a>.</p></footer>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<script src="prism.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
static-parts/index-start.html
Normal file
33
static-parts/index-start.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mini.css/3.0.0-alpha.1/mini-default.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Inconsolata:400,700|Poppins:400,400i,500,700,700i&subset=latin-ext" rel="stylesheet">
|
||||||
|
<title>30 seconds of code</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="description" content="Curated collection of useful Javascript snippets that you can understand in 30 seconds or less.">
|
||||||
|
<meta name="keywords" content="javascript, snippets, code, programming">
|
||||||
|
<meta name="author" content="Angelos Chalaris (chalarangelo@gmail.com)">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta property="og:title" content="30 seconds of code">
|
||||||
|
<meta property="og:description" content="Curated collection of useful Javascript snippets that you can understand in 30 seconds or less." />
|
||||||
|
<meta property="og:type" content="website" /><meta property="og:image" content="favicon.png">
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
|
<style>
|
||||||
|
html, * { font-family: 'Poppins', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif; }
|
||||||
|
code, pre, kbd, code *, pre *, kbd * { font-family: 'Inconsolata', Menlo, Consolas, monospace; }
|
||||||
|
code, kbd { font-size: 1em; }
|
||||||
|
pre { font-size: 1rem; border: 0.0625rem solid var(--secondary-border-color); border-radius: var(--universal-border-radius);}
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" href="prism.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1 class="logo" style="margin-top: -1rem; text-align:center;"><img src="favicon.png" style="height: 4rem;"/><span style="position:relative; top: -1rem;"> 30 seconds of code</span></h1>
|
||||||
|
<label for="doc-drawer-checkbox" class="button drawer-toggle" style="position: absolute; right: 0; top: 0;"></label>
|
||||||
|
</header>
|
||||||
|
<div class="row" style="height: calc(100vh - 3.5625rem);overflow: hidden;">
|
||||||
|
<input id="doc-drawer-checkbox" class="drawer" value="on" type="checkbox">
|
||||||
|
<nav class="col-md-4 col-lg-3" style="border-top: 0">
|
||||||
|
<label for="doc-drawer-checkbox" class="button drawer-close"></label>
|
||||||
|
<!-- <div><input style="width: 100%; margin: 0px;" placeholder="Search..." id="search-bar" oninput="search()" type="search"></div> -->
|
||||||
Reference in New Issue
Block a user