Skip to content

Commit

Permalink
migrate index.js to index.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed May 12, 2024
1 parent 91da030 commit 867446f
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 473 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -1,2 +1,5 @@
/node_modules
/index.js
/index.js.map
/index.d.ts

47 changes: 37 additions & 10 deletions index.js → index.ts
@@ -1,29 +1,54 @@
import { get as getEmoji } from 'node-emoji';
import { emoticon } from 'emoticon';
import { findAndReplace } from 'mdast-util-find-and-replace';
import { findAndReplace, type Find, type Replace } from 'mdast-util-find-and-replace';
import type { Plugin } from 'unified';
import type { Root, Nodes, Text } from 'mdast';

const RE_EMOJI = /:\+1:|:-1:|:[\w-]+:/g;
const RE_SHORT = /[$@|*'",;.=:\-)([\]\\/<>038BOopPsSdDxXzZ]{2,5}/g;
const RE_PUNCT = /(?:_|-(?!1))/g;

const DEFAULT_SETTINGS = {
export interface RemarkEmojiOptions {
/**
* Makes converted emoji and emoticon texts accessible by wrapping them with
* `span` element setting `role` and `aria-label` attributes.
*
* @defaultValue false
*/
accessible?: boolean;
/**
* Adds an extra whitespace after emoji.
* Useful when browser handle emojis with half character length and
* the following character is hidden.
*
* @defaultValue false
*/
padSpaceAfter?: boolean;
/**
* Whether to support emoticon shortcodes (e.g. :-) will be replaced by 😃)
*
* @defaultValue false
*/
emoticon?: boolean;
}

const DEFAULT_SETTINGS: RemarkEmojiOptions = {
padSpaceAfter: false,
emoticon: false,
accessible: false,
};

export default function plugin(options) {
const plugin: Plugin<[(RemarkEmojiOptions | null | undefined)?], Root> = options => {
const settings = Object.assign({}, DEFAULT_SETTINGS, options);
const pad = !!settings.padSpaceAfter;
const emoticonEnable = !!settings.emoticon;
const accessible = !!settings.accessible;

function aria(text, label) {
function aria(text: string, label: string): Text {
// Creating HTML node in Markdown node is undocumented.
// https://github.com/syntax-tree/mdast-util-math/blob/e70bb824dc70f5423324b31b0b68581cf6698fe8/index.js#L44-L55
return {
type: 'text',
meta: null,
value: text,
data: {
hName: 'span',
Expand All @@ -36,7 +61,7 @@ export default function plugin(options) {
};
}

function replaceEmoticon(match) {
function replaceEmoticon(match: string): string | false | Text {
// find emoji by shortcode - full match or with-out last char as it could be from text e.g. :-),
const iconFull = emoticon.find(e => e.emoticons.includes(match)); // full match
const iconPart = emoticon.find(e => e.emoticons.includes(match.slice(0, -1))); // second search pattern
Expand All @@ -53,7 +78,7 @@ export default function plugin(options) {
return replaced;
}

function replaceEmoji(match) {
function replaceEmoji(match: string): string | false | Text {
let got = getEmoji(match);

if (typeof got === 'undefined') {
Expand All @@ -72,14 +97,16 @@ export default function plugin(options) {
return got;
}

const replacers = [[RE_EMOJI, replaceEmoji]];
const replacers: [Find, Replace][] = [[RE_EMOJI, replaceEmoji]];
if (emoticonEnable) {
replacers.push([RE_SHORT, replaceEmoticon]);
}

function transformer(tree) {
function transformer(tree: Nodes): void {
findAndReplace(tree, replacers);
}

return transformer;
}
};

export default plugin;

0 comments on commit 867446f

Please sign in to comment.