-
-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ad3bd79
commit 2836e47
Showing
9 changed files
with
250 additions
and
109 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
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,32 @@ | ||
declare module '@uiw/react-markdown-preview/nohighlight' { | ||
import React from 'react'; | ||
import { Options } from 'react-markdown'; | ||
import { PluggableList } from 'unified'; | ||
import { RehypeRewriteOptions } from 'rehype-rewrite'; | ||
export interface MarkdownPreviewProps extends Omit<Options, 'children'> { | ||
prefixCls?: string; | ||
className?: string; | ||
source?: string; | ||
disableCopy?: boolean; | ||
style?: React.CSSProperties; | ||
pluginsFilter?: (type: 'rehype' | 'remark', plugin: PluggableList) => PluggableList; | ||
wrapperElement?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & { | ||
'data-color-mode'?: 'light' | 'dark'; | ||
}; | ||
/** | ||
* Please use wrapperElement, Will be removed in v5 release. | ||
* @deprecated | ||
*/ | ||
warpperElement?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & { | ||
'data-color-mode'?: 'light' | 'dark'; | ||
}; | ||
onScroll?: (e: React.UIEvent<HTMLDivElement>) => void; | ||
onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void; | ||
rehypeRewrite?: RehypeRewriteOptions['rewrite']; | ||
} | ||
export interface MarkdownPreviewRef extends MarkdownPreviewProps { | ||
mdp: React.RefObject<HTMLDivElement>; | ||
} | ||
const _default: React.ForwardRefExoticComponent<MarkdownPreviewProps & React.RefAttributes<MarkdownPreviewRef>>; | ||
export default _default; | ||
} |
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
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,117 +1,20 @@ | ||
import React, { useImperativeHandle } from 'react'; | ||
import ReactMarkdown, { Options } from 'react-markdown'; | ||
import { Element } from 'hast'; | ||
import React from 'react'; | ||
import MarkdownPreview, { type MarkdownPreviewProps, type MarkdownPreviewRef } from './preview'; | ||
import rehypePrism from 'rehype-prism-plus'; | ||
import { PluggableList } from 'unified'; | ||
import gfm from 'remark-gfm'; | ||
import raw from 'rehype-raw'; | ||
import slug from 'rehype-slug'; | ||
import headings from 'rehype-autolink-headings'; | ||
import rehypeRewrite from 'rehype-rewrite'; | ||
import rehypeAttrs from 'rehype-attr'; | ||
import rehypeIgnore from 'rehype-ignore'; | ||
import rehypePrism from 'rehype-prism-plus'; | ||
import rehypeRewrite, { getCodeString, RehypeRewriteOptions } from 'rehype-rewrite'; | ||
import { octiconLink } from './nodes/octiconLink'; | ||
import { copyElement } from './nodes/copy'; | ||
import { useCopied } from './plugins/useCopied'; | ||
import './styles/markdown.less'; | ||
|
||
import { reservedMeta } from './plugins/reservedMeta'; | ||
|
||
export interface MarkdownPreviewProps extends Omit<Options, 'children'> { | ||
prefixCls?: string; | ||
className?: string; | ||
source?: string; | ||
disableCopy?: boolean; | ||
style?: React.CSSProperties; | ||
pluginsFilter?: (type: 'rehype' | 'remark', plugin: PluggableList) => PluggableList; | ||
wrapperElement?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & { | ||
'data-color-mode'?: 'light' | 'dark'; | ||
}; | ||
/** | ||
* Please use wrapperElement, Will be removed in v5 release. | ||
* @deprecated | ||
*/ | ||
warpperElement?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & { | ||
'data-color-mode'?: 'light' | 'dark'; | ||
}; | ||
onScroll?: (e: React.UIEvent<HTMLDivElement>) => void; | ||
onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void; | ||
rehypeRewrite?: RehypeRewriteOptions['rewrite']; | ||
} | ||
|
||
export interface MarkdownPreviewRef extends MarkdownPreviewProps { | ||
mdp: React.RefObject<HTMLDivElement>; | ||
} | ||
import { rehypeRewriteHandle, defaultRehypePlugins } from './rehypePlugins'; | ||
|
||
export default React.forwardRef<MarkdownPreviewRef, MarkdownPreviewProps>((props, ref) => { | ||
const { | ||
prefixCls = 'wmde-markdown wmde-markdown-color', | ||
className, | ||
source, | ||
style, | ||
disableCopy = false, | ||
skipHtml = true, | ||
onScroll, | ||
onMouseOver, | ||
pluginsFilter, | ||
rehypeRewrite: rewrite, | ||
wrapperElement = {}, | ||
warpperElement = {}, | ||
...other | ||
} = props; | ||
const mdp = React.useRef<HTMLDivElement>(null); | ||
useImperativeHandle(ref, () => ({ ...props, mdp }), [mdp, props]); | ||
const cls = `${prefixCls || ''} ${className || ''}`; | ||
useCopied(mdp); | ||
|
||
const rehypeRewriteHandle: RehypeRewriteOptions['rewrite'] = (node, index, parent) => { | ||
if (node.type === 'element' && parent && parent.type === 'root' && /h(1|2|3|4|5|6)/.test(node.tagName)) { | ||
const child = node.children && (node.children[0] as Element); | ||
if (child && child.properties && child.properties.ariaHidden === 'true') { | ||
child.properties = { class: 'anchor', ...child.properties }; | ||
child.children = [octiconLink]; | ||
} | ||
} | ||
if (node.type === 'element' && node.tagName === 'pre' && !disableCopy) { | ||
const code = getCodeString(node.children); | ||
node.children.push(copyElement(code)); | ||
} | ||
rewrite && rewrite(node, index, parent); | ||
}; | ||
|
||
const rehypePlugins: PluggableList = [ | ||
reservedMeta, | ||
[rehypePrism, { ignoreMissing: true }], | ||
slug, | ||
headings, | ||
rehypeIgnore, | ||
[rehypeRewrite, { rewrite: rehypeRewriteHandle }], | ||
...defaultRehypePlugins, | ||
[rehypeRewrite, { rewrite: rehypeRewriteHandle(props.disableCopy ?? false, props.rehypeRewrite) }], | ||
[rehypeAttrs, { properties: 'attr' }], | ||
...(other.rehypePlugins || []), | ||
...(props.rehypePlugins || []), | ||
]; | ||
const customProps: MarkdownPreviewProps = { | ||
allowElement: (element, index, parent) => { | ||
if (other.allowElement) { | ||
return other.allowElement(element, index, parent); | ||
} | ||
return /^[A-Za-z0-9]+$/.test(element.tagName); | ||
}, | ||
}; | ||
if (skipHtml) { | ||
rehypePlugins.push(raw); | ||
} | ||
const remarkPlugins = [...(other.remarkPlugins || []), gfm]; | ||
const wrapperProps = { ...warpperElement, ...wrapperElement }; | ||
return ( | ||
<div ref={mdp} onScroll={onScroll} onMouseOver={onMouseOver} {...wrapperProps} className={cls} style={style}> | ||
<ReactMarkdown | ||
{...customProps} | ||
{...other} | ||
skipHtml={skipHtml} | ||
rehypePlugins={pluginsFilter ? pluginsFilter('rehype', rehypePlugins) : rehypePlugins} | ||
remarkPlugins={pluginsFilter ? pluginsFilter('remark', remarkPlugins) : remarkPlugins} | ||
children={source || ''} | ||
/> | ||
</div> | ||
); | ||
return <MarkdownPreview {...props} rehypePlugins={rehypePlugins} ref={ref} />; | ||
}); |
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,18 @@ | ||
import React from 'react'; | ||
import MarkdownPreview, { type MarkdownPreviewProps, type MarkdownPreviewRef } from './preview'; | ||
import { PluggableList } from 'unified'; | ||
import rehypeRewrite from 'rehype-rewrite'; | ||
import { reservedMeta } from './plugins/reservedMeta'; | ||
import rehypeAttrs from 'rehype-attr'; | ||
import { rehypeRewriteHandle, defaultRehypePlugins } from './rehypePlugins'; | ||
|
||
export default React.forwardRef<MarkdownPreviewRef, MarkdownPreviewProps>((props, ref) => { | ||
const rehypePlugins: PluggableList = [ | ||
reservedMeta, | ||
...defaultRehypePlugins, | ||
[rehypeRewrite, { rewrite: rehypeRewriteHandle(props.disableCopy ?? false, props.rehypeRewrite) }], | ||
[rehypeAttrs, { properties: 'attr' }], | ||
...(props.rehypePlugins || []), | ||
]; | ||
return <MarkdownPreview {...props} rehypePlugins={rehypePlugins} ref={ref} />; | ||
}); |
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,83 @@ | ||
import React, { useImperativeHandle } from 'react'; | ||
import ReactMarkdown, { Options } from 'react-markdown'; | ||
import { PluggableList } from 'unified'; | ||
import gfm from 'remark-gfm'; | ||
import raw from 'rehype-raw'; | ||
import { type RehypeRewriteOptions } from 'rehype-rewrite'; | ||
import { useCopied } from './plugins/useCopied'; | ||
import './styles/markdown.less'; | ||
|
||
export interface MarkdownPreviewProps extends Omit<Options, 'children'> { | ||
prefixCls?: string; | ||
className?: string; | ||
source?: string; | ||
disableCopy?: boolean; | ||
style?: React.CSSProperties; | ||
pluginsFilter?: (type: 'rehype' | 'remark', plugin: PluggableList) => PluggableList; | ||
wrapperElement?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & { | ||
'data-color-mode'?: 'light' | 'dark'; | ||
}; | ||
/** | ||
* Please use wrapperElement, Will be removed in v5 release. | ||
* @deprecated | ||
*/ | ||
warpperElement?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & { | ||
'data-color-mode'?: 'light' | 'dark'; | ||
}; | ||
onScroll?: (e: React.UIEvent<HTMLDivElement>) => void; | ||
onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void; | ||
rehypeRewrite?: RehypeRewriteOptions['rewrite']; | ||
} | ||
|
||
export interface MarkdownPreviewRef extends MarkdownPreviewProps { | ||
mdp: React.RefObject<HTMLDivElement>; | ||
} | ||
|
||
export default React.forwardRef<MarkdownPreviewRef, MarkdownPreviewProps>((props, ref) => { | ||
const { | ||
prefixCls = 'wmde-markdown wmde-markdown-color', | ||
className, | ||
source, | ||
style, | ||
disableCopy = false, | ||
skipHtml = true, | ||
onScroll, | ||
onMouseOver, | ||
pluginsFilter, | ||
rehypeRewrite: rewrite, | ||
wrapperElement = {}, | ||
warpperElement = {}, | ||
...other | ||
} = props; | ||
const mdp = React.useRef<HTMLDivElement>(null); | ||
useImperativeHandle(ref, () => ({ ...props, mdp }), [mdp, props]); | ||
const cls = `${prefixCls || ''} ${className || ''}`; | ||
useCopied(mdp); | ||
|
||
const rehypePlugins: PluggableList = [...(other.rehypePlugins || [])]; | ||
const customProps: MarkdownPreviewProps = { | ||
allowElement: (element, index, parent) => { | ||
if (other.allowElement) { | ||
return other.allowElement(element, index, parent); | ||
} | ||
return /^[A-Za-z0-9]+$/.test(element.tagName); | ||
}, | ||
}; | ||
if (skipHtml) { | ||
rehypePlugins.push(raw); | ||
} | ||
const remarkPlugins = [...(other.remarkPlugins || []), gfm]; | ||
const wrapperProps = { ...warpperElement, ...wrapperElement }; | ||
return ( | ||
<div ref={mdp} onScroll={onScroll} onMouseOver={onMouseOver} {...wrapperProps} className={cls} style={style}> | ||
<ReactMarkdown | ||
{...customProps} | ||
{...other} | ||
skipHtml={skipHtml} | ||
rehypePlugins={pluginsFilter ? pluginsFilter('rehype', rehypePlugins) : rehypePlugins} | ||
remarkPlugins={pluginsFilter ? pluginsFilter('remark', remarkPlugins) : remarkPlugins} | ||
children={source || ''} | ||
/> | ||
</div> | ||
); | ||
}); |
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,27 @@ | ||
import { PluggableList } from 'unified'; | ||
import slug from 'rehype-slug'; | ||
import headings from 'rehype-autolink-headings'; | ||
import rehypeIgnore from 'rehype-ignore'; | ||
import { getCodeString, RehypeRewriteOptions } from 'rehype-rewrite'; | ||
import { octiconLink } from './nodes/octiconLink'; | ||
import { copyElement } from './nodes/copy'; | ||
import { Root, Element, RootContent } from 'hast'; | ||
|
||
export const rehypeRewriteHandle = | ||
(disableCopy: boolean, rewrite?: RehypeRewriteOptions['rewrite']) => | ||
(node: Root | RootContent, index: number | null, parent: Root | Element | null) => { | ||
if (node.type === 'element' && parent && parent.type === 'root' && /h(1|2|3|4|5|6)/.test(node.tagName)) { | ||
const child = node.children && (node.children[0] as Element); | ||
if (child && child.properties && child.properties.ariaHidden === 'true') { | ||
child.properties = { class: 'anchor', ...child.properties }; | ||
child.children = [octiconLink]; | ||
} | ||
} | ||
if (node.type === 'element' && node.tagName === 'pre' && !disableCopy) { | ||
const code = getCodeString(node.children); | ||
node.children.push(copyElement(code)); | ||
} | ||
rewrite && rewrite(node, index, parent); | ||
}; | ||
|
||
export const defaultRehypePlugins: PluggableList = [slug, headings, rehypeIgnore]; |
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
Oops, something went wrong.