From 63951fb6b88909d69a02b9fb834fe48f75d15a91 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 2 Apr 2020 14:24:58 +0300 Subject: [PATCH] fix(v2): synchronize code block components changes --- .../src/theme/CodeBlock/index.js | 4 +- .../src/theme/CodeBlock/styles.module.css | 10 +- .../src/theme/CodeBlock/index.js | 113 +++++++++++++++++- 3 files changed, 118 insertions(+), 9 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js index f18b886b303f..a8a003875c56 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js @@ -229,7 +229,7 @@ export default ({children, className: languageClassName, metastring}) => { onClick={handleCopyCode}> {showCopied ? 'Copied' : 'Copy'} -
 {
                   );
                 })}
               
-            
+ )} diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/styles.module.css b/packages/docusaurus-theme-classic/src/theme/CodeBlock/styles.module.css index d7ced44e1021..cee4986566e7 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/styles.module.css @@ -19,9 +19,6 @@ .codeBlock { overflow: auto; - display: block; - padding: 0; - margin: 0; } .codeBlockWithTitle { @@ -58,9 +55,10 @@ } .codeBlockLines { - background-color: transparent; - border-radius: 0; - margin-bottom: 0; + font-family: var(--ifm-font-family-monospace); + font-size: inherit; + line-height: var(--ifm-pre-line-height); + white-space: pre; float: left; min-width: 100%; padding: var(--ifm-pre-padding); 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 9fd9c4bc0bb6..beaff00d5edc 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js +++ b/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js @@ -20,6 +20,73 @@ import Playground from '@theme/Playground'; import styles from './styles.module.css'; const highlightLinesRangeRegex = /{([\d,-]+)}/; +const getHighlightDirectiveRegex = ( + languages = ['js', 'jsBlock', 'jsx', 'python', 'html'], +) => { + // supported types of comments + const comments = { + js: { + start: '\\/\\/', + end: '', + }, + jsBlock: { + start: '\\/\\*', + end: '\\*\\/', + }, + jsx: { + start: '\\{\\s*\\/\\*', + end: '\\*\\/\\s*\\}', + }, + python: { + start: '#', + end: '', + }, + html: { + start: '', + }, + }; + // supported directives + const directives = [ + 'highlight-next-line', + 'highlight-start', + 'highlight-end', + ].join('|'); + // to be more reliable, the opening and closing comment must match + const commentPattern = languages + .map( + lang => + `(?:${comments[lang].start}\\s*(${directives})\\s*${comments[lang].end})`, + ) + .join('|'); + // white space is allowed, but otherwise it should be on it's own line + return new RegExp(`^\\s*(?:${commentPattern})\\s*$`); +}; +// select comment styles based on language +const highlightDirectiveRegex = lang => { + switch (lang) { + case 'js': + case 'javascript': + case 'ts': + case 'typescript': + return getHighlightDirectiveRegex(['js', 'jsBlock']); + + case 'jsx': + case 'tsx': + return getHighlightDirectiveRegex(['js', 'jsBlock', 'jsx']); + + case 'html': + return getHighlightDirectiveRegex(['js', 'jsBlock', 'html']); + + case 'python': + case 'py': + return getHighlightDirectiveRegex(['python']); + + default: + // all comment types + return getHighlightDirectiveRegex(); + } +}; const codeBlockTitleRegex = /title=".*"/; export default ({ @@ -105,6 +172,50 @@ export default ({ language = prism.defaultLanguage; } + // only declaration OR directive highlight can be used for a block + let code = children.replace(/\n$/, ''); + if (highlightLines.length === 0 && language !== undefined) { + let range = ''; + const directiveRegex = highlightDirectiveRegex(language); + // go through line by line + const lines = children.replace(/\n$/, '').split('\n'); + let blockStart; + // loop through lines + for (let index = 0; index < lines.length; ) { + const line = lines[index]; + // adjust for 0-index + const lineNumber = index + 1; + const match = line.match(directiveRegex); + if (match !== null) { + const directive = match + .slice(1) + .reduce((final, item) => final || item, undefined); + switch (directive) { + case 'highlight-next-line': + range += `${lineNumber},`; + break; + + case 'highlight-start': + blockStart = lineNumber; + break; + + case 'highlight-end': + range += `${blockStart}-${lineNumber - 1},`; + break; + + default: + break; + } + lines.splice(index, 1); + } else { + // lines without directives are unchanged + index += 1; + } + } + highlightLines = rangeParser.parse(range); + code = lines.join('\n'); + } + const handleCopyCode = () => { window.getSelection().empty(); setShowCopied(true); @@ -117,7 +228,7 @@ export default ({ {...defaultProps} key={mounted} theme={prismTheme} - code={children.replace(/\n$/, '')} + code={code} language={language}> {({className, style, tokens, getLineProps, getTokenProps}) => ( <>