Browse Source

using erl_syntax now

git-svn-id: http://erlydtl.googlecode.com/svn/trunk@21 a5195066-8e3e-0410-a82a-05b01b1b9875
rsaccon 17 years ago
parent
commit
57d15b7cdd

+ 220 - 0
demo/out/test_csstags.css

@@ -0,0 +1,220 @@
+#foo {
+    width: 10px;
+}
+
+
+ /*================= STYLES FOR THE GRC MASTHEAD & CONTROLS ==================*/
+
+.menuminwidth0 {             /* for all browsers (non-IE) that obey min-width */
+	position:relative;
+	border:0;
+	margin:0;
+	padding:0;
+	width:100%;
+	height:55px;/* 36px masthead height + 18px button height + 1px lower border*/
+	height:600px;
+	min-width:560px;
+	z-index: 10;
+}
+
+/* suppress our whole menu when not an interactive mode (when printing, etc.) */
+@media print, projection { .menuminwidth0 { display:none; } }
+
+* html .menuminwidth1 { /* this allows IE5/6 to simulate min-width capability */
+	position:relative;  /* we can simulate a minimum width by creating a large */
+	float:left;          /* border in this first div, then placing our content */
+	height: 1px;          /* into a second nested div (see 2nd nested div next */
+	border-left:560px solid #fff;    /* CSS box-model borders are a fixed size */
+}
+
+* html .menuminwidth2 {    /* used to simulate min-width capability for IE5/6 */
+	position:relative;
+	margin-left:-560px;
+	height: 1px;
+}
+
+#yah {                                    /* the "You are here" label graphic */
+	position:absolute;
+	top:5px;
+	right:99px;
+	width:87px;
+	height:9px;
+}
+
+ /*========================= TOP OF THE MENU CASCADE =========================*/
+
+.menu {
+	position:relative;        /* establish a menu-relative positioning context */
+	float:left;                                     /* play nicely with others */
+	margin:0;
+	padding:0;
+	border:0;
+	height:18px;                                  /* the menu's overall height */
+	width:100%;         /* we always want our menu to fill the available space */
+	background:#f3f3f3;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size:12px;         /* this (and also below) sets the menu's font size */
+	border-bottom:1px solid black;        /* give us a black border underneath */
+}
+
+.menu img {
+	vertical-align: top;      /* prevent images from being pushed down by text */
+}
+
+.menu ul {
+	padding:0;
+	margin:0;
+	border:0;
+	list-style-type:none;          /* we don't want to view the list as a list */
+	line-height:1.5em;           /* globally set the menu's item spacing. note */
+}                               /* this must be 1.0 or 1.5 or 2.0 for Mozilla */
+
+.menu li {
+	float:left;    /* this creates the side-by-side array of top-level buttons */
+	position:relative;    /* create local positioning contexts for each button */
+	margin:0;
+}
+
+.menu ul li table {
+	margin:-1px 0;              /* IE5 needs -1px top and bottom table margins */
+	margin:0;               /* re-zero the table margins for everyone but IE5 */
+	border-collapse:collapse;      /* IE5 needs this for the sub-menus to work */
+	font-size:12px;        /* this sets the base font size for our entire menu */
+}
+
+.drop {
+	display:block;
+	padding:0px 0.33em;	       /* this sets the l/r margins for our menu item */
+	margin:0;
+	text-align:right;   /* this right alignment goes with the float:left below */
+	cursor:pointer;      /* IE tries to switch back to an I-beam, don't let it */
+	cursor:hand;           /* IE5 only knows about "hand", so set it both ways */
+}
+
+.drop span {        /* this simultaneously left and right aligns the text and */
+	float:left;       /* the >> in the drop-down menus which link to sub-menus */
+}
+
+.rightmenu {
+	position:relative;  /* establish a local positioning context for YAH label */
+	float:right;                  /* and right-align it at the top of our page */
+}
+
+#research {            /* this rightmost "Research" button must be positioned */
+	position:absolute;       /* absolutely so that the YAH (you are here) text */
+	top:0px;               /* label will slide underneath it under Opera v8.54 */
+	left:364px;    /* which has a z-order sequencing bug with abs-pos elements */
+}
+
+/*======================== TOP LEVEL MENU DEFINITIONS ========================*/
+
+.menu ul li ul {
+	display:none;                  /* initially hide the entire list hierarchy */
+	padding:1px;                               /* this is our box border width */
+}
+
+.menu ul li a,
+.menu ul li a:visited {                    /* unselected top-level menu items */
+	display:block;
+	float:left;
+	text-decoration:none;
+	height:18px;
+}
+
+.menu ul li:hover a,
+.menu ul li a:hover {                        /* selected top-level menu items */
+	border-top:1px solid #000;    /* these 2 lines create the push-in illusion */
+	height:16px;
+}
+
+/*======================== 2ND LEVEL MENU DEFINITIONS ========================*/
+
+.menu ul li:hover ul,
+.menu ul li a:hover ul {                           /* 2nd level drop-down box */
+	display:block;
+	position:absolute;
+	margin:0;
+	top:18px;              /* place us just up underneath the top-level images */
+	left:-1px;       /* left-align our drop-down to the previous button border */
+	height:auto;      /* the drop-down height will be determiend by line count */
+	width:13.5em;
+	color:black;                        /* this sets the unselected-text color */
+	background:black;         /* this sets our menu's effective "border" color */
+}
+
+.menu ul li:hover ul.leftbutton,
+.menu ul li a:hover ul.leftbutton {/* our first dropdown should not be skewed */
+	left:0px;
+}
+
+.menu ul li:hover ul.skinny,
+.menu ul li a:hover ul.skinny {             /* 2nd level skinny drop-down box */
+	width:8.08333em;   /* with a 12px default font, this is 97px width (97/12) */
+}
+
+.menu ul.rightmenu li:hover ul,
+.menu ul.rightmenu li a:hover ul {    /* 2nd level neighborhood drop-down box */
+	left:auto;
+	right:0;         /* nudge the right menu right to line up under the border */
+}
+
+* html .menu ul.rightmenu li a:hover ul {         /* IE5/6 needs a tweak here */
+	right:-1px;
+}
+
+.menu ul li:hover ul li a,
+.menu ul li a:hover ul li a {                   /* 2nd level unselected items */
+	border:0;
+	margin:0;
+	padding:0;
+	height:auto;
+	color:#000;               /* this sets the unselected drop-down text color */
+	background:#d8d8d8;       /* this sets the drop-down menu background color */
+	width:13.5em;
+}
+
+.menu ul li:hover ul li:hover a,
+.menu ul li a:hover ul li a:hover {                /* 2nd level selected item */
+	color:black;
+	background:white;
+}
+
+.menu ul li:hover ul.skinny li a,
+.menu ul li a:hover ul.skinny li a,
+.menu ul li:hover ul.skinny li a:hover,
+.menu ul li a:hover ul.skinny li a:hover {     /* 2nd level un+selected items */
+	width:8.08333em;
+}
+
+/*======================== 3RD LEVEL MENU DEFINITIONS ========================*/
+
+.menu ul li:hover ul li ul,
+.menu ul li a:hover ul li a ul {             /* hide inactive 3rd-level menus */
+	visibility:hidden;
+}
+     
+.menu ul li:hover ul li:hover ul,
+.menu ul li a:hover ul li a:hover ul {             /* 3rd level drop-down box */
+	visibility:visible;
+	position:absolute;
+	margin-top:-1px;	      /* bring the top edge of the 3rd level menu up one */
+	top:0;
+	left:8.08333em;
+	width:14em;
+}
+
+.menu ul li:hover ul li:hover ul li a,
+.menu ul li a:hover ul li a:hover ul li a {     /* 3rd level unselected items */
+	width:14em;
+	background:#d8d8d8;
+}
+
+.menu ul li:hover ul li:hover ul li a:hover,
+.menu ul li a:hover ul li a:hover ul li a:hover {    /* level3 selected items */
+	width:14em;
+	background:white;
+}
+
+#text {           /* the Mac's standard Safari browser will not see this code */
+	height:1.215em;#           /* ...  but every other browser will and should */
+} /* Safari barfs on the illegal pound sign (#) after the rule's property val */

