Repository: zestedesavoir/zmarkdown
Pull request #246 (2018-07-19 15:18:59)

Emoticons fix


Patch:
diff --git a/packages/remark-emoticons/dist/index.js b/packages/remark-emoticons/dist/index.js
index c6b7a0df..74d5e140 100644
--- a/packages/remark-emoticons/dist/index.js
+++ b/packages/remark-emoticons/dist/index.js
@@ -1,5 +1,7 @@
 'use strict';
 
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
 function escapeRegExp(str) {
   return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); // eslint-disable-line no-useless-escape
 }
@@ -9,13 +11,44 @@ var SPACE = ' ';
 module.exports = function inlinePlugin(ctx) {
   var emoticonClasses = ctx && ctx.classes;
   var emoticons = ctx && ctx.emoticons;
-  var pattern = Object.keys(emoticons).map(escapeRegExp).join('|');
 
-  if (!pattern) {
+  if (!emoticons) {
     throw new Error('remark-emoticons needs to be passed a configuration object as option');
   }
 
-  var regex = new RegExp('(\\s|^)(' + pattern + ')(\\s|$)');
+  var _iteratorNormalCompletion = true;
+  var _didIteratorError = false;
+  var _iteratorError = undefined;
+
+  try {
+    for (var _iterator = Object.entries(emoticons)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+      var _ref = _step.value;
+
+      var _ref2 = _slicedToArray(_ref, 2);
+
+      var key = _ref2[0];
+      var val = _ref2[1];
+
+      emoticons[key.toLowerCase()] = val;
+    }
+  } catch (err) {
+    _didIteratorError = true;
+    _iteratorError = err;
+  } finally {
+    try {
+      if (!_iteratorNormalCompletion && _iterator.return) {
+        _iterator.return();
+      }
+    } finally {
+      if (_didIteratorError) {
+        throw _iteratorError;
+      }
+    }
+  }
+
+  var pattern = Object.keys(emoticons).map(escapeRegExp).join('|');
+
+  var regex = new RegExp('(\\s|^)(' + pattern + ')(\\s|$)', 'i');
 
   function locator(value, fromIndex) {
     var keep = regex.exec(value);
@@ -36,13 +69,15 @@ module.exports = function inlinePlugin(ctx) {
         toEat = toEat.substring(0, toEat.length - 1);
       }
       var emoticon = toEat.trim();
+      var src = emoticons[emoticon.toLowerCase()];
+
       var emoticonNode = {
         type: 'emoticon',
         value: emoticon,
         data: {
           hName: 'img',
           hProperties: {
-            src: emoticons[emoticon],
+            src: src,
             alt: emoticon
           }
         }
diff --git a/packages/remark-emoticons/package.json b/packages/remark-emoticons/package.json
index d96c4afd..749ae4e9 100644
--- a/packages/remark-emoticons/package.json
+++ b/packages/remark-emoticons/package.json
@@ -43,6 +43,7 @@
     "rehype-stringify": "^4.0.0",
     "remark-parse": "^5.0.0",
     "remark-rehype": "^3.0.0",
-    "unified": "^7.0.0"
+    "unified": "^7.0.0",
+    "unist-util-visit": "^1.3.1"
   }
 }
diff --git a/packages/remark-emoticons/src/index.js b/packages/remark-emoticons/src/index.js
index 4343c5e8..2eb48cfe 100644
--- a/packages/remark-emoticons/src/index.js
+++ b/packages/remark-emoticons/src/index.js
@@ -7,13 +7,18 @@ const SPACE = ' '
 module.exports = function inlinePlugin (ctx) {
   const emoticonClasses = ctx && ctx.classes
   const emoticons = ctx && ctx.emoticons
-  const pattern = Object.keys(emoticons).map(escapeRegExp).join('|')
 
-  if (!pattern) {
+  if (!emoticons) {
     throw new Error('remark-emoticons needs to be passed a configuration object as option')
   }
 
-  const regex = new RegExp(`(\\s|^)(${pattern})(\\s|$)`)
+  for (const [key, val] of Object.entries(emoticons)) {
+    emoticons[key.toLowerCase()] = val
+  }
+
+  const pattern = Object.keys(emoticons).map(escapeRegExp).join('|')
+
+  const regex = new RegExp(`(\\s|^)(${pattern})(\\s|$)`, 'i')
 
   function locator (value, fromIndex) {
     const keep = regex.exec(value)
@@ -34,13 +39,15 @@ module.exports = function inlinePlugin (ctx) {
         toEat = toEat.substring(0, toEat.length - 1)
       }
       const emoticon = toEat.trim()
+      const src = emoticons[emoticon.toLowerCase()]
+
       const emoticonNode = {
         type: 'emoticon',
         value: emoticon,
         data: {
           hName: 'img',
           hProperties: {
-            src: emoticons[emoticon],
+            src: src,
             alt: emoticon,
           },
         },


Test patch:
diff --git a/packages/remark-emoticons/__tests__/index.js b/packages/remark-emoticons/__tests__/index.js
index 3218049c..af4d6c29 100644
--- a/packages/remark-emoticons/__tests__/index.js
+++ b/packages/remark-emoticons/__tests__/index.js
@@ -2,6 +2,7 @@ import dedent from 'dedent'
 import unified from 'unified'
 import reParse from 'remark-parse'
 import stringify from 'rehype-stringify'
+import visit from 'unist-util-visit'
 import remark2rehype from 'remark-rehype'
 import remarkStringify from 'remark-stringify'
 import remarkCaption from '../../remark-captions/src'
@@ -19,7 +20,7 @@ const config = {
     '^^': '/static/smileys/hihi.png',
     ':o': '/static/smileys/huh.png',
     ':p': '/static/smileys/langue.png',
-    ':magicien:': '/static/smileys/magicien.png',
+    ':magICIen:': '/static/smileys/magicien.png',
     ':colere2:': '/static/smileys/mechant.png',
     ':ninja:': '/static/smileys/ninja.png',
     'x(': '/static/smileys/pinch.png',
@@ -115,7 +116,7 @@ test('emoticons without class', () => {
   expect(contents).toMatchSnapshot()
 })
 
-test('Errors without config', () => {
+test('errors without config', () => {
   const fail = () => unified()
     .use(reParse)
     .use(remark2rehype)
@@ -155,3 +156,23 @@ test('renders to markdown', () => {
   const recompiled = renderToMarkdown(contents).contents
   expect(recompiled).toBe(contents)
 })
+
+test('emoticons are case insensitive', () => {
+  const render = text => unified()
+    .use(reParse)
+    .use(plugin, config)
+    .use(() => (tree) => {
+      visit(tree, 'emoticon', (node) => {
+        node.data.hProperties.alt = ''
+      })
+    })
+    .use(remark2rehype)
+    .use(stringify)
+    .processSync(text)
+
+  expect(render(`:p`).contents).toBe(render(`:P`).contents)
+  expect(render(`:d`).contents).toBe(render(`:D`).contents)
+  expect(render(`:magicien:`).contents).toBe(render(`:MAGICIEN:`).contents)
+  expect(render(`:magicien:`).contents).toBe(render(`:MagICIEn:`).contents)
+  expect(render(`:magICIen:`).contents).toBe(render(`:MagICIEn:`).contents)
+})