'use strict'; const greentextRegex = /^>((?!>\d+|>>/\w+(/\d*)?|>>#/).*)/gm , pinktextRegex = /^<(.+)/gm , boldRegex = /''(.+?)''/gm , titleRegex = /==(.+?)==/gm , monoRegex = /`(.+?)`/gm , underlineRegex = /__(.+?)__/gm , strikeRegex = /~~(.+?)~~/gm , italicRegex = /\*\*(.+?)\*\*/gm , spoilerRegex = /\|\|([\s\S]+?)\|\|/gm , detectedRegex = /(\(\(\(.+?\)\)\))/gm , linkRegex = /\[([^\[][^\]]*?)\]\((https?\://[^\s<>\[\]{}|\\^)]+)\)|(https\://[^\s<>\[\]{}|\\^]+)/g , codeRegex = /(?:(?[a-z+]{1,10})\r?\n)?(?[\s\S]+)/i , includeSplitRegex = /(\[code\][\s\S]+?\[\/code\])/gm , splitRegex = /\[code\]([\s\S]+?)\[\/code\]/gm , trimNewlineRegex = /^\s*(\r?\n)*|(\r?\n)*$/g , escape = require(__dirname+'/escape.js') , { highlight, highlightAuto } = require('highlight.js') , { highlightOptions } = require(__dirname+'/../../configs/main.js') , diceroll = require(__dirname+'/diceroll.js') , linkmatch = require(__dirname+'/linkmatch.js') , replacements = [ { regex: pinktextRegex, cb: (match, pinktext) => `<${pinktext}` }, { regex: greentextRegex, cb: (match, greentext) => `>${greentext}` }, { regex: boldRegex, cb: (match, bold) => `${bold}` }, { regex: underlineRegex, cb: (match, underline) => `${underline}` }, { regex: strikeRegex, cb: (match, strike) => `${strike}` }, { regex: titleRegex, cb: (match, title) => `${title}` }, { regex: italicRegex, cb: (match, italic) => `${italic}` }, { regex: spoilerRegex, cb: (match, spoiler) => `${spoiler}` }, { regex: monoRegex, cb: (match, mono) => `${mono}` }, { regex: linkRegex, cb: linkmatch }, { regex: detectedRegex, cb: (match, detected) => `${detected}` }, { regex: diceroll.regexMarkdown, cb: diceroll.markdown }, ]; module.exports = { prepareMarkdown: (text, force) => { if (!text || text.length === 0) { return text; } const chunks = text.split(includeSplitRegex); for (let i = 0; i < chunks.length; i++) { //every other chunk will be a code block if (i % 2 === 0) { chunks[i] = chunks[i].replace( diceroll.regexPrepare, diceroll.prepare(force)); } } return chunks.join(''); }, markdown: (text) => { const chunks = text.split(splitRegex); for (let i = 0; i < chunks.length; i++) { //every other chunk will be a code block if (i % 2 === 0) { const escaped = escape(chunks[i]); const newlineFix = escaped.replace(/^\r?\n/,''); //fix ending newline because of codeblock chunks[i] = module.exports.processRegularChunk(newlineFix); } else { chunks[i] = module.exports.processCodeChunk(chunks[i]); } } return chunks.join(''); }, processCodeChunk: (text) => { const matches = text.match(codeRegex); const trimFix = matches.groups.code.replace(trimNewlineRegex, ''); let lang; if (matches.groups.language && matches.groups.language.length > 0) { lang = matches.groups.language.toLowerCase(); } if (!lang) { const { language, relevance, value } = highlightAuto(trimFix, highlightOptions.languageSubset); if (relevance > highlightOptions.threshold) { return `possible language: ${language}, relevance: ${relevance}\n${value}`; } } else if (lang !== 'plain' && highlightOptions.languageSubset.includes(lang)) { const { value } = highlight(lang, trimFix, true); return `language: ${lang}\n${value}`; } else if (lang === 'aa') { return `${escape(matches.groups.code)}`; } return `${escape(trimFix)}`; }, processRegularChunk: (text) => { for (let i = 0; i < replacements.length; i++) { text = text.replace(replacements[i].regex, replacements[i].cb); } return text; }, }