Metadata-Version: 2.4
Name: emoji-index
Version: 0.2.0
Summary: A lightweight extension to the emoji library providing indexed traversal of emoji characters for selection menus
Author-email: nQuest Corporation <support@nquest.io>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/nquest-corp/emoji-index
Project-URL: Repository, https://github.com/nquest-corp/emoji-index
Project-URL: Issues, https://github.com/nquest-corp/emoji-index/issues
Keywords: emoji,unicode,index,emoji-data,emoji-picker,emoticons,shortcodes,picker
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing
Classifier: Topic :: Text Processing :: Linguistic
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: LICENSE_UNICODE.txt
Requires-Dist: emoji>=2.15.0
Dynamic: license-file

# emoji-index

[![PyPI version](https://badge.fury.io/py/emoji-index.svg)](https://pypi.org/project/emoji-index/)
[![Python versions](https://img.shields.io/pypi/pyversions/emoji-index.svg)](https://pypi.org/project/emoji-index/)
[![License](https://img.shields.io/github/license/nquest-corp/emoji-index.svg)](LICENSE)
[![Unicode Emoji](https://img.shields.io/badge/unicode_emoji-17.0-blue.svg)](https://unicode.org/reports/tr51/)

Browse every Unicode emoji by **group → subgroup → emoji** — the missing index for building emoji pickers, category menus, and search UIs in Python. Built on the official [Unicode Emoji data](https://unicode.org/reports/tr51/#emoji_data) (Emoji 17.0) with version filtering and skin tone grouping included.

## Why emoji-index?

The [`emoji`](https://github.com/carpedm20/emoji/) library is excellent for converting between shortcodes and Unicode characters, but it has no concept of emoji groups or subgroups. Its `EMOJI_DATA` dictionary is a flat mapping from character to metadata — there's no built-in way to browse "all face emojis" or "all food emojis."

`emoji-index` is a companion to that library, not a replacement: it organizes the same characters into the official Unicode groups and subgroups, so category-based browsing falls out naturally.

### When to use it

- **Emoji pickers and menus** — groups map to tabs, subgroups to sections, emojis to buttons.
- **Version-gated emoji sets** — ship only emojis a target platform supports (e.g., pin to 13.0 for older devices).
- **Curated browsing or datasets** — walk emojis in Unicode (CLDR) order, or pull every emoji in a category for analysis.
- **Frontend payloads** — each `Emoji` bundles the character, name, `:shortcode:` alias, and skin tone variants in one JSON-serializable object.

### When not to use it

- **Just converting shortcodes** — if you only need `emojize`/`demojize`, use the `emoji` library directly; this package adds nothing there.
- **Multi-person groupings** — `family`, `couple with heart`, and similar sequences are excluded (see Known Limitations).
- **Multilingual search or keywords** — names and aliases are English-only; CLDR annotations in other languages are out of scope.
- **Render support detection** — the index reflects the Unicode standard, not what a given OS, browser, or font can actually display.
- **Finding emoji inside free text** — for detection, segmentation, or stripping emoji from strings, use a regex-based tool instead.

## Features

- **Hierarchical browsing** — 9 groups, 99 subgroups, 1,861 emojis at the default version, following the Unicode standard
- **Version filtering** — pin the index to any Emoji version from 1.0 to 17.0 for cross-platform compatibility
- **Skin tone grouping** — variants (👋🏻 👋🏼 👋🏽 👋🏾 👋🏿) nest under their parent emoji instead of cluttering the index
- **Picker-ready objects** — each emoji carries its character, human-readable name, `:shortcode:` alias, and variants
- **Zero configuration** — `from emoji_index import emoji_index` and start browsing

## Installation

```bash
pip install emoji-index
```

Requires Python >= 3.10 and `emoji` >= 2.15.0.

## Quick Start

```python
from emoji_index import emoji_index

for group in emoji_index.groups:
    for subgroup in emoji_index[group].subgroups:
        for emoji in emoji_index[group][subgroup]:
            print(f"{emoji.emoji} {emoji.name}")
```

Output:

```
😀 grinning face
😃 grinning face with big eyes
😄 grinning face with smiling eyes
😁 beaming face with smiling eyes
😆 grinning squinting face
...
```

## Examples

### Build a picker menu

Groups and subgroups map directly onto picker tabs and sections:

```python
from emoji_index import emoji_index

menu = {group: emoji_index[group].subgroups for group in emoji_index.groups}
print(len(menu), "tabs; first tab sections:", menu["Smileys & Emotion"][:5])
# 9 tabs; first tab sections: ['face-smiling', 'face-affection', 'face-tongue', 'face-hand', 'face-neutral-skeptical']
```

### Search by name

```python
hits = [
    (e.emoji, e.name)
    for group in emoji_index.groups
    for subgroup in emoji_index[group].subgroups
    for e in emoji_index[group][subgroup]
    if "heart" in e.name
][:5]
print(hits)
# [('🥰', 'smiling face with hearts'), ('😍', 'smiling face with heart-eyes'), ('😻', 'smiling cat with heart-eyes'), ('💘', 'heart with arrow'), ('💝', 'heart with ribbon')]
```

### Target an older Emoji version

Only show emojis available on platforms that lag behind the latest release:

```python
from emoji_index import EmojiIndex

picker = EmojiIndex()
picker.set_version("13.0")
count = sum(len(picker[g][s]) for g in picker.groups for s in picker[g].subgroups)
print(count, "emojis at Emoji 13.0")  # 1758 emojis at Emoji 13.0 (vs 1861 at 17.0)
```

### Export to JSON

`Emoji` is a dataclass, so it serializes cleanly for APIs and front ends:

```python
import json
from dataclasses import asdict

first = emoji_index["Smileys & Emotion"]["face-smiling"][0]
print(json.dumps(asdict(first), ensure_ascii=False))
# {"emoji": "😀", "name": "grinning face", "alias": ":grinning_face:", "variants": null}
```

## API Reference

### `emoji_index`

A pre-built singleton instance of `EmojiIndex`, ready to use out of the box.

```python
from emoji_index import emoji_index
```

### `EmojiIndex`

The main entry point for browsing emoji.

| Property / Method | Returns | Description |
|---|---|---|
| `groups` | `list[str]` | All top-level emoji group names |
| `version` | `_EmojiVersion` | The currently selected emoji version (e.g., `_EmojiVersion.E17_0`) |
| `set_version(version)` | `None` | Filter the index to a specific emoji version; raises `ValueError` for unknown versions |
| `[group_name]` | `EmojiGroup` | Access a group by name; raises `KeyError` for unknown groups |

#### Groups

The index contains 9 top-level groups following the Unicode standard (counts at the default version, Emoji 17.0):

| Group | Subgroups | Emojis |
|---|---|---|
| Smileys & Emotion | 16 | 171 |
| People & Body | 16 | 335 |
| Animals & Nature | 8 | 160 |
| Food & Drink | 7 | 131 |
| Travel & Places | 11 | 219 |
| Activities | 5 | 85 |
| Objects | 18 | 266 |
| Symbols | 14 | 224 |
| Flags | 3 | 270 |

#### Version Filtering

Filter the index to only include emojis available at a specific Unicode Emoji version. This is useful for ensuring compatibility across platforms that may not support the latest emoji.

```python
emoji_index.set_version("13.0")
print(emoji_index.version)  # _EmojiVersion.E13_0
```

Supported versions: `1.0`, `2.0`, `3.0`, `4.0`, `5.0`, `11.0`, `12.0`, `12.1`, `13.0`, `13.1`, `14.0`, `15.0`, `15.1`, `16.0`, `17.0`

The default version is `17.0`.

New in Emoji 16.0–17.0 versus 15.1: `ballet dancer`, `distorted face`, `face with bags under eyes`, `fight cloud`, `fingerprint`, `flag: Sark`, `hairy creature`, `harp`, `landslide`, `leafless tree`, `orca`, `root vegetable`, `shovel`, `splatter`, `treasure chest`, `trombone`.

### `EmojiGroup`

Represents a top-level emoji group (e.g., "Smileys & Emotion").

| Property / Method | Returns | Description |
|---|---|---|
| `subgroups` | `list[str]` | All subgroup names within this group |
| `[subgroup_name]` | `list[Emoji]` | Access emojis in a subgroup; raises `KeyError` for unknown subgroups |

```python
group = emoji_index["Smileys & Emotion"]
print(group.subgroups)
# ['face-smiling', 'face-affection', 'face-tongue', ...]

emojis = group["face-smiling"]
# [Emoji(emoji='😀', name='grinning face', ...), ...]
```

### `Emoji`

A dataclass representing a single emoji.

| Field | Type | Description |
|---|---|---|
| `emoji` | `str` | The emoji character |
| `name` | `str` | Human-readable name (e.g., `"grinning face"`) |
| `alias` | `str` | Demojized shortcode (e.g., `":grinning_face:"`) |
| `variants` | `list[str] \| None` | Skin tone variants, if applicable |

#### Skin Tone Variants

Emojis that support skin tone modifiers have their variants grouped under the parent emoji, rather than appearing as separate entries in the index:

```python
for emoji in emoji_index["People & Body"]["hand-fingers-open"]:
    print(f"{emoji.emoji} {emoji.name}")
    if emoji.variants:
        print(f"  variants: {' '.join(emoji.variants)}")
```

Output:

```
👋 waving hand
  variants: 👋🏻 👋🏼 👋🏽 👋🏾 👋🏿
🤚 raised back of hand
  variants: 🤚🏻 🤚🏼 🤚🏽 🤚🏾 🤚🏿
🖐️ hand with fingers splayed
  variants: 🖐🏻 🖐🏼 🖐🏽 🖐🏾 🖐🏿
...
```

## FAQ

**Why do the counts differ from unicode.org?**
Two intentional reductions keep the index picker-friendly: skin tone variants nest under their parent instead of counting separately, and multi-person groupings (e.g., `family`, `couple with heart`) are excluded — see Known Limitations.

**Where do aliases come from?**
From the [`emoji`](https://github.com/carpedm20/emoji/) library's `demojize`, which is why `emoji >= 2.15.0` is required for current shortcodes. If an alias is ever unknown to that library, one is synthesized from the Unicode name so the field is never empty.

**How do I follow new Unicode releases?**
Emoji data lives in `src/emoji_index/data/emoji_data.py` (a snapshot of `emoji-test.txt`) with versions enumerated in `src/emoji_index/objects/emoji.py`. See [CONTRIBUTING.md](CONTRIBUTING.md) for the update recipe.

## Known Limitations

- Multi-person grouping emojis are not supported, as these require special handling that is at the moment out of scope. See [Multi-Person Groupings](https://www.unicode.org/reports/tr51/#MultiPersonGroupingsTable).
- Hair component modifiers are not presently supported. See [Hair Components](https://www.unicode.org/reports/tr51/#hair_components).

## Contributing

Bug reports and pull requests are welcome — especially new-emoji data updates after each Unicode release. See [CONTRIBUTING.md](CONTRIBUTING.md) for the development setup and the data-update recipe, and check the [issue tracker](https://github.com/nquest-corp/emoji-index/issues) for open tasks.

## Changelog

See [CHANGELOG.md](CHANGELOG.md) for release history.

## Licensing

This project is released under the Apache 2.0 License. See the license file for the Apache 2.0 License.

The project also contains data from the Unicode Consortium, which is licensed under the Unicode License Agreement. See the LICENSE_UNICODE.txt file for details.
