I have a CodeSandbox here, which shows this:
import React from "react";
import ReactDOM from "react-dom";
import { PrismLight as Code } from "react-syntax-highlighter";
// Code.registerLanguage('xml', xml)
note.displayName = "note";
/** @type {import('../core.js').Syntax} */
function note(Prism) {
// https://www.json.org/json-en.html
Prism.languages.note = {
comment: {
pattern: /# .*n?/,
greedy: true,
},
bracketed_term: {
pattern: /{{([a-z][a-z0-9/.@*]*(?:-+[a-z0-9/.@*]+)*-*)}}/,
greedy: true,
alias: "string",
inside: {
term: {
pattern: /([a-z][a-z0-9/.@*]*(?:-+[a-z0-9/.@*]+)*-*)/,
greedy: true,
alias: "tag",
},
},
},
nested_term: {
pattern: /([a-z][a-z0-9/.@*]*(?:-+[a-z0-9/.@*]+)*-*)[ (]/,
greedy: true,
alias: "tag",
},
term: {
pattern: /([a-z./*@][a-z0-9/.@*]*(?:-+[a-z0-9/.@*]+)*-*)/,
greedy: true,
alias: "keyword",
},
string: {
pattern: /(<[^<>]+>)/,
greedy: true,
alias: "string",
},
bracket: {
pattern: /[{}]/,
greedy: true,
alias: "string",
},
code: {
pattern: /#ww+/,
greedy: true,
alias: "number",
},
number: {
pattern: /-?bd+(?:.d+)?b/i,
greedy: true,
},
punctuation: /[{}[],]/,
boolean: /b(?:false|true)b/,
};
}
Code.registerLanguage("note", note);
const light = {
'code[class*="language-"]': {
color: "#333",
fontWeight: "bold",
background: "none",
fontFamily: "Noto Sans Mono",
textAlign: "left",
whiteSpace: "pre",
wordSpacing: "normal",
wordBreak: "normal",
wordWrap: "normal",
lineHeight: "1.7",
MozTabSize: "2",
OTabSize: "2",
tabSize: "2",
WebkitHyphens: "none",
MozHyphens: "none",
msHyphens: "none",
hyphens: "none",
},
'pre[class*="language-"]': {
color: "#333",
fontWeight: "bold",
fontFamily: "Noto Sans Mono",
textAlign: "left",
whiteSpace: "pre",
wordSpacing: "normal",
wordBreak: "normal",
wordWrap: "normal",
lineHeight: "1.7",
MozTabSize: "2",
OTabSize: "2",
tabSize: "2",
WebkitHyphens: "none",
MozHyphens: "none",
msHyphens: "none",
hyphens: "none",
overflow: "auto",
},
':not(pre) > code[class*="language-"]': {
background: "#282a36",
whiteSpace: "normal",
},
comment: {
color: "#ccc",
fontWeight: "normal",
},
prolog: {
color: "#6272a4",
},
doctype: {
color: "#6272a4",
},
cdata: {
color: "#6272a4",
},
punctuation: {
color: "#aaa",
fontWeight: "bold",
},
".namespace": {
Opacity: ".7",
},
property: {
color: "#333",
},
tag: {
color: "#333",
},
constant: {
color: "#9248fc",
},
symbol: {
color: "#9248fc",
},
deleted: {
color: "#9248fc",
},
boolean: {
color: "#3b82f6",
},
number: {
color: "#34D399",
},
selector: {
color: "#9248fc",
},
"attr-name": {
color: "#aaa",
},
string: {
color: "#9248fc",
},
char: {
color: "#9248fc",
},
builtin: {
color: "#9248fc",
},
inserted: {
color: "#9248fc",
},
operator: {
color: "#bbb",
},
entity: {
color: "#333",
fontWeight: "bold",
cursor: "help",
},
url: {
color: "#333",
fontWeight: "bold",
},
".language-css .token.string": {
color: "#333",
fontWeight: "bold",
},
".style .token.string": {
color: "#333",
fontWeight: "bold",
},
variable: {
color: "#aaa",
},
atrule: {
color: "#aaa",
fontWeight: "bold",
},
"attr-value": {
color: "#9248fc",
fontWeight: "bold",
},
function: {
color: "#111",
fontWeight: "bold",
},
"class-name": {
color: "#111",
fontWeight: "bold",
},
keyword: {
color: "#999",
},
regex: {
color: "#34D399",
},
important: {
color: "#34D399",
fontWeight: "bold",
},
bold: {
fontWeight: "bold",
},
italic: {
fontStyle: "italic",
},
};
const note3 = `deck @termsurf/base
mark <0.0.1>
head <A NoteText Package Manager>
term link-text
term computation
term philosophy
term information
term platform
term white-label
term compiler
face <Lance Pollard>, site <[email protected]>
task ./task
read ./note
lock apache-2
example <The moon's period is {bold(<28 days>)}
link @termsurf/bolt, mark <0.x.x>
link @termsurf/nest, mark <0.x.x>
link @termsurf/crow, mark <0.x.x>`;
ReactDOM.render(
<Code
customStyle={{
height: "100%",
padding: 16,
margin: 0,
}}
language="note"
style={light}
>
{note3}
</Code>,
document.getElementById("base")
);
If you’ll see the preview, notice the “example” line:
How do I make it so the text is highlighted properly, so it handles “terms” nested inside strings, nested inside terms, etc., recursively? More like this:
How can I change the definition of the syntax highlighter above to allow nested strings within terms? Terms are as defined in the highlighter, and they can be nested with parens, like term-a(term-b, term-c(term-d, etc))
. But you can have strings within terms, and terms within strings.