textlint 11.0.0をリリースしました。

細かい変更点は次のリリースノートにまとめられています。

⭐️ Features

@textlint/textlint-plugin-text@textlint/textlint-plugin-markdownextensions オプションをサポート

@textlint/textlint-plugin-text@textlint/textlint-plugin-markdownはビルトインのプラグインです。 このプラグインによって、.mdなどの拡張子がMarkdownとして認識されtextlintでLintできています。

textlint 11ではビルトインのプラグインがextensionsというオプションをサポートしています。 たとえば、 .hown という拡張子をMarkdownとして扱いたい場合 .textlintrc に次のように記述します。

{
    "plugins": {
        "@textlint/markdown": {
            "extensions": [".hown"]
        }
    }
}

詳しくは custom extension example というサンプルを見るとわかります。

自分で作ったプラグインで同じ仕組みの extensions オプションをサポートする場合は、Plugin · textlintのドキュメントを読んでください。

🔥BREAKING CHANGE

Drop Node.js 4.x support #443

textlint 11からはNode.js 4.xをサポートしていません。 (ここでのサポートはテスト対象ではないという意味なのでまだ動く可能性はあります)

また、Node.js 4.x自体がNode.js公式にサポートが終了しています(EOL)。

そのため、Node.js 4.xを使っている人は、セキュリティ的な問題もあるためNode.jsのアップデートをしてください。

[Developer] Freeze Rule’s Context #508

開発者向けですが、ルールにわたされる context オブジェクトが Object.freezeされるようになりました。余計な変更ができないようにするためです。 次のようなコードはtextlint 11では例外を投げます。

export default function(context) {
    // Error: `context` object can not be modified
    context.modifiedContext = true;
    const { Syntax } = context;
    return {
        [Syntax.Str](node) {
        }
    };
}

同じようにASTの変更も例外を投げるようにするというIssueがあります。 興味がある人は見てみてください。

[Developer] ルールとプラグインのoptionsのデフォルト値を変更 #535 #540

textlint 11ではルールとプラグインで何もオプションを指定してないのときのデフォルト値をtrueから{}(空オブジェクト)に変更しました。

例えば次のようなvery-nice-ruletrueで有効化していた場合にtextlint 10と11ではoptionsに渡される値が異なります。

{
  "rules": {
    "very-nice-rule": true
  }
}

Before

very-nice-rule.js rule get true as options.

export default function(context, options) {
    console.log(options); // true
}

After:

very-nice-rule.js rule get {} (emptry object) as options.

export default function(context, options) {
    console.log(options); // {}
}

textlint 10までの実装は使いみちがなく扱いにくいだけだったので11で {} 空オブジェクトに変更しました。もしかしたらこの影響を受けるルールがあるかもしれません。textlint 11でエラーがでるルールを見つけたらお知らせください。

⚠ Deprecation

[Developer] Deprecate static availableExtensions() in plugin Processor

textlint 10までは、プラグインではサポートしている拡張子をstatic availableExtensions()を実装し返すようになっていました。 textlint 11からは、プラグインではサポートしている拡張子をavailableExtensions()を実装することで返せるようになります。

staticメソッドではなくインスタンスメソッドで実装できるようになることで、availableExtensions()の中でオプションの値を利用できます。 これはextensionsオプションを実装するために必要な変更でした。

そのため、既存のプラグインは次のように変更することを推奨しています。 (staticメソッドも互換性のために維持しています。)

-    static availableExtensions() {
+    availableExtensions() {
        return [".txt", ".text"];
    }

プラグインでextensionsオプションをサポートするには次のように書けます。

// TextProcessor.js
import { parse } from "txt-to-ast";
export default class TextProcessor {
    constructor(options = {}) {
        this.options = options;
        // support "extension" option
        this.extensions = this.config.extensions ? this.config.extensions : [];
    }
    // available ".ext" list
    // user can add own custom extension as "extensions" option
    availableExtensions() {
        return [".txt", ".text"].concat(this.extensions);
    }
    // define pre/post process
    // in other words, parse and generate process
    processor(ext) {
        return {
            preProcess(text, filePath) {
                // parsed result is a AST object
                // AST is consist of TxtNode
                // https://github.com/textlint/textlint/blob/master/docs/txtnode.md
                return parse(text);
            },
            postProcess(messages, filePath) {
                return {
                    messages,
                    filePath: filePath ? filePath : "<text>"
                };
            }
        };
    }
}

詳しくは次のページをみてください。

リリースノート

次のリリース

そろそろLintエラーのメッセージのローカライズやカスタマイズ(textlintをモジュールとして使っていてルールのメッセージを変えたい)などができる仕組みを入れたいと考えています。実際にそういうユースケースを持っている人は次のIssueを参照してください。

その他: ルール

textlint本体ではありませんが、技術文書向けのtextlintルールプリセットも最近メジャーアップデートしています。

macOS + Chromeで一時期バグって入っていた制御文字を検出して修正できるtextlint-rule-no-invalid-control-character textlint-rule-sentence-lengthが大幅にアップデートされています。

興味がある人は見てみてください。

最近Wikipedia:表記ガイド - Wikipediaをみていて、結構よくまとまっていたのでこのガイドもルール化できると面白そうです。