テーブル出力の略記法
ここでは、AmXMLのテーブル関係の機能を説明しますが、その前に、ハッシュと配列以外のオブジェクトの扱いについて説明します。
ハッシュ以外のデータの扱い
以下のテーブル出力のサンプルでは、以下のデータを使用します。
context "table" do WebSite = Struct.new(:name, :url) class Lang include Amrita2::DictionaryData attr_reader :name, :author, :website def initialize(n, a, w) @name, @author, @website = n, a, w end end setup do @data = { :lang_list =>[ Lang.new("Ruby", "matz", WebSite.new('Ruby Home Page', 'http://www.ruby-lang.org/')), Lang.new("Perl", "Larry Wall", WebSite.new('The Source for Perl', 'http://perl.com/')), Lang.new("Python","Guido van Rossum", WebSite.new('Python Programing Language', 'http://www.python.org/')) ] } end
Amrita2では、Structもハッシュと同様にモデルデータとして使用できます。
また、目印としてAmrita2::DictionaryDataというモジュールを include することで、他の任意のオブジェクトをハッシュの代わりに使用することができます。
この場合は、データの取り出しは、対応する名前のメソッド呼び出しになります。
AmXMLのセルライン
AmXMLでは、<<...>> <<<...>>>に加えて、|で区切られた行から、td要素を生成する記述方式があります。
行の先頭が、「|」である行を「セルライン」と呼び、AmXMLプリプロセッサは、この行に対して特殊な処理を行ないます。
specify "simple" do t = Amrita2::Template.new <<-END <<table border='1'< <<tr:lang_list < ||| <<:name>> | <<:author>>| >>> >>> END t.render_with(@data).should_be_samexml_as <<-END <table border = "1"> <tr><td>Ruby</td><td>matz</td></tr> <tr><td>Perl</td><td>Larry Wall</td></tr> <tr><td>Python</td><td>Guido van Rossum</td></tr> </table> END end
一番単純な例では、上記のように、td要素を出力します。
th要素を出力したり、属性を設定することもできます。
specify "with title and attributes" do t = Amrita2::Template.new <<-END <<table border='1'< <<tr< #------------------------------------------- | || name || author ||cite || |class|| h_name || h_author ||h_cite || #------------------------------------------- >>> <<tr:lang_list |ToHash[:name=>:name, :author=>:author, :site=>:website] |Each[:class=>["odd", "even"]] |Attr[:class] < #------------------------------------------------------------------------------ | || <<:name>> | <<:author>>|<<a:site\\|Attr[:href=>:url, :body=>:name]>>| |class|| name | author |site | #------------------------------------------------------------------------------ >>> >>> END #t.set_trace(STDOUT) t.render_with(@data).should_be_samexml_as <<-END <table border='1'> <tr> <th class='h_name'>name</th> <th class='h_author'>author</th> <th class='h_cite'>cite</th> </tr> <tr class='odd'> <td class='name'>Ruby</td> <td class='author'>matz</td> <td class='site'> <a href='http://www.ruby-lang.org/'>Ruby Home Page</a> </td> </tr> <tr class='even'> <td class='name'>Perl</td> <td class='author'>Larry Wall</td> <td class='site'> <a href='http://perl.com/'>The Source for Perl</a> </td> </tr> <tr class='odd'> <td class='name'>Python</td> <td class='author'>Guido van Rossum</td> <td class='site'> <a href='http://www.python.org/'>Python Programing Language</a> </td> </tr> </table> END end
「|属性名||」という行があると、その行の値を属性として設定します。また、セルの右側が、「||」であるセルは、th要素として出力されます。
#------------------------------------------- | || name || author ||cite || |class|| h_name || h_author ||h_cite || #-------------------------------------------
という記述が、次のように展開されます。(#..はコメント行)
<th class='h_name'>name</th> <th class='h_author'>author</th> <th class='h_cite'>cite</th>
<<tr:lang_list |ToHash[:name=>:name, :author=>:author, :site=>:website] |Each[:class=>["odd", "even"]] |Attr[:class] <
Each[:class=>["odd", "even"]] によって、コンテキストデータの:class要素に"odd"と"even"がかわりばんこに設定され、それがAttrによって展開されます。
この機能により、clospanやrowspanを使う場合等も、区切りの位置を工夫することで、出力結果に近い形式でテンプレートを記述することができます。
specify 'rowspan colspan' do # from http://www.y-adagio.com/public/standards/tr_html4/struct/tables.html =begin A test table with merged cells /-----------------------------------------\ | | Average | Red | | |-------------------| eyes | | | height | weight | | |-----------------------------------------| | Males | 1.9 | 0.003 | 40% | |-----------------------------------------| | Females | 1.7 | 0.002 | 43% | \-----------------------------------------/ =end expected = <<-END <table border="1" summary="This table gives some statistics about fruit flies: average height and weight, and percentage with red eyes (for both males and females)."> <caption><em>A test table with merged cells</em></caption> <tr> <th rowspan="2" /> <th colspan="2">Average</th> <th rowspan="2">Red<br/>eyes</th> </tr> <tr> <th>height</th> <th>weight</th> </tr> <tr> <th>Males</th> <td>1.9</td> <td>0.003</td> <td>40%</td> </tr> <tr> <th>Females</th> <td>1.7</td> <td>0.002</td> <td>43%</td> </tr> </table> END t = Amrita2::Template.new <<-END <<table border='1':|Attr[:summary]< <<caption< <<em:caption>> >>> <<tr< #------------------------------------------------------ | rowspan || 2 || || 2 || | colspan || || 2 || || | || ||Average ||Red<br />eyes|| >>> <<tr< | || || || | ||height ||weight|| | || || || #------------------------------------------------------ >>> <<tr:data< | ||<<:sex>>||<<:height>> | | || || |<<:weight\\|Format['%1.3f']>>| | || || | |<<:percent\\|Format['%d%%']>>| >>> >>> END data = { :summary=>"This table gives some statistics about fruit flies: average height and weight, and percentage with red eyes (for both males and females).", :caption=>'A test table with merged cells', :data => [ { :sex=>'Males' , :height=>1.9, :weight=>0.003, :percent=>40 }, { :sex=>'Females' , :height=>1.7, :weight=>0.002, :percent=>43 } ] } t.render_with(data).should_be_samexml_as(expected)
┌────┬───────┬──┐ │ │ Average │Red │ │ ├───┬───┤eyes│ │ │height│weight│ │ ├────┼───┼───┼──┤ │ Males │1.9 │0.003 │40% │ ├────┼───┼───┼──┤ │Females │1.7 │0.002 │43% │ └────┴───┴───┴──┘