はじめに
連載の第1回、第2回で見てきたように、Perlのようなテキスト処理を得意とする言語を使えば、テキストのパターンを読み取って、ある一定の規則で変換したり、加工したりすることは自由自在です。今回は、筆者が作成した「日記記述言語(DDL)」という簡易言語を使った日記の記述から、HTMLで書かれた日記に変換出力するスクリプトを作成します。
最近は「ブログ」という言葉が日常会話の中で普通に使われるようになり、自分のブログを持っている人も多くなりました。しかし、お仕着せのパターン化されたブログは使いたくないという方もいると思います。ブログのデザインもバラエティーに富んでいて、実際なかなかやるなと思うようなデザインも多いのですが、記事部分の表現の自由度が低いのが一般的でしょう。今回紹介する方法は、自分のアイデアを活かしてすべてを作り出したいという方を支援するものであり、これを応用すれば、すべてを自分の好みにカスタマイズできます。また、仕事でHTMLを使う場合やCMS(Contents Management System)を構築する場合に、HTML作成を支援する方法を生み出すヒントともなるでしょう。
日記記述言語(DDL)と、DDLの記述をHTMLに変換する「ddl2html.pl」は、第2回の「Web日記のAtom配信」をそのまま適用できるWeb日記を生成します。さらに、その一種の変形として、「ddl2html.pl」で生成した日記を検索し、検索結果をHTMLで出力するスクリプト「renewal_r2html.pl」を作成します。また、生成したWeb日記のHTMLファイルをエディタ上からFTP配信するスクリプト「ftp2site.pl」も紹介します。
Perlの選択とエディタ上のスクリプトの動作
今回は、HTML編集が目的なので、テキスト加工の自由度を最大限に確保するためにCGIは使わず、エディタ上でjperlスクリプトを動作させます。テキスト処理においてはエディタも強力なツールとなります。Windows上のエディタとして推奨するのは、TeraPadです。エディタ編集画面上の選択範囲を、標準入力としてjperlに渡し、jperlが処理して標準出力した内容に置き換えることができます。同様の機能があれば、他のエディタも使えるはずです。筆者はDanaも使用しています。
今回利用するPerlは、最新のPerl 5.8ではなく、Windows用のjperlを使います。jperlはスクリプトをShift JISで書けますし、Shift JISのテキストをデフォルトで標準入出力できます。そのため入力と出力が共にShift JISの場合はスクリプトがシンプルになり、効率が良いので有力な選択肢です。言うまでもなく、Windowsの文字コード環境はShift JISであり、通常のテキストはShift JISで保存されるために相性が良いのです。
Perl 5.8は、スクリプトを変換するencodingを用いて、Shift JISでスクリプトを書けるようになっています。しかし、Perlは本来UTF-8入出力を想定して設計されているので、Perlの内部表現を変換する過程でパフォーマンスが低下します。Perl 5.8が適しているのは、RSS/AtomのようなUTF-8のXMLを出力する場合や、XHTMLなどでUTF-8でサイトを構築する場合などです。
TeraPadでは、encodingを使用したスクリプトは標準入出力の受け渡しが動作しない問題があります。また、encodingを使用しなくても、UTF-8の出力が文字化けしてしまう不具合があります。TeraPadの標準入出力の受け渡しはShift JISが前提となっているようです。
どうしてもPerl 5.8を使いたい場合やUTF-8のテキストをエディタ上に出力する場合には、Danaを使うとよいでしょう。Danaには、現在のTeraPadのような制限はありません。UTF-8でWeb日記を統一する場合には、「ddl2html.pl」をUTF-8に変換して保存して、入力(エディタの文字コード)をUTF-8にすれば問題なく使えます。
対象読者
Perl、CGI、テキストエディタ、HTML、HTTPサーバー(特にApache)、Webブラウザ、文字コード、コマンドプロンプトや環境変数などのWindowsのシステムについての基礎的な知識を持ち、かつ、インターネットからソフトウェアをダウンロードして、インストールできるレベルの方。
必要な環境
jperlと、jperlのインストールに必要なActivePerl(APi522e.exe)、Windows用エディタTeraPadとDana、WebブラウザのFirefoxのダウンロードページは以下の通りです。
- jperl(鈴木紀夫氏のJperl)
- ActivePerl(APi522e.exe)
- TeraPad
- DANA
- Firefox
jperlのインストール
作者の鈴木紀夫氏のサイトで紹介されているインストール方法に従ってください。
TeraPadエディタでの編集にスクリプトを使う方法
TeraPadエディタの編集画面でテキストを範囲指定し、選択部分をPerlスクリプトで加工処理をした後、処理結果を範囲指定部分と置換する方法を説明します。TeraPad上で、編集内容が処理結果に置換される過程は次のようになります。
この処理を可能にするために、以下のものを入手してください。
インストールはReadme.txtに従って行い、続いてツールを設定します。
ツール設定はTeraPadのツールバーから、[ツール]-[ツールの設定]-[追加]-[ツールの編集]で行います。実際の画面を示しますので、参考にしてください。
次項の説明を読んだ後、DDL記述サンプルと本稿で作成する「ddl2html.pl」を使って編集・変換してみてください。すると以下の画面のようになるはずです。実行する際には、HTML編集画面上でDDLで記述された範囲を指定して、マウスを右クリックし、[ツール]-[ddl2html]を選択してクリックします。
Web日記の作成と配信
それでは、実際にサンプルコードを見ながら、Web日記の作成と配信の仕組みについて解説しましょう。
日記記述言語 DDL
最初に、筆者が作成した簡易言語「DDL」について説明します。DDLは「Diary Description Language」の頭文字を取ったもので、もともとは筆者がWeb日記を書く際にHTMLのタグを簡単に埋め込むために作成したものでした。筆者のWeb日記のHTMLの一部とそれに対応するDDL記述を比べてみましょう。
<DT>8/3/2006 (Thu.)<DD> <div class="emph"><A HREF="renewal_index.html#perl">[Perl]</A> <A NAME="perl_1154609700">Perl 6 が完成?</A></div> <p><a href="http://opentechpress.jp/opensource/06/08/02/0223222.shtml"> Open Tech Press | OSCON開催4日日:禅とトマトの話題</a>ネタ。</p> <p>Damian Conway氏とLarry Wall氏によるPerl 6 updateの講演が行われた。 満席、鮨詰め、立ち見は当然、部屋から人が溢れ出るほどの関心が集まった らしい。Perl 6が完成したら何が起こるのか誰もが注目していることは間違 いない。Perl 4のパフォーマンスに驚いたことのある人なら、特に期待して いることだろう。</p> <ul> <li><a href="http://business.newsforge.com/article.pl? sid=06/07/28/189249&from=rss"> NewsForge | OSCON day four: Zen and tomatoes</a> <li><a href="http://conferences.oreillynet.com/os2006/"> O'Reilly Open Source Convention - July, 24-28, 2006 - Portland, OR</a> </ul><br>
da: c: perl t: Perl 6 が完成? p: [u: http://opentechpress.jp/opensource/06/08/02/0223222.shtml; t: Open Tech Press | OSCON開催4日日:禅とトマトの話題]ネタ。 p: Damian Conway氏とLarry Wall氏によるPerl 6 updateの講演が行われた。 満席、鮨詰め、立ち見は当然、部屋から人が溢れ出るほどの関心が集まった らしい。Perl 6が完成したら何が起こるのか誰もが注目していることは間違 いない。Perl 4のパフォーマンスに驚いたことのある人なら、特に期待して いることだろう。 ul: [u: http://business.newsforge.com/article.pl?sid=06/07/28/189249& from=rss;t: NewsForge | OSCON day four: Zen and tomatoes] [u: http://conferences.oreillynet.com/os2006/; t: O'Reilly Open Source Convention - July, 24-28, 2006 - Portland, OR] /ul:
このDDL記述サンプルで使っているものも含めて、DDLコマンドとその使い方には5種類あります。
- 行頭に置く「コマンド名:《改行》」形式のコマンド文字列。
- 行頭に置く「コマンド名:《改行》」形式のコマンド文字列によって、行単位でデータ行範囲を指定をする。
- 行頭に置く「コマンド名:」形式のコマンド文字列。この後に空白文字(半角空白、タブ)を入れ、行末の改行までにデータを置く。
- 行頭に置く「‐コマンド名 《改行》」形式のコマンド文字列。microformatsの入力用テンプレートを出力する。
- データの中に埋め込むコマンド。ハイパーリンクや画像ファイルを示す
a
タグやimg
タグを生成するコマンドがある。
例) da:《改行》
例) p: これは段落のサンプルです。《改行》
例) [u: http://host/path;t: タイトル]
DDLコマンド解説
では、DDLコマンドについて詳しく見ていきましょう。表1に、コマンド文字列をPerlの正規表現によるパターンマッチで示し、その意味とスクリプトによる変換動作をまとめました。変換動作の詳細は、次項で示す「ddl2html.pl」の該当部分を参照してください。
DDL記述の正規表現 | 意味 | スクリプトによる変換動作 |
/^ddl:$/i | Web日記のHTML開始部分 | DDLHEADER で指定されるヒアドキュメント部分を参照。 |
/^\/ddl:$i | Web日記のHTML終了部分 | DDLFOOTER で指定されるヒアドキュメント部分を参照。 |
/^da:$/i | 日付 | 行頭がda:[改行] のみになっている場合は、<DT>8/3/2006 (Thu.)<DD>[改行] のように日付をDT タグとDD タグで囲んで出力します。日記を生成した時の日付が入ります。 |
/^up*da*t*e*d*:$/i | 更新日付日時 | div タグに、class 属性がupdated で更新日付日時を出力します。形式は例えば「更新: 2006-08-17T23:18:52+09:00」のようになります。 |
/^c:\s+(.+)$/i | カテゴリー | カテゴリーとタイトルはセットで動作します。順序はどちらでもよいですが、並べて記述する必要があります。 |
/^t:\s+(.+)$/i | タイトル | 同上。 |
/^p:\s+(.+)$/i | 段落 | 行末までのデータをp タグの開始タグと終了タグで括ります。 |
/^pre:$/i ~ /^\/pre:$/i | pre タグの範囲指定 | 範囲内の行では、&、<、>、" が文字実体参照に変換されます。 |
/^ul:$/i ~ /^\/ul:$/i | ul タグ(リスト)の範囲指定 | 範囲内の行にあるハイパーリンクなどが変換されます。 |
/^ol:$/i ~ /^\/ol:$/i | ol タグ(番号つきリスト)の範囲指定 | 同上。 |
/^uls:$/i ~ /^\/uls:$/i | 階層型リストの範囲指定 | 同上。 |
/^dl:$/i ~ /^\/dl:$/i | dl タグ(定義リスト)の範囲指定 | 同上。 |
/^ta:$/i ~ /^\/ta:$/i | table タグ(表)の範囲指定 | 同上。表のデータはまず第1行にキャプション(表のタイトル)を記述し、次の行に項目名をタブで区切って記述します。以下の行には項目に対応した表データをタブで区切って記述します。 |
/^bq:$/i ~ /^\/bq:$/i | blockqoute の範囲指定 | 同上。 |
/^(li|em)book:$/i ~ /^\/(li|em)book:$/i | microformatsのbook(書籍情報)の範囲指定 | テンプレートの内容に従って、div タグやspan タグに変換されます。 |
/^vp:$/i ~ /^\/vp:$/i | microformatsのviewpoint(地点情報)の範囲指定 | 同上。 |
\[U:\s+([^;]+);T:\s+([^\]]+)\] | ハイパーリンクの出力 | URL(U)とタイトル(T)からハイパーリンクを出力します。変換内容は「ddl2html.pl」のlinking サブルーチンを参照。 |
\[N:\s+([^;]+);T:\s+([^\]]+)\] | アンカーの出力 | アンカー名(N)とアンカーテキスト(T)からアンカーを出力します。変換内容は「ddl2html.pl」のlinking サブルーチンを参照。 |
\[U:\s+([^;\]]+)\] | ハイパーリンクの出力 | URLのみから、URL(U)をタイトルとしてハイパーリンクを出力します。変換内容は「ddl2html.pl」のlinking サブルーチンを参照。 |
\[I:\s+([^;\]]+)\] | img タグ出力 | src 属性要素、すなわち画像ファイルのパス(I)からimg タグを出力します。 |
^\[I:\s+([^;]+);T:\s+([^\]]+)\]$ | img タグの標準的出力(1) | 行頭にある場合のみの出力形式。画像ファイルのパス(I)とタイトル(T)から、img タグを出力します。 |
^\[I:\s+([^;]+);U:\s+([^;]+); T:\s+([^\]]+)\]$ | img タグの標準的出力(2) | 同上。画像ファイルのパス(I)とURL(U)とタイトル(T)を指定すると、タイトルにハイパーリンクを出力します。 |
^\[U:\s+([^;]+);I:\s+([^;]+); T:\s+([^\]]+)\]$ | img タグの標準的出力(3) | 同上。URL(U)と画像ファイルのパス(I)とタイトル(T)を指定すると画像ファイルにハイパーリンクを出力します。 |
^\[U:\s+([^;]+);I:\s+([^;]+); U:\s+([^;]+);T:\s+([^\]]+)\]$ | img タグの標準的出力(4) | 同上。画像とタイトルの両方にハイパーリンクを指定します。 |
\[rb: ([^;]+);([^]]+)\] | ルビ出力 | [rb: 対象文字列;ルビ文字列] からルビのタグを出力します。 |
/^-libook$/i | microformatsのbook(書籍情報)のリスト入力用テンプレート出力 | 指定のテンプレートが出力されます。 |
/^-embook$/i | microformatsのbook(書籍情報)の埋め込み入力用テンプレート出力 | 同上。 |
/^-vp$/i | microformatsのviewpoint(地点情報)の埋め込み入力用テンプレート出力 | 同上。 |