diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js index d67a5d93d..34f7569bc 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js @@ -22,8 +22,82 @@ RED.utils = (function() { return renderMarkdown(txt); } - _marked.setOptions({ - renderer: new _marked.Renderer(), + let enable = true; + const descriptionList = { + name: 'descriptionList', + level: 'block', // Is this a block-level or inline-level tokenizer? + start(src) { + if (!src) return null + return src.match(/:[^:\n]/)?.index; // Hint to Marked.js to stop and check for a match + }, + tokenizer(src, tokens) { + if (!src) return null; + const rule = /^(?::[^:\n]+:[^:\n]*(?:\n|$))+/; // Regex for the complete token + const match = rule.exec(src); + if (match) { + return { // Token to generate + type: 'descriptionList', // Should match "name" above + raw: match[0], // Text to consume from the source + text: match[0].trim(), // Additional custom properties + tokens: this.inlineTokens(match[0].trim()) // inlineTokens to process **bold**, *italics*, etc. + }; + } + }, + renderer(token) { + return `
${this.parseInline(token.tokens)}\n
`; // parseInline to turn child tokens into HTML + } + }; + + const description = { + name: 'description', + level: 'inline', // Is this a block-level or inline-level tokenizer? + start(src) { + if (!enable) return null + src.match(/:/)?.index; // Hint to Marked.js to stop and check for a match + }, + tokenizer(src, tokens) { + if (!enable) return null; + const rule = /^:([^:\n]+)\(([^:\n]+)\).*?:([^:\n]*)(?:\n|$)/; // Regex for the complete token + const match = rule.exec(src); + if (match) { + return { // Token to generate + type: 'description', // Should match "name" above + raw: match[0], // Text to consume from the source + dt: this.inlineTokens(match[1].trim()), // Additional custom properties + types: this.inlineTokens(match[2].trim()), + dd: this.inlineTokens(match[3].trim()), + }; + } + }, + renderer(token) { + return `\n
${this.parseInline(token.dt)}${this.parseInline(token.types)}
${this.parseInline(token.dd)}
`; + }, + childTokens: ['dt', 'dd'], // Any child tokens to be visited by walkTokens + walkTokens(token) { // Post-processing on the completed token tree + if (token.type === 'strong') { + token.text += ' walked'; + } + } + }; + + + const renderer = new window._marked.Renderer(); + + //override list creation - add node-ports to order lists + renderer.list = function (body, ordered, start) { + let temp = body; + if (enable && ordered) { + temp = `
    ${body}
`; + } else if (ordered) { + temp = `
    ${body}
`; + } else { + temp = ``; + } + return temp; + } + + window._marked.setOptions({ + renderer: renderer, gfm: true, tables: true, breaks: false, @@ -32,6 +106,8 @@ RED.utils = (function() { smartypants: false }); + window._marked.use({extensions: [descriptionList, description] } ); + function renderMarkdown(txt) { var rendered = _marked(txt); var cleaned = DOMPurify.sanitize(rendered, {SAFE_FOR_JQUERY: true})