Skip to content
This repository has been archived by the owner on Jun 21, 2024. It is now read-only.

Commit

Permalink
feat: implement defaults tag
Browse files Browse the repository at this point in the history
  • Loading branch information
customcommander committed Jan 2, 2020
1 parent 2e0803a commit 90d5d6e
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 1 deletion.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
## API

* <a name="defaults">defaults</a> - _Replace an empty value with a default value_
* <a name="hide">hide</a> - _Hides interpolated values_
* <a name="lower">lower</a> - _Lowercase interpolated values_
* <a name="pluralize">pluralize</a> - _Choose between singular or plural forms._
* <a name="trim">trim</a> - _Trim interpolated values_
* <a name="upper">upper</a> - _Uppercase interpolated values_

### <a name="#defaults"></a>defaults


The default value for an empty interpolated value is defined in the string template itself.<br>
It is separated by a single `/` character. e.g. `${name}/guest`.

A value is considered empty if it is:

- `null`
- `undefined`
- An empty string `''`
- An empty array `[]`
- An empty object `{}`

When the default value is used, the separator (i.e. the `/` character)
is removed from the string.

When the interpolated value is not empty, the default value (and the separator)
is removed from the string.

```javascript
import {defaults} from '@customcommander/tagtical';

var username = '';
var num;
defaults`Hi ${username}/guest, you have ${num}/no new emails`;
//=> "Hi guest, you have no new emails"

var username = 'John';
var num = 10;
defaults`Hi ${username}/guest, you have ${num}/no new emails`;
//=> "Hi John, you have 10 new emails"
```
### <a name="#hide"></a>hide


Expand Down
95 changes: 95 additions & 0 deletions src/defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @license
* Copyright (c) 2020 Julien Gonzalez
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

const RE = /^(\s*)(\/)([a-zA-Z0-9]+)(\s*)/;

const is_empty = x =>
x === null
|| x === undefined
|| ( ( typeof x === 'string'
|| Array.isArray(x)
)
&& x.length === 0
)
|| ( typeof x === 'object'
&& Object.keys(x).length === 0
);

const get_default = str =>
str.replace
( RE
, (ignored, lws, sep, replacement, tws) =>
`${lws}${replacement}${tws}`
);

const remove_default = str =>
str.replace
( RE
, (ignored, lws, sep, replacement, tws) =>
`${lws}${tws}`
);

/**
* Replace an empty value with a default value
*
* The default value for an empty interpolated value is defined in the string template itself.<br>
* It is separated by a single `/` character. e.g. `${name}/guest`.
*
* A value is considered empty if it is:
*
* - `null`
* - `undefined`
* - An empty string `''`
* - An empty array `[]`
* - An empty object `{}`
*
* When the default value is used, the separator (i.e. the `/` character)
* is removed from the string.
*
* When the interpolated value is not empty, the default value (and the separator)
* is removed from the string.
*
* ```javascript
* import {defaults} from '@customcommander/tagtical';
*
* var username = '';
* var num;
* defaults`Hi ${username}/guest, you have ${num}/no new emails`;
* //=> "Hi guest, you have no new emails"
*
* var username = 'John';
* var num = 10;
* defaults`Hi ${username}/guest, you have ${num}/no new emails`;
* //=> "Hi John, you have 10 new emails"
* ```
*/
module.exports =
(l, x, r) =>
[ l
, is_empty(x)
? ''
: x
, is_empty(x)
? get_default(r)
: remove_default(r)
];
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const tag_function = require('./utils/tag_function');
const join = require('./utils/join');
const intersperse = require('./utils/intersperse');
const compose = require('./utils/compose');
const defaults = require('./defaults');
const hide = require('./hide');
const lower = require('./lower');
const pluralize = require('./pluralize');
Expand All @@ -13,6 +14,7 @@ const tag = (...fns) =>
compose(join(''), ...fns.map(tag_function.unwrap))
(intersperse(strs, vals));

tag.defaults = tag_function(defaults);
tag.hide = tag_function(hide);
tag.lower = tag_function(lower);
tag.pluralize = tag_function(pluralize);
Expand Down
25 changes: 24 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const test = require('tape');
const tag = require('./dist');
const
{ hide
{ defaults
, hide
, lower
, pluralize
, trim
Expand All @@ -20,6 +21,28 @@ test('tag: can compose other tags', t => {
);
});

test('defaults: replace empty values', t => {
t.plan(2);

let foo;
let bar;

foo = '';

t.is
( defaults`foo=${foo}/aaa, bar=${bar}/bbb`
, 'foo=aaa, bar=bbb'
);

foo = false,
bar = 0;

t.is
( defaults`foo=${foo}/aaa, bar=${bar}/bbb`
, 'foo=false, bar=0'
);
});

test('tag: can compose user-defined tags', t => {
t.plan(1);

Expand Down

0 comments on commit 90d5d6e

Please sign in to comment.