I have a React app in which there are a couple areas where users need to edit rich text bodies that can include merge field tokens in certain formats.
(There are two: one is the <<[
]>>
LINQ Reporting Engine syntax from Aspose.Words
, and the other is manual [[
]]
.)
I want to highlight the various field syntaxes wherever they appear in the body.
I was using mui-rte
, a wrapper for draft-js
, and this was easily accomplished using the Decorators feature:
const OpenForeachDecorator = (props: any) => {
return (
<span spellCheck="false" className={`${classes.markupTag} ${classes.foreachTag} ${classes.openTag}`}>
{props.children}
</span>
);
};
// etc.
const decorators = [
{
component: OpenForeachDecorator,
regex: /<<foreach \[[^\]]+\]>>/gim
},
// etc.
However I'm just having too many other little issues with it, which I can avoid if I switch to Quill
via react-quill
.
That conversion was going really well...
with the exception of this field syntax highlighting aspect, since Quill doesn't have a built-in equivalent.
It does, however, have a built-in syntax highlighting via highlight.js
...
So, I have described my two formats of merge fields as languages for highlight.js
,
export default function asposeLinqHighlight(hljs: any) {
return {
name: "asposelinq",
contains: [
{
className: "fieldTag",
begin: /<<\[/,
end: />>/,
//etc.
and registered them at the top of my rich text editor component,
import hljs from "highlight.js";
import asposeLinqHighlight from "./AsposeLinqHighlight";
import htmlMergeHighlight from "./HtmlMergeHighlight";
hljs.registerLanguage("asposelinq", asposeLinqHighlight);
hljs.registerLanguage("htmlmerge", htmlMergeHighlight);
and set up the syntax highlighting module:
const modules = useMemo(
() => ({
syntax: {
highlight: (text: string) => hljs.highlightAuto(text,
[props.templateMarkup ? "asposelinq" : "htmlmerge"])
.value
},
Obviously at this point you wouldn't expect it to work automatically, and it doesn't:
but if I wrap everything in a code block, it does indeed appear, proving the implementation is otherwise sound:
(though of course you lose the other formatting as well, but yeah.)
The span tags providing the syntax highlighting style aren't in the onChange value, either, which is good.
Interestingly to me, if I Ctrl
+Z
, the code block goes away, but the syntax highlighting remains:
and now those style tags ARE in the onChange value, which is not great.
So my main question, after all of that, is:
How can I easily change the behavior of the syntax
module to apply to the whole body text, not just within a code block?
(And keep it from clobbering other styles like placing it in a code block would do)
And then secondarily:
Is the fact that the span tags aren't in the onChange value something the syntax module is doing specifically, or is it just a function of being in a tag (meaning that if I get it to work without a tag, they'll be in my output too)?