comparison src/implab/text/format-compile.js @ 0:fc2517695ee1

Initial commit, draft import of existing work
author cin
date Thu, 01 Jun 2017 13:20:03 +0300
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:fc2517695ee1
1 define(
2 [],
3 function() {
4 var map = {
5 "\\{" : "&curlopen;",
6 "\\}" : "&curlclose;",
7 "&" : "&",
8 "\\:" : ":"
9 };
10
11 var rev = {
12 curlopen : "{",
13 curlclose : "}",
14 amp : "&",
15 colon : ":"
16 };
17
18 var espaceString = function(s) {
19 if (!s)
20 return s;
21 return "'" + s.replace(/('|\\)/g, "\\$1") + "'";
22 };
23
24 var encode = function(s) {
25 if (!s)
26 return s;
27 return s.replace(/\\{|\\}|&|\\:/g, function(m) {
28 return map[m] || m;
29 });
30 };
31
32 var decode = function(s) {
33 if (!s)
34 return s;
35 return s.replace(/&(\w+);/g, function(m, $1) {
36 return rev[$1] || m;
37 });
38 };
39
40 var subst = function(s) {
41 var i = s.indexOf(":"), name, pattern;
42 if (i >= 0) {
43 name = s.substr(0, i);
44 pattern = s.substr(i + 1);
45 } else {
46 name = s;
47 }
48
49 if (pattern)
50 return [
51 espaceString(decode(name)),
52 espaceString(decode(pattern)) ];
53 else
54 return [ espaceString(decode(name)) ];
55 };
56
57 var compile = function(str) {
58 if (!str)
59 return function() {};
60
61 var chunks = encode(str).split("{"), chunk;
62
63 var code = [ "var result=[];" ];
64
65 for (var i = 0; i < chunks.length; i++) {
66 chunk = chunks[i];
67
68 if (i === 0) {
69 if (chunk)
70 code.push("result.push(" + espaceString(decode(chunk)) +
71 ");");
72 } else {
73 var len = chunk.indexOf("}");
74 if (len < 0)
75 throw new Error("Unbalanced substitution #" + i);
76
77 code.push("result.push(subst(" +
78 subst(chunk.substr(0, len)).join(",") + "));");
79 if (chunk.length > len + 1)
80 code.push("result.push(" +
81 espaceString(decode(chunk.substr(len + 1))) + ");");
82 }
83 }
84
85 code.push("return result.join('');");
86
87 /* jshint -W054 */
88 return new Function("subst", code.join("\n"));
89 };
90
91 var cache = {};
92
93 return function(template) {
94 var compiled = cache[template];
95 if (!compiled) {
96 compiled = compile(template);
97 cache[template] = compiled;
98 }
99 return compiled;
100 };
101 });