Revert "Revert "Merge pull request #1 from 30-seconds/master""
This reverts commit 2f79031e0e.
This commit is contained in:
104
scripts/build.js
Normal file
104
scripts/build.js
Normal file
@ -0,0 +1,104 @@
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const chalk = require("chalk");
|
||||
const util = require("./util.js");
|
||||
const markdown = require("markdown-builder");
|
||||
const snippets = require("../data/snippet_data.json")
|
||||
|
||||
const { headers, misc, lists } = markdown;
|
||||
const TAG_NAMES = [...new Set(snippets.reduce((acc,v) => [...acc,v.tags[0]],[]))].sort((a,b) => a.localeCompare(b));
|
||||
console.log(TAG_NAMES);
|
||||
|
||||
const STATIC_PARTS_PATH = "./static-parts";
|
||||
|
||||
let startPart = "";
|
||||
let endPart = "";
|
||||
let output = "";
|
||||
|
||||
const detailsTOC = (title, snippetsArray) =>
|
||||
`\n${misc
|
||||
.collapsible(
|
||||
title,
|
||||
lists
|
||||
.ul(snippetsArray, snippet =>
|
||||
misc.link(
|
||||
snippet.title
|
||||
.replace("\n", "")
|
||||
.split("```")[0]
|
||||
.trim(),
|
||||
misc.anchor(
|
||||
snippet.title
|
||||
.replace("\n", "")
|
||||
.split("```")[0]
|
||||
.trim()
|
||||
)
|
||||
)
|
||||
)
|
||||
.trim()
|
||||
)
|
||||
.trim()}\n\n`;
|
||||
|
||||
console.time("Builder");
|
||||
|
||||
try {
|
||||
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) {
|
||||
console.log(`${chalk.red("ERROR!")} During static part loading: ${err}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
// add static part for start
|
||||
output += `${startPart}\n`;
|
||||
|
||||
const snippetsInTag = {};
|
||||
|
||||
TAG_NAMES.forEach(tag => snippetsInTag[tag] = snippets.filter(v => v.tags[0] == tag));
|
||||
|
||||
// write Table of Contents
|
||||
TAG_NAMES.forEach(tag => {
|
||||
const taggedSnippets = snippetsInTag[tag];
|
||||
output += headers.h3(util.capitalize(tag));
|
||||
output += detailsTOC("View contents", taggedSnippets);
|
||||
});
|
||||
|
||||
// delimeter after TOC
|
||||
output += misc.hr();
|
||||
|
||||
// write actual snippets
|
||||
TAG_NAMES.forEach(tag => {
|
||||
output += headers.h2(util.capitalize(tag));
|
||||
const taggedSnippets = snippetsInTag[tag];
|
||||
taggedSnippets.forEach(snippet => {
|
||||
output += headers.h3(snippet.title).trim();
|
||||
output += `\n\n${snippet.text}${snippet.codeBlocks.slice(0,-1).join('\n\n')}`;
|
||||
if (snippet.notes && snippet.notes.length) {
|
||||
output += headers.h4('Notes');
|
||||
output += `\n${snippet.notes}`;
|
||||
}
|
||||
output += misc.collapsible('Examples', snippet.codeBlocks.slice(-1));
|
||||
output += `\n<br>${misc.link(
|
||||
"⬆ Back to top",
|
||||
misc.anchor("Table of Contents")
|
||||
)}\n\n`
|
||||
})
|
||||
});
|
||||
|
||||
// add static part for end
|
||||
output += `\n${endPart}\n`;
|
||||
|
||||
fs.writeFileSync("README.md", output);
|
||||
} catch (err) {
|
||||
console.log(`${chalk.red("ERROR!")} During README generation: ${err}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`${chalk.green("SUCCESS!")} README file generated!`);
|
||||
console.timeEnd("Builder");
|
||||
59
scripts/extract.js
Normal file
59
scripts/extract.js
Normal file
@ -0,0 +1,59 @@
|
||||
const fs = require("fs-extra")
|
||||
const path = require("path")
|
||||
const chalk = require("chalk")
|
||||
const {
|
||||
attempt,
|
||||
readSnippets,
|
||||
getCodeBlocks,
|
||||
getSection,
|
||||
getTitle,
|
||||
getTextualContent
|
||||
} = require("./util");
|
||||
|
||||
console.time("Extractor");
|
||||
|
||||
attempt("snippet_data.json generation", () => {
|
||||
const output = Object.entries(readSnippets()).map(([name, contents]) => {
|
||||
const title = getTitle(contents);
|
||||
const text = getTextualContent(contents);
|
||||
const codeBlocks = getCodeBlocks(contents);
|
||||
const notes = getSection("#### Notes", contents, false)
|
||||
.split("\n")
|
||||
.map(v => v.replace(/[*-] /g, ""))
|
||||
.filter(v => v.trim() !== "")
|
||||
// const answer = getSection("#### Answer", contents)
|
||||
|
||||
// const goodToHear = getSection("#### Good to hear", contents, false)
|
||||
// .split("\n")
|
||||
// .map(v => v.replace(/[*-] /g, ""))
|
||||
// .filter(v => v.trim() !== "")
|
||||
|
||||
// const links = getSection("##### Additional links", contents)
|
||||
// .split("\n")
|
||||
// .filter(v =>
|
||||
// /(\/\*[\w\'\s\r\n\*]*\*\/)|(\/\/[\w\s\']*)|(\<![\-\-\s\w\>\/]*\>)/.test(
|
||||
// v
|
||||
// )
|
||||
// )
|
||||
// .map(v => v.replace(/[*-] /g, ""))
|
||||
// .filter(v => v.trim() !== "" && !v.includes("tags"))
|
||||
|
||||
return {
|
||||
name,
|
||||
title,
|
||||
text,
|
||||
codeBlocks,
|
||||
expertise: parseInt(
|
||||
(contents.match(/<!--\s*expertise:\s*\(*(.+)\)*/) || [])[1],
|
||||
10
|
||||
),
|
||||
tags: (contents.match(/<!--\s*tags:\s*\(*(.+)\)*\s*-->/) || [])[1].split(",").map(v => v.trim()),
|
||||
notes
|
||||
}
|
||||
})
|
||||
|
||||
fs.writeFileSync("./data/snippet_data.json", JSON.stringify(output, null, 2))
|
||||
})
|
||||
|
||||
console.log(`${chalk.green("SUCCESS!")} snippet_data.json file generated!`);
|
||||
console.timeEnd("Extractor");
|
||||
95
scripts/util.js
Normal file
95
scripts/util.js
Normal file
@ -0,0 +1,95 @@
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const chalk = require("chalk");
|
||||
|
||||
const SNIPPETS_PATH = "./snippets";
|
||||
|
||||
const attempt = (task, cb) => {
|
||||
try {
|
||||
return cb();
|
||||
} catch (e) {
|
||||
console.log(`${chalk.red("ERROR!")} During ${task}: ${e}`);
|
||||
process.exit(1);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const capitalize = ([first, ...rest], lowerRest = false) =>
|
||||
first.toUpperCase() + (lowerRest ? rest.join("").toLowerCase() : rest.join(""));
|
||||
|
||||
const readSnippets = () =>
|
||||
attempt("read snippets", () =>
|
||||
fs
|
||||
.readdirSync(SNIPPETS_PATH)
|
||||
.sort((a, b) => (a.toLowerCase() < b.toLowerCase() ? -1 : 1))
|
||||
.reduce((acc, name) => {
|
||||
acc[name] = fs
|
||||
.readFileSync(path.join(SNIPPETS_PATH, name), "utf8")
|
||||
.replace(/\r\n/g, "\n");
|
||||
return acc;
|
||||
}, {})
|
||||
);
|
||||
|
||||
const getCodeBlocks = str => {
|
||||
const regex = /```[.\S\s]*?```/g;
|
||||
const results = [];
|
||||
let m = null;
|
||||
while ((m = regex.exec(str)) !== null) {
|
||||
if (m.index === regex.lastIndex) {
|
||||
regex.lastIndex += 1;
|
||||
}
|
||||
m.forEach(match => results.push(match));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
const getSection = (searchString, contents, includeSubsections = true) => {
|
||||
const indexOfSearch = contents.indexOf(searchString);
|
||||
if (indexOfSearch < 0) return "";
|
||||
|
||||
let endSearch = "\\n#"
|
||||
if (includeSubsections) {
|
||||
let i;
|
||||
for (i = 0; searchString[i] === "#" && i < searchString.length; i++);
|
||||
|
||||
if (i > 0) {
|
||||
endSearch += `{${i - 1},${i}}[^#]`;
|
||||
}
|
||||
}
|
||||
const endRegex = new RegExp(endSearch);
|
||||
|
||||
const sliceStart = indexOfSearch + searchString.length + 1;
|
||||
const endIndex = contents.slice(sliceStart).search(endRegex);
|
||||
const sliceEnd = endIndex === -1 ? undefined : endIndex + sliceStart;
|
||||
|
||||
return contents.slice(sliceStart, sliceEnd).trim();
|
||||
}
|
||||
|
||||
const getTextualContent = str => {
|
||||
const regex = /###.*\n*([\s\S]*?)```/g;
|
||||
const results = [];
|
||||
let m = null;
|
||||
while ((m = regex.exec(str)) !== null) {
|
||||
if (m.index === regex.lastIndex)
|
||||
regex.lastIndex += 1;
|
||||
|
||||
m.forEach((match, groupIndex) => {
|
||||
results.push(match);
|
||||
});
|
||||
}
|
||||
return results[1];
|
||||
};
|
||||
|
||||
const getTitle = (contents) =>
|
||||
contents.split('\n')[0].replace(/^#+\s+/g,'');
|
||||
|
||||
module.exports = {
|
||||
attempt,
|
||||
readSnippets,
|
||||
SNIPPETS_PATH,
|
||||
capitalize,
|
||||
getTextualContent,
|
||||
getCodeBlocks,
|
||||
getSection,
|
||||
getTitle
|
||||
};
|
||||
Reference in New Issue
Block a user