スマレジエンジニアyushiのブログ

スマレジエンジニアのブログ

【自作ブログ #2】Markdownをparseする

自作ブログを作っています。

yushi-dev.hatenablog.com

技術スタック

  • TypeScript
  • React
  • Next.js
  • Styled Components
  • GitHub Pages

remarkの導入

Next.jsの公式ドキュメントでは、Markdownをrenderする仕組みとしてremarkを紹介しています。

今回はこちらを利用します。

npm i remark remark-html remark-gfm

remark-gfmは、テーブルなどいくつかの拡張的な記述方法のためのプラグインです。

Markdownファイルのparser

ファイルの読み込みと、markdownをhtmlにparseする仕組みを合わせたutilityを用意します。

(markdown-utils.ts)

import fs from 'fs'
import { remark } from 'remark'
import remarkGfm from 'remark-gfm'
import html from 'remark-html'

export async function convertToHtml(md: string) {
  const result = await remark().use(html).use(remarkGfm).process(md)

  return result.toString()
}

export async function loadFile(filePath: string) {
  const contents = await convertToHtml(
    fs.readFileSync(filePath, { encoding: 'utf8' })
  )

  return { contents }
}

Markdownの色々な記述方法を含むサンプルファイルを用意します。

(sample.md)

# Sample

## サブタイトル

### 文字装飾

サンプルです。

_イタリック_

**太文字**

### リスト

- データ 1
- データ 2

1. 手順 1
2. 手順 2

### テーブル

| a   | b   |
| --- | --- |
| c   | d   |
| e   | f   |

これを、/postsに配置します。

上記の/posts以下のファイルを読み込むためのメソッドを用意します。
先ほど作ったmarkdown-utils.tsを利用しています。

(post-service.ts)

import path from 'path'
import * as markdownUtils from '@/utils/markdown-utils'

export async function loadMarkdown(slug: string) {
  const postDir = path.join(process.cwd(), 'posts')
  const fullPath = path.join(postDir, `${slug}.md`)

  return markdownUtils.loadFile(fullPath)
}

最後に、pages以下に先程用意したsample.mdに対応するページを表示するためのファイルを用意します。

(sample.tsx)

import * as postService from '@/services/post-service'

export async function getStaticProps() {
  const postData = await postService.loadMarkdown('sample')

  return {
    props: {
      contents: postData.contents,
    },
  }
}

const Slug = ({ contents }) => {
  return (
    <>
      <div dangerouslySetInnerHTML={{ __html: contents }} />
    </>
  )
}

export default Slug

スクリーンショット

画面が表示できるようになりました。
Markdownの各記述がうまくparseされています。

Pull Request

https://github.com/nek0meshi/blog/pull/3

あとがき

最近はハリポタを読んでいます。学生時代ぶりです。とても面白いです。