Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/_markbind/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<variable name="icon_check_blue"><span style="color: {{ markbind_blue }}">:fas-check-circle:</span></variable>
<variable name="icon_bulb_blue"><span style="color: {{ markbind_blue }}">:fas-lightbulb:</span></variable>
<variable name="icon_dislike">:fas-thumbs-down:</variable>
<variable name="icon_example"><big><span class='badge badge-pill badge-light' style="background-color: #d9d9d9; color: #737373; position:relative; left:-10px">Example:</span></big></variable>
<variable name="icon_examples"><big><span class='badge badge-pill badge-light' style="background-color: #d9d9d9; color: #737373; position:relative; left:-10px">Examples:</span></big></variable>
<variable name="icon_example"><big><span class='badge badge-pill badge-secondary' style="padding-bottom: 4px; margin-right: 5px;">Example</span></big></variable>
<variable name="icon_examples"><big><span class='badge badge-pill badge-secondary' style="padding-bottom: 4px;">Examples</span></big></variable>
<variable name="icon_info">:fas-info-circle:</variable>
<variable name="icon_ticked">:far-check-square:</variable>

Expand Down
83 changes: 65 additions & 18 deletions docs/userGuide/cliCommands.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ Usage: markbind <command>
<hr><!-- ========================================================================== -->

### `init` Command
<br>

**Format:** `markbind init [options] [root]`

**Format:** `markbind init [options] [root]`<br>
**Alias:** `markbind i`

**Description:** Initializes a directory into a MarkBind site by creating a skeleton structure for the website which includes a `index.md` and a `site.json`.
Expand All @@ -37,7 +39,10 @@ Usage: markbind <command>
Root directory. Default is the current directory.<br>
{{ icon_example }} `./myWebsite`

**`options`:**
<panel header="**Options** :fas-cogs:" type="minimal">

**Options** :fas-cogs:

