Настройте gatsby-transformer-remark, чтобы добавить классы по умолчанию

Я использую gatsby с плагинами gatsby-source-filesystem и gatsby-transformer-remark для отображения файлов уценки в виде страниц, как описано в официальные документы.

Это прекрасно работает, но я ищу способ добавить классы по умолчанию ко всем элементам, преобразованным из уценки.

Допустим, я хочу, чтобы каждый элемент <h1> имел класс title, а элементы <h2> по умолчанию имели класс subtitle.

Мне удалось сделать что-то подобное с gatsby-remark-attr, но с этим я могу только программно добавлять классы в файл уценки. Это выглядит так:

# My markdown heading
{.title}

## Subtitle
{.subtitle}

превращается в

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

Я ищу способ определить классы по умолчанию один раз для каждого элемента и применить их автоматически, без необходимости указывать их в файлах уценки.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
1 390
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

ТЛ, ДР: Использовать gatsby-remark-default-html-attrs


Gatsby gatsby-transformer-remark использует mdast-util-to-hast для преобразования узлов уценки в узлы html, которые затем преобразуются в необработанный HTML. Если узел уценки имеет объект data.hProperties, он будет преобразован в атрибуты html.

Допустим, вы хотите добавить имя класса foo ко всем узлам h1. Вам нужно:

  • найдите узел уценки, который в конечном итоге будет преобразован в html-элемент h1
  • добавить 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. Найдите узел уценки

Плагину будет предоставлен объект 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.info(h1Nodes) 
  // this yields  
  // [{ type: "heading", children: [{ type: "text", value: "..." }] }, ...]
}

2. Добавьте className в его data.hProperties

Мы можем изменить узел напрямую.

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

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

Вот и все, теперь все h1 должны иметь класс foo.

Это особенно интересный вопрос для меня, так как я изучаю Юнист и его экосистему, которая поддерживает remark; так что спасибо за это.

Я делаю простой плагин, который здесь немного более общий, не стесняйтесь попробовать и дайте мне знать, если что-то пошло не так.

Спасибо за этот хорошо объясненный, тщательно продуманный ответ. Я также пошел на создание плагина, но, просмотрев ваш, мой гораздо менее гибкий и более подвержен ошибкам — github.com/chrisg86/gatsby-remark-классы. Обязательно попробую ваш плагин, еще раз спасибо.

chrisg86 04.02.2019 14:22

Спасибо, @chrisg86, вы на самом деле уже поняли это, поэтому я не был так полезен! Я думаю, что мое случайное открытие потрясающего unist-util-select — это главное, что делает мою реализацию более гибкой. Если бы я придерживался unist-util-visit, думаю, я бы сделал то же самое, что и вы. Это был отличный вопрос, еще раз спасибо за него.

Derek Nguyen 04.02.2019 16:07

Также есть gatsby-remark-classes (Гитхаб, НПМ), который позволяет указать classMap в вашем gatsby-config.js.

{
  resolve: `gatsby-transformer-remark`,
  options: {
    plugins: [
      {
        resolve: `gatsby-remark-classes`,
        options: {
          classMap: {
            "heading[depth=1]": "title",
            "heading[depth=2]": "subtitle",
            paragraph: "para",
          }
        }
      }
    ]
  }
}

Его функциональность кажется идентичной gatsby-remark-default-html-attrs. Как ни странно, эти два плагина были созданы с разницей в один день (1 февраля 2019 г. и 2 февраля 2019 г. соответственно).

забавный факт объясняется в комментариях к другому решению :)

muescha 02.06.2020 16:32

Другие вопросы по теме