forked from voxel51/fiftyone
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
markdown support for operator io label, description, and caption
- Loading branch information
Showing
3 changed files
with
183 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
app/packages/core/src/plugins/SchemaIO/components/Markdown.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
import { CopyButton, useTheme } from "@fiftyone/components"; | ||
import { | ||
Box, | ||
Link, | ||
Paper, | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableContainer, | ||
TableHead, | ||
TableRow, | ||
Typography, | ||
} from "@mui/material"; | ||
import React from "react"; | ||
import { useHover } from "react-laag"; | ||
import ReactMarkdown from "react-markdown"; | ||
import { ReactMarkdownOptions } from "react-markdown/lib/react-markdown"; | ||
import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; | ||
import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript"; | ||
import python from "react-syntax-highlighter/dist/esm/languages/hljs/python"; | ||
import ts from "react-syntax-highlighter/dist/esm/languages/hljs/typescript"; | ||
import tomorrow from "react-syntax-highlighter/dist/esm/styles/hljs/tomorrow"; | ||
import vs2015 from "react-syntax-highlighter/dist/esm/styles/hljs/vs2015"; | ||
import remarkGfm from "remark-gfm"; | ||
import styled from "styled-components"; | ||
|
||
SyntaxHighlighter.registerLanguage("javascript", js); | ||
SyntaxHighlighter.registerLanguage("typescript", ts); | ||
SyntaxHighlighter.registerLanguage("python", python); | ||
|
||
const InlineCode = styled.span` | ||
background: ${({ theme }) => theme.background.level1}; | ||
color: ${({ theme }) => theme.voxel[500]}; | ||
border-radius: 3px; | ||
padding: 0.2em 0.4em; | ||
font-size: 85%; | ||
font-family: Roboto Mono, monospace; | ||
`; | ||
|
||
const CodeContainer = styled(Box)` | ||
border: 1px solid ${({ theme }) => theme.background.level1}; | ||
pre { | ||
margin: 0; | ||
padding: 1rem !important; | ||
} | ||
border-radius: 3px; | ||
`; | ||
|
||
const CodeHeader = styled.div` | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
padding: 0rem 1rem; | ||
border-bottom: 1px solid ${({ theme }) => theme.background.level1}; | ||
background: ${({ theme }) => theme.background.level2}; | ||
`; | ||
|
||
const componentsMap = { | ||
a({ children, ...props }) { | ||
if ( | ||
props.href && | ||
props.href.startsWith("http") && | ||
!props.href.includes(window.location.host) | ||
) { | ||
props = { | ||
...props, | ||
target: "_blank", | ||
}; | ||
} | ||
|
||
return <Link {...props}>{children}</Link>; | ||
}, | ||
table({ children }) { | ||
return ( | ||
<TableContainer component={Paper}> | ||
<Table>{children}</Table> | ||
</TableContainer> | ||
); | ||
}, | ||
td: TableCell, | ||
th: TableCell, | ||
tbody: TableBody, | ||
thead: TableHead, | ||
tr: TableRow, | ||
code({ node, inline, className, children, ...props }) { | ||
const theme = useTheme(); | ||
const [hovered, hoverProps] = useHover(); | ||
const isDarkMode = theme.mode === "dark"; | ||
const highlightTheme = isDarkMode ? vs2015 : tomorrow; | ||
const match = /language-(\w+)/.exec(className || ""); | ||
let language = match ? match[1] : "text"; | ||
if (language === "js") { | ||
language = "javascript"; | ||
} | ||
if (language === "ts") { | ||
language = "typescript"; | ||
} | ||
if (language === "py") { | ||
language = "python"; | ||
} | ||
return !inline && match ? ( | ||
<CodeContainer {...hoverProps}> | ||
<CodeHeader> | ||
<Typography component="span">{language}</Typography> | ||
<CopyButton | ||
text={children} | ||
sx={{ visibility: hovered ? "visible" : "hidden" }} | ||
/> | ||
</CodeHeader> | ||
|
||
<SyntaxHighlighter language={language} style={highlightTheme}> | ||
{children} | ||
</SyntaxHighlighter> | ||
</CodeContainer> | ||
) : ( | ||
<InlineCode className={className} {...props}> | ||
{children} | ||
</InlineCode> | ||
); | ||
}, | ||
p: ({ children, ...props }) => <Typography>{children}</Typography>, | ||
h1: ({ children, ...props }) => ( | ||
<Typography variant="h1" {...props}> | ||
{children} | ||
</Typography> | ||
), | ||
h2: ({ children, ...props }) => ( | ||
<Typography variant="h2" {...props}> | ||
{children} | ||
</Typography> | ||
), | ||
h3: ({ children, ...props }) => ( | ||
<Typography variant="h3" {...props}> | ||
{children} | ||
</Typography> | ||
), | ||
h4: ({ children, ...props }) => ( | ||
<Typography variant="h4" {...props}> | ||
{children} | ||
</Typography> | ||
), | ||
h5: ({ children, ...props }) => ( | ||
<Typography variant="h5" {...props}> | ||
{children} | ||
</Typography> | ||
), | ||
h6: ({ children, ...props }) => ( | ||
<Typography variant="h6" {...props}> | ||
{children} | ||
</Typography> | ||
), | ||
}; | ||
|
||
export default function Markdown(props: ReactMarkdownOptions) { | ||
const { children, ...otherProps } = props; | ||
|
||
return ( | ||
<ReactMarkdown | ||
{...otherProps} | ||
components={componentsMap} | ||
remarkPlugins={[remarkGfm]} | ||
> | ||
{children} | ||
</ReactMarkdown> | ||
); | ||
} |
135 changes: 7 additions & 128 deletions
135
app/packages/core/src/plugins/SchemaIO/components/MarkdownView.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,139 +1,18 @@ | ||
import { CopyButton, useTheme } from "@fiftyone/components"; | ||
import { | ||
Box, | ||
Link, | ||
Typography, | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableContainer, | ||
TableHead, | ||
TableRow, | ||
Paper, | ||
} from "@mui/material"; | ||
import { useHover } from "react-laag"; | ||
import ReactMarkdown from "react-markdown"; | ||
import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; | ||
import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript"; | ||
import python from "react-syntax-highlighter/dist/esm/languages/hljs/python"; | ||
import ts from "react-syntax-highlighter/dist/esm/languages/hljs/typescript"; | ||
import tomorrow from "react-syntax-highlighter/dist/esm/styles/hljs/tomorrow"; | ||
import vs2015 from "react-syntax-highlighter/dist/esm/styles/hljs/vs2015"; | ||
import styled from "styled-components"; | ||
import { Box } from "@mui/material"; | ||
import React from "react"; | ||
import { HeaderView } from "."; | ||
import { getComponentProps } from "../utils"; | ||
import remarkGfm from "remark-gfm"; | ||
import React from "react"; | ||
|
||
SyntaxHighlighter.registerLanguage("javascript", js); | ||
SyntaxHighlighter.registerLanguage("typescript", ts); | ||
SyntaxHighlighter.registerLanguage("python", python); | ||
|
||
const InlineCode = styled.span` | ||
background: ${({ theme }) => theme.background.level1}; | ||
color: ${({ theme }) => theme.voxel[500]}; | ||
border-radius: 3px; | ||
padding: 0.2em 0.4em; | ||
font-size: 85%; | ||
font-family: Roboto Mono, monospace; | ||
`; | ||
|
||
const CodeContainer = styled(Box)` | ||
border: 1px solid ${({ theme }) => theme.background.level1}; | ||
pre { | ||
margin: 0; | ||
padding: 1rem !important; | ||
} | ||
border-radius: 3px; | ||
`; | ||
|
||
const CodeHeader = styled.div` | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
padding: 0rem 1rem; | ||
border-bottom: 1px solid ${({ theme }) => theme.background.level1}; | ||
background: ${({ theme }) => theme.background.level2}; | ||
`; | ||
|
||
const componentsMap = { | ||
a({ children, ...props }) { | ||
if ( | ||
props.href && | ||
props.href.startsWith("http") && | ||
!props.href.includes(window.location.host) | ||
) { | ||
props = { | ||
...props, | ||
target: "_blank", | ||
}; | ||
} | ||
|
||
return <Link {...props}>{children}</Link>; | ||
}, | ||
table({ children }) { | ||
return ( | ||
<TableContainer component={Paper}> | ||
<Table>{children}</Table> | ||
</TableContainer> | ||
); | ||
}, | ||
td: TableCell, | ||
th: TableCell, | ||
tbody: TableBody, | ||
thead: TableHead, | ||
tr: TableRow, | ||
code({ node, inline, className, children, ...props }) { | ||
const theme = useTheme(); | ||
const [hovered, hoverProps] = useHover(); | ||
const isDarkMode = theme.mode === "dark"; | ||
const highlightTheme = isDarkMode ? vs2015 : tomorrow; | ||
const match = /language-(\w+)/.exec(className || ""); | ||
let language = match ? match[1] : "text"; | ||
if (language === "js") { | ||
language = "javascript"; | ||
} | ||
if (language === "ts") { | ||
language = "typescript"; | ||
} | ||
if (language === "py") { | ||
language = "python"; | ||
} | ||
return !inline && match ? ( | ||
<CodeContainer {...hoverProps}> | ||
<CodeHeader> | ||
<Typography component="span">{language}</Typography> | ||
<CopyButton | ||
text={children} | ||
sx={{ visibility: hovered ? "visible" : "hidden" }} | ||
/> | ||
</CodeHeader> | ||
|
||
<SyntaxHighlighter language={language} style={highlightTheme}> | ||
{children} | ||
</SyntaxHighlighter> | ||
</CodeContainer> | ||
) : ( | ||
<InlineCode className={className} {...props}> | ||
{children} | ||
</InlineCode> | ||
); | ||
}, | ||
}; | ||
import Markdown from "./Markdown"; | ||
|
||
export default function MarkdownView(props) { | ||
const { data } = props; | ||
const { data, schema } = props; | ||
|
||
return ( | ||
<Box {...getComponentProps(props, "container")}> | ||
<HeaderView {...props} nested /> | ||
<ReactMarkdown | ||
components={componentsMap} | ||
remarkPlugins={[remarkGfm]} | ||
{...getComponentProps(props, "markdown")} | ||
> | ||
{data} | ||
</ReactMarkdown> | ||
<Markdown {...getComponentProps(props, "markdown")}> | ||
{data ?? schema?.default} | ||
</Markdown> | ||
</Box> | ||
); | ||
} |