annotate src/implab/text/format-compile.js @ 21:7c22fc01fcec

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