Current section

Files

Jump to
tale src tale@content.erl
Raw

src/tale@content.erl

-module(tale@content).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/tale/content.gleam").
-export([permalink_from_output/1, is_post_page/1, is_list_layout/1, with_output_path/3, load_pages/3]).
-export_type([page_frontmatter/0, page_metadata/0, page_data/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type page_frontmatter() :: {page_frontmatter,
binary(),
binary(),
binary(),
gleam@option:option(binary()),
boolean(),
list(binary()),
gleam@option:option(binary())}.
-type page_metadata() :: {page_metadata,
binary(),
binary(),
gleam@option:option(binary()),
boolean(),
list(binary()),
binary(),
binary()}.
-type page_data() :: {page_data,
binary(),
binary(),
binary(),
binary(),
binary(),
page_metadata(),
binary()}.
-file("src/tale/content.gleam", 182).
-spec relative_content_path(binary(), binary()) -> binary().
relative_content_path(Path, Content_dir) ->
Prefix = <<Content_dir/binary, "/"/utf8>>,
case gleam_stdlib:string_starts_with(Path, Prefix) of
true ->
gleam@string:drop_start(Path, string:length(Prefix));
false ->
Path
end.
-file("src/tale/content.gleam", 209).
-spec strip_extension(binary()) -> binary().
strip_extension(Path) ->
case gleam_stdlib:string_ends_with(Path, <<".md"/utf8>>) of
true ->
gleam@string:drop_end(Path, 3);
false ->
Path
end.
-file("src/tale/content.gleam", 228).
-spec is_section_index(binary()) -> boolean().
is_section_index(Relative) ->
Stem = strip_extension(Relative),
case Stem of
<<"_index"/utf8>> ->
true;
_ ->
gleam_stdlib:string_ends_with(Stem, <<"/_index"/utf8>>)
end.
-file("src/tale/content.gleam", 216).
-spec infer_layout(binary()) -> binary().
infer_layout(Relative) ->
case is_section_index(Relative) of
true ->
<<"home"/utf8>>;
false ->
case gleam_stdlib:string_starts_with(Relative, <<"posts/"/utf8>>) of
true ->
<<"section"/utf8>>;
false ->
<<"page"/utf8>>
end
end.
-file("src/tale/content.gleam", 295).
-spec capitalize_slug(binary()) -> binary().
capitalize_slug(Slug) ->
Words = begin
_pipe = Slug,
_pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<" "/utf8>>),
gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<" "/utf8>>)
end,
case string:length(Words) of
0 ->
<<"Page"/utf8>>;
_ ->
<<(string:uppercase(gleam@string:slice(Words, 0, 1)))/binary,
(gleam@string:drop_start(Words, 1))/binary>>
end.
-file("src/tale/content.gleam", 283).
-spec fallback_title(binary()) -> binary().
fallback_title(Relative) ->
Stem = begin
_pipe = Relative,
_pipe@1 = strip_extension(_pipe),
_pipe@2 = gleam@string:split(_pipe@1, <<"/"/utf8>>),
_pipe@3 = lists:reverse(_pipe@2),
_pipe@4 = gleam@list:first(_pipe@3),
gleam@result:unwrap(_pipe@4, <<"Page"/utf8>>)
end,
capitalize_slug(Stem).
-file("src/tale/content.gleam", 137).
?DOC(" Parsing Page metadata\n").
-spec parse_page_metadata(binary(), gleam@option:option(binary())) -> {ok,
page_frontmatter()} |
{error, binary()}.
parse_page_metadata(Relative, Raw) ->
Defaults = {page_frontmatter,
fallback_title(Relative),
<<"Page description"/utf8>>,
infer_layout(Relative),
none,
false,
[],
none},
case Raw of
none ->
{ok, Defaults};
{some, Text} ->
gleam@result:'try'(
begin
_pipe = tom:parse(Text),
gleam@result:map_error(
_pipe,
fun(Err) ->
<<<<<<"Unable to parse frontmatter in "/utf8,
Relative/binary>>/binary,
": "/utf8>>/binary,
(tale@util:describe_toml_error(Err))/binary>>
end
)
end,
fun(Doc) ->
{ok,
{page_frontmatter,
tale@util:get_string_or(
Doc,
[<<"title"/utf8>>],
erlang:element(2, Defaults)
),
tale@util:get_string_or(
Doc,
[<<"description"/utf8>>],
erlang:element(3, Defaults)
),
tale@util:get_string_or(
Doc,
[<<"layout"/utf8>>],
erlang:element(4, Defaults)
),
tale@util:optional_string(
tom:get_string(Doc, [<<"date"/utf8>>])
),
tale@util:get_bool_or(
Doc,
[<<"draft"/utf8>>],
erlang:element(6, Defaults)
),
tale@util:get_string_list_or(
Doc,
[<<"tags"/utf8>>],
erlang:element(7, Defaults)
),
tale@util:optional_string(
tom:get_string(Doc, [<<"author"/utf8>>])
)}}
end
)
end.
-file("src/tale/content.gleam", 316).
-spec fallback_slug(binary()) -> binary().
fallback_slug(Relative) ->
_pipe = Relative,
_pipe@1 = strip_extension(_pipe),
_pipe@2 = gleam@string:split(_pipe@1, <<"/"/utf8>>),
_pipe@3 = gleam@list:filter(
_pipe@2,
fun(Segment) ->
(Segment /= <<""/utf8>>) andalso (Segment /= <<"_index"/utf8>>)
end
),
_pipe@4 = gleam@list:last(_pipe@3),
_pipe@5 = gleam@result:unwrap(_pipe@4, <<"page"/utf8>>),
tale@util:slugify(_pipe@5).
-file("src/tale/content.gleam", 309).
-spec slug_from_title(binary(), binary()) -> binary().
slug_from_title(Relative, Title) ->
case tale@util:slugify(Title) of
<<""/utf8>> ->
fallback_slug(Relative);
Slug ->
Slug
end.
-file("src/tale/content.gleam", 326).
-spec segments_without_extension(binary()) -> list(binary()).
segments_without_extension(Relative) ->
_pipe = Relative,
_pipe@1 = strip_extension(_pipe),
_pipe@2 = gleam@string:split(_pipe@1, <<"/"/utf8>>),
gleam@list:filter(_pipe@2, fun(Segment) -> Segment /= <<""/utf8>> end).
-file("src/tale/content.gleam", 333).
-spec drop_last(list(binary())) -> list(binary()).
drop_last(List_) ->
case List_ of
[] ->
[];
[_] ->
[];
[First | Rest] ->
[First | drop_last(Rest)]
end.
-file("src/tale/content.gleam", 341).
-spec parent_index_path(list(binary())) -> binary().
parent_index_path(Parents) ->
case Parents of
[] ->
<<"index.html"/utf8>>;
_ ->
<<(gleam@string:join(Parents, <<"/"/utf8>>))/binary,
"/index.html"/utf8>>
end.
-file("src/tale/content.gleam", 348).
-spec build_path(list(binary()), binary()) -> binary().
build_path(Parents, Final) ->
case Parents of
[] ->
Final;
_ ->
<<<<(gleam@string:join(Parents, <<"/"/utf8>>))/binary, "/"/utf8>>/binary,
Final/binary>>
end.
-file("src/tale/content.gleam", 355).
-spec slug_or_fallback(binary(), binary()) -> binary().
slug_or_fallback(Slug, Fallback) ->
case Slug of
<<""/utf8>> ->
tale@util:slugify(Fallback);
Other ->
Other
end.
-file("src/tale/content.gleam", 190).
-spec output_path_for(binary(), binary()) -> binary().
output_path_for(Relative, Slug) ->
Segments = segments_without_extension(Relative),
case Segments of
[] ->
<<"index.html"/utf8>>;
Segs ->
Last = begin
_pipe = gleam@list:last(Segs),
gleam@result:unwrap(_pipe, <<"index"/utf8>>)
end,
Parents = drop_last(Segs),
case Last of
<<"_index"/utf8>> ->
parent_index_path(Parents);
Other ->
Final = slug_or_fallback(Slug, Other),
build_path(Parents, <<Final/binary, "/index.html"/utf8>>)
end
end.
-file("src/tale/content.gleam", 362).
-spec path_from_segments(list(binary())) -> binary().
path_from_segments(Segments) ->
case Segments of
[] ->
<<"/"/utf8>>;
_ ->
<<"/"/utf8, (gleam@string:join(Segments, <<"/"/utf8>>))/binary>>
end.
-file("src/tale/content.gleam", 236).
-spec permalink_for_path(binary(), binary()) -> binary().
permalink_for_path(Relative, Slug) ->
Segments = segments_without_extension(Relative),
case Segments of
[] ->
<<"/"/utf8>>;
Segs ->
Last = begin
_pipe = gleam@list:last(Segs),
gleam@result:unwrap(_pipe, <<""/utf8>>)
end,
Parents = drop_last(Segs),
case Last of
<<"_index"/utf8>> ->
path_from_segments(Parents);
Other ->
Final = slug_or_fallback(Slug, Other),
path_from_segments(lists:append(Parents, [Final]))
end
end.
-file("src/tale/content.gleam", 254).
-spec permalink_from_output(binary()) -> binary().
permalink_from_output(Output_rel) ->
Trimmed = case gleam_stdlib:string_ends_with(Output_rel, <<".html"/utf8>>) of
true ->
gleam@string:drop_end(Output_rel, 5);
false ->
Output_rel
end,
Segments = begin
_pipe = Trimmed,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
gleam@list:filter(_pipe@1, fun(S) -> S /= <<""/utf8>> end)
end,
case Segments of
[] ->
<<"/"/utf8>>;
Segs ->
Last = begin
_pipe@2 = gleam@list:last(Segs),
gleam@result:unwrap(_pipe@2, <<""/utf8>>)
end,
Parents = drop_last(Segs),
case Last of
<<"index"/utf8>> ->
case Parents of
[] ->
<<"/"/utf8>>;
_ ->
path_from_segments(Parents)
end;
Other ->
path_from_segments(lists:append(Parents, [Other]))
end
end.
-file("src/tale/content.gleam", 369).
-spec is_post_page(page_data()) -> boolean().
is_post_page(Page) ->
gleam_stdlib:string_starts_with(erlang:element(2, Page), <<"posts/"/utf8>>).
-file("src/tale/content.gleam", 373).
-spec is_list_layout(page_data()) -> boolean().
is_list_layout(Page) ->
(erlang:element(6, Page) =:= <<"home"/utf8>>) orelse (erlang:element(
6,
Page
)
=:= <<"term"/utf8>>).
-file("src/tale/content.gleam", 377).
-spec with_output_path(page_data(), binary(), binary()) -> page_data().
with_output_path(Page, Root, Output_rel) ->
{page_data,
erlang:element(2, Page),
Output_rel,
<<<<Root/binary, "/"/utf8>>/binary, Output_rel/binary>>,
permalink_from_output(Output_rel),
erlang:element(6, Page),
erlang:element(7, Page),
erlang:element(8, Page)}.
-file("src/tale/content.gleam", 393).
-spec render_markdown(binary()) -> binary().
render_markdown(Markdown) ->
Options = begin
_pipe = mork:configure(),
mork:extended(_pipe, true)
end,
_pipe@1 = mork:parse_with_options(Options, Markdown),
mork:to_html(_pipe@1).
-file("src/tale/content.gleam", 91).
?DOC(" Load page\n").
-spec load_page(binary(), binary(), binary(), binary()) -> {ok, page_data()} |
{error, binary()}.
load_page(Root, Content_dir, Default_author, Path) ->
gleam@result:'try'(
begin
_pipe = simplifile:read(Path),
gleam@result:map_error(
_pipe,
fun(Err) ->
<<<<<<"Unable to read "/utf8, Path/binary>>/binary,
": "/utf8>>/binary,
(simplifile:describe_error(Err))/binary>>
end
)
end,
fun(Contents) ->
{extracted, Fm_text, Body} = frontmatter:extract(Contents),
Relative = relative_content_path(Path, Content_dir),
gleam@result:'try'(
parse_page_metadata(Relative, Fm_text),
fun(Meta) ->
Body_html = render_markdown(Body),
Slug = slug_from_title(Relative, erlang:element(2, Meta)),
Output_rel = output_path_for(Relative, Slug),
Output_abs = <<<<Root/binary, "/"/utf8>>/binary,
Output_rel/binary>>,
Author = gleam@option:unwrap(
erlang:element(8, Meta),
Default_author
),
Permalink = permalink_for_path(Relative, Slug),
{ok,
{page_data,
Relative,
Output_rel,
Output_abs,
Permalink,
erlang:element(4, Meta),
{page_metadata,
erlang:element(2, Meta),
erlang:element(3, Meta),
erlang:element(5, Meta),
erlang:element(6, Meta),
erlang:element(7, Meta),
Author,
Slug},
Body_html}}
end
)
end
).
-file("src/tale/content.gleam", 74).
?DOC(" Loads page list\n").
-spec load_page_list(
binary(),
binary(),
binary(),
list(binary()),
list(page_data())
) -> {ok, list(page_data())} | {error, binary()}.
load_page_list(Root, Content_dir, Default_author, Files, Acc) ->
case Files of
[] ->
{ok, lists:reverse(Acc)};
[File | Rest] ->
gleam@result:'try'(
load_page(Root, Content_dir, Default_author, File),
fun(Page) ->
load_page_list(
Root,
Content_dir,
Default_author,
Rest,
[Page | Acc]
)
end
)
end.
-file("src/tale/content.gleam", 54).
?DOC(" Load pages\n").
-spec load_pages(binary(), binary(), binary()) -> {ok, list(page_data())} |
{error, binary()}.
load_pages(Root, Content_dir, Default_author) ->
gleam@result:'try'(
begin
_pipe = simplifile:get_files(Content_dir),
gleam@result:map_error(
_pipe,
fun(Err) ->
<<"Unable to list content: "/utf8,
(simplifile:describe_error(Err))/binary>>
end
)
end,
fun(Files) ->
Md_files = begin
_pipe@1 = Files,
gleam@list:filter(
_pipe@1,
fun(Path) ->
gleam_stdlib:string_ends_with(Path, <<".md"/utf8>>)
end
)
end,
load_page_list(Root, Content_dir, Default_author, Md_files, [])
end
).