346
*/
347
export function template(template: string, values: { [key: string]: string | ISeparator | undefined | null } = Object.create(null)): string {
348
>
const segments: ISegment[] = [];
labels.ts
349
>
350
>
let inVariable = false;
351
>
let curVal = '';
352
>
for (const char of template) {
353
>
// Beginning of variable
354
>
if (char === '$' || (inVariable && char === '{')) {
355
>
if (curVal) {
356
>
segments.push({ value: curVal, type: Type.TEXT });
357
>
}
358
>
359
>
curVal = '';
360
>
inVariable = true;
361
>
}
362
>
363
>
// End of variable
364
>
else if (char === '}' && inVariable) {
365
>
const resolved = values[curVal];
366
>
367
>
// Variable
368
>
if (typeof resolved === 'string') {
369
>
if (resolved.length) {
370
>
segments.push({ value: resolved, type: Type.VARIABLE });
371
>
}
372
>
}
373
>
374
>
// Separator
375
>
else if (resolved) {
376
>
const prevSegment = segments[segments.length - 1];
377
>
if (!prevSegment || prevSegment.type !== Type.SEPARATOR) {
378
>
segments.push({ value: resolved.label, type: Type.SEPARATOR }); // prevent duplicate separators
379
>
}
380
>
}
381
>
382
>
curVal = '';
383
>
inVariable = false;
384
>
}
385
>
386
>
// Text or Variable Name
387
>
else {
388
>
curVal += char;
389
>
}
390
>
}
391
>
392
>
// Tail
393
>
if (curVal && !inVariable) {
394
>
segments.push({ value: curVal, type: Type.TEXT });
395
>
}
396
>
397
>
return segments.filter((segment, index) => {
398
>
399
>
// Only keep separator if we have values to the left and right
400
>
if (segment.type === Type.SEPARATOR) {
401
>
const left = segments[index - 1];
402
>
const right = segments[index + 1];
403
>
404
>
return [left, right].every(segment => segment && (segment.type === Type.VARIABLE || segment.type === Type.TEXT) && segment.value.length > 0);
405
>
}
406
>
407
>
// accept any TEXT and VARIABLE
408
>
return true;
409
>
}).map(segment => segment.value).join('');
410
>
}
411
412
/**