-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: detach utility logics from app/docs/[...categories]/page.jsx (
#63) * refactor: detach markdownToJsx logic from app/docs/.../page.jsx * refactor: simplify code logic in generateStaticParams
- Loading branch information
1 parent
5592b86
commit 2f74439
Showing
2 changed files
with
78 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)}</>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/, ''); | ||
} | ||
}, | ||
}); | ||
} |