Closed codler closed 3 years ago
By default react-markdown supports CommonMark only. However, syntax extensions/plugins can be used to add new syntax features https://github.com/remarkjs/remark/blob/main/doc/plugins.md The particular syntax you are looking for appears to be https://github.com/arobase-che/remark-attr, which can work with react-markdown but needs an update to do so https://github.com/arobase-che/remark-attr/issues/22
For anyone else who runs into this, I got this working with a custom component for my scenario (I needed call-to-action button-links). All buttons that have \ as the first-child [**text here**](... "custom:attribute title text")
are rendered as buttons and their title
text is parsed for custom attribute strings. Highly limited, but worked for me!
// typescript component rendering
import React, { ReactElement } from "react";
import ReactMarkdown from "react-markdown";
import { Components, ReactBaseProps, ReactMarkdownProps } from "react-markdown/src/ast-to-react";
import remarkGfm from "remark-gfm";
import { first, fromPairs } from "lodash";
import { Button } from "@material-ui/core";
const components: Components = {
a: ({
node,
children,
href,
title,
...props
}: ReactBaseProps & ReactMarkdownProps & { href: string; title: string }) => {
// if the first child of the button is a bold element, make this a CTA button
if ((first(children) as ReactElement)?.type === "strong") {
const splitTitle = title.split(' ');
const titleAttrEntries = splitTitle.filter(t => t.includes(':'));
const remainingTitleEntries = splitTitle.filter(t => !t.includes(':'));
const finalTitle = remainingTitleEntries.join(' ');
const titleAttrPairs = titleAttrEntries.map(te => te.split(':'))
const titleAttrs = fromPairs(titleAttrPairs);
return (
<Button variant="contained" href={href} title={finalTitle} {...props} {...titleAttrs}>
{children}
</Button>
);
}
return <a href={href} title={title} children={children} {...props}></a>;
},
};
export function renderMarkdown(markdown: string) {
return (
<ReactMarkdown
plugins={[remarkGfm]}
children={markdown}
components={components}/>
);
}
<!-- markdown -->
[Regular Link](/where_to_go/)
[**CTA Button Link**](/where_to_go/ "color:primary any:attribute things without colons will be treated as the title")
output
@david-sharer Looks like the ReactBaseProps
is deprecated??
{:target="_blank"}
For anyone else who runs into this, I got this working with a custom component for my scenario (I needed call-to-action button-links). All buttons that have \<strong> as the first-child
[**text here**](... "custom:attribute title text")
are rendered as buttons and theirtitle
text is parsed for custom attribute strings. Highly limited, but worked for me!// typescript component rendering import React, { ReactElement } from "react"; import ReactMarkdown from "react-markdown"; import { Components, ReactBaseProps, ReactMarkdownProps } from "react-markdown/src/ast-to-react"; import remarkGfm from "remark-gfm"; import { first, fromPairs } from "lodash"; import { Button } from "@material-ui/core"; const components: Components = { a: ({ node, children, href, title, ...props }: ReactBaseProps & ReactMarkdownProps & { href: string; title: string }) => { // if the first child of the button is a bold element, make this a CTA button if ((first(children) as ReactElement)?.type === "strong") { const splitTitle = title.split(' '); const titleAttrEntries = splitTitle.filter(t => t.includes(':')); const remainingTitleEntries = splitTitle.filter(t => !t.includes(':')); const finalTitle = remainingTitleEntries.join(' '); const titleAttrPairs = titleAttrEntries.map(te => te.split(':')) const titleAttrs = fromPairs(titleAttrPairs); return ( <Button variant="contained" href={href} title={finalTitle} {...props} {...titleAttrs}> {children} </Button> ); } return <a href={href} title={title} children={children} {...props}></a>; }, }; export function renderMarkdown(markdown: string) { return ( <ReactMarkdown plugins={[remarkGfm]} children={markdown} components={components}/> ); }
<!-- markdown --> [Regular Link](/where_to_go/) [**CTA Button Link**](/where_to_go/ "color:primary any:attribute things without colons will be treated as the title")
output
Very useful, thanks
Subject of the feature
Support custom attributes through markdown
Example syntax
Problem
https://stackoverflow.com/a/4705645/304894 Im my case I want to be able to set different
rel
attribute from markdownExpected behavior
I would get the attributes from renderers