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





ТЛ, ДР: Использовать gatsby-remark-default-html-attrs
Gatsby gatsby-transformer-remark использует mdast-util-to-hast для преобразования узлов уценки в узлы html, которые затем преобразуются в необработанный HTML. Если узел уценки имеет объект data.hProperties, он будет преобразован в атрибуты html.
Допустим, вы хотите добавить имя класса foo ко всем узлам h1. Вам нужно:
h1data.hPropertiesВо-первых, вам нужен собственный плагин для изменения узлов уценки 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`
],
},
},
Плагину будет предоставлен объект 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: "..." }] }, ...]
}
Мы можем изменить узел напрямую.
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; так что спасибо за это.
Я делаю простой плагин, который здесь немного более общий, не стесняйтесь попробовать и дайте мне знать, если что-то пошло не так.
Спасибо, @chrisg86, вы на самом деле уже поняли это, поэтому я не был так полезен! Я думаю, что мое случайное открытие потрясающего unist-util-select — это главное, что делает мою реализацию более гибкой. Если бы я придерживался unist-util-visit, думаю, я бы сделал то же самое, что и вы. Это был отличный вопрос, еще раз спасибо за него.
Также есть 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 г. соответственно).
забавный факт объясняется в комментариях к другому решению :)
Спасибо за этот хорошо объясненный, тщательно продуманный ответ. Я также пошел на создание плагина, но, просмотрев ваш, мой гораздо менее гибкий и более подвержен ошибкам — github.com/chrisg86/gatsby-remark-классы. Обязательно попробую ваш плагин, еще раз спасибо.