From a2947a4edcd3b1aaf14b2a8e8b956d083d092b6b Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Tue, 22 Oct 2019 15:20:41 +0300 Subject: [PATCH] Add line highlighting for live code blocks --- .../package.json | 1 + .../src/theme/CodeBlock/index.js | 39 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/docusaurus-theme-live-codeblock/package.json b/packages/docusaurus-theme-live-codeblock/package.json index d70228fb0b30..1efc6ed94d7a 100644 --- a/packages/docusaurus-theme-live-codeblock/package.json +++ b/packages/docusaurus-theme-live-codeblock/package.json @@ -11,6 +11,7 @@ "@philpl/buble": "^0.19.7", "classnames": "^2.2.6", "clipboard": "^2.0.4", + "parse-numeric-range": "^0.0.2", "prism-react-renderer": "^1.0.1", "react-live": "^2.1.2" }, diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js b/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js index 9e14e2fbc08e..93b2c083bfc9 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js +++ b/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js @@ -10,11 +10,20 @@ import classnames from 'classnames'; import Highlight, {defaultProps} from 'prism-react-renderer'; import defaultTheme from 'prism-react-renderer/themes/palenight'; import Clipboard from 'clipboard'; +import rangeParser from 'parse-numeric-range'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Playground from '@theme/Playground'; import styles from './styles.module.css'; -export default ({children, className: languageClassName, live, ...props}) => { +const highlightLinesRangeRegex = /{([\d,-]+)}/; + +export default ({ + children, + className: languageClassName, + live, + metastring, + ...props +}) => { const { siteConfig: { themeConfig: {prismTheme}, @@ -23,6 +32,12 @@ export default ({children, className: languageClassName, live, ...props}) => { const [showCopied, setShowCopied] = useState(false); const target = useRef(null); const button = useRef(null); + let highlightLines = []; + + if (metastring && highlightLinesRangeRegex.test(metastring)) { + const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1]; + highlightLines = rangeParser.parse(highlightLinesRange).filter(n => n > 0); + } useEffect(() => { let clipboard; @@ -73,13 +88,21 @@ export default ({children, className: languageClassName, live, ...props}) => { ref={target} className={classnames(className, styles.codeBlock)} style={style}> - {tokens.map((line, i) => ( -
- {line.map((token, key) => ( - - ))} -
- ))} + {tokens.map((line, i) => { + const lineProps = getLineProps({line, key: i}); + + if (highlightLines.includes(i + 1)) { + lineProps.className = `${lineProps.className} highlight-line`; + } + + return ( +
+ {line.map((token, key) => ( + + ))} +
+ ); + })}