Skip to content

Commit

Permalink
refactor: detach utility logics from app/docs/[...categories]/page.jsx (
Browse files Browse the repository at this point in the history
#63)

* refactor: detach markdownToJsx logic from app/docs/.../page.jsx

* refactor: simplify code logic in generateStaticParams
  • Loading branch information
lumirlumir authored Sep 17, 2024
1 parent 5592b86 commit 2f74439
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 41 deletions.
46 changes: 5 additions & 41 deletions src/app/docs/[...categories]/page.jsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,23 @@
import { promises as fs } from 'fs';
import parse from 'html-react-parser';
import { join, sep } from 'path';

import { REPOSITORY } from '@/constants/github';
import { DOCS } from '@/constants/path';
import markdownToJsx from '@/utils/markdownToJsx';

export async function generateStaticParams() {
const paths = await fs.readdir(DOCS, {
encoding: 'utf-8',
recursive: true,
});

return paths
.filter(path => path.endsWith('.md'))
.map(path => ({
categories: path.replace(/\\/g, '/').replace('.md', '').split('/'),
categories: path.replace(/\.md$/, '').split(sep),
}));
}

export default async function Page({ params }) {
const markdown = await fs.readFile(
`${DOCS}/${params.categories.join('/')}.md`,
'utf-8',
);
const filePath = join(DOCS, `${params.categories.join(sep)}.md`);

return <>{await markdownToJsx(markdown)}</>;
}

async function markdownToHtml(markdown) {
const response = await fetch('https://api.github.com/markdown', {
method: 'POST',
headers: {
Accept: 'application/vnd.github+json',
'Content-Type': 'application/json',
'X-GitHub-Api-Version': '2022-11-28',
},
body: JSON.stringify({
text: markdown,
mode: 'gfm',
context: REPOSITORY.fullName,
}),
});

return response.text();
}

function htmlToJsx(html) {
return parse(html, {
replace: ({ name, attribs }) => {
if (name === 'img' && attribs.src.startsWith('/public')) {
attribs.src = attribs.src.replace(/^\/public/, '');
}
},
});
}

async function markdownToJsx(markdown) {
return htmlToJsx(await markdownToHtml(markdown));
return <>{await markdownToJsx(filePath)}</>;
}
73 changes: 73 additions & 0 deletions src/utils/markdownToJsx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { promises as fs } from 'fs';

import parse from 'html-react-parser';

import { REPOSITORY } from '@/constants/github';

/**
* Converts a markdown file to JSX.
*
* @async
* @param {string} filePath Path to the markdown file.
* @returns {Promise<JSX.Element>} A promise that resolves to JSX.
*/
export default async function markdownToJsx(filePath) {
const markdown = await readMarkdown(filePath);
const html = await markdownToHtml(markdown);
const jsx = htmlToJsx(html);

return jsx;
}

/**
* Reads a markdown file.
*
* @async
* @param {string} filePath Path to the markdown file.
* @returns {Promise<string>} A promise that resolves to the markdown content.
*/
export async function readMarkdown(filePath) {
return await fs.readFile(filePath, 'utf-8');
}

/**
* Converts markdown text to HTML using GitHub's Markdown API.
*
* @async
* @param {string} markdown The markdown content.
* @returns {Promise<string>} A promise that resolves to HTML.
*/
export async function markdownToHtml(markdown) {
const response = await fetch('https://api.github.com/markdown', {
method: 'POST',
headers: {
Accept: 'application/vnd.github+json',
'Content-Type': 'application/json',
'X-GitHub-Api-Version': '2022-11-28',
},
body: JSON.stringify({
text: markdown,
mode: 'gfm',
context: REPOSITORY.fullName,
}),
});

return response.text();
}

/**
* Converts HTML to JSX.
*
* @param {string} html The HTML content.
* @returns {JSX.Element} The JSX representation.
*/
export function htmlToJsx(html) {
return parse(html, {
replace: ({ name, attribs }) => {
// img-attribute-src
if (name === 'img' && attribs.src.startsWith('/public')) {
attribs.src = attribs.src.replace(/^\/public/, '');
}
},
});
}

0 comments on commit 2f74439

Please sign in to comment.