// Converts from Markdown to Pango. This does not support code blocks. // For illogical-impulse, code blocks are treated separately, in their own GtkSourceView widgets. // Partly inherited from https://github.com/ubunatic/md2pango const monospaceFonts = 'JetBrains Mono NF, JetBrains Mono Nerd Font, JetBrains Mono NL, SpaceMono NF, SpaceMono Nerd Font, monospace'; const codeBlockRegex = /^\s*```([a-zA-Z0-9]+)?\n?/; const replacements = { 'indents': [ { name: 'BULLET', re: /^(\s*)([\*\-]\s)(.*)(\s*)$/, sub: ' $1- $3' }, { name: 'NUMBERING', re: /^(\s*[0-9]+\.\s)(.*)(\s*)$/, sub: ' $1 $2' }, ], 'escapes': [ { name: 'COMMENT', re: //, sub: '' }, { name: 'AMPERSTAND', re: /&/g, sub: '&' }, { name: 'LESSTHAN', re: //g, sub: '>' }, ], 'sections': [ { name: 'H1', re: /^(#\s+)(.*)(\s*)$/, sub: '$2' }, { name: 'H2', re: /^(##\s+)(.*)(\s*)$/, sub: '$2' }, { name: 'H3', re: /^(###\s+)(.*)(\s*)$/, sub: '$2' }, { name: 'H4', re: /^(####\s+)(.*)(\s*)$/, sub: '$2' }, { name: 'H5', re: /^(#####\s+)(.*)(\s*)$/, sub: '$2' }, ], 'styles': [ { name: 'BOLD', re: /(\*\*)(\S[\s\S]*?\S)(\*\*)/g, sub: "$2" }, { name: 'UND', re: /(__)(\S[\s\S]*?\S)(__)/g, sub: "$2" }, { name: 'EMPH', re: /\*(\S.*?\S)\*/g, sub: "$1" }, // { name: 'EMPH', re: /_(\S.*?\S)_/g, sub: "$1" }, { name: 'HEXCOLOR', re: /#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/g, sub: '#$1' }, { name: 'INLCODE', re: /(`)([^`]*)(`)/g, sub: '$2' }, // { name: 'UND', re: /(__|\*\*)(\S[\s\S]*?\S)(__|\*\*)/g, sub: "$2" }, ], 'forceLatex': [ { name: 'LATEX_INLINE_SQUARE', re: /\\\[(.*?)\\\]/g, sub: '\n```latex\n$1\n```' }, { name: 'LATEX_INLINE_ROUND', re: /\\\((.*?)\\\)/g, sub: '\n```latex\n$1\n```' }, { name: 'LATEX_INLINE_DOLLAR', re: /\$(.*?)\$/g, sub: '\n```latex\n$1\n```' } ] } const replaceCategory = (text, replaces) => { for (const type of replaces) { text = text.replace(type.re, type.sub); } return text; } // Main function export function replaceInlineLatexWithCodeBlocks(text) { return text.replace(/\\\[(.*?)\\\]|\\\((.*?)\\\)|\$\$(.*?)\$\$|(?:^|[^\w])\$(.*?[^\\])\$(?!\w)/gs, (match, square, round, double, single) => { const latex = square || round || double || single; return `\n\`\`\`latex\n${latex}\n\`\`\`\n`; }); } export default (text) => { let lines = text.split('\n') let output = []; let inCode = false; // Replace for (const line of lines) { let result = line; if (codeBlockRegex.test(line)) inCode = !inCode; if (inCode) continue; result = replaceCategory(result, replacements.indents); result = replaceCategory(result, replacements.escapes); result = replaceCategory(result, replacements.sections); result = replaceCategory(result, replacements.styles); output.push(result) } // Remove trailing whitespaces output = output.map(line => line.replace(/ +$/, '')) return output.join('\n'); } export const markdownTest = `## Inline formatting - **Bold** *Italics* __Underline__ - \`Monospace text\` 🤓 - Colors - Nvidia green #7ABB08 - Soundcloud orange #FF5500 ## Code block \`\`\`cpp #include const std::string GREETING = "UwU"; int main(int argc, char* argv[]) { std::cout << GREETING; } \`\`\` ## LaTeX - Inline LaTeX: \\[ \\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\] - Block LaTeX: \`\`\`latex \\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\\\ → \\\\ cos(2x) = 2cos^2(x) - 1 = 1 - 2sin^2(x) = cos^2(x) - sin^2(x) \`\`\` `;