Skip to content

Instantly share code, notes, and snippets.

@timw4mail
Last active January 31, 2020 15:24
Show Gist options
  • Save timw4mail/429190c3ab719dccf732c6cc061e383c to your computer and use it in GitHub Desktop.
Save timw4mail/429190c3ab719dccf732c6cc061e383c to your computer and use it in GitHub Desktop.
Emojis
<?php declare(strict_types=1);
function createDataObject (int $min, int $max, array $blacklist = []): array
{
$output = [];
$index = 0;
for ($i = $min; $i <= $max; $i++)
{
$n = base_convert((string)$i, 10, 16);
if ($i % 16 === 0 || $i === $min)
{
$index = substr($n, 0, -1) . 'x';
}
if (in_array($index, $blacklist))
{
continue;
}
if ( ! array_key_exists($index, $output))
{
$output[$index] = [];
}
$output[$index][] = html_entity_decode(ee($n), 0, 'UTF-8');
}
return $output;
}
function renderTable(array $data, string $caption=''): string
{
ob_start();
?>
<table>
<caption><?= $caption ?></caption>
<thead>
<tr>
<th>&nbsp;</th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
<th>e</th>
<th>f</th>
</tr>
</thead>
<tfoot>
<tr>
<th>&nbsp;</th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
<th>e</th>
<th>f</th>
</tr>
</tfoot>
<tbody>
<?php foreach($data as $label => $values): ?>
<tr>
<td><?= $label ?></td>
<?php foreach($values as $value): ?>
<td>
<a class="emoji" target="_blank" href="https://emojipedia.org/emoji/<?= $value ?>/">
<?= $value ?>
</a>
</td>
<?php endforeach ?>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php
$content = ob_get_contents();
ob_clean();
$content = preg_replace("/\t+/", "\t", $content);
return $content;
}
function ee(string $codePoint): string
{
return "&#x{$codePoint};";
}
function random_skin_tone()
{
$modifiers = ['1f3fb', '1f3fc', '1f3fd', '1f3fe', '1f3ff'];
$key = array_rand($modifiers);
$colorModifier = $modifiers[$key];
return ee($colorModifier);
}
function has_skin_variant(string $codePoint): bool
{
$blacklist = ['1f9de', '1f9df'];
return ! in_array($codePoint, $blacklist);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Unicode Emoji</title>
<link rel="stylesheet" href="/emojis/css/marx.css" />
<link rel="stylesheet" href="/emojis/css/emojis.css" />
</head>
<body>
<header>
<h1>Emoji Examples</h1>
<p><a href="/emojis/">Full emoji tables</a></p>
</header>
<main>
<?php
require_once 'emoji-functions.php';
$genderCombinations = [
/*'Adult' => '1f9d1',
'Child' => '1f9d2',
'Older Person' => '1f9d3',
'Baby' => '1f476',*/
'Person Running' => '1f3c3',
'Police Officer' => '1f46e',
'People with Bunny Ears' => '1f46f',
'Construction Worker' => '1f477',
'Person Tipping Hand' => '1f481',
'Guard' => '1f482',
'Person Getting Message' => '1f486',
'Person Getting Haircut' => '1f487',
'Detective' => '1f575',
'Person Gesturing No' => '1f645',
'Person Bowing' => '1f647',
'Person Raising Hand' => '1f64b',
'Person Frowning' => '1f64d',
'Person Pouting' => '1f64e',
'Person Facepalming' => '1f926',
'Person Shrugging' => '1f937',
'Superhero' => '1f9b8',
'Supervillain' => '1f9b9',
'Person Standing' => '1f9cd',
'Person in Sauna' => '1f9d6',
'Mage' => '1f9d9',
'Fairy' => '1f9da',
'Vampire' => '1f9db',
'Merperson' => '1f9dc',
'Elf' => '1f9dd',
'Genie' => '1f9de',
'Zombie' => '1f9df',
];
$colorModifier = random_skin_tone();
?>
<table>
<caption>Gender combinations (with <?= $colorModifier ?> skin tone)</caption>
<thead>
<tr>
<th>Description</th>
<th>Formula</th>
<th>Live Example (Neutral / Male / Female)</th>
<th>Code Sequences</th>
</tr>
</thead>
<tbody>
<?php foreach($genderCombinations as $name => $code): ?>
<tr>
<td><?= $name ?></td>
<td>
<span class="emoji-small"><?= ee($code) ?></span> /
<span class="emoji-small"><?= ee($code) ?>|&#x2642;</span> /
<span class="emoji-small"><?= ee($code) ?>|&#x2640;</span>
</td>
<?php if (has_skin_variant($code)): ?>
<td class="flex">
<span class="emoji-large"><?= ee($code) ?><?= $colorModifier ?>&#xfe0f;</span> /
<span class="emoji-large"><?= ee($code) ?><?= $colorModifier ?>&zwj;&#x2642;&#xfe0f;</span> /
<span class="emoji-large"><?= ee($code) ?><?= $colorModifier ?>&zwj;&#x2640;&#xfe0f;</span>
</td>
<?php else: ?>
<td class="flex">
<span class="emoji-large"><?= ee($code) ?></span> /
<span class="emoji-large"><?= ee($code) ?>&zwj;&#x2642;</span> /
<span class="emoji-large"><?= ee($code) ?>&zwj;&#x2640;</span>
</td>
<?php endif ?>
<td>
U+<?= $code ?> /
U+<?= $code ?>, U+200d, U+2642 /
U+<?= $code ?>, U+200d, U+2640
</td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<hr />
<table>
<caption>Combined Glyphs</caption>
<thead>
<tr>
<th>Description</th>
<th>Formula (| = Zero-width-joiner, U+200d)</th>
<th>Live example</th>
<th>Code Sequences</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lightly colored pregnant woman</td>
<td class="emoji-small">&#x1f930;&zwj;&#x1f3fc;</td>
<td class="emoji-large">&#x1f930;&#x1f3fc;</td>
<td>U+1f930, U+1f3fc</td>
</tr>
<tr>
<td>Couple</td>
<td class="emoji-small">&#x1f468;|&#x1f469;</td>
<td class="emoji-large">&#x1f468;&zwj;&#x1f469;</td>
<td>U+1f468, U+1f469</td>
</tr>
<tr>
<td>Family, with mother,father,son, and daughter</td>
<td class="emoji-small">&#x1f468;&zwj;|&zwj;&#x1f469;&zwj;|&zwj;&#x1f467;&zwj;|&zwj;&#x1f466;</td>
<td class="emoji-large">&#x1f468;&zwj;&#x1f469;&zwj;&#x1f467;&zwj;&#x1f466;</td>
<td>U+1f468, U+200d, U+1f469, U+200d, U+1f467, U+200d, U+1f466</td>
</tr>
<tr>
<td>Family, with wide skin color diversity</td>
<td class="emoji-small">&#x1f468;&zwj;&#x1f3fb;&zwj;|&zwj;&#x1f469;&zwj;&#x1f3ff;&zwj;|&zwj;&#x1f467;&zwj;&#x1f3fe;&zwj;|&zwj;&#x1f466;&zwj;&#x1f3fc;</td>
<td class="emoji-large">&#x1f468;&#x1f3fb;&zwj;&#x1f469;&#x1f3ff;&zwj;&#x1f467;&#x1f3fe;&zwj;&#x1f466;&#x1f3fc;</td>
<td>U+1F468, U+1f3fb, U+1f469, U+1f3ff, U+1f467, U+1f3fe, U+1f466, U+1f3fc</td>
</tr>
</tbody>
</table>
<table>
<caption>Skin-tone modifiers</caption>
<thead>
<tr>
<th>Code Point</th>
<th>Modifier</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>None</td>
<td>&nbsp;</td>
<td class="emoji-large">&#x1f931;</td>
</tr>
<tr>
<td>1 (U+1f3fb)</td>
<td class="emoji-large">&#x1f3fb;</td>
<td class="emoji-large">&#x1f931;&#x1f3fb;</td>
</tr>
<tr>
<td>2 (U+1f3fc)</td>
<td class="emoji-large">&#x1f3fc;</td>
<td class="emoji-large">&#x1f931;&#x1f3fc;</td>
</tr>
<tr>
<td>3 (U+1f3fd)</td>
<td class="emoji-large">&#x1f3fd;</td>
<td class="emoji-large">&#x1f931;&#x1f3fd;</td>
</tr>
<tr>
<td>4 (U+1f3fe)</td>
<td class="emoji-large">&#x1f3fe;</td>
<td class="emoji-large">&#x1f931;&#x1f3fe;</td>
</tr>
<tr>
<td>5 (U+1f3ff)</td>
<td class="emoji-large">&#x1f3ff;</td>
<td class="emoji-large">&#x1f931;&#x1f3ff;</td>
</tr>
</tbody>
</table>
<hr />
<table>
<caption>Male / Female Pairs</caption>
<thead>
<tr>
<th>Code Sequences</th>
<th>Live Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>U+1f385, U+1f936</td>
<td class="emoji-large">&#x1f385;&#x1f3fb;&#x1f936;&#x1f3fb;</td>
</tr>
<tr>
<td>U+1f478, U+1f934</td>
<td class="emoji-large">&#x1f478;&#x1f934;</td>
</tr>
<tr>
<td>U+1f470, U+1f935</td>
<td class="emoji-large">&#x1f470;&#x1f935;</td>
</tr>
<tr>
<td>U+1f6b9, U+1f6ba</td>
<td class="emoji-large">&#x1f6b9;&#x1f6ba;</td>
</tr>
<tr>
<td>U+1f483, U+1f57a</td>
<td class="emoji-large">&#x1f483;&#x1f3fd;&#x1f57a;&#x1f3fd;</td>
</tr>
</tbody>
</table>
<hr />
<table>
<caption>Platform-specific combinations</caption>
<tr>
<td>Windows Cat emojis</td>
<td class="emoji-large">
&#x1f431;&zwj;&#x1f464;
</td>
<td class="emoji-large">
&#x1f431;&zwj;&#x1f3cd;
</td>
<td class="emoji-large">
&#x1f431;&zwj;&#x1f4bb;
</td>
<td class="emoji-large">
&#x1f431;&zwj;&#x1f409;
</td>
<td class="emoji-large">
&#x1f431;&zwj;&#x1f453;
</td>
<td class="emoji-large">
&#x1f431;&zwj;&#x1f680;
</td>
</tr>
</table>
</main>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>PHP Emoji Rendering</title>
<link rel="stylesheet" href="./css/marx.css" />
<link rel="stylesheet" href="./css/emojis.css" />
</head>
<body>
<header>
<h1>Emoji Listing</h1>
<p><a href="./examples.php">Some emoji combination examples.</a></p>
</header>
<main>
<?php
require_once 'emoji-functions.php';
echo renderTable(createDataObject(0x1f300, 0x1facf, [
'1f65x', '1f66x', '1f67x',
'1f70x', '1f71x', '1f72x', '1f73x', '1f74x', '1f75x', '1f76x', '1f77x', '1f78x', '1f79x',
'1f7ax', '1f7bx', '1f7cx', '1f7dx', '1f7fx',
'1f80x', '1f81x', '1f82x', '1f83x', '1f84x', '1f85x', '1f86x', '1f87x', '1f88x', '1f89x',
'1f8ax', '1f8bx', '1f8cx', '1f8dx', '1f8ex', '1f8fx',
'1fa0x', '1fa1x', '1fa2x', '1fa3x', '1fa4x', '1fa5x', '1fa6x',
]), 'Main Emoji Characters');
echo renderTable(array_merge_recursive(
createDataObject(0x00a0, 0x00af),
createDataObject(0x2030, 0x204f),
createDataObject(0x2120, 0x213f),
createDataObject(0x2190, 0x21af),
createDataObject(0x2310, 0x232f),
createDataObject(0x23c0, 0x23ff),
createDataObject(0x24c0, 0x24cf),
createDataObject(0x25a0, 0x25cf),
createDataObject(0x25f0, 0x27bf),
createDataObject(0x2930, 0x293f),
createDataObject(0x2b00, 0x2b1f),
createDataObject(0x2b50, 0x2b5f),
createDataObject(0x3030, 0x303f),
createDataObject(0x3290, 0x329f),
createDataObject(0x1f000, 0x1f0df)
), 'Other Emoji / Symbol Characters');
?>
</main>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>JS Emoji Rendering</title>
<link rel="stylesheet" href="./css/marx.css" />
<link rel="stylesheet" href="./css/emojis.css" />
</head>
<body>
<header>
<h1>Emoji Listing</h1>
<p><a href="./examples.php">Some emoji combination examples.</a></p>
</header>
<main></main>
<script type="module" src="./js/buildTable.js"></script>
</body>
</html>
const createDataObject = (min, max, blacklist) => {
blacklist = blacklist || [];
let ind = 0;
const output = {};
let i = min;
for (; i < (max + 1); i++) {
if (i % 16 === 0 || i === min) {
ind = i.toString(16).slice(0,-1) + 'x';
}
if (blacklist.includes(ind) || blacklist.includes(i.toString(16))) {
continue;
}
if (typeof output[ind] === 'undefined') {
output[ind] = [];
}
output[ind].push(String.fromCodePoint(i));
}
return output;
}
const createDomTable = (data, caption) => {
const codeTable = document.createElement('table');
const captionTag = codeTable.createCaption();
const thead = codeTable.createTHead();
const tbody = document.createElement('tbody');
const thRow = thead.insertRow(-1);
codeTable.appendChild(tbody);
captionTag.appendChild(document.createTextNode(caption));
// Create headers
String(' 0123456789abcdef').split('').forEach((char) => {
const cell = document.createElement('th');
cell.appendChild(document.createTextNode(char));
thRow.appendChild(cell);
});
for (const ind in data) {
const tr = tbody.insertRow(-1);
const row = data[ind];
const firstTd = tr.insertCell(-1);
firstTd.appendChild(document.createTextNode(ind));
row.forEach((char) => {
const td = tr.insertCell(-1);
td.className = 'emoji';
td.appendChild(document.createTextNode(char));
});
}
return codeTable;
}
const flatten = (...args) => {
const output = {};
args.forEach((obj) => {
for (const x in obj) {
output[x] = obj[x];
}
});
return output;
}
const fragment = document.createDocumentFragment();
const data = flatten(
createDataObject(0x1f300, 0x1f9ff, [
'1f1ax', '1f1bx', '1f1cx', '1f1dx', '1f1ex',
'1f26x', '1f27x', '1f28x', '1f29x', '1f2ax', '1f2bx', '1f2cx', '1f2dx', '1f2ex', '1f2fx',
'1f7ex', '1f7fx',
'1f8bx', '1f8cx', '1f8dx', '1f8ex', '1f8fx', '1f90x',
//'1f97x',
//'1f9ax',
])
);
fragment.appendChild(createDomTable(data, 'Main Emoji Characters'));
const basicFragment = document.createDocumentFragment();
const basicData = flatten(
createDataObject(0x00a0, 0x00af),
createDataObject(0x2030, 0x204f),
createDataObject(0x2120, 0x213f),
createDataObject(0x2190, 0x21af),
createDataObject(0x2310, 0x232f),
createDataObject(0x23c0, 0x23ff),
createDataObject(0x24c0, 0x24cf),
createDataObject(0x25a0, 0x25cf),
createDataObject(0x25f0, 0x27bf),
createDataObject(0x2930, 0x293f),
createDataObject(0x2b00, 0x2b1f),
createDataObject(0x2b50, 0x2b5f),
createDataObject(0x3030, 0x303f),
createDataObject(0x3290, 0x329f),
createDataObject(0x1f000, 0x1f0df)
);
basicFragment.appendChild(createDomTable(basicData, 'Other Emoji / Symbol Characters'));
const mainTag = document.getElementsByTagName('main')[0];
mainTag.appendChild(fragment);
mainTag.appendChild(basicFragment);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment