From 348bf3bb24457664e67cef9be1158ad53aa88e61 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Tue, 15 Oct 2024 15:16:39 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=A9=E2=80=8D=F0=9F=92=BB=20Fix=20SSR?= =?UTF-8?q?=20styling=20of=20code-blocks=20(#480)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rowan Cockett --- .changeset/honest-pumpkins-wink.md | 5 + .changeset/shiny-rocks-approve.md | 5 + packages/myst-to-react/src/code.tsx | 70 +++++++------ styles/app.css | 2 + styles/code-highlight-dark.css | 146 ++++++++++++++++++++++++++++ styles/code-highlight-light.css | 124 +++++++++++++++++++++++ 6 files changed, 320 insertions(+), 32 deletions(-) create mode 100644 .changeset/honest-pumpkins-wink.md create mode 100644 .changeset/shiny-rocks-approve.md create mode 100644 styles/code-highlight-dark.css create mode 100644 styles/code-highlight-light.css diff --git a/.changeset/honest-pumpkins-wink.md b/.changeset/honest-pumpkins-wink.md new file mode 100644 index 00000000..10390749 --- /dev/null +++ b/.changeset/honest-pumpkins-wink.md @@ -0,0 +1,5 @@ +--- +'@myst-theme/styles': patch +--- + +Add styling for code-blocks diff --git a/.changeset/shiny-rocks-approve.md b/.changeset/shiny-rocks-approve.md new file mode 100644 index 00000000..7ee283f3 --- /dev/null +++ b/.changeset/shiny-rocks-approve.md @@ -0,0 +1,5 @@ +--- +'myst-to-react': patch +--- + +Fix themeing of code-blocks diff --git a/packages/myst-to-react/src/code.tsx b/packages/myst-to-react/src/code.tsx index e7757a40..699fdaaf 100644 --- a/packages/myst-to-react/src/code.tsx +++ b/packages/myst-to-react/src/code.tsx @@ -1,12 +1,11 @@ import type { NodeRenderer } from '@myst-theme/providers'; -import { useThemeSwitcher } from '@myst-theme/providers'; import { LightAsync as SyntaxHighlighter } from 'react-syntax-highlighter'; -import light from 'react-syntax-highlighter/dist/esm/styles/hljs/xcode.js'; -import dark from 'react-syntax-highlighter/dist/esm/styles/hljs/vs2015.js'; import { DocumentIcon } from '@heroicons/react/24/outline'; import classNames from 'classnames'; import { CopyIcon } from './components/index.js'; import { MyST } from './MyST.js'; +import { useMemo } from 'react'; +import type { ComponentProps } from 'react'; type Props = { value: string; @@ -32,8 +31,9 @@ function normalizeLanguage(lang?: string): string | undefined { } } +type HighlightPropsType = ComponentProps; + export function CodeBlock(props: Props) { - const { isLight } = useThemeSwitcher(); const { value, lang, @@ -48,7 +48,39 @@ export function CodeBlock(props: Props) { background, border, } = props; - const highlightLines = new Set(emphasizeLines); + const highlighterProps: Omit = useMemo(() => { + const highlightLines = new Set(emphasizeLines); + return { + language: normalizeLanguage(lang), + startingLineNumber, + showLineNumbers, + useInlineStyles: true, + wrapLines: true, + lineNumberContainerStyle: { + // This stops page content shifts + display: 'inline-block', + float: 'left', + minWidth: '1.25em', + paddingRight: '1em', + textAlign: 'right', + userSelect: 'none', + borderLeft: '4px solid transparent', + }, + lineProps: (line: number | boolean) => { + if (typeof line === 'boolean') return {}; + return highlightLines.has(line) + ? ({ + 'data-line-number': `${line}`, + 'data-highlight': 'true', + } as any) + : ({ 'data-line-number': `${line}` } as any); + }, + customStyle: { + backgroundColor: 'unset', + }, + }; + }, [emphasizeLines]); + return (
)} - { - if (typeof line === 'boolean') return {}; - return highlightLines.has(line) - ? ({ - 'data-line-number': `${line}`, - 'data-highlight': 'true', - } as any) - : ({ 'data-line-number': `${line}` } as any); - }} - customStyle={{ padding: '0.8rem' }} - > + {value} {showCopy && ( diff --git a/styles/app.css b/styles/app.css index ab58897c..a1168257 100644 --- a/styles/app.css +++ b/styles/app.css @@ -5,6 +5,8 @@ @import './figures.css'; @import './text-spacers.css'; @import './code-highlight.css'; +@import './code-highlight-dark.css'; +@import './code-highlight-light.css'; @import './math.css'; @import './cross-references.css'; @import './block-styles.css'; diff --git a/styles/code-highlight-dark.css b/styles/code-highlight-dark.css new file mode 100644 index 00000000..134cfe36 --- /dev/null +++ b/styles/code-highlight-dark.css @@ -0,0 +1,146 @@ +/* +BSD 3-Clause License + +Copyright (c) 2006, Ivan Sagalaev. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Visual Studio 2015 dark style +Author: Nicolas LLOBERA +*/ + +.dark .hljs { + background: #1e1e1e !important; + color: #dcdcdc; +} + +.dark .hljs-keyword, +.dark .hljs-literal, +.dark .hljs-symbol, +.dark .hljs-name { + color: #569cd6; +} +.dark .hljs-link { + color: #569cd6; + text-decoration: underline; +} + +.dark .hljs-built_in, +.dark .hljs-type { + color: #4ec9b0; +} + +.dark .hljs-number, +.dark .hljs-class { + color: #b8d7a3; +} + +.dark .hljs-string, +.dark .hljs-meta .hljs-string { + color: #d69d85; +} + +.dark .hljs-regexp, +.dark .hljs-template-tag { + color: #9a5334; +} + +.dark .hljs-subst, +.dark .hljs-function, +.dark .hljs-title, +.dark .hljs-params, +.dark .hljs-formula { + color: #dcdcdc; +} + +.dark .hljs-comment, +.dark .hljs-quote { + color: #57a64a; + font-style: italic; +} + +.dark .hljs-doctag { + color: #608b4e; +} + +.dark .hljs-meta, +.dark .hljs-meta .hljs-keyword, +.dark .hljs-tag { + color: #9b9b9b; +} + +.dark .hljs-variable, +.dark .hljs-template-variable { + color: #bd63c5; +} + +.dark .hljs-attr, +.dark .hljs-attribute { + color: #9cdcfe; +} + +.dark .hljs-section { + color: gold; +} + +.dark .hljs-emphasis { + font-style: italic; +} + +.dark .hljs-strong { + font-weight: bold; +} + +/*.hljs-code { + font-family:'Monospace'; +}*/ + +.dark .hljs-bullet, +.dark .hljs-selector-tag, +.dark .hljs-selector-id, +.dark .hljs-selector-class, +.dark .hljs-selector-attr, +.dark .hljs-selector-pseudo { + color: #d7ba7d; +} + +.dark .hljs-addition { + background-color: #144212; + display: inline-block; + width: 100%; +} + +.dark .hljs-deletion { + background-color: #600; + display: inline-block; + width: 100%; +} + +.dark .hljs-code { + color: unset; +} diff --git a/styles/code-highlight-light.css b/styles/code-highlight-light.css new file mode 100644 index 00000000..2809c21b --- /dev/null +++ b/styles/code-highlight-light.css @@ -0,0 +1,124 @@ +/* +BSD 3-Clause License + +Copyright (c) 2006, Ivan Sagalaev. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +XCode style (c) Angel Garcia +*/ + +/* Gray DOCTYPE selectors like WebKit */ +.xml .hljs-meta { + color: #c0c0c0; + background: transparent; +} + +.hljs-comment, +.hljs-quote { + color: #007400; +} + +.hljs-tag, +.hljs-attribute, +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-name { + color: #aa0d91; +} + +.hljs-variable, +.hljs-template-variable { + color: #3f6e74; +} + +.hljs-code, +.hljs-string, +.hljs-meta .hljs-string { + color: #c41a16; +} + +.hljs-regexp, +.hljs-link { + color: #0e0eff; +} + +.hljs-title, +.hljs-symbol, +.hljs-bullet, +.hljs-number { + color: #1c00cf; +} + +.hljs-section, +.hljs-meta { + color: #643820; +} + +.hljs-title.class_, +.hljs-class .hljs-title, +.hljs-type, +.hljs-built_in, +.hljs-params { + color: #5c2699; +} + +.hljs-attr { + color: #836c28; +} + +.hljs-subst { + color: #000; +} + +.hljs-formula { + background-color: #eee; + font-style: italic; +} + +.hljs-addition { + background-color: #baeeba; +} + +.hljs-deletion { + background-color: #ffc8bd; +} + +.hljs-selector-id, +.hljs-selector-class { + color: #9b703f; +} + +.hljs-doctag, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +}