Archive for November, 2005

Replacing by tagname

Sunday, November 13th, 2005

I managed to crunch some stuff out this morning. Stitch now has the ability to identify and replace content by tag name. so, and html file:

<html>
<body>
<p class=”user”>John Doe</p>
</body>
</html>

and a stitch rule file:

p{
  content:$userName;
}

Running the template like so:

Template t = new Template(html, rules);
Map data = new HashMap();
data.put(”userName”, “Snoopy”);
String out = t.render(data);

“out” would be:

<html>
<body>
<p class=”user”>Snoopy</p>
</body>
</html>

It can traverse mult-level hash maps in the model as well as bean properties (so…basically like jsp expression language references). Not terribly useful yet…need class selectors to really become more useful. For now though, there are some refactorings to be done.

Progress on Stitch Parser

Sunday, November 6th, 2005

Took most of the weekend, but I now have a parser that will recognize the following:


pain{
display:none;
}
agony{
border-color:red;
margin:$user.name;
padding:$user;
}
.dog{
border-color:red;
margin:$user.name;
padding:$user;
}
#cat{
padding:$user;
}
#mouse .blah{
padding:$user;
}
#mouse p{
padding:$user;
}
#mouse p.short{
content:$user.name;
}
#rat p .blah span:if($owner.address){
content:$user;
}
hope:if($user.boss){
display:remove;
}

You can probably see some of my frustration coming out in some of the names. I’m better now…really. I have one “lexical nondeterminism” right now…which should be fairly easy to overcome…but not tonight.

Firefox Password Manager

Sunday, November 6th, 2005

Am I the only one that can’t stand the way the Password Manager doesn’t let you tab to the other buttons? Pisses me off…

StringTemplate

Friday, November 4th, 2005

I may not have emphasized enough in the previous post how much I really like what Terrence Parr is doing with antlr and StringTemplate. This article (especially the linked article on Enforcing Strict Model View Separation in Template Engines) really made me realize some bad things about the template engine I was starting to write (specifically around the conditionals). So, now the conditionals look something like this:

#user_name .boss:not($user.boss){
display:remove;
}
#user_name .boss{
content:$boss_salutation;
}
#favorite_song:if($user.favoriteSong){
content: $user.favoriteSong;
}
#favorite_song:not($user.favoriteSong){
content: $unknown_song;
}
/* shorthand for the above 2 selectors…if first arg is empty, second is used as default */
#favorite_song{
content: $user.favoriteSong, $unknown_song;
}

And the StringTemplate actually has me wondering whether I should write a new one at all. I think Stitch (note to self…probably should get a name…ctrlTemplate?) still adds some value over what StringTemplate does, by fully separating the markup from the rules about how the data is to be inserted into the document…and then the rules file being in a format that is VERY similar to css, a format most web designers should be very familiar with. Then the markup can change quite drastically so long as the ‘css’ rules still match (mostly ids and class selectors), and the rule file need not change. I do think that if/when the tempates have a server-side ‘compiled’ version, its very possible it will use StringTemplate.

I was thinking that the ctrlTemplate could also potentially operate on tree structures too (not just xml/html/xhtml). Like, for example, an AST tree result from a parser of some sort. Just a thought.

Parsers…

Friday, November 4th, 2005

I’m burnt a bit. Need a break. I think I have a basic idea of how I want to proceed. Basically just a css parser (ast tree output) and the html parser with the visitor pattern. Visit each node and traverse the AST tree for all matching css rules…for each match append an annotation to the html node. Then have another pass that will actually generate the output. At least as a start.

I’ve been looking at ANTLR quite a bit and I’m pretty impressed. It looks like ANTLR 3 will use the StringTemplate ‘engine’ for generating the actual code. The idea is that you could feasibly have 1 grammar and multiple output templates to render the grammar in different languages. Exactly what I was looking at maybe having to write…thank god because it looks like they know a hell of a lot more about lexers/parsers/compilers than I do…and I like where they are taking it (MVC separation). So I may evenually have 1 css grammar that would generate a parser for java, jsp, perl, javascript, php, ruby, python…etc. Awesome.

I also found it interesting how closely css syntax resembles the syntax used in the grammars and the string template files…

CSS Parsers

Thursday, November 3rd, 2005

