Kwartz-Ruby Users' Guide
4 Other Topics
4-1 Restrictions around presentation logic
There are several restrictions in presentation logic file.
- Position in which comment '
/* ... */' is available is limited. In the following example, 'value:' property will be error because string from 'expr;' to the end of comment is regared as argument of 'value:' property./* this comment is ok */ #foo { /* this comment is ok */ value: expr; /* this comment is NG! */ logic: { /* this comment will be Ruby syntax error! */ for item in list # ruby comment is OK in 'logic:' property _stag _cont _etag end } }
- '_stag', '_cont', '_etag', '_elem', '_element()', and '_content()' must be placed
one in per line, because Kwartz-ruby scans 'logic:' property with regular expression
pattern such as '/^\s*_(stag|cont|etag|element|content)(\(.*\))\s*$/' or so.
#foo { logic: { # OK if x > 0 _elem end # NG (parse failed) _elem if x > 0 } }
- The number of '{' and '}' must be equal in 'logic:' property.
#foo { logic: { str = "{" # this will be parse error _elem } } #bar { logic: { str = "{" # add dummy '}' in comment! _elem } }
- '@import "file.plogic"' should be at the beginning of presentation logic file.
/* OK */ @import 'file1.plogic'; #foo { } /* NG */ @import 'file2.plogic';
4-2 Restrictions around presentation data
Kwartz parses presentation data file by regular expression pattern matching. It means that Kwartz doesn't use HTML parser nor XML parser for parsing presentation data. This approach enables Kwartz to handle any type of text file, and also brings the following restrictions to Kwartz.
- Cannot omit end tag if id attribute is specified.
<!-- Kwartz cannot parse the following because </li> is omitted. --> <ul> <li id="foo">foo </ul>
An Element which doesn't have any content is to be written as an empty tag such as<foo id="..."/>.
- However,
<input>,<br>,<meta>,<img>, and<hr>are allowed to omit end tag. And these doesn't have to be written as an empty tag.<!-- </input/> is omitted but Kwartz can parse correctly. --> <input type="text" name="user" id="user">
Configuration option PROPERTY_NOEND lists these tag names in file 'kwartz/config.rb'. Upper-case and lower-case are distinguished.
- Attribute values should be surrounded with '
"'.<!-- Kwartz fails parsing because attribute value is not surrounded with '"'. --> <h1 id='id:title' class=title>title</h1>
4-3 Makefile and Rakefile
The followings are examples of Makefile, Rakefile, Rantfile, and Rookbook.
.SUFFIXES: .rhtml .html .plogic ALL = file1.rhtml file2.rhtml file3.rhtml LAYOUT = layout.html default: $(ALL) %.rhtml: %.html %.plogic kwartz -l eruby -p $*.plogic $*.html > $@ file3.rhtml: file3.html file3.plogic $(LAYOUT) kwartz -p file3.plogic -L $(LAYOUT) file3.html > file3.rhtml
all = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'
task :default => all
rule '.rhtml' => ['.html', '.plogic'] do |t|
pdata, plogic = t.sources
sh "kwartz -l eruby -p #{plogic} #{pdata} > #{t.name}"
end
file 'file3.rhtml' => ["file3.html", "file3.plogic", layout] do |t|
pdata, plogic, layout = t.prerequisites
sh "kwartz -p #{plogic} -L #{layout} #{pdata} > #{t.name}"
end
all = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'
task :default => all
gen Rule, ".rhtml" => [".html", ".plogic"] do |t|
pdata, plogic = t.prerequisites
sys "kwartz -p #{plogic} #{pdata} > #{t.name}"
end
file "file3.rhtml" => ["file3.html", "file3.plogic", layout] do |t|
pdata, plogic, layout = t.prerequisites
sys "kwartz -p #{plogic} -L #{layout} #{pdata} > #{t.name}"
end
properties:
- layout : layout.html
parameters:
- all : [ file1.rhtml, file2.rhtml, file3.rhtml ]
- rook_product: $(all)
recipes:
- product: *.rhtml
ingreds: [ $(1).html, $(1).plogic ]
method*: |
$pdata = $ingreds[0]; $plogic = $ingreds[1];
k_sys("kwartz -p $plogic} $pdata > $product");
- product: file3.rhtml
ingres: [ file3.html, file3.plogic, $(layout) ]
method*: |
$pdata = $ingreds[0]; $plogic = $ingreds[1]
k_sys("kwartz -p $plogic -L $(layout) $pdata > $product"
properties:
- layout : layout.html
parameters:
- all : [ file1.rhtml, file2.rhtml, file3.rhtml ]
- rook_product: $(all)
recipes:
- product: *.rhtml
ingreds: [ $(1).html, $(1).plogic ]
method*: |
pdata, plogic = @ingreds
sys "kwartz -p #{plogic} #{pdata} > #{@product}"
- product: file3.rhtml
ingres: [ file3.html, file3.plogic, $(layout) ]
method*: |
pdata, plogic, layout = @ingreds
sys "kwartz -p #{plogic} -L $(layout) #{pdata} > #{@product}"
4-4 Use Kwartz as Library
If you want to use Kwartz library in your Ruby script, use Kwartz::Main class.
require 'kwartz'
require 'kwartz/main'
argv = %w[-p hello.plogic -L layout.html hello.html]
main = Kwartz::Main.new(argv)
output = main.execute()
File.open('hello.rhtml', 'w') { |f| f.write(output) }
4-5 Use Kwartz with Non-Supported Language
Using Erubis, it is able to use Kwartz with Java, JavaScript, Scheme, and so on. Erubis is an implementation of eRuby which supports not only Ruby but also other languages.
The followings are examples of using JavaScript with Kwartz and Erubis.
<table>
<tr class="odd" id="mark:list">
<td>@{item}@</td>
</tr>
<tr class="even" id="dummy:d1">
<td>foo</td>
</tr>
</table>
#list {
attrs: 'class' klass;
logic: {
for (var i=0, len=list.length; i < len; i++) {
klass = i % 1 == 0 ? 'even' : 'odd';
item = list[i];
_elem;
}
}
}
$ kwartz -l erubis -p js-example.plogic js-example.html > js-example.jshtml
<table>
<% for (var i=0, len=list.length; i < len; i++) { %>
<% klass = i % 1 == 0 ? 'even' : 'odd'; %>
<% item = list[i]; %>
<tr class="<%= klass %>">
<td><%== item %></td>
</tr>
<% } %>
</table>
In Erubis, <%= ... %> means embedded expression and <%== ... %> means embedded expression with escaping.
In this example, @{item}@ is compiled into <%== item %> because it needs escaping and attr: 'class' klass is compiled into <%= klass %> without escaping.
The following is an example to compile into JavaScript code with Erubis.
$ erubis -l javascript -x js-example.jshtml
var _buf = []; _buf.push("<table>\n");
for (var i=0, len=list.length; i < len; i++) {
klass = i % 1 == 0 ? 'even' : 'odd';
item = list[i];
_buf.push(" <tr class=\""); _buf.push(klass); _buf.push("\">\n\
<td>"); _buf.push(escape(item)); _buf.push("</td>\n\
</tr>\n");
}
_buf.push("</table>\n");
document.write(_buf.join(""));