-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from jaredwray/making-helper-md-native-to-fuma…
…nchu Making helper md native to fumanchu
- Loading branch information
Showing
10 changed files
with
291 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/*! | ||
* helper-markdown <https://github.com/jonschlinkert/helper-markdown> | ||
* | ||
* Copyright (c) 2014 Jon Schlinkert, contributors. | ||
* Licensed under the MIT license. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
var fs = require('fs'); | ||
var path = require('path'); | ||
const { Remarkable } = require('remarkable'); | ||
var extend = require('extend-shallow'); | ||
var exists = require('fs-exists-sync'); | ||
var ent = require('ent'); | ||
|
||
/** | ||
* Expose `md` helper | ||
*/ | ||
|
||
var helper = module.exports = function(name, options, cb) { | ||
if (typeof options === 'function') { | ||
cb = options; | ||
options = {}; | ||
} | ||
|
||
if (typeof cb !== 'function') { | ||
return helper.sync.apply(this, arguments); | ||
} | ||
|
||
/* c8 ignore next 3 */ | ||
if (typeof this === 'undefined' || typeof this.app === 'undefined') { | ||
throw new Error('md async helper expects `app` to be exposed on the context'); | ||
} | ||
|
||
var opts = extend({cwd: process.cwd()}, this.options, options); | ||
opts = extend({}, opts, opts.hash); | ||
var md = markdown(opts); | ||
|
||
var filepath = path.resolve(opts.cwd, name); | ||
var view; | ||
var str = ''; | ||
|
||
if (exists(filepath)) { | ||
// create a collection to ensure middleware is consistent | ||
this.app.create('mdfiles'); | ||
str = fs.readFileSync(filepath, 'utf8'); | ||
view = this.app.mdfile(filepath, {path: filepath, content: str}); | ||
} else { | ||
view = this.app.find(name); | ||
} | ||
/* c8 ignore next 4 */ | ||
if (typeof view === 'undefined') { | ||
cb(null, ''); | ||
return; | ||
} | ||
|
||
view.content = ent.decode(md.render(view.content)); | ||
this.app.render(view, this.context, function(err, res) { | ||
if (err) return cb(err); | ||
cb(null, res.content); | ||
}); | ||
}; | ||
|
||
helper.sync = function(name, options) { | ||
var ctx = this || {}; | ||
var app = ctx.app || {}; | ||
|
||
var opts = extend({cwd: process.cwd()}, ctx.options, options); | ||
opts = extend({}, opts, opts.hash); | ||
var md = markdown(opts); | ||
|
||
var filepath = path.resolve(opts.cwd, name); | ||
var view; | ||
var html = ''; | ||
var str = ''; | ||
|
||
if (exists(filepath)) { | ||
str = fs.readFileSync(filepath, 'utf8'); | ||
html = ent.decode(md.render(str)); | ||
} else if (app.views) { | ||
view = app.find(name); | ||
if (view) { | ||
html = view.content = ent.decode(md.render(view.content)); | ||
} | ||
} | ||
|
||
if (view && typeof view.compile === 'function') { | ||
view.compile(opts); | ||
var data = ctx.cache ? ctx.cache.data : {}; | ||
ctx = extend({}, data, view.data); | ||
return view.fn(ctx); | ||
} | ||
|
||
if (typeof this.compile === 'function') { | ||
var fn = this.compile(html); | ||
return fn(this); | ||
} | ||
return html; | ||
}; | ||
|
||
/** | ||
* Shared settings for remarkable | ||
* | ||
* @param {Object} `options` | ||
* @return {Object} | ||
* @api private | ||
*/ | ||
|
||
function markdown(options) { | ||
let optsConfig = options || {}; | ||
optsConfig.breaks = true; | ||
optsConfig.html = true; | ||
optsConfig.langPrefix = 'lang-'; | ||
optsConfig.typographer = false; | ||
optsConfig.xhtmlOut = false; | ||
const md = new Remarkable(optsConfig); | ||
return md; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# AAA | ||
|
||
> this is aaa |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# BBB | ||
|
||
> this is bbb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# CCC | ||
|
||
This is {{name}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# DDD | ||
|
||
This is <%= name %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# EEE | ||
|
||
``` | ||
var message = 'This is an alert'; | ||
alert(message); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
/*! | ||
* helper-md <https://github.com/jonschlinkert/helper-md> | ||
* | ||
* Copyright (c) 2014 Jon Schlinkert, contributors. | ||
* Licensed under the MIT License | ||
*/ | ||
|
||
'use strict'; | ||
|
||
require('mocha'); | ||
var assert = require('assert'); | ||
var handlebars = require('handlebars'); | ||
var Templates = require('templates'); | ||
var hljs = require('highlight.js'); | ||
var md = require('../lib/md.js'); | ||
var _ = require('lodash'); | ||
var app; | ||
|
||
describe('sync', function() { | ||
beforeEach(function() { | ||
app = new Templates(); | ||
|
||
app.helper('md', md.sync); | ||
app.engine('md', require('engine-base')); | ||
app.option('engine', 'md'); | ||
|
||
app.create('page'); | ||
app.create('partial', {viewType: ['partial']}); | ||
app.create('include', {viewType: ['partial']}); | ||
|
||
app.include('one', {content: '# heading <%= name %>', data: {name: 'one'}}); | ||
app.partial('two', {content: '# heading <%= name %>', data: {name: 'two'}}); | ||
}); | ||
|
||
it('should convert markdown on the `content` property of a template to HTML:', function(cb) { | ||
app.page('home.md', {content: '<%= md("one") %>'}); | ||
|
||
app.render('home.md', function(err, view) { | ||
if (err) return cb(err); | ||
assert.equal(view.content, '<h1>heading one</h1>\n'); | ||
cb(); | ||
}); | ||
}); | ||
|
||
it('should support rendering markdown from a file:', function() { | ||
assert.equal(md.sync('test/fixtures/a.md'), '<h1>AAA</h1>\n<blockquote>\n<p>this is aaa</p>\n</blockquote>\n'); | ||
}); | ||
|
||
describe('handlebars:', function() { | ||
it('should support rendering markdown from a file:', function() { | ||
handlebars.registerHelper('md', md.sync); | ||
assert.equal(handlebars.compile('{{{md "test/fixtures/a.md"}}}')(), '<h1>AAA</h1>\n<blockquote>\n<p>this is aaa</p>\n</blockquote>\n'); | ||
}); | ||
|
||
it('should use the `render` function passed on the locals to render templates in partials :', function() { | ||
handlebars.registerHelper('md', md.sync); | ||
var locals = {name: 'CCC', compile: handlebars.compile}; | ||
assert.equal(handlebars.compile('{{{md "test/fixtures/c.md"}}}')(locals), '<h1>CCC</h1>\n<p>This is CCC</p>\n'); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('async', function() { | ||
beforeEach(function() { | ||
app = new Templates(); | ||
|
||
app.asyncHelper('md', md); | ||
app.engine('md', require('engine-base')); | ||
app.option('engine', 'md'); | ||
|
||
app.create('page'); | ||
app.create('partial', {viewType: ['partial']}); | ||
app.create('include', {viewType: ['partial']}); | ||
|
||
app.include('one', {content: '# heading <%= name %>', data: {name: 'one'}}); | ||
app.partial('two', {content: '# heading <%= name %>', data: {name: 'two'}}); | ||
}); | ||
|
||
it('should convert markdown on the `content` property of a template to HTML:', function(cb) { | ||
app.page('home.md', {content: '<%= md("one") %>'}); | ||
|
||
app.render('home.md', function(err, view) { | ||
if (err) return cb(err); | ||
assert.equal(view.content, '<h1>heading one</h1>\n'); | ||
cb(); | ||
}); | ||
}); | ||
|
||
it('should support rendering from a file', function(cb) { | ||
app.page('home.md', {content: '<%= md("test/fixtures/d.md") %>'}); | ||
|
||
app.render('home.md', {name: 'DDD'}, function(err, view) { | ||
if (err) return cb(err); | ||
assert.equal(view.content, '<h1>DDD</h1>\n<p>This is DDD</p>\n'); | ||
cb(); | ||
}); | ||
}); | ||
|
||
it('should use sync helper when a callback is not passed:', function(cb) { | ||
app.helper('md2', md); | ||
app.page('home.md', {content: '<%= md2("one") %>'}); | ||
|
||
app.render('home.md', function(err, view) { | ||
if (err) return cb(err); | ||
assert.equal(view.content, '<h1>heading one</h1>\n'); | ||
cb(); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('lodash:', function() { | ||
it('should work as a lodash mixin:', function() { | ||
_.mixin({md: md.sync}); | ||
assert.equal(_.template('<%= _.md("test/fixtures/a.md") %>', {})(), '<h1>AAA</h1>\n<blockquote>\n<p>this is aaa</p>\n</blockquote>\n'); | ||
}); | ||
|
||
it('should work when passed to lodash on the locals:', function() { | ||
assert.equal(_.template('<%= _.md("test/fixtures/a.md") %>')({md: md.sync}), '<h1>AAA</h1>\n<blockquote>\n<p>this is aaa</p>\n</blockquote>\n'); | ||
}); | ||
|
||
it('should work as a lodash import:', function() { | ||
var settings = {imports: {md: md.sync}}; | ||
assert.equal(_.template('<%= _.md("test/fixtures/a.md") %>', {}, settings)(), '<h1>AAA</h1>\n<blockquote>\n<p>this is aaa</p>\n</blockquote>\n'); | ||
}); | ||
}); | ||
|
||
describe('highlight:', function(argument) { | ||
it('should support syntax highlighting', function() { | ||
var actual = md.sync('test/fixtures/e.md', { | ||
highlight: function(code, lang) { | ||
try { | ||
try { | ||
return hljs.highlight(lang, code).value; | ||
} catch (err) { | ||
if (!/Unknown language/i.test(err.message)) { | ||
throw err; | ||
} | ||
return hljs.highlightAuto(code).value; | ||
} | ||
} catch (err) { | ||
return code; | ||
} | ||
} | ||
}); | ||
assert.equal(actual, '<h1>EEE</h1>\n<pre><code><span class="hljs-keyword">var</span> <span class="hljs-keyword">message</span> = <span class="hljs-string">\'This is an alert\'</span>;\nalert(<span class="hljs-keyword">message</span>);\n</code></pre>\n'); | ||
}); | ||
}); |