|
@@ -35,7 +35,7 @@
|
|
-author('rsaccon@gmail.com').
|
|
-author('rsaccon@gmail.com').
|
|
-author('emmiller@gmail.com').
|
|
-author('emmiller@gmail.com').
|
|
|
|
|
|
--export([compile/2, compile/3, compile/4, compile/5, compile/6, parse/1, scan/1, body_ast/2]).
|
|
|
|
|
|
+-export([compile/2, compile/3, compile/4, compile/5, compile/6, compile/7, parse/2, scan/2, body_ast/2]).
|
|
|
|
|
|
-record(dtl_context, {
|
|
-record(dtl_context, {
|
|
local_scopes = [],
|
|
local_scopes = [],
|
|
@@ -43,7 +43,8 @@
|
|
auto_escape = off,
|
|
auto_escape = off,
|
|
doc_root = "",
|
|
doc_root = "",
|
|
parse_trail = [],
|
|
parse_trail = [],
|
|
- preset_vars = []}).
|
|
|
|
|
|
+ preset_vars = [],
|
|
|
|
+ reader = {file, read_file}}).
|
|
|
|
|
|
-record(ast_info, {
|
|
-record(ast_info, {
|
|
dependencies = [],
|
|
dependencies = [],
|
|
@@ -58,18 +59,21 @@ compile(File, Module, DocRoot) ->
|
|
compile(File, Module, DocRoot, []).
|
|
compile(File, Module, DocRoot, []).
|
|
|
|
|
|
compile(File, Module, DocRoot, Vars) ->
|
|
compile(File, Module, DocRoot, Vars) ->
|
|
- compile(File, Module, DocRoot, Vars, "render").
|
|
|
|
|
|
+ compile(File, Module, DocRoot, Vars, {file, read_file}).
|
|
|
|
|
|
-compile(File, Module, DocRoot, Vars, Function) ->
|
|
|
|
- compile(File, Module, DocRoot, Vars, Function, "ebin").
|
|
|
|
|
|
+compile(File, Module, DocRoot, Vars, Reader) ->
|
|
|
|
+ compile(File, Module, DocRoot, Vars, Reader, "render").
|
|
|
|
+
|
|
|
|
+compile(File, Module, DocRoot, Vars, Reader, Function) ->
|
|
|
|
+ compile(File, Module, DocRoot, Vars, Reader, Function, "ebin").
|
|
|
|
|
|
-compile(File, Module, DocRoot, Vars, Function, OutDir) ->
|
|
|
|
- case parse(File) of
|
|
|
|
|
|
+compile(File, Module, DocRoot, Vars, Reader, Function, OutDir) ->
|
|
|
|
+ case parse(File, Reader) of
|
|
{ok, DjangoParseTree} ->
|
|
{ok, DjangoParseTree} ->
|
|
OldProcessDictVal = put(erlydtl_counter, 0),
|
|
OldProcessDictVal = put(erlydtl_counter, 0),
|
|
|
|
|
|
{BodyAst, BodyInfo} = body_ast(DjangoParseTree, #dtl_context{
|
|
{BodyAst, BodyInfo} = body_ast(DjangoParseTree, #dtl_context{
|
|
- doc_root = DocRoot, parse_trail = [File], preset_vars = Vars}),
|
|
|
|
|
|
+ doc_root = DocRoot, parse_trail = [File], preset_vars = Vars, reader = Reader}),
|
|
|
|
|
|
Render0FunctionAst = erl_syntax:function(erl_syntax:atom(Function),
|
|
Render0FunctionAst = erl_syntax:function(erl_syntax:atom(Function),
|
|
[erl_syntax:clause([], none, [erl_syntax:application(none,
|
|
[erl_syntax:clause([], none, [erl_syntax:application(none,
|
|
@@ -148,16 +152,16 @@ compile(File, Module, DocRoot, Vars, Function, OutDir) ->
|
|
Error
|
|
Error
|
|
end.
|
|
end.
|
|
|
|
|
|
-scan(File) ->
|
|
|
|
- case file:read_file(File) of
|
|
|
|
|
|
+scan(File, {Module, Function}) ->
|
|
|
|
+ case catch Module:Function(File) of
|
|
{ok, B} ->
|
|
{ok, B} ->
|
|
erlydtl_scanner:scan(binary_to_list(B));
|
|
erlydtl_scanner:scan(binary_to_list(B));
|
|
_ ->
|
|
_ ->
|
|
{error, "reading " ++ File ++ " failed "}
|
|
{error, "reading " ++ File ++ " failed "}
|
|
end.
|
|
end.
|
|
|
|
|
|
-parse(File) ->
|
|
|
|
- case scan(File) of
|
|
|
|
|
|
+parse(File, Reader) ->
|
|
|
|
+ case scan(File, Reader) of
|
|
{ok, Tokens} ->
|
|
{ok, Tokens} ->
|
|
erlydtl_parser:parse(Tokens);
|
|
erlydtl_parser:parse(Tokens);
|
|
Err ->
|
|
Err ->
|
|
@@ -175,7 +179,7 @@ body_ast([{extends, {string_literal, _Pos, String}} | ThisParseTree], Context) -
|
|
true ->
|
|
true ->
|
|
{error, "Circular file inclusion!"};
|
|
{error, "Circular file inclusion!"};
|
|
_ ->
|
|
_ ->
|
|
- {ok, ParentParseTree} = parse(File),
|
|
|
|
|
|
+ {ok, ParentParseTree} = parse(File, Context#dtl_context.reader),
|
|
BlockDict = lists:foldl(
|
|
BlockDict = lists:foldl(
|
|
fun
|
|
fun
|
|
({block, {identifier, _, Name}, Contents}, Dict) ->
|
|
({block, {identifier, _, Name}, Contents}, Dict) ->
|
|
@@ -297,7 +301,7 @@ string_ast(String) ->
|
|
|
|
|
|
include_ast(File, Context) ->
|
|
include_ast(File, Context) ->
|
|
FilePath = full_path(File, Context#dtl_context.doc_root),
|
|
FilePath = full_path(File, Context#dtl_context.doc_root),
|
|
- {ok, InclusionParseTree} = parse(FilePath),
|
|
|
|
|
|
+ {ok, InclusionParseTree} = parse(FilePath, Context#dtl_context.reader),
|
|
with_dependency(FilePath, body_ast(InclusionParseTree, Context#dtl_context{parse_trail =
|
|
with_dependency(FilePath, body_ast(InclusionParseTree, Context#dtl_context{parse_trail =
|
|
[FilePath | Context#dtl_context.parse_trail]})).
|
|
[FilePath | Context#dtl_context.parse_trail]})).
|
|
|
|
|
|
@@ -482,7 +486,7 @@ tag_ast(Name, Args, Context) ->
|
|
{list_to_atom(Key), resolve_variable_ast(Value, Context)}
|
|
{list_to_atom(Key), resolve_variable_ast(Value, Context)}
|
|
end, Args),
|
|
end, Args),
|
|
Source = filename:join([erlydtl_deps:get_base_dir(), "priv", "tags", Name]),
|
|
Source = filename:join([erlydtl_deps:get_base_dir(), "priv", "tags", Name]),
|
|
- case parse(Source) of
|
|
|
|
|
|
+ case parse(Source, Context#dtl_context.reader) of
|
|
{ok, TagParseTree} ->
|
|
{ok, TagParseTree} ->
|
|
with_dependency(Source, body_ast(TagParseTree, Context#dtl_context{
|
|
with_dependency(Source, body_ast(TagParseTree, Context#dtl_context{
|
|
local_scopes = [ InterpretedArgs | Context#dtl_context.local_scopes ],
|
|
local_scopes = [ InterpretedArgs | Context#dtl_context.local_scopes ],
|