add parsing of floating links

This commit is contained in:
HF 2021-11-29 05:03:46 +01:00
parent 7060919f76
commit 14726a37ca
3 changed files with 82 additions and 7 deletions

View File

@ -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;
}
}

View File

@ -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;

View File

@ -35,6 +35,12 @@ const MarkdownParagraph = ({ pArray }) => pArray.map((part) => {
<MarkdownParagraph pArray={part[1]} />
</u>
);
case 'l':
return (
<a href={part[2]}>
{part[1]}
</a>
);
default:
return type;
}