An open API service indexing awesome lists of open source software.

https://github.com/reececomo/gcomply

Lightweight automatic grammar agreement engine for JavaScript/TypeScript
https://github.com/reececomo/gcomply

grammar l10n language localization natural-language nlp

Last synced: 8 months ago
JSON representation

Lightweight automatic grammar agreement engine for JavaScript/TypeScript

Awesome Lists containing this project

README

          


🪡 GComply


Beautiful and natural-sounding text in human interfaces.


NPM version
License
Minzipped size


```ts
`Add ${count} person to group.`
// ❌ "Add 2 person to group."

g`Add ${count} person to group.`
// ✅ "Add 2 people to group."
```


Lightweight automatic grammar agreement.

> [!WARNING]
> **Experimental**: This is an experimental JavaScript API for automatic grammar
> agreement, modeled after the equivalent
> [Swift API](https://developer.apple.com/documentation/foundation/inflectionrule).

## **🚀 Mission**

- ✅ **What it is:**
A lightweight engine for automatic grammar agreement – scoped specifically for human
interfaces in software products. Provide fast, automatic grammar agreement to cover ~99%
of real-world cases. Take the edge-case handling out of UI.

- ❌ **What it is NOT:**
Perfect or feature-complete grammar correction, stemming/lemmatization, lexical analysis,
or sentiment analysis. This package will never

📘 Read more: Distinction from ICU Intl.MessageFormat

**Intl.MessageFormat** provides manual support for plural/selects. But it is entirely
manual, and up to developers to predict all variance. It's also very challenging to
correctly translate any string where a parameter (i.e. a noun) is interpolated.

**Example:**

```ts
const notification = t("I was in {country}")
// German: "Ich war in {country}"

const switzerland = t("Switzerland")
// German: "die Schweiz"

notification.format({ country: switzerland })
// "Ich war in die Schweiz" ❌

// The feminine dative article is "der" (not
// "die") so it should instead be:
// "Ich war in der Schweiz" ✅
```

In this example if you supported 180+ countries, you might have a much bigger problem.

So to summarize, **ICU MessageFormat** is a great tool, but its focused primarily on a
different problem.

### Add plurals

```ts
import { Grammar, Plurals } from "gcomply";

Plurals.getLang("en").addTagged(Grammar.PartOfSpeech.noun,
{ one: "sausage", other: "sausages" },
{ one: "twist", other: "twists" },
);
```

## ✨ Features

- ⚡️ **Instant grammar agreement** — plurals, gender, articles, etc.
- 📦 **Highly pluggable** — compatible with any other framework
- 🌐 **Localizable** — add support for any natural language
- 🪶 **Lightweight** — <5kB, zero dependencies

Add custom transforms, domain terminology, nouns, pronouns, and more.

## API Usage

### Simple usage

- Syntax: ``` g`` ```

The `g` tagged template will coerce inline grammar
(in accordance to any global options).

```ts
import { g } from "gcomply";

let views = content.viewCount,
shares = content.shareCount

let text = g`${views} new views, ${shares} new shares`
// "35 new views, 1 new share"
```

### Complex grammar

- Syntax: `inflect(text, options?)`

The `inflect()` function provides a little more flexibility for complex
grammatical agreement, and may also be passed additional external options:

```ts
import { inflect } from "gcomply";

let text = "Votre conseiller est prêt."

let opts = {
language: "fr",
morphology: { grammaticalGender: "feminine" }
}

inflect(text) // "Votre conseiller est prêt."
inflect(text, opts) // "Votre conseillère est prête."
```

> [!NOTE]
> **Terminology:**
>
> Parts of the API terminology is modeled to be consistent with the emerging equivalent
> Swift APIs for
> [morphology](https://developer.apple.com/documentation/foundation/morphology)
> and [inflection](https://developer.apple.com/videos/play/wwdc2023/10153/).
>
> Notably though, there is **no direct proxy** for Swift's
> [AttributedString](https://developer.apple.com/documentation/foundation/attributedstring)
> in JavaScript.

## Implementation status

These are the Swift agreement features:

| Status | Agreement Type | Methodology | Code Changes | Description
| --- | ---------------------- | ----------------------- | ------------ | ---
| partial | `inflect` | Proximity-based | No | Reference neighboring elements.
| ❌ | `agreeWithArgument` | Explicit reference, same string | No | Directly reference other elements in the strings.
| ❌ | `agreeWithConcept` | Explicit reference, injected | Yes | Agree with a `Concept` passed in via context.

> [!NOTE]
> **Source:** See [WWDC2023 @ 6:15](https://developer.apple.com/videos/play/wwdc2023/10153/)

## 🛠️ Contributing

Contributions are welcome, such as:
- New language packs
- More granular inflection rules
- Bug fixes and test cases
- Integrations for other frameworks or i18n tools

> [!Important]
> Keep in mind, the goal of this package is not to provide perfect and comprehensive
> language support that covers all possible permutations out-of-the-box.