UNPKG

7.98 kBTypeScriptView Raw
1export as namespace commonTags;
2
3export type JSTag = (literals: TemplateStringsArray, ...placeholders: any[]) => string;
4
5export interface TemplateTag {
6 (str: string): string;
7 (tag: JSTag): TemplateTag;
8 (literals: TemplateStringsArray, ...placeholders: any[]): string;
9}
10
11/**
12 * You'll often find that you might want to include an array in a template.
13 * Typically, doing something like `${array.join(', ')}` would work - but what if you're printing a list of items
14 * in an HTML template and want to maintain the indentation? You'd have to count the spaces manually and include
15 * them in the `.join()` call - which is a bit ugly for my taste.
16 * This tag properly indents arrays, as well as newline characters in string substitutions,
17 * by converting them to an array split by newline and re-using the same array inclusion logic.
18 */
19export const html: TemplateTag;
20
21/**
22 * alias for `html`
23 */
24export const codeBlock: TemplateTag;
25
26/**
27 * alias for `html`
28 */
29export const source: TemplateTag;
30
31/**
32 * A tag very similar to `html` but it does safe HTML escaping for strings coming from substitutions.
33 * When combined with regular `html` tag, you can do basic HTML templating that is safe from
34 * XSS (Cross-Site Scripting) attacks.
35 */
36export const safeHtml: TemplateTag;
37
38/**
39 * Allows you to keep your single-line strings under 80 characters without resorting to crazy string concatenation.
40 */
41export const oneLine: TemplateTag;
42
43/**
44 * Allows you to keep your single-line strings under 80 characters while trimming the new lines.
45 */
46export const oneLineTrim: TemplateTag;
47
48/**
49 * If you want to strip the initial indentation from the beginning of each line in a multiline string.
50 * Important note: this tag will not indent multiline strings coming from the substitutions.
51 * If you want that behavior, use the `html` tag (aliases: `source`, `codeBlock`).
52 */
53export const stripIndent: TemplateTag;
54
55/**
56 * If you want to strip *all* of the indentation from the beginning of each line in a multiline string.
57 */
58export const stripIndents: TemplateTag;
59
60/**
61 * Allows you to inline an array substitution as a list.
62 */
63export const inlineLists: TemplateTag;
64
65/**
66 * Allows you to inline an array substitution as a list, rendered out on a single line.
67 */
68export const oneLineInlineLists: TemplateTag;
69
70/**
71 * Allows you to inline an array substitution as a comma-separated list.
72 */
73export const commaLists: TemplateTag;
74
75/**
76 * Allows you to inline an array substitution as a comma-separated list, the last of which is preceded by the word "or".
77 */
78export const commaListsOr: TemplateTag;
79
80/**
81 * Allows you to inline an array substitution as a comma-separated list, the last of which is preceded by the word "and".
82 */
83export const commaListsAnd: TemplateTag;
84
85/**
86 * Allows you to inline an array substitution as a comma-separated list, and is rendered out on to a single line.
87 */
88export const oneLineCommaLists: TemplateTag;
89
90/**
91 * Allows you to inline an array substitution as a comma-separated list, the last of which is preceded by the word "or", and is rendered out on to a single line.
92 */
93export const oneLineCommaListsOr: TemplateTag;
94
95/**
96 * Allows you to inline an array substitution as a comma-separated list, the last of which is preceded by the word "and", and is rendered out on to a single line.
97 */
98export const oneLineCommaListsAnd: TemplateTag;
99
100/**
101 * A no-op tag that might come in useful in some scenarios, e.g. mocking.
102 */
103export const id: TemplateTag;
104
105export interface TemplateTransformer<TCtx = { [key: string]: any }> {
106 /**
107 * Called before everything else.
108 * The result of this hook will be passed to other hooks as `context`.
109 * If omitted, `context` will be an empty object.
110 */
111 getInitialContext?: (() => TCtx) | undefined;
112 /**
113 * Called when the tag encounters a string.
114 * (a string is whatever's not inside "${}" in your template literal)
115 * `str` is the value of the current string
116 */
117 onString?: ((str: string, context: TCtx) => string) | undefined;
118 /**
119 * Called when the tag encounters a substitution.
120 * (a substitution is whatever's inside "${}" in your template literal)
121 * `substitution` is the value of the current substitution
122 * `resultSoFar` is the end result up to the point of this substitution
123 */
124 onSubstitution?: ((substitution: string, resultSoFar: string, context: TCtx) => string) | undefined;
125 /**
126 * Called when all substitutions have been parsed
127 * `endResult` is the final value.
128 */
129 onEndResult?: ((endResult: string, context: TCtx) => string) | undefined;
130}
131
132export type PluginFunction = (oldValue: string, newValue: string) => TemplateTransformer<any>;
133
134/**
135 * New Tag factory
136 */
137export function createTag(transformers?: Array<TemplateTransformer<any>>): TemplateTag;
138export function createTag(...transformers: Array<TemplateTransformer<any>>): TemplateTag;
139export function createTag(...pluginFunctions: PluginFunction[]): TemplateTag;
140
141export const TemplateTag: {
142 /**
143 * New Tag Constructor
144 * @deprecated
145 */
146 new(transformers?: Array<TemplateTransformer<any>>): TemplateTag;
147 new(...transformers: Array<TemplateTransformer<any>>): TemplateTag;
148 new(...pluginFunctions: PluginFunction[]): TemplateTag;
149};
150
151/**
152 * TemplateTag transformer that trims whitespace on the end result of a tagged template
153 * @param [side=''] The side of the string to trim. Can be 'start' or 'end' (alternatively 'left' or 'right')
154 * @return a TemplateTag transformer
155 */
156export function trimResultTransformer(
157 side?: "start" | "end" | "left" | "right" | "",
158): TemplateTransformer;
159
160/**
161 * strips indentation from a template literal
162 * @param [type='initial'] whether to remove all indentation or just leading indentation. can be 'all' or 'initial'
163 * @return a TemplateTag transformer
164 */
165export function stripIndentTransformer(type?: "initial" | "all"): TemplateTransformer;
166
167/**
168 * Replaces a value or pattern in the end result with a new value.
169 * @param replaceWhat the value or pattern that should be replaced
170 * @param replaceWith the replacement value
171 * @return a TemplateTag transformer
172 */
173export function replaceResultTransformer(
174 replaceWhat: string | RegExp,
175 replaceWith: string | ((substring: string, ...args: any[]) => string),
176): TemplateTransformer;
177
178/**
179 * Replaces the result of all substitutions (results of calling ${ ... }) with a new value.
180 * Same as for `replaceResultTransformer`, replaceWhat can be a string or regular expression and replaceWith is the new value.
181 */
182export function replaceSubstitutionTransformer(
183 replaceWhat: string | RegExp,
184 replaceWith: string | ((substring: string, ...args: any[]) => string),
185): TemplateTransformer;
186
187/**
188 * Replaces the result of all strings (what's not in ${ ... }) with a new value.
189 * Same as for `replaceResultTransformer`, replaceWhat can be a string or regular expression and replaceWith is the new value.
190 */
191export function replaceStringTransformer(
192 replaceWhat: string | RegExp,
193 replaceWith: string | ((substring: string, ...args: any[]) => string),
194): TemplateTransformer;
195
196/**
197 * Converts an array substitution to a string containing a list
198 * @param [opts.separator=''] what to separate each item with (always followed by a space)
199 * @param [opts.conjunction=''] replace the last separator with this value
200 * @param [opts.serial=false] should the separator be included before the conjunction? As in the case of serial/oxford commas
201 * @return a TemplateTag transformer
202 */
203export function inlineArrayTransformer(opts?: {
204 separator?: string | undefined;
205 conjunction?: string | undefined;
206 serial?: boolean | undefined;
207}): TemplateTransformer;
208
209/**
210 * Splits a string substitution into an array by the provided splitBy substring, only if the string contains the splitBy substring.
211 */
212export function splitStringTransformer(splitBy: string): TemplateTransformer;