わたしたち人類がゆるやかな衰退を迎えて,はや数世紀. すでに地球は”ぷろぐらまー”のものだったりします. 平均身長170センチで7頭身,高い知能を持ち,こーでぃんぐが大好きなぷろぐらまーさんたち. わたしは,そんなぷろぐらまーさんと人との間を取り持つ重要な職,国際公務員の” えすいー ”となり,故郷のニブンキの里に帰ってきました. 祖父の年齢でも現役でできる仕事なのだから,さぞや楽なのだろうとこの職を選んだのですが….
ある日,ぷろぐらまーさんたちが渡してくれたのは,2枚の設計書のようなもの. そのぷろぐらまーさん曰く,テキストとスクリプトを利用して,様々な情報を容易に交換できるのだと言います.
1枚目の設計書は,文章構造を表すファイルの説明でした. このファイルのファイル名が.dmlで終わり,DMLファイルと呼ばれます.
DMLファイルの中は,タグと呼ばれる文字列で挟むことで文章の構造を表しています. タグは,開始タグと終了タグが存在し,
<開始タグ名>内容</終了タグ名>
の要素で表されます. このとき,開始タグ名と終了タグ名は同じ文字列で表されます.
タグは入れ子構造にすることができ,<tagA><tagB></tagB></tagA>のようにしても構いません. また,<tagA><tagB></tagA></tagB>のような構造は許されません.
DMLファイル内のタグ名はいくつか特殊なものを除いて任意の文字列です. 特殊なタグは以下の5つです.
タグ名は,アルファベットの大文字,小文字のみで表されます. タグ名にスペースが現れることはありません. DMLファイル中に現れる文字列は,アルファベットの大文字,小文字,スペース,'<','>','/'となります. また,同名のタグが存在することもありえます.
scriptタグ以外で囲まれたタグ以外の文字列は,画面の左上(0, 0)から左詰めで出力され, 画面端かbrタグが出現するまで改行されません.
2枚目の設計書は,DMLファイル中のボタンを押した時の動作を表すDSファイルの説明でした. DSファイルは,サブルーチンが並べられています.
サブルーチン名 { 式; 式; ...; }
セミコロンは式の終わりを表します.
例えば,DMLファイル中に,<title>?</title>で囲まれた文章があるとします. そのとき可能な式は以下の4つの代入式です.
title.visible = true; title.visible = false; title.visible != true; title.visible != false;
visibleへの真偽値の代入は,そのタグの内容を表示するかしないかを変更します.表示され無くなった場合には,それ以降の文章は左に詰められます. 最初やlinkタグのクリックによって現在表示しているDMLファイルが書き変わった時,初期値は全てtrueになっています.
'!='は否定の代入を表します. 上の例では,1行目と4行目,2行目と3行目はそれぞれ等価です.
また式は,以下のように複数の値を同時に変更することもできます.
titleA.visible = titleB.visible = true;
この時,右から順に処理が行われます. すなわち,
titleB.visible = true; titleA.visible = titleB.visible;
の2行と等価です. ただし,この表し方は便宜上であって,スクリプト内で文の最も右において,タグによる指定が行われることはありません. また,
titleA.visible != titleB.visible = true;
は
titleB.visible = true; titleA.visible != titleB.visible;
と等価です.
タグの指定方法は,'.'で絞り込むことによって行われます. 例えば,
dml.body.title
は,dmlタグに囲まれた,bodyタグに囲まれた,titleタグを指します. ただし,scriptタグとbrタグが絞り込みにつかわれたり,指定されることはありません.
このとき,絞り込まれる要素が直接囲まれているとは限らないことに注意して下さい. 例えば, <a><b><c></c></b></a> とあるとき,a.b.cでもa.cでもcを指すことができます.
また,同名のタグが存在する場合には,指定されたタグが1つとは限りません. 指定したタグが存在しない場合には,表示に影響は与えられませんが,複数の値を同時に変更する際に現れた場合には,存在している場合と同様に評価されます.
BNFは以下のようになります.
<script_file> :: = <subroutine> | <script_file> <subroutine> <subroutine> ::= <identifier> '{' <expressions> '}' <expressions> ::= <expression> ';' | <expressions> <expression> ';' <expression> ::= <visible_var> '=' <visible_exp_right> | <visible_var> '!=' <visible_exp_right> | <visible_var> '=' <expression> | <visible_var> '!=' <expression> <visible_exp_right> ::= 'true' | 'false' <visible_var> ::= <selector> '.visible' <selector> ::= <identifier> | <selector> '.' <identifier> <identifier> ::= <alphabet> | <identifier> <alphabet> <alphabet> ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'
頭が痛くなりそうですね.ならないですか?そうですか.
ユーザは,最初のDMLファイルが表示された後,画面上の座標(x, y)をクリックします. すると,その場所のlinkやbuttonに応じて,画面が変化します. それ以外の場所をクリックしたらですか?なにも起こりませんよ.流石に.
さて,どんなものができるのでしょう? 大好物のえなじーどりんくでも渡しつつ,見守ることにします.
入力は,次の形式で与えられる.
N filename1 file1 filename2 file2 ... filenameN fileN M w1 h1 s1 startfile1 x11 y11 ... x1s1 y1s1 ... wM hM sM startfileM xM1 y11 ... xMsM yMsM ...
N(1 <= N <= 20)は,ファイルの数を表し,その後,ファイル名とファイルの内容が交互に与えられる. filenameは,任意のアルファベット16文字に'.dml'または'.ds'が加えられた形で表される. '.dml'で終わる場合はDMLファイルであり,'.ds'で終わる場合はDSファイルである. ファイルの文字列は一行で与えられ,500文字以下である.
M(1 <= M <= 50)は訪れたユーザの数を表す. ユーザ1人につき,画面の幅w,高さh(1 <= w * h <= 500),操作数s(0 <= s <= 50),開始DMLファイル名と,s行のクリックした座標x, y(0 <= x < w, 0 <= y < h)が与えられる.
DSファイルに空白は含まれない. また,与えられるDMLファイル中のタグは必ず閉じられている. 入力の全体を通して,スクリプト内に同名のサブルーチン名が現れることはない.
ユーザ1人につき,最終的な画面を幅w, 高さhで出力して下さい. 画面の右下を超えた分については出力しません. ある行において,出力する文字が無くなった場合には,その行がw文字になるまで'.'を出力して下さい.
1 index.dml <dml><title>Markup language has Declined</title><br>Programmers world</dml> 1 15 3 0 index
Markup language has Declined.. Programmers wor
2 hello.dml <dml><link>cut</link></dml> cut.dml <dml>hello very short</dml> 1 10 2 1 hello 1 0
hello very short....
2 index.dml <dml><script>s</script>slip<fade>akkariin</fade><br><button>on</button> <button>off</button></dml> s.ds on{fade.visible=true;}off{fade.visible!=true;} 2 15 3 0 index 15 3 3 index 3 1 1 1 3 1
slipakkariin... on off......... ............... slip........... on off......... ...............