Comments (30)
I actually have a hacky but working AST-based re-implementation of highlight.js working now. It’s probably bug filled though, will have to add lots of tests (I believe there’s like 60 supported languages? Gah.) But do expect more to come soon! 😄
@tmcw I’m writing it to expose HAST nodes, a unist and minimal HTML syntax tree. This means to get this working with react there needs to be a transformation between the two. I don’t expect it to be very hard, but I’m not experienced with react. could you help me there when the time comes?
from remark-react.
Awesome, been a bit quiet on this because of work-work but love the way this is shaping up.
from remark-react.
I published the solution as remark-react-lowlight. You can see it in action at react-component-boilerplate.
It's probably safe to close this issue now.
from remark-react.
@bebraw is there a way to use that component without having to specify the highlight js lang (relying on code fence blocks)? The example in the README makes me think I'd have to specify it.
from remark-react.
It's not currently possible to use highlight.js: highlight.js produces a string of HTML content, and remark-react is expressly written to avoid such HTML escapes. If there was a highlighter that output an AST instead, then we could integrate it into remark-react - otherwise, highlight.js is not compatible with remark-react's security model.
from remark-react.
Do you have an example of the AST structure you would need to implement the highlighting?
from remark-react.
I was thinking about the same problem recently, for example, I’d like to support syntax highlighting in remark-vdom, remark-man too.
I did some digging into highlight.js, and I don’t think their per-language syntax files needs changing (for example, javascript, wouldn’t need changing). However, their core is tightly coupled with outputting HTML.
So, either someone needs to create a fork which supports other syntaxes (in the form of specifying a compiler), or highlight.js itself should be rewritten, but I’m not sure whether they’d want to.
I have a full plate, but I’ll try my hands on whether it’s feasible, but I’d suggest you’d raise an issue regarding decoupling on highlight.js’s repository.
from remark-react.
Sure! Let me know when you get to the point of integration
from remark-react.
Great! 👌
from remark-react.
Done! https://github.com/wooorm/lowlight
from remark-react.
FYI, here's a Node friendly highlighter that has been developed based on Prism: Illuminate.js. Prism deals with JSX better than Highlight.js.
It would be great if you could design the system so that it's possible to glue in Illuminate. Note that there's react-illuminate as well.
from remark-react.
@bebraw just saw your comment, that looks nice too, although it doesn’t support many language, and it seems to be in beta?
@tmcw I think all the building blocks for syntax highlighting with remark-react
are now here, there’s lowlight
(or others), and there’s react-syntax-highlighter
(which uses lowlight under the hood).
What remains is “component” support in remark-react, which I guess means that users of this remark plugin can specify that code
is rendered as SyntaxHighlighter
?
Again, I’m not very familiar with React though, so you probably have a better idea of how this should be handled :)
from remark-react.
@wooorm It's a little limited at the moment, that's true. Given it's Prism based, it would be possible to add support to the missing languages if needed I think. I opened an issue so we get feedback from the author. Something Prism based would be a winner solution for me given how well it highlights.
from remark-react.
Diversity is good! If you want prism, that’s fine and it should happen.
I think this issue will allow that, if we add support for components through something similar like the method I proposed above!
from remark-react.
It would be nice to get this moving again. Can someone in the know explain what should happen code-wise? I could try to look into making the changes.
from remark-react.
I don’t know the API of react, but you can use react-lowlight or react-syntax-highlighter, both based on lowlight, to do virtual (thus, safe), syntax highlighting. Then, wrap one of those components, and integrate with remarkReactComponents
(see the readme of remark-react). I’m not entirely sure what API they use, and if you can access the lang
of a code
node though.
@tmcw, could you clarify whether this should work?
from remark-react.
@wooorm Thanks. Esp. react-lowlight seems great. I think could be enough if I just replace the portion that does code
now with that component. I'll give it a quick go and report back.
from remark-react.
I gave it more thought. We probably should agree on a basic interface. Right now we have
remark().use(reactRenderer)
What if we did
remark().use(reactRenderer({
code: codeRenderer // custom logic would go here
}))
The idea is that this type of hook system would allow you to replace h
per node type. This would allow the maximum amount of customization without breaking backwards compatibility. Most importantly it would enable highlighting plugin.
from remark-react.
I believe the current code already supports something like that:
var remark = require('remark');
var toReact = require('remark-react');
remark().use(toReact, {
remarkReactComponents: {
'code': 'Lowlight'
}
}))
Then, Lowlight
is passed to React.createElement
. But, aside from supporting string
, maybe function
should be supported in remark-react
too? Or, create a wrapper component around Lowlight
which supports the attributes given by remark-react
and transforms them to support the attributes expected by react-lowlight
.
from remark-react.
Oh, yeah. Missed that. It would need a tiny adapter right there. 👍
from remark-react.
Maybe create remark-react-highlight
? So people who use remark, react, and remark-react, need just remark().use(remarkReact).use(remarkReactHighlight)
? That’d be my suggestion :)
from remark-react.
I managed to set up highlighting to work with remark-react. Here's a quick demo.
@wooorm How would that remark().use(remarkReact).use(remarkReactHighlight)
work? I would need to understand how to connect the plugins internally to patch remark-react behavior (literally that element definition). Alternatively we could do something like this:
{remark().use(reactRenderer, {
remarkReactComponents: {
code: RemarkLowlight({
// list supported languages here, lowlight needs them
js: jsLangugeDefinition
})
}
}).process(readme)}
Lowlight requires those language definitions. Instead of passing them explicitly we could hide the registration within the package itself and perhaps support optional registration that would override that default. I think the reasoning is that each language definition bloats the bundle so the decided to go with opt-in kind of system there.
from remark-react.
Oh, you’re right, it wouldn’t work (currently) as a remark plug-in :/ I like your proposed idea; supporting an object mapping names to language definitions.
And, indeed, that’s the reason. Lowlight suggests against subscribing all languages when in the browser.
from remark-react.
Nice! Maybe add a link to the README here though?
from remark-react.
Ah, I see. If it's in the object passed to RemarkLowlight({})
it gets registered. Noticed that it will break down if the language specified in a code fence block isn't registered though.
from remark-react.
@rgbkrk Yeah. It has to register the languages first. Can you open an issue about the breakage at my repo? Maybe the right way to solve that is to skip highlighting in that case and just give a warning instead.
from remark-react.
Hey I'm attempting to get remark-react and syntax highlighting to cooperate, hoping someone who's run the gauntlet before can help :)
My naive implementation looks something like
Lowlight.registerLanguage('js', js);
const Pre = ({children}) => {
return <Lowlight language={'js'} value={children[0].props.children[0]} />
}
Pre.propTypes = {
className: React.PropTypes.string,
children: React.PropTypes.node,
};
...
const remarkReactComponents = { pre: Pre };
Which would work if I only needed to highlight js
,. so from here I wrote a little parser that grabs the language from a node
and drops it into an attributes object.
node.attributes.className = ['hljs', `language-${lang}`];
Which never appears to be available on the props of my React nodes.
P.S. I'm using pre
rather than code
to prevent nested elements.
from remark-react.
I think @bebraw got something working with https://github.com/bebraw/remark-react-lowlight.
@bebraw, does remark-react-lowlight
support pre
?
from remark-react.
@bebraw, does remark-react-lowlight support pre?
I can't see anything pre
specific at the code. Maybe "it just works"™. Worth a go.
from remark-react.
Cool, I’ll whip up a PR to include this in the docs here!
from remark-react.
Related Issues (20)
- HTML in markdown always getting escaped HOT 2
- Improve documentation around linking to custom React Components HOT 4
- Passing props to remarkReactComponents HOT 4
- hast-util-sanitize dep failing HOT 1
- Pass `position` into props HOT 1
- is "remark-react looks for an attributes object on each node" working? HOT 3
- Any reason why the root element has to be a <div>? HOT 2
- remarkReactComponents target classes HOT 2
- Incorrect treatment of 'tel'-links HOT 2
- Test passing options to toHast() wrong? HOT 1
- Laguage type not being passed HOT 2
- 5.0.0 HOT 13
- Uncaught TypeError: information is not a function HOT 4
- allowDangerousHTML doesn't work HOT 15
- table rendering not working HOT 12
- Nested ordered lists need at least 3 spaces to work HOT 1
- Confusing readme HOT 1
- remarkReactComponents not working HOT 1
- Add Typescript types HOT 3
- Access the data property of hast code elements in my custom component HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from remark-react.