Update builder script
This commit is contained in:
177
scripts/util_o.js
Normal file
177
scripts/util_o.js
Normal file
@ -0,0 +1,177 @@
|
||||
const fs = require('fs-extra'),
|
||||
path = require('path'),
|
||||
{ red } = require('kleur'),
|
||||
crypto = require('crypto');
|
||||
const babel = require('@babel/core');
|
||||
|
||||
const getMarkDownAnchor = paragraphTitle =>
|
||||
paragraphTitle
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^\w\- ]+/g, '')
|
||||
.replace(/\s/g, '-')
|
||||
.replace(/\-+$/, '');
|
||||
|
||||
const getFilesInDir = (directoryPath, withPath, exclude = null) => {
|
||||
try {
|
||||
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;
|
||||
});
|
||||
|
||||
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(`${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) {
|
||||
console.log(`${red('ERROR!')} During snippet loading: ${err}`);
|
||||
process.exit(1);
|
||||
}
|
||||
return snippets;
|
||||
};
|
||||
// Creates an object from pairs
|
||||
const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {});
|
||||
// Load tag data from the database
|
||||
const readTags = () => {
|
||||
let tagDbData = {};
|
||||
try {
|
||||
tagDbData = objectFromPairs(
|
||||
fs
|
||||
.readFileSync('tag_database', 'utf8')
|
||||
.split('\n')
|
||||
.filter(v => v.trim() !== '')
|
||||
.map(v => {
|
||||
let data = v.split(':').slice(0, 2);
|
||||
data[1] = data[1].split(',').map(t => t.trim());
|
||||
return data;
|
||||
})
|
||||
);
|
||||
} catch (err) {
|
||||
// Handle errors (hopefully not!)
|
||||
console.log(`${red('ERROR!')} During tag database loading: ${err}`);
|
||||
process.exit(1);
|
||||
}
|
||||
return tagDbData;
|
||||
};
|
||||
// Optimizes nodes in an HTML document
|
||||
const optimizeNodes = (data, regexp, replacer) => {
|
||||
let count = 0;
|
||||
let output = data;
|
||||
do {
|
||||
output = output.replace(regexp, replacer);
|
||||
count = 0;
|
||||
while (regexp.exec(output) !== null)
|
||||
++count;
|
||||
|
||||
} while (count > 0);
|
||||
return output;
|
||||
};
|
||||
// Randomizes the order of the values of an array, returning a new array.
|
||||
const shuffle = ([...arr]) => {
|
||||
let m = arr.length;
|
||||
while (m) {
|
||||
const i = Math.floor(Math.random() * m--);
|
||||
[arr[m], arr[i]] = [arr[i], arr[m]];
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
// Capitalizes the first letter of a string
|
||||
const capitalize = (str, lowerRest = false) =>
|
||||
str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
|
||||
// Checks if current environment is Travis CI
|
||||
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
|
||||
const isTravisCronOrAPI = () =>
|
||||
process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env['TRAVIS_EVENT_TYPE'] === 'api';
|
||||
const isNotTravisCronOrAPI = () => !isTravisCronOrAPI();
|
||||
// Creates a hash for a value using the SHA-256 algorithm.
|
||||
const hashData = val =>
|
||||
crypto
|
||||
.createHash('sha256')
|
||||
.update(val)
|
||||
.digest('hex');
|
||||
// Gets the code blocks for a snippet file.
|
||||
const getCodeBlocks = str => {
|
||||
const regex = /```[.\S\s]*?```/g;
|
||||
let 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);
|
||||
});
|
||||
}
|
||||
results = results.map(v => v.replace(/```js([\s\S]*?)```/g, '$1').trim());
|
||||
return {
|
||||
es6: results[0],
|
||||
es5: babel.transformSync(results[0], { presets: ['@babel/preset-env'] }).code.replace('"use strict";\n\n', ''),
|
||||
example: results[1]
|
||||
};
|
||||
};
|
||||
// Gets the textual content for a snippet file.
|
||||
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 prepTaggedData = tagDbData =>
|
||||
[...new Set(Object.entries(tagDbData).map(t => t[1][0]))]
|
||||
.filter(v => v)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
capitalize(a, true) === 'Uncategorized'
|
||||
? 1
|
||||
: capitalize(b, true) === 'Uncategorized'
|
||||
? -1
|
||||
: a.localeCompare(b)
|
||||
);
|
||||
module.exports = {
|
||||
getMarkDownAnchor,
|
||||
getFilesInDir,
|
||||
readSnippets,
|
||||
readTags,
|
||||
optimizeNodes,
|
||||
capitalize,
|
||||
objectFromPairs,
|
||||
isTravisCI,
|
||||
hashData,
|
||||
shuffle,
|
||||
getCodeBlocks,
|
||||
getTextualContent,
|
||||
isTravisCronOrAPI,
|
||||
isNotTravisCronOrAPI,
|
||||
prepTaggedData
|
||||
};
|
||||
Reference in New Issue
Block a user