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
15 changes: 7 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@


// Entry file for Markbind project
const chokidar = require('chokidar');
const clear = require('clear');
const fs = require('fs-extra-promise');
const path = require('path');
const Promise = require('bluebird');
const program = require('commander');
const htmlBeautify = require('js-beautify').html;
const liveServer = require('live-server');
const chokidar = require('chokidar');
const path = require('path');
const program = require('commander');
const Promise = require('bluebird');

const _ = {};
_.isBoolean = require('lodash/isBoolean');

const logger = require('./lib/util/logger');
const fsUtil = require('./lib/util/fsUtil');
const Site = require('./lib/Site');
const logger = require('./lib/util/logger');
const MarkBind = require('./lib/markbind/lib/parser');

const CLI_VERSION = require('./package.json').version;
const Site = require('./lib/Site');

const ACCEPTED_COMMANDS = ['version', 'include', 'render', 'init', 'build', 'serve', 'deploy'];
const CLI_VERSION = require('./package.json').version;

const markbinder = new MarkBind();

Expand Down
40 changes: 21 additions & 19 deletions lib/Page.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const cheerio = require('cheerio');
const fm = require('fastmatter');
const fs = require('fs-extra-promise');
const htmlBeautify = require('js-beautify').html;
const nunjucks = require('nunjucks');
const fs = require('fs-extra-promise');
const path = require('path');
const Promise = require('bluebird');
const logger = require('./util/logger');
const FsUtil = require('./util/fsUtil');
const pathIsInside = require('path-is-inside');
const cheerio = require('cheerio');
const fm = require('fastmatter');
const Promise = require('bluebird');

const FsUtil = require('./util/fsUtil');
const logger = require('./util/logger');
const MarkBind = require('./markbind/lib/parser');

const FRONT_MATTER_FENCE = '---';
Expand All @@ -18,31 +18,33 @@ cheerio.prototype.options.xmlMode = true; // Enable xml mode for self-closing ta
cheerio.prototype.options.decodeEntities = false; // Don't escape HTML entities

function Page(pageConfig) {
this.asset = pageConfig.asset;
this.baseUrl = pageConfig.baseUrl;
this.baseUrlMap = pageConfig.baseUrlMap;
this.content = pageConfig.content || '';
this.title = pageConfig.title || '';
this.rootPath = pageConfig.rootPath;
this.src = pageConfig.src;
this.template = pageConfig.pageTemplate;
this.title = pageConfig.title || '';
this.titlePrefix = pageConfig.titlePrefix;
this.userDefinedVariablesMap = pageConfig.userDefinedVariablesMap;

// the source file for rendering this page
this.sourcePath = pageConfig.sourcePath;
// the temp path for writing intermediate result
this.tempPath = pageConfig.tempPath;
// the output path of this page
this.resultPath = pageConfig.resultPath;
this.template = pageConfig.pageTemplate;
this.baseUrl = pageConfig.baseUrl;
this.asset = pageConfig.asset;
this.baseUrlMap = pageConfig.baseUrlMap;
this.userDefinedVariablesMap = pageConfig.userDefinedVariablesMap;
this.src = pageConfig.src;
this.titlePrefix = pageConfig.titlePrefix;
this.includedFiles = {};

this.frontMatter = {};
this.includedFiles = {};
}

/**
* Util Methods
*/

