Node.jsValidator.nuを使ってHTMLファイルをチェックするスクリプトを書いていた。form-dataモジュールを見つけるのに1時間、スクリプト書くのに15分。

form-dataモジュールはXMLHTTPRequest Level 2FormDataインターフェイスに似たものを提供するNode.jsモジュール。append()でパラメーターを追加していき、submit()で指定したURLにPOSTすることができる。Validator.nuはapplication/x-www-form-urlencodedに対応しておらず、Query Stringモジュールとかでポンと叩くことはできないため、このform-dataモジュールやahr2モジュールなどが(面倒くさいので)必要。

#!/usr/bin/env node

var FormData = require('form-data');
var fs = require('fs');

var htmlfile = process.argv.slice(2)[0];

var fd = new FormData();
fd.append('out', 'json');
fd.append('file', fs.createReadStream(htmlfile));
fd.submit('http://validator.nu/', function (error, response) {
  if (error) {
    throw error;
  }

  var chunks = '';

  response.on('data', function (chunk) {
    chunks += chunk;
  });

  response.on('end', function () {
    JSON.parse(chunks).messages.forEach(function (message) {
      if (message.type === 'error') {
        var line = (message.lastLine ? message.lastLine : 0);
        var column = (message.firstColumn ? message.firstColumn: 0);
        console.log([htmlfile, line, column, message.message].join(':'));
      }
    });
  });
});

コマンドラインに渡された最初の引数をHTMLファイルのパスとみなし、その内容をmultipart/form-dataでバリデーターにPOSTし、返ってきたJSONフォーマットの結果をGNUの標準エラーフォーマットに整形して標準出力に吐いている。

form-dataモジュールはHTTPモジュール決め打ちだったりなんかアレな気がするので、append()だけ使ってsubmit()を使わずにpipe()でHTTP(S)モジュールに渡す形で書いた方が良いかもしれない。