Packages
fermo
0.6.2
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.1
0.17.0
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.0
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.4
0.2.2
0.2.1
0.2.0
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
A static site generator
Current section
Files
Jump to
Current section
Files
lib/fermo/middleman_importer.ex
defmodule Fermo.MiddlemanImporter do
@args_options [source: :string, destination: :string]
def run(args) do
{source, destination} = parse_args(args)
ensure_directory(destination)
sources =
sources(source)
|> to_relative(source)
Enum.each(sources, &(import_slim(&1, source, destination)))
end
defp parse_args(args) do
{opts, arguments, invalid} = OptionParser.parse(args, strict: @args_options)
if arguments != [] do
raise "Unexpected arguments found: #{inspect(arguments)}"
end
if invalid != [] do
raise "Invalid options found: #{inspect(invalid)}"
end
source = opts[:source]
destination = opts[:destination]
if !File.dir?(source) do
raise "Source directory '#{source}' does not exist"
end
{source, destination}
end
defp sources(source) do
Path.wildcard(source <> "/**/*.slim")
end
defp to_relative(sources, source) do
Enum.map(sources, &(Path.relative_to(&1, source)))
end
defp import_slim(pathname, source, destination) do
source_pathname = Path.join(source, pathname)
raw = File.read!(source_pathname)
converted = convert(raw)
destination_pathname = Path.join(destination, pathname)
destination_directory = Path.dirname(destination_pathname)
ensure_directory(destination_directory)
File.write!(destination_pathname, converted, [:write])
end
defp convert(raw) do
raw
|> ifs
|> eachs
|> partial_params
|> ts
|> counts
|> presents
end
@if_match ~r<(\s*)-\s*if(.*)>x
defp ifs(raw) do
String.replace(raw, @if_match, "\\1= if\\2 do")
end
# Match ` - foos.each do |foo|`
@each_match ~r<
(\s*)
-\s* # SLIM code escape
([\w_\.]+) # a Ruby variable
.each\s* # each
do\s* # do
\|([\w_]+)\| # block parameters
>x
defp eachs(raw) do
String.replace(raw, @each_match, "\\1= Enum.map \\2, fn \\3 ->")
end
# Match `= partial "foo", locals: {bar: "baz"}`
@partial_params_match ~r<
(\s*)
=\s*
partial\s+
['"]
([\w\/\-\ "']+)
['"]
,\s*
locals:\s*
{
([^}]+)
}
>x
defp partial_params(raw) do
String.replace(raw, @partial_params_match, ~s<\\1= partial "\\2", %{\\3}>)
end
# Match `t("teh.label")`
@translation_match ~r<
\bt # t
\( # (
['"] # ' or "
([\w_\.\-]+) # localized string identifier
['"] # ' or "
\) # )
>x
defp ts(raw) do
String.replace(raw, @translation_match, ~s<t("\\1", locale)>)
end
# Match `foos.count`
@count_match ~r<
\b([\w_\.]+) # a Ruby variable
\.count # `.count`
>x
defp counts(raw) do
String.replace(raw, @count_match, ~s<length(\\1)>)
end
# Match `foo.present?`
@present_match ~r<
\b([\w_\.]+) # a Ruby variable
\.present\? # `.present?`
>x
defp presents(raw) do
String.replace(raw, @present_match, ~s<\\1>)
end
defp ensure_directory(path) do
if !File.dir?(path) do
File.mkdir_p!(path)
end
end
end