diff --git a/client/package-lock.json b/client/package-lock.json index 745f07fde3..71844a0c17 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -10585,8 +10585,7 @@ "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "hex-color-regex": { "version": "1.1.0", @@ -10701,6 +10700,16 @@ "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", "dev": true }, + "html-encoder-decoder": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/html-encoder-decoder/-/html-encoder-decoder-1.3.9.tgz", + "integrity": "sha512-dHv7bdOTEE69EIxXsM8Vslt+NW7QfEB5EGOC29BR14c7RQ9iHUgK76k3/aS23xNIwDg/xlZLWCSZ8lxol9bYlQ==", + "requires": { + "he": "^1.1.0", + "iterate-object": "^1.3.2", + "regex-escape": "^3.4.2" + } + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -11767,6 +11776,11 @@ "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" }, + "iterate-object": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz", + "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==" + }, "jest": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", @@ -17317,7 +17331,7 @@ } }, "reactstrap": { - "version": "github:SwissDataScienceCenter/reactstrap#npm-bs5-link", + "version": "git+ssh://git@github.com/SwissDataScienceCenter/reactstrap.git#4bf48f4c9e46916ed3da0a9b296ccbc2d02a7260", "from": "reactstrap@github:SwissDataScienceCenter/reactstrap#npm-bs5-link", "requires": { "@babel/runtime": "^7.12.5", @@ -17484,6 +17498,11 @@ "@babel/runtime": "^7.8.4" } }, + "regex-escape": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/regex-escape/-/regex-escape-3.4.10.tgz", + "integrity": "sha512-qEqf7uzW+iYcKNLMDFnMkghhQBnGdivT6KqVQyKsyjSWnoFyooXVnxrw9dtv3AFLnD6VBGXxtZGAQNFGFTnCqA==" + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -18780,6 +18799,16 @@ } } }, + "showdown-highlight": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/showdown-highlight/-/showdown-highlight-2.1.8.tgz", + "integrity": "sha512-WqrMzMPYrWEwbA03GJT8mc82QxTe91kFwvNWpEPfTgEwd/5G32d44bn5Z7zMYgOcePnXInmYClldezqHDAyGZg==", + "requires": { + "highlight.js": "^10.7.2", + "html-encoder-decoder": "^1.3.9", + "showdown": "^1.9.1" + } + }, "side-channel": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", diff --git a/client/package.json b/client/package.json index e4514c7473..501954ee5a 100644 --- a/client/package.json +++ b/client/package.json @@ -53,6 +53,7 @@ "redux-thunk": "^2.2.0", "sass": "^1.37.5", "showdown": "^1.9.1", + "showdown-highlight": "^2.1.8", "styled-jsx": "^3.4.5", "uuid": "^3.3.3", "xregexp": "^4.4.0", diff --git a/client/src/utils/HelperFunctions.js b/client/src/utils/HelperFunctions.js index 2a5e561dc4..4ad08f835d 100644 --- a/client/src/utils/HelperFunctions.js +++ b/client/src/utils/HelperFunctions.js @@ -19,6 +19,7 @@ // title.Author: Alex K. - https://stackoverflow.com/users/246342/alex-k // Source: https://stackoverflow.com/questions/6507056/replace-all-whitespace-characters/6507078#6507078 import showdown from "showdown"; +import showdownHighlight from "showdown-highlight"; import DOMPurify from "dompurify"; import XRegExp from "xregexp"; @@ -166,7 +167,13 @@ function sanitizedHTMLFromMarkdown(markdown, singleLine = false) { replace: `<${key} $1 class="$3 ${showdownClasses[key]}" $4>` })); - const converter = new showdown.Converter({ ...showdownOptions, extensions: [...bindings] }); + const converter = new showdown.Converter({ + ...showdownOptions, + extensions: [ + ...bindings, + showdownHighlight({ pre: true }) + ] + }); if (singleLine && markdown) { const lineBreakers = ["
", "
", "
", "\n"]; const breakPosition = Math.max(...lineBreakers.map(elem => markdown.indexOf(elem)));