diff --git a/src/core/MString.js b/src/core/MString.js index d8480436..9af28695 100644 --- a/src/core/MString.js +++ b/src/core/MString.js @@ -101,4 +101,62 @@ export default class MString { } return false; } + + static isWhiteSpace(chr) { + return (chr === ' ' || chr === '\t' || chr === '\n'); + } + + /* + * Convoluted way to check if the current ':' is part of a link + * we do not check for a 'http' because we might support application links + * like telegram://... or discord://.. + * returns the link or false if there is none + * moves iter forward to after the link, if there's one + */ + checkIfLink() { + let cIter = this.iter; + if (!this.txt.startsWith('://', cIter) || cIter < 3) { + return null; + } + + let linkStart = cIter - 1; + for (; linkStart >= 0 + && !MString.isWhiteSpace(this.txt[linkStart]) + && this.txt[linkStart] !== '('; linkStart -= 1); + linkStart += 1; + + cIter += 3; + /* just some most basic test */ + let dots = 0; + let slashes = 0; + for (; cIter < this.txt.length + && !MString.isWhiteSpace(this.txt[cIter]) + && this.txt[cIter] !== ')'; cIter += 1 + ) { + if (this.txt[cIter] === '.') { + if (slashes !== 0) { + return null; + } + dots += 1; + } else if (this.txt[cIter] === '/') { + slashes += 1; + } + } + if (!dots || (!slashes && this.txt[cIter - 1] === '.')) { + return null; + } + + /* special case where someone pasted a http link after a text + * without space in between + */ + let link = this.txt.slice(linkStart, cIter); + const httpOc = link.indexOf('http'); + if (httpOc !== -1 && httpOc !== 0) { + linkStart += httpOc; + link = this.txt.slice(linkStart, cIter); + } + + this.iter = cIter; + return link; + } } diff --git a/src/core/MarkdownParser.js b/src/core/MarkdownParser.js index b94c1470..272f72e5 100644 --- a/src/core/MarkdownParser.js +++ b/src/core/MarkdownParser.js @@ -41,8 +41,7 @@ function parseMParagraph(text, opts, breakChar) { } pStart = text.iter + 1; text.moveForward(); - } - else if (paraElems.includes(chr)) { + } else if (paraElems.includes(chr)) { /* * bold, cursive, underline, etc. */ @@ -55,12 +54,10 @@ function parseMParagraph(text, opts, breakChar) { } pArray.push([chr, children]); pStart = text.iter + 1; - } - else { + } else { text.setIter(oldPos); } - } - else if (chr === '`') { + } else if (chr === '`') { /* * inline code */ @@ -73,6 +70,20 @@ function parseMParagraph(text, opts, breakChar) { pArray.push(['c', text.slice(oldPos + 1)]); pStart = text.iter + 1; } + } else if (chr === ':') { + /* + * pure link + */ + const link = text.checkIfLink(); + if (link) { + const startLink = text.iter - link.length; + if (pStart < startLink) { + pArray.push(text.slice(pStart, startLink)); + } + pArray.push(['l', link, link]); + pStart = text.iter; + continue; + } } text.moveForward(); @@ -90,7 +101,7 @@ function parseMParagraph(text, opts, breakChar) { */ function parseCodeBlock(text) { text.skipSpaces(false); - if (text.getChar === '\n') { + if (text.getChar() === '\n') { text.moveForward(); } const cbStart = text.iter; diff --git a/utils/markdown-test/Markdown.jsx b/utils/markdown-test/Markdown.jsx index cfb3092f..3bef6742 100644 --- a/utils/markdown-test/Markdown.jsx +++ b/utils/markdown-test/Markdown.jsx @@ -35,6 +35,12 @@ const MarkdownParagraph = ({ pArray }) => pArray.map((part) => { ); + case 'l': + return ( + + {part[1]} + + ); default: return type; }