What is the best way to automatically highlight links, hashtags, etc

Could you please give us advice. What is the best way to automatically highlight links, hashtags, etc?

For example if I paste or enter text like this in proseMirror area:

I really love #proseMirror. Check it out here https://prosemirror.net/ref.html#ProseMirror.markRange

I want to highlight hashtags and links (change their color in blue) automatically in the proseMirror editor.

Here is my initial config

var pm = window.pm = new ProseMirror({
  place: document.querySelector(".full"),
  autoInput: true,
  doc: 'I really love #proseMirror. Check it out here https://prosemirror.net/ref.html#ProseMirror.markRange',
  docFormat: "text"
})

Thanks a lot for your advice. We are now using codemirror with few handwritten plugins for this goal, and it looks like this with codemirror 2016-02-27_0350

And we would really love to migrate to prosemirror, because it looks like a reeeeeally awesome alternative for our goals.

great job!

Consider using an input rule for both. I haven’t tested this lately but something like

import {InputRule} from "prosemirror/src/inputrules"

let urlex = /((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/
LinkMark.register("autoInput","startLink", new InputRule(urlex," ",
    function(pm, match, pos) {
        let url = match[0]
        pm.setMark(this,pos,{href: url, title: ""})
    }
))

Input rules should cover typed text. OP specifically mentions pasting, which isn’t really something doable at the moment. 0.5.0 is slated to bring a paste hook which should be usful to accomplish this in some way

2 Likes

There’s no great solution for this yet. At some point it would be nice to be able to more or less declaratively specify that some pieces of text should be converted to some kind of nodes/marks, but that does not exist yet.

How were you planning to model hash tags in terms of ProseMirror document elements? Text with a mark applied?

1 Like

I think that tags would be best represented as inline nodes instead of using marks. This has the following advantages:

  • You can associate a unique tag id with the node which allows you to later rename a tag and have it automatically updated inside all documents (serializing the node would just translate the tag id into the appropriate name at render time)
  • When working with tags you usually want to treat them as a whole entity, which is why it makes sense to be able to delete them in one go using backspace.
  • More freedom when choosing how to render the tag (e.g. might want to have an inline dropdown menu to change the tag when clicking on it)

I just wanted to give some input as I’ve thought about integrating tags into ProseMirror before and we are currently using inline nodes for something similar and it has worked great so far!

2 Likes

Thanks,@marijn

I am fully agree with @kiejo


@kiejo could you please describe

we are currently using inline nodes for something similar and it has worked great so far

how you do it now?

We are currently using inline nodes for what we call “internal links” in our system. They get created via an auto completion menu that gets displayed when a user types “@” followed by some characters:

->

When the user clicks on an item in the completion menu we create an inlinde node with an id attribute that contains the id of the referenced item. When rendering the node we render the title based on that id, which means that it’s always up to date.
This is pretty much the same thing I would do when adding tags to our system. The main difference would be changing the “@” prefix to “#”.

For this specific use case we currently do not need to handle pasting external content. If you need paste handling the issue https://github.com/ProseMirror/prosemirror/issues/221 should cover this in the next release. If you are interested in handling paste events in the mean time, I would suggest you check out https://github.com/ProseMirror/prosemirror/pull/182 or https://github.com/kiejo/prosemirror/commit/4146c0baa665478f7a9d3ee57de959fdb0cd3f9a.

Hope this helps!

2 Likes