WIP: updated HTMLReactParserOptions replace function, from complex if else to handler pattern
This commit is contained in:
109
app/post/[slug]/nodeHandler.tsx
Normal file
109
app/post/[slug]/nodeHandler.tsx
Normal file
@@ -0,0 +1,109 @@
|
||||
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,69 +1,21 @@
|
||||
import { getPost } from "@/backend/post";
|
||||
import DOMPurify from "dompurify";
|
||||
import { JSDOM } from "jsdom";
|
||||
import { nunito_sans, raleway } from "@/app/fonts";
|
||||
import parse, {
|
||||
domToReact,
|
||||
Element,
|
||||
// domToReact,
|
||||
HTMLReactParserOptions,
|
||||
} from "html-react-parser";
|
||||
import { DummyPostSlug, DummyPostString } from "@/components/dummyPost";
|
||||
import { Code } from "bright";
|
||||
import { mark } from "@/bright-extension/mark";
|
||||
import { handlers } from "@/app/post/[slug]/nodeHandler";
|
||||
|
||||
const options: HTMLReactParserOptions = {
|
||||
replace: (domNode) => {
|
||||
if (domNode instanceof Element && domNode.attribs) {
|
||||
// console.log(domNode.attribs)
|
||||
if (domNode.name === "h1") {
|
||||
if (domNode.attribs.class === "title") {
|
||||
return (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-4xl`}>
|
||||
{domToReact(domNode.children)}
|
||||
</h1>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-3xl`}>
|
||||
{domToReact(domNode.children)}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
} else if (domNode.name === "h2") {
|
||||
return (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-2xl`}>
|
||||
{domToReact(domNode.children)}
|
||||
</h1>
|
||||
);
|
||||
} else if (domNode.name === "h3") {
|
||||
return (
|
||||
<h1 className={`${raleway.className} mx-auto w-224 text-xl`}>
|
||||
{domToReact(domNode.children)}
|
||||
</h1>
|
||||
);
|
||||
} else if (domNode.name === "code") {
|
||||
let linenumber = false
|
||||
if ('class' in domNode.attribs) {
|
||||
const classes = domNode.attribs.class.split(" ");
|
||||
if (classes.includes('linenumber')) {
|
||||
linenumber = true;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div className={`w-224 mx-auto`}>
|
||||
<Code lang={`${domNode.attribs.lang}`} lineNumbers={linenumber} extensions={[mark]}>
|
||||
{domToReact(domNode.children)}
|
||||
</Code>
|
||||
</div>
|
||||
);
|
||||
} else if (domNode.name === "p") {
|
||||
// console.log(domNode.children)
|
||||
if (domNode.attribs.class === "paragraph") {
|
||||
return (
|
||||
<h1 className={`${nunito_sans.className} mx-auto w-224`}>
|
||||
{domToReact(domNode.children)}
|
||||
</h1>
|
||||
);
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +23,7 @@ const options: HTMLReactParserOptions = {
|
||||
};
|
||||
|
||||
export default async function Post({ params }: { params: { slug: string } }) {
|
||||
let content = "";
|
||||
let content;
|
||||
|
||||
const dummySlug = await DummyPostSlug();
|
||||
if (dummySlug === params.slug) {
|
||||
|
||||
Reference in New Issue
Block a user