Gatsby

Gatsbyで目次を自動生成するhtmlAstを使った方法

いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。

オススメ本
Web技術を勉強するなら、かなりオススメの雑誌です。毎月新しい発見があります。ついに最終号・・・、みなさん買いましょう!!
読んで損することはない名著。命名で悩むことが多い人はこの本がオススメです。

⇨ React 記事の目次はこちら

記事の目次を自動生成する方法について、htmlAst を使うとより簡単にかけることに気がついたのでその方法について記事にしています。

はじめに

以前

Gatsby のマークダウンで書いた記事で、気合いで目次を自動生成する

という記事を書きましたが、htmlAst を使うともう少し簡単にかけることがわかったので書き直しています。

htmlAst とは?

markdownRemark で取得できるデータのひとつです。

マークダウンで書かれたテキストが、タグごとに配列で出力されます。

data.markdownRemark.htmlAst.children

今までは、html で出力していたのでタグ含め全て文字列で出力されていたので、配列にすることによって、変形しやすくなりました。

テキストを取得する方法

階層が多いのでややこしいですが、配列なので順番を指定すればテキストを出力できます。

const text = post.htmlAst.children[0].children[0].value

タグを取得する方法

const tag = post.htmlAst.children[0].tagName

完成形

const post = data.markdownRemark

var toc = "<p class='mb-4'>目次</p><ol>"
var array = []

const childrens = post.htmlAst.children

function findText(children, ele) {
  if (children.tagName === ele) {
    const text = children.children[0].value
    const object = {
      element: ele,
      text: text,
    }
    children.properties = {
      id: text,
    }
    array.push(object)
  }
}

childrens.forEach(children => {
  findText(children, "h2")
  findText(children, "h3")
})

array.forEach(v => {
  var ele = ""
  if (v.element === "h2") {
    ele = `<li class="toc-h2"><a href="#${v.text}">${v.text}</a></li>`
  } else if (v.element === "h3") {
    ele = `<li class="toc-h3 text-sm font-normal"><a href="#${v.text}">${v.text}</a></li>`
  }
  toc += ele
})

toc += "</ol>"

前回と比べるとかなりマシになりました。やった!

表示する

<div dangerouslySetInnerHTML={{ __html: toc }}></div>

toc にタグがあるので、表示してあげれば OK で、その出力された内容に対してスタイルを与えてあげれば OK です。

まとめ

以上です。

誰かの参考になれば幸いです。

それでは!!!

質問、誤記などあれば Twitter などでご指摘よろしくおねがいします!

人気記事

PHP7.4 + Laravel6 のプロジェクトを AWS EC2 にデプロイする

関連記事

【ReactNative+CloudVision】「怒り顔採点アプリ」を作った