PageSourceSearch

https://muchoperro.com/webx/~1689229967343~/3rdparty/string-format.js

js muchoperro.com collected 2026-09-29 05:58:46 UTC 9,554 bytes, 332 lines download raw bytes

1void function(global) {
2
3	'use strict';
4  
5	//  ValueError :: String -> Error
6	function ValueError(message) {
7	  var err = new Error (message);
8	  err.name = 'ValueError';
9	  return err;
10	}
11  
12	//  create :: Object -> String,*... -> String
13	function create(transformers) {
14	  return function(template) {
15		var args = Array.prototype.slice.call (arguments, 1);
16		var idx = 0;
17		var state = 'UNDEFINED';
18  
19		return template.replace (
20		  /([{}])\1|[{](.*?)(?:!(.+?))?[}]/g,
21		  function(match, literal, _key, xf) {
22			if (literal != null) {
23			  return literal;
24			}
25			var key = _key;
26			if (key.length > 0) {
27			  if (state === 'IMPLICIT') {
28				throw ValueError ('cannot switch from ' +
29								  'implicit to explicit numbering');
30			  }
31			  state = 'EXPLICIT';
32			} else {
33			  if (state === 'EXPLICIT') {
34				throw ValueError ('cannot switch from ' +
35								  'explicit to implicit numbering');
36			  }
37			  state = 'IMPLICIT';
38			  key = String (idx);
39			  idx += 1;
40			}
41  
42			//  1.  Split the key into a lookup path.
43			//  2.  If the first path component is not an index, prepend '0'.
44			//  3.  Reduce the lookup path to a single result. If the lookup
45			//      succeeds the result is a singleton array containing the
46			//      value at the lookup path; otherwise the result is [].
47			//  4.  Unwrap the result by reducing with '' as the default value.
48			var path = key.split ('.');
49			var value = (/^\d+$/.test (path[0]) ? path : ['0'].concat (path))
50			  .reduce (function(maybe, key) {
51				return maybe.reduce (function(_, x) {
52				  return x != null && key in Object (x) ?
53					[typeof x[key] === 'function' ? x[key] () : x[key]] :
54					[];
55				}, []);
56			  }, [args])
57			  .reduce (function(_, x) { return x; }, '');
58  
59			if (xf == null) {
60			  return value;
61			} else if (Object.prototype.hasOwnProperty.call (transformers, xf)) {
62			  return transformers[xf] (value);
63			} else {
64			  throw ValueError ('no transformer named "' + xf + '"');
65			}
66		  }
67		);
68	  };
69	}
70  
71	//  format :: String,*... -> String
72	var format = create ({});
73  
74	//  format.create :: Object -> String,*... -> String
75	format.create = create;
76  
77	//  format.extend :: Object,Object -> ()
78	format.extend = function(prototype, transformers) {
79	  var $format = create (transformers);
80	  prototype.format = function() {
81		var args = Array.prototype.slice.call (arguments);
82		args.unshift (this);
83		return $format.apply (global, args);
84	  };
85	};
86  
87	/* istanbul ignore else */
88	if (typeof module !== 'undefined') {
89	  module.exports = format;
90	} else if (typeof define === 'function' && define.amd) {
91	  define (function() { return format; });
92	} else {
93	  global.format = format;
94	}
95  
96	/* istanbul ignore if */
97	if (typeof __doctest !== 'undefined') {
98	  format.extend (String.prototype, {});
99	}
100  
101	//. # string-format
102	//.
103	//. string-format is a small JavaScript library for formatting strings,
104	//. based on Python's [`str.format()`][1]. For example:
105	//.
106	//. ```javascript
107	//. > const user = {
108	//. .   firstName: 'Jane',
109	//. .   lastName: 'Smith',
110	//. .   email: '[email protected]',
111	//. . }
112	//. ```
113	//.
114	//. ```javascript
115	//. > '"{firstName} {lastName}" <{email}>'.format (user)
116	//. '"Jane Smith" <[email protected]>'
117	//. ```
118	//.
119	//. The equivalent concatenation:
120	//.
121	//. ```javascript
122	//. > '"' + user.firstName + ' ' + user.lastName + '" <' + user.email + '>'
123	//. '"Jane Smith" <[email protected]>'
124	//. ```
125	//.
126	//. ### Installation
127	//.
128	//. #### Node
129	//.
130	//. 1.  Install:
131	//.
132	//.     ```console
133	//.     $ npm install string-format
134	//.     ```
135	//.
136	//. 2.  Require:
137	//.
138	//.     ```javascript
139	//.     const format = require ('string-format')
140	//.     ```
141	//.
142	//. #### Browser
143	//.
144	//. 1.  Define `window.format`:
145	//.
146	//.     ```html
147	//.     <script src="path/to/string-format.js"></script>
148	//.     ```
149	//.
150	//. ### Modes
151	//.
152	//. string-format can be used in two modes: [function mode](#function-mode)
153	//. and [method mode](#method-mode).
154	//.
155	//. #### Function mode
156	//.
157	//. ```javascript
158	//. > format ('Hello, {}!', 'Alice')
159	//. 'Hello, Alice!'
160	//. ```
161	//.
162	//. In this mode the first argument is a template string and the remaining
163	//. arguments are values to be interpolated.
164	//.
165	//. #### Method mode
166	//.
167	//. ```javascript
168	//. > 'Hello, {}!'.format ('Alice')
169	//. 'Hello, Alice!'
170	//. ```
171	//.
172	//. In this mode values to be interpolated are supplied to the `format`
173	//. method of a template string. This mode is not enabled by default.
174	//. The method must first be defined via [`format.extend`](#format.extend):
175	//.
176	//. ```javascript
177	//. > format.extend (String.prototype, {})
178	//. ```
179	//.
180	//. `format (template, $0, $1, …, $N)` and `template.format ($0, $1, …, $N)`
181	//. can then be used interchangeably.
182	//.
183	//. <a name="format"></a>
184	//.
185	//. ### `format (template, $0, $1, …, $N)`
186	//.
187	//. Returns the result of replacing each `{…}` placeholder in the template
188	//. string with its corresponding replacement.
189	//.
190	//. Placeholders may contain numbers which refer to positional arguments:
191	//.
192	//. ```javascript
193	//. > '{0}
193, you have {1} unread message{2}'.format ('Holly', 2, 's')
194	//. 'Holly, you have 2 unread messages'
195	//. ```
196	//.
197	//. Unmatched placeholders produce no output:
198	//.
199	//. ```javascript
200	//. > '{0}, you have {1} unread message{2}'.format ('Steve', 1)
201	//. 'Steve, you have 1 unread message'
202	//. ```
203	//.
204	//. A format string may reference a positional argument multiple times:
205	//.
206	//. ```javascript
207	//. > "The name's {1}. {0} {1}.".format ('James', 'Bond')
208	//. "The name's Bond. James Bond."
209	//. ```
210	//.
211	//. Positional arguments may be referenced implicitly:
212	//.
213	//. ```javascript
214	//. > '{}, you have {} unread message{}'.format ('Steve', 1)
215	//. 'Steve, you have 1 unread message'
216	//. ```
217	//.
218	//. A format string must not contain both implicit and explicit references:
219	//.
220	//. ```javascript
221	//. > 'My name is {} {}. Do you like the name {0}?'.format ('Lemony', 'Snicket')
222	//. ! ValueError: cannot switch from implicit to explicit numbering
223	//. ```
224	//.
225	//. `{{` and `}}` in format strings produce `{` and `}`:
226	//.
227	//. ```javascript
228	//. > '{{}} creates an empty {} in {}'.format ('dictionary', 'Python')
229	//. '{} creates an empty dictionary in Python'
230	//. ```
231	//.
232	//. Dot notation may be used to reference object properties:
233	//.
234	//. ```javascript
235	//. > const bobby = {firstName: 'Bobby', lastName: 'Fischer'}
236	//. > const garry = {firstName: 'Garry', lastName: 'Kasparov'}
237	//.
238	//. > '{0.firstName} {0.lastName} vs. {1.firstName} {1.lastName}'.format (bobby, garry)
239	//. 'Bobby Fischer vs. Garry Kasparov'
240	//. ```
241	//.
242	//. `0.` may be omitted when referencing a property of `{0}`:
243	//.
244	//. ```javascript
245	//. > const repo = {owner: 'davidchambers', slug: 'string-format'}
246	//.
247	//. > 'https://github.com/{owner}/{slug}'.format (repo)
248	//. 'https://github.com/davidchambers/string-format'
249	//. ```
250	//.
251	//. If the referenced property is a method, it is invoked with no arguments
252	//. to determine the replacement:
253	//.
254	//. ```javascript
255	//. > const sheldon = {
256	//. .   firstName: 'Sheldon',
257	//. .   lastName: 'Cooper',
258	//. .   dob: new Date ('1970-01-01'),
259	//. .   fullName: function() { return this.firstName + ' ' + this.lastName },
260	//. .   quip: function() { return 'Bazinga!' },
261	//. . }
262	//.
263	//. > '{fullName} was born at precisely {dob.toISOString}'.format (sheldon)
264	//. 'Sheldon Cooper was born at precisely 1970-01-01T00:00:00.000Z'
265	//.
266	//. > "I've always wanted to go to a goth club. {quip.toUpperCase}".format (sheldon)
267	//. "I've always wanted to go to a goth club. BAZINGA!"
268	//. ```
269	//.
270	//. <a name="format.create"></a>
271	//.
272	//. ### `format.create (transformers)`
273	//.
274	//. This function takes an object mapping names to transformers and returns
275	//. a formatting function. A transformer is applied if its name appears,
276	//. prefixed with `!`, after a field name in a template string.
277	//.
278	//. ```javascript
279	//. > const fmt = format.create ({
280	//. .   escape: s =>
281	//. .     s.replace (/[&<>"'`]/g, c => '&#' + c.charCodeAt (0) + ';'),
282	//. .   upper: s =>
283	//. .     s.toUpperCase (),
284	//. . })
285	//.
286	//. > fmt ('Hello, {!upper}!', 'Alice')
287	//. 'Hello, ALICE!'
288	//.
289	//. > fmt ('<a href="{url!escape}">{name!escape}</a>', {
290	//. .   name: 'Anchor & Hope',
291	//. .   url: 'http://anchorandhopesf.com/',
292	//. . })
293	//. '<a href="http://anchorandhopesf.com/">Anchor &#38; Hope</a>'
294	//. ```
295	//.
296	//. <a name="format.extend"></a>
297	//.
298	//. ### `format.extend (prototype, transformers)`
299	//.
300	//. This function takes a prototype (presumably `String.prototype`) and an
301	//. object mapping names to transformers, and defines a `format` method on
302	//. the prototype. A transformer is applied if its name appears, prefixed
303	//. with `!`, after a field name in a template string.
304	//.
305	//. ```javascript
306	//. > format.extend (String.prototype, {
307	//. .   escape: s =>
308	//. .     s.replace (/[&<>"'`]/g, c => '&#' + c.charCodeAt (0) + ';'),
309	//. .   upper: s =>
310	//. .     s.toUpperCase (),
311	//. . })
312	//.
313	//. > 'Hello, {!upper}!'.format ('Alice')
314	//. 'Hello, ALICE!'
315	//.
316	//. > '<a href="{url!escape}">{name!escape}</a>'.format ({
317	//. .   name: 'Anchor & Hope',
318	//. .   url: 'http://anchorandhopesf.com/',
319	//. . })
320	//. '<a href="http://anchorandhopesf.com/">Anchor &#38; Hope</a>'
321	//. ```
322	//.
323	//. ### Running the test suite
324	//.
325	//. ```console
326	//. $ npm install
327	//. $ npm test
328	//. ```
329	//.
330	//. [1]: http://docs.python.org/library/stdtypes.html#str.format
331  
332  }.call (this, this);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.