Gatsby

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

いつもご利用ありがとうございます。このブログは、広告費によって運営されています。

⇨ 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】「怒り顔採点アプリ」を作った