forked from ppfun/pixelplanet
add parsing of []() enclosures
This commit is contained in:
parent
f6c348bab0
commit
cd485f4259
|
@ -106,10 +106,75 @@ export default class MString {
|
|||
return (chr === ' ' || chr === '\t' || chr === '\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* check if the current '[' is part of a [y](z) enclosure
|
||||
* returns [y, z] if it is enclosure, null otherwise
|
||||
* moves iter to last closing braked if it is enclosure
|
||||
*/
|
||||
checkIfEnclosure(zIsLink) {
|
||||
const yStart = this.iter + 1;
|
||||
|
||||
let yEnd = yStart;
|
||||
while (this.txt[yEnd] !== ']') {
|
||||
const chr = this.txt[yEnd];
|
||||
if (yEnd >= this.txt.length
|
||||
|| chr === '\n'
|
||||
|| chr === '['
|
||||
|| chr === '('
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
yEnd += 1;
|
||||
}
|
||||
|
||||
let zStart = yEnd + 1;
|
||||
if (this.txt[zStart] !== '(') {
|
||||
return null;
|
||||
}
|
||||
zStart += 1;
|
||||
|
||||
let zEnd = zStart;
|
||||
let z = null;
|
||||
while (this.txt[zEnd] !== ')') {
|
||||
const chr = this.txt[zEnd];
|
||||
if (zEnd >= this.txt.length
|
||||
|| chr === '\n'
|
||||
|| chr == '['
|
||||
|| chr == '('
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (zIsLink && chr === ':') {
|
||||
// set this.iter temporarily to be able to use thischeckIfLink
|
||||
const oldIter = this.iter;
|
||||
this.iter = zEnd;
|
||||
z = this.checkIfLink();
|
||||
zEnd = this.iter;
|
||||
this.iter = oldIter;
|
||||
if (z === null) {
|
||||
return null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
zEnd += 1;
|
||||
}
|
||||
if (zEnd < zStart + 1 || ( !z && zIsLink )) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!zIsLink) {
|
||||
z = this.txt.slice(zStart, zEnd);
|
||||
}
|
||||
const y = this.txt.slice(yStart, yEnd);
|
||||
|
||||
this.iter = zEnd;
|
||||
return [y, z];
|
||||
}
|
||||
|
||||
/*
|
||||
* 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://..
|
||||
* like tg://... or discord://..
|
||||
* returns the link or false if there is none
|
||||
* moves iter forward to after the link, if there's one
|
||||
*/
|
||||
|
@ -126,26 +191,14 @@ export default class MString {
|
|||
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] === '.')) {
|
||||
);
|
||||
if (cIter < this.iter + 4) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* special case where someone pasted a http link after a text
|
||||
* without space in between
|
||||
*/
|
||||
|
|
|
@ -75,15 +75,45 @@ function parseMParagraph(text, opts, breakChar) {
|
|||
* pure link
|
||||
*/
|
||||
const link = text.checkIfLink();
|
||||
if (link) {
|
||||
if (link !== null) {
|
||||
const startLink = text.iter - link.length;
|
||||
if (pStart < startLink) {
|
||||
pArray.push(text.slice(pStart, startLink));
|
||||
}
|
||||
pArray.push(['l', link, link]);
|
||||
pArray.push(['l', null, link]);
|
||||
pStart = text.iter;
|
||||
continue;
|
||||
}
|
||||
} else if (chr === '[') {
|
||||
/*
|
||||
* x[y](z) enclosure
|
||||
*/
|
||||
let oldPos = text.iter;
|
||||
let x = null;
|
||||
if (text.iter > 0) {
|
||||
text.move(-1);
|
||||
x = text.getChar();
|
||||
text.setIter(oldPos);
|
||||
}
|
||||
/*
|
||||
* x decides what element it is
|
||||
* defaults to ordinary link
|
||||
*/
|
||||
let tag = 'l'
|
||||
let zIsLink = true;
|
||||
if (x === '!') {
|
||||
tag = 'img';
|
||||
oldPos -= 1;
|
||||
}
|
||||
|
||||
const encArr = text.checkIfEnclosure(zIsLink);
|
||||
if (encArr !== null) {
|
||||
if (pStart < oldPos) {
|
||||
pArray.push(text.slice(pStart, oldPos));
|
||||
}
|
||||
pArray.push([tag, encArr[0], encArr[1]]);
|
||||
pStart = text.iter + 1;
|
||||
}
|
||||
}
|
||||
|
||||
text.moveForward();
|
||||
|
|
|
@ -3,6 +3,34 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
|
||||
/*
|
||||
* gets a descriptive text of the domain of the link
|
||||
* Example:
|
||||
* https://www.youtube.com/watch?v=G8APgeFfkAk returns 'youtube'
|
||||
* http://www.google.at returns 'google.at'
|
||||
* (www. and .com are split)
|
||||
*/
|
||||
function getLinkDesc(link) {
|
||||
let domainStart = link.indexOf('://') + 3;
|
||||
if (domainStart < 3) {
|
||||
domainStart = 0;
|
||||
}
|
||||
if (link.startsWith('www.', domainStart)) {
|
||||
domainStart += 4;
|
||||
}
|
||||
let domainEnd = link.indexOf('/', domainStart);
|
||||
if (domainEnd === -1) {
|
||||
domainEnd = link.length;
|
||||
}
|
||||
if (link.endsWith('.com', domainEnd)) {
|
||||
domainEnd -= 4;
|
||||
}
|
||||
if (domainEnd <= domainStart) {
|
||||
return link;
|
||||
}
|
||||
return link.slice(domainStart, domainEnd);
|
||||
}
|
||||
|
||||
const MarkdownParagraph = ({ pArray }) => pArray.map((part) => {
|
||||
if (!Array.isArray(part)) {
|
||||
return part;
|
||||
|
@ -35,19 +63,32 @@ const MarkdownParagraph = ({ pArray }) => pArray.map((part) => {
|
|||
<MarkdownParagraph pArray={part[1]} />
|
||||
</u>
|
||||
);
|
||||
case 'l':
|
||||
case 'l': {
|
||||
let title = getLinkDesc(part[2]);
|
||||
if (part[1]) {
|
||||
title += ` | ${part[1]}`;
|
||||
}
|
||||
return (
|
||||
<a href={part[2]}>
|
||||
{part[1]}
|
||||
{title}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
case 'img': {
|
||||
let title = getLinkDesc(part[2]);
|
||||
if (part[1]) {
|
||||
title += ` | ${part[1]}`;
|
||||
}
|
||||
return (
|
||||
<img src={part[2]} title={part[1] || title} alt={title} />
|
||||
);
|
||||
}
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
});
|
||||
|
||||
const Markdown = ({ mdArray }) => {
|
||||
return mdArray.map((part) => {
|
||||
const Markdown = ({ mdArray }) => mdArray.map((part) => {
|
||||
const type = part[0];
|
||||
switch (type) {
|
||||
/* Heading */
|
||||
|
@ -127,7 +168,7 @@ const Markdown = ({ mdArray }) => {
|
|||
default:
|
||||
return part[0];
|
||||
}
|
||||
})};
|
||||
});
|
||||
|
||||
const MarkdownArticle = ({ mdArray }) => (
|
||||
<article>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Markdown parser testing
|
||||
|
||||
Code to test markdown parsing, run `npx webpack` to build and open index.html
|
||||
|
||||
No npm install in this folder neccessary, it takes the packages from the parent project
|
||||
|
|
|
@ -22,7 +22,7 @@ var babelPlugins = [
|
|||
module.exports = {
|
||||
name: 'script',
|
||||
target: 'web',
|
||||
mode: 'production',
|
||||
mode: 'development',
|
||||
|
||||
entry: [ path.resolve(__dirname, './mdtest.js') ],
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user