Permalink
Browse files

Feature : Render static dir (#224)

  • Loading branch information...
skad authored and webpro committed Dec 6, 2018
1 parent e2704b8 commit 8cc524f3fcac4b04be365b328891e9a108e8b5de
Showing with 83 additions and 26 deletions.
  1. +1 −0 .gitignore
  2. +7 −5 lib/options.js
  3. +19 −11 lib/render.js
  4. +53 −7 lib/static.js
  5. +1 −1 lib/template/listing.html
  6. +1 −1 lib/template/reveal.html
  7. +1 −1 test/render.spec.js
@@ -2,3 +2,4 @@ node_modules
.idea
dist
_static
.vscode
@@ -65,7 +65,6 @@ try {
}
debug('revealOptions %O', revealOptions);

defaults.base = '';
defaults.revealBasePath = path.resolve(require.resolve('reveal.js'), '..', '..');
defaults.highlightThemePath = path.resolve(require.resolve('highlight.js'), '..', '..', 'styles');
defaults.templatePath = path.join(__dirname, defaults.template);
@@ -90,10 +89,13 @@ const setArgOptions = options => {
config.args = parseOptions(_.pick(options, optionList));
config.args.initialPath = options.args[0] || '.';
const { initialPath } = config.args;
config.args.initialDir = isDirSync(initialPath) ? initialPath : path.dirname(initialPath);
config.args.initialDir = getInitalDir(initialPath);
return _.defaults({}, config.args, config.local, config.defaults);
};

function getInitalDir(initialPath) {
return isDirSync(initialPath) ? initialPath : path.dirname(initialPath);
}
function getOptions() {
return _.defaults({}, config.args, config.local, config.defaults);
}
@@ -107,13 +109,12 @@ function getSlideOptions(yamlOptions, extraOptions) {
config.local,
config.defaults
);
options.themeUrl = (options.base + '/' + options.themeUrl).replace(/^\.\/http/, 'http');
options.themeUrl = options.themeUrl.replace(/^\.\/http/, 'http');
return options;
}

function parseOptions(options) {
if (options.static) {
options.base = '.';
const staticPath = options.static === true ? '_static' : options.static;
options.staticDir = path.resolve(process.cwd(), staticPath);
}
@@ -175,5 +176,6 @@ function parseTheme(options) {
module.exports = {
setArgOptions,
getOptions,
getSlideOptions
getSlideOptions,
getInitalDir
};
@@ -40,6 +40,19 @@ function render(markdown, extraOptions = {}) {
});
}

function renderListFile(files, extraOptions = {}) {
const list = files.map(
filePath => `<a href="${filePath}` + (extraOptions.static ? '/index.html' : '') + `">${filePath}</a>`
);

return Mustache.to_html(extraOptions.templateListing(), {
base: extraOptions.base,
themeUrl: extraOptions.themeUrl,
title: extraOptions.title,
listing: list.join('<br>')
});
}

