mirror of
https://github.com/ikatyang/emoji-cheat-sheet.git
synced 2024-12-05 06:24:38 +08:00
refactor: rewrite with typescript
This commit is contained in:
parent
277d9e143e
commit
e33fa33e1e
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "emoji-cheat-sheet-generator",
|
||||
"name": "emoji-cheat-sheet",
|
||||
"version": "0.0.0-dev",
|
||||
"private": true,
|
||||
"author": "ikatyang",
|
||||
@ -7,6 +7,7 @@
|
||||
"homepage": "https://github.com/ikatyang/emoji-cheat-sheet",
|
||||
"repository": "https://github.com/ikatyang/emoji-cheat-sheet/tree/generator",
|
||||
"scripts": {
|
||||
"lint": "tslint -p ./tsconfig.json",
|
||||
"generate": "node ./scripts/generate.js"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -16,6 +17,7 @@
|
||||
"devDependencies": {
|
||||
"@types/cheerio": "0.22.2",
|
||||
"@types/jest": "20.0.2",
|
||||
"@types/node": "8.0.13",
|
||||
"@types/request": "0.0.47",
|
||||
"jest": "20.0.4",
|
||||
"jest-playback": "1.0.0",
|
||||
|
157
src/create-cheat-sheet.ts
Normal file
157
src/create-cheat-sheet.ts
Normal file
@ -0,0 +1,157 @@
|
||||
import $ = require('cheerio');
|
||||
import request = require('request');
|
||||
|
||||
// tslint:disable-next-line:no-var-requires
|
||||
const package_json = require('../package.json');
|
||||
|
||||
const repo_name = package_json.name;
|
||||
const repo_author = package_json.author;
|
||||
|
||||
const uncategorized = 'Uncategorized';
|
||||
|
||||
const api_url = 'https://api.github.com/emojis';
|
||||
const sheet_url = 'http://www.emoji-cheat-sheet.com';
|
||||
|
||||
const travis_repo_url = `https://travis-ci.org/${repo_author}/${repo_name}`;
|
||||
const travis_badge_url = `https://travis-ci.org/${repo_author}/${repo_name}.svg?branch=master`;
|
||||
|
||||
const url_descriptions = [
|
||||
['GitHub Emoji API', api_url],
|
||||
['Emoji Cheat Sheet', sheet_url],
|
||||
].map(([site_name, site_url]) => `[${site_name}](${site_url})`).join(' and ');
|
||||
|
||||
// tslint:disable-next-line:max-line-length
|
||||
const description = `This cheat sheet is automatically generated from ${url_descriptions}`;
|
||||
|
||||
const toc_name = 'Table of Contents';
|
||||
|
||||
const top_name = 'top';
|
||||
const top_href = '#table-of-contents';
|
||||
|
||||
const column_divisions = 2;
|
||||
|
||||
type Url = string;
|
||||
|
||||
export interface Urls {
|
||||
[site_name: string]: Url;
|
||||
}
|
||||
|
||||
export interface EmojiTable {
|
||||
[category: string]: string[];
|
||||
}
|
||||
|
||||
export async function create_cheat_sheet() {
|
||||
const api_html = await get_html(api_url);
|
||||
const sheet_html = await get_html(sheet_url);
|
||||
|
||||
const api_emojis = Object.keys(JSON.parse(api_html));
|
||||
const emoji_table: EmojiTable = {};
|
||||
|
||||
const $html = $.load(sheet_html).root();
|
||||
$html.find('h2').each((_outer_index, category_element) => {
|
||||
const emojis: string[] = [];
|
||||
const category = $(category_element).text();
|
||||
$html.find(`#emoji-${category.toLowerCase()} li .name`).each((_inner_index, emoji_element) => {
|
||||
const emoji = $(emoji_element).text();
|
||||
const index = api_emojis.indexOf(emoji);
|
||||
if (index !== -1) {
|
||||
api_emojis.splice(index, 1);
|
||||
emojis.push(emoji);
|
||||
}
|
||||
});
|
||||
emoji_table[category] = emojis;
|
||||
});
|
||||
|
||||
if (api_emojis.length > 0) {
|
||||
emoji_table[uncategorized] = api_emojis;
|
||||
}
|
||||
|
||||
return create_table(emoji_table);
|
||||
}
|
||||
|
||||
function create_table(emoji_table: EmojiTable) {
|
||||
const categories = Object.keys(emoji_table);
|
||||
return format(`
|
||||
|
||||
# ${repo_name}
|
||||
|
||||
[![build](${travis_badge_url})](${travis_repo_url})
|
||||
|
||||
${description}
|
||||
|
||||
## ${toc_name}
|
||||
|
||||
${categories.map(category => `- [${category}](#${category.toLowerCase()})`).join('\n')}
|
||||
|
||||
${
|
||||
categories.map(category => {
|
||||
const emojis = emoji_table[category];
|
||||
return format(`
|
||||
|
||||
### ${category}
|
||||
|
||||
${create_table_head()}
|
||||
${create_table_content(emojis)}
|
||||
|
||||
`);
|
||||
}).join(('\n').repeat(2))
|
||||
}
|
||||
|
||||
`);
|
||||
}
|
||||
|
||||
function create_table_content(emojis: string[]) {
|
||||
let table_content = '';
|
||||
for (let i = 0; i < emojis.length; i += column_divisions) {
|
||||
const row_emojis = emojis.slice(i, i + column_divisions);
|
||||
while (row_emojis.length < column_divisions) {
|
||||
row_emojis.push('');
|
||||
}
|
||||
table_content += `${format(`
|
||||
|
||||
| [${top_name}](${top_href}) |${
|
||||
row_emojis.map(
|
||||
emoji => emoji.length !== 0
|
||||
? ` :${emoji}: | \`:${emoji}:\` `
|
||||
: ' | ',
|
||||
).join(' | ')
|
||||
}|
|
||||
|
||||
`)}\n`;
|
||||
}
|
||||
return table_content;
|
||||
}
|
||||
|
||||
function create_table_head() {
|
||||
return format(`
|
||||
|
||||
| |${(' ico | emoji |').repeat(column_divisions)}
|
||||
| - |${(' --- | ----- |').repeat(column_divisions)}
|
||||
|
||||
`);
|
||||
}
|
||||
|
||||
function format(str: string) {
|
||||
return str.trim().replace(/^ +/mg, '');
|
||||
}
|
||||
|
||||
async function get_html(url: string) {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const options = {url};
|
||||
if (url === api_url) {
|
||||
Object.assign(options, {
|
||||
headers: {'User-Agent': 'https://github.com/ikatyang/emoji-cheat-sheet'},
|
||||
});
|
||||
}
|
||||
request.get(options, (error, response, html) => {
|
||||
if (error || response.statusCode !== 200) {
|
||||
const error_message = Boolean(error)
|
||||
? error
|
||||
: `Unexpected response status code: ${response.statusCode}`;
|
||||
reject(error_message);
|
||||
} else {
|
||||
resolve(html);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
#!/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const $ = require('cheerio');
|
||||
const request = require('request');
|
||||
const markdown = require('./markdown');
|
||||
|
||||
const title = 'emoji-cheat-sheet';
|
||||
const apiUrl = 'https://api.github.com/emojis';
|
||||
const sheetUrl = 'http://www.emoji-cheat-sheet.com';
|
||||
|
||||
const outDir = path.resolve(process.cwd(), './generated');
|
||||
const outFile = path.join(outDir, 'README.md');
|
||||
|
||||
const columnDivisions = 2;
|
||||
|
||||
const getHTML = (url) => new Promise((resolve, reject) => {
|
||||
const options = { url };
|
||||
if (url === apiUrl) {
|
||||
Object.assign(options, {
|
||||
headers: { 'User-Agent': 'https://github.com/ikatyang/emoji-cheat-sheet' },
|
||||
});
|
||||
}
|
||||
request.get(options, (error, response, html) => {
|
||||
if (error || response.statusCode !== 200) {
|
||||
reject(error || `Unexpected response status code: ${response.statusCode}`);
|
||||
} else {
|
||||
resolve(html);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all([getHTML(apiUrl), getHTML(sheetUrl)]).then(([apiHTML, sheetHTML]) => {
|
||||
const apiEmojis = Object.keys(JSON.parse(apiHTML));
|
||||
const emojiTable = {};
|
||||
const $html = $.load(sheetHTML).root();
|
||||
$html.find('h2').each((_, categoryElement) => {
|
||||
const emojis = [];
|
||||
const category = $(categoryElement).text();
|
||||
$html.find(`#emoji-${category.toLowerCase()} li .name`).each((_, emojiElement) => {
|
||||
const emoji = $(emojiElement).text();
|
||||
const index = apiEmojis.indexOf(emoji);
|
||||
if (index !== -1) {
|
||||
apiEmojis.splice(index, 1);
|
||||
emojis.push(emoji);
|
||||
}
|
||||
});
|
||||
emojiTable[category] = emojis;
|
||||
});
|
||||
if (apiEmojis.length > 0) {
|
||||
emojiTable['Uncategorized'] = apiEmojis;
|
||||
}
|
||||
if (fs.existsSync(outDir)) {
|
||||
if (!fs.statSync(outDir).isDirectory()) {
|
||||
throw `OutDir '${outDir}' should be a directory.`;
|
||||
}
|
||||
} else {
|
||||
fs.mkdirSync(outDir);
|
||||
}
|
||||
fs.writeFileSync(outFile, markdown.create({
|
||||
'GitHub Emoji API': apiUrl,
|
||||
'Emoji Cheat Sheet': sheetUrl,
|
||||
}, title, emojiTable, columnDivisions));
|
||||
});
|
@ -1,60 +0,0 @@
|
||||
const format = str => str.trim().replace(/^ +/mg, '');
|
||||
|
||||
module.exports = class Markdown {
|
||||
|
||||
static create(urls, title, emojiTable, columnDivisions) {
|
||||
const categories = Object.keys(emojiTable);
|
||||
const urlDescriptions = Object.keys(urls).map((site) => `[${site}](${urls[site]})`).join(' and ');
|
||||
return format(`
|
||||
|
||||
# ${title}
|
||||
|
||||
[![build](https://travis-ci.org/ikatyang/emoji-cheat-sheet.svg?branch=generator)](https://travis-ci.org/ikatyang/emoji-cheat-sheet)
|
||||
|
||||
This cheat sheet is auto-generated from ${urlDescriptions} using [emoji-cheat-sheet-generator](https://github.com/ikatyang/emoji-cheat-sheet/tree/generator).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
${categories.map(category => `- [${category}](#${category.toLowerCase()})`).join('\n')}
|
||||
|
||||
${
|
||||
categories.map(category => {
|
||||
const emojis = emojiTable[category];
|
||||
return format(`
|
||||
|
||||
### ${category}
|
||||
|
||||
${this.createTable(emojis, columnDivisions)}
|
||||
|
||||
`);
|
||||
}).join(('\n').repeat(2))
|
||||
}
|
||||
|
||||
`);
|
||||
}
|
||||
|
||||
static createTableHead(columnDivisions) {
|
||||
return format(`
|
||||
|
||||
| |${(' ico | emoji |').repeat(columnDivisions)}
|
||||
| - |${(' --- | ----- |').repeat(columnDivisions)}
|
||||
|
||||
`);
|
||||
}
|
||||
|
||||
static createTable(emojis, columnDivisions) {
|
||||
let table = this.createTableHead(columnDivisions) + '\n';
|
||||
for (let i = 0; i < emojis.length; i += columnDivisions) {
|
||||
const rowEmojis = emojis.slice(i, i + columnDivisions);
|
||||
while (rowEmojis.length < columnDivisions)
|
||||
rowEmojis.push('');
|
||||
table += format(`
|
||||
|
||||
| [top](#table-of-contents) |${rowEmojis.map((emoji) => emoji ? ` :${emoji}: | \`:${emoji}:\` ` : ' | ').join(' | ')}|
|
||||
|
||||
`) + '\n';
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
};
|
@ -47,7 +47,7 @@
|
||||
version "20.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-20.0.2.tgz#86c751121fb53dbd39bb1a08c45083da13f2dc67"
|
||||
|
||||
"@types/node@*":
|
||||
"@types/node@*", "@types/node@8.0.13":
|
||||
version "8.0.13"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.13.tgz#530f0f9254209b0335bf5cc6387822594ef47093"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user