1.14 タイトルまたは見出しを適切にキャピタライズしたい

書籍、書類などにはタイトルや見出しがある。このタイトルおよび見出しに使用する文字列を適切にキャピタライズしたい。

INIT {
  our %nocap;
  for (qw(
          a an the
          and but or
          as at but by for from in into of off on onto per to with
       ))
  {
    $nocap{$_}++;
  }
}

sub tc {
  local $_ = shift;

  # リストにある文字は小文字に、それ以外はタイトル文字に変換
  s/(\pL[\pL']*)/$nocap{$1} ? lc($1) : ucfirst(lc($1))/ge;

  s/^(\pL[\pL']*) /\u\L$1/x;  # 最初の単語をキャピタライズする
  s/ (\pL[\pL']*)$/\u\L$1/x;  # 最後の単語をキャピタライズする

  # カッコ内は完全なタイトルとして扱う
  s/\( (\pL[\pL']*) /(\u\L$1/x;
  s/(\pL[\pL']*) \) /\u\L$1)/x;

  # コロン、セミコロンの直後の単語をキャピタライズする
  s/ ( [:;] \s+ ) (\pL[\pL']* ) /$1\u\L$2/x;

  return $_;
}