Giter VIP home page Giter VIP logo

journalize's Introduction

journalize

A collection of functions useful for making prose reader friendly. Inspired by (and initially based on) Django's django.contrib.humanize.

build status Coveralls branch npm version npm

Why did you create this?

I've always really appreciated the built-in functionality provided by Django's humanize, and I wanted to port it over to JavaScript/Node.js. Originally this was to be a collection of custom filters, but I think it could be just as useful as a generic library.

Installation

npm install journalize

# or

yarn add journalize

journalize tries to support the many ways to load packages in the Node.js ecosystem.

If you use a module bundler like Browserify or Webpack, a version of journalize is built to be compatible.

const journalize = require('journalize');

// you can also reach in and grab specific functions
const intcomma = require('journalize').intcomma;
// or
const { intcomma } = require('journalize');

It also supports ES6 imports:

import { intcomma } from 'journalize';

// or if you want the whole thing
import * as journalize from 'journalize';

API Docs

Table of Contents

apdate

Returns an AP-formatted date string that corresponds with the supplied Date. If an input is not passed, it will use the result of new Date();.

Parameters

  • date Date? JavaScript Date object, defaults to current date if not passed (optional, default new Date())

Examples

var journalize = require('journalize');

// Remember that JavaScript zero-indexes months!
journalize.apdate(new Date(2016, 10, 8));
// returns 'Nov. 8, 2016'

// Uses the current date if no parameter is passed
journalize.apdate();
// returns 'July 4, 2016' (pretend it is actually July 4, 2016)

Returns string

apdatetab

Returns a tabular AP-formatted date string that corresponds with the supplied Date. If an input is not passed, it will use the result of new Date();.

Parameters

  • date Date? JavaScript Date object, defaults to current date if not passed (optional, default new Date())

Examples

var journalize = require('journalize');

// Remember that JavaScript zero-indexes months!
journalize.apdate(new Date(2016, 10, 8));
// returns 'Nov 8, 2016'

// Uses the current date if no parameter is passed
journalize.apdate();
// returns 'Jul 4, 2016' (pretend it is actually July 4, 2016)

Returns string

apmonth

Returns an AP-formatted month string that corresponds with the supplied Date. If an input is not passed, it will use the result of new Date();.

Parameters

  • date Date? JavaScript Date object, defaults to current date if not passed (optional, default new Date())

Examples

var journalize = require('journalize');

// Remember that JavaScript zero-indexes months!
journalize.apmonth(new Date(2016, 10, 8));
// returns 'Nov.'

// Uses the current date if no parameter is passed
journalize.apmonth();
// returns 'July' (pretend it is actually July)

Returns string

apmonthtab

Returns a tabular AP-formatted month string that corresponds with the supplied Date. If an input is not passed, it will use the result of new Date();.

Parameters

  • date Date? JavaScript Date object, defaults to current date if not passed (optional, default new Date())

Examples

var journalize = require('journalize');

// Remember that JavaScript zero-indexes months!
journalize.apmonth(new Date(2016, 10, 8));
// returns 'Nov'

// Uses the current date if no parameter is passed
journalize.apmonth();
// returns 'Jul' (pretend it is actually July)

Returns string

apnumber

Converts an integer to string representation per AP style rules. If an integer is not one that would be converted, it is returned in its original form.

If a non-integer is given, it will be returned in its original form as well.

Parameters

Examples

var journalize = require('journalize');

journalize.apnumber(8);
// returns 'eight'

journalize.apnumber(42);
// returns 42

Returns string

aptime

Returns an AP-formatted time string that corresponds with the supplied Date. If an input is not passed, it will use the result of new Date();.

Parameters

  • date Date? JavaScript Date object, defaults to current date if not passed (optional, default new Date())

Examples

var journalize = require('journalize');

// Bright and early
journalize.aptime(new Date(2016, 10, 8, 6, 30));
// returns '6:30 a.m.'

// It can handle `p.m.` too
journalize.aptime(new Date(2016, 10, 8, 16, 30));
// returns '4:30 p.m.'

// Uses the current time if no parameter is passed
journalize.aptime();
// returns '6:45 p.m.' (pretend it is actually 6:45 p.m. right now)

