From ec25375ba8d51f6b1877d48fd5c8e73652707b4b Mon Sep 17 00:00:00 2001 From: ipluser Date: Mon, 16 May 2016 18:35:53 +0800 Subject: [PATCH] refactor: add include tag plugin and parseFilters options --- bower.json | 4 +- dist/magicbook.min.js | 2 +- index.html | 4 +- lib/magicbook.js | 38 +++++++-- navigator.md | 4 +- package.json | 2 +- .../components/js/magicbook-plugin-include.js | 80 +++++++++++++++++++ .../js/magicbook-plugin-include.min.js | 1 + public/doc/options.md | 18 +++++ .../components/js/magicbook-plugin-include.md | 50 ++++++++++++ 10 files changed, 191 insertions(+), 12 deletions(-) create mode 100644 plugins/components/js/magicbook-plugin-include.js create mode 100644 plugins/components/js/magicbook-plugin-include.min.js create mode 100644 public/doc/plugins/components/js/magicbook-plugin-include.md diff --git a/bower.json b/bower.json index f2fddd4..4847ad5 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "magicbook", - "version": "0.7.1", + "version": "0.8.0", "description": "An lightweight and scalable docs system for markdown, text or other.", "homepage": "http://ipluser.github.io/magicbook/", "keywords": [ @@ -16,4 +16,4 @@ "authors": [ "Plus " ] -} \ No newline at end of file +} diff --git a/dist/magicbook.min.js b/dist/magicbook.min.js index 552104b..41f4f28 100644 --- a/dist/magicbook.min.js +++ b/dist/magicbook.min.js @@ -1 +1 @@ -!function(n,r){function t(n,r){return C.call(n)===r}function a(n){return t(n,"[object Function]")}function e(n){return t(n,"[object String]")}function o(n){return t(n,"[object Array]")}function i(n){return t(n,"[object Number]")}function c(n){return"undefined"==typeof n}function u(n){return null===n||c(n)?[]:o(n)&&n||[n]}function l(n,r,t){return n&&r&&n[r]||t}function s(n,r){return{}.hasOwnProperty.call(n,r)}function f(n,t){n&&r.get(n).success(function(n){t&&a(t.success)&&t.success(n)}).fail(function(n){t&&a(t.fail)&&t.fail(n)}).always(function(){t&&a(t["finally"])&&t["finally"]()})}function d(n,t){var a=r(n);a&&!a.hasClass(t)&&a.addClass(t)}function g(n,r,t,e){var i,c,u,s=!1;if(!o(n))return s;for(i=0,c=n.length;c>i;i++)u=l(n[i],r),a(u)&&(s=!0,u.apply(t,e));return s}function v(n,r){d(n,m+r)}function p(n,r){n.after(r),n.remove(),r.append(n)}var h={title:"magicbook - An lightweight and scalable docs system for markdown, text or other.",container:"",navigator:"",content:"",navigatorUrl:"navigator.md",homeUrl:"README.md",baseUrl:"",urlArgs:"",debug:!1,navigatorCallbackQueue:[],routeCallbackQueue:[]},m="magicbook-",b=n.location,y=n.document,k=Object.prototype,C=k.toString,U=n.Magicbook=function Q(t){function a(){var n,t,a,e=c.container,o=c.navigator,u=c.content,l=r('
'),s=r('
');o||u?(o&&(t=r(o),t.length&&(v(t,"navigator"),p(t,l))),u&&(a=r(u),a.length&&(v(a,"content"),p(a,s)))):(n=r(e),n.length||(n=r('
'),r("body").prepend(n)),v(n,"container"),t=r('
'),a=r('
'),l.append(t),s.append(a),n.append(l).append(s)),i.$container=n,i.$navigatorWrap=l,i.$contentWrap=s,i.$navigator=t,i.$content=a}function e(n){var t,a,e;for(t=0,a=n.length;a>t;t++)e=r(n[t]),e.attr("src",i.relativeCurrentUrl(e.attr("src")))}function o(){var n=i.normalizeUrl(c.navigatorUrl),r=c.navigatorCallbackQueue;n&&f(n,{success:function(n){var t=i.parser(n);i.$navigator&&i.$navigator.empty().append(i.parser(n)),g(r,"success",i,[{origin:n,result:t}])},fail:function(n){g(r,"fail",i,[n])||i.$navigator&&i.$navigator.empty().append('
navigator not found
')},"finally":function(){g(r,"finally",i)}})}if(!(this instanceof Q))return new Q(t);var i=this,c=i.config=r.extend({},h,t);c.navigatorCallbackQueue=u(c.navigatorCallbackQueue),c.routeCallbackQueue=u(c.routeCallbackQueue),c.navigatorCallbackQueue.unshift({success:function(){e(i.$navigatorWrap.find("img"))}}),c.routeCallbackQueue.unshift({success:function(){e(i.$contentWrap.find("img"))}}),i.handlers={},i.handlersCount=0,i.handler("drawNavigator",o,{priority:1}),i.handler("drawContent",function(){i.route()},{priority:1}),n.onhashchange=function(){i.route(b.hash)},y.title=c.title,a()},$=U.potion=U.prototype;$.parser=function(n){return n},$.route=function(n,r){var t=this,a=e(n)&&n||b.hash||t.config.homeUrl;a=t.normalizeUrl(a),t.render(a,r)},$.render=function(n,r){var t=this,a=t.config.routeCallbackQueue,e=u(r);n&&f(n,{success:function(n){var r=t.parser(n);t.$content&&t.$content.empty().append(r),g(a,"success",t,[{origin:n,result:r}]),g(e,"success",t,[{origin:n,result:r}])},fail:function(n){g(a,"fail",t,[n])||g(e,"fail",t,[n])||t.$content&&t.$content.empty().append('
content not found
')},"finally":function(){g(a,"finally",t),g(e,"finally",t)}})},$.normalizeUrl=function(n){if(!n)return n;var r=this,t=r.config,a=t.urlArgs,o=t.baseUrl+n.replace(/^#/,"");return a&&e(a)&&(o+=(-1===o.indexOf("?")?"?":"&")+a),o},$.relativeCurrentUrl=function(n){var r=this,t=b.hash||r.config.homeUrl,a=t||"";return!t&&!n||!e(t)||n&&!e(n)?n||"":-1!==n.search(/\:\/\//)?n:(a=a.replace(/\#/,"").replace(/\/$/,""),a=a+(t&&"/../"||"")+(n||""),r.normalizeUrl(a))},$.handler=function(n,t,a){var o=this,i=o.handlers;if(n&&e(n)&&!t&&!a)return i[n];var c=i[n],u={order:c&&c.order||o.handlersCount++,name:n,action:t,options:r.extend({priority:2},a)};i[n]=u},$.show=function(){var n,r,t=this,e=t.handlers,o=[];for(var i in e){if(!s(e,i))return;var c=e[i],u=c.options.priority;for(n=0,r=o.length;r>n;n++){var l=o[n],f=l.options.priority;if(f>u||u===f&&c.ordern;n++){var d=o[n].action;a(d)&&d.call(this)}},$.getCurrentDocUrl=function(){var n=this,r=b.hash||n.config.homeUrl;return r.replace(/^#/,"")};var w={};U.markdown=function(n,r){var t=w[n]||U;return t(r)},U.customizeMarkdown=function(n,r){w[n]=r},U.toStringEqual=t,U.isFunction=a,U.isString=e,U.isArray=o,U.isNumber=i,U.isUndefined=c,U.parseArray=u,U.getPropertyByDefaultValue=l,U.hasOwnProperty=s,U.requestGet=f,U.addClassName=d}(window,jQuery); \ No newline at end of file +!function(n,r){function t(n,r){return C.call(n)===r}function a(n){return t(n,"[object Function]")}function e(n){return t(n,"[object String]")}function o(n){return t(n,"[object Array]")}function i(n){return t(n,"[object Number]")}function c(n){return"undefined"==typeof n}function u(n){return null===n||c(n)?[]:o(n)&&n||[n]}function l(n,r,t){return n&&r&&n[r]||t}function s(n,r){return{}.hasOwnProperty.call(n,r)}function f(n,t){n&&r.get(n).success(function(n){t&&a(t.success)&&t.success(n)}).fail(function(n){t&&a(t.fail)&&t.fail(n)}).always(function(){t&&a(t["finally"])&&t["finally"]()})}function g(n,t){var a=r(n);a&&!a.hasClass(t)&&a.addClass(t)}function d(n,r,t,e){var i,c,u,s=!1;if(!o(n))return s;for(i=0,c=n.length;c>i;i++)u=l(n[i],r),a(u)&&(s=!0,u.apply(t,e));return s}function p(n,r){g(n,m+r)}function v(n,r){n.after(r),n.remove(),r.append(n)}var h={title:"magicbook - An lightweight and scalable docs system for markdown, text or other.",container:"",navigator:"",content:"",navigatorUrl:"navigator.md",homeUrl:"README.md",baseUrl:"",urlArgs:"",debug:!1,parseFilters:[],navigatorCallbackQueue:[],routeCallbackQueue:[]},m="magicbook-",b=n.location,y=n.document,k=Object.prototype,C=k.toString,U=n.Magicbook=function Q(t){function a(){var n,t,a,e=c.container,o=c.navigator,u=c.content,l=r('
'),s=r('
');o||u?(o&&(t=r(o),t.length&&(p(t,"navigator"),v(t,l))),u&&(a=r(u),a.length&&(p(a,"content"),v(a,s)))):(n=r(e),n.length||(n=r('
'),r("body").prepend(n)),p(n,"container"),t=r('
'),a=r('
'),l.append(t),s.append(a),n.append(l).append(s)),i.$container=n,i.$navigatorWrap=l,i.$contentWrap=s,i.$navigator=t,i.$content=a}function e(n){var t,a,e;for(t=0,a=n.length;a>t;t++)e=r(n[t]),e.attr("src",i.relativeCurrentUrl(e.attr("src")))}function o(){var n=i.normalizeUrl(c.navigatorUrl),r=c.navigatorCallbackQueue;n&&f(n,{success:function(n){var t=i.parse(n);i.$navigator&&i.$navigator.empty().append(t),d(r,"success",i,[{origin:n,result:t}])},fail:function(n){d(r,"fail",i,[n])||i.$navigator&&i.$navigator.empty().append('
navigator not found
')},"finally":function(){d(r,"finally",i)}})}if(!(this instanceof Q))return new Q(t);var i=this,c=i.config=r.extend({},h,t);c.parseFilters=u(c.parseFilters),c.navigatorCallbackQueue=u(c.navigatorCallbackQueue),c.routeCallbackQueue=u(c.routeCallbackQueue),c.navigatorCallbackQueue.unshift({success:function(){e(i.$navigatorWrap.find("img"))}}),c.routeCallbackQueue.unshift({success:function(){e(i.$contentWrap.find("img"))}}),i.handlers={},i.handlersCount=0,i.handler("drawNavigator",o,{priority:1}),i.handler("drawContent",function(){i.route()},{priority:1}),n.onhashchange=function(){i.route(b.hash)},y.title=c.title,a()},$=U.potion=U.prototype;$.parser=function(n){return n},$.parse=function(n){var r,t,e=this,o=e.config.parseFilters,i=o.length;for(r=0;i>r;r++){var c=o[r],u=c.before,l=c.after;a(u)&&(t=u.call(e,n)),t=e.parser(t),a(c.after)&&(t=l.call(e,t))}return t&&t||e.parser(n)},$.route=function(n,r){var t=this,a=e(n)&&n||b.hash||t.config.homeUrl;a=t.normalizeUrl(a),t.render(a,r)},$.render=function(n,r){var t=this,a=t.config.routeCallbackQueue,e=u(r);n&&f(n,{success:function(n){var r=t.parse(n);t.$content&&t.$content.empty().append(r),d(a,"success",t,[{origin:n,result:r}]),d(e,"success",t,[{origin:n,result:r}])},fail:function(n){d(a,"fail",t,[n])||d(e,"fail",t,[n])||t.$content&&t.$content.empty().append('
content not found
')},"finally":function(){d(a,"finally",t),d(e,"finally",t)}})},$.normalizeUrl=function(n){if(!n)return n;var r=this,t=r.config,a=t.urlArgs,o=t.baseUrl+n.replace(/^#/,"");return a&&e(a)&&(o+=(-1===o.indexOf("?")?"?":"&")+a),o},$.relativeCurrentUrl=function(n){var r=this,t=b.hash||r.config.homeUrl,a=t||"";return!t&&!n||!e(t)||n&&!e(n)?n||"":-1!==n.search(/\:\/\//)?n:(a=a.replace(/\#/,"").replace(/\/$/,""),a=a+(t&&"/../"||"")+(n||""),r.normalizeUrl(a))},$.handler=function(n,t,a){var o=this,i=o.handlers;if(n&&e(n)&&!t&&!a)return i[n];var c=i[n],u={order:c&&c.order||o.handlersCount++,name:n,action:t,options:r.extend({priority:2},a)};i[n]=u},$.show=function(){var n,r,t=this,e=t.handlers,o=[];for(var i in e){if(!s(e,i))return;var c=e[i],u=c.options.priority;for(n=0,r=o.length;r>n;n++){var l=o[n],f=l.options.priority;if(f>u||u===f&&c.ordern;n++){var g=o[n].action;a(g)&&g.call(this)}},$.getCurrentDocUrl=function(){var n=this,r=b.hash||n.config.homeUrl;return r.replace(/^#/,"")};var w={};U.markdown=function(n,r){var t=w[n]||U;return t(r)},U.customizeMarkdown=function(n,r){w[n]=r},U.toStringEqual=t,U.isFunction=a,U.isString=e,U.isArray=o,U.isNumber=i,U.isUndefined=c,U.parseArray=u,U.getPropertyByDefaultValue=l,U.hasOwnProperty=s,U.requestGet=f,U.addClassName=g}(window,jQuery); \ No newline at end of file diff --git a/index.html b/index.html index 7803e7b..039cd0e 100644 --- a/index.html +++ b/index.html @@ -24,11 +24,11 @@ - \ No newline at end of file + diff --git a/lib/magicbook.js b/lib/magicbook.js index 75a4dce..6ce05bb 100644 --- a/lib/magicbook.js +++ b/lib/magicbook.js @@ -10,6 +10,7 @@ baseUrl: '', urlArgs: '', debug: false, + parseFilters: [], navigatorCallbackQueue: [], routeCallbackQueue: [] }; @@ -193,8 +194,8 @@ requestGet(navigatorUrl, { success: function drawNavigatorSuccess(data) { - var result = self.parser(data); - self.$navigator && self.$navigator.empty().append(self.parser(data)); + var result = self.parse(data); + self.$navigator && self.$navigator.empty().append(result); executeCallbackQueue(defaultCallbackQueue, 'success', self, [{ origin: data, @@ -214,6 +215,7 @@ }); } + config.parseFilters = parseArray(config.parseFilters); config.navigatorCallbackQueue = parseArray(config.navigatorCallbackQueue); config.routeCallbackQueue = parseArray(config.routeCallbackQueue); @@ -252,8 +254,34 @@ var proto = Magicbook.potion = Magicbook.prototype; - proto.parser = function parser(data) { - return data; + proto.parser = function parser(source) { + return source; + }; + + proto.parse = function parse(source) { + var self = this; + var filters = self.config.parseFilters; + var len = filters.length; + var index; + + var data; + for (index = 0; index < len; index++) { + var filter = filters[index]; + var beforeParse = filter.before; + var afterParse = filter.after; + + if (isFunction(beforeParse)) { + data = beforeParse.call(self, source); + } + + data = self.parser(data); + + if (isFunction(filter.after)) { + data = afterParse.call(self, data); + } + } + + return data && data || self.parser(source); }; proto.route = function route(url, callback) { @@ -275,7 +303,7 @@ requestGet(url, { success: function renderCallbackSuccess(data) { - var result = self.parser(data); + var result = self.parse(data); self.$content && self.$content.empty().append(result); executeCallbackQueue(defaultCallbackQueue, 'success', self, [{ diff --git a/navigator.md b/navigator.md index 0dc07c2..2f9b38d 100644 --- a/navigator.md +++ b/navigator.md @@ -17,6 +17,8 @@ License: [MIT](https://github.com/ipluser/magicbook/blob/gh-pages/LICENSE) - [agilities](#public/doc/plugins/components/css/agilities.md) - js - [agilities](#public/doc/plugins/components/js/agilities.md) + - js + - [magicbook-plugin-include](#public/doc/plugins/components/js/magicbook-plugin-include.md) - markdown - css - [awesome](#public/doc/plugins/markdown/css/awesome.md) @@ -31,4 +33,4 @@ License: [MIT](https://github.com/ipluser/magicbook/blob/gh-pages/LICENSE) - [Commit Message Format](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format) ### Friend Links -- [speechless](http://ipluser.github.io/speechless/) \ No newline at end of file +- [speechless](http://ipluser.github.io/speechless/) diff --git a/package.json b/package.json index 4cba417..753a086 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicbookjs", - "version": "0.7.1", + "version": "0.8.0", "description": "An lightweight and scalable docs system for markdown, text or other.", "author": "ipluser", "main": "dist/magicbook.js", diff --git a/plugins/components/js/magicbook-plugin-include.js b/plugins/components/js/magicbook-plugin-include.js new file mode 100644 index 0000000..5e4cfb2 --- /dev/null +++ b/plugins/components/js/magicbook-plugin-include.js @@ -0,0 +1,80 @@ +;(function (global, $, Magicbook) { // eslint-disable-line + + var TAG_NAME = 'include'; + var defaults = { + openTag: '{%', + closeTag: '%}' + }; + + function tempate(cfg) { + var options = $.extend({}, defaults, cfg); + var openTag = options.openTag; + var closeTag = options.closeTag; + + function parse(chunk) { + var tokens = chunk.trim().replace(/\s+/g, ' ').split(' '); + var tag = tokens[0]; + var len = tokens.length; + + if (len <= 1 || tag !== TAG_NAME) { + return openTag + chunk + closeTag; // + } + + var content; + var url = tokens[1]; + var _url = url.length > 2 ? url.substring(1, url.length - 1) : url; + _url = _url.search(/\:\/\//) !== -1 ? _url : this.relativeCurrentUrl(_url); + + $.ajax({ + url: _url, + async: false, + success: function templateIncludeTagSuccess(data) { + content = data; + }, + error: function templateIncludeTagError() { + content = [TAG_NAME, ': \'', url, '\' not found'].join(' '); + } + }); + + return content; + } + + return function render(source) { + var blocks = (source || '').split(openTag); + var len = blocks.length; + var index; + + if (len <= 1) { + return source; + } + + var out = ''; + for (index = 0; index < len; index++) { + var block = blocks[index]; + var chunks = block.split(closeTag); + + if (chunks.length === 1) { + out += chunks[0]; + continue; + } + + var content = parse.call(this, chunks[0]); + + out += content; + out += chunks[1]; + } + + return out; + }; + } + + Magicbook.potion.enableIncludeTag = function enableIncludeTag(cfg) { + var self = this; + + self.config.parseFilters.push({ + before: tempate(cfg) + }); + + self.templateIncludeTag = tempate(cfg); + }; +})(window, jQuery, Magicbook); // eslint-disable-line diff --git a/plugins/components/js/magicbook-plugin-include.min.js b/plugins/components/js/magicbook-plugin-include.min.js new file mode 100644 index 0000000..462bf49 --- /dev/null +++ b/plugins/components/js/magicbook-plugin-include.min.js @@ -0,0 +1 @@ +!function(n,e,r){function t(n){function r(n){var r=n.trim().replace(/\s+/g," ").split(" "),t=r[0],i=r.length;if(1>=i||t!==a)return l+n+o;var u,c=r[1],s=c.length>2?c.substring(1,c.length-1):c;return s=-1!==s.search(/\:\/\//)?s:this.relativeCurrentUrl(s),e.ajax({url:s,async:!1,success:function(n){u=n},error:function(){u=[a,": '",c,"' not found"].join(" ")}}),u}var t=e.extend({},i,n),l=t.openTag,o=t.closeTag;return function(n){var e,t=(n||"").split(l),a=t.length;if(1>=a)return n;var i="";for(e=0;a>e;e++){var u=t[e],c=u.split(o);if(1!==c.length){var s=r.call(this,c[0]);i+=s,i+=c[1]}else i+=c[0]}return i}}var a="include",i={openTag:"{%",closeTag:"%}"};r.potion.enableIncludeTag=function(n){var e=this;e.config.parseFilters.push({before:t(n)}),e.templateIncludeTag=t(n)}}(window,jQuery,Magicbook); \ No newline at end of file diff --git a/public/doc/options.md b/public/doc/options.md index 252d99f..7687f8f 100644 --- a/public/doc/options.md +++ b/public/doc/options.md @@ -62,6 +62,24 @@ A path of navigator. ##### default `navigator.md` +### parseFilters +`parseFilters ` to execute before/after parser that consist of a series of `Filter` object. `Filter` object has `before` and `after`function properties. Example below: + +```js +// It will be transformed into Array if it is a Filter object +parseFilters: [{ + before: function (source) { + // todo + }, + after: function (source) { + // todo + } +}] +``` + +##### default `[]` + + ### routeCallbackQueue `routeCallbackQueue ` to execute after navigator have been rendered that consist of a series of `Callback` object. `Callback` object has `success`, `fail` and `finally` function properties. Example below: diff --git a/public/doc/plugins/components/js/magicbook-plugin-include.md b/public/doc/plugins/components/js/magicbook-plugin-include.md new file mode 100644 index 0000000..0c190c3 --- /dev/null +++ b/public/doc/plugins/components/js/magicbook-plugin-include.md @@ -0,0 +1,50 @@ +## magicbook-plugin-include.js +The **magicbook-plugin-include** supports `include` template tag in document. + +### usage +#### Import Dependencies +To use magicbook-plugin-include, you’ll need to make sure `magicbook` are included. +```html + +``` + +#### To use include tag +```markup +{% include './test.md' %} +``` + +#### Initialize +```js + {magicbook instance}.enableIncludeTag({ + openTag: '{%', + closeTag: '%}' + }); + + // or + + {magicbook instance}.enableIncludeTag(); +``` + +### configuration +#### openTag +Open controls for include tag. + +##### default +`{%` + + +#### closeTag +Close controls for include tag. + +##### default +`%}` + + +### methods +#### templateIncludeTag +Parse include tag. + +##### parameters +| name | description | +|-----------|------------------| +| source | document content |