Skip to content

Commit

Permalink
Add %J formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Apr 14, 2017
1 parent 99585a6 commit 4192659
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 15 deletions.
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ or at runtime:
acho.level = 'debug';
```

See more at [examples/levels](https://github.com/achohq/acho/blob/master/examples/levels.js).

### Customization

You can completely customize the library to your requirements: changes colors, add more types, sort the priorities... the internal structure of the object is public and you can edit it dynamically. **You have the power**.
Expand Down Expand Up @@ -195,6 +197,52 @@ acho.info('I am hungry');

If you need customize more the output you can setup `.print` `.generateMessage` (see below) that are a more low level methods for generate and print the output message.

## Formatters

We use [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters:

| Formatter | Representation |
|-----------|---------------------------------------------------------------|
| `%s` | String. |
| `%d` | Number (both integer and float). |
| `%j` | JSON serialization in one line |
| `%J` | JSON pretty object in multiple lines |
| `%%` | Single percent sign ('%'). This does not consume an argument. |

By default, the `%j` is applied when you pass an object to be logged:

```js
acho.info({hello: 'world', foo: 'bar'})
// => 'info hello=world foo=bar'
```

If you want to use a different formatter, use printf markup:

```js
acho.info('formatting with object interpolation %J', {
hello: 'world',
foo: 'bar',
deep: {
foo: 'bar',
arr: [1, 2, 3, 4, 5]
}
})

// info formatting with object interpolation
// hello: "world"
// foo: "bar"
// deep:
// foo: "bar"
// arr:
// 0: 1
// 1: 2
// 2: 3
// 3: 4
// 4: 5
```

See more at [examples/formatter](https://github.com/achohq/acho/blob/master/examples/formatter.js).

## API

### Acho({Object} [options])
Expand Down
18 changes: 18 additions & 0 deletions examples/formatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict'

var Acho = require('..')
var acho = Acho()

acho.info('formatting plain text: hello world')
acho.info('formatting with number interpolation %d', 123)
acho.info('formatting with float interpolation %d', 3.14)
acho.info('formatting with string interpolation %s', 'hello world')
acho.info('formatting with object interpolation %j', {hello: 'world', foo: 'bar'})
acho.info('formatting with object interpolation %J', {
hello: 'world',
foo: 'bar',
deep: {
foo: 'bar',
arr: [1, 2, 3, 4, 5]
}
})
12 changes: 6 additions & 6 deletions lib/Default.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,11 @@ module.exports =
symbol : CONST.FIGURE.warning

error:
level : 1
color : 'red'
symbol: CONST.FIGURE.error
level : 1
color : 'red'
symbol : CONST.FIGURE.error

fatal:
level : 0
color : 'red'
symbol: CONST.FIGURE.error
level : 0
color : 'red'
symbol : CONST.FIGURE.error
36 changes: 27 additions & 9 deletions lib/Format.coffee
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
'use strict'

fmtObj = require 'fmt-obj'
slice = require 'sliced'
chalk = require 'chalk'

CONST = require './Constants'

ESCAPE_REGEX = /%{2,2}/g
TYPE_REGEX = /(%?)(%([jds]))/g
TYPE_REGEX = /(%?)(%([Jjds]))/g

isString = (obj) -> typeof obj is 'string'
isSymbol = (obj) -> typeof obj is 'symbol'
isObject = (obj) -> typeof obj is 'object'
isFalsy = (value) -> [null, undefined, false].indexOf(value) isnt -1
isArray = (arr) -> Array.isArray(arr)
colorize = (value, color) -> chalk[color](value)
hasWhiteSpace = (s) -> s.indexOf(' ') isnt -1

serialize = (color, obj, key) ->
colorize = (value, color) -> chalk[color](value)

prettyObj = (obj, color) ->
lineColor = chalk[CONST.LINE_COLOR]

fmtObj(obj, Infinity,
punctuation: lineColor
annotation: lineColor
property: chalk[color]
literal: lineColor
number: lineColor
string: lineColor
)

serialize = (obj, color, key) ->
# symbols cannot be directly casted to strings
key = key.toString() if isSymbol key
obj = obj.toString() if isSymbol obj
Expand All @@ -38,20 +54,20 @@ serialize = (color, obj, key) ->
key = keys[i]
value = obj[key]

if isArray(value)
if isArray value
msg += key + '=['
j = 0
l = value.length
while j < l
msg += serialize(color, value[j])
msg += serialize(value[j], color)
if j < l - 1
msg += ' '
j++
msg += ']'
else if value instanceof Date
msg += key + '=' + value
else
msg += serialize(color, value, colorize(key, color))
msg += serialize(value, color, colorize(key, color))
if i < length - 1
msg += ' '
i++
Expand All @@ -70,14 +86,16 @@ format = (fmt) ->
when 'd'
arg = colorize(Number(arg), color)
when 'j'
arg = serialize color, arg
arg = serialize arg, color
when 'J'
arg = prettyObj arg, color
return arg if !escaped
args.unshift arg
match
)

fmt += ' ' + serialize color, arg for arg in args if args.length
fmt += ' ' + serialize arg, color for arg in args if args.length
fmt = fmt.replace(ESCAPE_REGEX, '%') if fmt.replace?
serialize color, fmt
serialize fmt, color

module.exports = format
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"dependencies": {
"chalk": "~1.1.1",
"coffee-script": "~1.12.4",
"fmt-obj": "~1.3.0",
"pretty-ms": "~2.1.0",
"sliced": "~1.0.1"
},
Expand Down

0 comments on commit 4192659

Please sign in to comment.