UNPKG

28.5 kBMarkdownView Raw
1# ![common-tags](media/logo.svg)
2
3🔖 A set of **well-tested**, commonly used template literal tag functions for use in ES2015+.
4
5🌟 Plus some extra goodies for easily making your own tags.
6
7## Example
8
9```js
10import { html } from 'common-tags';
11
12html`
13 <div id="user-card">
14 <h2>${user.name}</h2>
15 </div>
16`
17```
18
19## Project Status
20
21| Info | Badges |
22| ---------- | ---------------------------------------- |
23| Version | [![github release](https://img.shields.io/github/release/declandewet/common-tags.svg?style=flat-square)](https://github.com/declandewet/common-tags/releases/latest) [![npm version](https://img.shields.io/npm/v/common-tags.svg?style=flat-square)](http://npmjs.org/package/common-tags) |
24| License | [![npm license](https://img.shields.io/npm/l/common-tags.svg?style=flat-square)](https://github.com/declandewet/common-tags/blob/master/license.md) |
25| Popularity | [![npm downloads](https://img.shields.io/npm/dm/common-tags.svg?style=flat-square)](http://npm-stat.com/charts.html?package=common-tags) |
26| Testing | [![Build status](https://ci.appveyor.com/api/projects/status/75eiommx0llt3sgd?svg=true)](https://ci.appveyor.com/project/declandewet/common-tags) [![build status](https://img.shields.io/travis/declandewet/common-tags.svg?style=flat-square)](https://travis-ci.org/declandewet/common-tags) [![codecov.io](https://img.shields.io/codecov/c/gh/declandewet/common-tags.svg?style=flat-square)](https://codecov.io/gh/declandewet/common-tags?branch=master) |
27| Quality | [![bitHound Overall Score](https://www.bithound.io/github/declandewet/common-tags/badges/score.svg)](https://www.bithound.io/github/declandewet/common-tags) [![dependency status](https://img.shields.io/david/declandewet/common-tags.svg?style=flat-square)](https://david-dm.org/declandewet/common-tags) [![dev dependency status](https://img.shields.io/david/dev/declandewet/common-tags.svg?style=flat-square)](https://david-dm.org/declandewet/common-tags#info=devDependencies) |
28| Style | [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) |
29
30<!-- START doctoc generated TOC please keep comment here to allow auto update -->
31<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
32## Table of Contents
33
34- [Introduction](#introduction)
35- [Why You Should Care](#why-you-should-care)
36- [See Who Is Using `common-tags`](#see-who-is-using-common-tags)
37- [Installation](#installation)
38 - [Requirements](#requirements)
39 - [Instructions](#instructions)
40 - [With unpkg](#with-unpkg)
41- [Usage](#usage)
42 - [Imports](#imports)
43 - [Available Tags](#available-tags)
44 - [`html`](#html)
45 - [Aliases: `source`, `codeBlock`](#aliases-source-codeblock)
46 - [`safeHtml`](#safehtml)
47 - [`oneLine`](#oneline)
48 - [`oneLineTrim`](#onelinetrim)
49 - [`stripIndent`](#stripindent)
50 - [`stripIndents`](#stripindents)
51 - [`inlineLists`](#inlinelists)
52 - [`oneLineInlineLists`](#onelineinlinelists)
53 - [`commaLists`](#commalists)
54 - [`commaListsOr`](#commalistsor)
55 - [`commaListsAnd`](#commalistsand)
56 - [`oneLineCommaLists`](#onelinecommalists)
57 - [`oneLineCommaListsOr`](#onelinecommalistsor)
58 - [`oneLineCommaListsAnd`](#onelinecommalistsand)
59- [Advanced Usage](#advanced-usage)
60 - [Tail Processing](#tail-processing)
61 - [Using Tags on Regular String Literals](#using-tags-on-regular-string-literals)
62 - [Type Definitions](#type-definitions)
63 - [Make Your Own Template Tag](#make-your-own-template-tag)
64 - [Class is in Session: TemplateTag](#class-is-in-session-templatetag)
65 - [The Anatomy of a Transformer](#the-anatomy-of-a-transformer)
66 - [Plugin Transformers](#plugin-transformers)
67 - [Plugin Pipeline](#plugin-pipeline)
68 - [Returning Other Values from a Transformer](#returning-other-values-from-a-transformer)
69 - [List of Built-in Transformers](#list-of-built-in-transformers)
70 - [`trimResultTransformer([side])`](#trimresulttransformerside)
71 - [`stripIndentTransformer([type='initial'])`](#stripindenttransformertypeinitial)
72 - [`replaceResultTransformer(replaceWhat, replaceWith)`](#replaceresulttransformerreplacewhat-replacewith)
73 - [`replaceSubstitutionTransformer(replaceWhat, replaceWith)`](#replacesubstitutiontransformerreplacewhat-replacewith)
74 - [`replaceStringTransformer(replaceWhat, replaceWith)`](#replacestringtransformerreplacewhat-replacewith)
75 - [`inlineArrayTransformer(opts)`](#inlinearraytransformeropts)
76 - [`splitStringTransformer(splitBy)`](#splitstringtransformersplitby)
77- [How to Contribute](#how-to-contribute)
78- [License](#license)
79- [Other ES2015 Template Tag Modules](#other-es2015-template-tag-modules)
80
81<!-- END doctoc generated TOC please keep comment here to allow auto update -->
82
83## Introduction
84
85`common-tags` initially started out as two template tags I'd always find myself writing - one for stripping indents, and one for trimming multiline strings down to a single line. In it's prime, I was an avid user of [CoffeeScript](http://coffeescript.org), which had this behaviour by default as part of it's block strings feature. I also started out programming in Ruby, which has a similar mechanism called Heredocs.
86
87Over time, I found myself needing a few more template tags to cover edge cases - ones that supported including arrays, or ones that helped to render out tiny bits of HTML not large enough to deserve their own file or an entire template engine. So I packaged all of these up into this module.
88
89As more features were proposed, and I found myself needing a way to override the default settings to cover even more edge cases, I realized that my initial implementation wouldn't be easy to scale.
90
91So I re-wrote this module on top of a core architecture that makes use of transformer plugins which can be composed, imported independently and re-used.
92
93## Why You Should Care
94
95Tagged templates in ES2015 are a welcome feature. But, they have their downsides. One such downside is that they preserve all whitespace by default - which makes multiline strings in source code look terrible.
96
97Source code is not just for computers to interpret. Humans have to read it too 😁. If you care at all about how neat your source code is, or come from a [CoffeeScript](http://coffeescript.org/) background and miss the [block string syntax](http://coffeescript.org/#strings), then you will love `common-tags`, as it was initially intended to bring this feature "back" to JS since it's [initial commit](https://github.com/declandewet/common-tags/commit/2595288d6c276439d98d1bcbbb0aa113f4f7cd86).
98
99`common-tags` also [exposes a means of composing pipelines of dynamic transformer plugins](#plugin-transformers). As someone with a little experience writing tagged templates, I can admit that it is often the case that one tag might need to do the same thing as another tag before doing any further processing; for example - a typical tag that renders out HTML could strip initial indents first, then worry about handling character escapes. Both steps could easily be useful as their own separate template tags, but there isn't an immediately obvious way of composing the two together for maximum re-use. `common-tags` offers not [one](#tail-processing), but [two](#plugin-pipeline) ways of doing this.
100
101Furthermore, I try to keep this project as transparently stable and updated as frequently as I possibly can. As you may have already seen by the [project status table](#project-status), `common-tags` is linted, well tested, tests are well covered, tests pass on both Unix and Windows operating systems, the popularity bandwidth is easily referenced and dependency health is in plain sight 😄. `common-tags` is also already [used in production on a number of proprietary sites and dependent projects](#see-who-is-using-common-tags), and [contributions are always welcome](#how-to-contribute), as are [suggestions](issues).
102
103## See Who Is Using `common-tags`
104
105- **[Slack](https://slack.com/)** ([ref](https://slack.com/libs/desktop))
106- **[Discord](https://discordapp.com)** ([ref](https://discordapp.com/acknowledgements))
107- **[CircleCI](https://circleci.com)** ([ref](https://circleci.com/docs/2.0/open-source/))
108- **[Confluent](https://www.confluent.io/)** ([ref](https://www.confluent.io/third_party_software/))
109- **[Tessel](https://tessel.io/)** ([ref](https://github.com/tessel/t2-cli/blob/575ddb23f432d10f86b76f5cdca866d1146dedf5/package.json#L56))
110- **[Ember.js](https://www.emberjs.com/)** ([ref](https://github.com/emberjs/ember.js/blob/cacefee49ea4be2621a0ced3e4ceb0010d6cd841/package.json#L93))
111- **[Angular](https://angularjs.org/)** ([ref](https://github.com/angular/angular-cli/blob/90e2e805aae6e0bd2e00e52063221736a8d9cb0c/package.json#L50))
112- **[Prettier](https://prettier.io/)** ([ref](https://github.com/prettier/prettier-eslint/blob/49b762b57b7e7af3b06bd933050c614a91b6742d/package.json#L18))
113- **[Apollo](https://www.apollographql.com)** ([ref](https://github.com/apollographql/apollo-codegen/blob/b9b9a2afd851fa3cba786b26684b26378b1a6f53/package.json#L48))
114- **[Workbox](https://developers.google.com/web/tools/workbox/)** ([ref](https://github.com/GoogleChrome/workbox/blob/d391a0cb51b3e89121c5274fb15f05988233b57e/package.json#L64))
115- **[Gatsby](https://www.gatsbyjs.org/)** ([ref](https://github.com/gatsbyjs/gatsby/blob/3af191c9961b6da1cc04e9cb0a03787af25878db/packages/gatsby-cli/package.json#L16))
116- **[Storybook](https://storybook.js.org/)** ([ref](https://github.com/storybooks/storybook/blob/c275e5c508714bd1a49342e51ddf00bbdb54d277/app/react/package.json#L46))
117- **[Cypress](https://www.cypress.io/)** ([ref](https://github.com/cypress-io/cypress/blob/5d761630f233abb30b9b2e3fede9a4c4887cf880/cli/package.json#L44))
118- **[stylelint](http://stylelint.io/)** ([ref](https://github.com/stylelint/stylelint/blob/5dc5db5599a00cabc875cf99c56d60f93fbbbd2d/package.json#L82))
119- **[pnpm](https://pnpm.js.org/)** ([ref](https://github.com/pnpm/pnpm/blob/36be3d3f0c75992a1f3ff14b60c99115547d0fcc/package.json#L36))
120- **[jss](http://cssinjs.org/)** ([ref](https://github.com/cssinjs/jss/blob/7b9c1222893495c585b4b61d7ca9af05077cefec/package.json#L44))
121
122## Installation
123
124### Requirements
125
126The official recommendation for running `common-tags` is as follows:
127
128- [Node.js](https://nodejs.org/en/download/) v5.0.0 or higher
129- In order to use `common-tags`, your environment will also need to support ES2015 tagged templates ([pssst… check Babel out](http://babeljs.io))
130- You might also want to [polyfill some features](https://github.com/zloirock/core-js) if you plan on supporting older browsers: `Array.prototype.includes`
131
132It might work with below versions of Node, but this is not a guarantee.
133
134### Instructions
135
136`common-tags` is a [Node](https://nodejs.org/) module. So, as long as you have Node.js and NPM installed, installing `common-tags` is as simple as running this in a terminal at the root of your project:
137
138```sh
139npm install common-tags
140```
141
142### With unpkg
143
144`common-tags` is also available at [unpkg](https://unpkg.com/common-tags). Just put this code in your HTML:
145
146```html
147<script src="https://unpkg.com/common-tags"></script>
148```
149
150This will make the library available under a global variable `commonTags`.
151
152## Usage
153
154### Imports
155
156Like all modules, `common-tags` begins with an `import`. In fact, `common-tags` supports two styles of import:
157
158**Named imports:**
159
160```js
161import {stripIndent} from 'common-tags'
162```
163
164**Direct module imports:**
165
166*(Useful if your bundler doesn't support [tree shaking](https://medium.com/@roman01la/dead-code-elimination-and-tree-shaking-in-javascript-build-systems-fb8512c86edf#.p30lbjm94) but you still want to only include modules you need).*
167
168```js
169import stripIndent from 'common-tags/lib/stripIndent'
170```
171
172### Available Tags
173
174`common-tags` exports a bunch of wonderful pre-cooked template tags for your eager consumption. They are as follows:
175
176#### `html`
177
178##### Aliases: `source`, `codeBlock`
179
180You'll often find that you might want to include an array in a template. Typically, doing something like `${array.join(', ')}` would work - but what if you're printing a list of items in an HTML template and want to maintain the indentation? You'd have to count the spaces manually and include them in the `.join()` call - which is a bit *ugly* for my taste. This tag properly indents arrays, as well as newline characters in string substitutions, by converting them to an array split by newline and re-using the same array inclusion logic:
181
182```js
183import {html} from 'common-tags'
184let fruits = ['apple', 'orange', 'watermelon']
185html`
186 <div class="list">
187 <ul>
188 ${fruits.map(fruit => `<li>${fruit}</li>`)}
189 ${'<li>kiwi</li>\n<li>guava</li>'}
190 </ul>
191 </div>
192`
193```
194
195Outputs:
196
197```html
198<div class="list">
199 <ul>
200 <li>apple</li>
201 <li>orange</li>
202 <li>watermelon</li>
203 <li>kiwi</li>
204 <li>guava</li>
205 </ul>
206</div>
207```
208
209#### `safeHtml`
210
211A tag very similar to `html` but it does safe HTML escaping for strings coming from substitutions. When combined with regular `html` tag, you can do basic HTML templating that is safe from XSS (Cross-Site Scripting) attacks.
212
213```js
214import {html, safeHtml} from 'common-tags'
215let userMessages = ['hi', 'what are you up to?', '<script>alert("something evil")</script>']
216html`
217 <div class="chat-list">
218 <ul>
219 ${userMessages.map(message => safeHtml`<li>${message}</li>`)}
220 </ul>
221 </div>
222`
223```
224
225Outputs:
226
227```html
228<div class="chat-list">
229 <ul>
230 <li>hi</li>
231 <li>what are you up to?</li>
232 <li>&lt;script&gt;alert(&quot;something evil&quot;)&lt;/script&gt;</li>
233 </ul>
234</div>
235```
236
237#### `oneLine`
238
239Allows you to keep your single-line strings under 80 characters without resorting to crazy string concatenation.
240
241```js
242import {oneLine} from 'common-tags'
243
244oneLine`
245 foo
246 bar
247 baz
248`
249// "foo bar baz"
250```
251
252#### `oneLineTrim`
253
254Allows you to keep your single-line strings under 80 characters while trimming the new lines:
255
256```js
257import {oneLineTrim} from 'common-tags'
258
259oneLineTrim`
260 https://news.com/article
261 ?utm_source=designernews.co
262`
263// https://news.com/article?utm_source=designernews.co
264```
265
266#### `stripIndent`
267
268If you want to strip the initial indentation from the beginning of each line in a multiline string:
269
270```js
271import {stripIndent} from 'common-tags'
272
273stripIndent`
274 This is a multi-line string.
275 You'll ${verb} that it is indented.
276 We don't want to output this indentation.
277 But we do want to keep this line indented.
278`
279// This is a multi-line string.
280// You'll notice that it is indented.
281// We don't want to output this indentation.
282// But we do want to keep this line indented.
283```
284
285Important note: this tag will not indent multiline strings coming from the substitutions. If you want that behavior, use the `html` tag (aliases: `source`, `codeBlock`).
286
287#### `stripIndents`
288
289If you want to strip *all* of the indentation from the beginning of each line in a multiline string:
290
291```js
292import {stripIndents} from 'common-tags'
293
294stripIndents`
295 This is a multi-line string.
296 You'll ${verb} that it is indented.
297 We don't want to output this indentation.
298 We don't want to keep this line indented either.
299`
300// This is a multi-line string.
301// You'll notice that it is indented.
302// We don't want to output this indentation.
303// We don't want to keep this line indented either.
304```
305
306#### `inlineLists`
307
308Allows you to inline an array substitution as a list:
309
310```js
311import {inlineLists} from 'common-tags'
312
313inlineLists`
314 I like ${['apples', 'bananas', 'watermelons']}
315 They're good!
316`
317// I like apples bananas watermelons
318// They're good!
319```
320
321#### `oneLineInlineLists`
322
323Allows you to inline an array substitution as a list, rendered out on a single line:
324
325```js
326import {oneLineInlineLists} from 'common-tags'
327
328oneLineInlineLists`
329 I like ${['apples', 'bananas', 'watermelons']}
330 They're good!
331`
332// I like apples bananas watermelons They're good!
333```
334
335#### `commaLists`
336
337Allows you to inline an array substitution as a comma-separated list:
338
339```js
340import {commaLists} from 'common-tags'
341
342commaLists`
343 I like ${['apples', 'bananas', 'watermelons']}
344 They're good!
345`
346// I like apples, bananas, watermelons
347// They're good!
348```
349
350#### `commaListsOr`
351
352Allows you to inline an array substitution as a comma-separated list, the last of which is preceded by the word "or":
353
354```js
355import {commaListsOr} from 'common-tags'
356
357commaListsOr`
358 I like ${['apples', 'bananas', 'watermelons']}
359 They're good!
360`
361// I like apples, bananas or watermelons
362// They're good!
363```
364
365#### `commaListsAnd`
366
367Allows you to inline an array substitution as a comma-separated list, the last of which is preceded by the word "and":
368
369```js
370import {commaListsAnd} from 'common-tags'
371
372commaListsAnd`
373 I like ${['apples', 'bananas', 'watermelons']}
374 They're good!
375`
376// I like apples, bananas and watermelons
377// They're good!
378```
379
380#### `oneLineCommaLists`
381
382Allows you to inline an array substitution as a comma-separated list, and is rendered out on to a single line:
383
384```js
385import {oneLineCommaLists} from 'common-tags'
386
387oneLineCommaLists`
388 I like ${['apples', 'bananas', 'watermelons']}
389 They're good!
390`
391// I like apples, bananas or watermelons They're good!
392```
393
394#### `oneLineCommaListsOr`
395
396Allows 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:
397
398```js
399import {oneLineCommaListsOr} from 'common-tags'
400
401oneLineCommaListsOr`
402 I like ${['apples', 'bananas', 'watermelons']}
403 They're good!
404`
405// I like apples, bananas or watermelons They're good!
406```
407
408#### `oneLineCommaListsAnd`
409
410Allows 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:
411
412```js
413import {oneLineCommaListsAnd} from 'common-tags'
414
415oneLineCommaListsAnd`
416 I like ${['apples', 'bananas', 'watermelons']}
417 They're good!
418`
419// I like apples, bananas and watermelons They're good!
420```
421
422## Advanced Usage
423
424### Tail Processing
425
426It's possible to pass the output of a tagged template to another template tag in pure ES2015+:
427
428```js
429import {oneLine} from 'common-tags'
430
431oneLine`
432 ${String.raw`
433 foo
434 bar\nbaz
435 `}
436`
437// "foo bar\nbaz"
438```
439
440We can make this neater. Every tag `common-tags` exports can delay execution if it receives a function as it's first argument. This function is assumed to be a template tag, and is called via an intermediary tagging process before the result is passed back to our tag. Use it like so (this code is equivalent to the previous code block):
441
442```js
443import {oneLine} from 'common-tags'
444
445oneLine(String.raw)`
446 foo
447 bar\nbaz
448`
449// "foo bar\nbaz"
450```
451
452### Using Tags on Regular String Literals
453
454Sometimes you might want to use a tag on a normal string (e.g. for stripping the indentation). For that purpose just call a tag as a function with the passed string:
455
456```js
457import {stripIndent} from 'common-tags'
458
459stripIndent(" foo\n bar")
460// "foo\n bar"
461```
462
463### Type Definitions
464
465There are third-party type definitions for `common-tags` on [npm](https://www.npmjs.com/package/@types/common-tags). Just install them like so:
466
467```sh
468npm install @types/common-tags
469```
470
471Please note that these type definitions are not officially maintained by the authors of
472`common-tags` - they are maintained by the TypeScript community.
473
474### Make Your Own Template Tag
475
476`common-tags` exposes an interface that allows you to painlessly create your own template tags.
477
478#### Class is in Session: TemplateTag
479
480`common-tags` exports a `TemplateTag` class. This class is the foundation of `common-tags`. The concept of the class works on the premise that transformations occur on a template either when the template is finished being processed (`onEndResult`), or when the tag encounters a string (`onString`) or a substitution (`onSubstitution`). Any tag produced by this class supports [tail processing](#tail-processing).
481
482The easiest tag to create is a tag that does nothing:
483
484```js
485import {TemplateTag} from 'common-tags'
486
487const doNothing = new TemplateTag()
488
489doNothing`foo bar`
490// 'foo bar'
491```
492
493#### The Anatomy of a Transformer
494
495`TemplateTag` receives either an array or argument list of `transformers`. A `transformer` is just a plain object with three optional methods - `onString`, `onSubstitution` and `onEndResult` - it looks like this:
496
497```js
498{
499 onString (str) {
500 // optional. Called when the tag encounters a string.
501 // (a string is whatever's not inside "${}" in your template literal)
502 // `str` is the value of the current string
503 },
504 onSubstitution (substitution, resultSoFar) {
505 // optional. Called when the tag encounters a substitution.
506 // (a substitution is whatever's inside "${}" in your template literal)
507 // `substitution` is the value of the current substitution
508 // `resultSoFar` is the end result up to the point of this substitution
509 },
510 onEndResult (endResult) {
511 // optional. Called when all substitutions have been parsed
512 // `endResult` is the final value.
513 }
514}
515```
516
517#### Plugin Transformers
518
519You can wrap a transformer in a function that receives arguments in order to create a dynamic plugin:
520
521```js
522const substitutionReplacer = (oldValue, newValue) => ({
523 onSubstitution(substitution, resultSoFar) {
524 if (substitution === oldValue) {
525 return newValue
526 }
527 return substitution
528 }
529})
530
531const replaceFizzWithBuzz = new TemplateTag(substitutionReplacer('fizz', 'buzz'))
532
533replaceFizzWithBuzz`foo bar ${"fizz"}`
534// "foo bar buzz"
535```
536
537> **note** - if you call `new TemplateTag(substitutionReplacer)`, `substitutionReplacer` will automatically be initiated with no arguments.
538
539#### Plugin Pipeline
540
541You can pass a list of transformers, and `TemplateTag` will call them on your tag in the order they are specified:
542
543```js
544// note: passing these as an array also works
545const replace = new TemplateTag(
546 substitutionReplacer('fizz', 'buzz'),
547 substitutionReplacer('foo', 'bar')
548)
549
550replace`${"foo"} ${"fizz"}`
551// "bar buzz"
552```
553
554When multiple transformers are passed to `TemplateTag`, they will be iterated three times - first, all transformer `onString` methods will be called. Once they are done processing, `onSubstitution` methods will be called. Finally, all transformer `onEndResult` methods will be called.
555
556#### Returning Other Values from a Transformer
557
558This is super easy. Transformers are just objects, after all. They have full access to `this`:
559
560```js
561const listSubs = {
562 onString(str) {
563 this.ctx = this.ctx || { strings: [], subs: [] }
564 this.ctx.strings.push(str);
565 return str
566 },
567 onSubstitution(sub, res) {
568 this.ctx.subs.push({ sub, precededBy: res })
569 return sub
570 },
571 onEndResult(res) {
572 return this.ctx
573 }
574}
575
576const toJSON = {
577 onEndResult(res) {
578 return JSON.stringify(res, null, 2)
579 }
580}
581
582const log = {
583 onEndResult(res) {
584 console.log(res)
585 return res
586 }
587}
588
589const process = new TemplateTag([listSubs, toJSON, log])
590
591process`
592 foo ${'bar'}
593 fizz ${'buzz'}
594`
595// {
596// "strings": [
597// "\n foo ",
598// "\n foo bar\n fizz ",
599// "\n"
600// ],
601// "subs": [
602// {
603// "sub": "bar",
604// "precededBy": "\n foo "
605// },
606// {
607// "sub": "buzz",
608// "precededBy": "\n foo bar\n fizz "
609// }
610// ]
611// }
612```
613
614#### List of Built-in Transformers
615
616Since `common-tags` is built on the foundation of this TemplateTag class, it comes with its own set of built-in transformers:
617
618##### `trimResultTransformer([side])`
619
620Trims the whitespace surrounding the end result. Accepts an optional `side` (can be `"start"` or `"end"` or alternatively `"left"` or `"right"`) that when supplied, will only trim whitespace from that side of the string.
621
622##### `stripIndentTransformer([type='initial'])`
623
624Strips the indents from the end result. Offers two types: `all`, which removes all indentation from each line, and `initial`, which removes the shortest indent level from each line. Defaults to `initial`.
625
626##### `replaceResultTransformer(replaceWhat, replaceWith)`
627
628Replaces a value or pattern in the end result with a new value. `replaceWhat` can be a string or a regular expression, `replaceWith` is the new value.
629
630##### `replaceSubstitutionTransformer(replaceWhat, replaceWith)`
631
632Replaces the result of all substitutions (results of calling `${ ... }`) with a new value. Same as for `replaceResultTransformer`, `replaceWhat` can be a string or regular expression and `replaceWith` is the new value.
633
634##### `replaceStringTransformer(replaceWhat, replaceWith)`
635
636Replaces the result of all strings (what's not in `${ ... }`) with a new value. Same as for `replaceResultTransformer`, `replaceWhat` can be a string or regular expression and `replaceWith` is the new value.
637
638##### `inlineArrayTransformer(opts)`
639
640Converts any array substitutions into a string that represents a list. Accepts an options object:
641
642```js
643opts = {
644 separator: ',', // what to separate each item with (always followed by a space)
645 conjunction: 'and', // replace the last separator with this value
646 serial: true // should the separator be included before the conjunction? As in the case of serial/oxford commas
647}
648```
649
650##### `splitStringTransformer(splitBy)`
651
652Splits a string substitution into an array by the provided `splitBy` substring, **only** if the string contains the `splitBy` substring.
653
654## How to Contribute
655
656Please see the [Contribution Guidelines](contributing.md).
657
658## License
659
660MIT. See [license.md](license.md).
661
662## Other ES2015 Template Tag Modules
663
664If `common-tags` doesn't quite fit your bill, and you just can't seem to find what you're looking for - perhaps these might be of use to you?
665
666- [tage](https://www.npmjs.com/package/tage) - make functions work as template tags too
667- [is-tagged](https://www.npmjs.com/package/is-tagged) - Check whether a function call is initiated by a tagged template string or invoked in a regular way
668- [es6-template-strings](https://www.npmjs.com/package/es6-template-strings) - Compile and resolve template strings notation as specified in ES6
669- [t7](https://github.com/trueadm/t7) - A light-weight virtual-dom template library
670- [html-template-tag](https://www.npmjs.com/package/html-template-tag) - ES6 Tagged Template for compiling HTML template strings.
671- [clean-tagged-string](https://www.npmjs.com/package/clean-tagged-string) - A simple utility function to clean ES6 template strings.
672- [multiline-tag](https://www.npmjs.com/package/multiline-tag) - Tags for template strings making them behave like coffee multiline strings
673- [deindent](https://www.npmjs.com/package/deindent) - ES6 template string helper for deindentation.
674- [heredoc-tag](https://www.npmjs.com/package/heredoc-tag) - Heredoc helpers for ES2015 template strings
675- [regx](https://www.npmjs.com/package/regx) - Tagged template string regular expression compiler.
676- [regexr](https://www.npmjs.org/package/regexr) - Provides an ES6 template tag function that makes it easy to compose regexes out of template strings without double-escaped hell.
677- [url-escape-tag](https://www.npmjs.com/package/url-escape-tag) - A template tag for escaping url parameters based on ES2015 tagged templates.
678- [shell-escape-tag](https://www.npmjs.com/package/shell-escape-tag) - An ES6+ template tag which escapes parameters for interpolation into shell commands.
679- [sql-tags](https://www.npmjs.com/package/sql-tags) - ES6 tagged template string functions for SQL statements.
680- [sql-tag](https://www.npmjs.com/package/sql-tag) - A template tag for writing elegant sql strings.
681- [sequelize-sql-tag](https://www.npmjs.com/package/sequelize-sql-tag) - A sequelize plugin for sql-tag
682- [pg-sql-tag](https://www.npmjs.com/package/pg-sql-tag) - A pg plugin for sql-tag
683- [sql-template-strings](https://www.npmjs.com/package/sql-template-strings) - ES6 tagged template strings for prepared statements with mysql and postgres
684- [sql-composer](https://www.npmjs.com/package/sql-composer) - Composable SQL template strings for Node.js
685- [pg-template-tag](https://www.npmjs.com/package/pg-template-tag) - ECMAScript 6 (2015) template tag function to write queries for node-postgres.
686- [digraph-tag](https://www.npmjs.com/package/digraph-tag) - ES6 string template tag for quickly generating directed graph data
687- [es2015-i18n-tag](https://www.npmjs.com/package/es2015-i18n-tag) - ES2015 template literal tag for i18n and l10n translation and localization