UNPKG

3.68 kBJavaScriptView Raw
1var MD = require("./tfw-md");
2var FS = require("fs");
3var Path = require("path");
4var Source = require("./source");
5
6
7module.exports.compile = function(prj) {
8 var svcPath = prj.srcPath("tfw/svc");
9 console.log(svcPath);
10 if (!FS.existsSync(svcPath)) {
11 console.log("No services.");
12 return;
13 }
14 var files = FS.readdirSync(svcPath);
15 fi
16 var services = {};
17 files.forEach(
18 function(f) {
19 var path = Path.join(svcPath, f);
20 if (f.substr(f.length - 4) != '.php') return;
21 var shortName = f.substr(0, f.length - 4);
22 var source = new Source(prj, path);
23 if (!source.isUptodate()) {
24 var html = "<h1>" + shortName + "</h1>" + compile(source.read(), shortName);
25 source.tag("html", html);
26 source.save();
27 }
28 services[shortName] = source.tag("html");
29 }
30 );
31 FS.writeFileSync(
32 prj.docPath("services.js"),
33 "window.SERVICES=" + JSON.stringify(services) + ";"
34 );
35};
36
37
38function compile(content, name) {
39 var level = 0;
40 var mode = null;
41 var role = "";
42 var comment = "";
43 var html = "";
44 var c, i;
45 var rxRole = /^\$ROLE[ \t\n\r]*=[ \t\n\r]*['"]([^'"]*)['"][ \t\n\r]*;/;
46 var rxEnd = /^function[ \t\n\r]+execService[ \t\n\r]*\(/;
47 var rxComment1 = /^\/\/(.+?)[\n\r]+/;
48 var rxComment2 = /^\/\*(([^*]+|\*[^\/])+)\*\//;
49 function hit(text) {
50 if (content.substr(i, text.length) == text) {
51 i += text.length - 1;
52 return true;
53 }
54 return false;
55 }
56 function rx(x) {
57 var match = x.exec(content.substr(i));
58 if (!match) return null;
59 i += match[0].length - 1;
60 return match;
61 }
62 var modes = {
63 search: function() {
64 var match = rx(rxRole);
65 if (match) {
66 role = match[1].toUpperCase();
67 return;
68 }
69 match = rx(rxComment1) || rx(rxComment2);
70 if (match) {
71 comment += match[1] + "\n";
72 return;
73 }
74 match = rx(rxEnd);
75 if (match) {
76 mode = null;
77 return;
78 }
79 return;
80 if (hit('{')) {
81 level++;
82 mode = "block";
83 return;
84 }
85 },
86 block: function() {
87 if (hit('{')) {
88 level++;
89 }
90 else if (hit('}')) {
91 level--;
92 if (level < 1) {
93 comment = "";
94 mode = "search";
95 }
96 }
97 }
98 };
99
100 mode = "search";
101
102 for (i = 0 ; i < content.length ; i++) {
103 if (!mode) {
104 html = MD.toHTML(cleanup(comment));
105 if (role == "") {
106 html = "<div class='public'>Public access</div>" + html;
107 } else {
108 html = "<div class='restricted'>Restricted to " + role + "</div>" + html;
109 }
110 console.log("Service: " + name.yellow + " [" + role.green + "]");
111 return html;
112 }
113 c = content.charAt(i);
114 modes[mode]();
115 }
116 throw "Invalid service: missing function execService()!";
117}
118
119
120function cleanup(comment) {
121 var lines = comment.split("\n");
122 var lines2 = [];
123 var result = "";
124 var min1 = comment.length;
125 var min2 = comment.length;
126 var rx1 = /^[ \t]+/;
127 var rx2 = /^[ \t]*\*[ \t]*/;
128 lines.forEach(
129 function(line) {
130 var trimedLine = line.trim();
131 var emptyLine = trimedLine.length == 0 || trimedLine == "*";
132 line.split("\n").forEach(
133 function(line2) {
134 if (!emptyLine) {
135 var match = rx1.exec(line2);
136 min1 = match ? Math.min(min1, match[0].length) : 0;
137 match = rx2.exec(line2);
138 min2 = match ? Math.min(min2, match[0].length) : 0;
139 }
140 lines2.push(line2);
141 }
142 );
143 }
144 );
145 var skip = Math.max(min1, min2);
146 lines2.forEach(
147 function(line2) {
148 result += line2.substr(skip);
149 }
150 );
151 return result;
152}