Compare commits

...

9 Commits

Author SHA1 Message Date
rei
f15a1fb167 yt fix
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-24 18:30:28 +02:00
rei
bab35fbfce bg fix 2023-04-24 18:27:42 +02:00
rei
84cc6d64db upgrade to next 13
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-24 18:13:50 +02:00
rei
63245d9afd WIP: c9f5dfc Update 'content/projects/RE-Chess.md' 2023-03-13 23:43:17 +01:00
9b8b59d4e6 add Blur
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-24 13:16:50 +01:00
Rei
dc7e82b143 kollors
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-15 18:46:29 +01:00
Rei
703b611dfd sorted
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-15 18:29:52 +01:00
Rei
dd4f848071 divider
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-15 17:57:47 +01:00
Rei
46097b8390 style changes 2023-02-15 16:43:14 +01:00
15 changed files with 2218 additions and 2136 deletions

View File

@@ -1,41 +1,41 @@
import React, {Children, useState} from "react"; import React, { useState } from "react";
import {AiFillLeftCircle} from 'react-icons/ai'; import { AiFillLeftCircle } from "react-icons/ai";
export const ImageSlide = ({ children }: any) => {
const [current, setCurrent] = useState(0);
const length = children.length;
export const ImageSlide = ({children}:any) => { const nextSlide = () => {
const [current, setCurrent] = useState(0); setCurrent(current === length - 1 ? 0 : current + 2);
const length = children.length; };
const array = Children.toArray(children);
console.log(array)
const nextSlide = () => {
setCurrent(current === length - 1 ? 0 : current + 2);
};
const prevSlide = () => { const prevSlide = () => {
setCurrent(current === 0 ? length - 1 : current - 2); setCurrent(current === 0 ? length - 1 : current - 2);
}; };
if(children.length <= 0){ if (children.length <= 0) {
return null; return null;
}; }
return( return (
<section className='slider'> <section className="slider">
<AiFillLeftCircle className='left-arrow' onClick={prevSlide} /> <AiFillLeftCircle className="left-arrow" onClick={prevSlide} />
<AiFillLeftCircle className='right-arrow' onClick={nextSlide} /> <AiFillLeftCircle className="right-arrow" onClick={nextSlide} />
{children.map((slide : any, index : any) => { {children.map((slide: any, index: any) => {
return ( return (
<div <div
className={index === current ? 'slide active' : 'slide'} className={index === current ? "slide active" : "slide"}
key={index} key={index}
> >
{index === current && ( {index === current && (
<img src={slide.props.children[0]} alt='travel image' className='image' /> <img
)} src={slide.props.children[0]}
</div> alt="travel image"
); className="image"
})} />
</section> )}
); </div>
}; );
})}
</section>
);
};

View File

