Skip to content

Commit

Permalink
add optimizations and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Joschua Schneider committed Sep 17, 2021
1 parent 6620e70 commit 26a7056
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 22 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
lib/

# dependencies
node_modules/
node_modules/

# bench
bench/
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bench/
.github/
73 changes: 72 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,72 @@
# Mehrzahl
# 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!
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
38 changes: 19 additions & 19 deletions src/mehrzahl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,42 @@ 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") {
return value(isPlural, amount)
}

if (Array.isArray(value)) {
return value[isPlural ? 1 : 0]?.toString() ?? ""
return value[isPlural ? 1 : 0] ?? ""
}

return value.toString()
return value
})

return formatGroupSyntax(
strings.reduce(
(result, part, index) =>
result + part + (interpolatedValues[index] ?? ""),
""
)
).replace("$value", amount.toString())
),
isPlural,
delimiter
).replace("$value", amountString)
}

0 comments on commit 26a7056

Please sign in to comment.