address Logo

Rit ver. 1.0

目次

2004/12/20

はじめに

Rit (rc in text) はテキスト中に埋め込まれた Rc コマンドを処理するプログラムです。主要な用途は CGI プログラムの作成で HTML 文書にコマンドを埋め込みホスト側でダイナミックに HTML 文書を生成するのに使えます。
同じ趣旨のプログラムとして有名なのは PHP です。Plan 9 では PHP 自体はまだ移植されていませんが、Rit は Plan 9 の Web サーバである Pegasus によくなじみます。すなわち Rit の中では Rc の全ての機能を使用できて、コマンドのアクセス空間の制限は Pegasus がかけます。
筆者は Pegasus の CGI ツールとして、テキスト中に埋め込まれたコマンドを処理するプログラムとして Dx を添えていましたが、Dx には強い制限( I/O の切り替えや パイプの処理などができない)がありました。今回の Rit は、Dx のアプローチをやめて、コマンド部分は直接 Rc に処理させる事によって、遥かに強力になり、かつプログラム自体は遥かにシンプルになっています。
Rit は http://plan9.aichi-u.ac.jp/netlib/cmd/ から手に入ります。

規則

Rit の中ではただ1つの記号 $ が特殊な意味を持っています。

$ に続く英数字
Rc のシェル変数や環境変数と置き換えられます。
$ に続く {
{ から } までが Rc スクリプトです。スクリプトは複数行に渡って書く事ができて、Rc の全ての機能を使えます。Rc スクリプトを終了する } は文字列の外、{ } ネストの外になければなりません。
NL ('\n')
NL エスケープです。

以下にもつと詳しい文法解説を兼ねた例を挙げます。

例1

Example 1       command execution
        A dollar followed by '{':
        You can write rc script in curly brace { }
        Date: ${date}
        Note that we have redundant empty line after this command;
        this comes from two subsequent '\n's:
                one from command and one from our this text line.
        Avoiding this problem we have:
        ${date} continues nest line
        ${date}$ continues same line.

この文は Rit によって次のように変換されます。

Example 1       command execution
        A dollar followed by '{':
        You can write rc script in curly brace { }
        Date: Mon Dec 20 20:23:03 JST 2004

        Note that we have redundant empty line after this command;
        this comes from two subsequent '\n's:
                one from command and one from our this text line.
        Avoiding this problem we have:
        Mon Dec 20 20:23:03 JST 2004
 continues nest line
        Mon Dec 20 20:23:03 JST 2004 continues same line.

例2

Example 2       variable
        A dollar followed by alpha or numeric
        User: $user
        This is equivalent to
        User: ${echo -n $user}

この文は Rit によって次のように変換されます。

Example 2       variable
        A dollar followed by alpha or numeric
        User: arisawa
        This is equivalent to
        User: arisawa

例3

Example 3               NL escape
        A dollar at the end of line is NL escape.
        Example: This line has NL escape $
        next line.
        Many rc command produce NL at the end
        We can avoid redundant NL by putting NL escape:
        ${pwd}$
        is current working directory.
        ${pwd}$$
        this line stayes in $${pwd}$$ line.

この文は Rit によって次のように変換されます。

Example 3               NL escape
        A dollar at the end of line is NL escape.
        Example: This line has NL escape        next line.
        Many rc command produce NL at the end
        We can avoid redundant NL by putting NL escape:
        /usr/arisawa/src/pegasus-2.1/rit
        is current working directory.
        /usr/arisawa/src/pegasus-2.1/rit        this line stayes in ${pwd}$$ line.

例4

