Skip to content

Instantly share code, notes, and snippets.

@boxofrox
Last active January 31, 2016 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boxofrox/4b184bc4e2aad0d04e1a to your computer and use it in GitHub Desktop.
Save boxofrox/4b184bc4e2aad0d04e1a to your computer and use it in GitHub Desktop.
import { __, always, call, compose, concat, cond, converge, curry, equals,
flatten, head, init, is, isEmpty, join, last, map, of, path, prop,
split, T, tail, toPairs, toString, trim, unapply } from 'ramda';
// :: String -> String
const indent = curry((level, a) => concat(' '.repeat(level), a));
// :: [String] -> String
const joinLines = join('\n');
// :: [String] -> [String]
const appendComma =
converge(concat,
[ init,
compose(of,
concat(__, [',']),
last), ]);
// :: [[String]] -> [[String]]
const appendCommas =
converge(concat,
[ compose(map(appendComma),
init),
last ]);
// :: Monoid a => a -> a -> a -> a
const surround = curry((front, back, a) => concat(front, concat(a, back)));
const dateToString = compose(
of,
a => `Date { ${a.toUTCString()} }`
);
// :: Int -> [*] -> [Lines]
const complexArrayToString = level =>
compose(
of,
joinLines,
surround(['Array ['], [indent(level, ']')]),
appendCommas,
map(_prettyprint(level + 1))
);
// :: Int -> [*] -> [Lines]
const arrayToString = level =>
cond([
[isEmpty, always(['[]'])],
[T, complexArrayToString(level)],
]);
// :: {} -> String
const getName = path(['constructor', 'name']);
// :: Int -> {} -> [String]
const complexObjecToString = level =>
compose(
of,
joinLines,
converge(call,
[ compose(
surround(__, [indent(level, '}')]),
of,
concat(__, ' {'),
getName),
compose(
appendCommas,
map(converge(unapply(join(': ')),
[ compose(indent(level + 1), head),
compose(trim, _prettyprint(level + 1), last), ])),
toPairs) ])
);
// :: Int -> {} -> [String]
const objectToString = level =>
cond([
[isEmpty, always(['{}'])],
[T, complexObjecToString(level)],
]);
// jshint ignore:start
const _prettyprint = curry((level, target) =>
compose(
joinLines,
flatten,
map(indent(level)),
cond([
[equals(undefined), always(['undefined'])],
[equals(null), always(['null'])],
[is(String), compose(
of,
surround('"', '"')
)],
[is(Error), compose(
of,
join('\n'),
converge(concat,
[ compose(of, head),
compose(
map(indent(level)), // no +1, stack already has indentation.
tail ) ]),
split('\n'),
prop('stack')
)],
[is(Date), dateToString],
[is(RegExp), compose(split('\n'), toString)],
[is(Function), compose(split('\n'), toString)],
[is(Array), arrayToString(level)],
[is(Object), objectToString(level)],
[T, compose(split('\n'), toString)],
])
)(target)
);
// jshint ignore:end
export default _prettyprint(0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment