From 828946eb02bdfaa7ec5631f1e854881f874f7b7e Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sun, 5 Apr 2020 22:06:54 +0300 Subject: refactor: rename InlineSyntax -> SyntacticSpan --- src/lib/Markdown/Content.tsx | 3 +- src/lib/Markdown/InlineSyntax.tsx | 93 ------------------------------------ src/lib/Markdown/SyntacticSpan.tsx | 96 ++++++++++++++++++++++++++++++++++++++ src/lib/Markdown/Text.tsx | 11 +++-- 4 files changed, 104 insertions(+), 99 deletions(-) delete mode 100644 src/lib/Markdown/InlineSyntax.tsx create mode 100644 src/lib/Markdown/SyntacticSpan.tsx (limited to 'src/lib/Markdown') diff --git a/src/lib/Markdown/Content.tsx b/src/lib/Markdown/Content.tsx index e27b63f..caac91c 100644 --- a/src/lib/Markdown/Content.tsx +++ b/src/lib/Markdown/Content.tsx @@ -2,7 +2,6 @@ import React from 'react'; import CodeBlock from './CodeBlock'; import Text from './Text'; -import InlineSyntax from './InlineSyntax'; import { ParserPropTypes } from './types'; @@ -44,7 +43,7 @@ const Content: React.FC = ({ rawLines }) => { const closeIndex = rawLines.findIndex(line => !denotesDottedList(line)); const dottedListLines = rawLines.splice(0, closeIndex).slice(0, closeIndex); dottedListLines.unshift(line); - buffer = ; + buffer = ; } else if (denotesOpenHtml(line)) { const tag = denotesOpenHtml(line); const closeIndex = rawLines.findIndex(line => denotesClosingHtml(line, tag)); diff --git a/src/lib/Markdown/InlineSyntax.tsx b/src/lib/Markdown/InlineSyntax.tsx deleted file mode 100644 index 53cdaf0..0000000 --- a/src/lib/Markdown/InlineSyntax.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react'; -import { Link, makeStyles } from '@material-ui/core'; - -import { lib as emojiLib } from 'emojilib'; -import { InlineParserPropTypes } from './types'; - -interface RegexPair { - global: RegExp; - local: RegExp; -} - -interface Emoji { - name: string; - char: string; -} - -const enclosureRegex = (e: string): RegexPair => ({ - local: new RegExp(`${e}([^${e}]+)${e}`), - global: new RegExp(`(${e}[^${e}]+${e})`) -}); - -const regex: Record = { - conceal: { - global: /(!?\[.+?\]\(.+?\))/g, - local: /!?\[(.+?)\]\((.+?)\)/ - }, - rawLink: { - global: /((?:(?:[A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www\.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)(?:(?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/\\\w]*))?)/, - local: /&^/ - }, - emoji: enclosureRegex(':'), - bold: enclosureRegex('\\*\\*'), - italic: enclosureRegex('\\*'), - code: enclosureRegex('`'), - strikeThrough: enclosureRegex('~~'), -} - -const splitter = new RegExp(Object.values(regex).map(pair => pair.global.source).join('|')); - -const emojiList: Emoji[] = []; -Object.keys(emojiLib).forEach(name => emojiList.push({ name, char: emojiLib[name].char })); -console.log({emojiList}) - -const useStyles = makeStyles(theme => ({ - code: { - background: theme.palette.background.default, - borderRadius: theme.spacing(.5), - padding: theme.spacing(.5), - fontFamily: 'Monospace', - }, - image: { - maxWidth: '100%', - maxHeight: '100%' - }, -})); - -const InlineSyntax: React.FC = ({ line }) => { - const classes = useStyles(); - if (!line) return null; - - const matchConceal = regex.conceal.local.exec(line); - if (matchConceal) { - if (line[0] === '!') return {matchConceal[1]}; - return {matchConceal[1]}; - } - - const matchEmoji = line.match(regex.emoji.local); - if (matchEmoji) { - const emoji = emojiList.find(emoji => emoji.name === matchEmoji[1]); - return {emoji ? emoji.char : line}; - } - - const matchCode = line.match(regex.code.local); - if (matchCode) return {matchCode[1]}; - - const matchBold = line.match(regex.bold.local); - if (matchBold) return {matchBold[1]}; - - const matchItalic = line.match(regex.italic.local); - if (matchItalic) return {matchItalic[1]}; - - const matchStrikeThrough = line.match(regex.strikeThrough.local); - if (matchStrikeThrough) return {matchStrikeThrough[1]}; - - if (line.match(regex.rawLink.global)) return {line}; - - return <>{line}; -} - - -export { splitter }; -export default InlineSyntax; - diff --git a/src/lib/Markdown/SyntacticSpan.tsx b/src/lib/Markdown/SyntacticSpan.tsx new file mode 100644 index 0000000..299bf87 --- /dev/null +++ b/src/lib/Markdown/SyntacticSpan.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { Link, makeStyles } from '@material-ui/core'; + +import { lib as emojiLib } from 'emojilib'; + +interface PropTypes { + span: string; +} + +interface RegexPair { + global: RegExp; + local: RegExp; +} + +interface Emoji { + name: string; + char: string; +} + +const enclosureRegex = (e: string): RegexPair => ({ + local: new RegExp(`${e}([^${e}]+)${e}`), + global: new RegExp(`(${e}[^${e}]+${e})`) +}); + +const regex: Record = { + conceal: { + global: /(!?\[.+?\]\(.+?\))/g, + local: /!?\[(.+?)\]\((.+?)\)/ + }, + rawLink: { + global: /((?:(?:[A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www\.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)(?:(?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/\\\w]*))?)/, + local: /&^/ + }, + emoji: enclosureRegex(':'), + bold: enclosureRegex('\\*\\*'), + italic: enclosureRegex('\\*'), + code: enclosureRegex('`'), + strikeThrough: enclosureRegex('~~'), +} + +const splitter = new RegExp(Object.values(regex).map(pair => pair.global.source).join('|')); + +const emojiList: Emoji[] = []; +Object.keys(emojiLib).forEach(name => emojiList.push({ name, char: emojiLib[name].char })); +console.log({emojiList}) + +const useStyles = makeStyles(theme => ({ + code: { + background: theme.palette.background.default, + borderRadius: theme.spacing(.5), + padding: theme.spacing(.5), + fontFamily: 'Monospace', + }, + image: { + maxWidth: '100%', + maxHeight: '100%' + }, +})); + +const SyntacticSpan: React.FC = ({ span }) => { + const classes = useStyles(); + if (!span) return null; + + const matchConceal = regex.conceal.local.exec(span); + if (matchConceal) { + if (span[0] === '!') return {matchConceal[1]}; + return {matchConceal[1]}; + } + + const matchEmoji = span.match(regex.emoji.local); + if (matchEmoji) { + const emoji = emojiList.find(emoji => emoji.name === matchEmoji[1]); + return {emoji ? emoji.char : span}; + } + + const matchCode = span.match(regex.code.local); + if (matchCode) return {matchCode[1]}; + + const matchBold = span.match(regex.bold.local); + if (matchBold) return {matchBold[1]}; + + const matchItalic = span.match(regex.italic.local); + if (matchItalic) return {matchItalic[1]}; + + const matchStrikeThrough = span.match(regex.strikeThrough.local); + if (matchStrikeThrough) return {matchStrikeThrough[1]}; + + if (span.match(regex.rawLink.global)) return {span}; + + return <>{span}; +} + + +export { splitter }; +export default SyntacticSpan; + diff --git a/src/lib/Markdown/Text.tsx b/src/lib/Markdown/Text.tsx index b989476..e287dee 100644 --- a/src/lib/Markdown/Text.tsx +++ b/src/lib/Markdown/Text.tsx @@ -1,9 +1,12 @@ import React from 'react'; -import { InlineParserPropTypes } from './types'; -import InlineSyntax, { splitter } from './InlineSyntax'; +import SyntacticSpan, { splitter } from './SyntacticSpan'; -const Text: React.FC = ({ line }) => { - return <>{line.split(splitter).map(span => )}; +interface PropTypes { + line: string; +} + +const Text: React.FC = ({ line }) => { + return <>{line.split(splitter).map(span => )}; } export default Text; -- cgit v1.2.3