From 26a7056a2a5f422e211a6a59bfc06a11ffc58b36 Mon Sep 17 00:00:00 2001 From: Joschua Schneider Date: Fri, 17 Sep 2021 15:54:51 +0200 Subject: [PATCH] add optimizations and documentation --- .gitignore | 5 +++- .npmignore | 2 ++ README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 +- src/mehrzahl.ts | 38 ++++++++++++------------- 5 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 .npmignore diff --git a/.gitignore b/.gitignore index d2eebe9..e6aac56 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ lib/ # dependencies -node_modules/ \ No newline at end of file +node_modules/ + +# bench +bench/ \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..7958889 --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +bench/ +.github/ \ No newline at end of file diff --git a/README.md b/README.md index a331634..1e408de 100644 --- a/README.md +++ b/README.md @@ -1 +1,72 @@ -# Mehrzahl \ No newline at end of file +# mehrzahl + +[![npm version](https://badgen.net/npm/v/mehrzahl)](https://www.npmjs.com/package/mehrzahl) +![Bundlephobia Minzipped Size](https://badgen.net/bundlephobia/minzip/mehrzahl) +![build workflow](https://github.com/JoschuaSchneider/mehrzahl/actions/workflows/build.yml/badge.svg?branch=main) +![test workflow](https://github.com/JoschuaSchneider/mehrzahl/actions/workflows/test.yml/badge.svg?branch=main) +![TypeScript](https://badgen.net/badge/-/TypeScript/blue?icon=typescript&label) +![License: MIT](https://badgen.net/npm/license/mehrzahl) + +Tiny utility to format parts of a template string in singular or plural. + +### Installation + +```bash +npm i mehrzahl +``` +```bash +yarn add mehrzahl +``` + +### Usage + +```ts +import { mz } from "mehrzahl" +// import mz from "mehrzahl" // default import + +const str = mz(1)`There {was|were} $value person{|s} at this event.` +// str = "There was 1 person at this event." +const str = mz(5)`There {was|were} $value person{|s} at this event.` +// str = "There were 5 persons at this event." +``` + +💡 `$value` is replaced by the amount specified. + +#### Singular/Plural tuples + +```ts +const str = mz(1)`There ${['was', 'were']} $value person${[,'s']} at this event.` +// str = "There was 1 person at this event." +const str = mz(5)`There ${['was', 'were']} $value person${[,'s']} at this event.` +// str = "There were 5 persons at this event." +``` + +💡 Left or right value of the delimiter `|` can be omitted: +`{|plural}` or `{singular|}` + +💡 First or second value of tuples can be omitted: +`[,'plural']` or `['singular']` + +**Singular/Plural formatter function** + +```ts +const wasWereFormatter = (plural) => plural ? 'were' : 'was' +const personPersonsFormatter = (plural) => plural ? 'persons' : 'person' + +const str = mz(1)`There ${wasWereFormatter} $value ${personPersonsFormatter} at this event.` +// str = "There was 1 person at this event." +const str = mz(5)`There ${wasWereFormatter} $value ${personPersonsFormatter} at this event.` +// str = "There were 5 persons at this event." +``` + +#### Customizing the delimiter +Pass your custom delimiter as a second argument. +```ts +const str = mz(1, ';')`There {was;were} $value person{;s} at this event.` +``` + +## Contributions + +Contributions are always welcome. + +Feel free to open issues or pull requests! \ No newline at end of file diff --git a/package.json b/package.json index 62f38b6..9edd464 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mehrzahl", - "version": "0.0.1-alpha3", + "version": "1.0.0", "description": "Tagged template literals for singular/plural formatting", "source": "src/index.ts", "main": "lib/index.js", diff --git a/src/mehrzahl.ts b/src/mehrzahl.ts index f93479e..e866aca 100644 --- a/src/mehrzahl.ts +++ b/src/mehrzahl.ts @@ -24,24 +24,23 @@ export type InterpolatableValue = const DEFAULT_DELIMITER = "|" const GROUPING_REGEX = /\{(.*?)\}/g +const formatGroupSyntax = ( + value: string, + isPlural: boolean, + delimiter: string +) => + value.replace(GROUPING_REGEX, (_, firstSubmatch) => { + if (typeof firstSubmatch === "string") { + return firstSubmatch.split(delimiter)[isPlural ? 1 : 0] + } + return firstSubmatch + }) + export const mz: MehrzahlFormatterFactory = (amount, delimiter = DEFAULT_DELIMITER) => (strings, ...valuesToInterpolate) => { const isPlural = amount > 1 - - const formatGroupSyntax = (value: string) => - value.replace(GROUPING_REGEX, (_, firstSubmatch) => { - if (typeof firstSubmatch === "string") { - const [singular, plural] = firstSubmatch.split(delimiter) - return isPlural ? plural : singular - } - - return firstSubmatch - }) - - if (strings.length === 1) { - return formatGroupSyntax(strings[0]).replace("$value", amount.toString()) - } + const amountString = amount.toString() const interpolatedValues = valuesToInterpolate.map((value) => { if (typeof value === "function") { @@ -49,10 +48,9 @@ export const mz: MehrzahlFormatterFactory = } if (Array.isArray(value)) { - return value[isPlural ? 1 : 0]?.toString() ?? "" + return value[isPlural ? 1 : 0] ?? "" } - - return value.toString() + return value }) return formatGroupSyntax( @@ -60,6 +58,8 @@ export const mz: MehrzahlFormatterFactory = (result, part, index) => result + part + (interpolatedValues[index] ?? ""), "" - ) - ).replace("$value", amount.toString()) + ), + isPlural, + delimiter + ).replace("$value", amountString) }