Skip to content

Commit 2abc664

Browse files
committed
Initial commit
0 parents  commit 2abc664

11 files changed

+345
-0
lines changed

.babelrc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"env": {
3+
"commonjs": {
4+
"plugins": [
5+
["transform-es2015-modules-commonjs", { "loose": true }]
6+
]
7+
},
8+
"es": {
9+
"plugins": [
10+
"./build/use-lodash-es"
11+
]
12+
}
13+
}
14+
}

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.gitignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
6+
# Runtime data
7+
pids
8+
*.pid
9+
*.seed
10+
11+
# Directory for instrumented libs generated by jscoverage/JSCover
12+
lib-cov
13+
14+
# Coverage directory used by tools like istanbul
15+
coverage
16+
17+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18+
.grunt
19+
20+
# node-waf configuration
21+
.lock-wscript
22+
23+
# Compiled binary addons (http://nodejs.org/api/addons.html)
24+
build/Release
25+
26+
# Dependency directories
27+
node_modules
28+
jspm_packages
29+
30+
# Optional npm cache directory
31+
.npm
32+
33+
# Optional REPL history
34+
.node_repl_history
35+
36+
# Project folders
37+
dist
38+
es
39+
lib

build/use-lodash-es.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = function () {
2+
return {
3+
visitor: {
4+
ImportDeclaration(path) {
5+
var source = path.node.source;
6+
source.value = source.value.replace(/^lodash($|\/)/, 'lodash-es$1');
7+
}
8+
}
9+
};
10+
};

package.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"name": "journalize",
3+
"version": "0.1.0",
4+
"description": "A collection of functions useful for making prose more reader friendly. Inspired by Django's `django.contrib.humanize`.",
5+
"main": "lib/index.js",
6+
"jsnext:main": "es/index.js",
7+
"files": [
8+
"dist",
9+
"lib",
10+
"es",
11+
"src"
12+
],
13+
"scripts": {
14+
"build:commonjs": "BABEL_ENV=commonjs babel src --out-dir lib",
15+
"build:es": "BABEL_ENV=es babel src --out-dir es",
16+
"build:umd": "BABEL_ENV=commonjs rollup --config --output ./dist/journalize.js -- ./src/index.js",
17+
"build:umd:min": "BABEL_ENV=commonjs rollup --config -- ./src/index.js | uglifyjs --compress --mangle --output ./dist/journalize.min.js",
18+
"build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
19+
"clean": "rimraf dist es lib",
20+
"docs:serve": "documentation serve --watch ./src/index.js",
21+
"test": "BABEL_ENV=commonjs mocha --compilers js:babel-register",
22+
"test:cov": "BABEL_ENV=commonjs babel-node $(npm bin)/isparta cover $(npm bin)/_mocha"
23+
},
24+
"repository": {
25+
"type": "git",
26+
"url": "git+https://github.com/rdmurphy/journalize.git"
27+
},
28+
"keywords": [
29+
"normalization",
30+
"journalism",
31+
"humanity",
32+
"editing",
33+
"prose"
34+
],
35+
"author": "Ryan Murphy <[email protected]>",
36+
"license": "MIT",
37+
"bugs": {
38+
"url": "https://github.com/rdmurphy/journalize/issues"
39+
},
40+
"homepage": "https://github.com/rdmurphy/journalize#readme",
41+
"dependencies": {
42+
"lodash": "^4.11.0",
43+
"lodash-es": "^4.11.0"
44+
},
45+
"devDependencies": {
46+
"babel-cli": "^6.7.5",
47+
"babel-plugin-transform-es2015-modules-commonjs": "^6.7.4",
48+
"babel-register": "^6.7.2",
49+
"documentation": "^4.0.0-beta2",
50+
"isparta": "^4.0.0",
51+
"mocha": "^2.4.5",
52+
"rimraf": "^2.5.2",
53+
"rollup": "^0.25.8",
54+
"rollup-plugin-commonjs": "^2.2.1",
55+
"rollup-plugin-node-resolve": "^1.5.0",
56+
"uglify-js": "^2.6.2"
57+
}
58+
}

rollup.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import commonjs from 'rollup-plugin-commonjs';
2+
import node from 'rollup-plugin-node-resolve';
3+
4+
export default {
5+
format: 'umd',
6+
moduleName: 'journalize',
7+
plugins: [
8+
commonjs(),
9+
node({
10+
jsnext: true,
11+
main: true
12+
})
13+
]
14+
};

src/apnumber.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import isInteger from 'lodash/isInteger';
2+
import isNil from 'lodash/isNil';
3+
4+
/**
5+
* List of spelled out numbers per AP style.
6+
* @private
7+
* @type {Array}
8+
*/
9+
var AP_NUMBERS = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
10+
11+
/**
12+
* Converts an integer to string representation per AP style rules. If an
13+
* integer is not one that would be converted, it is returned in its original
14+
* form.
15+
*
16+
* If a non-integer is given, it will be returned in its original form, as
17+
* well.
18+
*
19+
* @param {Number} val
20+
* @return {String}
21+
* @example
22+
*
23+
* var journalize = require('journalize');
24+
*
25+
* journalize.apnumber(8);
26+
* // returns 'eight'
27+
*
28+
* journalize.apnumber(42);
29+
* // returns 42
30+
*
31+
*/
32+
export default function apnumber (val) {
33+
// if `val` is undefined or null, return an empty string
34+
if (isNil(val)) return '';
35+
36+
var convertedVal = +val;
37+
38+
// if `convertedVal` is not an integer, return `val`
39+
if (!isInteger(convertedVal)) return val;
40+
41+
// if `convertedVal` is not between 0 and 10, return `val`
42+
if (convertedVal <= 0 || convertedVal >= 10) return val;
43+
44+
return AP_NUMBERS[convertedVal - 1];
45+
}

