Skip to content

Commit

Permalink
feat: metadata compatibility with google, docs
Browse files Browse the repository at this point in the history
  • Loading branch information
wait-what committed Jul 19, 2023
1 parent 5ec1689 commit 965259b
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 53 deletions.
13 changes: 7 additions & 6 deletions docs/input-manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ The `name` of the variable must start with `$`.

`$` variables will only get resolved in:
- `colormap` entry keys and values
- `colormap.codepoint` (**not** expanded)
- `colormap.codepoint` (expanded)
- `emoji.codepoint` (expanded)
- `emoji.colormaps` (expanded)

Expand Down Expand Up @@ -164,13 +164,14 @@ description = "The flag of Lithuania"
- `description` - used for metadata
- `category` - used for metadata and structure
> The first `category` will be used as the group in the metadata
- `codepoint`: single codepoint split into parts, each starting with `U+`
- `codepoint` (optional) - single codepoint split into parts, each starting with `U+`
> If `structure.filenames` is `codepoint`, this will be used as the filename, with `U+` stripped and joined with `_`
- `shortcodes`: list of shortcodes.
- `root_codepoint` (optional) - codepoint used to generate alternates in the output metadata
- `shortcodes` - list of shortcodes.
> The first one will be used as the filename if `structure.filenames` is `shortcode`
- `tags`: used to select which targets this emoji will be built for
- `src`: path to the svg file, **relative to the manifest file**
- `colormaps` create multiple emoji entries, one for each colormap.
- `tags` - used to select which targets this emoji will be built for
- `src` - path to the svg file, **relative to the manifest file**
- `colormaps` (optional) - create multiple emoji entries, one for each colormap
> `%label`, `%shortcode`, `%codepoint`, `%description` will be replaced, and the svg will be recolored with the colormap's entries.
> If emojis have overlapping tags, they can't have overlapping names and labels
Expand Down
52 changes: 33 additions & 19 deletions docs/output-metadata.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Output metadata
The output metadata consists of a JSON file with the structure shown below. It is loosely based on [Google emoji metadata](https://github.com/googlefonts/emoji-metadata).
The output metadata consists of a JSON file with the structure shown below.

It is designed to be compatible with [Google emoji metadata](https://github.com/googlefonts/emoji-metadata).

```json
[
Expand All @@ -14,34 +16,46 @@ The output metadata consists of a JSON file with the structure shown below. It i

## Emoji object
### Required fields
- `src` is the path to the emoji image
- `description` is a string

### Optional fields
- `shortcodes` can be an array of strings, or an empty array
- `codepoint` and `root_codepoint` can be an array of numbers, or an empty array
- `category` can be an array of strings, or an empty array
Name | Type | Notes
--- | --- | ---
`src` | `string` | relative path to the emoji image
`shortcodes` | `string[]` | _can be empty_
`base` | `number[] \| null` | codepoint of this emoji, if it has one
`alternates` | `number[][]` | codepoints of emojis that are variations of this emoji
`category` | `string[]` | the category of this emoji
`description` | `string` |
`emoticons` | `string[]` | **Always** empty array
`animated` | `boolean` | **Always** false

```json
{
"codepoint": [
9996,
8205,
128994
],
"root_codepoint": [
"src": "expressions/skintones/human/victory_hand",
"base": [
9996
],
"src": "expressions/skintones/human/victory_hand_g",
"alternates": [
[
9996,
8205,
128997
],
[
9996,
8205,
128994
]
],
"shortcodes": [
":victory_hand_g:",
":v_g:"
":victory_hand:",
":v:"
],
"category": [
"expressions",
"skintones",
"human"
],
"description": "something"
},
"description": "something",
"emoticons": [],
"animated": false
}
```
82 changes: 54 additions & 28 deletions src/process/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,62 @@ struct Group {

#[derive(Serialize)]
struct Emoji {
codepoint: Option<Vec<u64>>,
root_codepoint: Option<Vec<u64>>,
src: Option<String>,
base: Option<Vec<u64>>,
alternates: Vec<Vec<u64>>,
shortcodes: Vec<String>,
category: Vec<String>,
description: String,
emoticons: Vec<String>,
animated: bool,
}

fn parse_codepoint(codepoint: &Vec<String>) -> Vec<u64> {
codepoint
.iter()
.map(|codepoint| {
let codepoint = codepoint.replace("U+", "");
u64::from_str_radix(&codepoint, 16).unwrap()
})
.collect()
}

pub fn generate_metadata(emojis: &Vec<EmojiEncoded>) -> String {
let mut groups: HashMap<String, Vec<Emoji>> = HashMap::new();
let mut alternate_map: HashMap<Vec<u64>, Vec<Vec<u64>>> = HashMap::new();
for emoji in emojis {
let root_codepoint = match &emoji.emoji.root_codepoint {
Some(codepoint) => parse_codepoint(codepoint),
None => continue,
};

let codepoint = match &emoji.emoji.codepoint {
Some(codepoint) => parse_codepoint(codepoint),
None => continue,
};

if codepoint == root_codepoint {
continue;
}

if !alternate_map.contains_key(&root_codepoint) {
alternate_map.insert(root_codepoint.to_owned(), Vec::new());
}

let alternates = alternate_map.get_mut(&root_codepoint).unwrap();
if !alternates.contains(&codepoint) {
alternates.push(codepoint);
}
}

let mut groups: HashMap<String, Vec<Emoji>> = HashMap::new();
for emoji in emojis {
let group = emoji.emoji.category[0].clone();
if !groups.contains_key(&group) {
groups.insert(group.clone(), Vec::new());
}

let codepoint: Option<Vec<u64>> = match emoji.emoji.codepoint.as_ref() {
Some(codepoint) => Some(
codepoint
.iter()
.map(|codepoint| {
let codepoint = codepoint.replace("U+", "");
u64::from_str_radix(&codepoint, 16).unwrap()
})
.collect(),
),
None => None,
};

let root_codepoint: Option<Vec<u64>> = match emoji.emoji.root_codepoint.as_ref() {
Some(codepoint) => Some(
codepoint
.iter()
.map(|codepoint| {
let codepoint = codepoint.replace("U+", "");
u64::from_str_radix(&codepoint, 16).unwrap()
})
.collect(),
),
let codepoint: Option<Vec<u64>> = match &emoji.emoji.codepoint {
Some(codepoint) => Some(parse_codepoint(codepoint)),
None => None,
};

Expand All @@ -61,13 +77,23 @@ pub fn generate_metadata(emojis: &Vec<EmojiEncoded>) -> String {
.map(|s| format!(":{}:", s))
.collect();

let alternates = match &codepoint {
Some(codepoint) => match alternate_map.get(codepoint) {
Some(alternates) => alternates.to_owned(),
None => Vec::with_capacity(0),
},
None => Vec::with_capacity(0),
};

let emoji = Emoji {
codepoint,
root_codepoint: root_codepoint,
src: emoji.filename.clone(),
base: codepoint,
alternates,
category: emoji.emoji.category.clone(),
shortcodes,
description: emoji.emoji.description.clone(),
emoticons: Vec::with_capacity(0),
animated: false,
};

groups.get_mut(&group).unwrap().push(emoji);
Expand Down

0 comments on commit 965259b

Please sign in to comment.