start to parse markdown paragraphs
This commit is contained in:
parent
d91bfeb527
commit
87e053f99d
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Markdown parsing
|
||||
*
|
||||
* we do not support all markdown, but do additionally parse extra
|
||||
* stuff like pixelplanet coords and usernames and bare links
|
||||
* We do not support all markdown, but do additionally parse extra
|
||||
* 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
|
||||
*/
|
||||
|
@ -90,12 +92,17 @@ export default class MarkdownParser {
|
|||
) {
|
||||
let iter = start;
|
||||
const mdArray = [];
|
||||
let pArray = [];
|
||||
let paraStart = iter;
|
||||
let lineNr = 0;
|
||||
|
||||
const addParagraph = (start, end) => {
|
||||
/*
|
||||
let paraText = text.slice(start, end);
|
||||
mdArray.push(['p', paraText]);
|
||||
*/
|
||||
mdArray.push(['p', pArray]);
|
||||
pArray = [];
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
@ -187,7 +194,7 @@ export default class MarkdownParser {
|
|||
/*
|
||||
* code block
|
||||
*/
|
||||
if (chr === '`' && text[iter + 1] === '`' && text[iter + 2] === '`') {
|
||||
if (text.startsWith('```', iter)) {
|
||||
if (paraLineStart - 1 > paraStart) {
|
||||
addParagraph(paraStart, paraLineStart - 1);
|
||||
}
|
||||
|
@ -220,13 +227,67 @@ export default class MarkdownParser {
|
|||
continue;
|
||||
}
|
||||
// rest of line
|
||||
for (;iter < text.length && text[iter] !== '\n'; iter += 1) {}
|
||||
iter += 1;
|
||||
const [pPArray, newIter] = this.parseParagraph(text, iter);
|
||||
if (pPArray) {
|
||||
pArray = pArray.concat(pPArray);
|
||||
}
|
||||
iter = newIter;
|
||||
}
|
||||
|
||||
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
|
||||
* @param text
|
||||
|
@ -266,10 +327,7 @@ export default class MarkdownParser {
|
|||
return [['cb', text.slice(cbStart)], iter];
|
||||
}
|
||||
iter = this.skipSpaces(text, iter, true);
|
||||
if (text[iter] === '`'
|
||||
&& text[iter + 1] === '`'
|
||||
&& text[iter + 2] === '`'
|
||||
) {
|
||||
if (text.startsWith('```', iter)) {
|
||||
const nextIter = iter + 3;
|
||||
return [['cb', text.slice(cbStart, iter)], nextIter];
|
||||
}
|
||||
|
|
|
@ -3,6 +3,25 @@
|
|||
*/
|
||||
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 }) => {
|
||||
return mdArray.map((part) => {
|
||||
const type = part[0];
|
||||
|
@ -35,19 +54,10 @@ const Markdown = ({ mdArray }) => {
|
|||
}
|
||||
/* Paragraph */
|
||||
case 'p': {
|
||||
const text = part[1];
|
||||
return (
|
||||
<p className="post-para">
|
||||
{text}
|
||||
</p>
|
||||
);
|
||||
return <MarkdownParagraph pArray={part[1]} />;
|
||||
}
|
||||
/* Code Block */
|
||||
case 'cb': {
|
||||
/*
|
||||
* using pe instead of code because pre
|
||||
* keeps linebreaks
|
||||
*/
|
||||
const content = part[1];
|
||||
return <pre>{content}</pre>;
|
||||
}
|
||||
|
@ -87,7 +97,7 @@ const Markdown = ({ mdArray }) => {
|
|||
);
|
||||
}
|
||||
default:
|
||||
return <p>{part[1]}</p>;
|
||||
return part[0];
|
||||
}
|
||||
})};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ article {
|
|||
border-style: solid;
|
||||
}
|
||||
|
||||
.post-para {
|
||||
article p {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user