wip: some progress on markdown; cleaning up code using html-react-parser and its dependencies
This commit is contained in:
26
app/fonts.ts
26
app/fonts.ts
@@ -1,4 +1,11 @@
|
||||
import { Raleway, Syne, Questrial, Nunito_Sans } from "next/font/google";
|
||||
import {
|
||||
Raleway,
|
||||
Syne,
|
||||
Questrial,
|
||||
Roboto,
|
||||
Nunito_Sans,
|
||||
Open_Sans
|
||||
} from "next/font/google";
|
||||
|
||||
export const raleway = Raleway({
|
||||
subsets: ['latin'],
|
||||
@@ -16,8 +23,19 @@ export const questrial = Questrial({
|
||||
weight: ['400'],
|
||||
});
|
||||
|
||||
export const nunito_sans = Nunito_Sans({
|
||||
export const roboto = Roboto({
|
||||
subsets: ['latin'],
|
||||
weight: ['400'],
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
export const openSans = Open_Sans({
|
||||
subsets: ['latin'],
|
||||
display: "swap",
|
||||
weight: ['400'],
|
||||
});
|
||||
})
|
||||
|
||||
export const nunito = Nunito_Sans({
|
||||
subsets: ['latin'],
|
||||
weight: ['300'],
|
||||
display: "swap",
|
||||
})
|
||||
@@ -1,12 +1,9 @@
|
||||
import "./globals.css";
|
||||
import type { Metadata } from "next";
|
||||
import { Inter } from "next/font/google";
|
||||
import BlogHeader from "@/components/blogHeader";
|
||||
import BlogFooter from "@/components/blogFooter";
|
||||
import React from "react";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
@@ -19,7 +16,7 @@ export default function RootLayout({
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>
|
||||
<body>
|
||||
<div className={`flex flex-col bg-white`}>
|
||||
<BlogHeader />
|
||||
{children}
|
||||
|
||||
@@ -3,11 +3,12 @@ import remarkGfm from 'remark-gfm';
|
||||
import remarkParse from 'remark-parse';
|
||||
import remarkRehype from 'remark-rehype';
|
||||
import rehypeSanitize from 'rehype-sanitize';
|
||||
import rehypeHighlight from 'rehype-highlight';
|
||||
import rehypeHighlight, { Options as RehypeHighlightOptions } from 'rehype-highlight';
|
||||
import rehypeReact, { Options as RehypeReactOptions } from 'rehype-react';
|
||||
import { all } from 'lowlight';
|
||||
import { Fragment, jsx, jsxs } from 'react/jsx-runtime';
|
||||
import { MarkPostString } from '@/components/dummyPost';
|
||||
import {raleway} from "@/app/fonts";
|
||||
import { raleway, roboto, nunito } from "@/app/fonts";
|
||||
|
||||
export default async function Mark() {
|
||||
let content = await MarkPostString();
|
||||
@@ -16,16 +17,21 @@ export default async function Mark() {
|
||||
.use(remarkGfm)
|
||||
.use(remarkRehype)
|
||||
.use(rehypeSanitize)
|
||||
.use(rehypeHighlight)
|
||||
.use(rehypeHighlight, {
|
||||
languages: all,
|
||||
} as RehypeHighlightOptions)
|
||||
.use(rehypeReact, {
|
||||
Fragment: Fragment,
|
||||
jsx: jsx,
|
||||
jsxs: jsxs,
|
||||
components: {
|
||||
h1: props => <h1 className={`${raleway.className} mx-auto w-224 text-4xl`}>{props.children}</h1>,
|
||||
h2: props => <h2 className={`${raleway.className} mx-auto w-224 text-3xl`}>{props.children}</h2>,
|
||||
h3: props => <h3 className={`${raleway.className} mx-auto w-224 text-2xl`}>{props.children}</h3>,
|
||||
h4: props => <h4 className={`${raleway.className} mx-auto w-224 text-xl`}>{props.children}</h4>
|
||||
h2: props => <h2 className={`${raleway.className} mx-auto mt-6 w-224 text-3xl`}>{props.children}</h2>,
|
||||
h3: props => <h3 className={`${raleway.className} mx-auto mt-4 w-224 text-2xl`}>{props.children}</h3>,
|
||||
h4: props => <h4 className={`${raleway.className} mx-auto mt-3 w-224 text-xl`}>{props.children}</h4>,
|
||||
p: props => <p className={`${nunito.className} mx-auto mt-2 w-224`}>{props.children}</p>,
|
||||
pre: props => <div className={`w-224 mx-auto mt-2`}><pre>{props.children}</pre></div>,
|
||||
hr: props => <hr className={`mx-auto w-224 mt-6`} />
|
||||
}
|
||||
} as RehypeReactOptions)
|
||||
.process(content);
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
import {ReactElement} from "react";
|
||||
import {domToReact, Element} from "html-react-parser";
|
||||
import {nunito_sans, raleway} from "@/app/fonts";
|
||||
import {Code} from "bright";
|
||||
import {mark} from "@/bright-extension/mark";
|
||||
|
||||
export type nodeHandlerResult = {match :boolean, element? :ReactElement}
|
||||
export type nodeHandler = (node :Element) => nodeHandlerResult
|
||||
|
||||
function h1(node: Element): nodeHandlerResult {
|
||||
if (node.name === "h1") {
|
||||
if (node.attribs.class === "title") {
|
||||
return {
|
||||
match: true,
|
||||
element: (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-4xl`}>
|
||||
{domToReact(node.children)}
|
||||
</h1>
|
||||
),
|
||||
};
|
||||
}
|
||||
return {
|
||||
match: true,
|
||||
element: (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-3xl`}>
|
||||
{domToReact(node.children)}
|
||||
</h1>
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return { match: false};
|
||||
}
|
||||
|
||||
function h2(node: Element): nodeHandlerResult {
|
||||
if (node.name === "h2") {
|
||||
return {
|
||||
match: true,
|
||||
element: (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-2xl`}>
|
||||
{domToReact(node.children)}
|
||||
</h1>
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
return {match: false};
|
||||
}
|
||||
|
||||
function h3(node: Element): nodeHandlerResult {
|
||||
if (node.name === "h3") {
|
||||
return {
|
||||
match: true,
|
||||
element: (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-xl`}>
|
||||
{domToReact(node.children)}
|
||||
</h1>
|
||||
)
|
||||
};
|
||||
}
|
||||
return {match: false};
|
||||
}
|
||||
|
||||
function code(node: Element): nodeHandlerResult {
|
||||
if (node.name === "code") {
|
||||
let linenumber = false;
|
||||
if ("class" in node.attribs) {
|
||||
const classes = node.attribs.class.split(" ");
|
||||
if (classes.includes("linenumber")) {
|
||||
linenumber = true;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
match: true,
|
||||
element: (
|
||||
<div className={`w-224 mx-auto`}>
|
||||
<Code
|
||||
lang={`${node.attribs.lang}`}
|
||||
lineNumbers={linenumber}
|
||||
extensions={[mark]}
|
||||
>
|
||||
{domToReact(node.children)}
|
||||
</Code>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
return {match: false};
|
||||
}
|
||||
|
||||
function p(node: Element): nodeHandlerResult {
|
||||
if (node.name === "p") {
|
||||
if (node.attribs.class === "paragraph") {
|
||||
return {
|
||||
match: true,
|
||||
element: (
|
||||
<h1 className={`${nunito_sans.className} mx-auto w-224`}>
|
||||
{domToReact(node.children)}
|
||||
</h1>
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
return {match: false};
|
||||
}
|
||||
|
||||
export const handlers: nodeHandler[] = [h1, h2, h3, code, p];
|
||||
@@ -1,43 +1,21 @@
|
||||
import { getPost } from "@/backend/post";
|
||||
import DOMPurify from "dompurify";
|
||||
import { JSDOM } from "jsdom";
|
||||
import parse, {
|
||||
Element,
|
||||
// domToReact,
|
||||
HTMLReactParserOptions,
|
||||
} from "html-react-parser";
|
||||
import { DummyPostSlug, DummyPostString } from "@/components/dummyPost";
|
||||
import { handlers } from "@/app/post/[slug]/nodeHandler";
|
||||
|
||||
const options: HTMLReactParserOptions = {
|
||||
replace: (domNode) => {
|
||||
for (let handler of handlers) {
|
||||
if (domNode instanceof Element && domNode.attribs) {
|
||||
let result = handler(domNode)
|
||||
if (result.match && typeof result.element !== 'undefined') {
|
||||
return result.element
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default async function Post({ params }: { params: { slug: string } }) {
|
||||
let content;
|
||||
// let content;
|
||||
//
|
||||
// const dummySlug = DummyPostSlug();
|
||||
// if (dummySlug === params.slug) {
|
||||
// content = await DummyPostString();
|
||||
// } else {
|
||||
// content = await getPost(params.slug);
|
||||
// }
|
||||
//
|
||||
// content = DOMPurify(new JSDOM("<!DOCTYPE html>").window).sanitize(content);
|
||||
// const elem = parse(content, options);
|
||||
//
|
||||
// return (
|
||||
// <div className={`flex flex-col`}>
|
||||
// {elem}
|
||||
// </div>
|
||||
// );
|
||||
|
||||
const dummySlug = DummyPostSlug();
|
||||
if (dummySlug === params.slug) {
|
||||
content = await DummyPostString();
|
||||
} else {
|
||||
content = await getPost(params.slug);
|
||||
}
|
||||
|
||||
content = DOMPurify(new JSDOM("<!DOCTYPE html>").window).sanitize(content);
|
||||
const elem = parse(content, options);
|
||||
|
||||
return (
|
||||
<div className={`flex flex-col`}>
|
||||
{elem}
|
||||
</div>
|
||||
);
|
||||
return(<></>);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user