function renderMarkdown(req, res) {
const location = req.url.replace(/^\//, '');
const parsedUrl = url.parse(location, true, true);
@@ -61,24 +74,19 @@ function renderMarkdown(req, res) {

function renderMarkdownFileListing(req, res) {
const options = getOptions();
const list = glob
.sync('**/*.md', {
cwd: options.initialDir,
ignore: 'node_modules/**'
})
.map(filePath => `<a href="${filePath}">${filePath}</a>`);

const markup = Mustache.to_html(options.templateListing(), {
themeUrl: options.themeUrl,
title: options.title,
listing: list.join('<br>')
const list = glob.sync('**/*.md', {
cwd: options.initialDir,
ignore: 'node_modules/**'
});

const markup = renderListFile(list, options);

res.send(markup);
}

module.exports = {
render,
renderListFile,
renderMarkdown,
renderMarkdownFileListing,
parseSlides,
@@ -1,10 +1,15 @@
'use strict';

const bluebird = require('bluebird');
const fs = require('fs-extra');
const path = require('path');
var glob = require('glob');
bluebird.promisifyAll(glob);
const url = require('url');
const render = require('./render').render;
const render = require('./render');
const featuredSlide = require('./featured-slide');
const imageDataURI = require('image-data-uri');
const Options = require('./options');
const _ = require('lodash');

const mdImageRE = /!\[([^\]]*)\]\(([^)]+)\)/gi;
@@ -46,18 +51,59 @@ module.exports = function renderStaticMarkup(options) {

const staticDirs = typeof options.staticDirs === 'string' ? options.staticDirs.split(',') : options.staticDirs;
const extraDirs = staticDirs.map(dir => fs.copyAsync(path.join(process.cwd(), dir), path.join(staticDir, dir)));

awaits.push.apply(awaits, extraDirs);

const parseSlideAwait = fs.readFileAsync(options.initialPath).then(markdown => markdown.toString());
if (fs.lstatSync(options.initialPath).isDirectory()) {
const list = glob.GlobAsync('**/*.md', {
cwd: options.initialDir,
ignore: ['node_modules/**', staticDir + '/**']
});

const listmarkAwait = list
.then(list => {
options.base = '.';
return render.renderListFile(list, options);
})
.then(html => fs.outputFileAsync(path.join(staticDir, 'index.html'), html));

const markupAwait = parseSlideAwait
.then(markdown => embedImages(markdown, options))
.then(markdown => render(markdown))
.then(markdown => fs.outputFileAsync(path.join(staticDir, 'index.html'), markdown));
awaits.push(listmarkAwait);

list.then(list =>
list.map(markdown => awaitPushMarkdownPage(path.join(options.initialPath, markdown), options, markdown))
);
} else {
awaitPushMarkdownPage(options.initialPath, options);
}

function awaitPushMarkdownPage(file, options, subdir = null) {
const parseSlideAwait = fs.readFileAsync(file).then(markdown => markdown.toString());
const markupAwait = parseSlideAwait
.then(markdown => {
options.initialDir = Options.getInitalDir(file);
return embedImages(markdown, options);
})
.then(markdown => {
if (subdir != null) {
options.base = subdir
.split('/')
.map(v => {
return '..';
})
.join('/');
} else {
options.base = '.';
}
return render.render(markdown, options);
})
.then(markdown =>
fs.outputFileAsync(path.join(staticDir + (subdir != null ? '/' + subdir : ''), 'index.html'), markdown)
);
awaits.push(markupAwait);
}

const highlightAwait = fs.copyAsync(options.highlightThemePath, path.join(staticDir, 'css', 'highlight'));

awaits.push(markupAwait);
awaits.push(highlightAwait);

if (!_.isEmpty(options.scripts)) {
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<title>Directory Listing</title>
<link rel="stylesheet" href="/{{{themeUrl}}}" id="theme">
<link rel="stylesheet" href="{{{base}}}/{{{themeUrl}}}" id="theme">
<style type="text/css">
body {
margin: 1em;
@@ -12,7 +12,7 @@
<meta property="og:url" content="{{{absoluteUrl}}}">
{{/absoluteUrl}}
<link rel="stylesheet" href="{{{base}}}/css/reveal.css">
<link rel="stylesheet" href="{{{themeUrl}}}" id="theme">
<link rel="stylesheet" href="{{{base}}}/{{{themeUrl}}}" id="theme">
<link rel="stylesheet" href="{{{base}}}{{{highlightThemeUrl}}}">
<link rel="stylesheet" href="{{{base}}}/css/print/{{#print}}pdf{{/print}}{{^print}}paper{{/print}}.css" type="text/css" media="print">
{{#cssPaths}}
@@ -61,7 +61,7 @@ describe('render', () => {
});

it('should render root-based domain-less links for static markup', () => {
return render.render('', { static: true }).then(actual => {
return render.render('', { static: true, base: '.' }).then(actual => {
expect(actual.match(/href="\.\//g).length).toBe(4);
expect(actual.match(/src="\.\//g).length).toBe(2);
expect(actual.match(/src:\ '\.\//g).length).toBe(7);

0 comments on commit 8cc524f

Please sign in to comment.