最初に結論から
- Atomのlinter-markdownプラグインは、内部的にremark-lintを使っている
- デフォルト設定のまま使うときは、システムへのremark-lintインストールは不要
- 設定ファイル名は
.remarkrc
(JSON)または.remarkrc.yaml
(YAML) -
設定ファイルを作った場合はシステムへのremark-lintインストールが必須
- プリセットのパッケージ
remark-preset-lint-consistent
とremark-preset-lint-recommended
も同時にインストールする - インストールはnpmを使ってローカル(
.remarkrc
と同じ階層)にインストール
- プリセットのパッケージ
インストールコマンドはこんな感じで。
% npm install remark-lint
% npm install remark-preset-lint-consistent
% npm install remark-preset-lint-recommended
JSONが好きな人は.remarkrc
を作成
{
"plugins": [
"remark-preset-lint-consistent",
"remark-preset-lint-recommended",
["remark-lint-list-item-indent", "space"],
["remark-lint-code-block-style", false],
["remark-lint-no-shortcut-reference-link", false]
]
}
YAMLが好きな人は.remarkrc.yaml
を作成
plugins:
- remark-preset-lint-consistent
- remark-preset-lint-recommended
- # 箇条書きリストのインデントは(タブではなく)スペース
- remark-lint-list-item-indent
- space
- # Qiitaのコードブロックで警告が出ないように
- remark-lint-code-block-style
- false
- # Qiitaの注釈で警告が出ないように
- remark-lint-no-shortcut-reference-link
- false
同階層に.remarkrc
と.remarkrc.yaml
が両方存在した場合は両方有効になりますが、設定項目がかぶった場合はJSONの.remarkrc
が優先されるようです。
バージョン組み合わせ
Atomのlinter-markdownパッケージのバージョンと、remark-lintのバージョンの組み合わせに要注意です。
この記事を投稿した2017/3/3時点では、linter-markdown 3.1.0がremark-lint 6.0.0に対応しておらず、古いremark-lintをインストールする必要がありました。2017/4/18時点ではlinter-markdownが4.0.0にバージョンアップしており、remark-lintの最新版で動く事を確認済みです。
バージョン組み合わせ | OK | NG | NG | NG | OK |
---|---|---|---|---|---|
linter-markdown | 4.0.0 | 3.1.0 | 3.1.0 | 3.1.0 | 3.1.0 |
remark-lint | 6.0.0 | 6.0.0 | 5.4.0 | 5.4.0 | 5.4.0 |
remark-preset-lint-consistent | 2.0.0 | 2.0.0 | 2.0.0 | 1.0.0 | 1.0.0 |
remark-preset-lint-recommended | 2.0.0 | 2.0.0 | 1.0.0 | 2.0.0 | 1.0.0 |
古いremark-lintのインストールコマンドと設定ファイルの記法も念のため残しておきます。特に設定ファイルの記法は最新版と違うので要注意。
古いバージョンのインストール
% npm install remark-lint@5.4.0
% npm install remark-preset-lint-consistent@1.0.0
% npm install remark-preset-lint-recommended@1.0.0
.remarkrc(古い記法)
{
"presets": [
"lint-consistent",
"lint-recommended"
],
"plugins": {
"lint": {
"list-item-indent": "space",
"code-block-style": false,
"no-shortcut-reference-link": false
}
}
}
.remarkrc.yaml(古い記法)
presets:
- lint-consistent
- lint-recommended
plugins:
lint:
list-item-indent: space
code-block-style: false
no-shortcut-reference-link: false
格闘記録(読み飛ばし可)
例のごとく、上記結論に至るまでの格闘記録を時系列で書きました。
興味があればどうぞ。
プロローグ
Markdown文章は今までMacDownで書いてたんですが、メインエディタのAtomに統一したいなーと思いまして、この記事とか参考に一通りMarkdown用のプラグインを入れました。
[さんざん悩んだマークダウンエディタの最終決定は「Atom」快適に使えるようにする設定と必須のパッケージ 厳選18個]
(http://www.kotalog.net/archives/6038)
ついでならMarkdown用のLinterも入れようと思いlinter-markdownプラグインもインストールしたのですが、その設定でもう果てしなく果てしなくハマってしまいました。特に日本語の情報が少ない少ない。。。
AtomにもLinterにもNode.jsにもMarkdownにもまだ不慣れだったので、これを機に勉強がてらとことんハマって、日本語でQiita記事にまとめておく覚悟を決めたのでした。自分でQiitaに書いたこともなかったですし。
これは壮絶なるエラーとの格闘サーガ三部作、最終話となります!
- Episode I
- [Titaniumで自動インストールされたnodeやnpmが/usr/local配下に残っていた件] (http://qiita.com/the_red/items/aeee6d328995f557cfbf)
- Episode II
- [Homebrewでnodebrewのインストールに失敗した時の対処(Perl, CPAN絡み)] (http://qiita.com/the_red/items/fd04d97947b9b0bd7a57)
- Anthology
- [AtomのLinterでエラー内容をコピペできない時はGitHubの最新版をインストールしよう!] (http://qiita.com/the_red/items/ebbece2411f55450db72)
- Episode III
- Atomのlinter-markdownを.remarkrcで設定する方法 (本エントリ)
Atomのlinter-markdownと、npmのremark-lint
linter-markdown
このプラグインは、内部的にremark-lintというnpmパッケージを使っているっぽい。スタイルなどの設定変更は、設定ファイル.remarkrc
を作成するとのこと。
.remarkrcを作成
Configuring remark-lint
まずはremark-lintのREADMEを読んで、サンプル通りに.remarkrc
作ってホームディレクトリに置いてみる。YAMLじゃなくてJSON形式。
{
"plugins": [
"remark-preset-lint-recommended",
["remark-lint-list-item-indent", false]
]
}
TypeError: name.charAt is not a function
at resolvePlugin (/Users/$USER/.atom/packages/linter-markdown/node_modules/load-plugin/index.js:59:45)
at merge (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:105:20)
at required (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:266:3)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:315:9
at /Users/$USER/.atom/packages/linter-markdown/node_modules/vfile-find-up/index.js:135:9
at FSReqWrap.oncomplete (fs.js:123:15)
linter-markdownのREADMEをもっかい読んでみる。
If there is configuration for remark-lint, through .remarkrc files or remarkConfig in package.jsons, this linter works just like remark-cli but only uses the remark-lint plugin. Make sure remark-lint is installed in this case (optionally globally).
「.remarkrcで設定変更するときは、システムにremark-lintをインストールしてね」って仕様みたい。
逆に「デフォルト設定のまま使うときはシステムへのremark-lintインストールは不要」ってのが変わってるよね。Rubyのlinter-rubocopとか、普通はシステムに入ってるLinterをAtomから呼ぶ仕様なので。
というわけで、npmでremark-lintをインストールすることに。実はnpmコマンドを自分で叩くのが初めてだった。。。
Node.jsのアンインストール、再インストール
予想外にあんなことやこんなことに苦労しまくって、ようやくnpmがまともに動くようになる。
remark-lintをnpmでインストール
linter-markdownのREADMEには「optionally globallyでインストールしてね」と書いてあったのでグローバルに入れてみるが、
% npm install -g remark-lint
結果変わらずエラー起きてしまうが内容は変わった。インストールしたremark-lintが認識されていないっぽい。
Error: Cannot find module `lint`
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/file-pipeline/configure.js:68:19
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:444:7
at Array.forEach (native)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:443:13
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:327:5
at /Users/$USER/.atom/packages/linter-markdown/node_modules/vfile-find-up/index.js:135:9
at FSReqWrap.oncomplete (fs.js:123:15)
いろいろ調べたら、GitHubに似たようなIssue発見。まだOpenの状態だった。
[Cannot find module 'lint' (with global remark-lint install) #115]
(https://github.com/AtomLinter/linter-markdown/issues/115)
For now the solution is to use locally installed modules!
作者が「ローカルにインストールすれば解決するよ!」って言ってるのでやってみる。
% npm uninstall -g remark-lint
% npm install remark-lint
TypeError: name.charAt is not a function
at resolvePlugin (/Users/$USER/.atom/packages/linter-markdown/node_modules/load-plugin/index.js:59:45)
at merge (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:105:20)
at required (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:266:3)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:315:9
at /Users/$USER/.atom/packages/linter-markdown/node_modules/vfile-find-up/index.js:135:9
at FSReqWrap.oncomplete (fs.js:123:15)
.remarkrc抜きでremark-lintと連携できるか試す
一旦.remarkrc
を変名して設定無効化。
mv .remarkrc .Lemarkrc
TypeError: Cannot read property 'use' of null at lint (/Users/$USER/node_modules/remark-lint/index.js:11:7)
at Function.use (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified/index.js:318:25)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/file-pipeline/configure.js:117:19
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:444:7
at Array.forEach (native)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:443:13
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:327:5
at /Users/$USER/.atom/packages/linter-markdown/node_modules/vfile-find-up/index.js:135:9
at FSReqWrap.oncomplete (fs.js:123:15)
remark-lintパッケージ自体は認識してて、その内部のエラーっぽい。
んでここからが超ハマる。GitHubのIssueはじめ何を検索しても情報がない。JS詳しくないのでnullの原因を突き止めるのも無理。英語で新規Issueあげるまでの気もちょっと起きないし。。。
バージョンを下げてみる
かなり悩んだ挙句、「remark-lintのバージョンを下げてみたらどうじゃろ?」と思いつく。(もっと早く思いつけ俺!)
普通に入れると最新の6.0.0が入ったので、GitHubのtag確認して1つ前の5.4.0を入れてみる。
https://github.com/wooorm/remark-lint/tree/5.4.0
% npm uninstall remark-lint
% npm install remark-lint@5.4.0
お、動いた!
.remarkrc
ナシなので、remark-lint@5.4.0
のデフォルト設定でLintしてる状態。
.remarkrcを有効に戻す
% mv .Lemarkrc .remarkrc
やっぱエラー。軽く絶望。
そして最初に起きたremark-lintが全く入っていない状態のエラーとまた同じ。。。
TypeError: name.charAt is not a function
at resolvePlugin (/Users/$USER/.atom/packages/linter-markdown/node_modules/load-plugin/index.js:59:45)
at merge (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:105:20)
at required (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:266:3)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:315:9
at /Users/$USER/.atom/packages/linter-markdown/node_modules/vfile-find-up/index.js:135:9
at FSReqWrap.oncomplete (fs.js:123:15)
.remarkrcを前のバージョンの形式に
まだ色々と粘る。諦め悪いよねー。
6.0.0と5.4.0のREADMEを見比べたところ、.remarkrc
のサンプルが違っていることに気づいたので、5.4.0のスタイルにまるっと書き直してみる。
https://github.com/wooorm/remark-lint/tree/5.4.0
{
"presets": ["lint-recommended"],
"plugins": {
"lint": {
"list-item-indent": false
}
}
}
Error: Cannot read configuration file: lint-recommended ENOENT: no such file or directory, open 'lint-recommended'
at Error (native)
at Object.fs.openSync (fs.js:640:18)
at Object.module.(anonymous function) [as openSync] (ELECTRON_ASAR.js:168:20)
at fs.readFileSync (fs.js:508:33)
at fs.readFileSync (ELECTRON_ASAR.js:501:29)
at load (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:213:13)
at required (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:266:17)
at preset (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:169:5)
at merge (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:81:11)
at required (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:266:3)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:315:9
at /Users/$USER/.atom/packages/linter-markdown/node_modules/vfile-find-up/index.js:135:9
at FSReqWrap.oncomplete (fs.js:123:15)
これは分りやすい。「lint-recommendedが見つからない」と言われてるので入れてみましょ。デフォルト設定で使われるプリセット一式のことやね。
https://github.com/wooorm/remark-lint#list-of-presets
If there is no configuration found for remark-lint, this linter runs remark-preset-lint-consistent and remark-preset-lint-recommended (both can be turned off).
この変から「行けそう!」って感覚になる。
少なくともバージョン6.0.0と5.4.0で.remarkrc
の互換性がないことは間違いなさそう。バージョンに沿ったスタイルの.remarkrc
を作る必要があるってことね。
remark-preset-lint-recommendedインストール
https://github.com/wooorm/remark-lint/tree/master/packages/remark-preset-lint-recommended
% npm install remark-preset-lint-recommended
TypeError: name.indexOf is not a function
at resolvePlugin (/Users/$USER/.atom/packages/linter-markdown/node_modules/load-plugin/index.js:59:12)
at merge (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:105:20)
at required (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:266:3)
at preset (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:169:5)
at merge (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:81:11)
at required (/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:266:3)
at /Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:315:9
at /Users/$USER/.atom/packages/linter-markdown/node_modules/vfile-find-up/index.js:135:9
at FSReqWrap.oncomplete (fs.js:123:15)
ここは直感で「remark-preset-lint-recommendedもバージョンを合わせれば良さそう」と気づく。
remark-preset-lint-recommendedのバージョン下げる
remark-preset-lint-recommendedは、npmで普通に入れると2.0.0が入る。そのバージョン番号はこのソースに書いてあった。
https://github.com/wooorm/remark-lint/blob/master/packages/remark-preset-lint-recommended/package.json
"version": "2.0.0",
GitHubリポジトリとしてはremark-lint配下のパッケージなのでtagは共通。tagを5.4.0に切り替えてみると、
https://github.com/wooorm/remark-lint/blob/5.4.0/packages/remark-preset-lint-recommended/package.json
"version": "1.0.0",
ということでremark-preset-lint@5.4.0
に対応するのはremark-preset-lint-recommended@1.0.0
ってことだね!
% npm uninstall remark-preset-lint-recommended
% npm install remark-preset-lint-recommended@1.0.0
オッケー!!!動いたーーーーー!!!!!!
ついでにもう一つのプリセットremark-preset-lint-consistent
もインストールしておく。バージョン体系は共通。
% npm install remark-preset-lint-consistent@1.0.0
最終的にnpm list
の結果はこの状態でちゃんと動いてます。
% npm list
/Users/$USER
├─┬ remark-preset-lint-consistent@1.0.0
│ └─┬ remark-lint@5.4.0
│ ├── decamelize@1.2.0
│ ├─┬ load-plugin@2.1.0
│ │ ├─┬ npm-prefix@1.2.0
│ │ │ ├─┬ rc@1.1.7
│ │ │ │ ├── deep-extend@0.4.1
│ │ │ │ ├── ini@1.3.4
│ │ │ │ ├── minimist@1.2.0
│ │ │ │ └── strip-json-comments@2.0.1
│ │ │ ├── shellsubstitute@1.2.0
│ │ │ └─┬ untildify@2.1.0
│ │ │ └── os-homedir@1.0.2
│ │ └── resolve-from@2.0.0
│ ├── mdast-util-heading-style@1.0.2
│ ├── mdast-util-to-string@1.0.2
│ ├─┬ plur@2.1.2
│ │ └── irregular-plurals@1.2.0
│ ├─┬ remark-message-control@2.0.3
│ │ ├── mdast-comment-marker@1.0.1
│ │ └── trim@0.0.1
│ ├── trough@1.0.0
│ ├── unist-util-generated@1.1.0
│ ├── unist-util-position@3.0.0
│ ├── unist-util-visit@1.1.1
│ ├── vfile-location@2.0.1
│ ├── vfile-sort@2.0.0
│ └─┬ wrapped@1.0.1
│ ├── co@3.1.0
│ └── sliced@1.0.1
└── remark-preset-lint-recommended@1.0.0
yamlで.remarkrcを書く
.remarkrc
のスタイルはJSON形式だけど、YAMLで書く方法ないものか探したら見つかった。拡張子を付けて.remarkrc.yaml
とすることでYAMLで書けるようになる。(なぜか拡張子.yml
はダメだった)
YAML configuration file support #75
presets:
- lint-recommended
plugins:
lint:
list-item-indent: false
同階層に.remarkrc
と.remarkrc.yaml
を両方作って試してみたところ、設定項目がかぶった場合はJSONの.remarkrc
が優先された。正式な仕様なのかは分からんので、どっちか片方だけ作る方が自然だとは思います。
Qiitaにまとめようとして
この辺でQiita記事を書こうと準備はじめたんですが、LinterのエラーメッセージをMarkdownにコピペしたいのに出来なくてイライラして、すんごい調べた結果Anthology記事が書けてしまいました(笑)
自分なりの設定を書く
やっと最初にやりたかったことが出来る(´;ω;`)
そもそもは、list-item-indentがデフォルトでtab-size
だったのが嫌でspace
に直したかったのでした。サンプルの.remarkrc
でたまたまlist-item-indent: false
と設定してあったのでspace
に変更。false
だとチェック自体が走らないので。
ついでにプリセットのlint-consistent
も書いてみたり、Qiitaで記事を書くときに不都合な設定をfalse
にしたりして、現時点の.remarkrc.yaml
はこんな感じでちゃんと動いてます。これから少しずつ設定追加していくと思いますが。
presets:
- lint-consistent
- lint-recommended
plugins:
lint:
list-item-indent: space
code-block-style: false # Qiitaのコードブロックで警告が出ないように
no-shortcut-reference-link: false # Qiitaの注釈で警告が出ないように
おわりに
これにて本シリーズは一旦終了です!ほぼ自己満だけど長かった(´;ω;`)
Linterまだまだ使いこなしてないけど好きな分野なので、linter-markdownに関する日本語の情報が皆無な状態を何とかしたくて結構がんばりました。この記事を読んでAtomでMarkdownをLintする日本人が少しでも増えてくれますと、大悦至極に存じ奉ります。
日頃Qiitaとか他の記事とか読んで「たいていのノウハウは誰かが書いてくれてる」と思ってたんですが、「ニッチな分野では誰も書いてないノウハウがまだまだある」ってことが今回わかりました。誰も書いてないことが分かると「俺が書いてやろう!」って自然に燃えるので、今後もそういうタイミングで少しずつQiitaに投稿しようと思います。
そして僕の一番の課題は「細部にこだわりすぎてスピード遅すぎる」こと。今回はあえて思う存分時間かけましたが、ある程度の質でサクサク沢山書けるようになりたいっすねーマジで。ソースコードも同じなんだけど。。。
最後までお付き合いくださった方、どうもありがとうございました〜m(. .)m
2017/4/18 追記
linter-markdownが4.0.0にバージョンアップして、remark-lint@6.0.0に対応していました。それに伴ってremark-lint@5.4.0では動かなくなっており、Markdownを編集しようとするとこんなエラーが。
TypeError: remark.use is not a function at Function.lint
(/Users/$USER/node_modules/remark-lint/lib/index.js:65:10) at freeze
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified/index.js:122:28) at Function.parse
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified/index.js:271:5) at parse
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/file-pipeline/parse.js:37:36) at wrapped
(/Users/$USER/.atom/packages/linter-markdown/node_modules/trough/index.js:128:19) at next
(/Users/$USER/.atom/packages/linter-markdown/node_modules/trough/index.js:81:24) at done
(/Users/$USER/.atom/packages/linter-markdown/node_modules/trough/index.js:163:12) at handleConfiguration
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/file-pipeline/configure.js:68:5) at done
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/configuration.js:77:14) at apply
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/find-up.js:176:7) at applyAll
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/find-up.js:166:7) at found
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/find-up.js:158:7) at apply
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/find-up.js:176:7) at applyAll
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/find-up.js:166:7) at found
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/find-up.js:158:7) at done
(/Users/$USER/.atom/packages/linter-markdown/node_modules/unified-engine/lib/find-up.js:149:9) at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:445:3)
前回ハマりまくった経験があったので、今回は普通にnpmの最新版を入れて、設定ファイルの記法も変更して、短時間で解決できました。めでたし。
% npm install remark-lint
% npm install remark-preset-lint-consistent
% npm install remark-preset-lint-recommended
{
"plugins": [
"remark-preset-lint-consistent",
"remark-preset-lint-recommended",
["remark-lint-list-item-indent", "space"],
["remark-lint-code-block-style", false],
["remark-lint-no-shortcut-reference-link", false]
]
}
plugins:
- remark-preset-lint-consistent
- remark-preset-lint-recommended
- # 箇条書きリストのインデントは(タブではなく)スペース
- remark-lint-list-item-indent
- space
- # Qiitaのコードブロックで警告が出ないように
- remark-lint-code-block-style
- false
- # Qiitaの注釈で警告が出ないように
- remark-lint-no-shortcut-reference-link
- false