function baseUrlFromRoot(filePath, root, lookUp) {
function calculateNewBaseUrl(filePath, root, lookUp) {
function calculate(file, result) {
if (file === root || !pathIsInside(file, root)) {
return undefined;
Expand All @@ -65,10 +67,10 @@ function unique(array) {

Page.prototype.prepareTemplateData = function () {
return {
asset: this.asset,
baseUrl: this.baseUrl,
content: this.content,
title: this.title,
asset: this.asset,
};
};

Expand Down Expand Up @@ -156,7 +158,7 @@ Page.prototype.generate = function (builtFiles) {
.then((result) => {
this.content = htmlBeautify(result, { indent_size: 2 });

const newBaseUrl = baseUrlFromRoot(this.sourcePath, this.rootPath, this.baseUrlMap);
const newBaseUrl = calculateNewBaseUrl(this.sourcePath, this.rootPath, this.baseUrlMap);
const baseUrl = newBaseUrl ? `${this.baseUrl}/${newBaseUrl}` : this.baseUrl;
const hostBaseUrl = this.baseUrl;

Expand Down Expand Up @@ -238,7 +240,7 @@ Page.prototype.resolveDependency = function (dependency, builtFiles) {
}))
.then((result) => {
// resolve the site base url here
const newBaseUrl = baseUrlFromRoot(file, this.rootPath, this.baseUrlMap);
const newBaseUrl = calculateNewBaseUrl(file, this.rootPath, this.baseUrlMap);
const baseUrl = newBaseUrl ? `${this.baseUrl}/${newBaseUrl}` : this.baseUrl;
const hostBaseUrl = this.baseUrl;

Expand Down
41 changes: 21 additions & 20 deletions lib/Site.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
/* eslint-disable no-underscore-dangle */

const cheerio = require('cheerio');
const delay = require('./util/delay');
const path = require('path');
const ignore = require('ignore');
const ejs = require('ejs');
const fs = require('fs-extra-promise');
const walkSync = require('walk-sync');
const Promise = require('bluebird');
const ghpages = require('gh-pages');
const logger = require('./util/logger');
const ignore = require('ignore');
const path = require('path');
const Promise = require('bluebird');
const walkSync = require('walk-sync');

const _ = {};
_.unionWith = require('lodash/unionWith');
_.uniq = require('lodash/uniq');

const delay = require('./util/delay');
const logger = require('./util/logger');
const Page = require('./Page');

const TEMP_FOLDER_NAME = '.temp';
const SITE_CONFIG_NAME = 'site.json';
const SITE_DATA_NAME = 'siteData.json';
const INDEX_MARKDOWN_FILE = 'index.md';
const PAGE_TEMPLATE_NAME = 'page.ejs';
const BOILERPLATE_FOLDER_NAME = '_markbind/boilerplates';
const SITE_ASSET_FOLDER_NAME = 'asset';
const TEMP_FOLDER_NAME = '.temp';
const TEMPLATE_ROOT_FOLDER_NAME = 'template';
const TEMPLATE_SITE_ASSET_FOLDER_NAME = 'markbind';

const INDEX_MARKDOWN_FILE = 'index.md';
const PAGE_TEMPLATE_NAME = 'page.ejs';
const SITE_CONFIG_NAME = 'site.json';
const SITE_DATA_NAME = 'siteData.json';
const USER_VARIABLES_PATH = '_markbind/variables.md';

const SITE_CONFIG_DEFAULT = {
Expand Down Expand Up @@ -183,31 +184,31 @@ Site.prototype.createPageData = function (config) {
const tempPath = path.join(this.tempPath, config.pageSrc);
const resultPath = path.join(this.outputPath, setExtension(config.pageSrc, '.html'));
return new Page({
baseUrl: config.baseUrl,
baseUrlMap: this.baseUrlMap,
content: '',
title: config.title || '',
pageTemplate: config.pageTemplate,
rootPath: this.rootPath,
src: config.pageSrc,
title: config.title || '',
titlePrefix: config.titlePrefix,
userDefinedVariablesMap: this.userDefinedVariablesMap,
sourcePath,
tempPath,
resultPath,
baseUrl: config.baseUrl,
pageTemplate: config.pageTemplate,
baseUrlMap: this.baseUrlMap,
userDefinedVariablesMap: this.userDefinedVariablesMap,
src: config.pageSrc,
titlePrefix: config.titlePrefix,
asset: {
bootstrap: path.relative(path.dirname(resultPath),
path.join(this.siteAssetsDestPath, 'css', 'bootstrap.min.css')),
highlight: path.relative(path.dirname(resultPath),
path.join(this.siteAssetsDestPath, 'css', 'github.min.css')),
markbind: path.relative(path.dirname(resultPath),
path.join(this.siteAssetsDestPath, 'css', 'markbind.css')),
setup: path.relative(path.dirname(resultPath),
path.join(this.siteAssetsDestPath, 'js', 'setup.js')),
vue: path.relative(path.dirname(resultPath),
path.join(this.siteAssetsDestPath, 'js', 'vue.min.js')),
vueStrap: path.relative(path.dirname(resultPath),
path.join(this.siteAssetsDestPath, 'js', 'vue-strap.min.js')),
setup: path.relative(path.dirname(resultPath),
path.join(this.siteAssetsDestPath, 'js', 'setup.js')),
},
});
};
Expand Down
45 changes: 21 additions & 24 deletions lib/markbind/lib/parser.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/* eslint-disable no-underscore-dangle */

const cheerio = require('cheerio');
const fs = require('fs');
const htmlparser = require('htmlparser2');
const md = require('./markdown-it');
const nunjucks = require('nunjucks');
const path = require('path');
const pathIsInside = require('path-is-inside');
const Promise = require('bluebird');
const url = require('url');

const _ = {};
_.clone = require('lodash/clone');
Expand All @@ -11,21 +17,12 @@ _.isArray = require('lodash/isArray');
_.isEmpty = require('lodash/isEmpty');
_.pick = require('lodash/pick');

const Promise = require('bluebird');

const cheerio = require('cheerio');
const md = require('./markdown-it');
const utils = require('./utils');

cheerio.prototype.options.xmlMode = true; // Enable xml mode for self-closing tag
cheerio.prototype.options.decodeEntities = false; // Don't escape HTML entities

const utils = require('./utils');

const fs = require('fs');
const path = require('path');
const pathIsInside = require('path-is-inside');
const url = require('url');
const nunjucks = require('nunjucks');

const ATTRIB_INCLUDE_PATH = 'include-path';
const ATTRIB_CWF = 'cwf';

Expand All @@ -38,9 +35,9 @@ const BOILERPLATE_FOLDER_NAME = '_markbind/boilerplates';
/**
* @throws Will throw an error if a non-absolute path or path outside the root is given
*/
function calculateNewBaseUrl(filePath, root, lookUp) {
function calculateNewBaseUrls(filePath, root, lookUp) {
if (!path.isAbsolute(filePath)) {
throw new Error(`Non-absolute path given to calculateNewBaseUrl: '${filePath}'`);
throw new Error(`Non-absolute path given to calculateNewBaseUrls: '${filePath}'`);
}
if (!pathIsInside(filePath, root)) {
throw new Error(`Path given '${filePath}' is not in root '${root}'`);
Expand All @@ -62,8 +59,8 @@ function calculateNewBaseUrl(filePath, root, lookUp) {
}

function calculateBoilerplateFilePath(pathInBoilerplates, asIfAt, config) {
const fileBase = calculateNewBaseUrl(asIfAt, config.rootPath, config.baseUrlMap).relative;
return path.resolve(fileBase, BOILERPLATE_FOLDER_NAME, pathInBoilerplates);
const fileBase = calculateNewBaseUrls(asIfAt, config.rootPath, config.baseUrlMap);
return path.resolve(fileBase.relative, BOILERPLATE_FOLDER_NAME, pathInBoilerplates);
}

function createErrorNode(element, error) {
Expand Down Expand Up @@ -186,8 +183,8 @@ Parser.prototype._preprocess = function (node, context, config) {
}

let fileContent = self._fileCache[actualFilePath]; // cache the file contents to save some I/O
const fileBase = path.resolve(calculateNewBaseUrl(filePath, config.rootPath, config.baseUrlMap).relative);
const userDefinedVariables = config.userDefinedVariablesMap[fileBase];
const fileBase = calculateNewBaseUrls(filePath, config.rootPath, config.baseUrlMap);
const userDefinedVariables = config.userDefinedVariablesMap[path.resolve(fileBase.relative)];
fileContent = nunjucks.renderString(fileContent, userDefinedVariables);
delete element.attribs.boilerplate;
delete element.attribs.src;
Expand Down Expand Up @@ -408,8 +405,8 @@ Parser.prototype.includeFile = function (file, config) {
reject(err);
return;
}
const fileBase = path.resolve(calculateNewBaseUrl(file, config.rootPath, config.baseUrlMap).relative);
const userDefinedVariables = config.userDefinedVariablesMap[fileBase];
const fileBase = calculateNewBaseUrls(file, config.rootPath, config.baseUrlMap);
const userDefinedVariables = config.userDefinedVariablesMap[path.resolve(fileBase.relative)];
const fileContent = nunjucks.renderString(data, userDefinedVariables);
const fileExt = utils.getExtName(file);
if (fileExt === 'md') {
Expand Down Expand Up @@ -540,7 +537,7 @@ Parser.prototype._rebaseReference = function (node, foundBase) {
// rebase current element
if (element.attribs[ATTRIB_CWF]) {
const filePath = element.attribs[ATTRIB_CWF];
let newBase = calculateNewBaseUrl(filePath, this.rootPath, this.baseUrlMap);
let newBase = calculateNewBaseUrls(filePath, this.rootPath, this.baseUrlMap);
if (newBase) {
const { relative, parent } = newBase;
// eslint-disable-next-line no-param-reassign
Expand All @@ -553,7 +550,7 @@ Parser.prototype._rebaseReference = function (node, foundBase) {
newBase = childrenBase[bases[0]];
const { children } = element;
if (children) {
const currentBase = calculateNewBaseUrl(element.attribs[ATTRIB_CWF], this.rootPath, this.baseUrlMap);
const currentBase = calculateNewBaseUrls(element.attribs[ATTRIB_CWF], this.rootPath, this.baseUrlMap);
if (currentBase) {
if (currentBase.relative !== newBase) {
cheerio.prototype.options.xmlMode = false;
Expand Down Expand Up @@ -581,13 +578,13 @@ Parser.prototype._rebaseReferenceForStaticIncludes = function (pageData, element
}

const filePath = element.attribs[ATTRIB_INCLUDE_PATH];
const fileBase = calculateNewBaseUrl(filePath, config.rootPath, config.baseUrlMap);
const fileBase = calculateNewBaseUrls(filePath, config.rootPath, config.baseUrlMap);
if (!fileBase.relative) {
return pageData;
}

const currentPath = element.attribs[ATTRIB_CWF];
const currentBase = calculateNewBaseUrl(currentPath, config.rootPath, config.baseUrlMap);
const currentBase = calculateNewBaseUrls(currentPath, config.rootPath, config.baseUrlMap);
if (currentBase.relative === fileBase.relative) {
return pageData;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/util/delay.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const Promise = require('bluebird');
module.exports = function delay(func, wait) {
let context;
let pendingArgs = [];
let waitingPromise = null;
let runningPromise = Promise.resolve();
let waitingPromise = null;

return function (arg) {
context = this;
Expand Down
22 changes: 11 additions & 11 deletions lib/util/fsUtil.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
const path = require('path');

module.exports = {
isHtml: filePath => path.extname(filePath) === '.html',
isMarkdown: filePath => path.extname(filePath) === '.md',
isSourceFile(filePath) {
return this.isMarkdown(filePath) || this.isHtml(filePath);
},

isInRoot: (root, fileName) => {
let normalizedRoot = path.normalize(root);
const normalizedFilename = path.normalize(fileName);
if (normalizedRoot === '.') {
return true;
}
if (normalizedRoot[normalizedRoot.length - 1] !== path.sep) {
normalizedRoot += path.sep;
}
const normalizedFilename = path.normalize(fileName);
return (normalizedFilename.substr(0, normalizedRoot.length) === normalizedRoot);
},

setExtension: (normalizedFilename, ext) => path.join(
path.dirname(normalizedFilename),
path.basename(normalizedFilename, path.extname(normalizedFilename)) + ext,
),

isUrl: (unknownPath) => {
const r = new RegExp('^(?:[a-z]+:)?//', 'i');
return r.test(unknownPath);
},

isMarkdown: filePath => path.extname(filePath) === '.md',
isHtml: filePath => path.extname(filePath) === '.html',
isSourceFile(filePath) {
return this.isMarkdown(filePath) || this.isHtml(filePath);
},
setExtension: (normalizedFilename, ext) => path.join(
path.dirname(normalizedFilename),
path.basename(normalizedFilename, path.extname(normalizedFilename)) + ext,
),
};
Loading