reynir.dk/src/task.ml

103 lines
3.3 KiB
OCaml

open Yocaml
module Metaformat = Yocaml_yaml
module Markup = Yocaml_markdown
module Template = Yocaml_jingoo
let css_target target = "css" |> into target
let images_target target = "images" |> into target
let js_target target = "js" |> into target
let audio_target target = "audio" |> into target
let index_html target = "index.html" |> into target
let about_html target = "about.html" |> into target
let contact_html target = "contact.html" |> into target
let archive_html target = "archive.html" |> into target
let article_target file target = Model.article_path file |> into target
let move_css target =
process_files
[ "css" ]
File.is_css
(Build.copy_file ~into:(css_target target))
let move_images target =
process_files
[ "images" ]
File.is_image
(Build.copy_file ~into:(images_target target))
let move_js target =
process_files
[ "js" ]
File.is_javascript
(Build.copy_file ~into:(js_target target))
let move_audio target =
process_files
[ "audio" ]
(with_extension "ogg")
(Build.copy_file ~into:(audio_target target))
let with_layout (type a) (module M : Metadata.INJECTABLE with type t = a)
(read_model : (_, a) Build.t) page target =
let open Build in
let module M = Model.With_layout(M) in
let apply_template_from_string (v, content) =
let values = M.inject (module Template) v in
let content = Template.to_string ~strict:true values content in
(v, content)
in
create_file target
(watch Sys.argv.(0)
>>> Metaformat.read_file_with_metadata (module Model.Page) page
&&& read_model
>>^ (fun (({ Model.Page.title; head_extra }, content), v) ->
M.merge ~title ~head_extra v, content)
>>^ apply_template_from_string
>>> Markup.content_to_html ()
>>> Template.apply_as_template (module M) "templates/layout.html"
>>^ Stdlib.snd)
let process_articles target =
let open Build in
process_files [ "posts" ] File.is_markdown (fun article_file ->
create_file (article_target article_file target)
(Metaformat.read_file_with_metadata (module Model.Article) article_file
>>> Markup.content_to_html ()
>>> Template.apply_as_template (module Model.Article) "templates/article.html"
>>> Template.apply_as_template (module Model.Article) "templates/layout.html"
>>^ Stdlib.snd))
let articles =
let open Build in
collection
(read_child_files "posts" File.is_markdown)
(fun path ->
Metaformat.read_file_with_metadata (module Model.Article) path
>>^ fun (meta, _data) ->
(Model.article_path path, meta))
(fun articles () -> articles)
let generate_archive target =
let* articles = articles in
with_layout (module Model.Articles) articles "pages/archive.md" (archive_html target)
let page page_file target =
let open Build in
create_file target
(watch Sys.argv.(0)
>>> Metaformat.read_file_with_metadata (module Model.Page) page_file
>>> Markup.content_to_html ()
>>> Template.apply_as_template (module Model.Page) "templates/layout.html"
>>^ Stdlib.snd)
let generate_about target =
page "pages/about.md" (about_html target)
let generate_contact target =
page "pages/contact.md" (contact_html target)
let generate_index target =
let* articles = articles in
with_layout (module Model.Articles) articles "pages/index.md" (index_html target)