From 86578163799820b4d594f5630b09bafc2e41c620 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Sat, 19 Oct 2019 22:14:24 +0300 Subject: [PATCH 01/31] feat(v2): allow line highlighting --- CHANGELOG-2.x.md | 1 + .../src/theme/CodeBlock/index.js | 47 +++++++++++++++---- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGELOG-2.x.md b/CHANGELOG-2.x.md index c8fd2b776667..e3653462bde2 100644 --- a/CHANGELOG-2.x.md +++ b/CHANGELOG-2.x.md @@ -8,6 +8,7 @@ - Fix `swizzle` command not being able to swizzle single js file. - Fix logo URL in footer to be appended with baseUrl automatically. - Add the option `--no-open` for `start` command. +- Add highlight specific lines in code blocks. ## 2.0.0-alpha.27 diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js index 1914e65b7856..f104858fea85 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js @@ -13,7 +13,29 @@ import Clipboard from 'clipboard'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import styles from './styles.module.css'; -export default ({children, className: languageClassName}) => { +const regexHighlightRange = /{([\d,-]+)}/; + +const calculateLinesToHighlight = meta => { + if (!regexHighlightRange.test(meta)) { + return () => false; + } + + const lineNumbers = regexHighlightRange + .exec(meta)[1] + .split(',') + .map(v => v.split('-').map(ve => parseInt(ve, 10))); + + return index => { + const lineNumber = index + 1; + const inRange = lineNumbers.some(([start, end]) => + end ? lineNumber >= start && lineNumber <= end : lineNumber === start, + ); + + return inRange; + }; +}; + +export default ({children, className: languageClassName, metastring}) => { const { siteConfig: { themeConfig: {prismTheme}, @@ -22,6 +44,7 @@ export default ({children, className: languageClassName}) => { const [showCopied, setShowCopied] = useState(false); const target = useRef(null); const button = useRef(null); + const shouldHighlightLine = calculateLinesToHighlight(metastring); useEffect(() => { let clipboard; @@ -61,13 +84,21 @@ export default ({children, className: languageClassName}) => { 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 (shouldHighlightLine(i)) { + lineProps.className = `${lineProps.className} highlight-line`; + } + + return ( +
+ {line.map((token, key) => ( + + ))} +
+ ); + })}