From db4ce525b58a28d47cee4f9f0f4e339eaa752701 Mon Sep 17 00:00:00 2001 From: Aadyaa Maddi Date: Fri, 12 Apr 2019 12:16:20 +0800 Subject: [PATCH] Automatically convert GitHub-based projects into MarkBind websites (#698) GitHub projects commonly have wikis or docs folders for project documentation. As MarkBind is especially optimized as a project documentation tool, we would want to make it easier for projects to adopt it in their workflow. Let's add the ability to automatically convert a GitHub wiki or docs folder into a MarkBind website. --- docs/userGuide/cliCommands.md | 3 + .../userGuide/markBindInTheProjectWorkflow.md | 24 + index.js | 21 +- src/Site.js | 157 + src/util/fsUtil.js | 8 +- test/functional/test.bat | 32 +- test/functional/test.sh | 34 +- .../test_site_convert/expected/Home.html | 68 + .../test_site_convert/expected/Page-1.html | 68 + .../test_site_convert/expected/_Footer.html | 68 + .../test_site_convert/expected/_Sidebar.html | 71 + .../test_site_convert/expected/about.html | 69 + .../test_site_convert/expected/index.html | 68 + .../markbind/css/bootstrap-vue.min.css | 1 + .../expected/markbind/css/bootstrap.min.css | 7 + .../markbind/css/bootstrap.min.css.map | 1 + .../expected/markbind/css/github.min.css | 1 + .../expected/markbind/css/markbind.css | 197 + .../expected/markbind/css/page-nav.css | 61 + .../expected/markbind/css/site-nav.css | 219 + .../markbind/fontawesome/css/all.min.css | 1 + .../fontawesome/webfonts/fa-brands-400.eot | Bin 0 -> 125320 bytes .../fontawesome/webfonts/fa-brands-400.svg | 3296 ++++++++++++ .../fontawesome/webfonts/fa-brands-400.ttf | Bin 0 -> 125016 bytes .../fontawesome/webfonts/fa-brands-400.woff | Bin 0 -> 84564 bytes .../fontawesome/webfonts/fa-brands-400.woff2 | Bin 0 -> 72112 bytes .../fontawesome/webfonts/fa-regular-400.eot | Bin 0 -> 34388 bytes .../fontawesome/webfonts/fa-regular-400.svg | 799 +++ .../fontawesome/webfonts/fa-regular-400.ttf | Bin 0 -> 34092 bytes .../fontawesome/webfonts/fa-regular-400.woff | Bin 0 -> 16812 bytes .../fontawesome/webfonts/fa-regular-400.woff2 | Bin 0 -> 13592 bytes .../fontawesome/webfonts/fa-solid-900.eot | Bin 0 -> 186512 bytes .../fontawesome/webfonts/fa-solid-900.svg | 4516 +++++++++++++++++ .../fontawesome/webfonts/fa-solid-900.ttf | Bin 0 -> 186228 bytes .../fontawesome/webfonts/fa-solid-900.woff | Bin 0 -> 96244 bytes .../fontawesome/webfonts/fa-solid-900.woff2 | Bin 0 -> 74348 bytes .../css/bootstrap-glyphicons.min.css | 17 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 ++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../markbind/js/bootstrap-utility.min.js | 7 + .../expected/markbind/js/bootstrap-vue.min.js | 1 + .../expected/markbind/js/polyfill.min.js | 4 + .../expected/markbind/js/setup.js | 145 + .../expected/markbind/js/vue-strap.min.js | 58 + .../expected/markbind/js/vue.min.js | 6 + .../markbind/layouts/default/footer.md | 3 + .../expected/markbind/layouts/default/head.md | 0 .../markbind/layouts/default/header.md | 10 + .../markbind/layouts/default/navigation.md | 4 + .../markbind/layouts/default/scripts.js | 4 + .../markbind/layouts/default/styles.css | 0 .../test_site_convert/expected/siteData.json | 45 + .../non_markbind_site/Home.md | 1 + .../non_markbind_site/Page-1.md | 1 + .../non_markbind_site/_Footer.md | 1 + .../non_markbind_site/_Sidebar.md | 2 + test/unit/Site.test.js | 84 + test/unit/utils/data.js | 16 + 61 files changed, 10481 insertions(+), 6 deletions(-) create mode 100644 test/functional/test_site_convert/expected/Home.html create mode 100644 test/functional/test_site_convert/expected/Page-1.html create mode 100644 test/functional/test_site_convert/expected/_Footer.html create mode 100644 test/functional/test_site_convert/expected/_Sidebar.html create mode 100644 test/functional/test_site_convert/expected/about.html create mode 100644 test/functional/test_site_convert/expected/index.html create mode 100644 test/functional/test_site_convert/expected/markbind/css/bootstrap-vue.min.css create mode 100644 test/functional/test_site_convert/expected/markbind/css/bootstrap.min.css create mode 100644 test/functional/test_site_convert/expected/markbind/css/bootstrap.min.css.map create mode 100644 test/functional/test_site_convert/expected/markbind/css/github.min.css create mode 100644 test/functional/test_site_convert/expected/markbind/css/markbind.css create mode 100644 test/functional/test_site_convert/expected/markbind/css/page-nav.css create mode 100644 test/functional/test_site_convert/expected/markbind/css/site-nav.css create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/css/all.min.css create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-brands-400.eot create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-brands-400.svg create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-brands-400.ttf create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-brands-400.woff create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-brands-400.woff2 create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-regular-400.eot create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-regular-400.svg create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-regular-400.ttf create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-regular-400.woff create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-regular-400.woff2 create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-solid-900.eot create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-solid-900.svg create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-solid-900.ttf create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-solid-900.woff create mode 100644 test/functional/test_site_convert/expected/markbind/fontawesome/webfonts/fa-solid-900.woff2 create mode 100644 test/functional/test_site_convert/expected/markbind/glyphicons/css/bootstrap-glyphicons.min.css create mode 100644 test/functional/test_site_convert/expected/markbind/glyphicons/fonts/glyphicons-halflings-regular.eot create mode 100644 test/functional/test_site_convert/expected/markbind/glyphicons/fonts/glyphicons-halflings-regular.svg create mode 100644 test/functional/test_site_convert/expected/markbind/glyphicons/fonts/glyphicons-halflings-regular.ttf create mode 100644 test/functional/test_site_convert/expected/markbind/glyphicons/fonts/glyphicons-halflings-regular.woff create mode 100644 test/functional/test_site_convert/expected/markbind/glyphicons/fonts/glyphicons-halflings-regular.woff2 create mode 100644 test/functional/test_site_convert/expected/markbind/js/bootstrap-utility.min.js create mode 100644 test/functional/test_site_convert/expected/markbind/js/bootstrap-vue.min.js create mode 100644 test/functional/test_site_convert/expected/markbind/js/polyfill.min.js create mode 100644 test/functional/test_site_convert/expected/markbind/js/setup.js create mode 100644 test/functional/test_site_convert/expected/markbind/js/vue-strap.min.js create mode 100644 test/functional/test_site_convert/expected/markbind/js/vue.min.js create mode 100644 test/functional/test_site_convert/expected/markbind/layouts/default/footer.md create mode 100644 test/functional/test_site_convert/expected/markbind/layouts/default/head.md create mode 100644 test/functional/test_site_convert/expected/markbind/layouts/default/header.md create mode 100644 test/functional/test_site_convert/expected/markbind/layouts/default/navigation.md create mode 100644 test/functional/test_site_convert/expected/markbind/layouts/default/scripts.js create mode 100644 test/functional/test_site_convert/expected/markbind/layouts/default/styles.css create mode 100644 test/functional/test_site_convert/expected/siteData.json create mode 100644 test/functional/test_site_convert/non_markbind_site/Home.md create mode 100644 test/functional/test_site_convert/non_markbind_site/Page-1.md create mode 100644 test/functional/test_site_convert/non_markbind_site/_Footer.md create mode 100644 test/functional/test_site_convert/non_markbind_site/_Sidebar.md diff --git a/docs/userGuide/cliCommands.md b/docs/userGuide/cliCommands.md index bc0d612bd5..ce182a81c5 100644 --- a/docs/userGuide/cliCommands.md +++ b/docs/userGuide/cliCommands.md @@ -76,10 +76,13 @@ MarkBind Command Line Interface (CLI) can be run in the following ways: * ``
Root directory. Default is the current directory.
{{ icon_example }} `./myWebsite` +* `-c`, `--convert`
+ Convert an existing GitHub wiki or `docs` folder into a MarkBind website. See [Converting an existing Github project]({{ baseUrl }}/userGuide/markBindInTheProjectWorkflow.html#converting-an-existing-github-project) for more information. {{ icon_examples }} * `markbind init` : Initializes the site in the current working directory. * `markbind init ./myWebsite` : Initializes the site in `./myWebsite` directory. +* `markbind init --convert` : Converts the Github wiki or `docs` folder in the current working directory into a MarkBind website.
diff --git a/docs/userGuide/markBindInTheProjectWorkflow.md b/docs/userGuide/markBindInTheProjectWorkflow.md index 1fb664808c..f3336881c8 100644 --- a/docs/userGuide/markBindInTheProjectWorkflow.md +++ b/docs/userGuide/markBindInTheProjectWorkflow.md @@ -36,5 +36,29 @@ You can keep the user docs in a separate directory (say `user-docs`) and set up Similarly, you can keep the dev docs in a separate directory (sey `dev-docs`) and set up Netlify to deploy the site when there is an update to the `master` branch; that way, developers can see the latest version of dev-docs via the Netlify site. +#### Converting existing project documentation/wiki + +MarkBind supports the automatic conversion of an existing GitHub wiki or `docs` folder containing Markdown files. + +A MarkBind conversion involves the following: +- Adding a Home page: If your project already has a `README.md` or `Home.md`, the content will be copied over to `index.md`. Otherwise, a default home page will be added. +- Adding an About Us page: If your project already has `about.md`, this will be used as the About page. Otherwise, a default About page will be added. +- Adding a top navigation bar. +- Adding a site navigation menu: If your project has a valid `_Sidebar.md` file, it will be used as the [site navigation menu](https://markbind.org/userGuide/tweakingThePageStructure.html#site-navigation-menus). Otherwise, the menu will be built from your project's directory structure and contain links to all addressable pages. +- Adding a custom footer: If your project has a valid `_Footer.md` file, it will be used as the website footer. Otherwise, a default footer will be added. + + + Conversion might not work if your project files have existing Nunjucks syntax. + + +To convert your existing project, follow these steps: +1. Navigate into the project directory. +1. Run `markbind init --convert` to convert the project. +1. You can now preview the website using `markbind serve` to view your newly converted MarkBind website. + + + You only need to run the conversion once. Once you have converted your project, you can proceed to edit it as a normal MarkBind project. + + {% from "njk/common.njk" import previous_next %} {{ previous_next('deployingTheSite', 'themes') }} diff --git a/index.js b/index.js index ff4d28d878..1bdce1b0e0 100755 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ // Entry file for Markbind project const chokidar = require('chokidar'); +const fs = require('fs-extra-promise'); const liveServer = require('live-server'); const path = require('path'); const program = require('commander'); @@ -45,15 +46,33 @@ program program .command('init [root]') + .option('-c, --convert', 'convert a GitHub wiki or docs folder to a MarkBind website') .alias('i') .description('init a markbind website project') - .action((root) => { + .action((root, options) => { const rootFolder = path.resolve(root || process.cwd()); + const outputRoot = path.join(rootFolder, '_site'); printHeader(); + if (options.convert) { + if (fs.existsSync(path.resolve(rootFolder, 'site.json'))) { + logger.error('Cannot convert an existing MarkBind website!'); + return; + } + } Site.initSite(rootFolder) .then(() => { logger.info('Initialization success.'); }) + .then(() => { + if (options.convert) { + logger.info('Converting to MarkBind website.'); + new Site(rootFolder, outputRoot).convert() + .then(() => { + logger.info('Conversion success.'); + }) + .catch(handleError); + } + }) .catch(handleError); }); diff --git a/src/Site.js b/src/Site.js index 2684a00a5a..efeb6f5816 100644 --- a/src/Site.js +++ b/src/Site.js @@ -18,6 +18,7 @@ _.isBoolean = require('lodash/isBoolean'); _.isUndefined = require('lodash/isUndefined'); _.noop = require('lodash/noop'); _.omitBy = require('lodash/omitBy'); +_.startCase = require('lodash/startCase'); _.union = require('lodash/union'); _.uniq = require('lodash/uniq'); @@ -25,6 +26,7 @@ const url = {}; url.join = path.posix.join; const delay = require('./util/delay'); +const FsUtil = require('./util/fsUtil'); const logger = require('./util/logger'); const Page = require('./Page'); @@ -38,6 +40,7 @@ const TEMP_FOLDER_NAME = '.temp'; const TEMPLATE_ROOT_FOLDER_NAME = 'template'; const TEMPLATE_SITE_ASSET_FOLDER_NAME = 'markbind'; +const ABOUT_MARKDOWN_FILE = 'about.md'; const BUILT_IN_PLUGIN_FOLDER_NAME = 'plugins'; const BUILT_IN_DEFAULT_PLUGIN_FOLDER_NAME = 'plugins/default'; const FAVICON_DEFAULT_PATH = 'favicon.ico'; @@ -59,6 +62,8 @@ const LAYOUT_FOLDER_PATH = '_markbind/layouts'; const LAYOUT_SCRIPTS_PATH = 'scripts.js'; const LAYOUT_SITE_FOLDER_NAME = 'layouts'; const USER_VARIABLES_PATH = '_markbind/variables.md'; +const WIKI_SITE_NAV_PATH = '_Sidebar.md'; +const WIKI_FOOTER_PATH = '_Footer.md'; function getBootswatchThemePath(theme) { return path.join(__dirname, '..', 'node_modules', 'bootswatch', 'dist', theme, 'bootstrap.min.css'); @@ -114,6 +119,9 @@ const SITE_CONFIG_DEFAULT = { }, }; +const ABOUT_MARKDOWN_DEFAULT = '# About\n' + + 'Welcome to your **About Us** page.\n'; + const FOOTER_DEFAULT = '