diff --git a/Dockerfile b/Dockerfile
index e1f462b5e..8c9503e44 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -25,8 +25,6 @@ COPY . ./
RUN mkdir -p __tests__/browser/__image_snapshots__/__diff_output__
-RUN make emojis
-
EXPOSE 9966
CMD ["test.browser"]
diff --git a/Dockerfile.legacy b/Dockerfile.legacy
index 9e408ddfb..37f275265 100644
--- a/Dockerfile.legacy
+++ b/Dockerfile.legacy
@@ -32,8 +32,6 @@ COPY . ./
RUN mkdir -p __tests__/browser/__image_snapshots__/__diff_output__
-RUN make emojis
-
EXPOSE 9966
CMD ["test.browser"]
diff --git a/Makefile b/Makefile
index 485120fb8..ca13857a5 100644
--- a/Makefile
+++ b/Makefile
@@ -6,14 +6,6 @@ DOCKER_WORKSPACE := "/markdown"
MOUNTS = --volume ${PWD}:${DOCKER_WORKSPACE} \
--volume ${DOCKER_WORKSPACE}/node_modules
-emojis: example/public/img/emojis ## Install our emojis.
-
-example/public/img/emojis: node_modules/@readme/emojis
- rm -rf example/img/emojis
- rm -rf example/public/img/emojis
- mkdir -p example/public/img/emojis
- cp node_modules/@readme/emojis/src/img/*.png example/public/img/emojis/
-
ifeq ($(USE_LEGACY), true)
dockerfile = -f Dockerfile.legacy
endif
diff --git a/__tests__/__snapshots__/index.test.js.snap b/__tests__/__snapshots__/index.test.js.snap
index ba04fa5cb..71115eb9c 100644
--- a/__tests__/__snapshots__/index.test.js.snap
+++ b/__tests__/__snapshots__/index.test.js.snap
@@ -73,7 +73,7 @@ Object {
`;
exports[`emojis 1`] = `
-"

+"
😂
:unknown-emoji:
"
`;
diff --git a/__tests__/flavored-compilers/gemoji.test.js b/__tests__/flavored-compilers/gemoji.test.js
new file mode 100644
index 000000000..16be2915a
--- /dev/null
+++ b/__tests__/flavored-compilers/gemoji.test.js
@@ -0,0 +1,10 @@
+import { mdast, md } from '../../index';
+
+describe('gemoji compiler', () => {
+ it('writes an gemojis back to shortcodes', () => {
+ const doc = ':poop:';
+ const tree = mdast(doc);
+
+ expect(md(tree)).toMatch(doc);
+ });
+});
diff --git a/__tests__/gemoji-parser.test.js b/__tests__/gemoji-parser.test.js
index bf50b5d22..c8847cd17 100644
--- a/__tests__/gemoji-parser.test.js
+++ b/__tests__/gemoji-parser.test.js
@@ -3,9 +3,35 @@ const unified = require('unified');
const parser = require('../processor/parse/gemoji-parser');
-test('should output an image node for a known emoji', () => {
+test('should output emoji', () => {
const emoji = 'joy';
const markdown = `This is a gemoji :${emoji}:.`;
+ const ast = {
+ type: 'root',
+ children: [
+ {
+ type: 'paragraph',
+ children: [
+ { type: 'text', value: 'This is a gemoji ' },
+ {
+ type: 'gemoji',
+ value: '😂',
+ name: emoji,
+ },
+ { type: 'text', value: '.' },
+ ],
+ },
+ ],
+ };
+
+ expect(unified().use(remarkParse).use(parser).data('settings', { position: false }).parse(markdown)).toStrictEqual(
+ ast,
+ );
+});
+
+test('should output an image node for a custom readme emoji', () => {
+ const emoji = 'owlbert';
+ const markdown = `This is a gemoji :${emoji}:.`;
const ast = {
type: 'root',
children: [
diff --git a/assets/img/emojis/owlbert-books.png b/assets/img/emojis/owlbert-books.png
new file mode 100644
index 000000000..bb3e40f0c
Binary files /dev/null and b/assets/img/emojis/owlbert-books.png differ
diff --git a/assets/img/emojis/owlbert-mask.png b/assets/img/emojis/owlbert-mask.png
new file mode 100644
index 000000000..92987a2ec
Binary files /dev/null and b/assets/img/emojis/owlbert-mask.png differ
diff --git a/assets/img/emojis/owlbert-reading.png b/assets/img/emojis/owlbert-reading.png
new file mode 100644
index 000000000..954e0a1ac
Binary files /dev/null and b/assets/img/emojis/owlbert-reading.png differ
diff --git a/assets/img/emojis/owlbert-thinking.png b/assets/img/emojis/owlbert-thinking.png
new file mode 100644
index 000000000..bf0663c2f
Binary files /dev/null and b/assets/img/emojis/owlbert-thinking.png differ
diff --git a/assets/img/emojis/owlbert.png b/assets/img/emojis/owlbert.png
new file mode 100644
index 000000000..89a305b36
Binary files /dev/null and b/assets/img/emojis/owlbert.png differ
diff --git a/lib/gemoji.js b/lib/gemoji.js
new file mode 100644
index 000000000..e8a859fa2
--- /dev/null
+++ b/lib/gemoji.js
@@ -0,0 +1,16 @@
+const { nameToEmoji } = require('gemoji');
+
+const owlmoji = ['owlbert-books', 'owlbert-mask', 'owlbert', 'owlbert-reading', 'owlbert-thinking'];
+
+class Emoji {
+ static kind = name => {
+ if (name in nameToEmoji) return 'gemoji';
+ else if (name.match(/^fa-/)) return 'fontawesome';
+ else if (owlmoji.includes(name)) return 'owlmoji';
+ return null;
+ };
+
+ static nameToEmoji = nameToEmoji;
+}
+
+module.exports = Emoji;
diff --git a/package-lock.json b/package-lock.json
index 9c0210066..c340f12b6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"@readme/syntax-highlighter": "^13.0.0",
"copy-to-clipboard": "^3.3.3",
"emoji-regex": "^10.3.0",
+ "gemoji": "^8.1.0",
"hast-util-sanitize": "^4.0.0",
"lodash.escape": "^4.0.1",
"lodash.kebabcase": "^4.1.1",
@@ -12671,6 +12672,15 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/gemoji": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/gemoji/-/gemoji-8.1.0.tgz",
+ "integrity": "sha512-HA4Gx59dw2+tn+UAa7XEV4ufUKI4fH1KgcbenVA9YKSj1QJTT0xh5Mwv5HMFNN3l2OtUe3ZIfuRwSyZS5pLIWw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -38125,6 +38135,11 @@
"globule": "^1.0.0"
}
},
+ "gemoji": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/gemoji/-/gemoji-8.1.0.tgz",
+ "integrity": "sha512-HA4Gx59dw2+tn+UAa7XEV4ufUKI4fH1KgcbenVA9YKSj1QJTT0xh5Mwv5HMFNN3l2OtUe3ZIfuRwSyZS5pLIWw=="
+ },
"gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
diff --git a/package.json b/package.json
index 30c96511a..83c8accd8 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
],
"scripts": {
"build": "webpack --mode production",
- "heroku-postbuild": "make emojis && webpack --mode production --config ./webpack.dev.js",
+ "heroku-postbuild": "webpack --mode production --config ./webpack.dev.js",
"lint": "npm run lint:js && npm run lint:css",
"lint:css": "stylelint '{components,styles}/**/*.{css,scss}'",
"lint:js": "eslint --ext ts,tsx,js,jsx .",
@@ -28,10 +28,10 @@
"watch": "webpack -w --progress --mode production"
},
"dependencies": {
- "@readme/emojis": "^6.0.0",
"@readme/syntax-highlighter": "^13.0.0",
"copy-to-clipboard": "^3.3.3",
"emoji-regex": "^10.3.0",
+ "gemoji": "^8.1.0",
"hast-util-sanitize": "^4.0.0",
"lodash.escape": "^4.0.1",
"lodash.kebabcase": "^4.1.1",
diff --git a/processor/compile/gemoji.js b/processor/compile/gemoji.js
new file mode 100644
index 000000000..3010fb368
--- /dev/null
+++ b/processor/compile/gemoji.js
@@ -0,0 +1,6 @@
+module.exports = function GemojiCompiler() {
+ const { Compiler } = this;
+ const { visitors } = Compiler.prototype;
+
+ visitors.gemoji = node => `:${node.name}:`;
+};
diff --git a/processor/compile/index.js b/processor/compile/index.js
index e55cb7d52..fd111b06f 100644
--- a/processor/compile/index.js
+++ b/processor/compile/index.js
@@ -3,6 +3,7 @@ export { default as codeTabsCompiler } from './code-tabs';
export { default as divCompiler } from './div';
export { default as escapeCompiler } from './escape';
export { default as figureCompiler } from './figure';
+export { default as gemojiCompiler } from './gemoji';
export { default as htmlBlockCompiler } from './html-block';
export { default as iconCompiler } from './i';
export { default as imageCompiler } from './image';
diff --git a/processor/parse/gemoji-parser.js b/processor/parse/gemoji-parser.js
index 523c33010..a7ddcc76b 100644
--- a/processor/parse/gemoji-parser.js
+++ b/processor/parse/gemoji-parser.js
@@ -1,9 +1,7 @@
-const Emoji = require('@readme/emojis').emoji;
+const Emoji = require('../../lib/gemoji');
const { insertInlineTokenizerBefore } = require('./utils');
-const emojis = new Emoji();
-
const colon = ':';
function tokenize(eat, value, silent) {
@@ -11,46 +9,50 @@ function tokenize(eat, value, silent) {
if (value.charAt(0) !== colon) return false;
const pos = value.indexOf(colon, 1);
-
if (pos === -1) return false;
- const subvalue = value.slice(1, pos);
+ const name = value.slice(1, pos);
// Exit with true in silent
if (silent) return true;
- const match = colon + subvalue + colon;
-
- if (subvalue.substr(0, 3) === 'fa-') {
- return eat(match)({
- type: 'i',
- data: {
- hName: 'i',
- hProperties: {
- className: ['fa', subvalue],
+ const match = colon + name + colon;
+
+ switch (Emoji.kind(name)) {
+ case 'gemoji':
+ return eat(match)({
+ type: 'gemoji',
+ value: Emoji.nameToEmoji[name],
+ name,
+ });
+ case 'fontawesome':
+ return eat(match)({
+ type: 'i',
+ data: {
+ hName: 'i',
+ hProperties: {
+ className: ['fa', name],
+ },
},
- },
- });
- }
-
- if (emojis.is(subvalue)) {
- return eat(match)({
- type: 'image',
- title: `:${subvalue}:`,
- alt: `:${subvalue}:`,
- url: `/public/img/emojis/${subvalue}.png`,
- data: {
- hProperties: {
- className: 'emoji',
- align: 'absmiddle',
- height: '20',
- width: '20',
+ });
+ case 'owlmoji':
+ return eat(match)({
+ type: 'image',
+ title: `:${name}:`,
+ alt: `:${name}:`,
+ url: `/public/img/emojis/${name}.png`,
+ data: {
+ hProperties: {
+ className: 'emoji',
+ align: 'absmiddle',
+ height: '20',
+ width: '20',
+ },
},
- },
- });
+ });
+ default:
+ return false;
}
-
- return false;
}
function locate(value, fromIndex) {