From d71b44d606cc4ec771c693b81703a05ef78621a0 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 14 Oct 2020 16:05:46 -0700 Subject: [PATCH] feat: add syntax highlighting to terminal commands --- src/components/Terminal/SyntaxHighlighter.js | 127 +++++++++++++++++++ src/components/Terminal/Terminal.js | 41 +----- 2 files changed, 129 insertions(+), 39 deletions(-) create mode 100644 src/components/Terminal/SyntaxHighlighter.js diff --git a/src/components/Terminal/SyntaxHighlighter.js b/src/components/Terminal/SyntaxHighlighter.js new file mode 100644 index 000000000..2afeddd66 --- /dev/null +++ b/src/components/Terminal/SyntaxHighlighter.js @@ -0,0 +1,127 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { css } from '@emotion/core'; +import Highlight from 'prism-react-renderer'; +import Prism from 'prismjs'; + +const WHITESPACE = /^\s*$/; +const MULTILINE_COMMAND = /\\\s*$/; + +const SyntaxHighlighter = ({ code }) => ( + + {({ tokens, getLineProps, getTokenProps }) => ( +
+        
+          {tokens.map((line, idx) => {
+            const previousLine = collapse(tokens[idx - 1] || [])
+              .map((token) => token.content)
+              .join(' ');
+            const isMultiline = MULTILINE_COMMAND.test(previousLine);
+
+            return (
+              // eslint-disable-next-line react/jsx-key
+              
+
+ + {isMultiline ? '>' : '$'} + +
+ {line.map((token, key) => ( + // eslint-disable-next-line react/jsx-key + + ))} +
+
+
+ ); + })} +
+
+ )} +
+); + +const nordTheme = css` + .namespace { + opacity: 0.7; + } + .token { + &.plain:empty { + display: inline-block; + } + + &.comment { + color: var(--color-nord-3); + } + + &.punctuation, + &.operator { + color: var(--color-nord-9); + } + + &.constant { + color: var(--color-nord-15); + } + + &.string { + color: var(--color-nord-14); + } + } +`; + +const collapse = (line) => { + return line.filter( + (token) => + !WHITESPACE.test(token.content) && !token.types.includes('comment') + ); +}; + +SyntaxHighlighter.propTypes = { + className: PropTypes.string, + code: PropTypes.string.isRequired, +}; + +export default SyntaxHighlighter; diff --git a/src/components/Terminal/Terminal.js b/src/components/Terminal/Terminal.js index 0c063d298..3e68c1ba5 100644 --- a/src/components/Terminal/Terminal.js +++ b/src/components/Terminal/Terminal.js @@ -2,8 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { css } from '@emotion/core'; import { Button, useClipboard } from '@newrelic/gatsby-theme-newrelic'; - -const MULTILINE_COMMAND = /\\\s*$/; +import SyntaxHighlighter from './SyntaxHighlighter'; const Terminal = ({ children }) => { const [copied, copy] = useClipboard(); @@ -66,17 +65,7 @@ const Terminal = ({ children }) => { border-bottom-right-radius: var(--border-radius); `} > - {children - .trim() - .split('\n') - .map((line, idx, lines) => ( - - {line} - - ))} + ); @@ -97,32 +86,6 @@ FrameButton.propTypes = { color: PropTypes.string, }; -const Line = ({ children, multiline }) => ( -
- - {multiline ? '>' : '$'} - -
- {children} -
-
-); - Terminal.propTypes = { children: PropTypes.string, };