So I was beginning to think I was going to actually have to write my own css parser…then I found 3 different .jj grammar files (for javacc) that I should be able to bend to my will. One of them is actually used for the w3c’s css validator. I also found a promising html parser too (also javacc generated). It implements a nice visitor pattern as well as supporting annotations on the nodes…so I can write a visitor that will visit each node and leave annotations indicating what css rules matched…then visit it again with a visitor that will actually generate the merged file. Better than what I’d originally thought I’d do…with the added benefit of not requiring strict xml conformance in the markup file.

Conditionals again…

Thursday, November 3rd, 2005

Looks like I’ve got my answer as to how to do conditionals. I got this from the css3 draft:


body > h2:not(:first-of-type):not(:last-of-type)

So, conditionals will probably look like:

#favorite_song:ctrl.empty($user.name){
content:lang.i18n(”unknown_song”);
}
#favorite_song:ctrl.equals($user.name, “Joe”){
content: “Some Song”;
}
#favorite_song:ctrl.equals($user.name, “Alice”){
content:”The Muppet Song”;
}
#favorite_song:ctrl.equals($user.name, “Corbin”){
content:”Blue’s Clues”;
}

First Test Case for Stitch

Wednesday, November 2nd, 2005

public static final String simpleCds = “p{ctrl-content:$test;}”;
public static final String simpleHtml = “<html><p>Mock</p></html>”;
public static final String simpleResult = “<html><p>Hello World!</p></html>”;
public void testReplaceByTagName(){
View view = new View(new StringReader(simpleCds), new StringReader(simpleHtml));
Map data = new HashMap();
data.put(”test”, “Hello World!”);
StringWriter out = new StringWriter();
view.render(data, out);
out.flush();
String val = out.getBuffer().toString();
assertEquals(”View got invalid output.”, simpleResult, val);
}
Green baby green…you can imagine how ugly the actual impl is (hint: not parsing anything). I dug around the net a bit and stumbled onto a w3c page on SAC (Simple API for CSS). They modeled it after SAX…seems like a good place to start.

Conditionals in CDS (or stitch)

Wednesday, November 2nd, 2005

Trying to decide on a way of doing conditionals in the cds stuff…my options so far are:

#favorite_song{
ctrl-content:ctrl.equals($user.name, “Joe”) “Some Song”;
ctrl-content:ctrl.equals($user.name, “Alice”) “The Muppet Song”;
ctrl-content:ctrl.equals($user.name, “Corbin”) “Blue’s Clues”;
ctrl-content:lang.i18n(”unknown_song”);
}

/* OR */

#favorite_song{
ctrl-content-0:ctrl.equals($user.name, “Joe”) “Some Song”;
ctrl-content-1:ctrl.equals($user.name, “Alice”) “The Muppet Song”;
ctrl-content-2:ctrl.equals($user.name, “Corbin”) “Blue’s Clues”;
ctrl-content-3:lang.i18n(”unknown_song”);
}

/* OR */

#favorite_song:ctrl.empty($user.name){
lang-textContentKey:”unknown_song”;
}

#favorite_song:ctrl.equals($user.name, “Joe”){
ctrl-content: “Some Song”;
}

#favorite_song:ctrl.equals($user.name, “Alice”){
ctrl-content:”The Muppet Song”;
}

#favorite_song:ctrl.equals($user.name, “Corbin”){
ctrl-content:”Blue’s Clues”;
}

Ideas…CDS

Tuesday, November 1st, 2005

%def-tags%{
ctrl:com.ctrlweb.cds.DefaultProcessor;
lang:com.ctrlweb.cds.LangProcessor;
}
%def-inputs%{
title:string;
records:collection required;
time:date required “MM/dd/yyyy HH:mm:ss”
page:TemplatePage;
}

title{
ctrl-content:page.head.title;
}

#content{
ctrl-content:page.body;
}

label{
lang-text-content-key:$(document[this[@for]][@name]);
lang-text-content-default:”####”;
}

#records{
ctrl-iterate-collection:records;
ctrl-iterate-var:record;
ctrl-iterate-copynode:#records .record;
}

#records .record .album{
ctrl-content:record.album;
}
#records .record .artist{
ctrl-content:record.artist;
}
#records .record .year{
ctrl-content:record.year;
}