-module(tale@build). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/tale/build.gleam"). -export([resolved_public_root/0, build_site/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. -file("src/tale/build.gleam", 54). ?DOC(" Resolves public root function\n"). -spec resolved_public_root() -> {ok, binary()} | {error, binary()}. resolved_public_root() -> gleam@result:'try'( tale@config:load(), fun(Site_config) -> {ok, tale@config:public_root(Site_config)} end ). -file("src/tale/build.gleam", 209). ?DOC(" Sorting posts per date (From newer to older)\n"). -spec sort_posts_by_date(list(tale@content:page_data())) -> list(tale@content:page_data()). sort_posts_by_date(Posts) -> _pipe = Posts, gleam@list:sort( _pipe, fun(A, B) -> A_date = gleam@option:unwrap( erlang:element(4, erlang:element(7, A)), <<"0000-00-00"/utf8>> ), B_date = gleam@option:unwrap( erlang:element(4, erlang:element(7, B)), <<"0000-00-00"/utf8>> ), gleam@string:compare(B_date, A_date) end ). -file("src/tale/build.gleam", 253). ?DOC(" Paginated output\n"). -spec paginated_output_rel(binary(), integer()) -> binary(). paginated_output_rel(Base, Index) -> Suffix = <<<<"page/"/utf8, (erlang:integer_to_binary(Index))/binary>>/binary, "/index.html"/utf8>>, case tale@paths:parent_directory(Base) of none -> Suffix; {some, Dir} -> <<<>/binary, Suffix/binary>> end. -file("src/tale/build.gleam", 220). ?DOC(" Previous link(page) to pagination\n"). -spec previous_link(tale@content:page_data(), integer()) -> gleam@option:option(binary()). previous_link(Base_page, Index) -> case Index of 1 -> none; 2 -> {some, erlang:element(5, Base_page)}; _ -> Rel = paginated_output_rel(erlang:element(3, Base_page), Index - 1), {some, tale@content:permalink_from_output(Rel)} end. -file("src/tale/build.gleam", 232). ?DOC(" Next link(page) to pagination\n"). -spec next_link(tale@content:page_data(), integer(), integer()) -> gleam@option:option(binary()). next_link(Base_page, Index, Total_pages) -> case Index >= Total_pages of true -> none; false -> Target = Index + 1, case Target of 1 -> {some, erlang:element(5, Base_page)}; _ -> Rel = paginated_output_rel( erlang:element(3, Base_page), Target ), {some, tale@content:permalink_from_output(Rel)} end end. -file("src/tale/build.gleam", 153). ?DOC(" Paginate page jobs function.\n"). -spec paginate_loop( list(list(tale@content:page_data())), integer(), integer(), integer(), tale@content:page_data(), list(tale@renderer:tag_context()), binary(), gleam@option:option(tale@renderer:tag_context()), list(tale@renderer:render_job()) ) -> list(tale@renderer:render_job()). paginate_loop( Chunks, Index, Per_page, Total_pages, Base_page, Site_tags, Root, Current_tag, Acc ) -> case Chunks of [] -> lists:reverse(Acc); [Chunk | Rest] -> Paged_page = case Index of 1 -> Base_page; _ -> Rel = paginated_output_rel( erlang:element(3, Base_page), Index ), tale@content:with_output_path(Base_page, Root, Rel) end, Pagination_info = {some, {pagination_info, Index, Total_pages, Per_page, previous_link(Base_page, Index), next_link(Base_page, Index, Total_pages)}}, Job = {render_job, Paged_page, Chunk, Pagination_info, Current_tag, Site_tags}, paginate_loop( Rest, Index + 1, Per_page, Total_pages, Base_page, Site_tags, Root, Current_tag, [Job | Acc] ) end. -file("src/tale/build.gleam", 131). ?DOC(" Function responsible for the pagination\n"). -spec paginate_page_jobs( tale@content:page_data(), list(list(tale@content:page_data())), integer(), integer(), list(tale@renderer:tag_context()), binary() ) -> list(tale@renderer:render_job()). paginate_page_jobs(Page, Chunks, Per_page, Total_pages, Site_tags, Root) -> paginate_loop( Chunks, 1, Per_page, Total_pages, Page, Site_tags, Root, none, [] ). -file("src/tale/build.gleam", 262). ?DOC(" Pagination size\n"). -spec pagination_size(gleam@option:option(integer()), integer()) -> integer(). pagination_size(Setting, Total_posts) -> Fallback = case Total_posts of 0 -> 1; Other -> Other end, case Setting of {some, Value} when Value > 0 -> Value; _ -> Fallback end. -file("src/tale/build.gleam", 285). -spec paginate_posts_loop( list(tale@content:page_data()), integer(), list(list(tale@content:page_data())) ) -> list(list(tale@content:page_data())). paginate_posts_loop(Posts, Per_page, Acc) -> case Posts of [] -> lists:reverse(Acc); _ -> Chunk = gleam@list:take(Posts, Per_page), Remaining = gleam@list:drop(Posts, Per_page), paginate_posts_loop(Remaining, Per_page, [Chunk | Acc]) end. -file("src/tale/build.gleam", 275). ?DOC(" Paginate posts\n"). -spec paginate_posts(list(tale@content:page_data()), integer()) -> list(list(tale@content:page_data())). paginate_posts(Posts, Per_page) -> case Posts of [] -> [Posts]; _ -> paginate_posts_loop(Posts, Per_page, []) end. -file("src/tale/build.gleam", 328). ?DOC(" Tags permalink\n"). -spec tag_permalink(binary()) -> binary(). tag_permalink(Slug) -> <<<<"/tags/"/utf8, Slug/binary>>/binary, "/"/utf8>>. -file("src/tale/build.gleam", 301). ?DOC(" Build tags page\n"). -spec build_site_tags(list(tale@content:page_data())) -> list(tale@renderer:tag_context()). build_site_tags(Posts) -> _pipe = Posts, _pipe@1 = gleam@list:fold( _pipe, maps:new(), fun(Acc, Page) -> gleam@list:fold( erlang:element(6, erlang:element(7, Page)), Acc, fun(Tags_acc, Tag) -> gleam@dict:upsert( Tags_acc, Tag, fun(Existing) -> Posts_list = case Existing of none -> []; {some, Current} -> Current end, [Page | Posts_list] end ) end ) end ), _pipe@2 = maps:to_list(_pipe@1), gleam@list:map( _pipe@2, fun(Entry) -> {Tag@1, Tagged_posts} = Entry, Slug = tale@util:slugify(Tag@1), {tag_context, Tag@1, Slug, tag_permalink(Slug), lists:reverse(Tagged_posts)} end ). -file("src/tale/build.gleam", 332). -spec tag_output_rel(binary()) -> binary(). tag_output_rel(Slug) -> <<<<"tags/"/utf8, Slug/binary>>/binary, "/index.html"/utf8>>. -file("src/tale/build.gleam", 337). ?DOC(" Tag page data\n"). -spec tag_page_data(tale@renderer:tag_context(), binary(), binary()) -> tale@content:page_data(). tag_page_data(Tag, Root, Default_author) -> Output_rel = tag_output_rel(erlang:element(3, Tag)), {page_data, <<<<"tags/"/utf8, (erlang:element(3, Tag))/binary>>/binary, ".generated"/utf8>>, Output_rel, <<<>/binary, Output_rel/binary>>, erlang:element(4, Tag), <<"term"/utf8>>, {page_metadata, <<"Tag: "/utf8, (erlang:element(2, Tag))/binary>>, <<"Posts tagged "/utf8, (erlang:element(2, Tag))/binary>>, none, false, [], Default_author, erlang:element(3, Tag)}, <<""/utf8>>}. -file("src/tale/build.gleam", 104). ?DOC(" Build tags jobs function\n"). -spec build_tag_jobs( list(tale@renderer:tag_context()), integer(), list(tale@renderer:tag_context()), binary(), binary() ) -> list(tale@renderer:render_job()). build_tag_jobs(Tags, Per_page, Site_tags, Root, Default_author) -> _pipe = Tags, gleam@list:flat_map( _pipe, fun(Tag) -> Tag_page = tag_page_data(Tag, Root, Default_author), Tag_chunks = paginate_posts(erlang:element(5, Tag), Per_page), Total_pages = erlang:length(Tag_chunks), paginate_loop( Tag_chunks, 1, Per_page, Total_pages, Tag_page, Site_tags, Root, {some, Tag}, [] ) end ). -file("src/tale/build.gleam", 380). ?DOC(" Tag overview page function.\n"). -spec tag_overview_page(binary(), binary()) -> tale@content:page_data(). tag_overview_page(Root, Default_author) -> Output_rel = <<"tags/index.html"/utf8>>, {page_data, <<"tags/index.generated"/utf8>>, Output_rel, <<<>/binary, Output_rel/binary>>, <<"/tags/"/utf8>>, <<"taxonomy"/utf8>>, {page_metadata, <<"All tags"/utf8>>, <<"Browse every tag used on the site"/utf8>>, none, false, [], Default_author, <<"tags"/utf8>>}, <<""/utf8>>}. -file("src/tale/build.gleam", 363). ?DOC(" Tag overview job function.\n"). -spec tag_overview_job( list(tale@renderer:tag_context()), tale@config:site_config(), binary() ) -> list(tale@renderer:render_job()). tag_overview_job(Site_tags, Site_config, Root) -> [{render_job, tag_overview_page(Root, erlang:element(5, Site_config)), [], none, none, Site_tags}]. -file("src/tale/build.gleam", 60). ?DOC(" Plan render jobs function\n"). -spec plan_render_jobs( list(tale@content:page_data()), list(tale@content:page_data()), list(tale@renderer:tag_context()), tale@config:site_config(), binary() ) -> list(tale@renderer:render_job()). plan_render_jobs(Pages, Posts, Site_tags, Site_config, Root) -> Per_page = pagination_size( erlang:element(9, Site_config), erlang:length(Posts) ), Chunks = paginate_posts(Posts, Per_page), Total_pages = erlang:length(Chunks), Page_jobs = begin _pipe = Pages, gleam@list:flat_map( _pipe, fun(Page) -> case tale@content:is_list_layout(Page) of true -> paginate_page_jobs( Page, Chunks, Per_page, Total_pages, Site_tags, Root ); false -> [{render_job, Page, [], none, none, Site_tags}] end end ) end, Tag_jobs = build_tag_jobs( Site_tags, Per_page, Site_tags, Root, erlang:element(5, Site_config) ), Jobs = lists:append(Page_jobs, Tag_jobs), lists:append(Jobs, tag_overview_job(Site_tags, Site_config, Root)). -file("src/tale/build.gleam", 412). ?DOC(" Clean public dir function.\n"). -spec clean_public_dir(binary()) -> {ok, nil} | {error, binary()}. clean_public_dir(Root) -> case simplifile_erl:delete(Root) of {ok, nil} -> {ok, nil}; {error, enoent} -> {ok, nil}; {error, Err} -> {error, <<"Unable to clean public directory: "/utf8, (simplifile:describe_error(Err))/binary>>} end. -file("src/tale/build.gleam", 402). ?DOC(" Reset public dir function.\n"). -spec reset_public_dir(binary()) -> {ok, nil} | {error, binary()}. reset_public_dir(Root) -> gleam@result:'try'( clean_public_dir(Root), fun(_) -> _pipe = simplifile:create_directory_all(Root), gleam@result:map_error( _pipe, fun(Err) -> <<"Unable to create public directory: "/utf8, (simplifile:describe_error(Err))/binary>> end ) end ). -file("src/tale/build.gleam", 424). ?DOC(" Copy assets function.\n"). -spec copy_assets(binary(), binary()) -> {ok, binary()} | {error, binary()}. copy_assets(Root, Assets_dir) -> case simplifile_erl:is_directory(Assets_dir) of {ok, true} -> Dest = <>, _pipe = simplifile:copy_directory(Assets_dir, Dest), _pipe@1 = gleam@result:map( _pipe, fun(_) -> <<"Copied assets to "/utf8, Dest/binary>> end ), gleam@result:map_error( _pipe@1, fun(Err) -> <<"Unable to copy assets: "/utf8, (simplifile:describe_error(Err))/binary>> end ); _ -> {ok, <<"No assets directory to copy"/utf8>>} end. -file("src/tale/build.gleam", 439). ?DOC(" Copy static function.\n"). -spec copy_static(binary(), binary()) -> {ok, binary()} | {error, binary()}. copy_static(Root, Static_dir) -> case simplifile_erl:is_directory(Static_dir) of {ok, true} -> _pipe = simplifile:copy_directory(Static_dir, Root), _pipe@1 = gleam@result:map( _pipe, fun(_) -> <<"Copied static files from "/utf8, Static_dir/binary>> end ), gleam@result:map_error( _pipe@1, fun(Err) -> <<"Unable to copy static files: "/utf8, (simplifile:describe_error(Err))/binary>> end ); _ -> {ok, <<"No static directory to copy"/utf8>>} end. -file("src/tale/build.gleam", 17). ?DOC(" Build site function\n"). -spec build_site() -> {ok, list(binary())} | {error, binary()}. build_site() -> gleam@result:'try'( tale@config:load(), fun(Site_config) -> Root = tale@config:public_root(Site_config), Paths = tale@config:site_paths(Site_config), gleam@result:'try'( tale@content:load_pages( Root, erlang:element(2, Paths), erlang:element(5, Site_config) ), fun(Pages) -> gleam@result:'try'( tale@renderer:load_partials(erlang:element(4, Paths)), fun(Partials) -> gleam@result:'try'( reset_public_dir(Root), fun(_) -> gleam@result:'try'( copy_assets( Root, erlang:element(5, Paths) ), fun(Assets_msg) -> gleam@result:'try'( copy_static( Root, erlang:element(6, Paths) ), fun(Static_msg) -> Posts = begin _pipe = Pages, _pipe@1 = gleam@list:filter( _pipe, fun tale@content:is_post_page/1 ), _pipe@2 = gleam@list:filter( _pipe@1, fun(Page) -> erlang:element( 5, erlang:element( 7, Page ) ) =:= false end ), sort_posts_by_date( _pipe@2 ) end, Site_tags = build_site_tags( Posts ), Jobs = plan_render_jobs( Pages, Posts, Site_tags, Site_config, Root ), gleam@result:'try'( tale@renderer:render_jobs( Jobs, Site_config, Partials, erlang:element( 3, Paths ) ), fun(Rendered) -> {ok, [Assets_msg, Static_msg | Rendered]} end ) end ) end ) end ) end ) end ) end ).