defmodule Slime do
@moduledoc """
Slim-like HTML templates.
"""
alias Slime.Renderer
defmodule TemplateSyntaxError do
@moduledoc """
Syntax exception which may appear during parsing and compilation processes
"""
defexception [:line, :line_number, :column, message: "Syntax error", source: "INPUT"]
def message(exception) do
column = if exception.column == 0, do: 0, else: exception.column - 1
"""
#{exception.message}
#{exception.source}, Line #{exception.line_number}, Column #{exception.column}
#{exception.line}
#{String.duplicate(" ", column)}^
"""
end
end
defdelegate render(slime), to: Renderer
defdelegate render(slime, bindings), to: Renderer
@doc """
Generates a function definition from the file contents.
The kind (`:def` or `:defp`) must be given, the
function name, its arguments and the compilation options.
This function is useful in case you have templates but
you want to precompile inside a module for speed.
## Examples
# sample.slim
= a + b
# sample.ex
defmodule Sample do
require Slime
Slime.function_from_file :def, :sample, "sample.slime", [:a, :b]
end
# iex
Sample.sample(1, 2) #=> "3"
"""
defmacro function_from_file(kind, name, file, args \\ [], opts \\ []) do
quote bind_quoted: binding() do
require EEx
eex = file |> File.read!() |> Renderer.precompile()
EEx.function_from_string(kind, name, eex, args, opts)
end
end
@doc """
Generates a function definition from the string.
The kind (`:def` or `:defp`) must be given, the
function name, its arguments and the compilation options.
## Examples
iex> defmodule Sample do
...> require Slime
...> Slime.function_from_string :def, :sample, "= a + b", [:a, :b]
...> end
iex> Sample.sample(1, 2)
"3"
"""
defmacro function_from_string(kind, name, source, args \\ [], opts \\ []) do
quote bind_quoted: binding() do
require EEx
eex = source |> Renderer.precompile()
EEx.function_from_string(kind, name, eex, args, opts)
end
end
end