0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Slidevの.mdに書いたVueをESLintで整える「slidev-md-lint」を作った

0
Posted at

はじめに

前回の記事で,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の仕組みがあります.これを使い,次のように処理しています.

  1. .md を --- で区切り,スライド1枚ごとに分ける(frontmatterとコードフェンスは除く)
  2. 1枚ごとに <template> で包み,eslint-plugin-vue に渡す
  3. 自動修正の位置を元の .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をお願いします.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?