macOS で textlint を右クリックのメニューから呼べるようにする


textlint 、皆さんつかってますか?
設定に応じて文章の問題点を指摘してくれて、校正的な作業が手軽にできてめっちゃ便利ですね。

これを JavaScript やシェル経由だけでなく、あちこちのアプリケーションで手軽に呼んでチェックできたら、さらに便利だと思いませんか?

この記事では、 macOS の Automator を使って、右クリックで出るメニュー (コンテクストメニュー) から textlint を呼べるようにする方法を解説します。

なお、私は macOS を英語ロケールで使用していますので、日本語ロケールの場合は若干操作を読み替えていただく必要があります。

インストール方法

textlint 自体の導入

基本的にはすでに npm や textlint を使っている人向けの記事と考えていますので、深くは解説しません。コマンドだけ載せておきます。

$ npm install -g textlint
$ textlint --init

サンプルのために「だ・である」調と「です・ます」調の統一のルールをインストールしています。ここは各々の普段使っている設定で良いでしょう。

$ npm install -g textlint-rule-no-mix-dearu-desumasu
$ cat <<EOF > ~/.textlintrc
{
  "rules": {
    "no-mix-dearu-desumasu": true
  }
}
EOF

Automator でサービスを作る

コンテクストメニューに項目を追加するには、 Automator を使うと手っ取り早いのです。

1. Automator アプリケーションの起動

Automator というアプリケーションを /Applications から探して起動してください。
あるいは Spotlight から au などと入力すれば候補が表示されると思います。

2. New → Service を選択

3. Run Shell Script を追加

Run Shell Script をライブラリから加えます。
検索ボックスから run shell script などと検索すると見つけやすいです。

4. スクリプトの内容を記述

下記のスクリプトを貼り付ければ OK です。

export PATH='/usr/local/bin:/usr/bin:/bin'
/usr/bin/osascript -l JavaScript -e '
this.run = (argv) => {
  const app = Application.currentApplication();
  app.includeStandardAdditions = true;
  if (!argv[0]) {
    app.displayAlert("OK");
    return;
  }
  app.displayAlert(argv[0]);
};' "$(cat - | /usr/local/bin/textlint --stdin 2>&1)"

 5. 保存

メニューから File -> Save を選択して、名前をつけて保存します。
私は Textlint という名前をつけました。

これで完了です。

使用例

せっかくなので、この Qiita 記事の入力画面での実行した例をスクリーンショットで載せてみます。

こんな感じの、わかりやすい「である」と「です」が混合した文を用意してみました。

サンプル文章
これはオレンジである。リンゴではないのです。

1. テキストを選択

2. 右クリックで Textlint を選択してクリック

3. すると、ちゃんとエラー内容がアラートがでます

特に問題ない文字列の場合には「OK」と出力します。
このように、どこでもテキストを検証できるので、とてもしあわせになれそうです。
(なお、コンテクストメニューやテキスト選択に対応していないアプリケーションでは無力です。)

おまけ: 解説

貼り付けたシェルスクリプトの解説をします。

1. パスを通す

コンテクストメニューから呼ばれる場合 /usr/local/bin あたりのパスが通っていないので明示的に追加してやる必要があります。

export PATH='/usr/local/bin:/usr/bin:/bin'

2. textlint 部分

--stdin オプションをつけても、うまく標準入力経由から読めなかったため、 cat - でパイプしています。
おそらく textlint が TTY 経由とそうでない場合ですこし挙動を変えているためと推測していますが、まだ追っていません。

cat - | /usr/local/bin/textlint --stdin 2>&1

3. JXA 部分

この部分で Apple Script (JXA) と textlint をつなげています。

/usr/bin/osascript -l JavaScript -e '(JavaScript コード)' "$( textlint 部分 )"

JXA とは JavaScript for Automation のことで、 AppleScript を JavaScript で書けるようにしたもの、と考えればよいです。

(JavaScriptコード)
this.run = (argv) => {
  const app = Application.currentApplication();
  app.includeStandardAdditions = true;
  if (!argv[0]) {
    app.displayAlert("OK");
    return;
  }
  app.displayAlert(argv[0]);
};

やっていることはとても単純で、第一引数をエラーメッセージとして、
メッセージが空文字列なら OK そうでないならそのままメッセージを出力する、というものです。

グローバルスコープの run は C 言語の main 関数のようなものです。
(グローバルスコープでない const run = (argv) => { ... }; のように書いても実行されません。)

表示には displayAlert を使っています。
アラートではなく通知にしたい場合には app.displayNotification を使うなど、自分の好みにあわせていろいろと工夫すれば、さらに使いやすくすることができるでしょう。

また、このやり方さえ覚えてしまえば、 textlint 以外の校正ツール (e.g. redpen ) 等でもかんたんに右クリックメニューの項目を作ることができると思います。どうぞお試しください。