diff --git a/.gitignore b/.gitignore index 3c135f4..a91b961 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,4 @@ dist # Finder (MacOS) folder config .DS_Store emoji +css diff --git a/index.ts b/index.ts index b1f6c26..c2f01c7 100644 --- a/index.ts +++ b/index.ts @@ -3,6 +3,8 @@ import * as path from 'path' const emojiDir = './emoji' if(!await exists(emojiDir)) await mkdir(emojiDir) +const cssDir = './css' +if(!await exists(cssDir)) await mkdir(cssDir) const fluentDir = './sources/fluentui-emoji/assets' const fluentList = await readdir(fluentDir) @@ -14,13 +16,20 @@ for(let c in animatedCatList) { const catDir = `${animatedDir}/${category}` const catFiles = await readdir(catDir) catFiles.forEach((filename) => { - animatedList.set(path.parse(filename).name, `${catDir}/${filename}`) + let key = path.parse(filename).name.toLowerCase()//.replace(/[\(\)'’“”]/g, '') + animatedList.set(key, `${catDir}/${filename}`) }) } +const rootURL = process.env.ROOT_URL || "https://flumoji.pages.dev/emoji/" +const cssRules = { + animated: [] as string[], + threeD: [] as string[], + color: [] as string[], + flat: [] as string[], + highContrast: [] as string[] +} -const mapping = [] - -await fluentList.forEach(async (folder) => { +await Promise.all(fluentList.map(async (folder) => { let thisEmojiIn = `${fluentDir}/${folder}` const metadataFile = Bun.file(`${thisEmojiIn}/metadata.json`) const metadata = await metadataFile.json() @@ -35,19 +44,66 @@ await fluentList.forEach(async (folder) => { const inHighContrast = `${thisEmojiIn}/High Contrast` // we have to search for the appropriate animated folder - let title = folder - if(metadata.unicodeSkintones) title += ' Light Skin Tone' + let title = metadata.tts.toLowerCase().replace(/[:]/g, '') + // if(metadata.unicodeSkintones) title += ' Light Skin Tone' - let imgAnim = Bun.file(animatedList.get(title) || `${in3d}/${(await readdir(in3d))[0]}`) + let imgAnimPath = animatedList.get(title) + const img3DPath = `${in3d}/${(await readdir(in3d))[0]}` + const imgColorPath = `${inColor}/${(await readdir(inColor))[0]}` + const imgFlatPath = `${inFlat}/${(await readdir(inFlat))[0]}` + const imgHighContrastPath = `${inHighContrast}/${(await readdir(inHighContrast))[0]}` - const img3d = Bun.file(`${in3d}/${(await readdir(in3d))[0]}`) - const imgColor = Bun.file(`${inColor}/${(await readdir(inColor))[0]}`) - const imgFlat = Bun.file(`${inFlat}/${(await readdir(inFlat))[0]}`) - const imgHighContrast = Bun.file(`${inHighContrast}/${(await readdir(inHighContrast))[0]}`) + if(!imgAnimPath){ + // hard-coded matches: + switch(title){ + case 'keycap 0': imgAnimPath = animatedList.get("keycap digit zero"); break; + case 'keycap 1': imgAnimPath = animatedList.get("keycap digit one"); break; + case 'keycap 2': imgAnimPath = animatedList.get("keycap digit two"); break; + case 'keycap 3': imgAnimPath = animatedList.get("keycap digit three"); break; + case 'keycap 4': imgAnimPath = animatedList.get("keycap digit four"); break; + case 'keycap 5': imgAnimPath = animatedList.get("keycap digit five"); break; + case 'keycap 6': imgAnimPath = animatedList.get("keycap digit six"); break; + case 'keycap 7': imgAnimPath = animatedList.get("keycap digit seven"); break; + case 'keycap 8': imgAnimPath = animatedList.get("keycap digit eight"); break; + case 'keycap 9': imgAnimPath = animatedList.get("keycap digit nine"); break; + case 'keycap #': imgAnimPath = animatedList.get("keycap number sign"); break; + case 'keycap *': imgAnimPath = animatedList.get("keycap asterisk"); break; + case 'pouting face': imgAnimPath = animatedList.get("enraged face"); break; + default: console.warn(`could not find animated ${metadata.glyph} ${title}. Defaulting to 3D version: ${img3DPath}`) + } + + } + + const imgAnim = Bun.file(imgAnimPath || img3DPath) + const img3d = Bun.file(img3DPath) + const imgColor = Bun.file(imgColorPath) + const imgFlat = Bun.file(imgFlatPath) + const imgHighContrast = Bun.file(imgHighContrastPath) if(!await exists(`${thisEmojiOut}/animated.png`)) await Bun.write(`${thisEmojiOut}/animated.png`, imgAnim) if(!await exists(`${thisEmojiOut}/3d.png`)) await Bun.write(`${thisEmojiOut}/3d.png`, img3d) if(!await exists(`${thisEmojiOut}/color.svg`)) await Bun.write(`${thisEmojiOut}/color.svg`, imgColor) if(!await exists(`${thisEmojiOut}/flat.svg`)) await Bun.write(`${thisEmojiOut}/flat.svg`, imgFlat) if(!await exists(`${thisEmojiOut}/high-contrast.svg`)) await Bun.write(`${thisEmojiOut}/high-contrast.svg`, imgHighContrast) -}) \ No newline at end of file + + const cssRule = `[alt|="${metadata.glyph}"]{ content: url(${rootURL}${metadata.glyph}/{file}); }` + + + cssRules.animated.push(cssRule.replace("{file}", "animated.png")) + cssRules.threeD.push(cssRule.replace("{file}", "3d.png")) + cssRules.color.push(cssRule.replace("{file}", "color.svg")) + cssRules.flat.push(cssRule.replace("{file}", "flat.svg")) + cssRules.highContrast.push(cssRule.replace("{file}", "high-contrast.svg")) +})) + +const cssAnim = Bun.file(path.join(cssDir, 'animated.css')) +const css3d = Bun.file(path.join(cssDir, '3d.css')) +const cssColor = Bun.file(path.join(cssDir, 'color.css')) +const cssFlat = Bun.file(path.join(cssDir, 'flat.css')) +const cssHighContrast = Bun.file(path.join(cssDir, 'high-contrast.css')) + +await Bun.write(cssAnim, cssRules.animated.join('\n')) +await Bun.write(css3d, cssRules.threeD.join('\n')) +await Bun.write(cssColor, cssRules.color.join('\n')) +await Bun.write(cssFlat, cssRules.flat.join('\n')) +await Bun.write(cssHighContrast, cssRules.highContrast.join('\n')) \ No newline at end of file