+ 2 - 2
demo/out/test_extend.html

@@ -1,4 +1,4 @@
-bar1string
+bar2string
 
 base template
 
@@ -6,6 +6,6 @@ replacing the base title
 
 more of base template
 
-replacing the base content - variable: bar2string after variable 
+replacing the base content - variable: bar1string after variable 
 
 end of base template

+ 33 - 0
demo/out/test_htmltags.html

@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test variable</title>								 
+  </head>
+  <body>
+	before
+	
+<object id="myvideo" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600">
+	<param name="movie" value="/static/mediaplayer.swf">
+    <param name="allowfullscreen" value="true">
+    <param name="menu" value="false">
+    <param name="flashvars" value="file=/static/myvideo.mp4&image=/static/mypreview.jpg">
+    <!--[if !IE]>-->
+    <object type="application/x-shockwave-flash" data="/static/mediaplayer.swf" width="800" height="620">
+    <param name="allowfullscreen" value="true">
+    <param name="menu" value="false">
+    <param name="flashvars" value="file=/static/myvideo.mp4&image=/static/mypreview.jpg">
+    <!--<![endif]-->
+    <h2>To view the Video:</h2>
+    <p>
+    	<a href="http://www.adobe.com/go/getflashplayer">
+        	<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"alt="Get Adobe Flash player">
+    	</a>
+    </p>
+    <!--[if !IE]>-->
+    </object>
+    <!--<![endif]-->
+</object>
+	after
+  </body>
+</html>