@@ -13,7 +13,7 @@ export const Navbar = () => {
const [showMenu, setShowMenu] = useState(false); const [showMenu, setShowMenu] = useState(false);
return ( return (
<nav className="py-4 xl:px-10 px-4 flex flex-row justify-between sticky top-0 bg-slate-100 dark:bg-gradient-dark z-50 border-b dark:border-gradient-light border-gray-200"> <nav className="py-4 xl:px-10 px-4 flex flex-row justify-between sticky top-0 z-50 bg-gradient-to-b from-black/50 to-black/30">
<Link <Link
href="/" href="/"
id="logo" id="logo"
@@ -28,7 +28,7 @@ export const Navbar = () => {
<div className="hidden xl:flex flex-row gap-10 items-center font-medium font-mono"> <div className="hidden xl:flex flex-row gap-10 items-center font-medium font-mono">
{links.map(({ name, href }) => ( {links.map(({ name, href }) => (
<Link href={href} key={name}> <Link href={href} key={name}>
<button className="px-10 py-1 rounded-sm bg-primary hover:bg-primary/50 transition-all duration-150 ease-out text-white"> <button className="px-10 py-1 rounded-sm bg-gradient-to-r from-indigo-500/30 to-fuchsia-500/20 hover:bg-primary/50 transition-all duration-150 ease-out text-white">
{name} {name}
</button> </button>
</Link> </Link>

View File

@@ -1,8 +1,8 @@
import { useRef, useMemo } from 'react' import { useRef, useMemo } from "react";
import { Canvas, useFrame } from '@react-three/fiber' import { Canvas, useFrame } from "@react-three/fiber";
import { BufferGeometry, Material, MathUtils, Mesh } from "three"; import { BufferGeometry, Material, MathUtils, Mesh } from "three";
import { vertexShader } from './Shaders/Background/vertex'; import { vertexShader } from "./Shaders/Background/vertex";
import { fragmentShader } from './Shaders/Background/fragment'; import { fragmentShader } from "./Shaders/Background/fragment";
const Fragment = () => { const Fragment = () => {
// This reference will give us direct access to the mesh // This reference will give us direct access to the mesh
@@ -21,12 +21,13 @@ const Fragment = () => {
); );
useFrame((state) => { useFrame((state) => {
if(!meshRef.current){ if (!meshRef.current) {
return; return;
} }
const { clock } = state; const { clock } = state;
//@ts-ignore //@ts-ignore
meshRef.current.material.uniforms.u_time.value = 0.4 * clock.getElapsedTime()/5; meshRef.current.material.uniforms.u_time.value =
(0.4 * clock.getElapsedTime()) / 5;
//@ts-ignore //@ts-ignore
meshRef.current.material.uniforms.u_intensity.value = MathUtils.lerp( meshRef.current.material.uniforms.u_intensity.value = MathUtils.lerp(
//@ts-ignore //@ts-ignore
@@ -37,7 +38,12 @@ const Fragment = () => {
}); });
return ( return (
<mesh ref={meshRef} position={[0, 0, 0]} rotation={[-Math.PI/17, Math.PI/20, 0]} scale={1.5}> <mesh
ref={meshRef}
position={[0, 0, 0]}
rotation={[-Math.PI / 17, Math.PI / 20, 0]}
scale={1.5}
>
<planeGeometry args={[30, 30, 200, 200]} /> <planeGeometry args={[30, 30, 200, 200]} />
<shaderMaterial <shaderMaterial
fragmentShader={fragmentShader} fragmentShader={fragmentShader}
@@ -49,13 +55,12 @@ const Fragment = () => {
); );
}; };
export const R3Gradient = () => { export const R3Gradient = () => {
return ( return (
<div className='-z-40 h-screen w-screen fixed bg-black opacity-60'> <div className="-z-40 h-screen w-screen fixed bg-black opacity-60 top-0 left-0 blur">
<Canvas camera={{ position: [0.0, 0.0, 5.0] }}> <Canvas camera={{ position: [0.0, 0.0, 5.0] }}>
<Fragment /> <Fragment />
</Canvas> </Canvas>
</div> </div>
); );
}; };

View File

@@ -17,8 +17,8 @@ import smartypants from "remark-smartypants";
import rehypeRaw from "rehype-raw"; import rehypeRaw from "rehype-raw";
import emoji from "remark-emoji"; import emoji from "remark-emoji";
import oembed from "@agentofuser/remark-oembed"; import oembed from "@agentofuser/remark-oembed";
import remarkDirective from 'remark-directive' import remarkDirective from "remark-directive";
import remarkDirectiveRehype from 'remark-directive-rehype' import remarkDirectiveRehype from "remark-directive-rehype";
import { YouTubeVideo } from "./Youtube"; import { YouTubeVideo } from "./Youtube";
import { ImageSlide } from "./ImageSlide"; import { ImageSlide } from "./ImageSlide";
//import rehypeSanitize from "rehype-sanitize"; //import rehypeSanitize from "rehype-sanitize";
@@ -30,7 +30,6 @@ SyntaxHighlighter.registerLanguage("bash", bash);
SyntaxHighlighter.registerLanguage("markdown", markdown); SyntaxHighlighter.registerLanguage("markdown", markdown);
SyntaxHighlighter.registerLanguage("json", json); SyntaxHighlighter.registerLanguage("json", json);
export const StyledMarkdown = ({ html }: { html: string }) => { export const StyledMarkdown = ({ html }: { html: string }) => {
const MarkdownComponents: Components = { const MarkdownComponents: Components = {
h1: (props: any) => { h1: (props: any) => {
@@ -110,11 +109,9 @@ export const StyledMarkdown = ({ html }: { html: string }) => {
); );
}, },
code({ node, inline, className, ...props }: any) { code({ node, inline, className, ...props }: any) {
const match = /language-(\w+)/.exec(className || ""); const match = /language-(\w+)/.exec(className || "");
const hasMeta = node?.data?.meta; const hasMeta = node?.data?.meta;
const applyHighlights: object = (applyHighlights: number) => { const applyHighlights: object = (applyHighlights: number) => {
if (hasMeta) { if (hasMeta) {
const RE = /{([\d,-]+)}/; const RE = /{([\d,-]+)}/;
@@ -154,7 +151,6 @@ export const StyledMarkdown = ({ html }: { html: string }) => {
return "Code"; return "Code";
}; };
return match ? ( return match ? (
<div> <div>
<div className="w-full flex flex-row items-center gap-4"> <div className="w-full flex flex-row items-center gap-4">
@@ -185,18 +181,18 @@ export const StyledMarkdown = ({ html }: { html: string }) => {
}, },
//custom directives //custom directives
//@ts-ignore //@ts-ignore
'yt': YouTubeVideo, yt: YouTubeVideo,
'img-slide': ImageSlide, "img-slide": ImageSlide,
}; };
return ( return (
<div <div
className=" className="
prose prose
prose-code:font-mono prose-code:text-gray-100 prose-code:bg-gray-700 prose-code:p-1 prose-code:m-1 prose-code:rounded-md prose-code:font-mono prose-code:text-gray-100 prose-code:bg-black/20 prose-code:p-1 prose-code:m-1 prose-code:rounded-md
prose-headings:text-gray-800 dark:prose-headings:text-gray-100 prose-p:text-gray-600 dark:prose-p:text-gray-300 prose-headings:text-gray-800 dark:prose-headings:text-gray-100 prose-p:text-gray-600 dark:prose-p:text-gray-300
prose-img:w-full prose-img:h-auto prose-img:object-cover prose-img:w-full prose-img:h-auto prose-img:object-cover
prose-li:text-gray-600 dark:prose-li:text-gray-300 prose-td:text-gray-600 dark:prose-td:text-gray-400 prose-li:text-gray-600 dark:prose-li:text-gray-200 prose-td:text-gray-600 dark:prose-td:text-gray-300
prose-a:text-primary prose-strong:text-gray-900 dark:prose-strong:text-gray-50 prose-a:text-primary prose-strong:text-gray-900 dark:prose-strong:text-gray-50
dark:prose-hr:bg-gray-200 prose-hr:bg-gray-400 dark:prose-hr:bg-gray-200 prose-hr:bg-gray-400
" "
@@ -204,7 +200,15 @@ export const StyledMarkdown = ({ html }: { html: string }) => {
<ReactMarkdown <ReactMarkdown
components={MarkdownComponents} components={MarkdownComponents}
rehypePlugins={[rehypeRaw]} rehypePlugins={[rehypeRaw]}
remarkPlugins={[remarkDirective, remarkDirectiveRehype, oembed, remarkGfm, smartypants, emoji, remarkTypograf]} remarkPlugins={[
remarkDirective,
remarkDirectiveRehype,
oembed,
remarkGfm,
smartypants,
emoji,
remarkTypograf,
]}
children={html} children={html}
/> />
</div> </div>

View File

@@ -1,9 +1,5 @@
export const YouTubeVideo = ({id, children} : any) => ( export const YouTubeVideo = ({ id, children }: any) => (
<iframe <iframe src={'https://www.youtube.com/embed/' + id} className="w-full xl:h-96 md:h-80 h-64">
src={'https://www.youtube.com/embed/' + id} {children}
width="640"
height="360"
>
{children}
</iframe> </iframe>
) )

View File

@@ -1,13 +1,12 @@
import { PropsWithChildren } from "react"; import { PropsWithChildren } from 'react'
import { R3Gradient } from '../components/R3Background'; import { R3Gradient } from '../components/R3Background'
import { Navbar } from "../components/Navbar"; import { Navbar } from '../components/Navbar'
export const MainLayout = ({ children }: PropsWithChildren) => { export const MainLayout = ({ children }: PropsWithChildren) => {
return ( return (
<div className="w-full"> <div className="w-full">
<Navbar /> <Navbar />
<R3Gradient /> <main className="xl:p-5 p-4 px-5 xl:mx-0">{children}</main>
<main className="xl:p-5 p-4 px-5 xl:mx-0">{children}</main> </div>
</div> )
); }
};

View File

@@ -20,10 +20,10 @@
"@types/three": "^0.149.0", "@types/three": "^0.149.0",
"framer-motion": "^8.0.2", "framer-motion": "^8.0.2",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"next": "13.0.6", "next": "^13.3.1",
"parse-numeric-range": "^1.3.0", "parse-numeric-range": "^1.3.0",
"react": "18.2.0", "react": "^18.2.0",
"react-dom": "18.2.0", "react-dom": "^18.2.0",
"react-icons": "^4.7.1", "react-icons": "^4.7.1",
"react-markdown": "^8.0.4", "react-markdown": "^8.0.4",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",

View File

@@ -1,6 +1,12 @@
import { R3Gradient } from '../components/R3Background'
import '../styles/globals.css' import '../styles/globals.css'
import type { AppProps } from 'next/app' import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) { export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} /> return (
<>
<R3Gradient />
<Component {...pageProps} />
</>
)
} }

View File

@@ -36,7 +36,7 @@ const Blog = ({ posts }: { posts: Post[] }) => {
<h1 className="text-3xl font-bold text-gray-800 dark:text-gray-200"> <h1 className="text-3xl font-bold text-gray-800 dark:text-gray-200">
Blog Blog
</h1> </h1>
<div className="w-full h-0.5 bg-violet-200 dark:bg-violet-700 my-4 rounded-full" /> <div className="w-full h-0.5 bg-violet-200 dark:bg-white/20 my-4 rounded-full" />
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{posts.map((post, index) => ( {posts.map((post, index) => (
<BlogCard <BlogCard

View File

@@ -3,7 +3,7 @@ export default function Home() {
return ( return (
<MainLayout> <MainLayout>
<div className="grid lg:grid-cols-2 grid-cols-1 xl:mt-10 gap-10 items-center"> <div className="grid lg:grid-cols-2 grid-cols-1 xl:mt-10 gap-10 items-center">
<div className="bg-primary-dark p-10 rounded-lg flex flex-col gap-10 h-fit 3xl:w-2/3 w-full text-lg text-primary-text/90 shadow-lg shadow-gradient-dark/20"> <div className="bg-primary-dark/30 border-white/30 border p-10 rounded-lg flex flex-col gap-10 h-fit 3xl:w-2/3 w-full text-lg text-primary-text/90 shadow-lg shadow-gradient-dark/20">
<div> <div>
<span className="font-bold text-xl text-primary-text"> <span className="font-bold text-xl text-primary-text">
Lorem ipsum dolor{" "} Lorem ipsum dolor{" "}

View File

@@ -1,7 +1,11 @@
import { GetStaticPaths, GetStaticProps } from "next"; import { GetStaticPaths, GetStaticProps } from "next";
import fs from "fs"; import fs from "fs";
import { ParsedUrlQuery } from "querystring"; import { ParsedUrlQuery } from "querystring";
import { getProjectContentBySlug, PROJECTS_PATH } from "../../utils/markdown"; import {
getHeadings,
getProjectContentBySlug,
PROJECTS_PATH,
} from "../../utils/markdown";
import { MarkdownRenderingResult } from "../../types/types"; import { MarkdownRenderingResult } from "../../types/types";
import { MainLayout } from "../../layouts/MainLayout"; import { MainLayout } from "../../layouts/MainLayout";
import Link from "next/link"; import Link from "next/link";
@@ -52,6 +56,9 @@ export const getStaticProps: GetStaticProps<MarkdownRenderingResult> = async ({
params, params,
}) => { }) => {
const markdownContent = getProjectContentBySlug(params?.slug as string); const markdownContent = getProjectContentBySlug(params?.slug as string);
console.log(getHeadings(markdownContent.content));
return { return {
props: { props: {
frontMatter: markdownContent.frontMatter, frontMatter: markdownContent.frontMatter,

View File

@@ -1,71 +1,55 @@
import { GetServerSideProps } from "next"; import { GetServerSideProps } from 'next'
import { MainLayout } from "../../layouts/MainLayout"; import { MainLayout } from '../../layouts/MainLayout'
import { Post, getAllProjectsFrontMatter } from "../../utils/markdown"; import { Post, getAllProjectsFrontMatter } from '../../utils/markdown'
import Link from "next/link"; import Link from 'next/link'
import { formatDate } from "../../utils/general"; import { formatDate } from '../../utils/general'
import { BasicArticleProps } from "../../components/PostHeader"; import { BasicArticleProps } from '../../components/PostHeader'
const ProjectCard = ({ const ProjectCard = ({ project, slug }: { project: BasicArticleProps; slug: string }) => {
project, return (
slug, <div className="p-4 rounded-md border border-gray-200 shadow-md shadow-gray-200 dark:shadow-gray-900 dark:border-gray-700 grid grid-cols-1 xl:grid-cols-2 items-center gap-4 bg-black bg-opacity-60">
}: { <div className="order-last xl:order-1">
project: BasicArticleProps; <div className="text-sm font-medium text-gray-500">{formatDate(project.date)}</div>
slug: string; <h2 className="text-2xl font-bold">{project.title}</h2>
}) => { <p className="text-gray-600 dark:text-gray-400 text-sm">{project.description}</p>
return ( <Link href={`project/${slug}`}>
<div className="p-4 rounded-md border border-gray-200 shadow-md shadow-gray-200 dark:shadow-gray-900 dark:border-gray-700 grid grid-cols-1 xl:grid-cols-2 items-center gap-4 bg-black bg-opacity-60"> <button className="bg-action px-2 py-1 rounded-md mt-4 hover:bg-action/60 transition-all ease-in duration-100 font-bold text-white">
<div className="order-last xl:order-1"> Read more
<div className="text-sm font-medium text-gray-500"> </button>
{formatDate(project.date)} </Link>
</div>
{project.thumbnail && (
<img
src={project.thumbnail}
alt={`${slug}-thumbnail`}
className="w-full xl:h-40 h-auto object-cover rounded-md order-1 xl:order-last"
/>
)}
</div> </div>
<h2 className="text-2xl font-bold">{project.title}</h2> )
<p className="text-gray-600 dark:text-gray-400 text-sm"> }
{project.description}
</p>
<Link href={`project/${slug}`}>
<button className="bg-action px-2 py-1 rounded-md mt-4 hover:bg-action/60 transition-all ease-in duration-100 font-bold text-white">
Read more
</button>
</Link>
</div>
{project.thumbnail && (
<img
src={project.thumbnail}
alt={`${slug}-thumbnail`}
className="w-full xl:h-40 h-auto object-cover rounded-md order-1 xl:order-last"
/>
)}
</div>
);
};
const Projects = ({ posts }: { posts: Post[] }) => { const Projects = ({ posts }: { posts: Post[] }) => {
return ( return (
<MainLayout> <MainLayout>
<h1 className="text-3xl font-bold text-gray-800 dark:text-gray-100"> <h1 className="text-3xl font-bold text-gray-800 dark:text-gray-100">Projects</h1>
Projects <div className="w-full h-0.5 bg-violet-200 dark:bg-white/20 my-4 rounded-full" />
</h1> <div className="grid grid-cols-1 gap-4">
<div className="w-full h-0.5 bg-violet-200 dark:bg-violet-700 my-4 rounded-full" /> {posts.map((post, index) => (
<div className="grid grid-cols-1 gap-4"> <ProjectCard key={index} project={post.frontMatter as BasicArticleProps} slug={post.slug} />
{posts.map((post, index) => ( ))}
<ProjectCard </div>
key={index} </MainLayout>
project={post.frontMatter as BasicArticleProps} )
slug={post.slug} }
/>
))}
</div>
</MainLayout>
);
};
export const getServerSideProps: GetServerSideProps = async () => { export const getServerSideProps: GetServerSideProps = async () => {
const posts = getAllProjectsFrontMatter(); const posts = getAllProjectsFrontMatter()
return { return {
props: { props: {
posts, posts,
}, },
}; }
}; }
export default Projects; export default Projects

View File

@@ -19,22 +19,25 @@ main {
} }
pre { pre {
@apply dark:bg-slate-800 bg-slate-200 text-slate-800 dark:text-slate-200 !important; @apply dark:bg-black/30 bg-slate-200 text-slate-800 dark:text-slate-200 !important;
} }
pre > code { pre > code {
@apply bg-transparent text-gray-700 dark:text-slate-300 !important; @apply bg-transparent text-gray-700 dark:text-slate-300 !important;
} }
.codeStyle > code { .codeStyle {
background: transparent; @apply bg-transparent !important;
} }
pre > div > div > button > svg:hover { pre > div > div > button > svg:hover {
@apply hover:text-action transition-all ease-in-out duration-100 !important; @apply hover:text-action transition-all ease-in-out duration-100 !important;
} }
h1 > a, h2 > a, h3 > a, h4 > a { h1 > a,
h2 > a,
h3 > a,
h4 > a {
@apply cursor-pointer relative text-gray-800 dark:text-gray-100 decoration-transparent font-bold !important; @apply cursor-pointer relative text-gray-800 dark:text-gray-100 decoration-transparent font-bold !important;
} }
@@ -42,11 +45,24 @@ h1 > a:hover::before,
h2 > a:hover::before, h2 > a:hover::before,
h3 > a:hover::before, h3 > a:hover::before,
h4 > a:hover::before { h4 > a:hover::before {
@apply content-['#'] absolute -left-8 text-gray-300 dark:text-gray-600; @apply content-['#'] absolute -left-8 text-gray-300 dark:text-gray-400;
} }
div > code, pre > code { h2 > a:hover::before {
@apply p-0 m-0 !important @apply -left-6;
}
h3 > a:hover::before {
@apply -left-5;
}
h4 > a:hover::before {
@apply -left-4;
}
div > code,
pre > code {
@apply p-0 m-0 !important;
} }
.slider { .slider {
@@ -94,4 +110,4 @@ div > code, pre > code {
opacity: 1; opacity: 1;
transition-duration: 0.5s; transition-duration: 0.5s;
transform: scale(0.8); transform: scale(0.8);
} }

View File

@@ -4,8 +4,6 @@ import fs from "fs";
import { FrontMatter, MarkdownDocument } from "../types/types"; import { FrontMatter, MarkdownDocument } from "../types/types";
import { remark } from "remark"; import { remark } from "remark";
import html from "remark-html"; import html from "remark-html";
import remarkGfm from "remark-gfm";
export const BLOGS_PATH = join(process.cwd(), "content/blogs"); export const BLOGS_PATH = join(process.cwd(), "content/blogs");
export const PROJECTS_PATH = join(process.cwd(), "content/projects"); export const PROJECTS_PATH = join(process.cwd(), "content/projects");
@@ -14,6 +12,14 @@ export interface Post {
slug: string; slug: string;
} }
const getDate = (date: string) => {
if (typeof date === "string") {
const d = date.split(".").map((v) => +v);
return new Date(d[2], d[1] - 1, d[0]);
}
return new Date();
};
export const getBlogContentBySlug = (slug: string): MarkdownDocument => { export const getBlogContentBySlug = (slug: string): MarkdownDocument => {
const filepath = join(BLOGS_PATH, `${slug}.md` || `${slug}.mdx`); const filepath = join(BLOGS_PATH, `${slug}.md` || `${slug}.mdx`);
const filecontents = fs.readFileSync(filepath); const filecontents = fs.readFileSync(filepath);
@@ -40,22 +46,50 @@ export const getProjectContentBySlug = (slug: string): MarkdownDocument => {
export const getAllBlogsFrontMatter = (): Post[] => { export const getAllBlogsFrontMatter = (): Post[] => {
const files = fs.readdirSync(BLOGS_PATH); const files = fs.readdirSync(BLOGS_PATH);
return files.reduce((allPosts: Post[], postSlug: string) => { const blogs = files.reduce((allPosts: Post[], postSlug: string) => {
const slug = postSlug.replace(".md", ""); const slug = postSlug.replace(".md", "");
const post = getBlogContentBySlug(slug); const post = getBlogContentBySlug(slug);
return [{ frontMatter: post.frontMatter, slug }, ...allPosts]; return [{ frontMatter: post.frontMatter, slug }, ...allPosts];
}, []); }, []);
return blogs.sort(
//@ts-ignore
(a, b) => getDate(b.frontMatter.date) - getDate(a.frontMatter.date)
);
}; };
export const getAllProjectsFrontMatter = (): Post[] => { export const getAllProjectsFrontMatter = (): Post[] => {
const files = fs.readdirSync(PROJECTS_PATH); const files = fs.readdirSync(PROJECTS_PATH);
return files.reduce((allPosts: Post[], postSlug: string) => { const projects = files.reduce((allPosts: Post[], postSlug: string) => {
const slug = postSlug.replace(".md", ""); const slug = postSlug.replace(".md", "");
const post = getProjectContentBySlug(slug); const post = getProjectContentBySlug(slug);
return [{ frontMatter: post.frontMatter, slug }, ...allPosts]; return [{ frontMatter: post.frontMatter, slug }, ...allPosts];
}, []); }, []);
return projects.sort(
//@ts-ignore
(a, b) => getDate(b.frontMatter.date) - getDate(a.frontMatter.date)
);
};
export const getHeadings = (markdown: string): any => {
const headingOne = markdown.match(/^(#{1})\s(.*)/gm);
const headingTwo = markdown.match(/^(#{2})\s(.*)/gm);
const headingThree = markdown.match(/^(#{3})\s(.*)/gm);
const headingFour = markdown.match(/^(#{4})\s(.*)/gm);
const headings = markdown.match(/^(#{1,4})\s(.*)/gm);
var tree: any[] = [];
var prev = "";
headings?.forEach((heading) => {
if (headingOne?.includes(heading)) {
tree.push(heading);
}
});
return tree;
}; };
export async function markdownToHtml(markdown: any) { export async function markdownToHtml(markdown: any) {

3975
yarn.lock

File diff suppressed because it is too large Load Diff