Builds obj from unicode emoji-test text
0
parse_unicode_emoji_list.ts
1/**
2 * Builds obj from unicode emoji-test text
3 * @reference https://unicode.org/Public/emoji/14.0/emoji-test.txt
4 * @reference http://www.unicode.org/reports/tr51/
5 *
6 * @example deno run --allow-net fetch-emoji.ts
7 */
8
9type Qualification = "fully-qualified" | "minimally-qualified" | "unqualified";
10
11interface EmojiObj {
12 emoji: string;
13 version: number;
14 name: string;
15 qualification: Qualification;
16 codepoints: string[];
17 ln?: string;
18}
19
20interface Results {
21 [groupName: string]: {
22 [subgroupName: string]: EmojiObj[];
23 };
24}
25
26const version = "14.0";
27const response = await fetch(
28 `https://unicode.org/Public/emoji/${version}/emoji-test.txt`,
29);
30const text = await response.text();
31
32const groups = text.split("# group: ");
33groups.shift();
34
35const results: Results = {};
36
37groups.forEach((group) => {
38 const [rawGroupName, ...subgroups] = group.split("# subgroup: ");
39 const groupName = rawGroupName.replace("\n\n", "");
40
41 results[groupName] = {};
42
43 subgroups.map((subgroup) => {
44 const [subgroupName, ...emojis] = subgroup.split("\n");
45
46 const emojiObjs = emojis
47 .map((ln): EmojiObj => {
48 const [_, codepoints, qualification, emoji, version, name] = ln.match(
49 /^(.*);(.*)#(.*)E(\S*)\s(.*)/,
50 ) || [];
51 return {
52 emoji: (emoji || "").trim(),
53 version: Number(version),
54 name: name,
55 qualification: (qualification || "").trim() as Qualification,
56 codepoints: (codepoints || "").trim().split(/\s+/),
57 // ln: ln,
58 };
59 })
60 .filter((emojiObj) =>
61 emojiObj.emoji && emojiObj.qualification === "fully-qualified"
62 );
63
64 results[groupName][subgroupName] = emojiObjs;
65 });
66});
67
68console.log(results);