/* eslint-disable max-lines */
const _ = require('lodash');
const Markdown = require('marked');
const renderer = new Markdown.Renderer();
//Processes the markdown within an HTML block if it's just a class-wrapper
renderer.html = function (html) {
if(_.startsWith(_.trim(html), '
')){
const openTag = html.substring(0, html.indexOf('>')+1);
html = html.substring(html.indexOf('>')+1);
html = html.substring(0, html.lastIndexOf('
'));
return `${openTag} ${Markdown(html)} `;
}
return html;
};
// Don't wrap {{ Divs or {{ empty Spans in tags
renderer.paragraph = function(text){
let match;
if(text.startsWith('
${text}\n`;
};
const mustacheSpans = {
name: 'mustacheSpans',
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 completeSpan = /^{{[^\n]*}}/; // Regex for the complete token
const inlineRegex = /{{(?:="[\w,\-. ]*"|[^"'{}}\s])*\s*|}}/g;
const match = completeSpan.exec(src);
if (match) {
//Find closing delimiter
let blockCount = 0;
let tags = '';
let endIndex = 0;
let delim;
while (delim = inlineRegex.exec(match[0])) {
if(delim[0].startsWith('{{')) {
tags = tags || ' ' + processStyleTags(delim[0].substring(2));
blockCount++;
}
else if(delim[0] == '}}' && blockCount !== 0) {
blockCount--;
if(blockCount == 0) {
endIndex = inlineRegex.lastIndex;
break;
}
}
}
if(endIndex) {
const raw = src.slice(0, endIndex);
const text = raw.slice((raw.indexOf(' ')+1) || -2, -2)
return { // Token to generate
type: 'mustacheSpans', // Should match "name" above
raw: raw, // Text to consume from the source
text: text, // Additional custom properties
tags: tags,
tokens: this.inlineTokens(text) // inlineTokens to process **bold**, *italics*, etc.
}
}
}
},
renderer(token) {
console.log(token);
return `
{
if(splitText) r.push(Markdown.parseInline(splitText, { renderer: renderer }));
const block = matches[matchIndex] ? matches[matchIndex].trimLeft() : '';
if(block && block.startsWith('{')) {
const values = processStyleTags(block.substring(2));
r.push(``);
blockCount++;
} else if(block == '}}' && blockCount !== 0){
r.push('
');
blockCount--;
}
matchIndex++;
return r;
}, []).join('');
return res;
} else {
if(!matches) {
return `${text}`;
}
}
};
//Fix local links in the Preview iFrame to link inside the frame
renderer.link = function (href, title, text) {
let self = false;
if(href[0] == '#') {
self = true;
}
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
if(href === null) {
return text;
}
let out = `${text}`;
return out;
};
const nonWordAndColonTest = /[^\w:]/g;
const cleanUrl = function (sanitize, base, href) {
if(sanitize) {
let prot;
try {
prot = decodeURIComponent(unescape(href))
.replace(nonWordAndColonTest, '')
.toLowerCase();
} catch (e) {
return null;
}
if(prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
return null;
}
}
try {
href = encodeURI(href).replace(/%25/g, '%');
} catch (e) {
return null;
}
return href;
};
const escapeTest = /[&<>"']/;
const escapeReplace = /[&<>"']/g;
const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
const escapeReplacements = {
'&' : '&',
'<' : '<',
'>' : '>',
'"' : '"',
'\'' : '''
};
const getEscapeReplacement = (ch)=>escapeReplacements[ch];
const escape = function (html, encode) {
if(encode) {
if(escapeTest.test(html)) {
return html.replace(escapeReplace, getEscapeReplacement);
}
} else {
if(escapeTestNoEncode.test(html)) {
return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
}
}
return html;
};
const sanatizeScriptTags = (content)=>{
return content
.replace(/