|
|
@ -10,31 +10,41 @@ const greentextRegex = /^>((?!>\d+|>>/\w+(/\d*)?|>># |
|
|
|
, italicRegex = /\*\*(.+?)\*\*/gm |
|
|
|
, italicRegex = /\*\*(.+?)\*\*/gm |
|
|
|
, spoilerRegex = /\|\|([\s\S]+?)\|\|/gm |
|
|
|
, spoilerRegex = /\|\|([\s\S]+?)\|\|/gm |
|
|
|
, detectedRegex = /(\(\(\(.+?\)\)\))/gm |
|
|
|
, detectedRegex = /(\(\(\(.+?\)\)\))/gm |
|
|
|
, linkRegex = /(https?\://[^\s<>\[\]{}|\\^]+)/g |
|
|
|
, linkRegex = /\[(?<label>[^\[][^\]]*?)\]\((?<url>https?\://[^\s<>\[\]{}|\\^)]+)\)|(?<urlOnly>https?\://[^\s<>\[\]{}|\\^]+)/g |
|
|
|
, aLinkRegex = /\[(?<label>[^\[][^\]]*?)\]\((?<url>https?\://[^\s<>\[\]{}|\\^)]+)\)|(?<urlOnly>https?\://[^\s<>\[\]{}|\\^]+)/g |
|
|
|
|
|
|
|
, codeRegex = /(?:(?<language>[a-z+]{1,10})\r?\n)?(?<code>[\s\S]+)/i |
|
|
|
, codeRegex = /(?:(?<language>[a-z+]{1,10})\r?\n)?(?<code>[\s\S]+)/i |
|
|
|
, includeSplitRegex = /(\[code\][\s\S]+?\[\/code\])/gm |
|
|
|
, includeSplitRegex = /(\[code\][\s\S]+?\[\/code\])/gm |
|
|
|
, splitRegex = /\[code\]([\s\S]+?)\[\/code\]/gm |
|
|
|
, splitRegex = /\[code\]([\s\S]+?)\[\/code\]/gm |
|
|
|
, trimNewlineRegex = /^\s*(\r?\n)*|(\r?\n)*$/g |
|
|
|
, trimNewlineRegex = /^\s*(\r?\n)*|(\r?\n)*$/g |
|
|
|
, escape = require(__dirname+'/escape.js') |
|
|
|
, escape = require(__dirname+'/escape.js') |
|
|
|
, { highlight, highlightAuto } = require('highlight.js') |
|
|
|
, { highlight, highlightAuto } = require('highlight.js') |
|
|
|
|
|
|
|
, { addCallback } = require(__dirname+'/../../redis.js') |
|
|
|
, config = require(__dirname+'/../../config.js') |
|
|
|
, config = require(__dirname+'/../../config.js') |
|
|
|
, diceroll = require(__dirname+'/diceroll.js') |
|
|
|
, diceroll = require(__dirname+'/diceroll.js') |
|
|
|
, linkmatch = require(__dirname+'/linkmatch.js') |
|
|
|
, linkmatch = require(__dirname+'/linkmatch.js'); |
|
|
|
, replacements = [ |
|
|
|
|
|
|
|
{ regex: pinktextRegex, cb: (match, pinktext) => `<span class='pinktext'><${pinktext}</span>` }, |
|
|
|
let replacements = [] |
|
|
|
{ regex: greentextRegex, cb: (match, greentext) => `<span class='greentext'>>${greentext}</span>` }, |
|
|
|
, markdownPermLevels; |
|
|
|
{ regex: boldRegex, cb: (match, bold) => `<span class='bold'>${bold}</span>` }, |
|
|
|
|
|
|
|
{ regex: underlineRegex, cb: (match, underline) => `<span class='underline'>${underline}</span>` }, |
|
|
|
const updateMarkdownPerms = () => { |
|
|
|
{ regex: strikeRegex, cb: (match, strike) => `<span class='strike'>${strike}</span>` }, |
|
|
|
markdownPermLevels = config.get.permLevels.markdown; |
|
|
|
{ regex: titleRegex, cb: (match, title) => `<span class='title'>${title}</span>` }, |
|
|
|
replacements = [ |
|
|
|
{ regex: italicRegex, cb: (match, italic) => `<span class='em'>${italic}</span>` }, |
|
|
|
{ permLevel: markdownPermLevels.pink, regex: pinktextRegex, cb: (permLevel, match, pinktext) => `<span class='pinktext'><${pinktext}</span>` }, |
|
|
|
{ regex: spoilerRegex, cb: (match, spoiler) => `<span class='spoiler'>${spoiler}</span>` }, |
|
|
|
{ permLevel: markdownPermLevels.green, regex: greentextRegex, cb: (permLevel, match, greentext) => `<span class='greentext'>>${greentext}</span>` }, |
|
|
|
{ regex: monoRegex, cb: (match, mono) => `<span class='mono'>${mono}</span>` }, |
|
|
|
{ permLevel: markdownPermLevels.bold, regex: boldRegex, cb: (permLevel, match, bold) => `<span class='bold'>${bold}</span>` }, |
|
|
|
{ regex: linkRegex, aRegex: aLinkRegex, cb: linkmatch }, |
|
|
|
{ permLevel: markdownPermLevels.underline, regex: underlineRegex, cb: (permLevel, match, underline) => `<span class='underline'>${underline}</span>` }, |
|
|
|
{ regex: detectedRegex, cb: (match, detected) => `<span class='detected'>${detected}</span>` }, |
|
|
|
{ permLevel: markdownPermLevels.strike, regex: strikeRegex, cb: (permLevel, match, strike) => `<span class='strike'>${strike}</span>` }, |
|
|
|
{ regex: diceroll.regexMarkdown, cb: diceroll.markdown }, |
|
|
|
{ permLevel: markdownPermLevels.title, regex: titleRegex, cb: (permLevel, match, title) => `<span class='title'>${title}</span>` }, |
|
|
|
|
|
|
|
{ permLevel: markdownPermLevels.italic, regex: italicRegex, cb: (permLevel, match, italic) => `<span class='em'>${italic}</span>` }, |
|
|
|
|
|
|
|
{ permLevel: markdownPermLevels.spoiler, regex: spoilerRegex, cb: (permLevel, match, spoiler) => `<span class='spoiler'>${spoiler}</span>` }, |
|
|
|
|
|
|
|
{ permLevel: markdownPermLevels.mono, regex: monoRegex, cb: (permLevel, match, mono) => `<span class='mono'>${mono}</span>` }, |
|
|
|
|
|
|
|
{ permLevel: markdownPermLevels.link, regex: linkRegex, cb: linkmatch }, |
|
|
|
|
|
|
|
{ permLevel: markdownPermLevels.detected, regex: detectedRegex, cb: (permLevel, match, detected) => `<span class='detected'>${detected}</span>` }, |
|
|
|
|
|
|
|
{ permLevel: markdownPermLevels.dice, regex: diceroll.regexMarkdown, cb: diceroll.markdown }, |
|
|
|
]; |
|
|
|
]; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updateMarkdownPerms(); |
|
|
|
|
|
|
|
addCallback('config', updateMarkdownPerms); |
|
|
|
|
|
|
|
|
|
|
|
module.exports = { |
|
|
|
module.exports = { |
|
|
|
|
|
|
|
|
|
|
@ -53,7 +63,7 @@ module.exports = { |
|
|
|
return chunks.join(''); |
|
|
|
return chunks.join(''); |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
markdown: (text, allowAdvanced=false) => { |
|
|
|
markdown: (text, permLevel=4) => { |
|
|
|
const chunks = text.split(splitRegex); |
|
|
|
const chunks = text.split(splitRegex); |
|
|
|
const { highlightOptions } = config.get; |
|
|
|
const { highlightOptions } = config.get; |
|
|
|
for (let i = 0; i < chunks.length; i++) { |
|
|
|
for (let i = 0; i < chunks.length; i++) { |
|
|
@ -61,8 +71,8 @@ module.exports = { |
|
|
|
if (i % 2 === 0) { |
|
|
|
if (i % 2 === 0) { |
|
|
|
const escaped = escape(chunks[i]); |
|
|
|
const escaped = escape(chunks[i]); |
|
|
|
const newlineFix = escaped.replace(/^\r?\n/,''); //fix ending newline because of codeblock
|
|
|
|
const newlineFix = escaped.replace(/^\r?\n/,''); //fix ending newline because of codeblock
|
|
|
|
chunks[i] = module.exports.processRegularChunk(newlineFix, allowAdvanced); |
|
|
|
chunks[i] = module.exports.processRegularChunk(newlineFix, permLevel); |
|
|
|
} else { |
|
|
|
} else if (permLevel <= markdownPermLevels.code){ |
|
|
|
chunks[i] = module.exports.processCodeChunk(chunks[i], highlightOptions); |
|
|
|
chunks[i] = module.exports.processCodeChunk(chunks[i], highlightOptions); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -82,19 +92,21 @@ module.exports = { |
|
|
|
return `<span class='code hljs'><small>possible language: ${language}, relevance: ${relevance}</small>\n${value}</span>`; |
|
|
|
return `<span class='code hljs'><small>possible language: ${language}, relevance: ${relevance}</small>\n${value}</span>`; |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (lang !== 'plain' && highlightOptions.languageSubset.includes(lang)) { |
|
|
|
} else if (lang !== 'plain' && highlightOptions.languageSubset.includes(lang)) { |
|
|
|
const { value } = highlight(lang, trimFix, true); |
|
|
|
if (lang === 'aa') { |
|
|
|
return `<span class='code hljs'><small>language: ${lang}</small>\n${value}</span>`; |
|
|
|
return `<span class='aa'>${escape(matches.groups.code)}</span>`; |
|
|
|
} else if (lang === 'aa') { |
|
|
|
} else { |
|
|
|
return `<span class='aa'>${escape(matches.groups.code)}</span>`; |
|
|
|
const { value } = highlight(lang, trimFix, true); |
|
|
|
|
|
|
|
return `<span class='code hljs'><small>language: ${lang}</small>\n${value}</span>`; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return `<span class='code'>${escape(trimFix)}</span>`; |
|
|
|
return `<span class='code'>${escape(trimFix)}</span>`; |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
processRegularChunk: (text, allowAdvanced) => { |
|
|
|
processRegularChunk: (text, permLevel) => { |
|
|
|
for (let i = 0; i < replacements.length; i++) { |
|
|
|
//so theoretically now with some more options in the global manage page you can set permissions or enable/disable markdowns
|
|
|
|
//if allowAdvanced is true, use aRegex if available
|
|
|
|
const allowedReplacements = replacements.filter(r => r.permLevel >= permLevel); |
|
|
|
const replaceRegex = allowAdvanced === true && replacements[i].aRegex || replacements[i].regex; |
|
|
|
for (let i = 0; i < allowedReplacements.length; i++) { |
|
|
|
text = text.replace(replaceRegex, replacements[i].cb); |
|
|
|
text = text.replace(allowedReplacements[i].regex, allowedReplacements[i].cb.bind(null, permLevel)); |
|
|
|
} |
|
|
|
} |
|
|
|
return text; |
|
|
|
return text; |
|
|
|
}, |
|
|
|
}, |
|
|
|