1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-07-16 18:55:30 -04:00

switch to shiki for syntax highlighting

This commit is contained in:
2025-03-15 21:19:57 -04:00
parent bc65285c08
commit 7c4144a1e7
32 changed files with 577 additions and 482 deletions

View File

@@ -0,0 +1,85 @@
figure:has(.highlighted) {
margin: 1em auto;
position: relative;
width: 100%;
background-color: var(--colors-background-header);
}
.highlighted {
display: block;
overflow-x: auto;
padding: 1em;
font-size: 0.9em;
tab-size: 2px;
border: 1px solid var(--colors-kinda-light);
border-radius: 0.6em;
}
.highlighted span {
color: var(--shiki-light);
font-style: var(--shiki-light-font-style);
font-weight: var(--shiki-light-font-weight);
text-decoration: var(--shiki-light-text-decoration);
}
[data-theme="dark"] .highlighted span {
color: var(--shiki-dark);
font-style: var(--shiki-dark-font-style);
font-weight: var(--shiki-dark-font-weight);
text-decoration: var(--shiki-dark-text-decoration);
}
.highlighted[data-line-numbers] {
counter-reset: line;
}
.highlighted[data-line-numbers] > [data-line]::before {
display: inline-block;
width: 1em;
margin-right: 1.5em;
text-align: right;
color: var(--colors-medium-light);
counter-increment: line;
content: counter(line);
user-select: none;
}
.highlighted[data-line-numbers-max-digits="2"] > [data-line]::before {
width: 1.25rem;
}
.highlighted[data-line-numbers-max-digits="3"] > [data-line]::before {
width: 1.75rem;
}
.inline {
padding: 0.2em 0.3em;
font-size: 0.925em;
page-break-inside: avoid;
background-color: var(--colors-background-outer);
border: 1px solid var(--colors-kinda-light);
border-radius: 0.6em;
}
.copyButton {
position: absolute;
top: 0;
right: 0;
height: 3em;
width: 3em;
color: var(--colors-medium-dark);
border: 1px solid var(--colors-kinda-light);
border-top-right-radius: 0.6em;
border-bottom-left-radius: 0.6em;
background-color: var(--colors-background-header);
backdrop-filter: saturate(180%) blur(5px);
}
.copyButton > svg {
vertical-align: middle;
}
.copyButton:hover,
.copyButton:focus-visible {
color: var(--colors-link);
}

View File

@@ -1,38 +1,41 @@
import CodeBlock from "../CodeBlock";
import CodeInline from "../CodeInline";
import clsx from "clsx";
import CopyButton from "../CopyButton";
import type { ComponentPropsWithoutRef } from "react";
import styles from "./Code.module.css";
export type CodeProps = ComponentPropsWithoutRef<"code"> & {
forceBlock?: boolean;
"data-language"?: string;
"data-theme"?: string;
};
// a simple wrapper component that "intelligently" picks between inline code and code blocks (w/ optional syntax
// highlighting & a clipboard button)
const Code = ({ forceBlock, className, children, ...rest }: CodeProps) => {
// detect if this input has already been touched by prism.js via rehype
const classNames = className?.split(" ");
const prismEnabled = classNames?.includes("code-highlight");
if (prismEnabled || forceBlock) {
const Code = ({
"data-language": dataLanguage,
"data-theme": dataTheme, // eslint-disable-line @typescript-eslint/no-unused-vars
className,
children,
...rest
}: CodeProps) => {
// detect if this input has already been touched by shiki via rehype-pretty-code
if (dataLanguage) {
// full multi-line code blocks with copy-to-clipboard button
// automatic if highlighted by prism, otherwise can be forced (rather than inlined) with `forceBlock={true}`
return (
<CodeBlock
highlight={prismEnabled && !classNames?.includes("language-plaintext")}
withCopyButton
className={className}
{...rest}
>
{children}
</CodeBlock>
<>
<CopyButton className={styles.copyButton} source={children} />
<code className={clsx(styles.highlighted, className)} {...rest}>
{children}
</code>
</>
);
}
// simple inline code in paragraphs, headings, etc. (never highlighted)
return (
<CodeInline className={className} {...rest}>
<code className={clsx(styles.inline, className)} {...rest}>
{children}
</CodeInline>
</code>
);
};