Returns string

capfirst

Capitalizes the first character of a value and returns it.

Parameters

  • val any

Examples

var journalize = require('journalize');

journalize.capfirst('hello world');
// returns 'Hello world'

Returns string

intcomma

Alters a string or number to include commas. If val is undefined or null, an empty string is returned.

Parameters

Examples

var journalize = require('journalize');

journalize.intcomma(10311);
// returns '10,311'

journalize.intcomma('1234567.1234567');
// returns '1,234,567.1234567'

Returns string

intword

Converts a large integer into a string representation. Only makes sense for numbers at least 1 million or more.

Parameters

Examples

var journalize = require('journalize');

journalize.intword(1000000);
// returns '1 million'

journalize.intword(6500000000000);
// returns '6.5 trillion'

Returns string

ordinal

Converts an integer into its ordinal form. If spellOutOrdinals is true, 1 through 9 will be spelled out per AP style. Handles the special cases of 11, 12 and 13, too. If a non-integer is submitted it will be returned in its original form.

Parameters

Examples

var journalize = require('journalize');

journalize.ordinal(5);
// returns '5th'

journalize.ordinal(13);
// returns '13th'

journalize.ordinal(103);
// returns '103rd'

journalize.ordinal(7, true);
// returns 'seventh'

Returns string

ordinalsuffix

Determines the ordinal suffix for a given integer. Handles the special cases of 11, 12 and 13. If a non-integer is submitted an empty string will be returned.

Parameters

Examples

var journalize = require('journalize');

journalize.ordinalsuffix(5);
// returns 'th'

journalize.ordinalsuffix(13);
// returns 'th'

journalize.ordinalsuffix(103);
// returns 'rd'

journalize.ordinalsuffix(7);
// returns 'th'

journalize.ordinalsuffix('foo');
// returns ''

Returns string

pluralize

Returns a plural suffix if the value is not 1. By default, pluralize uses "s" as the suffix. If a String is provided, pluralize will attempt to convert it into a Number. If an Array is provided instead of a number, the length of the Array is used to determine the suffix. An alternative plural suffix can be provided as the second parameter, and if necessary, an alternative singular suffix can be provided as the third.

Parameters

Examples

var journalize = require('journalize');

// typical usage
'vote' + journalize.pluralize(0); // votes
'vote' + journalize.pluralize(1); // vote
'vote' + journalize.pluralize(2); // votes

// the plural suffix may be changed
'class' + journalize.pluralize(0, 'es'); // classes
'class' + journalize.pluralize(1, 'es'); // class
'class' + journalize.pluralize(2, 'es'); // classes

// some words also need a custom singular suffix
'cand' + journalize.pluralize(0, 'ies', 'y'); // candies
'cand' + journalize.pluralize(1, 'ies', 'y'); // candy
'cand' + journalize.pluralize(2, 'ies', 'y'); // candies

Returns string

widont

Prevents "widows" - a word by itself on a line - from appearing in strings by replacing the space between the last two words with a non-breaking space character.

Parameters

  • val string
  • replaceChar string The character to replace the space with (optional, default '\xA0')

Examples

var journalize = require('journalize');

journalize.widont('this is a string');
// returns 'this is a string'

journalize.widont('this is a string', 'HELLO');
// returns 'this is aHELLOstring'

Returns string

yesno

Given a mapping of arguments for true, false, and (optionally) null/undefined, return a string according to the value. If maybe is not provided, a null or undefined value will return the no argument.

Parameters

Examples

var journalize = require('journalize');

journalize.yesno(true);
// returns 'yes'
journalize.yesno(false);
// returns 'no'
journalize.yesno(null);
// returns 'maybe'

journalize.yesno(true, 'yay', 'nay', 'shruggie');
// returns 'yay'
journalize.yesno(false, 'yay', 'nay', 'shruggie');
// returns 'nay'
journalize.yesno(null, 'yay', 'nay', 'shruggie');
// returns 'shruggie'

Returns (string | boolean | Null | undefined)

What if I do want to use this in Nunjucks?

Great question! I cannot speak to whether this is the best way, but it's what I've done without issue since journalize was released.

