URL encode in LaTeX

LaTeX でロシア語テクストを含む URL を出力しなければならないとき,url パッケージの \url 命令だと,キリル文字が出力できない。hyperref パッケージの \href{URL}{text} 命令を使って,text 部にロシア語テクストを記述すれば,これが可能となる。ところが,後者の場合でも,URL 部にロシア語 URL をそのまま指定しても,PDF にした際にそのリンクから当該リソースに飛んでくれない。この URL 部にはエンコード形式,つまり,ロシア文字を 1 オクテットずつ %xx の十六進数とした形式を指定しておかなければならないようである。

URL エンコードを行うツールはあちこちに転がっていて,Web なら http://www.tagindex.com/tool/url.html などの便利なサイトがある。Emacs 用の Elisp も探せばあるかも知れない。でも,LaTeX で,この URL エンコードを埋め込むとなると,% 文字が含まれるため,これをいちいちエスケープする手間が別途発生し,これまた面倒である。そこで,これくらいならツールを探す時間の間に出来てしまうと思い,自前で LaTeX 向け UTF-8 前提 URL エンコード・ツールを作ってみた。Perl である。U+0080 以上の UTF-8 文字を URL エンコードするので,ロシア語以外に日本語,ドイツ語などを含む URL にも適用できるはずである。同じ必要に駆られる方もいらっしゃると思うので,以下にそのコードを掲載しておく。ここにも置いておくので,ダウンロードして使っていただいてよい(無保証)。

#!/usr/bin/perl -w
# -*- coding: utf-8; mode: cperl; -*-
#  URL encoding: convert chars over U+0080 to format %hex.
#  Usage: urlenc [ -l ] < stdin (url text)
use strict;
use utf8;
use Getopt::Std;    # command line processing
use File::Basename; # get file basename
 
# command line
my %opts = ('l' => 0);
Getopt::Std::getopts('l', \%opts) ||
    die "Usage: " . basename($0) .
    " [ -l ] \< (stdin)\n  -l: insert \\ before % for LaTeX\n";
my $sfx = "%"; $sfx = "\\" . $sfx if ($opts{'l'});
 
# hex format
while (<STDIN>) {
    utf8::decode($_);
    my $enc = "";
    foreach my $chr (split(//, $_)) {
        if ($chr ge "\x{0080}") {
            utf8::encode($chr);
            foreach my $bchr (split(//, $chr)) {
                $enc .= $sfx . sprintf("%x", ord($bchr));
            }
        } else {
            $enc .= $chr;
        }
    }
    print $enc;
}

Perl コードはこれだけである。標準入力から読んだ URL 文字列のうち U+0080 以上を %xx 形式に変換して,標準出力に書き出す。オプション -l を指定すると LaTeX 向けに \%xx とエスケープした形で出力する。このプログラムを urlenc と名付けて,パスの通ったところにコピーして利用する。Mac OS X ターミナルでの実行例を以下に示す。

url-term.png

Emacs から利用する場合は,以下の内容を .emacs に記述し,関数定義を C-x C-e で Emacs に認識させるか,Emacs を再起動すれば,urlencode 命令が利用可能となる。ウラで上記 urlenc プログラムが動くので先きにこれを組込んでおくこと。urlenc の絶対パスは利用者の環境に応じて変更する必要がある。LaTeX 原稿において変換したいテクストをリージョン設定し,M-x urlencode RTN とすれば,当該リージョンが URL エンコード変換される。Emacs の set-default-coding-systems'utf-8 にセットしておかなければならない。

;;
;; URL encoding for LaTeX
;;
(set-default-coding-systems 'utf-8) ;; すでに設定されていれば不要
;;
(defun urlencode (start end)
  "URL encoding for LaTeX"
  (interactive "r")
  (call-process-region
   start end
   "/usr/local/bin/urlenc" ;; urlenc の絶対パスを指定
   t (list t nil) nil
   "-l") ;; urlenc LaTeX 用オプション
  )

Emacs 上での変換の様子を以下に示す。

url-emacs.png