c319294460
* make the scripts share the same lock file by using a Yarn workspace * replaced winston with fancy-log * replaced sync-exec with execa * add type annotations to some functions
133 lines
3.6 KiB
JavaScript
133 lines
3.6 KiB
JavaScript
require("checkenv").check();
|
|
|
|
const util = require("util");
|
|
const logger = require("fancy-log");
|
|
|
|
const sanitizeHtml = require("sanitize-html");
|
|
const fs = require("fs-extra");
|
|
const execa = import("execa");
|
|
|
|
const inputDirectory = "./wiki/";
|
|
const outputDirectory = "../../../site/content/wiki/";
|
|
|
|
/** Generate URL for the given title name
|
|
* @param {string} title
|
|
*/
|
|
function url(title) {
|
|
return "/wiki/" + title.replace(/\s+/g, "-").toLowerCase();
|
|
}
|
|
|
|
async function run() {
|
|
if (fs.existsSync(inputDirectory)) {
|
|
logger.info(`Purging input directory: ${inputDirectory}`);
|
|
fs.removeSync(inputDirectory);
|
|
}
|
|
|
|
const exec = (await execa).execaSync;
|
|
logger.info(`git clone ${process.env.GITHUB_WIKI_URL} wiki`);
|
|
exec("git", ["clone", process.env.GITHUB_WIKI_URL, "wiki"]);
|
|
|
|
if (!fs.existsSync(outputDirectory)) {
|
|
logger.info(`Creating missing output directory: ${outputDirectory}`);
|
|
fs.mkdirSync(outputDirectory);
|
|
}
|
|
|
|
fs.readdir(inputDirectory, (err, items) => {
|
|
if (err) {
|
|
logger.error(err);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Look for all .md files within the wiki directory.
|
|
items
|
|
.filter((file) => file.endsWith(".md"))
|
|
.forEach((item) => {
|
|
// Generate the title from the filename.
|
|
generateEntry(item);
|
|
});
|
|
} catch (err) {
|
|
logger.error(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
/** Generate one wiki entry
|
|
* @param {string} item */
|
|
function generateEntry(item) {
|
|
const title = item.replace(/-/g, " ").slice(0, -3);
|
|
const stats = fs.statSync(`${inputDirectory}${item}`);
|
|
const modified = new Date(util.inspect(stats.mtime));
|
|
|
|
// Read the .md file.
|
|
fs.readFile(`${inputDirectory}${item}`, "utf8", (err, data) => {
|
|
if (err) {
|
|
logger.error(err);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Convert various data inside of the markdown language.
|
|
let cleanData = sanitizeHtml(data);
|
|
|
|
// Blackfriday Markdown Rendering requires a blank line before lists.
|
|
try {
|
|
const lines = cleanData.split(/\r?\n/);
|
|
for (let i = 0; i < lines.length; i++) {
|
|
// If it's the start of the file, ignore to prevent an index issue.
|
|
if (i > lines.length) return;
|
|
if (i === 0 || lines[i] === "\n") continue;
|
|
|
|
// Search for the start of a list designated by the * character.
|
|
if (
|
|
lines[i].startsWith("* ") &&
|
|
lines[i - 1].startsWith("* ") === false
|
|
) {
|
|
i++;
|
|
lines.splice(i - 1, 0, "");
|
|
}
|
|
}
|
|
cleanData = lines.join("\n");
|
|
} catch (err) {
|
|
logger.error(err);
|
|
}
|
|
|
|
// Replacing tags like [[Common Issues on Windows|Common Issues]]
|
|
cleanData = cleanData.replace(
|
|
/\[\[(.*)\|(.*)\]\]/g,
|
|
(_, p1, p2) => `[${p1}](${url(p2)})`
|
|
);
|
|
|
|
// Replacing tags like [[Common Issues]]
|
|
cleanData = cleanData.replace(
|
|
/\[\[(.*)\]\]/g,
|
|
(_, p1) => `[${p1}](${url(p1)})`
|
|
);
|
|
|
|
// Restore some escaped entities
|
|
cleanData = cleanData
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">");
|
|
|
|
// Create the new markdown header for Hugo.
|
|
const newFileContents = `+++\r\ntitle = "${title}"\r\ndate = "${modified.toISOString()}"\r\n+++\r\n\r\n${cleanData}\r\n`;
|
|
|
|
const itemOutput = item.toLowerCase();
|
|
fs.writeFile(
|
|
`${outputDirectory}${itemOutput}`,
|
|
newFileContents,
|
|
(err) => {
|
|
if (err) {
|
|
return logger.error(err);
|
|
}
|
|
logger.info(`Wrote file ${itemOutput} to filesystem.`);
|
|
}
|
|
);
|
|
} catch (err) {
|
|
logger.error(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
run().catch((e) => logger.error(e));
|