Skip to content

Commit 35002c9

Browse files
jhildenbiddleKoooooo-7
andauthoredMar 6, 2022
feat: Native emoji w/ image-based fallbacks and improved parsing (#1746)
* Render native emoji with image fallback Fix #779 * Deprecate emoji plugin * Add emoji tests * Remove console.log statement * Fix emoji image alt attribute * Set nativeEmoji to false by default (non-breaking) * Fix parsing emoji in HTML comments and script tags * Add nativeEmoji and update noEmoji details * Add Emoji plugin deprecation notice * Fix ESLint issues * Create build:emoji task - Auto-generate emoji data from GitHub API - Auto-generate emoji markdown for website - Add emoji page to navigation * Fix rendering of GitHub emoji without unicode * Adjust and match size of native and image emoji * Update emoji test snapshot * Update docs test snapshot * Fix ci/codesandbox error * Update native emoji font-stack * Fix rendering of native multi-character emoji * Kick GitHub Workflow * Replace rollup’s uglify plugin with terser * Switch “npm ci” instead of “npm i” for stability * Change emoji data from default to named export * Revert "Replace rollup’s uglify plugin with terser" This reverts commit 7ba8513. * Revert "Switch “npm ci” instead of “npm i” for stability" This reverts commit d52b476. * Revert "Change emoji data from default to named export" This reverts commit 3f2dd46. * Specify codesandbox template and node version * Update codesandbox config * Revert "Revert "Replace rollup’s uglify plugin with terser"" This reverts commit e06fed4. * Revert "Revert "Revert "Replace rollup’s uglify plugin with terser""" This reverts commit 27d4952. * Update codesandbox config * Revert "Update codesandbox config" This reverts commit 5120dd2. * Fix codesandbox uglify error * Emoji docs tweaks * Restore and update emoji plugin code * Restore and update emoji plugin docs * Prettier updates * Match lowercase shortcodes only Co-authored-by: Koy Zhuang <369491420@qq.com>
1 parent fd883e6 commit 35002c9

18 files changed

+6092
-1956
lines changed
 

‎.codesandbox/ci.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"sandboxes": ["2d17z"],
3-
"packages": [".", "packages/docsify-server-renderer"]
3+
"packages": [".", "packages/docsify-server-renderer"],
4+
"node": "16"
45
}

