diff options
author | eug-vs <eug-vs@keemail.me> | 2020-04-05 02:35:03 +0300 |
---|---|---|
committer | eug-vs <eug-vs@keemail.me> | 2020-04-05 02:35:03 +0300 |
commit | 208322f596240d23ff8248733f4b196c1baf8a5a (patch) | |
tree | ee34e3c3882b764dde046169c3ef7a1185024013 /src | |
parent | a35cdfebf2d8c53c77900fee0826d4a967290e5d (diff) | |
download | react-benzin-208322f596240d23ff8248733f4b196c1baf8a5a.tar.gz |
feat: parse all inline styles
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/Markdown/Paragraph.tsx | 81 |
1 files changed, 41 insertions, 40 deletions
diff --git a/src/lib/Markdown/Paragraph.tsx b/src/lib/Markdown/Paragraph.tsx index f433cf5..5ecedfc 100644 --- a/src/lib/Markdown/Paragraph.tsx +++ b/src/lib/Markdown/Paragraph.tsx @@ -4,62 +4,63 @@ interface PropTypes { data: string; } -interface Closures { - [key: string]: string; -} +type RuleName = 'bold' | 'italic' | 'inlineCode' | 'strikeThrough'; -interface Patterns { - [key: string]: RegExp; +interface RuleProperties { + enclosure: string; + style: React.CSSProperties; + pattern?: RegExp; } -interface Styles { - [key: string]: React.CSSProperties; -} +const rules: Record<RuleName, RuleProperties>= { // Order matters - lowest property has highest priority + strikeThrough: { + enclosure: '~~', + style: { textDecoration: 'line-through' }, + }, + inlineCode: { + enclosure: '`', + style: { background: '#444444', padding: '4px' }, + }, + italic: { + enclosure: '\\*', + style: { fontStyle: 'italic' }, + }, + bold: { + enclosure: '\\*\\*', + style: { fontWeight: 'bold' }, + }, +}; +const ruleNames = Object.keys(rules) as RuleName[]; -const captureInside = (closure: string): any => { - return new RegExp(closure + '([^' + closure + ']+)' + closure); +const capture = (enclosure: string): RegExp => { + return new RegExp(enclosure + '([^' + enclosure + ']+)' + enclosure); } -const capture = (closure: string): any => { - return new RegExp('(' + closure + '[^' + closure + ']+' + closure + ')'); +const captureSplit = (enclosure: string): string => { + return '(' + enclosure + '[^' + enclosure + ']+' + enclosure + ')'; } -const closures: Closures = { - inlineCode: '`', - bold: '\\*\\*', -}; - -const styles: Styles = { - inlineCode: { background: '#444444', padding: '4px' }, - bold: { fontWeight: 'bold' }, -}; -const patterns: Patterns = {}; - - -Object.keys(closures).forEach((key: string): void => { - patterns[key] = capture(closures[key]); -}); - -const matcher = new RegExp(Object.values(patterns).map(regex => regex.source).join('|')); - -Object.keys(closures).forEach((key: string): void => { - patterns[key] = captureInside(closures[key]); +const ruleSplitPatterns: string[] = []; +ruleNames.forEach(name => { + rules[name].pattern = capture(rules[name].enclosure); + ruleSplitPatterns.push(captureSplit(rules[name].enclosure)); }); +const splitter = new RegExp(ruleSplitPatterns.join('|')); const SyntaxSpan: React.FC<PropTypes> = ({ data }) => { if (!data) return null; - for (let key in styles) { - const match = data.match(patterns[key]); - if (match) return <span style={styles[key]}>{match[1]}</span>; - }; - return <>{data}</>; + let span = <>{data}</>; + ruleNames.forEach(name => { + const rule = rules[name]; + const match = data.match(rule.pattern || ''); + if (match) span = <span style={rule.style}>{match[1]}</span>; + }); + return span; } const Paragraph: React.FC<PropTypes> = ({ data }) => { - let result; - result = data.split(matcher); - result = result.map(span => <SyntaxSpan data={span} />); + const result = data.split(splitter).map(span => <SyntaxSpan data={span} />); return <p> {result} </p>; } |