Skip to content

Commit

Permalink
Fix: syntax highlighting auto detecting lang (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
peppescg authored Jan 7, 2025
1 parent 92d93ee commit 5c40ead
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 325 deletions.
11 changes: 0 additions & 11 deletions docker-compose.yml

This file was deleted.

20 changes: 0 additions & 20 deletions dockerfile

This file was deleted.

28 changes: 0 additions & 28 deletions nginx.conf

This file was deleted.

28 changes: 24 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"highlight.js": "^11.11.1",
"lucide-react": "^0.462.0",
"prismjs": "^1.29.0",
"react": "19.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function Chat() {
<div className="w-[calc(100vw-18rem)]">
<ChatMessageList>
{(chat?.question_answers ?? []).map(({ question, answer }, index) => (
<div key={index} className="flex flex-col w-full h-full p-4 gap-6">
<div key={index} className="flex flex-col w-full h-full gap-6">
<ChatBubble variant="sent">
<ChatBubbleAvatar fallback="User" className="w-14" />
<ChatBubbleMessage variant="sent" className="bg-zinc-700">
Expand Down
10 changes: 6 additions & 4 deletions src/components/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,15 @@ const wrapObjectOutput = (input: string | MaliciousPkgType | null) => {
const isObject = /\{"/.test(input);
if (isObject) {
return (
<pre className="max-h-40 overflow-y-auto whitespace-pre-wrap bg-gray-100 p-2">
<pre className="max-h-40 overflow-y-auto whitespace-pre-wrap bg-secondary p-2">
<code>{input}</code>
</pre>
);
}
return (
<Markdown className="bg-gray-100 overflow-auto w-fit p-1">{input}</Markdown>
<Markdown className="bg-secondary rounded-lg overflow-auto w-fit p-1">
{input}
</Markdown>
);
};

Expand Down Expand Up @@ -119,7 +121,7 @@ export function Dashboard() {
setSearchParams(searchParams);
toggleMaliciousFilter(isChecked);
},
[setSearchParams, setSearch, searchParams, toggleMaliciousFilter]
[setSearchParams, setSearch, searchParams, toggleMaliciousFilter],
);

const handleSearch = useCallback(
Expand All @@ -135,7 +137,7 @@ export function Dashboard() {
}
setSearchParams(searchParams);
},
[searchParams, setSearch, setSearchParams, toggleMaliciousFilter]
[searchParams, setSearch, setSearchParams, toggleMaliciousFilter],
);

return (
Expand Down
109 changes: 54 additions & 55 deletions src/components/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@ import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism";
import { cn } from "@/lib/utils";
import { CopyToClipboard } from "./CopyToClipboard";
import hljs from "highlight.js";

const LANGUAGES_SUBSET_DETECTION = [
"c",
"cpp",
"csharp",
"css",
"elixir",
"go",
"groovy",
"haskell",
"html",
"java",
"javascript",
"json",
"kotlin",
"markdown",
"php",
"python",
"ruby",
"rust",
"scala",
"sql",
"typescript",
"yaml",
];

interface Props {
children: string;
Expand All @@ -12,85 +38,58 @@ interface Props {

const customStyle = {
...oneDark,
'code[class*="language-"]': {
...oneDark['code[class*="language-"]'],
background: "none",
},
'pre[class*="language-"]': {
...oneDark['pre[class*="language-"]'],
whiteSpace: "pre-wrap",
background: "#1a1b26",
padding: "1.5rem",
borderRadius: "0.5rem",
margin: "1.5rem 0",
fontSize: "10px",
width: "80%", // Ensure the block takes full width
width: "100%",
position: "relative",
boxSizing: "border-box",
},
};

export function Markdown({ children, className = "" }: Props) {
SyntaxHighlighter.supportedLanguages = LANGUAGES_SUBSET_DETECTION;
return (
<ReactMarkdown
components={{
/* eslint-disable @typescript-eslint/no-explicit-any */
code({ className, children, ...props }: any) {
code({ className, children, ...props }) {
const detectedLanguage =
hljs.highlightAuto(children, LANGUAGES_SUBSET_DETECTION).language ??
"plaintext";
const match = /language-(\w+)/.exec(className || "");
const inline = !match;
return !inline ? (
<div className="relative group w-full ml-0 px-4">
const language = match ? match[1] : detectedLanguage;
return (
<div className="relative group w-full ml-0 my-4">
<SyntaxHighlighter
style={{
...customStyle,
'pre[class*="language-"]': {
...oneDark['pre[class*="language-"]'],
background: "#1a1b26",
fontSize: "10x",
whiteSpace: "pre-wrap",
padding: "1.5rem",
borderRadius: "0.5rem",
margin: "1.5rem 0",
position: "relative", // Critical for clipboard positioning
width: "100%", // Ensure full width of parent container
boxSizing: "border-box", // Prevent padding overflow
},
}}
language={match[1]}
style={customStyle}
supportedLanguages={LANGUAGES_SUBSET_DETECTION}
language={language}
PreTag="div"
className="rounded-lg overflow-hidden shadow-lg text-sm"
showLineNumbers={false}
wrapLines={true}
className="rounded-lg overflow-hidden shadow-lg text-sm my-6 whitespace-normal"
wrapLines
{...props}
>
{String(children).replace(/\n$/, "")}
</SyntaxHighlighter>
<CopyToClipboard text={String(children).replace(/\n$/, "")} />
{match && (
<CopyToClipboard text={String(children).replace(/\n$/, "")} />
)}
</div>
) : (
<SyntaxHighlighter
style={{
...customStyle,
'pre[class*="language-"]': {
...oneDark['pre[class*="language-"]'],
fontSize: "10x",
whiteSpace: "pre-wrap",
padding: "1.5rem",
borderRadius: "0.5rem",
margin: "1.5rem 0",
position: "relative", // Critical for clipboard positioning
width: "100%", // Ensure full width of parent container
boxSizing: "border-box", // Prevent padding overflow
},
}}
PreTag="div"
className="rounded-lg overflow-hidden shadow-lg text-sm"
showLineNumbers={false}
wrapLines={true}
{...props}
>
{children}
</SyntaxHighlighter>
);
},
p({ children }) {
return (
<p className={cn("text-gray-600 leading-relaxed mb-4", className)}>
<p
className={cn(
"text-gray-600 leading-relaxed mt-6 mb-3",
className,
)}
>
{children}
</p>
);
Expand Down
Loading

0 comments on commit 5c40ead

Please sign in to comment.