Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config and Plugin Support #14

Merged
merged 10 commits into from
Aug 19, 2020
15 changes: 11 additions & 4 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const express = require("express");

const util = require("./util");

const app = express();
const port = 3000;

Expand All @@ -10,10 +11,16 @@ app.get("/:user/:repo/compile", (req, res) => {
const user = req.params.user;
const repo = req.params.repo;

util.getReadme(user, repo).then(() => {
util.serveDocs(app, user, repo);
res.send(`Successfully Compiled Docs! View them at /${user}/${repo}`);
});
try {
util.compileDocs(user, repo).then(() => {
util.serveDocs(app, user, repo);
res.send(`Successfully Compiled Docs! View them at /${user}/${repo}`);
});
} catch (error) {
res.send(
`Oops. We couldn't render these docs. Check your config if you have one and try again!`
);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does compileDocs have an error handler? That would be better than try / catch

});

app.listen(port, () =>
Expand Down
5 changes: 5 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"description": "Description",
"plugins": [],
"gaCode": ""
}
Comment on lines +1 to +5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request description says this isn'' required right? Is this an example?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the config.json here is just the list of supported keys that can be used

23 changes: 22 additions & 1 deletion docsify.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
// Generates docsify enabled html with no config
function generateHTML(user, repo) {
return `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"/><title>${repo}</title><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="description" content="Description"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/> <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css"/> </head> <body> <div id="app"></div><script>window.$docsify={name: '${repo}', repo: '${user}/${repo}'}; </script> <script src="//cdn.jsdelivr.net/npm/docsify@4"></script> </body></html>`;
}

module.exports = { generateHTML };
// Generated docsify enabled html with config and plugins
function generateHtmlWithConfig(config) {
if (config.enablePlugins) {
let ga = ""; // google analytics code
let search = ""; // search path

if (config.plugins.ga) {
ga = `, ga: ${config.gaCode}`;
}
if (config.plugins.search) {
search = ', search: ["/"]';
}

return `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"/><title>${config.repo}</title><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="description" content="${config.description}"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/> <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css"/> </head> <body> <div id="app"></div><script>window.$docsify={name: '${config.repo}', repo: '${config.user}/${config.repo}'${ga}${search}}; </script> <script src="//cdn.jsdelivr.net/npm/docsify@4"></script>${config.plugins.tags}</body></html>`;
}

// If no plugins, but config exists for description
return `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"/><title>${config.repo}</title><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="description" content="${config.description}"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/> <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css"/> </head> <body> <div id="app"></div><script>window.$docsify={name: '${config.repo}', repo: '${config.user}/${config.repo}'}; </script> <script src="//cdn.jsdelivr.net/npm/docsify@4"></script> </body></html>`;
aemmadi marked this conversation as resolved.
Show resolved Hide resolved
}

module.exports = { generateHTML, generateHtmlWithConfig };
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "docsify-up",
"version": "1.0.0",
"description": "- https://documentup.com/jeromegn/documentup\r - https://github.com/docsifyjs/docsify/issues/217",
"main": "index.js",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
Expand Down
34 changes: 34 additions & 0 deletions plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
function addPlugins(pluginList) {
let pluginConfig = {
ga: false,
search: false,
tags: "",
};
let scriptTags = "";
for (let i = 0; i < pluginList.length; i++) {
if (pluginList[i] == "docsify-copy-code") {
scriptTags +=
"<script src='//cdn.jsdelivr.net/npm/docsify-copy-code'></script>";
}
if (pluginList[i] == "full-text-search") {
scriptTags +=
"<script src='//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js'></script>";
pluginConfig.search = true;
}
if (pluginList[i] == "google-analytics") {
pluginConfig.ga = true;
}
if (pluginList[i] == "emoji") {
scriptTags +=
"<script src='//cdn.jsdelivr.net/npm/docsify/lib/plugins/emoji.min.js'></script>";
}
if (pluginList[i] == "zoom-image") {
scriptTags +=
aemmadi marked this conversation as resolved.
Show resolved Hide resolved
"<script src='//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js'></script>";
}
}
pluginConfig.tags = scriptTags;
return pluginConfig;
}

module.exports = { addPlugins };
88 changes: 85 additions & 3 deletions util.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const fs = require("fs");
const hasha = require("hasha");

const docsify = require("./docsify");
const plugins = require("./plugins");
let mainConfig = require("./config.json");

// Compares local and remote readme for changes
function isDiffReadme(user, repo, readmeData) {
Expand All @@ -22,7 +24,18 @@ function isDiffReadme(user, repo, readmeData) {
}

// Writes all the required files
function writeDocs(user, repo, readmeData) {
async function writeDocs(user, repo, readmeData) {
const config = await getConfig(user, repo);

if (isConfigDefault(config)) {
writeDocsWithDefaultConfig(user, repo, readmeData);
} else {
// TODO: if config is not default? --> plugin integration!!!
writeDocsWithConfig(user, repo, readmeData, config);
}
}

async function writeDocsWithDefaultConfig(user, repo, readmeData) {
const htmlData = docsify.generateHTML(user, repo);

fs.writeFileSync(`./docs/${user}-${repo}/README.md`, readmeData, function (
Expand All @@ -40,8 +53,47 @@ function writeDocs(user, repo, readmeData) {
});
}

async function writeDocsWithConfig(user, repo, readmeData, config) {
try {
Object.keys(config).forEach((key) => {
mainConfig[`${key}`] = config[key];
});

mainConfig.enablePlugins = false;
if (mainConfig.plugins.length > 0) {
mainConfig.enablePlugins = true;
}

if (mainConfig.enablePlugins) {
const pluginConfig = plugins.addPlugins(mainConfig.plugins);
mainConfig.plugins = pluginConfig;
}

const htmlData = docsify.generateHtmlWithConfig(mainConfig);

fs.writeFileSync(`./docs/${user}-${repo}/README.md`, readmeData, function (
err
) {
if (err) throw err;
console.log("Generated ReadMe!");
});

fs.writeFileSync(`./docs/${user}-${repo}/index.html`, htmlData, function (
err
) {
if (err) throw err;
console.log("Generated HTML!");
});
} catch (error) {
writeDocsWithDefaultConfig(user, repo, readmeData);
}
Comment on lines +55 to +87
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, interesting read. Will look more into error handling with callback functions. Future refactor!!

}

// Gets readme contents and generates /docs/<files> with docsify enabled to render
async function getReadme(user, repo) {
mainConfig.user = user;
mainConfig.repo = repo;

const readme = await axios.get(
`https://api.github.com/repos/${user}/${repo}/readme`
);
Expand All @@ -58,7 +110,7 @@ async function getReadme(user, repo) {

// Write file only if github readme is different from local copy
if (isDiffReadme(user, repo, readmeData.data)) {
writeDocs(user, repo, readmeData.data);
await writeDocs(user, repo, readmeData.data);
}
}

Expand All @@ -67,4 +119,34 @@ function serveDocs(app, user, repo) {
app.use(`/${user}/${repo}`, express.static(`./docs/${user}-${repo}`));
}

module.exports = { getReadme, serveDocs };
function isConfigDefault(config) {
if (config.name != "") return false;
aemmadi marked this conversation as resolved.
Show resolved Hide resolved
return true;
}

async function getConfig(user, repo) {
const gitRepo = await axios.get(
`https://api.github.com/repos/${user}/${repo}/contents`
);
const gitRepoFiles = gitRepo.data;
let configUrl = "";

for (let i = 0; i < gitRepoFiles.length; i++) {
if (gitRepoFiles[i].name == ".fastdocs.json") {
configUrl = gitRepoFiles[i].download_url;
break;
}
}

if (configUrl != "") {
const config = await axios.get(configUrl);
return config.data;
}
return mainConfig;
}

async function compileDocs(user, repo) {
await getReadme(user, repo);
}

module.exports = { compileDocs, serveDocs };