Once you have your nunjucks environment, you can loop through the properties of journalize and add each function as a filter.

const journalize = require('journalize');
const nunjucks = require('nunjucks');

const env = nunjucks.configure(/* */);

/*
Set up `journalize`.
 */
for (let key in journalize) {
  let func = journalize[key];

  if (typeof func === 'function') {
    env.addFilter(key, func); // this would work with env.addGlobal, too
  }
}

Now every function of journalize is available in your templates!

License

MIT

journalize's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar greenkeeperio-bot avatar mhkeller avatar rdmurphy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

journalize's Issues

Should there be a tabular version of apmonth? (Jan, Mar, Nov, etc.)

A variation of AP style on months is that in extremely tight scenarios you can use what they consider the "tabular" forms of month abbreviations, which is the first three characters of a month without a ending period. (Same logic with May of course, but it doesn't matter there.)

If it's worth having, there are a few paths we could take. apmonth (and apdate) currently have a single parameter (the input Date) so it would have to be decided whether we finally break from that and add options, or if there are spin off versions that do this instead. (Something like apmonthtab, tabularapmonth or something else less gross.)

I lean toward the option approach because it'd be wacky IMO to keep making spin offs for each little variation, and apdate is already slightly needing some way to optionally include the year.

Another path is to only do this for apmonth and not apdate, which one could assume is rarely after the tabular format.

intword() approx vs. exact

Would it be worthwhile to extend intword() so that it indicates whether the result is exact (65000000 = 6.5 million, EXACT) versus rounded (65036204 = 6.5 million, APPROX)?

Consider adding json_script from Django

Source reference.

This does risk going into a little funky territory — technically this should output HTML markup, and not just return a primitive value. It's not a big deal to build (already doing on the job, easy enough to port) but curious if that'd be a blocker for anyone.

It's also a feature that pretty much expects to be in a server-side world exclusively — cannot think of a scenario where you'd do this client-side.

(We could, however, additionally add a script that helps consume what json_script outputs.)

Feature request: intcomma options

Some style guides insert commas in numbers only starting at five digits.

10000 => 10,000
but
5000 => 5000

Also, some style guides use spaces instead of commas:

3000000 => 3 000 000

It would be helpful to have options to deal with each case.

Add `apmonth` function

AP has formatting rules for writing out months. Like states, some get abbreviated, and others are never abbreviated.

AP Date, but UTC

Have run into this a couple times, and running into it now: Editor puts a localized datetime in a source doc. Javascript parses as UTC and displays in local time, which is offset. Now the date is off.

Simplest solution I can think of is to parse and display as UTC, probably as a separate function, alongside apdate.

Support for a precision-based round/floor/ceil function

JavaScript has built-in functions for doing rounding calculations via the Math object. But what is missing is a way to supply a precision value to control where the rounding takes place in a number.

Lodash's version makes it possible to pass in a second parameter declaring the precision. Jinja2's filters also include a round() function that accepts a precision value and a flag for which rounding logic to use. And because Jinja2 does it, so does Nunjucks. (This does mean that Nunjucks doesn't technically need this enhancement.)

And while the logic to do this isn't complicated it's maybe just annoying enough to re-find/copy in that this would be helpful.

Decide whether date methods continue to be locale sensitive

This has come up multiple times over the years (#176, #276) and v3 is probably a great time to finally make the call.

The internal calls on the input Date in apdate assume the locale the code is running in — this means there are windows of time where you may end up with the wrong day because in a user's timezone the day has not turned over yet or already changed.

What makes this so tricky is journalize has absolutely no say in the origin of the Date it gets passed. Is it timezone adjusted? Was it just built from an ISO string?

The only observation I can confidently make — I've foisted journalize into so many codebases and I cannot think of a single time I've intentionally passed in a timezone aware date. I'd say nearly all scenarios where I've used it the original source was an ISO string I turned into a Date either via date.split('-') (and so on) or with a parse method via something like date-fns.

My hunch is I'm not alone in this.

aptime gives incorrect output at noon

The hour is reported as 0 rather than 12.

var journalize = require("journalize")
var date = new Date("2018-09-15T16:39:27.832Z") // My browser is in Eastern time
journalize.aptime(date) // "0:39 p.m."

I reproduced this bug in Chrome 68 and Firefox 62 running on macOS Sierra.

Find answer for date functions and year outputs

This would be a breaking change if done.

Frankly in the majority of scenarios that I'm attempting to use apdate the very first thing I do is peel off the , YEAR that's at the end of the string. Would it make sense for it to stop doing it entirely, or to make it a flag?

Originally it was going to be "smart" and only include it if the input date isn't current year, but I worried that was too clever.

Any input would be appreciated. 👋

[feat] Ordinal parameter to return only suffix

What
Add an optional parameter to have journalize.ordinal() return solely the suffix. Alternatively, add parameters to return it wrapped in sup or sub (though this assumption is not ideal).

I'm willing to write a quick PR for this.

Why
In many cases I would like to style or otherwise display the suffix. This currently is not possible without evoking the function, running code to split numbers from letters, and then rendering the html. It'd be easier and less expensive to have journalize break it apart for me.

Example use case:

<p>1<sup>st</sup></p>

How

Add an onlySuffix param in the default function of src/ordinal.js:

// if `convertedVal` is 11, 12 or 13, English gets weird
if (ENGLISH_ORDINAL_EXCEPTIONS.indexOf(convertedVal % 100) > -1) {
  if (onlySuffix) return SUFFIXES[0];
  return convertedVal + SUFFIXES[0];
}

if (onlySuffix) return SUFFIXES[convertedVal % 10];
return convertedVal + SUFFIXES[convertedVal % 10];

With an additional parameter, it may be best to have the parameters now be in object form for clarity. This would be a breaking change though.

journalize.ordinal(num, { spellOutOrdinal: boolean, onlySuffix: boolean })

Add `boolify` function (working title)

You sometimes see this called yesno as well, but that'd clash with #92. It's in the same ballpark, however.

This would normalize things like yes, YES, y, true, and 1 to the Boolean true, and no, NO, n, false, and 0 to the Boolean false.

This is basically what this package does, and we could even just straight up wrap it. The only iffy thing here is the inclusion of 1 and 0. I can totally see where in a general sense you'd know those should be "boolified," but in the journalism world sometimes numbers are, well, actually numbers. Could be a super edge case though.

"ordinal" should have a flag for spelling out 1-9 in AP style

Shocked this hasn't really came up until now, but here we are.

Similar to how apnumber converts 1 through 9 to their spelled out versions, ordinal should have a flag that optionally makes values from 1 through 9 be spelled out. (First, fifth, ninth, etc.)

Migrate intcomma to Intl.NumberFormat

I think it'd be good to rid this function of the regex that figures out where to place commas and migrate to the Intl.NumberFormat API.

This in theory would create a path for adding light localization to journalize without requiring a massive dependency.

Add `apstate` function

Per a suggestion on Twitter — there are some conversions that would make sense to be added via wireservice's lookup. The most obvious one is an AP style state abbreviation conversion.

Main questions to answer:

  1. Does this actually depend on that repo? Or do we grab a copy to use here?
  2. We need JSON. lookup doesn't provide JSON. While there are ways to read CSV in JS, I'd rather not add that to the library. Either we politely ask lookup to add JSON versions of the data files 😄, or we do the conversion on our end.

Add `yesno` function

Should work somewhat like Django's yesno.

Ideally though it's not a comma separated parameter being passed in and instead the standard function parameters like you'd expect.

intcomma rounding

I don't know if I would call this a feature or a bug or really anything more than just a thing, but I've noticed that intcomma decides to round off decimals of zero, but not other numbers. For instance:

journalize.intcomma(1000.0)
'1,000'

This is the case even when the user submits a value with an explicitly fixed decimal place.

journalize.intcomma((1000.0).toFixed(1))
'1,000'

I'm certain there is probably some good reason for this I'm unaware of, but I wanted to file this ticket since the second example above was not the behavior I expected as a user.

For what it's worth, it is also not the behavior of the old gods of Django.

>>> from django.contrib.humanize.templatetags.humanize import intcomma
>>> intcomma(1000.0)
'1000.0'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.