+ 3 - 0
demo/out/test_simple.html

@@ -0,0 +1,3 @@
+before
+
+after

+ 1 - 1
demo/out/test_variable.html

@@ -6,6 +6,6 @@
   </head>
   <body>
 	foostring
-	foostring
+	bar
   </body>
 </html>

+ 0 - 0
demo/templates/test_tags.css → demo/templates/test_csstags.css


+ 0 - 0
demo/templates/test_tags.html → demo/templates/test_htmltags.html


+ 3 - 0
demo/templates/test_simple.html

@@ -0,0 +1,3 @@
+before
+{# comment #}
+after

+ 2 - 2
demo/templates/test_variable.html

@@ -5,7 +5,7 @@
     <title>Test variable</title>								 
   </head>
   <body>
-	{{ variable }}
-	<!--{{ variable }}-->
+	{{ variable1 }}
+	<!--{{ variable2 }}-->
   </body>
 </html>

+ 59 - 0
priv/tags/layout_abs_pos.css

@@ -0,0 +1,59 @@
+html {
+	overflow: hidden;
+}
+    
+body {
+	overflow: hidden;
+	padding: 0;
+	margin: 0;
+	width: 100%;
+	height: 100%;
+	background:#fff url("/static/images/main_bg.png") repeat-x;
+}
+    
+#top {
+ 	padding: 0;
+ 	margin: 0;
+ 	position: absolute;
+ 	top: 0px;	
+ 	left: 0px;
+ 	width: 100%;
+ 	height: 80px;
+ 	overflow: hidden;
+ 	z-index: -10;
+}
+
+#side {	
+ 	padding: 0;
+ 	margin: 0;
+ 	position: absolute;	
+ 	top: 100px;
+ 	left: 20px;
+ 	bottom: 20px;
+ 	width: 200px;
+ 	overflow: auto;
+ 	z-index: -10;
+}
+    
+#main {
+ 	padding: 0;
+ 	margin: 0;
+ 	position: absolute;	
+ 	top: 100px;
+ 	left: 240px;
+ 	right: 20px;
+ 	bottom: 20px;
+ 	overflow: auto;
+ 	z-index: -10;
+}
+
+#footer {
+	padding: 0;
+	margin: 0;
+	position: absolute;
+	bottom: 0px;	
+	left: 0px;
+	width: 100%;
+	height: 15px;
+	overflow: hidden;
+}

+ 64 - 19
src/demo/erlydtl_demo.erl

@@ -34,10 +34,7 @@
 -author('rsaccon@gmail.com').
 
 %% API
--export([compile_templates/0, 
-    compile_test_template/1, 
-    compile_test_template/2, 
-    render_all/0]).
+-export([compile/0, compile/1, compile/2, render/0, render/1]).
 
 %%====================================================================
 %% API
