はじめに
前回の記事で,Slidevのテーマ「slidev-theme-gtlabo」を紹介しました.
スライドを書き進めると,.md に書いたVueのタグのインデントが崩れていきます.
<div>
<div>これを <MathText>$(\bm{x}, \bm{A}\bm{x})$</MathText> に代入する</div>
<br/>
<ul><li>a <MathText>$x$</MathText> b</li></ul>
</div>
ReactではESLintとPrettierが保存時に整形してくれるので,同じことをSlidevの .md でも行えるようにしました.保存すると,上のコードは次のようになります.
<div>
<div>
これを <MathText>$(\bm{x}, \bm{A}\bm{x})$</MathText> に代入する
</div>
<br />
<ul>
<li>
a <MathText>$x$</MathText> b
</li>
</ul>
</div>
gtlabo専用ではありません
どのSlidevプロジェクトでも使えます.ただし,slidev-theme-gtlabo に合わせた部分が3つあります.
- 改行を足さないインライン要素に,
MathText,HighlightText,EqRef,Citationを指定しています.ほかのテーマで似た役割のコンポーネントを使うと,改行が足されて表示の空白が変わることがあります -
:currentChapterのようなcamelCaseのpropsを,ハイフンに直しません - 対象は
slides.mdとpages/**/*.mdだけです
使い方
npm i -D slidev-md-lint eslint prettier
ESLint 9のflat configが前提です.eslint.config.js には以下のように記述します.
import base from 'slidev-md-lint/base' // .js / .ts / .vue の基本ルール
import slidevMd from 'slidev-md-lint' // .md の中のVue
export default [...base, ...slidevMd]
prettier.config.js には以下のように記述します.
import base from 'slidev-md-lint/prettier'
export default base
VS Codeで保存時に整形するには,.vscode/settings.json に以下を追加します.eslint.validate に markdown を含めないと,ESLint拡張が .md を検査しません.
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"eslint.validate": ["javascript", "typescript", "vue", "markdown"]
}
設定を変更したあとは,コマンドパレットから「ESLint: Restart ESLint Server」を実行します.
修正される要素
| 要素 | ルール |
|---|---|
| タグのインデント | vue/html-indent |
div や li の開始タグ・中身・終了タグの改行 |
vue/singleline-html-element-content-newline,vue/multiline-html-element-content-newline
|
| 属性が多いときの改行 | vue/max-attributes-per-line |
<br/> を <br /> に,<div /> を <div></div> に |
vue/html-self-closing |
| 末尾の空白,余分な空行 | prettier-plugin-slidev |
インライン要素に改行を足すと,前後に空白が入って表示が変わります.そのため改行を足す対象は,先頭と末尾の空白が表示に出ない div や li などのブロック要素に限っています.
仕組み
ESLintには,ファイルの一部を取り出して検査するprocessorの仕組みがあります.これを使い,次のように処理しています.
-
.mdを---で区切り,スライド1枚ごとに分ける(frontmatterとコードフェンスは除く) - 1枚ごとに
<template>で包み,eslint-plugin-vueに渡す - 自動修正の位置を元の
.mdの行に戻して書き込む
Markdown部分の整形は,Slidev公式の prettier-plugin-slidev が担当します.
実装上の注意点
- 囲みの
<template>を除外リストに入れると,eslint-plugin-vueのルールは子孫の要素も検査しなくなります.そのため,除外はせず,囲みの行に出た指摘をprocessor側で捨てています - slidev-theme-gtlabo の
eslint.config.jsは,package.jsonのfilesに含めておらず,npmには入っていませんでした.同じ内容をslidev-md-lint/baseに同梱しています - flat configでは,ESLintの
--extオプションは不要です.lintスクリプトはeslint .だけで動作します
注意
自動修正はファイルを書き換えます.初めて使うときは,先に git commit しておくことを勧めます.
検証中に,保存したら .md が空になったことが一度ありました.画面操作を自動化していた最中で,原因は特定できていません.再現した場合は,ESLintの出力パネルのログを添えてIssueで報告してもらえると助かります.
おわりに
インライン扱いにするコンポーネントは固定で,設定では追加できません.自作のインラインコンポーネントを使っていて問題がある場合は,IssueかPRをお願いします.