src/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import apnumber from './apnumber';
2+
import intword from './intword';
3+
import ordinal from './ordinal';
4+
5+
export {
6+
apnumber,
7+
intword,
8+
ordinal
9+
};

src/intword.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import isInteger from 'lodash/isInteger';
2+
import isNil from 'lodash/isNil';
3+
4+
export default function intword (val) {
5+
if (isNil(val)) return '';
6+
7+
var convertedVal = +val;
8+
9+
if (!isInteger(convertedVal)) return val;
10+
if (convertedVal < 1000000) return convertedVal;
11+
12+
return convertedVal;
13+
}

src/ordinal.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import isInteger from 'lodash/isInteger';
2+
import isNil from 'lodash/isNil';
3+
import includes from 'lodash/includes';
4+
5+
/**
6+
* A list of suffixes for conversions.
7+
* @private
8+
* @type {Array}
9+
*/
10+
var SUFFIXES = ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'];
11+
12+
/**
13+
* Converts an integer into its ordinal form. Handles the special cases of 11,
14+
* 12 and 13, too. If a non-integer is submitted, it will be returned in its
15+
* original form.
16+
*
17+
* @param {Number} val
18+
* @return {String}
19+
* @example
20+
*
21+
* var journalize = require('journalize');
22+
*
23+
* journalize.ordinal(5);
24+
* // returns '5th'
25+
*
26+
* journalize.ordinal(13);
27+
* // returns '13th'
28+
*
29+
* journalize.ordinal(103);
30+
* // returns '103rd'
31+
*/
32+
export default function ordinal (val) {
33+
// if `val` is undefined or null, return an empty string
34+
if (isNil(val)) return '';
35+
36+
var convertedVal = +val;
37+
38+
// if `convertedVal` is not an integer, return `val`
39+
if (!isInteger(convertedVal)) return val;
40+
41+
// if `convertedVal` is 11, 12 or 13, English gets weird
42+
if (includes([11, 12, 13], convertedVal % 100)) return convertedVal + SUFFIXES[0];
43+
44+
return convertedVal + SUFFIXES[convertedVal % 10];
45+
}

test/test.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
var assert = require('assert');
2+
var range = require('lodash/range');
3+
4+
var journalize = require('../src');
5+
6+
describe('apnumber', () => {
7+
it('should correctly convert numbers', () => {
8+
var test_list = range(-1, 11).map((n) => n.toString());
9+
10+
var result_list = ['-1', '0', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', '10'];
11+
12+
test_list.forEach((n, idx) => {
13+
assert.deepEqual(journalize.apnumber(n), result_list[idx]);
14+
});
15+
});
16+
17+
it('should return empty string when input is `undefined`', () => {
18+
assert.deepEqual(journalize.apnumber(undefined), '');
19+
});
20+
21+
it('should return empty string when input is `null`', () => {
22+
assert.deepEqual(journalize.apnumber(null), '');
23+
});
24+
25+
it('should return original input when input is not a number', () => {
26+
assert.deepEqual(journalize.apnumber('corgi'), 'corgi');
27+
});
28+
29+
it('should return original input when input is not an integer', () => {
30+
assert.deepEqual(journalize.apnumber('1.234'), '1.234');
31+
});
32+
});
33+
34+
describe('ordinal', () => {
35+
it('should correctly convert ordinals', () => {
36+
var test_list = ['1', '2', '3', '4', '11', '12', '13', '101', '102', '103', '111'];
37+
var result_list = ['1st', '2nd', '3rd', '4th', '11th', '12th', '13th', '101st', '102nd', '103rd', '111th'];
38+
39+
test_list.forEach((n, idx) => {
40+
assert.deepEqual(journalize.ordinal(n), result_list[idx]);
41+
});
42+
});
43+
44+
it('should return empty string when input is `undefined`', () => {
45+
assert.deepEqual(journalize.ordinal(undefined), '');
46+
});
47+
48+
it('should return empty string when input is `null`', () => {
49+
assert.deepEqual(journalize.ordinal(null), '');
50+
});
51+
52+
it('should return original input when input is not a number', () => {
53+
assert.deepEqual(journalize.ordinal('corgi'), 'corgi');
54+
});
55+
56+
it('should return original input when input is not an integer', () => {
57+
assert.deepEqual(journalize.ordinal('1.234'), '1.234');
58+
});
59+
});
60+
61+
describe('intword', () => {
62+
it('should correctly convert integers to words', () => {
63+
var test_list = ['100', '1000000', '1200000', '1290000', '1000000000', '2000000000', '6000000000000', '1300000000000000', '3500000000000000000000', '8100000000000000000000000000000000'];
64+
var result_list = ['100', '1.0 million', '1.2 million', '1.3 million', '1.0 billion', '2.0 billion', '6.0 trillion', '1.3 quadrillion', '3.5 sextillion', '8.1 decillion'];
65+
66+
test_list.forEach((n, idx) => {
67+
assert.deepEqual(journalize.intword(n), result_list[idx]);
68+
});
69+
});
70+
71+
it('should return empty string when input is `undefined`', () => {
72+
assert.deepEqual(journalize.intword(undefined), '');
73+
});
74+
75+
it('should return empty string when input is `null`', () => {
76+
assert.deepEqual(journalize.intword(null), '');
77+
});
78+
79+
it('should return original input when input is not a number', () => {
80+
assert.deepEqual(journalize.intword('corgi'), 'corgi');
81+
});
82+
83+
it('should return original input when input is not an integer', () => {
84+
assert.deepEqual(journalize.intword('1.234'), '1.234');
85+
});
86+
});

0 commit comments

Comments
 (0)