@@ -47,7 +44,7 @@
 %% @doc  compiles the templates to beam files
 %% @end 
 %%--------------------------------------------------------------------
-compile_templates() ->
+compile() ->
     DocRoot = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "templates"]),
     filelib:fold_files(DocRoot,
         "\.html$|\.css$",
@@ -65,8 +62,8 @@ compile_templates() ->
 %% compiles the template to beam files
 %% @end 
 %%--------------------------------------------------------------------        
-compile_test_template(Name) ->
-     compile_test_template(Name, ".html").
+compile(Name) ->
+     compile(Name, ".html").
       
       
 %%--------------------------------------------------------------------
@@ -75,33 +72,81 @@ compile_test_template(Name) ->
 %% compiles the template to beam files
 %% @end 
 %%--------------------------------------------------------------------       
-compile_test_template(Name, Ext) ->
+compile(Name, Ext) ->
     DocRoot = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "templates"]),
     Name2 = "test_" ++ Name,
     Path = filename:join([DocRoot, Name2 ++ Ext]),
     erlydtl_server:compile(Path, Name2, DocRoot).
 
-                       
+
 %%--------------------------------------------------------------------
 %% @spec () -> any()
-%% @doc renders the templete to a file
+%% @doc renders template to a file
+%% @end 
+%%--------------------------------------------------------------------
+render() ->
+    render("variable", ".html", ["foostring", "bar"]),
+    render("extend", ".html", ["bar1string", "bar2string"]),
+    render("comment", ".html"),
+    render("simple", ".html"),
+    render("htmltags", ".html"),
+    render("csstags", ".css"),
+    render("for", ".html", ["apple", "banana"]).
+        
+
+%%--------------------------------------------------------------------
+%% @spec (string()) -> ok()
+%% @doc renders template to a file
+%% @end 
+%%--------------------------------------------------------------------
+render("variable" = Name) ->
+    render(Name, ".html", ["foostring", "bar"]);
+ 
+render("extend" = Name) ->
+    render(Name, ".html", ["bar1string", "bar2string"]);
+        
+render("comment" = Name) ->
+    render(Name, ".html");
+            
+render("simple" = Name) ->
+    render(Name, ".html");
+                
+render("htmltags" = Name) ->
+    render(Name, ".html");
+    
+render("csstags" = Name) ->
+    render(Name, ".html");    
+                    
+render("for" = Name) ->
+    render(Name, ".html", ["apple", "banana"]).
+
+
+%%--------------------------------------------------------------------
+%% @spec (atom(), string()) -> any()
+%% @doc renders template to a file
+%% @end 
+%%--------------------------------------------------------------------
+render(Name, Ext) ->
+    OutDir = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "out"]),
+    render2(OutDir, list_to_atom("test_" ++ Name), Ext).   
+    
+
+%%--------------------------------------------------------------------
+%% @spec (atom(), string(), string()) -> any()
+%% @doc renders template to a file
 %% @end 
 %%--------------------------------------------------------------------
-render_all() ->
+render(Name, Ext, Args) ->
     OutDir = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "out"]),
-    render(OutDir, test_variable, ".html", ["foostring"]),
-    render(OutDir, test_extend, ".html", ["bar1string", "bar2string"]),
-    render(OutDir, test_comment, ".html"),
-    render(OutDir, test_tags, ".html"),
-    render(OutDir, test_tags, ".css"),
-    render(OutDir, test_for, ".html", ["apple", "banana"]).
+    render2(OutDir, list_to_atom("test_" ++ Name), Ext, Args).
+            
 
               
 %%====================================================================
 %% Internal functions
 %%====================================================================
 
-render(OutDir, Module, Ext, Args) ->
+render2(OutDir, Module, Ext, Args) ->
     case catch apply(Module, render, Args) of
         {'EXIT', Reason} -> 
             io:format("TRACE ~p:~p ~p: rendering failure: ~n",[?MODULE, ?LINE, Reason]);
@@ -116,7 +161,7 @@ render(OutDir, Module, Ext, Args) ->
         	end
     end.
     
