@panoramax/web-viewer
Version:
Panoramax web viewer for geolocated pictures
80 lines (69 loc) • 2.74 kB
JavaScript
/*
* Widely based on https://github.com/jsdoc2md/jsdoc-to-markdown/wiki/How-to-create-one-output-file-per-class
*/
const jsdoc2md = require("jsdoc-to-markdown");
const fs = require("node:fs").promises;
const path = require("path");
const SRC_FOLDER = path.resolve(__dirname, "..", "src");
const OUTPUT_FOLDER = path.resolve(__dirname, "..", "docs", "reference");
const MD_LINK_RGX = /\[([^\]]+)\]\(#([^+)]+)\+?([^)]+)?\)/g;
// Remove all stuff in docs/reference/ folder
async function cleanupDocFolder(folder) {
await fs.rm(folder, {recursive: true, force: true});
}
// Create subfolders in docs/reference/ to match JS files folder tree
async function createSubFolders(fullFolder) {
const relPath = path.relative(SRC_FOLDER, fullFolder);
const docPath = path.join(OUTPUT_FOLDER, relPath);
await fs.mkdir(docPath, {recursive: true});
return docPath;
}
// Replace links in generated Markdown to go to relative file instead of same file
function cleanupMdLinks(clid, md) {
return md.replace(MD_LINK_RGX, (match, text, link, plus) => {
if(link == clid || link == `new_${clid}_new` || link.startsWith(clid+".")) { return match; }
const linkClassPath = link.split("+")[0].split(".").slice(1);
const currentClassPath = clid.split(".").slice(1);
const relPath = path.relative(
path.dirname(currentClassPath.join("/")+".md"),
linkClassPath.join("/")+".md"
);
return `[${text}](${relPath}/#${link}${plus ? "+"+plus : ""})`;
});
}
// Create MD file for a single JS file
async function writeDocs(templateData) {
const classes = templateData.filter(i => i.kind === "class" && i.name !== "exports");
for(let cl of classes) {
console.log("Generating doc for", cl.name);
const docPath = await createSubFolders(cl.meta.path);
const template = `{{#class name="${cl.name}"}}{{>docs}}{{/class}}`;
let output = await jsdoc2md.render({ data: templateData, template: template });
output = cleanupMdLinks(cl.id, output);
if(!output.startsWith("ERROR")) {
await fs.writeFile(path.resolve(docPath, `${cl.name}.md`), output);
}
}
}
// Recursive load of JS files
async function readSingleFolder(folder) {
console.log("Searching in folder", path.basename(folder));
let jsfiles = [];
const files = await fs.readdir(folder);
for(let file of files) {
const filepath = path.join(folder, file);
const stat = await fs.stat(filepath);
if(stat.isDirectory()) {
jsfiles = jsfiles.concat(await readSingleFolder(filepath));
}
else if(stat.isFile() && path.extname(filepath) === ".js") {
jsfiles.push(filepath);
}
}
return jsfiles;
}
// Main code execution
cleanupDocFolder(OUTPUT_FOLDER)
.then(() => readSingleFolder(SRC_FOLDER))
.then(files => jsdoc2md.getTemplateData({ files }))
.then(writeDocs);