Skip to content
Browse files

scan is broken, time to figure out why

  • Loading branch information...
1 parent d0ae31e commit 7f8a9cb9b5361ab1b633e0f6deac7ad8f39992db @mojombo committed Dec 22, 2009
Showing with 61 additions and 20 deletions.
  1. +14 −0 examples/nonl.erl
  2. +1 −0 examples/nonl.mustache
  3. +46 −20 mustache.erl
View
14 examples/nonl.erl
@@ -0,0 +1,14 @@
+-module(nonl).
+-compile(export_all).
+
+name() ->
+ "Tom".
+
+value() ->
+ "10000".
+
+taxed_value() ->
+ integer_to_list(value() - (value() * 0.4)).
+
+in_ca() ->
+ true.
View
1 examples/nonl.mustache
@@ -0,0 +1 @@
+Hello {{name}} you {{#in_ca}} totally {{/in_ca}} win {{value}}!
View
66 mustache.erl
@@ -1,22 +1,29 @@
-module(mustache). %% v0.1.0beta
-author("Tom Preston-Werner").
--export([render/2, compile/1, start/0]).
+-export([render/2, val/3, start/1]).
--record(mstate, {section_re = undefined,
+-record(mstate, {mod = undefined,
+ section_re = undefined,
tag_re = undefined}).
-render(Mod, F) -> ok.
-% {ok, TemplateBin} = file:read_file(F),
-% CompiledTemplate = compile(binary_to_list(TemplateBin)),
-
+render(Mod, File) ->
+ {ok, TemplateBin} = file:read_file(File),
+ State = #mstate{mod = Mod},
+ CompiledTemplate = pre_compile(binary_to_list(TemplateBin), State),
+ io:format(CompiledTemplate ++ "~n", []),
+ {ok, Tokens, _} = erl_scan:string(CompiledTemplate),
+ {ok, [Form]} = erl_parse:parse_exprs(Tokens),
+ Bindings = erl_eval:new_bindings(),
+ {value, Fun, _} = erl_eval:expr(Form, Bindings),
+ Fun().
-compile(T) ->
+pre_compile(T, State) ->
SectionRE = "\{\{\#([^\}]*)}}\s*(.+?){{\/\\1\}\}\s*",
{ok, CompiledSectionRE} = re:compile(SectionRE, [dotall]),
TagRE = "\{\{(#|=|!|<|>|\{)?(.+?)\\1?\}\}+",
{ok, CompiledTagRE} = re:compile(TagRE, [dotall]),
- State = #mstate{section_re = CompiledSectionRE, tag_re = CompiledTagRE},
- compile(T, State).
+ State2 = State#mstate{section_re = CompiledSectionRE, tag_re = CompiledTagRE},
+ "fun() -> Ctx = dict:new(), " ++ compile(T, State2) ++ " end.".
compile(T, State) ->
Res = re:run(T, State#mstate.section_re),
@@ -35,15 +42,18 @@ compile(T, State) ->
end.
compile_section(Name, Content, State) ->
+ Mod = State#mstate.mod,
Result = compile(Content, State),
% "<" ++ Name ++ ">" ++ Result ++ "</" ++ Name ++ ">".
"fun() -> " ++
- "Res = apply(simple, " ++ Name ++ ", []), " ++
+ "Res = mustache:val(" ++ Name ++ ", Ctx, " ++ Mod ++ "), " ++
"case Res of " ++
"true -> " ++
Result ++ "; " ++
"false -> " ++
- "[] " ++
+ "[]; " ++
+ "List when is_list(List) -> " ++
+ "[" ++ Result ++ " || X <- List] " ++
"end " ++
"end()".
@@ -56,30 +66,46 @@ compile_tags(T, State) ->
Back = string:substr(T, M0 + M1 + 1),
Content = string:substr(T, C0 + 1, C1),
Kind = tag_kind(T, K),
- Result = compile_tag(Kind, Content),
+ Result = compile_tag(Kind, Content, State),
"[\"" ++ Front ++
"\" | [" ++ Result ++
" | " ++ compile_tags(Back, State) ++ "]]";
nomatch ->
"[\"" ++ T ++ "\"]"
end.
-tag_kind(T, {-1, 0}) ->
+tag_kind(_T, {-1, 0}) ->
none;
tag_kind(T, {K0, K1}) ->
string:substr(T, K0 + 1, K1).
-compile_tag(none, Content) ->
- "apply(simple, " ++ Content ++ ", [])";
-compile_tag("!", _Content) ->
+compile_tag(none, Content, State) ->
+ Mod = State#mstate.mod,
+ "apply(" ++ Mod ++ ", " ++ Content ++ ", [])";
+compile_tag("!", _Content, _State) ->
"[]".
+val(Key, Ctx, Mod) when is_list(Key) ->
+ val(list_to_atom(Key), Ctx, Mod);
+val(Key, Ctx, Mod) ->
+ case dict:find(Key, Ctx) of
+ {ok, Val} -> Val;
+ error ->
+ case erlang:function_exported(Mod, Key, 0) of
+ true ->
+ apply(Mod, Key, []);
+ false ->
+ []
+ end
+ end.
+
%%---------------------------------------------------------------------------
-start() ->
+start(T) ->
% T = "Hello {{name}}\nYou have just won ${{value}}!\n{{#in_ca}}\nWell, ${{ taxed_value }}, after taxes.\n{{/in_ca}}\n",
% T = "abc {{#foo}} hi {{/foo}} def {{#bar}} bye {{/bar}} ghi\n",
- T = "hello {{name}} you {{#in_ca}} DO {{/in_ca}} win {{value}}!",
- D = compile(T),
- io:format(D, []).
+ % T = "hello {{name}} you {{#in_ca}} DO {{/in_ca}} win {{value}}!",
+ % D = compile(T),
+ %io:format(D ++ "~n", []).
+ render(T, "examples/" ++ T ++ ".mustache").

0 comments on commit 7f8a9cb

Please sign in to comment.
Something went wrong with that request. Please try again.