From 9187c7a734fb9036c68a2d0fe8dd42a0d634b336 Mon Sep 17 00:00:00 2001 From: Carter Thaxton Date: Mon, 13 May 2024 16:18:09 -0700 Subject: [PATCH 1/3] Replace unicode emoji characters, allowing them to also be customized by renderer rules --- lib/normalize_opts.mjs | 1 + lib/replace.mjs | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/normalize_opts.mjs b/lib/normalize_opts.mjs index 69899ff..b84f580 100644 --- a/lib/normalize_opts.mjs +++ b/lib/normalize_opts.mjs @@ -41,6 +41,7 @@ export default function normalize_opts (options) { names = keys .map(name => { return `:${name}:` }) .concat(Object.keys(shortcuts)) + .concat(Object.values(emojies)) .sort() .reverse() .map(name => { return quoteRE(name) }) diff --git a/lib/replace.mjs b/lib/replace.mjs index fa81a58..5e1e363 100644 --- a/lib/replace.mjs +++ b/lib/replace.mjs @@ -8,6 +8,7 @@ export default function create_rule (md, emojies, shortcuts, scanRE, replaceRE) const ucm = md.utils.lib.ucmicro const has = md.utils.has const ZPCc = new RegExp([ucm.Z.source, ucm.P.source, ucm.Cc.source].join('|')) + const emojies_rev = reverse_object(emojies) function splitTextToken (text, level, Token) { let last_pos = 0 @@ -27,10 +28,16 @@ export default function create_rule (md, emojies, shortcuts, scanRE, replaceRE) if (offset + match.length < src.length && !ZPCc.test(src[offset + match.length])) { return } - } else { + } else if (match[0] === ':' && match[match.length-1] === ':') { + // emoji_name specified like :smile: emoji_name = match.slice(1, -1) + } else { + // replace unicode emoji using canonical name + emoji_name = emojies_rev[match] } + if (!emoji_name) { return } + // Add new tokens to pending list if (offset > last_pos) { const token = new Token('text', '', 0) @@ -83,3 +90,10 @@ export default function create_rule (md, emojies, shortcuts, scanRE, replaceRE) } } }; + +function reverse_object(obj) { + return Object.fromEntries(Object + .entries(obj) + .map(([key, value]) => [value, key]) + ) +} From 06e62632d4db62fb7985cc9ba29b3b82d566b2bc Mon Sep 17 00:00:00 2001 From: Carter Thaxton Date: Tue, 14 May 2024 13:37:26 -0700 Subject: [PATCH 2/3] Fix linter errors and code-coverage warnings Use enforced code style for spaces. The code coverage checker was complaining about the 'unnecessary' check that I added in the previous commit, in case the replacement regexp didn't match anything. --- lib/replace.mjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/replace.mjs b/lib/replace.mjs index 5e1e363..34287df 100644 --- a/lib/replace.mjs +++ b/lib/replace.mjs @@ -28,7 +28,7 @@ export default function create_rule (md, emojies, shortcuts, scanRE, replaceRE) if (offset + match.length < src.length && !ZPCc.test(src[offset + match.length])) { return } - } else if (match[0] === ':' && match[match.length-1] === ':') { + } else if (match[0] === ':' && match[match.length - 1] === ':') { // emoji_name specified like :smile: emoji_name = match.slice(1, -1) } else { @@ -36,8 +36,6 @@ export default function create_rule (md, emojies, shortcuts, scanRE, replaceRE) emoji_name = emojies_rev[match] } - if (!emoji_name) { return } - // Add new tokens to pending list if (offset > last_pos) { const token = new Token('text', '', 0) @@ -91,7 +89,7 @@ export default function create_rule (md, emojies, shortcuts, scanRE, replaceRE) } }; -function reverse_object(obj) { +function reverse_object (obj) { return Object.fromEntries(Object .entries(obj) .map(([key, value]) => [value, key]) From 37c55da3042c8b1d534be237d0f6979332566888 Mon Sep 17 00:00:00 2001 From: Carter Thaxton Date: Tue, 14 May 2024 13:58:56 -0700 Subject: [PATCH 3/3] Add some tests to handle overrides of markdownit().renderer.rules.emoji Specifically, add a test that emojies using unicode characters are also wrapped by such renderer rules, covering the new behavior in this pull request. --- test/fixtures/renderer.txt | 27 +++++++++++++++++++++++++++ test/test.mjs | 10 ++++++++++ 2 files changed, 37 insertions(+) create mode 100644 test/fixtures/renderer.txt diff --git a/test/fixtures/renderer.txt b/test/fixtures/renderer.txt new file mode 100644 index 0000000..1f8c796 --- /dev/null +++ b/test/fixtures/renderer.txt @@ -0,0 +1,27 @@ +--- +desc: Wrap emojis using renderer rules +--- + + +Replace emojis +. +before :smile: test __1__ +. +

before 😄 test 1

+. + + +alias + original +. +:) :smiley: +. +

😃 😃

+. + + +Unicode emojies are also wrapped +. +aaa 😂 bbb 😊 ccc 😘 ddd +. +

aaa 😂 bbb 😊 ccc 😘 ddd

+. diff --git a/test/test.mjs b/test/test.mjs index 4dfb9fe..fe3ac0b 100644 --- a/test/test.mjs +++ b/test/test.mjs @@ -111,3 +111,13 @@ describe('integrity', function () { } }) }) + +describe('renderer rules', function () { + const md = markdownit().use(emoji_full) + + md.renderer.rules.emoji = function (tokens, idx) { + return '' + tokens[idx].content + '' + } + + generate(fileURLToPath(new URL('fixtures/renderer.txt', import.meta.url)), { header: true }, md) +})