‎build/emoji.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
const axios = require('axios');
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
const filePaths = {
6+
emojiMarkdown: path.resolve(process.cwd(), 'docs', 'emoji.md'),
7+
emojiJS: path.resolve(
8+
process.cwd(),
9+
'src',
10+
'core',
11+
'render',
12+
'emojify-data.js'
13+
),
14+
};
15+
16+
async function getEmojiData() {
17+
const emojiDataURL = 'https://api.github.com/emojis';
18+
const response = await axios.get(emojiDataURL);
19+
const baseURL = Object.values(response.data)
20+
.find(url => /unicode\//)
21+
.split('unicode/')[0];
22+
const data = { ...response.data };
23+
24+
// Remove base URL from emoji URLs
25+
Object.entries(data).forEach(
26+
([key, value]) => (data[key] = value.replace(baseURL, ''))
27+
);
28+
29+
return {
30+
baseURL,
31+
data,
32+
};
33+
}
34+
35+
function writeEmojiPage(emojiData) {
36+
const emojiPage =
37+
(fs.existsSync(filePaths.emojiMarkdown) &&
38+
fs.readFileSync(filePaths.emojiMarkdown, 'utf8')) ||
39+
`<!-- START -->\n\n<!-- END -->`;
40+
const emojiRegEx = /(<!--\s*START.*-->\n)([\s\S]*)(\n<!--\s*END.*-->)/;
41+
const emojiMatch = emojiPage.match(emojiRegEx);
42+
const emojiMarkdownStart = emojiMatch[1].trim();
43+
const emojiMarkdown = emojiMatch[2].trim();
44+
const emojiMarkdownEnd = emojiMatch[3].trim();
45+
const newEmojiMarkdown = Object.keys(emojiData.data)
46+
.reduce(
47+
(preVal, curVal) =>
48+
(preVal += `:${curVal}: ` + '`' + `:${curVal}:` + '`' + '\n\n'),
49+
''
50+
)
51+
.trim();
52+
53+
if (emojiMarkdown !== newEmojiMarkdown) {
54+
const newEmojiPage = emojiPage.replace(
55+
emojiMatch[0],
56+
`${emojiMarkdownStart}\n${newEmojiMarkdown}\n${emojiMarkdownEnd}`
57+
);
58+
59+
fs.writeFileSync(filePaths.emojiMarkdown, newEmojiPage);
60+
console.info(`- Created new file: ${filePaths.emojiMarkdown}`);
61+
} else {
62+
console.info(`- No changes to file: ${filePaths.emojiMarkdown}`);
63+
}
64+
}
65+
66+
function writeEmojiJS(emojiData) {
67+
const emojiJS =
68+
fs.existsSync(filePaths.emojiJS) &&
69+
fs.readFileSync(filePaths.emojiJS, 'utf8');
70+
const newEmojiJS = `export default ${JSON.stringify(emojiData, {}, 2)}`;
71+
72+
if (!emojiJS || emojiJS !== newEmojiJS) {
73+
fs.writeFileSync(filePaths.emojiJS, newEmojiJS);
74+
console.info(`- Created new file: ${filePaths.emojiJS}`);
75+
} else {
76+
console.info(`- No changes to file: ${filePaths.emojiJS}`);
77+
}
78+
}
79+
80+
(async () => {
81+
console.log('Build emoji');
82+
83+
try {
84+
const emojiData = await getEmojiData();
85+
86+
writeEmojiPage(emojiData);
87+
writeEmojiJS(emojiData);
88+
} catch (e) {
89+
console.error(e);
90+
}
91+
})();

‎docs/_sidebar.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- [Write a Plugin](write-a-plugin.md)
1414
- [Markdown configuration](markdown.md)
1515
- [Language highlighting](language-highlight.md)
16+
- [Emoji](emoji.md)
1617

1718
- Guide
1819

‎docs/configuration.md

+84-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ The config can also be defined as a function, in which case the first argument i
1616

1717
```html
1818
<script>
19-
window.$docsify = function(vm) {
19+
window.$docsify = function (vm) {
2020
return {
2121
markdown: {
2222
renderer: {
@@ -319,14 +319,14 @@ window.$docsify = {
319319
markdown: {
320320
smartypants: true,
321321
renderer: {
322-
link: function() {
322+
link: function () {
323323
// ...
324324
},
325325
},
326326
},
327327

328328
// function
329-
markdown: function(marked, renderer) {
329+
markdown: function (marked, renderer) {
330330
// ...
331331
return marked;
332332
},
@@ -398,19 +398,97 @@ window.$docsify = {
398398

399399
Note that if you are running an external script, e.g. an embedded jsfiddle demo, make sure to include the [external-script](plugins.md?id=external-script) plugin.
400400

401+
## nativeEmoji
402+
403+
- type: `Boolean`
404+
- default: `false`
405+
406+
Render emoji shorthand codes using GitHub-style emoji images or platform-native emoji characters.
407+
408+
```js
409+
window.$docsify = {
410+
nativeEmoji: true,
411+
};
412+
```
413+
414+
```markdown
415+
:smile:
416+
:partying_face:
417+
:joy:
418+
:+1:
419+
:-1:
420+
```
421+
422+
GitHub-style images when `false`:
423+
424+
<output data-lang="output">
425+
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f604.png" alt="smile">
426+
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f973.png" alt="partying_face">
427+
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f602.png" alt="joy">
428+
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44d.png" alt="+1">
429+
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44e.png" alt="-1">
430+
</output>
431+
432+
Platform-native characters when `true`:
433+
434+
<output data-lang="output">
435+
<span class="emoji">😄︎</span>
436+
<span class="emoji">🥳︎</span>
437+
<span class="emoji">😂︎</span>
438+
<span class="emoji">👍︎</span>
439+
<span class="emoji">👎︎</span>
440+
</output>
441+
442+
To render shorthand codes as text, replace `:` characters with the `&colon;` HTML entity.
443+
444+
```markdown
445+
&colon;100&colon;
446+
```
447+
448+
<output data-lang="output">
449+
450+
&colon;100&colon;
451+
452+
</output>
453+
401454
## noEmoji
402455

403456
- type: `Boolean`
457+
- default: `false`
404458

405-
Disabled emoji parse.
459+
Disabled emoji parsing and render all emoji shorthand as text.
406460

407461
```js
408462
window.$docsify = {
409463
noEmoji: true,
410464
};
411465
```
412466

413-
?> If this option is `false` but you don't want to emojify some specific colons, [refer to this](https://github.com/docsifyjs/docsify/issues/742#issuecomment-586313143)
467+
```markdown
468+
:100:
469+
```
470+
471+
<output data-lang="output">
472+
473+
&colon;100&colon;
474+
475+
</output>
476+
477+
To disable emoji parsing of individual shorthand codes, replace `:` characters with the `&colon;` HTML entity.
478+
479+
```markdown
480+
:100:
481+
482+
&colon;100&colon;
483+
```
484+
485+
<output data-lang="output">
486+
487+
:100:
488+
489+
&colon;100&colon;
490+
491+
</output>
414492

415493
## mergeNavbar
416494

@@ -435,7 +513,7 @@ See https://github.com/lukeed/tinydate#patterns
435513
window.$docsify = {
436514
formatUpdated: '{MM}/{DD} {HH}:{mm}',
437515

438-
formatUpdated: function(time) {
516+
formatUpdated: function (time) {
439517
// ...
440518

441519
return time;

0 commit comments

Comments
 (0)