Permalink
Browse files

added options for managing template context

  • Loading branch information...
1 parent 656b8a9 commit a684dd8efdef3ddf26d7660764beb1ac9c0d9a64 @treasonx committed Jul 30, 2013
Showing with 106 additions and 8 deletions.
  1. +44 −0 README.md
  2. +1 −1 package.json
  3. +13 −2 tasks/lib/markdown.js
  4. +5 −1 tasks/markdown.js
  5. +43 −4 test/markdown_test.js
View
44 README.md
@@ -54,6 +54,9 @@ grunt.initConfig({
],
options: {
template: 'myTemplate.jst',
+ preCompile: function(src, context) {},
+ postCompile: function(src, context) {},
+ templateContext: {},
markdownOptions: {
gfm: true,
highlight: manual,
@@ -74,6 +77,47 @@ These are the properties that the `markdown` task accepts:
* `options`: options to be passed to the markdown parser
* `template`: If you wish to specify your own html template, use the `template` option. Include the following line: `<%=content%>` where you want the compiled markdown inserted in your template
* `markdownOptions`: Options passed directly to the markdown parser.
+ * `preCompile`: is run before the markdown is compiled
+ * `postCompile`: is run after the markdown has been compiled
+ * `templateContext`: the default context for template expansion
+
+### modifying content with preCompile and postCompile
+
+Sometimes there is a need to modify the markdown content prior to compilation.
+This is most commonly used to augment the template context with meta data before
+expanding the html template.
+
+#### preCompile
+
+This function is run prior to the compilation of md to html. It has the
+following format:
+
+```javascript
+ function(src, context) {
+ //do stuff to src and context
+ //optionally return the modified src
+ }
+```
+
+#### postCompile
+
+This function is run after the md has been converted to html. It has the
+following format:
+
+```javascript
+ function(src, context) {
+ //do stuff to src and context
+ //optionally return the modified src
+ }
+```
+### templateContext
+
+This object is used to expand your html template. Any data added to this object
+will be available in the template using the template syntax `<%=myAttr%>`.
+
+This can also be a function which is expected to return a context object.
+
+### markdownOptions
Most markdown options are passed as-is to the [marked](https://github.com/chjj/marked) markdown parser. The only option that is processed prior to compiling the markdown is the `highlight` option. If you specify `auto` or `manual` the task will handle highlighting code blocks for you use highlight.js. If you pass a custom function as the highlight option it will be used to highlight the code.
View
2 package.json
@@ -1,7 +1,7 @@
{
"name": "grunt-markdown",
"description": "Compile markdown to html. GFM and code highlighting support!",
- "version": "0.3.0",
+ "version": "0.4.0",
"homepage": "https://github.com/treasonx/grunt-markdown",
"author": {
"name": "James Morrin",
View
15 tasks/lib/markdown.js
@@ -19,6 +19,7 @@ exports.init = function(grunt) {
exports.markdown = function(src, options, template) {
var html = null;
+ var templateContext = null;
var codeLines = options.codeLines;
var shouldWrap = codeLines && codeLines.before && codeLines.after;
@@ -59,13 +60,23 @@ exports.init = function(grunt) {
}
- markdown.setOptions(options);
+ markdown.setOptions(options.markdownOptions);
grunt.verbose.write('Marking down...');
+ if(_.isFunction(options.templateContext)) {
+ templateContext = options.templateContext();
+ } else {
+ templateContext = options.templateContext;
+ }
+
+ src = options.preCompile(src, templateContext) || src;
html = markdown(src);
+ html = options.postCompile(src, templateContext) || html;
+
+ templateContext.content = templateContext.content || html;
- return _.template(template, {content:html});
+ return _.template(template, templateContext);
};
View
6 tasks/markdown.js
@@ -8,6 +8,7 @@
module.exports = function(grunt) {
'use strict';
+ var noop = function(){};
var path = require('path');
@@ -20,6 +21,9 @@ module.exports = function(grunt) {
htmlExtension: 'html',
markdownExtension: 'md',
markdownOptions: {},
+ preCompile: noop,
+ postCompile: noop,
+ templateContext: {},
template: path.join(__dirname, 'template.html')
});
var template = grunt.file.read(options.template);
@@ -32,7 +36,7 @@ module.exports = function(grunt) {
function convert(src, dest, next){
var content = markdown.markdown(
grunt.file.read(src),
- options.markdownOptions,
+ options,
template
);
View
47 test/markdown_test.js
@@ -25,12 +25,15 @@ var cheerio = require('cheerio');
*/
var filepath = 'test/samples/javascript.md';
-var file = grunt.file.read(filepath);
+var file = null;
+var defaultFile = grunt.file.read(filepath);
var templatepath = 'tasks/template.html';
-var template = grunt.file.read(templatepath);
+var template = null;
+var defaultTemplate = grunt.file.read(templatepath);
var html = null;
var $result = null;
-var options = {};
+var noop = function() {};
+var options = null;
function getjQuery() {
html = markdown.markdown(file, options, template);
@@ -39,10 +42,16 @@ function getjQuery() {
exports['markdown'] = {
setUp: function(done) {
+ options = {
+ preCompile: noop,
+ postCompile: noop,
+ templateContext: {}
+ };
+ template = defaultTemplate;
+ file = defaultFile;
done();
},
tearDown: function(done) {
- options = {};
done();
},
'helper': function(test) {
@@ -96,6 +105,36 @@ exports['markdown'] = {
test.ok($a.text() === 'json', 'should have code text');
test.done();
+ },
+
+ 'should expand preCompile context': function(test) {
+ template = grunt.file.read('test/data/titletest.html');
+ file = grunt.file.read('test/data/titletest.md');
+
+ options.preCompile = function(src, context) {
+ var matcher = src.match(/@-title:\s?([^@:\n]+)\n/i);
+ context.title = matcher && matcher.length > 1 && matcher[1];
+ matcher = src.match(/@-description:\s?([^@:\n]+)\n/i);
+ context.description = matcher && matcher.length > 1 && matcher[1];
+ };
+ getjQuery();
+ var $title = $result.find('title');
+ var $desc = $result.find('meta[name="description"]');
+
+ test.ok($title.text() === 'The name is this', 'the title should be set from preCompile context');
+ test.ok($desc.attr('content') === 'Monkey', 'the description should be set from preCompile context');
+ test.done();
+ },
+
+ 'should save postCompile Changes': function(test) {
+ options.postCompile = function(src, context) {
+ return '<div><h1>Oh Hai</h1></div>';
+ };
+
+ getjQuery();
+ var $h1 = $result.find('h1');
+ test.ok($h1.text() === 'Oh Hai', 'the content is replaced with postCompile changes');
+ test.done();
}
};

0 comments on commit a684dd8

Please sign in to comment.