-render(OutDir, Module, Ext) ->
+render2(OutDir, Module, Ext) ->
     case catch Module:render() of
         {'EXIT', Reason} -> 
             io:format("TRACE ~p:~p ~p: rendering failure: ~n",[?MODULE, ?LINE, Reason]);

+ 2 - 2
src/erlydtl/erlydtl_scanner.erl

@@ -144,14 +144,14 @@ fold_strings([], Folded, []) ->
     lists:reverse(Folded);
 
 fold_strings([], Folded, Acc) ->
-    S = {string, 1, lists:reverse(Acc)},
+    S = {string, lists:reverse(Acc)},
     lists:reverse([S | Folded]);
 
 fold_strings([H | T], Folded, []) when is_tuple(H) ->
     fold_strings(T, [translate_token(H) | Folded], []);
 
 fold_strings([H | T], Folded, Acc) when is_tuple(H) ->
-    S = {string, 1, lists:reverse(Acc)},
+    S = {string, lists:reverse(Acc)},
     fold_strings(T, [translate_token(H), S | Folded], []);
 
 fold_strings([H | T], Folded, Acc) ->

+ 74 - 63
src/erlydtl/erlydtl_server.erl

@@ -119,7 +119,7 @@ handle_call({compile, File, ModuleName, DocRoot, FunctionName}, _From, State) ->
         {ok, Ast} ->
 		    RelDir = rel_dir(filename:dirname(File), DocRoot),
 		    Ext = filename:extension(File),
-            compile_reload_ast(Ast, ModuleName, FunctionName, RelDir, Ext);
+            compile(Ast, ModuleName, FunctionName, RelDir, Ext);
         {error, Msg} = Err ->
             io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, File ++ " Parser failure:"]),
             io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Msg]),
@@ -193,36 +193,35 @@ parse(File) ->
 	end.
 	
 
-compile_reload_ast([H | T], ModuleName, FunctionName, RelDir, Ext) ->
-    {List, Args} = case walk_ast(H, T, [], [], RelDir, Ext) of
+compile([H | T], ModuleName, FunctionName, RelDir, Ext) ->
+    {List, Args} = case build_tree(H, T, [], [], RelDir, Ext) of
 	    {regular, List0, Args0} ->
 		    {[parse_transform(X) ||  X <- List0], Args0};
 		{inherited, List0, Arg0} ->
 			{List0, Arg0}
-	end,	           
-    Args2 = lists:reverse([{var, 1, Val} || {Val, _} <- Args]),  
-    Cons = list_fold(lists:reverse(List)),                           
-    Ast2 = {function, 1, list_to_atom(FunctionName), length(Args2),
-        [{clause, 1, Args2, [], [Cons]}]},
-    Ac = erlydtl_tools:create_module(Ast2 , ModuleName),   
-    case compile:forms(Ac) of
+	end, 
+	List1 = erl_syntax:list(List),
+	Args1 = [erl_syntax:variable(Val) || {Val, _} <- Args],
+	Clause = erl_syntax:clause(Args1, none, [List1]),
+	Func = erl_syntax:function(erl_syntax:atom(FunctionName), [Clause]),
+	[Mod, Cmp] = [erl_syntax:attribute(erl_syntax:atom(X), [erl_syntax:atom(Y)]) ||
+	    {X, Y} <- [{"module", ModuleName}, {"compile", "export_all"}]],
+    Forms = [erl_syntax:revert(X) || X <- [Mod, Cmp, Func]],
+    io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Forms]),
+    case compile:forms(Forms) of
         {ok, Module, Bin} ->
-            case erlydtl_tools:reload(Module, Bin) of
-                ok ->
-                    erlydtl_tools:write_beam(Module, Bin, "ebin");
-                _ -> 
-                    {error, "reload failed"}
-            end;            
+            erlydtl_tools:write_beam(Module, Bin, "ebin"),
+            erlydtl_tools:reload(Module, Bin);
         _ ->
-           {error, "compilation failed"}
-    end.                      
-
+            {error, "compilation failed"}
+    end.   
+    
 