* `-c`, `--convert`<br>
Convert an existing GitHub wiki or `docs` folder into a MarkBind website. See [Converting an existing Github project]({{ baseUrl }}/userGuide/markBindInTheProjectWorkflow.html#converting-existing-project-documentation-wiki) for more information.

Expand All @@ -46,11 +51,15 @@ Usage: markbind <command>
* `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.

</panel>

<hr><!-- ========================================================================== -->

### `serve` Command
<br>

**Format:** `markbind serve [options] [root]`

**Format:** `markbind serve [options] [root]`<br>
**Alias:** `markbind s`

**Description:** Does the following steps:
Expand All @@ -64,33 +73,55 @@ Usage: markbind <command>

**Arguments:**
* `[root]`<br>
Root directory. Default is the current directory.<br>
Root directory. The default is the directory where this command was executed.<br>
{{ icon_example }} `./myWebsite`

**`options`:**
* `-f`, `--force-reload`<br>
Force live reload to process all files in the site, instead of just the relevant files. This option is useful when you are modifying a file that is not a file type monitored by the <trigger trigger="click" for="modal:cliCommands-livePreview">live preview</trigger> feature.
* `-n`, `--no-open`<br>
Don't open a live preview in the browser automatically.
<panel header="**Options** :fas-cogs:" type="minimal">

**Options** :fas-cogs:

* `-o <file>`, `--one-page <file>`<br>
Render and serve only a single page from your website.<br>
{{ icon_example }} `--one-page guide/index.md`
* `-p <port>`, `--port <port>`<br>
Serve the website in the specified port.
Serves only a single page from your website **initially**. If `<file>` is not specified, it defaults to `index.md/mbf/mbdf`.<br>
* Thereafter, when changes to source files have been made, only the page being viewed will be rebuilt if it was affected.<br>
* Navigating to a new page will build the new page, if it has not been built before, or there were some changes to source files that affected it before navigating to it.<br>
* {{ icon_example }} `--one-page guide/index.md`

<box type="info" light header="Caveats" style="width: calc(100% - 50px); position: relative; left: 40px;">

Essentially, this optional feature is very useful when writing content, more so if your build times are starting to slow down!

The caveat is that not building all pages during the initial process, or not rebuilding all affected pages when a file changes, will cause your search results for these pages to be empty or outdated, until you navigate to them to trigger a rebuild.
</box>


* `-s <file>`, `--site-config <file>`<br>
Specify the site config file (default: `site.json`)<br>
{{ icon_example }} `-s otherSite.json`

* `-n`, `--no-open`<br>
Don't open a live preview in the browser automatically.

* `-f`, `--force-reload`<br>
Force live reload to process all files in the site, instead of just the relevant files. This option is useful when you are modifying a file that is not a file type monitored by the <trigger trigger="click" for="modal:cliCommands-livePreview">live preview</trigger> feature.

* `-p <port>`, `--port <port>`<br>
Serve the website in the specified port.


{{ icon_examples }}
* `markbind serve`
* `markbind serve ./myWebsite`
* `markbind serve -p 8888 -s otherSite.json`

</panel>

<hr><!-- ========================================================================== -->

### `build` Command
<br>

**Format:** `markbind build [options] [root] [output]`

**Format:** `markbind build [options] [root] [output]`<br>
**Alias:** `markbind b`

**Description:** Generates the site to the directory named `_site` in the current directory.
Expand All @@ -99,14 +130,19 @@ Usage: markbind <command>
* `[output]`<br>
Put the generated files in the specified directory<br>
{{ icon_example }} `../myOutDir`

* `[root] [output]`<br>
Read source files from the `[root]` directory and put the generated files in the specified `[output]` directory<br>
{{ icon_example }} `./myWebsite ../myOutDir`

**`options`:**
<panel header="**Options** :fas-cogs:" type="minimal">

**Options** :fas-cogs:

* `--baseUrl <base>`<br>
Override the `baseUrl` property (read from the `site.json`) with the give `<base>` value.<br>
{{ icon_example }} `--baseUrl staging`

* `-s <file>`, `--site-config <file>`<br>
Specify the site config file (default: `site.json`)<br>
{{ icon_example }} `-s otherSite.json`
Expand All @@ -116,27 +152,38 @@ Usage: markbind <command>
* `markbind build ./myWebsite ./myOutDir`
* `markbind build ./stagingDir --baseUrl staging`

</panel>

<hr><!-- ========================================================================== -->

### `deploy` Command
<br>

**Format:** `markbind deploy [options]`

**Format:** `markbind deploy [options]`<br>
**Alias:** `markbind d`

**Description:** Deploys the site to the repo's Github pages by pushing everything in the generated site (default dir: `_site`) to the `gh-pages` branch of the current git working directory's remote repo.

**`options`:**
<panel header="**Options** :fas-cogs:" type="minimal">

**Options** :fas-cogs:

* `-t <githubTokenName>`, `--travis <githubTokenName>`<br>
Deploy the site in Travis CI using the GitHub personal access token stored in `<githubTokenName>`. (default: `GITHUB_TOKEN`)<br>
{{ icon_example }} `-t PA_TOKEN`

%%{{ icon_info }} Related: [User Guide: Deploying the Website](deployingTheSite.html).%%

</panel>

<hr><!-- ========================================================================== -->

### `--help` Option
<br>

**Format:** `markbind [command] --help`

**Format:** `markbind [command] --help`<br>
**Alias:** `markbind [command] -h`

**Description:** Prints a summary of MarkBind commands or a detailed usage guide for the given `command`.
Expand Down
49 changes: 41 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const Site = require('./src/Site');
const {
ACCEPTED_COMMANDS,
ACCEPTED_COMMANDS_ALIAS,
INDEX_MARKDOWN_FILE,
LAZY_LOADING_SITE_FILE_NAME,
} = require('./src/constants');
const CLI_VERSION = require('./package.json').version;

Expand Down Expand Up @@ -95,26 +97,30 @@ program
.description('build then serve a website from a directory')
.option('-f, --force-reload', 'force a full reload of all site files when a file is changed')
.option('-n, --no-open', 'do not automatically open the site in browser')
.option('-o, --one-page <file>', 'render and serve only a single page in the site')
.option('-o, --one-page [file]', 'build and serve only a single page in the site initially,'
+ 'building more pages when they are navigated to. Also lazily rebuilds only the page being viewed when'
+ 'there are changes to the source files (if needed), building others when navigated to')
.option('-p, --port <port>', 'port for server to listen on (Default is 8080)')
.option('-s, --site-config <file>', 'specify the site config file (default: site.json)')
.action((userSpecifiedRoot, options) => {
let rootFolder;
try {
rootFolder = cliUtil.findRootFolder(userSpecifiedRoot, options.siteConfig);

if (options.forceReload && options.onePage) {
handleError(new Error('Oops! You shouldn\'t need to use the --force-reload option with --one-page.'));
process.exit();
}
} catch (err) {
handleError(err);
}
const logsFolder = path.join(rootFolder, '_markbind/logs');
const outputFolder = path.join(rootFolder, '_site');

if (options.onePage) {
// replace slashes for paths on Windows
// eslint-disable-next-line no-param-reassign
options.onePage = ensurePosix(options.onePage);
}
let onePagePath = options.onePage === true ? INDEX_MARKDOWN_FILE : options.onePage;
onePagePath = onePagePath ? ensurePosix(onePagePath) : onePagePath;

const site = new Site(rootFolder, outputFolder, options.onePage, options.forceReload, options.siteConfig);
const site = new Site(rootFolder, outputFolder, onePagePath, options.forceReload, options.siteConfig);

const addHandler = (filePath) => {
logger.info(`[${new Date().toLocaleTimeString()}] Reload for file add: ${filePath}`);
Expand Down Expand Up @@ -152,12 +158,15 @@ program
});
};

const onePageHtmlUrl = onePagePath && `/${onePagePath.replace(/\.(md|mbd|mbdf)$/, '.html')}`;

// server config
const serverConfig = {
open: options.open && (options.onePage ? `/${options.onePage.replace(/\.(md|mbd)$/, '.html')}` : true),
open: options.open && (onePageHtmlUrl || true),
logLevel: 0,
root: outputFolder,
port: options.port || 8080,
middleware: [],
mount: [],
};

Expand All @@ -167,6 +176,30 @@ program
.readSiteConfig()
.then((config) => {
serverConfig.mount.push([config.baseUrl || '/', outputFolder]);

if (onePagePath) {
const lazyReloadMiddleware = function (req, res, next) {
const isHtmlFile = req.url.endsWith('.html');

if (isHtmlFile) {
const isDynamicIncludeHtmlFile = req.url.endsWith('._include_.html');

if (!isDynamicIncludeHtmlFile) {
const urlWithoutBaseUrl = req.url.replace(config.baseUrl, '');
const urlWithoutExtension = fsUtil.removeExtension(urlWithoutBaseUrl);

const didInitiateRebuild = site.changeCurrentPage(urlWithoutExtension);
if (didInitiateRebuild) {
req.url = ensurePosix(path.join(config.baseUrl || '/', LAZY_LOADING_SITE_FILE_NAME));
}
}
}
next();
};

serverConfig.middleware.push(lazyReloadMiddleware);
}

return site.generate();
})
.then(() => {
Expand Down
66 changes: 66 additions & 0 deletions src/LazyLiveReloadLoadingSite.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Building ...</title>
</head>
<body>
<div id="loading-spinner"></div>
<div id="loading-text">... building your page ...</div>
</body>

<style>
body {
height: 90vh;
display: flex;
justify-content: center;
align-items: center;
}

#loading-spinner {
height: 50px;
width: 50px;
border-width: 5px;
border-color: #00b0f0 lightgrey;
border-style: solid;
border-radius: 50%;
animation-name: loading-spinner;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}

#loading-text {
position: absolute;
bottom: 20px;
color: #9b9b9b;
font-size: 1.2rem;
font-family: sans-serif;
animation-name: loading-text;
animation-duration: 1.5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}

@keyframes loading-spinner {
0% {
opacity: 0.5;
}

50% {
opacity: 1;
}

100% {
opacity: 0.5;
transform: rotate(360deg);
}
}

@keyframes loading-text {
50% {
transform: translateY(-3px);
}
}
</style>
</html>
Loading