source: node_modules/es-toolkit/dist/compat/string/template.js

Last change on this file was a762898, checked in by istevanoska <ilinastevanoska@…>, 5 months ago

Added visualizations

  • Property mode set to 100644
File size: 3.3 KB
RevLine 
[a762898]1'use strict';
2
3Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
5const escape = require('./escape.js');
6const attempt = require('../function/attempt.js');
7const defaults = require('../object/defaults.js');
8const toString = require('../util/toString.js');
9
10const esTemplateRegExp = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
11const unEscapedRegExp = /['\n\r\u2028\u2029\\]/g;
12const noMatchExp = /($^)/;
13const escapeMap = new Map([
14 ['\\', '\\'],
15 ["'", "'"],
16 ['\n', 'n'],
17 ['\r', 'r'],
18 ['\u2028', 'u2028'],
19 ['\u2029', 'u2029'],
20]);
21function escapeString(match) {
22 return `\\${escapeMap.get(match)}`;
23}
24const defaultInterpolateRegExp = /<%=([\s\S]+?)%>/g;
25const templateSettings = {
26 escape: /<%-([\s\S]+?)%>/g,
27 evaluate: /<%([\s\S]+?)%>/g,
28 interpolate: defaultInterpolateRegExp,
29 variable: '',
30 imports: {
31 _: {
32 escape: escape.escape,
33 template,
34 },
35 },
36};
37function template(string, options, guard) {
38 string = toString.toString(string);
39 if (guard) {
40 options = templateSettings;
41 }
42 options = defaults.defaults({ ...options }, templateSettings);
43 const delimitersRegExp = new RegExp([
44 options.escape?.source ?? noMatchExp.source,
45 options.interpolate?.source ?? noMatchExp.source,
46 options.interpolate === defaultInterpolateRegExp ? esTemplateRegExp.source : noMatchExp.source,
47 options.evaluate?.source ?? noMatchExp.source,
48 '$',
49 ].join('|'), 'g');
50 let lastIndex = 0;
51 let isEvaluated = false;
52 let source = `__p += ''`;
53 for (const match of string.matchAll(delimitersRegExp)) {
54 const [fullMatch, escapeValue, interpolateValue, esTemplateValue, evaluateValue] = match;
55 const { index } = match;
56 source += ` + '${string.slice(lastIndex, index).replace(unEscapedRegExp, escapeString)}'`;
57 if (escapeValue) {
58 source += ` + _.escape(${escapeValue})`;
59 }
60 if (interpolateValue) {
61 source += ` + ((${interpolateValue}) == null ? '' : ${interpolateValue})`;
62 }
63 else if (esTemplateValue) {
64 source += ` + ((${esTemplateValue}) == null ? '' : ${esTemplateValue})`;
65 }
66 if (evaluateValue) {
67 source += `;\n${evaluateValue};\n __p += ''`;
68 isEvaluated = true;
69 }
70 lastIndex = index + fullMatch.length;
71 }
72 const imports = defaults.defaults({ ...options.imports }, templateSettings.imports);
73 const importsKeys = Object.keys(imports);
74 const importValues = Object.values(imports);
75 const sourceURL = `//# sourceURL=${options.sourceURL ? String(options.sourceURL).replace(/[\r\n]/g, ' ') : `es-toolkit.templateSource[${Date.now()}]`}\n`;
76 const compiledFunction = `function(${options.variable || 'obj'}) {
77 let __p = '';
78 ${options.variable ? '' : 'if (obj == null) { obj = {}; }'}
79 ${isEvaluated ? `function print() { __p += Array.prototype.join.call(arguments, ''); }` : ''}
80 ${options.variable ? source : `with(obj) {\n${source}\n}`}
81 return __p;
82 }`;
83 const result = attempt.attempt(() => new Function(...importsKeys, `${sourceURL}return ${compiledFunction}`)(...importValues));
84 result.source = compiledFunction;
85 if (result instanceof Error) {
86 throw result;
87 }
88 return result;
89}
90
91exports.template = template;
92exports.templateSettings = templateSettings;
Note: See TracBrowser for help on using the repository browser.