-walk_ast(nil, [{extends, _Line, Name}], Out, Args, RelDir, Ext) -> 
+build_tree(nil, [{extends, _Line, Name}], Out, Args, RelDir, Ext) -> 
     case parse(filename:join([RelDir, Name])) of
         {ok, ParentAst} ->
 		    [H|T]=ParentAst,
-			{_, List, Args1} = walk_ast(H, T, [], [], RelDir, Ext),			 
+			{_, List, Args1} = build_tree(H, T, [], [], RelDir, Ext),			 
 			{List3, Args3} = lists:foldl(fun(X, {List2, Args2}) -> 
                 {List4, Args4} = parse_transform(X, Out, Args2, Ext),            
                 {[List4 | List2], Args4}
@@ -234,7 +233,7 @@ walk_ast(nil, [{extends, _Line, Name}], Out, Args, RelDir, Ext) ->
 		     {regular, Out, Args}			
     end;
 	
-walk_ast(nil, [{var, Line, Val}], Out, Args, _, _) ->
+build_tree(nil, [{var, Line, Val}], Out, Args, _, _) ->
     case lists:keysearch(Val, 2, Args) of
         false ->
             Key = list_to_atom(lists:concat(["A", length(Args) + 1])),
@@ -243,66 +242,79 @@ walk_ast(nil, [{var, Line, Val}], Out, Args, _, _) ->
             {regular, [{var, Line, Key} | Out], Args}
     end;
     
-walk_ast(nil, [{tag, _Line, [TagName | TagArgs]}], Out, Args, _, Ext) ->
+build_tree(nil, [{tag, _Line, [TagName | TagArgs]}], Out, Args, _, Ext) ->
     Out2 = load_tag(TagName, TagArgs, Out, default, Ext),    
     {regular, Out2, Args};
     
-walk_ast(nil, [{for, _Line, Var, List, Content}], Out, Args, _, Ext) ->
+build_tree(nil, [{for, _Line, Var, List, Content}], Out, Args, _, Ext) ->
 io:format("TRACE ~p:~p Content-nil: ~p~n",[?MODULE, ?LINE, Content]),
      Out2 = Out,
      {regular, Out2, Args};    
+ 
+build_tree(nil, [{string, Val}], Out, Args, _, _) ->
+     {regular, [binary_string(Val) | Out], Args}; 
     
-walk_ast(nil, [Token], Out, Args, _, _) ->
+build_tree(nil, [Token], Out, Args, _, _) ->
     {regular, [Token | Out], Args}; 
 	
-walk_ast([H | T], [{var, Line, Val}], Out, Args, DocRoot, Ext) ->
+build_tree([H | T], [{var, Line, Val}], Out, Args, DocRoot, Ext) ->
     case lists:keysearch(Val, 2, Args) of
         false ->           
             Key = list_to_atom(lists:concat(["A", length(Args) + 1])),
-            walk_ast(H, T, [{var, Line, Key} | Out], [{Key, Val} | Args], DocRoot, Ext);
+            build_tree(H, T, [{var, Line, Key} | Out], [{Key, Val} | Args], DocRoot, Ext);
         {value, {Key, _}} ->  
-            walk_ast(H, T, [{var, Line, Key} | Out], Args, DocRoot, Ext)
+            build_tree(H, T, [{var, Line, Key} | Out], Args, DocRoot, Ext)
 	end;	 
 	
-walk_ast([H | T], [{tag, _Line, [TagName | TagArgs]}], Out, Args, DocRoot, Ext) ->
+build_tree([H | T], [{tag, _Line, [TagName | TagArgs]}], Out, Args, DocRoot, Ext) ->
     Out2 = load_tag(TagName, TagArgs, Out, default, Ext),
-    walk_ast(H, T, Out2, Args, DocRoot, Ext);
+    build_tree(H, T, Out2, Args, DocRoot, Ext);
     
-walk_ast([H | T], [{for, _Line, Var, List, [nil | TFor]}], Out, Args, DocRoot, Ext) ->
+build_tree([H | T], [{for, _Line, Var, List, [nil | TFor]}], Out, Args, DocRoot, Ext) ->
 io:format("TRACE ~p:~p Content-not-nil: ~p~n",[?MODULE, ?LINE, T]),  %%
     % just subst. var
     Out2 = Out,
-    walk_ast(H, T, Out2, Args, DocRoot, Ext);     
+    build_tree(H, T, Out2, Args, DocRoot, Ext);     
 
-walk_ast([H | T], [{for, _Line, Var, List, [HFor | TFor]}], Out, Args, DocRoot, Ext) -> 
+build_tree([H | T], [{for, _Line, Var, List, [HFor | TFor]}], Out, Args, DocRoot, Ext) -> 
     %% List2 = lists:foldl(fun(X, Acc) -> 
-    %%         {_, List1, _Args1} = walk_ast(HFor, TFor, [], [], undefined, Ext),
+    %%         {_, List1, _Args1} = build_tree(HFor, TFor, [], [], undefined, Ext),
     %%         [parse_transform(Y, X, Var)  || Y <- List1]                
     %%     end,
     %%     [],
     %%     List),
     %% io:format("TRACE ~p:~p Content-not-nil-out1: ~p~n",[?MODULE, ?LINE, List2]),
     %% io:format("TRACE ~p:~p Content-not-nil-out2: ~p~n",[?MODULE, ?LINE, lists:flatten(List2)]),
+    %
+    % test(L) -> [a || _X <- L].  {lc, 1,  {atom,1,a}, [{generate, 1, {var,1,'_X'}, {var,1,'L'}}]}
+    %
     io:format("TRACE ~p:~p Content-not-nil-out1: ~p~n",[?MODULE, ?LINE, Var]),
     io:format("TRACE ~p:~p Content-not-nil-out1: ~p~n",[?MODULE, ?LINE, List]),
     io:format("TRACE ~p:~p Content-not-nil-out1: ~p~n",[?MODULE, ?LINE, [HFor | TFor]]),
     Out2 = Out,
-    walk_ast(H, T, Out2, Args, DocRoot, Ext);	
-	
-walk_ast([H | T], [Token], Out, Args, DocRoot, Ext) ->      
-    walk_ast(H, T, [Token | Out], Args, DocRoot, Ext).
+    build_tree(H, T, Out2, Args, DocRoot, Ext);	
+
+build_tree([H | T], [{string, Val}], Out, Args, DocRoot, Ext) ->      
+    build_tree(H, T, [binary_string(Val) | Out], Args, DocRoot, Ext);
+        	
+build_tree([H | T], [Token], Out, Args, DocRoot, Ext) ->      
+    build_tree(H, T, [Token | Out], Args, DocRoot, Ext).
 
 
 parse_transform({block, _Line, Name, [nil, Val]}, List, Args, Ext) ->
 	case lists:keysearch(Name, 3, List) of
 		false -> 
-			{Val, Args};
+            %% {Val, Args};
+            parse_transform(Val, List, Args, Ext);
 		{value, {_, _, _, [H | T]}} ->  
-		    {_, List2, Args2} = walk_ast(H, T, [], Args, undefined, Ext),
-		    {lists:reverse(List2), Args2} 
+		    {_, List2, Args2} = build_tree(H, T, [], Args, undefined, Ext),
+            %% {lists:reverse(List2), Args2} 
+            parse_transform(lists:reverse(List2), List, Args2, Ext)
  	end;
-parse_transform(Other, _What, Args, _) ->	
-	{Other, Args}.
+parse_transform({string, Val}, _, Args, _) ->    
+    {binary_string(Val), Args};
+parse_transform(Other, _What, Args, _) ->    
+    {Other, Args}.
 
     
 parse_transform({var, Line, Var}, Var1, Var) when is_atom(Var1) ->
@@ -311,22 +323,31 @@ parse_transform({var, Line, Var}, Var1, Var) when is_atom(Var1) ->
             
 parse_transform({var, Line, Var}, Args) ->
     {value, {_, Val}} = lists:keysearch(Var, 1, Args),
-    {string, Line, Val};            
-parse_transform(Other, _) ->
+    binary_string(Val);      
+parse_transform({string, Val}, _) ->    
+    binary_string(Val);
+parse_transform(Other, _) ->    
     Other.
         
 
-parse_transform({block, _Line , _Name, [nil, Str]}) ->
-	Str;
-parse_transform(Other) ->	
-	Other.
-    	
-    	        	
+parse_transform({block, _Line , _Name, [nil, T]}) ->
+	parse_transform(T);
+parse_transform({string, Val}) ->
+    binary_string(Val); 
+parse_transform({var, L, Val}) ->
+    erl_syntax:variable(Val);
+parse_transform(Other) ->    
+    Other.   	
+
+binary_string(Val) ->
+    erl_syntax:binary([erl_syntax:binary_field(erl_syntax:integer(X)) || X <- Val]).
+    
+       	        	
 load_tag(TagName, TagArgs, Acc0, default, Ext) ->
     case parse(filename:join([erlydtl_deps:get_base_dir(), "priv", "tags", atom_to_list(TagName) ++ Ext])) of
         {ok, ParentAst} ->
 		    [H|T]=ParentAst,
-			{_, List, Args1} = walk_ast(H, T, [], [], undefined, Ext),
+			{_, List, Args1} = build_tree(H, T, [], [], undefined, Ext),
 			Args2 = [{Var, Val} || {{Var, _}, Val} <- lists:zip(Args1, TagArgs)], 			
 			lists:foldl(fun(X, Acc) -> 
 			        [parse_transform(X, Args2) | Acc]			        
@@ -337,17 +358,7 @@ load_tag(TagName, TagArgs, Acc0, default, Ext) ->
     	    io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Msg]),
     	    Acc0
     end.
