blog.robur.coop/src/task.ml

108 lines
3.3 KiB
OCaml

open Yocaml
module Metaformat = Yocaml_yaml
module Markup = Yocaml_cmark
module Template = Yocaml_jingoo
let css_target target = "css" |> into target
let javascript_target target = "js" |> into target
let images_target target = "images" |> into target
let template file = add_extension file "html" |> into "templates"
let article_template = template "article"
let layout_template = template "layout"
let list_template = template "list_articles"
let article_target file target = Model.article_path file |> into target
let binary_update = Build.watch Sys.argv.(0)
let index_html target = "index.html" |> into target
let index_md = "index.md" |> into "pages"
let rss_feed target = "feed.xml" |> into target
let tag_file tag target = Model.tag_path tag |> into target
let tag_template = template "tag"
let move_css target =
process_files
[ "css" ]
File.is_css
(Build.copy_file ~into:(css_target target))
;;
let move_javascript target =
process_files
[ "js" ]
File.is_javascript
(Build.copy_file ~into:(javascript_target target))
;;
let move_images target =
process_files
[ "images" ]
File.is_image
(Build.copy_file ~into:(images_target target))
;;
let process_articles target =
process_files [ "articles" ] File.is_markdown (fun article_file ->
let open Build in
create_file
(article_target article_file target)
(binary_update
>>> Metaformat.read_file_with_metadata
(module Model.Article)
article_file
>>> Markup.content_to_html ~strict:false ()
>>> Template.apply_as_template (module Model.Article) article_template
>>> Template.apply_as_template (module Model.Article) layout_template
>>^ Stdlib.snd))
;;
let merge_with_page ((meta, content), articles) =
let title = Metadata.Page.title meta in
let description = Metadata.Page.description meta in
Model.Articles.make ?title ?description articles, content
;;
let generate_feed target =
let open Build in
let* articles_arrow =
Collection.Articles.get_all (module Metaformat) "articles"
in
create_file
(rss_feed target)
(binary_update >>> articles_arrow >>^ Feed.make >>^ Rss.Channel.to_rss)
;;
let generate_tags target =
let* deps, tags = Collection.Tags.compute (module Metaformat) "articles" in
let tags_string = List.map (fun (i, s) -> i, List.length s) tags in
let mk_meta tag articles () = Model.Tag.make tag articles tags_string, "" in
List.fold_left
(fun program (tag, articles) ->
let open Build in
program
>> create_file
(tag_file tag target)
(init deps
>>> binary_update
>>^ mk_meta tag articles
>>> Template.apply_as_template (module Model.Tag) tag_template
>>> Template.apply_as_template (module Model.Tag) layout_template
>>^ Stdlib.snd))
(return ())
tags
;;
let generate_index target =
let open Build in
let* articles_arrow =
Collection.Articles.get_all (module Metaformat) "articles"
in
create_file
(index_html target)
(binary_update
>>> Metaformat.read_file_with_metadata (module Metadata.Page) index_md
>>> Markup.content_to_html ~strict:false ()
>>> articles_arrow
>>^ merge_with_page
>>> Template.apply_as_template (module Model.Articles) list_template
>>> Template.apply_as_template (module Model.Articles) layout_template
>>^ Stdlib.snd)
;;