For a note taking application I am building (for personal use for now) I have designed a custom language for tagging pieces of text, a markup language. The tags are used to give more meaning to text and allow for customized styling of those pieces of text.
This was initially implemented using CodeMirror, because ProseMirror did not exist at the time. A tag could be as simple as {book: Some Title}
and by default it would be displayed just as the text itself, but I made it so that you could render them as special widgets that were either inline or block, such that their styling could be fully customized. The book tag could for example be rendered with a little thumbnail of its cover and a link to a website with its summary or whatever. And if you selected one of these widgets, they would automatically be converted back to their textual representation.
This approach works well for the simpler kind of widgets, i.e. leaf widgets, but for structural widgets that also introduce a layout, e.g. as is the case for tables, this approach no longer is as sufficient. You could embed additional CodeMirror instances to work around it, but this does not really scale and would get complex really fast. The other approach would be to try and stay within the one CodeMirror instance by leveraging readonly marks for the parts that are only used for styling the widget, but this would not allow for arbitrary HTML widgets and would also be very complex to keep correct. So I just kept thing simple and only allowed the editing of widgets within their textual representation. This meant that if you had a complex table structure, that as soon as you placed the cursor on the rendered widget, the whole thing would just collapse back to its textual representation.
With ProseMirror in beta I tried to readdress this and see whether I could get these more complex editable widgets to work. However from what I have gathered so far by experimenting and reading other topics it seems like my use case is not really supported.
The markup language consists of only text and tags. Tag attributes are also tags. If a tag, or one of its attribute tags, contains multi-line text it has to be a block tag. If the text within a tag should not be interpreted for other tags it has to be a literal tag. Otherwise it is an inline tag. Here are some examples of what the textual representation looks like:
text {inline{@attr: attr text}: tagged text} text
text {block:}
{@attr: attr text}
tagged text
tagged text
text {literal=}
{@attr: attr text}
{ignored: literal text}
literal text
I would love to enhance the textual representation with what ProseMirror has to offer. First I looked at decorators, but they seem more appropriate for things like syntax highlighting. What I really am after is the ability to style my tags with arbitrary HTML, but continue the editor as it were, in some fragments. So I created a schema instead, which mostly worked. However I then found the issue about inline nodes with content. So how does that affect my inline tags, which in turn can have other inline tags within them? Does this mean I cannot implement what I hoped to implement with ProseMirror?
And if nested inline nodes are no longer a problem, how do I best approach styling them? Say my inline tag has the schema content label attrTag* (markedText | inlineTag)*
. What if I want something after the label, but only for inline tags. I do not see how I can achieve this with the array notation, so I tried creating a DOM node instead, but that seems the wrong approach when you want something that is editable or has children. I also looked at node views, but they too seem made for just inline leaf nodes.
I love to be proved wrong, but it seems I am out of luck and my use case simply is not supported. If this is the case, does anyone have a suggestion of potential alternatives that I could use?