Created
May 7, 2013 05:49
-
-
Save poochin/5530506 to your computer and use it in GitHub Desktop.
代入とイテレートのみ実装したテンプレートエンジンです。 短い行数で欲しかったので書きました。
This file contains hidden or 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
| /** | |
| * Name: tParser | |
| * Desc: Lite template engine (only assign and array iterate) | |
| * License: MIT | |
| * Author: poochin | |
| **/ | |
| /** | |
| * 構文: | |
| * {{ A }}: 変数の代入 | |
| * ex: {{ A }}, {{A.B}} | |
| * {{ iter A@B }}: 配列 A に B という名前を付けてループ | |
| * ex: {{ iter A@B }} {{ B }} {{ /iter }} | |
| * {{ iter A.a@B }} ... {{/iter}} | |
| * | |
| * 自由度と制約: | |
| * {{...}} で参照する際には、オブジェクトの階層を .(ドット) を用いて掘ることができます | |
| * {{...}} の中括弧の直内は空白を自由に取って構いません | |
| * {{ iter }} はネストできません | |
| * {{ iter }} はインデックス番号を参照できません | |
| */ | |
| function tParser(src) { | |
| var self = this; | |
| var reg = /(?:{{\s*([A-Za-z0-9._]+)\s*}}|{{\s*iter\s+([A-Za-z0-9._]+)@([A-Za-z0-9_]+)\s*}}([\s\S]*){{\s*\/iter\s*}})/gm; | |
| var last_index = 0; | |
| var next_str = ""; | |
| var nodes = []; | |
| /* ここでは置換ではなく字句解析目的で replace 関数を用いています */ | |
| src.replace(reg, | |
| function(match_text, assign_key, iter_key, iter_as, iter_text, index, all_text){ | |
| if (index !== 0) { | |
| nodes.push(self.tNode(all_text.slice(last_index, index), 'text')); | |
| last_index = index; | |
| } | |
| if (assign_key !== undefined) { | |
| nodes.push(self.tNode(assign_key, 'assign')); | |
| last_index += match_text.length; | |
| } | |
| else { | |
| nodes.push(self.tNode(iter_text, 'iter', {iter_key: iter_key, iter_as: iter_as})); | |
| last_index += match_text.length; | |
| } | |
| next_str = all_text.slice(last_index); | |
| } | |
| ); | |
| if (next_str.length) { | |
| nodes.push(self.tNode(next_str, 'text')); | |
| } | |
| this.nodes = nodes; | |
| } | |
| tParser.prototype = { | |
| digDict: function digDict(dict, keys) { | |
| if (keys.length === 1) { | |
| return dict[keys[0]]; | |
| } | |
| return ((dict[keys[0]] !== undefined) | |
| ? (this.digDict(dict[keys[0]], keys.slice(1))) | |
| : (undefined)); | |
| }, | |
| textBuilder: function textBuilder(text, dict, iter_dict) { | |
| var self = this; | |
| var reg = /{{\s*([A-Za-z0-9._]+)\s*}}/gm; | |
| function replacer(a,b,c,d) { | |
| return self.digDict(iter_dict, b.split('.')) || self.digDict(dict, b.split('.')) || ""; | |
| } | |
| return text.replace(reg, replacer); | |
| }, | |
| tNode: function tNode(text, type, iter_options) { | |
| return { | |
| text: text, | |
| type: type, /* text, iter, assign */ | |
| iter_options: iter_options, /* iter_key, iter_as */ | |
| } | |
| }, | |
| assign: function(dict) { | |
| var self = this; | |
| return this.nodes.map( | |
| function(tnode){ | |
| var iter_array; | |
| var iter_results; | |
| switch(tnode.type) { | |
| case "iter": | |
| iter_array = self.digDict(dict, tnode.iter_options.iter_key.split('.')); | |
| iter_results = iter_array.map(function(src) { | |
| var iter_dict = {}; | |
| iter_dict[tnode.iter_options.iter_as] = src; | |
| return self.textBuilder(tnode.text, dict, iter_dict); | |
| }); | |
| return iter_results.join(''); | |
| case "assign": | |
| return self.digDict(dict, tnode.text.split('.')) || ""; | |
| } | |
| return tnode.text; | |
| } | |
| ).join(''); | |
| } | |
| }; | |
| /* // Sample | |
| var text = "Balls are{{ iter A.ITER@B }} {{ B }}{{ /iter }} and {{ C }}"; | |
| var dict = {A: {ITER: ["red", "blue"]}, C: "yellow"}; | |
| var t = new tParser(text); | |
| var result = t.assign(dict); // get "Balls are red blue and yellow" | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment