If these aren’t going to affect the Markdown parsing itself, and don’t need to appear in the syntax tree, a crude view plugin like below should work. If you want to actually integrate these into the Markdown parser, you might need a lot more patience (or could consider paying me to implement that feature).
let plugin = ViewPlugin.fromClass(class {
decorations: DecorationSet
constructor(view: EditorView) {
this.decorations = this.mkDeco(view)
}
update(update: ViewUpdate) {
if (update.viewportChanged || update.docChanged) this.decorations = this.mkDeco(update.view)
}
mkDeco(view: EditorView) {
let b = new RangeSetBuilder<Decoration>()
let highlight = /(@\w+)|(::.*?::)|(#\w+)/g
for (let {from, to} of view.visibleRanges) {
let range = view.state.sliceDoc(from, to), m
while (m = highlight.exec(range))
b.add(from + m.index, from + m.index + m[0].length, Decoration.mark({
class: m[1] ? "at-mention" : m[2] ? "highlight" : "hashtag"
}))
}
return b.finish()
}
}, {
decorations: v => v.decorations
})