首页 > 解决方案 > 配置 gatsby-transformer-remark 以添加默认类

问题描述

我正在使用带有插件的 gatsbygatsby-source-filesystem并将gatsby-transformer-remark降价文件显示为页面,如官方文档中所述。

它工作得很好,但我正在寻找一种方法来为从 markdown 转换的所有元素添加默认类。

假设我希望每个<h1>元素都有一个类title,默认情况下<h2>元素有一个类。subtitle

我设法用 . 做这样的事情gatsby-remark-attr,但是我只能在 markdown 文件中以编程方式添加类。它看起来像这样:

# My markdown heading
{.title}

## Subtitle
{.subtitle}

转换为

<h1 class="title">My markdown heading</h1>
<h2 class="subtitle">Subtitle</h2>

我正在寻找一种方法来为每个元素定义一次默认类并自动应用它们,而不必在降价文件中指定它们。

标签: gatsby

解决方案


TL,DR:使用gatsby-remark-default-html-attrs


Gatsbygatsby-transformer-remark用于mdast-util-to-hast将 markdown 节点转换为 html 节点,然后将其字符串化为原始 HTML。如果 markdown 节点有一个data.hProperties对象,它将被转换为 html 属性。

假设您想将类名添加foo到所有h1节点。你需要:

  • 找到最终将转换为h1html 元素的 markdown 节点
  • 将 className 添加到其data.hProperties

0. 设置

首先,您需要一个自定义插件来修改transformer-remark. 值得庆幸的是,使用 gatsby 创建本地插件很简单:

# Create a `plugins` folder at your root
mkdir plugins
mkdir plugins/remark-default-class-name
cd plugins/remark-default-class-name
npm init -y
touch index.js

您现在将获得以下结构:

root
  |--src
  |--gatsby-config.js
  `--plugins
      `--remark-default-class-name
           |--package.json
           `--index.js

然后将新的本地插件添加到gatsby-config.js

// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
  +       `remark-default-class-name`
        ],
      },
    },

1.找到markdown节点

该插件将被赋予一个markdownAST对象,它允许您查找和修改节点。

我会unist-util-select用来帮助找到正确的节点。它带有gatsby-transformer-remark,但如果由于某些原因它不起作用,只需重新安装即可。

从这里开始,找到节点是微不足道的:

const { selectAll } = require('unist-util-select');

module.exports = ({ markdownAST }) => {
  // `heading` is equivalent to `h1...h6` in markdown.
  // specify [depth] allow us to target the right heading tag.
  const h1Nodes = selectAll('heading[depth=1]', markdownAST);

  console.log(h1Nodes) 
  // this yields  
  // [{ type: "heading", children: [{ type: "text", value: "..." }] }, ...]
}

2.将className添加到它的data.hProperties

我们可以直接修改节点。

  const h1Nodes = selectAll('heading[depth=1]', markdownAST);

- console.log(h1Nodes)
  // node doesn't always have data
+ if (!node.data) node.data = {};
+ node.data.hProperties = {
+   className: 'foo'
+ }

就是这样,现在所有人都h1应该foo上课了。

这对我来说是一个特别有趣的问题,因为我正在学习Unist及其生态系统,它具有强大的remark; 所以谢谢你。

我在这里制作了一个更通用的简单插件,请随意尝试一下,如果出现问题,请告诉我。


推荐阅读