start to parse markdown paragraphs

This commit is contained in:
HF 2021-11-27 05:29:35 +01:00
parent d91bfeb527
commit 87e053f99d
3 changed files with 89 additions and 21 deletions

View File

@ -1,8 +1,10 @@
/* /*
* Markdown parsing * Markdown parsing
* *
* we do not support all markdown, but do additionally parse extra * We do not support all markdown, but do additionally parse extra
* stuff like pixelplanet coords and usernames and bare links * stuff like pixelplanet coords and usernames and bare links.
* This code is written in preparation for a possible imporementation in
* WebAssambly, so it's all in a big loop
* *
* @flow * @flow
*/ */
@ -90,12 +92,17 @@ export default class MarkdownParser {
) { ) {
let iter = start; let iter = start;
const mdArray = []; const mdArray = [];
let pArray = [];
let paraStart = iter; let paraStart = iter;
let lineNr = 0; let lineNr = 0;
const addParagraph = (start, end) => { const addParagraph = (start, end) => {
/*
let paraText = text.slice(start, end); let paraText = text.slice(start, end);
mdArray.push(['p', paraText]); mdArray.push(['p', paraText]);
*/
mdArray.push(['p', pArray]);
pArray = [];
} }
while (true) { while (true) {
@ -187,7 +194,7 @@ export default class MarkdownParser {
/* /*
* code block * code block
*/ */
if (chr === '`' && text[iter + 1] === '`' && text[iter + 2] === '`') { if (text.startsWith('```', iter)) {
if (paraLineStart - 1 > paraStart) { if (paraLineStart - 1 > paraStart) {
addParagraph(paraStart, paraLineStart - 1); addParagraph(paraStart, paraLineStart - 1);
} }
@ -220,13 +227,67 @@ export default class MarkdownParser {
continue; continue;
} }
// rest of line // rest of line
for (;iter < text.length && text[iter] !== '\n'; iter += 1) {} const [pPArray, newIter] = this.parseParagraph(text, iter);
iter += 1; if (pPArray) {
pArray = pArray.concat(pPArray);
}
iter = newIter;
} }
return [mdArray, iter]; return [mdArray, iter];
} }
/*
* go to character in line
* return position of character or null if not found before next line
*/
goToCharInLine(text, start, chr) {
let iter = start;
for (;iter < text.length && text[iter] !== '\n' && text[iter] !== chr; iter += 1) {}
if (text[iter] === chr) {
return iter;
}
return null;
}
/*
* Parse Paragraph till next newline
*/
parseParagraph(text, start) {
const pArray = [];
let iter = start;
let pStart = start;
let pEnd = 0;
for (;iter < text.length && text[iter] !== '\n'; iter += 1) {
let newElem = null;
if (text[iter] === '`') {
const pos = this.goToCharInLine(text, iter + 1, '`');
if (pos) {
newElem = ['c', text.slice(iter + 1, pos)];
pEnd = iter;
iter = pos;
}
}
/*
else if (text.startsWith('**', iter) {
}
*/
if (pEnd) {
if (pStart !== pEnd) {
pArray.push(text.slice(pStart, pEnd));
}
pStart = iter + 1;
pEnd = 0;
pArray.push(newElem);
}
}
iter += 1;
if (pStart !== iter) {
pArray.push(text.slice(pStart, iter));
}
return [pArray, iter];
}
/* /*
* get indentation of line * get indentation of line
* @param text * @param text
@ -266,10 +327,7 @@ export default class MarkdownParser {
return [['cb', text.slice(cbStart)], iter]; return [['cb', text.slice(cbStart)], iter];
} }
iter = this.skipSpaces(text, iter, true); iter = this.skipSpaces(text, iter, true);
if (text[iter] === '`' if (text.startsWith('```', iter)) {
&& text[iter + 1] === '`'
&& text[iter + 2] === '`'
) {
const nextIter = iter + 3; const nextIter = iter + 3;
return [['cb', text.slice(cbStart, iter)], nextIter]; return [['cb', text.slice(cbStart, iter)], nextIter];
} }

View File

@ -3,6 +3,25 @@
*/ */
import React from 'react'; import React from 'react';
const MarkdownParagraph = ({ pArray }) => (
<p>
{
pArray.map((part) => {
if (!Array.isArray(part)) {
return part;
}
const type = part[0];
switch (type) {
case 'c':
return (<code>{part[1]}</code>);
default:
return type;
}
})
}
</p>
);
const Markdown = ({ mdArray }) => { const Markdown = ({ mdArray }) => {
return mdArray.map((part) => { return mdArray.map((part) => {
const type = part[0]; const type = part[0];
@ -35,19 +54,10 @@ const Markdown = ({ mdArray }) => {
} }
/* Paragraph */ /* Paragraph */
case 'p': { case 'p': {
const text = part[1]; return <MarkdownParagraph pArray={part[1]} />;
return (
<p className="post-para">
{text}
</p>
);
} }
/* Code Block */ /* Code Block */
case 'cb': { case 'cb': {
/*
* using pe instead of code because pre
* keeps linebreaks
*/
const content = part[1]; const content = part[1];
return <pre>{content}</pre>; return <pre>{content}</pre>;
} }
@ -87,7 +97,7 @@ const Markdown = ({ mdArray }) => {
); );
} }
default: default:
return <p>{part[1]}</p>; return part[0];
} }
})}; })};

View File

@ -2,7 +2,7 @@ article {
border-style: solid; border-style: solid;
} }
.post-para { article p {
white-space: pre-line; white-space: pre-line;
} }