Example 4       multi-lines
        Rit has full functionality with rc.
        For example Rit allows multi-line script:
        ${book='Alice in Wonder Land'}$
        ${echo -n 'echo test of multi-line:
        line1: Carrol''s book:
        line2: '$book'
        line3: and we can use { and } in rc strings' }
        Back slash new line escape in Rc command will work:
        ${echo -n one\
        two }

この文は Rit によって次のように変換されます。

Example 4       multi-lines
        Rit has full functionality with rc.
        For example Rit allows multi-line script:
                echo test of multi-line:
        line1: Carrol's book:
        line2: Alice in Wonder Land
        line3: and we can use { and } in rc strings
        Back slash new line escape in Rc command will work:
        one two

例5

Example 5       'if' statement
        We have 'if' statement:
        ${
                if(~ $user arisawa)
                        echo ARISAWA
                if not
                        echo NOT
        }$

この文は Rit によって次のように変換されます。

Example 5       'if' statement
        We have 'if' statement:
        ARISAWA

例6

Example 6       braces in Rc
        Swicth statement.
        Note that { } is included in this example.
        ${switch($user){
                case arisawa
                        echo ARISAWA
                case *
                        echo NOT }}$

この文は Rit によって次のように変換されます。

Example 6       braces in Rc
        Swicth statement.
        Note that { } is included in this example.
        ARISAWA

例7

Example 7       comment in Rc command
        Comment in Rc command does not follow Rc syntax.
        In Rit, comment continues at most upto NL.
        If command line field is terminated by '}', comment stops there.
        The terminator '}' must be out of rc string and out of { .. } nest.
        Thus, single quote and brace { } in Rc comments might not be
        handled well. Quoted strings and nested braces are OK.
        ${# This is a comment}  # invisible
        ${# this is also a comment
        echo -n 'and this not a comment' }
        ${# {Nested {brace}}}   # invisible
        ${# 'quoted string'}    # invisible
        ${echo -n something # coment continuews; up to }
        $${# This is't a valid commant}
        In the last example, changing $$ to $ will make error
        If you do want single ', please write like:
        ${# alice's book.'} # invisible

この文は Rit によって次のように変換されます。

Example 7       comment in Rc command
        Comment in Rc command does not follow Rc syntax.
        In Rit, comment continues at most upto NL.
        If command line field is terminated by '}', comment stops there.
        The terminator '}' must be out of rc string and out of { .. } nest.
        Thus, single quote and brace { } in Rc comments might not be
        handled well. Quoted strings and nested braces are OK.
                # invisible
        and this not a comment
                # invisible
                # invisible
        something
        ${# This is't a valid commant}
        In the last example, changing $$ to $ will make error
        If you do want single ', please write like:
         # invisible

例8

Example 8
        $0 is special, this is a file name currently processed.
        Dollar followed by other charactors is not special. i.e,
        $, $#
        are shown as it is.

この文は Rit によって次のように変換されます。

Example 8
        readme is special, this is a file name currently processed.
        Dollar followed by other charactors is not special. i.e,
        $, $#
        are shown as it is.

例9

Example 9
        Sequence of dollars are processed as follows:
        If the sequence is followed by alpha or '{' or '\n'
        one dollar is simply discarded:
        $$$$home is equvalent to ${echo -n '$$$home'}
        $$$${not a rc script}
        $$$$
        is not a NL escape.
        If the sequence is followed by other charactors,
        they are shown as it is:
        $$$$ is shown as four dollars

この文は Rit によって次のように変換されます。

Example 9
        Sequence of dollars are processed as follows:
        If the sequence is followed by alpha or '{' or '\n'
        one dollar is simply discarded:
        $$$home is equvalent to $$$home
        $$${not a rc script}
        $$$
        is not a NL escape.
        If the sequence is followed by other charactors,
        they are shown as it is:
        $$$$ is shown as four dollars

文字コード

Rit は UTF-8 または EUC コードを処理できます。しかし Rc は EUC コードは処理できません。Rc の中で日本語文字を使う可能性があるのは echo だけでしょう。しかし echo の部分は全てテキスト部分に回す事ができます。つまり Rit を使えば Rc の中で echo を使うニーズはないはずです。

UNIX への移植

UNIX には既に Rc は移植されているので UNIX への移植は難しくはないはずです。 Rit を UNIX で使用した場合の問題は CGI で使うには強力すぎることにあります。( PHP は制限をかける事によってセキュリティ上問題を回避しようとしていますが、UNIX 上の Rit は制限をかけるメカニズムを持っていません。)

おわりに

Plan 9 のシェルである Rc はとても良くできていて、Rit を使わなくても HTML 文書を容易に作成できます。また UNIX 環境と違ってPlan 9 ではシェルを使って安全に CGI プログラムを書けます。すなわち HTML 形式で直接文書を作成するのであれば Rit のニーズはあまりありません。
しかしながら筆者は HTML 文書を直接書いているのではなく、もっと生産性の高い形式( tt 形式)で書いてそれを HTML 形式に自動変換しています。( tt 形式の例を見たいのであれば ここをクリックしてみてください。筆者のサーバにはその他多数の tt 形式の例を見ることができます。詳しくは http://ar.aichi-u.ac.jp/tt を見てください。) この場合には tt 形式の中に Rit によって Rc コマンドを埋め込み、それを Rit で処理可能な HTML 形式に変換できます。
tt 形式を HTML 形式に変換するプログラム( t2h )は近い将来公開するつもりでいます。