|
| 1 | +/** |
| 2 | + * Creates a tagged template to use for interpolating values into a string. |
| 3 | + * Primarily "inspired" by https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals |
| 4 | + * |
| 5 | + * @example |
| 6 | + * const message = tag `${0} ${'name'}!` |
| 7 | + * message('Hello', { name: 'Amsul' }) // 'Hello Amsul!' |
| 8 | + * |
| 9 | + * @example |
| 10 | + * const message = tag `It goes ${0} ${1} and back to ${0}` |
| 11 | + * message('one', 'two') // 'It goes one two and back to one' |
| 12 | + * |
| 13 | + * @param {String[]} strings The array that contains the string templates. |
| 14 | + * @param {...String|Number} keys The keys to use for interpolating values. |
| 15 | + * @return {Function} The tagged template. |
| 16 | + */ |
| 17 | +export const tag = (strings, ...keys) => (...values) => { |
| 18 | + |
| 19 | + const dict = values[values.length - 1] || {} |
| 20 | + const result = [strings[0]] |
| 21 | + const getValue = createGetValue(values, dict) |
| 22 | + |
| 23 | + keys.forEach((key, index) => { |
| 24 | + const value = getValue(key) |
| 25 | + result.push(value, strings[index + 1]) |
| 26 | + }) |
| 27 | + |
| 28 | + return result.join('') |
| 29 | +} |
| 30 | + |
| 31 | +const createGetValue = (values, dict) => (key) => { |
| 32 | + const value = Number.isInteger(key) ? values[key] : dict[key] |
| 33 | + const valueType = typeof value |
| 34 | + if (valueType !== 'number' && valueType !== 'string') { |
| 35 | + console.error('The value for the key %o must be a string or number: %o', key, value) |
| 36 | + return '' |
| 37 | + } |
| 38 | + return value |
| 39 | +} |
0 commit comments