Twitterではツイートの表示にいくつか規制がある。例えばTwitterの鳥さんを表示しなければならないとかユーザーのプロフィールへのリンクでは#!/のアレはダメだったりとかかなり細かい。ということでユーザー名やURL、ハッシュタグにまとめてリンクを張るJavaScriptをjQueryで普通に書いてみた

まず正規表現の定義。

var url     = "https?://\\S+";
var mention = "@[0-9a-zA-Z_]{1,15}";
var hashtag = "#[0-9a-zA-Z]+";

var re_url     = new RegExp("^" + url);
var re_mention = new RegExp("^" + mention);
var re_hashtag = new RegExp("^" + hashtag);

var re_token = new RegExp("(" + url + "|" + mention + "|" + hashtag + ")", "g");

テキストで定義して連結する。URLを優先した。

var tokens = input.split(re_token);

入力(=ツイート)を分割。

for (var i = 0, l = tokens.length; i < l; i++) {
  var token = tokens[i];

  if (re_url.test(token)) {
    console.log("URL: " + token);
    output.append($("<a/>", {
      href: token
    }).append(token));
  } else if (re_mention.test(token)) {
    console.log("Mention: " + token);
    output.append($("<a/>", {
      href: "http://twitter.com/" + encodeURIComponent(token.replace(/^@/, ""))
    }).append(token));
  } else if (re_hashtag.test(token)) {
    console.log("Hashtag: " + token);
    output.append($("<a/>", {
      href: "http://twitter.com/search?q=" + encodeURIComponent(token)
    }).append(token));
  } else {
    console.log("Plain: " + token);
    output.append(token.replace(/[\r\n]/g, "<br>"));
  }
}

あとはトークンごとに内容をチェックしそれに応じて適切なそうなURLにリンクを張る。URLのエスケープ他はある程度はjQueryが勝手にやってくれるので、それになんとなく任せた。

というかTwitter本家の行うHTML化と同じ結果を返してくれるパラメーターとかあれば良いのに。ガイドラインを厳しくするならその分サービス側で使う人が手抜きできる仕組みを用意して欲しい。Tweet Entities使って分割しながらリンクにして連結しろってことなのかもしれないけど、面倒な気がしてしょうがない。ということを書きたかったのでエントリにした。