aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Markdown
diff options
context:
space:
mode:
authorEug-VS <eug-vs@keemail.me>2020-04-04 22:05:40 +0300
committerEug-VS <eug-vs@keemail.me>2020-04-04 22:05:40 +0300
commitbdcc2edb38fb0e57604fa12d25b2a4b478261e18 (patch)
tree71aaedf7f4500cfcab9bd4f344b326dadd71d392 /src/lib/Markdown
parent464b5fbef2f58cbcd134b7200c5f7c2f904202a0 (diff)
downloadreact-benzin-bdcc2edb38fb0e57604fa12d25b2a4b478261e18.tar.gz
refactor: structurize Markdown component :recycle:
Diffstat (limited to 'src/lib/Markdown')
-rw-r--r--src/lib/Markdown/CodeBlock.tsx13
-rw-r--r--src/lib/Markdown/Content.tsx34
-rw-r--r--src/lib/Markdown/Markdown.tsx71
-rw-r--r--src/lib/Markdown/Section.tsx39
-rw-r--r--src/lib/Markdown/types.d.ts4
5 files changed, 92 insertions, 69 deletions
diff --git a/src/lib/Markdown/CodeBlock.tsx b/src/lib/Markdown/CodeBlock.tsx
new file mode 100644
index 0000000..e449f92
--- /dev/null
+++ b/src/lib/Markdown/CodeBlock.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import { ParserPropTypes } from './types';
+
+const CodeBlock: React.FC<ParserPropTypes> = ({ rawLines }) => {
+ return (
+ <p style={{background: '#444444'}}>
+ {rawLines.map(line => <> {line} <br/> </>)}
+ </p>
+ );
+}
+
+export default CodeBlock;
+
diff --git a/src/lib/Markdown/Content.tsx b/src/lib/Markdown/Content.tsx
new file mode 100644
index 0000000..b7829ed
--- /dev/null
+++ b/src/lib/Markdown/Content.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+
+import CodeBlock from './CodeBlock';
+import { ParserPropTypes } from './types';
+
+
+const denotesCodeBlock = (line: string): boolean => {
+ return line.slice(0, 3) === '```';
+}
+
+const Content: React.FC<ParserPropTypes> = ({ rawLines }) => {
+ if (!rawLines.length) return null;
+
+ const line = rawLines.splice(0, 1)[0];
+
+ let result;
+ if (denotesCodeBlock(line)) {
+ const closeIndex = rawLines.findIndex(line => denotesCodeBlock(line));
+ const codeBlockLines = rawLines.splice(0, closeIndex);
+ result = <CodeBlock rawLines={codeBlockLines} />
+ } else {
+ result = <p> {line} </p>
+ }
+
+ return (
+ <>
+ { result }
+ <Content rawLines={rawLines} />
+ </>
+ )
+}
+
+export default Content;
+
diff --git a/src/lib/Markdown/Markdown.tsx b/src/lib/Markdown/Markdown.tsx
index 8d93437..aee96e9 100644
--- a/src/lib/Markdown/Markdown.tsx
+++ b/src/lib/Markdown/Markdown.tsx
@@ -1,84 +1,17 @@
import React, { useState } from 'react';
import axios from 'axios';
-import ContentSection from '../ContentSection/ContentSection';
-
+import Section from './Section';
interface PropTypes {
data?: string;
url?: string;
}
-interface RawLinesPropType {
- rawLines: string[];
- level?: number;
-}
-
-const header = (level: number): string => {
- return `^#{${level}} .*$`;
-}
-
-const CodeBlock: React.FC<{ rawLines: String[]}> = ({ rawLines }) => {
- return (
- <p style={{background: '#444444'}}>
- {rawLines.map(line => <> {line} <br/> </>)}
- </p>
- );
-}
-
-
-const Content: React.FC<RawLinesPropType> = ({ rawLines }) => {
- if (!rawLines.length) return <></>;
- const line = rawLines[0];
- const otherLines = rawLines.slice(1);
- if (line.slice(0, 3) === '```') {
- const closeIndex = otherLines.findIndex(line => line.slice(0, 3) === '```');
- console.log({ line, otherLines, closeIndex });
- return (
- <>
- <CodeBlock rawLines={otherLines.slice(0, closeIndex)} />
- <Content rawLines={otherLines.slice(closeIndex + 1)} />
- </>
- )
- }
- return (
- <>
- <p> {line} </p>
- <Content rawLines={rawLines.slice(1)} />
- </>
- )
-}
-
-const Level: React.FC<RawLinesPropType> = ({ rawLines, level = 0 }) => {
- const name = rawLines[0].slice(level);
- const contentSize = rawLines.findIndex(line => line.match(header(level + 1)));
-
- const rawContent = (contentSize > 0) ? rawLines.slice(1, contentSize) : rawLines.slice(1);
- const rawChildren = rawLines.slice(contentSize);
-
- const childrenLineGroups = rawChildren.reduce((acc: string[][], cur: string) => {
- if (cur.match(header(level + 1))) acc.push([]);
- if (acc.length) acc[acc.length - 1].push(cur);
- return acc;
- }, []);
- const children = childrenLineGroups.map(lineGroup => <Level rawLines={lineGroup} level={level + 1}/>)
-
- return level ? (
- <ContentSection sectionName={name}>
- <Content rawLines={rawContent} />
- {children}
- </ContentSection>
- ) : (
- <>
- {children}
- </>
- );
-}
-
const Markdown: React.FC<PropTypes> = ({ data, url }) => {
const [markdown, setMarkdown] = useState<string>(data || '');
if (url) axios.get(url).then(response => setMarkdown(response.data));
- return <Level rawLines={markdown.split('\n')} />
+ return <Section rawLines={markdown.split('\n')} />
};
diff --git a/src/lib/Markdown/Section.tsx b/src/lib/Markdown/Section.tsx
new file mode 100644
index 0000000..c902379
--- /dev/null
+++ b/src/lib/Markdown/Section.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import ContentSection from '../ContentSection/ContentSection';
+import Content from './Content';
+import { ParserPropTypes } from './types';
+
+interface PropTypes extends ParserPropTypes {
+ level?: number;
+}
+
+const matchHeaderLevel = (line: string, level: number): boolean => {
+ return line.match(`^#{${level}} .*$`) !== null;
+}
+
+const Section: React.FC<PropTypes> = ({ rawLines, level = 0 }) => {
+ const sectionName = rawLines.splice(0, 1)[0].slice(level).trim();
+ const contentSize = rawLines.findIndex(line => matchHeaderLevel(line, level + 1));
+ const rawContent = rawLines.splice(0, (contentSize < 0) ? rawLines.length : contentSize);
+
+ const childrenSectionLines = rawLines.reduce((sections: string[][], line: string) => {
+ if (matchHeaderLevel(line, level + 1)) sections.push([]);
+ if (sections.length) sections[sections.length - 1].push(line);
+ return sections;
+ }, []);
+ const children = childrenSectionLines.map(sectionLines => <Section rawLines={sectionLines} level={level + 1}/>)
+
+ return level ? (
+ <ContentSection sectionName={sectionName}>
+ <Content rawLines={rawContent} />
+ {children}
+ </ContentSection>
+ ) : (
+ <>
+ {children}
+ </>
+ );
+}
+
+export default Section;
+
diff --git a/src/lib/Markdown/types.d.ts b/src/lib/Markdown/types.d.ts
new file mode 100644
index 0000000..0b6f4b6
--- /dev/null
+++ b/src/lib/Markdown/types.d.ts
@@ -0,0 +1,4 @@
+export interface ParserPropTypes {
+ rawLines: string[];
+}
+