puglite 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var uglify = require('uglify-js');
5
+ var runtime = require('./');
6
+
7
+ try {
8
+ fs.mkdirSync(__dirname + '/lib');
9
+ } catch (ex) {
10
+ if (ex.code !== 'EEXIST') throw ex;
11
+ }
12
+ var source = fs.readFileSync(__dirname + '/index.js', 'utf8');
13
+ var ast = uglify.parse(source);
14
+
15
+ var dependencies = {};
16
+ var internals = {dependencies: true, internals: true};
17
+ var sources = {};
18
+ ast.body.forEach(function(node) {
19
+ var name;
20
+ switch (node.TYPE) {
21
+ case 'Defun':
22
+ name = node.name.name;
23
+ break;
24
+ case 'Var':
25
+ name = node.definitions[0].name.name;
26
+ break;
27
+ }
28
+ if (!name || !/^pug\_/.test(name)) return;
29
+ name = name.replace(/^pug\_/, '');
30
+
31
+ var src = uglify.minify(source.substring(node.start.pos, node.end.endpos), {
32
+ fromString: true,
33
+ }).code;
34
+ sources[name] = src;
35
+
36
+ dependencies[name] = [];
37
+ if (node.TYPE === 'Defun') {
38
+ var ast = uglify.parse(src);
39
+ ast.figure_out_scope();
40
+ var globals = ast.globals.map(function(val, key) {
41
+ return key;
42
+ });
43
+ dependencies[name] = globals
44
+ .filter(function(key) {
45
+ return /^pug\_/.test(key);
46
+ })
47
+ .map(function(key) {
48
+ return key.replace(/^pug\_/, '');
49
+ });
50
+ }
51
+
52
+ if (!runtime[name]) internals[name] = true;
53
+ });
54
+
55
+ Object.keys(dependencies).forEach(function(fn) {
56
+ dependencies[fn] = dependencies[fn].sort();
57
+ });
58
+
59
+ fs.writeFileSync(
60
+ __dirname + '/lib/dependencies.js',
61
+ 'module.exports = ' + JSON.stringify(dependencies, null, 2) + '\n'
62
+ );
63
+ fs.writeFileSync(
64
+ __dirname + '/lib/internals.js',
65
+ 'module.exports = ' + JSON.stringify(internals, null, 2) + '\n'
66
+ );
67
+ fs.writeFileSync(
68
+ __dirname + '/lib/sources.js',
69
+ 'module.exports = ' + JSON.stringify(sources, null, 2) + '\n'
70
+ );
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var dependencies = require('./runtime-lib/dependencies.js');
5
+ var internals = require('./runtime-lib/internals.js');
6
+ var sources = require('./runtime-lib/sources.js');
7
+
8
+ module.exports = build;
9
+
10
+ function build(functions) {
11
+ var fns = [];
12
+ functions = functions.filter(function(fn) {
13
+ return !internals[fn];
14
+ });
15
+ for (var i = 0; i < functions.length; i++) {
16
+ if (fns.indexOf(functions[i]) === -1) {
17
+ fns.push(functions[i]);
18
+ functions.push.apply(functions, dependencies[functions[i]]);
19
+ }
20
+ }
21
+ return fns
22
+ .sort()
23
+ .map(function(name) {
24
+ return sources[name];
25
+ })
26
+ .join('\n');
27
+ }
@@ -0,0 +1,34 @@
1
+ module.exports = {
2
+ "has_own_property": [],
3
+ "merge": [
4
+ "style"
5
+ ],
6
+ "classes_array": [
7
+ "classes",
8
+ "escape"
9
+ ],
10
+ "classes_object": [
11
+ "has_own_property"
12
+ ],
13
+ "classes": [
14
+ "classes_array",
15
+ "classes_object"
16
+ ],
17
+ "style": [
18
+ "has_own_property"
19
+ ],
20
+ "attr": [
21
+ "escape"
22
+ ],
23
+ "attrs": [
24
+ "attr",
25
+ "classes",
26
+ "has_own_property",
27
+ "style"
28
+ ],
29
+ "match_html": [],
30
+ "escape": [
31
+ "match_html"
32
+ ],
33
+ "rethrow": []
34
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ "dependencies": true,
3
+ "internals": true,
4
+ "has_own_property": true,
5
+ "classes_array": true,
6
+ "classes_object": true,
7
+ "match_html": true
8
+ }
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ "has_own_property": "var pug_has_own_property=Object.prototype.hasOwnProperty;",
3
+ "merge": "function pug_merge(e,r){if(1===arguments.length){for(var t=e[0],g=1;g<e.length;g++)t=pug_merge(t,e[g]);return t}for(var l in r)if(\"class\"===l){var n=e[l]||[];e[l]=(Array.isArray(n)?n:[n]).concat(r[l]||[])}else if(\"style\"===l){var n=pug_style(e[l]);n=n&&\";\"!==n[n.length-1]?n+\";\":n;var a=pug_style(r[l]);a=a&&\";\"!==a[a.length-1]?a+\";\":a,e[l]=n+a}else e[l]=r[l];return e}",
4
+ "classes_array": "function pug_classes_array(r,a){for(var s,e=\"\",u=\"\",c=Array.isArray(a),g=0;g<r.length;g++)s=pug_classes(r[g]),s&&(c&&a[g]&&(s=pug_escape(s)),e=e+u+s,u=\" \");return e}",
5
+ "classes_object": "function pug_classes_object(r){var a=\"\",n=\"\";for(var o in r)o&&r[o]&&pug_has_own_property.call(r,o)&&(a=a+n+o,n=\" \");return a}",
6
+ "classes": "function pug_classes(s,r){return Array.isArray(s)?pug_classes_array(s,r):s&&\"object\"==typeof s?pug_classes_object(s):s||\"\"}",
7
+ "style": "function pug_style(r){if(!r)return\"\";if(\"object\"==typeof r){var t=\"\";for(var e in r)pug_has_own_property.call(r,e)&&(t=t+e+\":\"+r[e]+\";\");return t}return r+\"\"}",
8
+ "attr": "function pug_attr(t,e,n,r){if(e===!1||null==e||!e&&(\"class\"===t||\"style\"===t))return\"\";if(e===!0)return\" \"+(r?t:t+'=\"'+t+'\"');var f=typeof e;return\"object\"!==f&&\"function\"!==f||\"function\"!=typeof e.toJSON||(e=e.toJSON()),\"string\"==typeof e||(e=JSON.stringify(e),n||e.indexOf('\"')===-1)?(n&&(e=pug_escape(e)),\" \"+t+'=\"'+e+'\"'):\" \"+t+\"='\"+e.replace(/'/g,\"&#39;\")+\"'\"}",
9
+ "attrs": "function pug_attrs(t,r){var a=\"\";for(var s in t)if(pug_has_own_property.call(t,s)){var u=t[s];if(\"class\"===s){u=pug_classes(u),a=pug_attr(s,u,!1,r)+a;continue}\"style\"===s&&(u=pug_style(u)),a+=pug_attr(s,u,!1,r)}return a}",
10
+ "match_html": "var pug_match_html=/[\"&<>]/;",
11
+ "escape": "function pug_escape(e){var a=\"\"+e,t=pug_match_html.exec(a);if(!t)return e;var r,c,n,s=\"\";for(r=t.index,c=0;r<a.length;r++){switch(a.charCodeAt(r)){case 34:n=\"&quot;\";break;case 38:n=\"&amp;\";break;case 60:n=\"&lt;\";break;case 62:n=\"&gt;\";break;default:continue}c!==r&&(s+=a.substring(c,r)),c=r+1,s+=n}return c!==r?s+a.substring(c,r):s}",
12
+ "rethrow": "function pug_rethrow(e,n,r,t){if(!(e instanceof Error))throw e;if(!(\"undefined\"==typeof window&&n||t))throw e.message+=\" on line \"+r,e;var o,a,i,s;try{t=t||require(\"fs\").readFileSync(n,{encoding:\"utf8\"}),o=3,a=t.split(\"\\n\"),i=Math.max(r-o,0),s=Math.min(a.length,r+o)}catch(t){return e.message+=\" - could not read from \"+n+\" (\"+t.message+\")\",void pug_rethrow(e,null,r)}o=a.slice(i,s).map(function(e,n){var t=n+i+1;return(t==r?\" > \":\" \")+t+\"| \"+e}).join(\"\\n\"),e.path=n;try{e.message=(n||\"Pug\")+\":\"+r+\"\\n\"+o+\"\\n\\n\"+e.message}catch(e){}throw e}"
13
+ }
@@ -0,0 +1,10 @@
1
+ var runtime = require('./runtime');
2
+
3
+ module.exports = wrap;
4
+ function wrap(template, templateName) {
5
+ templateName = templateName || 'template';
6
+ return Function(
7
+ 'pug',
8
+ template + '\n' + 'return ' + templateName + ';'
9
+ )(runtime);
10
+ }
package/lib/runtime.js ADDED
@@ -0,0 +1,287 @@
1
+ 'use strict';
2
+
3
+ var pug_has_own_property = Object.prototype.hasOwnProperty;
4
+
5
+ /**
6
+ * Merge two attribute objects giving precedence
7
+ * to values in object `b`. Classes are special-cased
8
+ * allowing for arrays and merging/joining appropriately
9
+ * resulting in a string.
10
+ *
11
+ * @param {Object} a
12
+ * @param {Object} b
13
+ * @return {Object} a
14
+ * @api private
15
+ */
16
+
17
+ exports.merge = pug_merge;
18
+ function pug_merge(a, b) {
19
+ if (arguments.length === 1) {
20
+ var attrs = a[0];
21
+ for (var i = 1; i < a.length; i++) {
22
+ attrs = pug_merge(attrs, a[i]);
23
+ }
24
+ return attrs;
25
+ }
26
+
27
+ for (var key in b) {
28
+ if (key === 'class') {
29
+ var valA = a[key] || [];
30
+ a[key] = (Array.isArray(valA) ? valA : [valA]).concat(b[key] || []);
31
+ } else if (key === 'style') {
32
+ var valA = pug_style(a[key]);
33
+ valA = valA && valA[valA.length - 1] !== ';' ? valA + ';' : valA;
34
+ var valB = pug_style(b[key]);
35
+ valB = valB && valB[valB.length - 1] !== ';' ? valB + ';' : valB;
36
+ a[key] = valA + valB;
37
+ } else {
38
+ a[key] = b[key];
39
+ }
40
+ }
41
+
42
+ return a;
43
+ }
44
+
45
+ /**
46
+ * Process array, object, or string as a string of classes delimited by a space.
47
+ *
48
+ * If `val` is an array, all members of it and its subarrays are counted as
49
+ * classes. If `escaping` is an array, then whether or not the item in `val` is
50
+ * escaped depends on the corresponding item in `escaping`. If `escaping` is
51
+ * not an array, no escaping is done.
52
+ *
53
+ * If `val` is an object, all the keys whose value is truthy are counted as
54
+ * classes. No escaping is done.
55
+ *
56
+ * If `val` is a string, it is counted as a class. No escaping is done.
57
+ *
58
+ * @param {(Array.<string>|Object.<string, boolean>|string)} val
59
+ * @param {?Array.<string>} escaping
60
+ * @return {String}
61
+ */
62
+ exports.classes = pug_classes;
63
+ function pug_classes_array(val, escaping) {
64
+ var classString = '',
65
+ className,
66
+ padding = '',
67
+ escapeEnabled = Array.isArray(escaping);
68
+ for (var i = 0; i < val.length; i++) {
69
+ className = pug_classes(val[i]);
70
+ if (!className) continue;
71
+ escapeEnabled && escaping[i] && (className = pug_escape(className));
72
+ classString = classString + padding + className;
73
+ padding = ' ';
74
+ }
75
+ return classString;
76
+ }
77
+ function pug_classes_object(val) {
78
+ var classString = '',
79
+ padding = '';
80
+ for (var key in val) {
81
+ if (key && val[key] && pug_has_own_property.call(val, key)) {
82
+ classString = classString + padding + key;
83
+ padding = ' ';
84
+ }
85
+ }
86
+ return classString;
87
+ }
88
+ function pug_classes(val, escaping) {
89
+ if (Array.isArray(val)) {
90
+ return pug_classes_array(val, escaping);
91
+ } else if (val && typeof val === 'object') {
92
+ return pug_classes_object(val);
93
+ } else {
94
+ return val || '';
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Convert object or string to a string of CSS styles delimited by a semicolon.
100
+ *
101
+ * @param {(Object.<string, string>|string)} val
102
+ * @return {String}
103
+ */
104
+
105
+ exports.style = pug_style;
106
+ function pug_style(val) {
107
+ if (!val) return '';
108
+ if (typeof val === 'object') {
109
+ var out = '';
110
+ for (var style in val) {
111
+ /* istanbul ignore else */
112
+ if (pug_has_own_property.call(val, style)) {
113
+ out = out + style + ':' + val[style] + ';';
114
+ }
115
+ }
116
+ return out;
117
+ } else {
118
+ return val + '';
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Render the given attribute.
124
+ *
125
+ * @param {String} key
126
+ * @param {String} val
127
+ * @param {Boolean} escaped
128
+ * @param {Boolean} terse
129
+ * @return {String}
130
+ */
131
+ exports.attr = pug_attr;
132
+ function pug_attr(key, val, escaped, terse) {
133
+ if (
134
+ val === false ||
135
+ val == null ||
136
+ (!val && (key === 'class' || key === 'style'))
137
+ ) {
138
+ return '';
139
+ }
140
+ if (val === true) {
141
+ var useTerse = terse || key.charAt(0) === '#';
142
+ return ' ' + (useTerse ? key : key + '="' + key + '"');
143
+ }
144
+ var type = typeof val;
145
+ if (
146
+ (type === 'object' || type === 'function') &&
147
+ typeof val.toJSON === 'function'
148
+ ) {
149
+ val = val.toJSON();
150
+ }
151
+ if (typeof val !== 'string') {
152
+ val = JSON.stringify(val);
153
+ if (!escaped && val.indexOf('"') !== -1) {
154
+ return ' ' + key + "='" + val.replace(/'/g, '&#39;') + "'";
155
+ }
156
+ }
157
+ if (escaped) val = pug_escape(val);
158
+ return ' ' + key + '="' + val + '"';
159
+ }
160
+
161
+ /**
162
+ * Render the given attributes object.
163
+ *
164
+ * @param {Object} obj
165
+ * @param {Object} terse whether to use HTML5 terse boolean attributes
166
+ * @return {String}
167
+ */
168
+ exports.attrs = pug_attrs;
169
+ function pug_attrs(obj, terse) {
170
+ var attrs = '';
171
+
172
+ for (var key in obj) {
173
+ if (pug_has_own_property.call(obj, key)) {
174
+ var val = obj[key];
175
+
176
+ if ('class' === key) {
177
+ val = pug_classes(val);
178
+ attrs = pug_attr(key, val, false, terse) + attrs;
179
+ continue;
180
+ }
181
+ if ('style' === key) {
182
+ val = pug_style(val);
183
+ }
184
+ attrs += pug_attr(key, val, false, terse);
185
+ }
186
+ }
187
+
188
+ return attrs;
189
+ }
190
+
191
+ /**
192
+ * Escape the given string of `html`.
193
+ *
194
+ * @param {String} html
195
+ * @return {String}
196
+ * @api private
197
+ */
198
+
199
+ var pug_match_html = /["&<>]/;
200
+ exports.escape = pug_escape;
201
+ function pug_escape(_html) {
202
+ var html = '' + _html;
203
+ var regexResult = pug_match_html.exec(html);
204
+ if (!regexResult) return _html;
205
+
206
+ var result = '';
207
+ var i, lastIndex, escape;
208
+ for (i = regexResult.index, lastIndex = 0; i < html.length; i++) {
209
+ switch (html.charCodeAt(i)) {
210
+ case 34:
211
+ escape = '&quot;';
212
+ break;
213
+ case 38:
214
+ escape = '&amp;';
215
+ break;
216
+ case 60:
217
+ escape = '&lt;';
218
+ break;
219
+ case 62:
220
+ escape = '&gt;';
221
+ break;
222
+ default:
223
+ continue;
224
+ }
225
+ if (lastIndex !== i) result += html.substring(lastIndex, i);
226
+ lastIndex = i + 1;
227
+ result += escape;
228
+ }
229
+ if (lastIndex !== i) return result + html.substring(lastIndex, i);
230
+ else return result;
231
+ }
232
+
233
+ /**
234
+ * Re-throw the given `err` in context to the
235
+ * the pug in `filename` at the given `lineno`.
236
+ *
237
+ * @param {Error} err
238
+ * @param {String} filename
239
+ * @param {String} lineno
240
+ * @param {String} str original source
241
+ * @api private
242
+ */
243
+
244
+ exports.rethrow = pug_rethrow;
245
+ function pug_rethrow(err, filename, lineno, str) {
246
+ if (!(err instanceof Error)) throw err;
247
+ if ((typeof window != 'undefined' || !filename) && !str) {
248
+ err.message += ' on line ' + lineno;
249
+ throw err;
250
+ }
251
+ var context, lines, start, end;
252
+ try {
253
+ str = str || require('fs').readFileSync(filename, {encoding: 'utf8'});
254
+ context = 3;
255
+ lines = str.split('\n');
256
+ start = Math.max(lineno - context, 0);
257
+ end = Math.min(lines.length, lineno + context);
258
+ } catch (ex) {
259
+ err.message +=
260
+ ' - could not read from ' + filename + ' (' + ex.message + ')';
261
+ pug_rethrow(err, null, lineno);
262
+ return;
263
+ }
264
+
265
+ // Error context
266
+ context = lines
267
+ .slice(start, end)
268
+ .map(function(line, i) {
269
+ var curr = i + start + 1;
270
+ return (curr == lineno ? ' > ' : ' ') + curr + '| ' + line;
271
+ })
272
+ .join('\n');
273
+
274
+ // Alter exception message
275
+ err.path = filename;
276
+ try {
277
+ err.message =
278
+ (filename || 'Pug') +
279
+ ':' +
280
+ lineno +
281
+ '\n' +
282
+ context +
283
+ '\n\n' +
284
+ err.message;
285
+ } catch (e) {}
286
+ throw err;
287
+ }
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ var error = require('./error');
4
+
5
+ module.exports = stripComments;
6
+
7
+ function unexpectedToken(type, occasion, filename, line) {
8
+ var msg = '`' + type + '` encountered when ' + occasion;
9
+ throw error('UNEXPECTED_TOKEN', msg, {filename: filename, line: line});
10
+ }
11
+
12
+ function stripComments(input, options) {
13
+ options = options || {};
14
+
15
+ // Default: strip unbuffered comments and leave buffered ones alone
16
+ var stripUnbuffered = options.stripUnbuffered !== false;
17
+ var stripBuffered = options.stripBuffered === true;
18
+ var filename = options.filename;
19
+
20
+ var out = [];
21
+ // If we have encountered a comment token and are not sure if we have gotten
22
+ // out of the comment or not
23
+ var inComment = false;
24
+ // If we are sure that we are in a block comment and all tokens except
25
+ // `end-pipeless-text` should be ignored
26
+ var inPipelessText = false;
27
+
28
+ return input.filter(function(tok) {
29
+ switch (tok.type) {
30
+ case 'comment':
31
+ if (inComment) {
32
+ unexpectedToken(
33
+ 'comment',
34
+ 'already in a comment',
35
+ filename,
36
+ tok.line
37
+ );
38
+ } else {
39
+ inComment = tok.buffer ? stripBuffered : stripUnbuffered;
40
+ return !inComment;
41
+ }
42
+ case 'start-pipeless-text':
43
+ if (!inComment) return true;
44
+ if (inPipelessText) {
45
+ unexpectedToken(
46
+ 'start-pipeless-text',
47
+ 'already in pipeless text mode',
48
+ filename,
49
+ tok.line
50
+ );
51
+ }
52
+ inPipelessText = true;
53
+ return false;
54
+ case 'end-pipeless-text':
55
+ if (!inComment) return true;
56
+ if (!inPipelessText) {
57
+ unexpectedToken(
58
+ 'end-pipeless-text',
59
+ 'not in pipeless text mode',
60
+ filename,
61
+ tok.line
62
+ );
63
+ }
64
+ inPipelessText = false;
65
+ inComment = false;
66
+ return false;
67
+ // There might be a `text` right after `comment` but before
68
+ // `start-pipeless-text`. Treat it accordingly.
69
+ case 'text':
70
+ return !inComment;
71
+ default:
72
+ if (inPipelessText) return false;
73
+ inComment = false;
74
+ return true;
75
+ }
76
+ });
77
+ }
package/lib/wrap.js ADDED
@@ -0,0 +1,10 @@
1
+ var runtime = require('./');
2
+
3
+ module.exports = wrap;
4
+ function wrap(template, templateName) {
5
+ templateName = templateName || 'template';
6
+ return Function(
7
+ 'pug',
8
+ template + '\n' + 'return ' + templateName + ';'
9
+ )(runtime);
10
+ }
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "puglite",
3
+ "version": "1.0.0",
4
+ "description": "A clean, whitespace-sensitive template language for writing HTML",
5
+ "keywords": [
6
+ "html",
7
+ "jade",
8
+ "pug",
9
+ "template"
10
+ ],
11
+ "license": "MIT",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/raykin/puglite"
15
+ },
16
+ "main": "lib",
17
+ "builders": "builders.json",
18
+ "exports": {
19
+ ".": "./lib/index.js",
20
+ "./angular-webpack": "./angular-webpack/index.js",
21
+ "./builders/browser": "./builders/browser/index.js",
22
+ "./builders/dev-server": "./builders/dev-server/index.js",
23
+ "./builders/karma": "./builders/karma/index.js",
24
+ "./builders/vitest": "./builders/vitest/index.js",
25
+ "./builders.json": "./builders.json",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "lib/",
30
+ "angular-webpack/",
31
+ "builders.json",
32
+ "builders/"
33
+ ],
34
+ "scripts": {
35
+ "test": "jest",
36
+ "coverage": "jest --coverage",
37
+ "watch": "jest --watch"
38
+ },
39
+ "jest": {
40
+ "testEnvironment": "node",
41
+ "testMatch": [
42
+ "**/*.test.js"
43
+ ]
44
+ },
45
+ "dependencies": {
46
+ "character-parser": "^4.0.0",
47
+ "constantinople": "^4.0.1",
48
+ "doctypes": "^1.1.0",
49
+ "is-expression": "^4.0.0",
50
+ "js-stringify": "^1.0.2",
51
+ "token-stream": "^1.0.0",
52
+ "void-elements": "^3.1.0",
53
+ "with": "^7.0.2"
54
+ },
55
+ "devDependencies": {
56
+ "jest": "^30.2.0",
57
+ "uglify-js": "^3.19.3"
58
+ },
59
+ "peerDependencies": {
60
+ "@angular-builders/custom-webpack": ">=18.0.0",
61
+ "@angular-devkit/architect": ">=0.1800.0",
62
+ "@angular-devkit/build-angular": ">=18.0.0"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "@angular-builders/custom-webpack": {
66
+ "optional": true
67
+ }
68
+ },
69
+ "browser": {
70
+ "fs": false
71
+ }
72
+ }