Marked Test

node-red custom marked syntax for node help

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/2.1.3/marked.min.js"></script>
<textarea id="markdown-input" rows="6" style="width: 100%;">
Send data via a local serial port.  
### Inputs
:   payload     (string | buffer) :  data to be sent via the serial port
:  *baudrate*   (string)          :  baudrate of the serial port (optional)
</textarea>
<hr>
<div class="red-ui-help">
  <div id="markdown-output"></div>
</div>

CSS

p {
    display: block;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
}
.red-ui-help a {
    color: #08c;
    text-decoration: none;
}
.red-ui-help {
    font-size: 14px;
    line-height: 1.5em;
    font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;
}

div {
    display: block;
}

dl {
    display: block;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
}

.red-ui-help dl.message-properties {
    border: 1px solid #ddd;
    border-radius: 2px;
    margin: 5px auto 10px;
}


.red-ui-help dl.message-properties>dt .property-type {
    font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;
    color: #555;
    font-style: italic;
    font-size: 11px;
    float: right;
}


.red-ui-help dl.message-properties>dt {
    padding: 0px 3px 2px 3px;
    font-family: Menlo,Consolas,"DejaVu Sans Mono",Courier,monospace;
    font-weight: normal;
    margin: 5px 3px 1px;
    color: #ad1625;
    white-space: nowrap;
}

.red-ui-help dl.message-properties>dt.optional {
    font-style: italic;
}
.red-ui-help dl.message-properties>dd {
    margin: 0px 8px 2px 13px;
    vertical-align: top;
}

.red-ui-help h3 {
    font-weight: 500;
    font-size: 1.138em;
    margin: 7px auto 5px;
    line-height: 1.3em;
}

user agent stylesheet
h3 {
    display: block;
    font-size: 1.17em;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
    font-weight: bold;
}

JavaScript

const descriptionList = {
  name: 'descriptionList',
  level: 'block',                                     // Is this a block-level or inline-level tokenizer?
  start(src) { return src.match(/:[^:\n]/)?.index; }, // Hint to Marked.js to stop and check for a match
  tokenizer(src, tokens) {
    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 `<dl class="message-properties">${this.parseInline(token.tokens)}\n</dl>`; // parseInline to turn child tokens into HTML
  }
};

const description = {
  name: 'description',
  level: 'inline',                                 // Is this a block-level or inline-level tokenizer?
  start(src) { return src.match(/:/)?.index; },    // Hint to Marked.js to stop and check for a match
  tokenizer(src, tokens) {
    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<dt>${this.parseInline(token.dt)}<span...