From 87e053f99d9f3025725a7fd2eb1981964dc87aec Mon Sep 17 00:00:00 2001 From: HF Date: Sat, 27 Nov 2021 05:29:35 +0100 Subject: [PATCH] start to parse markdown paragraphs --- src/core/MarkdownParser.js | 76 ++++++++++++++++++++++++++++---- utils/markdown-test/Markdown.jsx | 32 +++++++++----- utils/markdown-test/index.css | 2 +- 3 files changed, 89 insertions(+), 21 deletions(-) diff --git a/src/core/MarkdownParser.js b/src/core/MarkdownParser.js index 2ddee53..7f3dd57 100644 --- a/src/core/MarkdownParser.js +++ b/src/core/MarkdownParser.js @@ -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]; } diff --git a/utils/markdown-test/Markdown.jsx b/utils/markdown-test/Markdown.jsx index d7a500a..7aa8f9c 100644 --- a/utils/markdown-test/Markdown.jsx +++ b/utils/markdown-test/Markdown.jsx @@ -3,6 +3,25 @@ */ import React from 'react'; +const MarkdownParagraph = ({ pArray }) => ( +

+ { + pArray.map((part) => { + if (!Array.isArray(part)) { + return part; + } + const type = part[0]; + switch (type) { + case 'c': + return ({part[1]}); + default: + return type; + } + }) + } +

+); + 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 ( -

- {text} -

- ); + return ; } /* Code Block */ case 'cb': { - /* - * using pe instead of code because pre - * keeps linebreaks - */ const content = part[1]; return
{content}
; } @@ -87,7 +97,7 @@ const Markdown = ({ mdArray }) => { ); } default: - return

{part[1]}

; + return part[0]; } })}; diff --git a/utils/markdown-test/index.css b/utils/markdown-test/index.css index a58a4c3..2f0fe7d 100644 --- a/utils/markdown-test/index.css +++ b/utils/markdown-test/index.css @@ -2,7 +2,7 @@ article { border-style: solid; } -.post-para { +article p { white-space: pre-line; }