diff options
author | eug-vs <eugene@eug-vs.xyz> | 2022-09-23 13:14:11 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2022-09-23 13:14:11 +0300 |
commit | 4df5503f3e06761a7096324f8e093ab4c1afefa7 (patch) | |
tree | 551dd6d3cbaab637d5b777615987657c02d8b9a2 | |
parent | 2a287f317a51f5f02b643af0acf2733cadbb8081 (diff) | |
download | benzin-next-4df5503f3e06761a7096324f8e093ab4c1afefa7.tar.gz |
feat: add emoji plugin
-rw-r--r-- | src/Emoji.tsx | 19 | ||||
-rw-r--r-- | src/emojiPlugin.tsx | 48 | ||||
-rw-r--r-- | src/pages/[...path].tsx | 35 | ||||
-rw-r--r-- | src/pages/_app.tsx | 4 |
4 files changed, 95 insertions, 11 deletions
diff --git a/src/Emoji.tsx b/src/Emoji.tsx new file mode 100644 index 0000000..b928087 --- /dev/null +++ b/src/Emoji.tsx @@ -0,0 +1,19 @@ +import { FC } from 'react'; +import Image from 'next/future/image'; + +interface Props { + children: string[]; +} + +const Emoji: FC<Props> = ({ children }) => { + const src = children[0]; + return ( + <Image + src={`/emoji/${src}`} + width={16} + alt={`${src}-emoji`} + /> + ); +} + +export default Emoji; diff --git a/src/emojiPlugin.tsx b/src/emojiPlugin.tsx new file mode 100644 index 0000000..a408ed7 --- /dev/null +++ b/src/emojiPlugin.tsx @@ -0,0 +1,48 @@ +import _ from 'lodash'; +import { Node } from 'unist'; +import { visitParents } from 'unist-util-visit-parents' + + +const emojiPlugin = (emojiFileNames: string[]) => () => { + const visitor = (node: any, ancestors: any[]) => { + const parent = _.last(ancestors); + const nodeIndex = parent?.children.indexOf(node); + + const text: string = node.value; + + const match = text?.match(/(:.*?:)/); + + if (match && match.index !== undefined) { + const emoji = match[0]?.replaceAll(':', '') || ''; + const src = emojiFileNames.find(fileName => fileName.match(`${emoji}.*`)); + + const beforeNode = { + type: 'text', + value: text.slice(0, match.index), + } + + const emojiNode = { + type: 'element', + tagName: 'emoji', + children: [{ + type: 'text', + value: src, + }], + } + + const afterNode = { + type: 'text', + value: text.slice(match.index + emoji?.length + 2), + } + + parent.children.splice(nodeIndex, 1, ...[beforeNode, emojiNode, afterNode]) + } + + } + + return (tree: Node) => { + visitParents(tree, { type: 'text' }, visitor); + } +} + +export default emojiPlugin; diff --git a/src/pages/[...path].tsx b/src/pages/[...path].tsx index 30fdcd6..9c7704e 100644 --- a/src/pages/[...path].tsx +++ b/src/pages/[...path].tsx @@ -1,12 +1,15 @@ import _ from 'lodash'; -import type { GetStaticPropsContext, NextPage } from "next"; +import type { GetStaticPropsContext, NextPage } from 'next'; import ReactMarkdown from 'react-markdown'; -import Head from "next/head"; -import deepReadDir from "../deepReadDir"; +import Head from 'next/head'; +import Emoji from '../Emoji'; +import deepReadDir from '../deepReadDir'; +import emojiPlugin from '../emojiPlugin'; import fs from 'fs'; const MARKDOWN_DIR = '../eug-vs-xyz/src'; +const EMOJI_DIR = 'public/emoji'; const transformLinkURI = (uri: string): string => { return uri.match(/(.*)\.md/)?.[1] || uri; @@ -15,9 +18,12 @@ const transformLinkURI = (uri: string): string => { export const getStaticProps = async (context: GetStaticPropsContext) => { const path = _.isArray(context.params?.path) && context.params?.path || [context.params?.path]; const markdownSource = fs.readFileSync(`${MARKDOWN_DIR}/${path?.join('/')}.md`).toString(); + const emojiFileNames = fs.readdirSync(EMOJI_DIR); + return { props: { markdownSource, + emojiFileNames, path, } } @@ -30,23 +36,34 @@ export const getStaticPaths = async () => { .filter(p => p) .map(p => p?.split('/')) .map(path => ({ params: { path } })); - console.log(paths); return { paths, fallback: false, } } -const Page: NextPage = ({ markdownSource }: any) => { +const Page: NextPage = ({ markdownSource, emojiFileNames }: any) => { return ( <> <Head> - <title>Create T3 App</title> - <meta name="description" content="Generated by create-t3-app" /> - <link rel="icon" href="/favicon.ico" /> + <title>{`Eugene's Space`}</title> + <meta name="description" content="TODO" /> + <link rel="icon" href="/icon-64.png" /> </Head> <main> - <ReactMarkdown transformLinkUri={transformLinkURI}>{markdownSource}</ReactMarkdown> + <ReactMarkdown + children={markdownSource} + transformLinkUri={transformLinkURI} + rehypePlugins={[emojiPlugin(emojiFileNames)]} + components={{ + emoji: Emoji, + h1: 'h2', + h2: 'h3', + h3: 'h4', + h4: 'h5', + h5: 'h6', + } as any} + /> </main> </> ); diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 191f276..a64a418 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,6 +1,6 @@ -import "../styles/globals.css"; +import '../styles/globals.css'; import logo from '../../public/eug-vs.png'; -import type { AppProps } from "next/app"; +import type { AppProps } from 'next/app'; import Image from 'next/future/image'; function MyApp({ Component, pageProps }: AppProps) { |