[3] | 1 | let ext = ".gmi"
|
---|
| 2 |
|
---|
| 3 | module GeminiConverter = struct
|
---|
| 4 | include Converter.Gemini
|
---|
| 5 | let angled_uri u a = if String.sub u 0 10 <> "urn:txtid:" then
|
---|
| 6 | angled_uri u a else angled_uri (String.(sub u 10 (length u - 10)) ^ ext) a
|
---|
| 7 | end
|
---|
| 8 |
|
---|
| 9 | let page _conversion text =
|
---|
[2] | 10 | let open Logarion.Text in
|
---|
| 11 | "# " ^ text.title
|
---|
| 12 | ^ "\nAuthors: " ^ Logarion.Person.Set.to_string text.authors
|
---|
| 13 | ^ "\nDate: " ^ Logarion.Date.(pretty_date @@ listing text.date)
|
---|
[3] | 14 | ^ let module T = Parsers.Plain_text.Make (GeminiConverter) in
|
---|
[2] | 15 | "\n" ^ T.of_string text.body ""
|
---|
| 16 |
|
---|
| 17 | let date_index title meta_list =
|
---|
| 18 | List.fold_left
|
---|
| 19 | (fun a m ->
|
---|
| 20 | a ^ "=> " ^ Logarion.Text.short_id m ^ ".gmi " ^
|
---|
| 21 | Logarion.(Date.(pretty_date (listing m.date)) ^ " " ^ m.title) ^ "\n")
|
---|
| 22 | ("# " ^ title ^ "\n\n## Posts by date\n\n") meta_list
|
---|
| 23 |
|
---|
| 24 | let to_dated_links ?(limit) meta_list =
|
---|
| 25 | let meta_list = match limit with
|
---|
| 26 | | None -> meta_list
|
---|
| 27 | | Some limit->
|
---|
| 28 | let rec reduced acc i = function
|
---|
| 29 | | [] -> acc
|
---|
| 30 | | h::t -> if i < limit then reduced (h::acc) (i+1) t else acc in
|
---|
| 31 | List.rev @@ reduced [] 0 meta_list
|
---|
| 32 | in
|
---|
| 33 | List.fold_left
|
---|
| 34 | (fun a m ->
|
---|
| 35 | a
|
---|
| 36 | ^ "=> " ^ Logarion.Text.short_id m ^ ".gmi "
|
---|
| 37 | ^ Logarion.(Date.(pretty_date (listing m.Text.date))) ^ " "
|
---|
| 38 | ^ m.Logarion.Text.title ^ "\n")
|
---|
| 39 | "" meta_list
|
---|
| 40 |
|
---|
[3] | 41 | let topic_link root topic =
|
---|
| 42 | let replaced_space = String.map (function ' '->'+' | x->x) in
|
---|
| 43 | "=> index." ^ replaced_space root ^ ".gmi " ^ String.capitalize_ascii topic ^ "\n"
|
---|
[2] | 44 |
|
---|
| 45 | let text_item path meta =
|
---|
| 46 | let open Logarion in
|
---|
| 47 | "=> " ^ path ^ Text.short_id meta ^ ".gmi "
|
---|
| 48 | ^ Date.(pretty_date (listing meta.Text.date)) ^ " "
|
---|
| 49 | ^ meta.Text.title ^ "\n"
|
---|
| 50 |
|
---|
| 51 | let listing_index topic_map topic_roots path metas =
|
---|
| 52 | let rec item_group topics =
|
---|
| 53 | List.fold_left (fun acc topic -> acc ^ sub_groups topic ^ items topic) "" topics
|
---|
| 54 | and sub_groups topic = match Logarion.Topic_set.Map.find_opt topic topic_map with
|
---|
| 55 | | None -> ""
|
---|
| 56 | | Some (_, subtopics) -> item_group (Logarion.String_set.elements subtopics)
|
---|
| 57 | and items topic =
|
---|
| 58 | let items =
|
---|
| 59 | let open Logarion in
|
---|
| 60 | List.fold_left
|
---|
| 61 | (fun a e ->
|
---|
| 62 | if String_set.mem topic (String_set.map (Logarion.Topic_set.topic) (Text.set "Topics" e))
|
---|
| 63 | then text_item path e ^ a else a) "" metas in
|
---|
| 64 | match items with
|
---|
| 65 | | "" -> ""
|
---|
| 66 | | x -> "## " ^ String.capitalize_ascii topic ^ "\n\n" ^ x
|
---|
| 67 | in
|
---|
| 68 | item_group topic_roots
|
---|
| 69 |
|
---|
| 70 | let fold_topic_roots topic_roots =
|
---|
| 71 | let list_item root t = topic_link root t in
|
---|
| 72 | List.fold_left (fun a x -> a ^ list_item x x) "" (List.rev topic_roots)
|
---|
| 73 |
|
---|
[15] | 74 | let topic_main_index r title topic_roots metas =
|
---|
| 75 | "# " ^ title ^ "\n\n"
|
---|
[2] | 76 | ^ (if topic_roots <> [] then ("## Main topics\n\n" ^ fold_topic_roots topic_roots) else "")
|
---|
| 77 | ^ "\n## Latest\n\n" ^ to_dated_links ~limit:10 metas
|
---|
[15] | 78 | ^ "\n=> index.date.gmi More by date\n\n"
|
---|
| 79 | ^ let peers = Logarion.Store.KV.find "Peers" r.Conversion.kv in
|
---|
| 80 | if peers = "" then "" else
|
---|
| 81 | List.fold_left (fun a s -> Printf.sprintf "%s=> %s\n" a s) "## Peers\n\n"
|
---|
| 82 | (Str.split (Str.regexp ";\n") peers)
|
---|
[2] | 83 |
|
---|
| 84 | let topic_sub_index title topic_map topic_root metas =
|
---|
| 85 | "# " ^ title ^ "\n\n"
|
---|
| 86 | ^ listing_index topic_map [topic_root] "" metas
|
---|
[3] | 87 |
|
---|
| 88 | let indices r =
|
---|
| 89 | let open Logarion in
|
---|
| 90 | let file name = File_store.file (Filename.concat r.Conversion.dir name) in
|
---|
| 91 | let index_name = try Store.KV.find "Gemini-index" r.kv with Not_found -> "index.gmi" in
|
---|
| 92 | let title = try Store.KV.find "Title" r.Conversion.kv with Not_found -> "" in
|
---|
[19] | 93 | if index_name <> "" then file index_name (topic_main_index r title r.topic_roots r.texts);
|
---|
[3] | 94 | file "index.date.gmi" (date_index title r.texts);
|
---|
| 95 | List.iter
|
---|
| 96 | (fun topic -> file ("index." ^ topic ^ ".gmi")
|
---|
| 97 | (topic_sub_index title r.topics topic r.texts))
|
---|
[19] | 98 | r.topic_roots
|
---|
[3] | 99 |
|
---|
[19] | 100 | let converter = Conversion.{ ext; page = Some page; indices = Some indices}
|
---|