feature-request: Support passing hProperties to renderers
bj00rn opened this issue ยท 10 comments
I was hoping to be able to use the remark-attr plugin in order to pass attributes from markdown.
remark-attr
plugin supports declaring attributes on elements like so:
### This is a title
{id="maintitle" style="color:red;"}
These properties are parsed correctly by the plugin into node.data.hProperties
However, properties are not passed on by react-markdown
to the renderers.
ast-to-react.js
Passing on hProperties would be nice, but maybe it has some security implications.
About the security aspect. remark-attr handle a lot of that part. It uses a whitelist approach.
By default, only standard attributes not event based(onclick, on...) are allowed.
In the meantime, if you like hacks (and who doesn't?) I have this workaround in my project:
- pass
rawSourcePos={true}
toReactMarkdown
- create a map
imageNodes
to store references to yourimage
nodes (see code below) - pass a function to
allowNodes
that saves references toimage
nodes - have a custom
image
renderer which looks up the corresponding node inimageNodes
(the node containsdata.hProperties
)
function MyMarkdown(props) {
const imageNodes = new Map();
const nodeKey = position => JSON.stringify(position.start); // or use your own hash function
function allowNodes(node) {
if (node.type === "image") imageNodes.set(nodeKey(node.position), node);
return true;
}
const renderers = {
image: ({ sourcePosition, alt, src, title }) => {
const node = imageNodes.get(nodeKey(sourcePosition));
return (
<img alt={alt} src={src} title={title} {...node.data.hProperties} />
);
}
};
return (
<ReactMarkdown
{...props}
allowNodes={allowNodes}
renderers={renderers}
rawSourcePos
/>
);
}
You don't need to clean up imageNodes
because it will be recreated and disposed on every render.
Yes, remark-attr
support would be great!
In the meantime, if you like hacks (and who doesn't?) I have this workaround in my project:
...
I used this code to resize images in a project I'm making. I did a short writeup of it on my blog here:
Thanks for the example!
this will be resolved by #428 which leverages remark-rehype which handles hProperties
This should be solved by landing GH-563 today, which will soon be released in v6.0.0!
Is there a trick to using this (other than passing remark-attr
to the remarkPlugins
array? The following isn't working for me:
import React from 'react'
import ReactMarkdown from 'react-markdown'
import attributes from 'remark-attr'
import behead from 'remark-behead'
import slug from 'remark-slug'
const REMARK_PLUGINS = [
[behead, { depth: 1 }],
[slug],
[attributes],
]
const Markdown = ({ children }) => {
<ReactMarkdown
remarkPlugins={REMARK_PLUGINS}
>
{children}
</ReactMarkdown>
}
But this results in the following error:
Error: Missing parser to attach `remark-attr` [link] (to)
This looks like it's caused by this check in remark-attr
, which calls the following function:
function isRemarkParser(parser) {
return Boolean(
parser &&
parser.prototype &&
parser.prototype.inlineTokenizers &&
parser.prototype.inlineTokenizers.link &&
parser.prototype.inlineTokenizers.link.locator,
);
}
(This might be an issue with the remark-attr
implementation, so let me know if this is the case and I'll open an issue there)
remark-attr
has not updated to the latest parser. See status indications for plugins in the list of plugins. And the issue tracker on that project.
@wooorm thanks so much for the quick response, will keep an eye on that page!
I plan to update remark-attr
before September. No guarantee.
As it's need for my use case.
If someone wants deadline or support. We may find a monetary arrangement. Otherwise,I think @wooorm has pretty good alternatives. :)