Skip to content

Commit

Permalink
feat(ai-help): add syntax highlighting for code examples (#9510)
Browse files Browse the repository at this point in the history
Uses prism for syntax highlighting.

Co-authored-by: Claas Augner <caugner@mozilla.com>
  • Loading branch information
fiji-flo and caugner authored Aug 18, 2023
1 parent 59ab4be commit e9f49cd
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
9 changes: 7 additions & 2 deletions client/src/plus/ai-help/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,11 @@
&.status-pending .ai-help-message-content,
&.status-in-progress .ai-help-message-content {
&.empty::after,
> :not(ol):not(ul):not(pre):last-child:after,
> :not(ol):not(ul):not(pre):not(div.code-example):last-child:after,
> ol:last-child li:last-child:after,
> pre:last-child code:after,
> ul:last-child li:last-child:after {
> ul:last-child li:last-child:after,
> div.code-example:last-child pre:last-child code:after {
animation: blink 1s steps(5, start) infinite;
content: "";
margin-left: 0.25rem;
Expand Down Expand Up @@ -270,6 +271,10 @@
&:last-child {
margin-bottom: 0;
}

&.example-header {
margin-bottom: 0;
}
}

ul,
Expand Down
61 changes: 60 additions & 1 deletion client/src/plus/ai-help/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { MutableRefObject, useEffect, useRef, useState } from "react";
import Prism from "prismjs";
import {
Children,
MutableRefObject,
ReactElement,
useEffect,
useRef,
useState,
} from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

Expand Down Expand Up @@ -220,6 +228,57 @@ export function AIHelpInner() {
// eslint-disable-next-line jsx-a11y/anchor-has-content
return <a {...props} />;
},
pre: ({ node, className, children, ...props }) => {
const code = Children.toArray(children)
.map(
(child) =>
/language-(\w+)/.exec(
(child as ReactElement)?.props?.className ||
""
)?.[1]
)
.find(Boolean);

if (!code) {
return (
<pre {...props} className={className}>
{children}
</pre>
);
}
return (
<div className="code-example">
<p className="example-header">
<span className="language-name">{code}</span>
</p>
<pre className={`brush: ${code}`}>
{children}
</pre>
</div>
);
},
code: ({ inline, className, children, ...props }) => {
const match = /language-(\w+)/.exec(
className || ""
);
const lang = Prism.languages[match?.[1]];
return !inline && lang ? (
<code
{...props}
className={className}
dangerouslySetInnerHTML={{
__html: Prism.highlight(
String(children),
lang
),
}}
/>
) : (
<code {...props} className={className}>
{children}
</code>
);
},
}}
>
{message.content.replace(SORRY_BACKEND, SORRY_FRONTEND)}
Expand Down

0 comments on commit e9f49cd

Please sign in to comment.