Draft-js: Syntax highlighting

Created on 23 Feb 2016  路  18Comments  路  Source: facebook/draft-js

As per our discussion on Twitter https://twitter.com/rgbkrk/status/702172656657764352.

Lets chat more here. Cc: @hellendag @vjeux @rgbkrk

discussion enhancement

Most helpful comment

For those interested, here is an example of using Prism to highlight code block in a Rich text editor: https://gist.github.com/SamyPesse/0690602631c19aedcfa0a28feabb9d2b

And here is a gif of the result:

prism

All 18 comments

Sweet, thanks for starting this.

I hacked Prism into a decorator class, and got a decent code editor working. Since Prism is built for one-time parsing and highlighting of static content, though, it wasn't really ideal for quickly decorating on the fly. The entire ContentState had to be parsed on every change, so as the file grew, the editor got slower.

IIRC, an approach more similar to CodeMirror, with parsing context on a per-line basis, would allow for minimal analysis on each change. It's been a while since I last looked into this, though. :)

Great! Thanks for moving it over here. Since my current use case ends up being lots of individual editor views (that are currently CodeMirror in a React environment), this could end up working out ok. Especially if we're only rendering the editor component that is in view. To be more concrete, the use case is an open source literate coding notebook (backed by Jupyter/IPython):

backandforth

Swapping out the markdown area to be a draft-js editor is currently on my "scope it out" list.

I'm assuming I'd need to try out your first approach before I could even start thinking about the per-line parsing context.

@rgbkrk Awesome. Just to clarify: is your goal to remove the markdown CM in favor of a Draft WYSWIYG editor, or to use Draft for direct markdown editing?

My goal is to remove the markdown CM in favor of a Draft WYSIWYG editor and entertain the possiblity of switching the code editors out for Draft.

Our underlying model (the notebook document) relies on Markdown underneath for those. The one in the spec lists marked while the demo above is using commonmark. That's merely the on disk format though.

I'm in a pretty similar situation as @rgbkrk, currently using CM for Markdown editing but thinking about switching to Draft.js for WYSIWYG. If anyone dives more into this, would love to hear about good solution patterns :)

@jorilallo We're currently also using CM for Markdown editing, but working on switching to Draft:

  • markup-it Markdown parser to generate draft's contentState, or markdown from draft's contentState
  • react-markup-editor Editor built on top of Draft with table editing, etc (it requires #216).

The hard parts are tables, lists and blockquotes, since they are trees in the markdown AST. react-markup-editor abstracts this with its own state and handle nested draft editor.
The goal is also to supports syntax highlighting for code blocks.

BTW: These modules are still Work-in-Progress.

@hellendag Can you share your decorator class example? I'm trying to build a highlighter of a toy language I built, and If I had the example, I could get this done much quicker! 馃槃

@SamyPesse Interesting, this is pretty much what I was looking for as I'm building a sideproject in the similar space (big fan of Gitbook!). I'll take another look when I get to rebuilding with Draft.js

For those interested, here is an example of using Prism to highlight code block in a Rich text editor: https://gist.github.com/SamyPesse/0690602631c19aedcfa0a28feabb9d2b

And here is a gif of the result:

prism

I've published it as a node module: https://github.com/SamyPesse/draftjs-prism

We are probably going to use it for the GitBook Editor, and I think some perf optimizations can be done for large code blocks.

I've also followed a similar approach powered by something other than Prism, but as @hellendag noted things get slower as the content size increases.

I'd love to hear how a more incremental approach can be achieved. My sense is that it's not using the decorator approach.

Hi, I'm using a similar approach to @SamyPesse parsing the content in getDecorations and using the retuned AST to set the decorations. It works, but it seems out of place (for the reasons mentioned in the thread).

I tried another approach which is to create entities, but I quickly run into problems. It seems that modifying the editorState in the onChange event is not a good idea.

My use case is to use draft for a formula editor. As the user types I parse the formula, and based on the AST I apply styles + add some interactivity (like clicking in a function to show the function help).

Apart from using decorators, is there any other approach to tokenize an input?

I'm doing the same thing with a lexer and parser. I'm using a decorator at the moment but have been trying to figure out #453 so I can use onChange.

Just thought I'd throw in https://typora.io for inspiration - its source isn't published, but its editing between markdown, code, and "rendered" content is seamless

@rgbkrk is the code behind that gif that you posted open-source?

Edit: found it https://github.com/nteract/nteract

Yup! You found the right one!

I think it's save to assume that this issue doesn't need to stay open any longer. Feel free to continue adding comments however :+1:

Was this page helpful?
0 / 5 - 0 ratings