- 
-
-list_fold([E]) ->
-    E;      
-list_fold([E1, E2]) ->
-    {cons, 1, E2, E1};           
-list_fold([E1, E2 | Tail]) ->
-    lists:foldl(fun(X, T) -> 
-        {cons, 1, X, T}
-    end, {cons, 1, E2, E1}, Tail).
-     
+  
     
 rel_dir(Dir, DocRoot) when Dir =:= DocRoot ->
     DocRoot;

+ 4 - 23
src/erlydtl/erlydtl_tools.erl

@@ -34,7 +34,7 @@
 -author('rsaccon@gmail.com').
 
 %% API
--export([create_parser/0, create_module/2, reload/2, write_beam/3]).
+-export([create_parser/0, reload/2, write_beam/3]).
 
 %% --------------------------------------------------------------------
 %% Definitions
@@ -59,20 +59,6 @@ create_parser() ->
     
 
 %%--------------------------------------------------------------------
-%% @spec (Ast::tuple(), Name::atom()) -> any()
-%% @doc Translate Abstract Syntax Tree to Abstract Module Code
-%% @end 
-%%--------------------------------------------------------------------    
-create_module(Ast, ModuleName) when is_list(Ast) ->
-    Tail = lists:reverse([{eof, 1} | lists:reverse(lists:flatten(Ast))]),
-    add_module_header(Tail, ModuleName);
-create_module(Ast, ModuleName) ->
-    Tail = [Ast, {eof, 1}],
-    add_module_header(Tail, ModuleName).
-
-
-
-%%--------------------------------------------------------------------
 %% @spec (ModuleName::string(), Bin,::binary()) -> Ok::atom() | Error::atom()
 %% @doc reloads byte code
 %% @end 
@@ -103,13 +89,13 @@ write_beam(ModuleName, Bin, Dir) ->
 create_parser(Path, Outdir) ->
     case yecc:file(Path) of
         {ok, _} ->
-            compile_reload(Path, Outdir);
+            compile_reload_parser(Path, Outdir);
         Err ->
             io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Path ++ ": yecc failed"]),
             Err
     end.
     
-compile_reload(Path, Outdir) ->
+compile_reload_parser(Path, Outdir) ->
     case compile:file(Path, ?PRINT_ERR_WARNS ++ [{outdir, Outdir}]) of
         {ok, Bin} ->
             code:purge(Bin),
@@ -117,9 +103,4 @@ compile_reload(Path, Outdir) ->
         Err ->
             io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Path ++ ": compilation failed"]),
             Err
-    end.
-    
-    
-add_module_header(Tail, ModuleName) -> 
-    Tail2 = [{attribute, 1, compile, export_all} | Tail],
-    [{attribute, 1, module, list_to_atom(ModuleName)} | Tail2].
+    end.