Begin unifying conf and pck code; inline CSS; optional CSS & Atom
git-svn-id: file:///srv/svn/repo/kosuzu/trunk@20 eb64cd80-c68d-6f47-b6a3-0ada418499da
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
open Logarion
|
open Logarion
|
||||||
type t = {
|
type t = {
|
||||||
id: string; dir: string;
|
id: string;
|
||||||
|
dir: string;
|
||||||
kv: string Store.KV.t;
|
kv: string Store.KV.t;
|
||||||
topic_roots: string list;
|
topic_roots: string list;
|
||||||
topics: (String_set.t * String_set.t) Topic_set.Map.t;
|
topics: (String_set.t * String_set.t) Topic_set.Map.t;
|
||||||
@@ -12,3 +13,11 @@ type fn_t = {
|
|||||||
page: (t -> Logarion.Text.t -> string) option;
|
page: (t -> Logarion.Text.t -> string) option;
|
||||||
indices: (t -> unit) option;
|
indices: (t -> unit) option;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let empty () = {
|
||||||
|
id = ""; dir = "";
|
||||||
|
kv = Store.KV.empty;
|
||||||
|
topic_roots = [];
|
||||||
|
topics = Topic_set.Map.empty;
|
||||||
|
texts = []
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
open Logarion
|
open Logarion
|
||||||
|
|
||||||
let is_older source dest = try
|
(*TODO: move to converters (style, feed checks)*)
|
||||||
Unix.((stat dest).st_mtime < (stat source).st_mtime) with _-> true
|
let is_older s d = try Unix.((stat d).st_mtime < (stat s).st_mtime) with _-> true
|
||||||
|
|
||||||
let convert cs r (text, files) = match Text.str "Content-Type" text with
|
let convert cs r (text, files) = match Text.str "Content-Type" text with
|
||||||
| "" | "text/plain" ->
|
| "" | "text/plain" ->
|
||||||
@@ -26,47 +26,52 @@ let converters types kv =
|
|||||||
let t = if List.(mem "all" n || mem "gmi-atom" n) then (Atom.converter "text/gemini")::t else t in
|
let t = if List.(mem "all" n || mem "gmi-atom" n) then (Atom.converter "text/gemini")::t else t in
|
||||||
t
|
t
|
||||||
|
|
||||||
let directory converters noindex dir id kv =
|
let directory converters noindex repo =
|
||||||
let empty = Topic_set.Map.empty in
|
|
||||||
let repo = Conversion.{ id; dir; kv; topic_roots = []; topics = empty; texts = [] } in
|
|
||||||
let fn (ts,ls,acc) ((elt,_) as r) =
|
let fn (ts,ls,acc) ((elt,_) as r) =
|
||||||
(Topic_set.to_map ts (Text.set "topics" elt)), elt::ls,
|
(Topic_set.to_map ts (Text.set "topics" elt)), elt::ls,
|
||||||
if convert converters repo r then acc+1 else acc in
|
if convert converters repo r then acc+1 else acc in
|
||||||
let topics, texts, count = File_store.(fold ~dir ~order:newest fn (empty,[],0)) in
|
let topics, texts, count =
|
||||||
let topic_roots = try List.rev @@ String_set.list_of_csv (Store.KV.find "Topics" kv)
|
File_store.(fold ~dir:repo.Conversion.dir ~order:newest fn (Topic_set.Map.empty,[],0)) in
|
||||||
|
let topic_roots = try List.rev @@ String_set.list_of_csv (Store.KV.find "Topics" repo.kv)
|
||||||
with Not_found -> Topic_set.roots topics in
|
with Not_found -> Topic_set.roots topics in
|
||||||
let repo = Conversion.{ repo with topic_roots; topics; texts } in
|
let repo = Conversion.{ repo with topic_roots; topics; texts } in
|
||||||
if not noindex then List.iter (fun c -> match c.Conversion.indices with None -> () | Some f -> f repo) converters;
|
if not noindex then List.iter (fun c -> match c.Conversion.indices with None -> () | Some f -> f repo) converters;
|
||||||
Printf.printf "Converted: %d Indexed: %d\n" count (List.length texts)
|
Printf.printf "Converted: %d Indexed: %d\n" count (List.length texts)
|
||||||
|
|
||||||
let at_path types noindex path =
|
let load_kv dir =
|
||||||
match path with "" -> prerr_endline "unspecified text file or directory"
|
let conf = Filename.concat dir ".convert.conf" in (* TODO: better name? *)
|
||||||
| dir when Sys.file_exists dir && Sys.is_directory dir ->
|
let kv = if Sys.file_exists conf then File_store.of_kv_file conf else Store.KV.empty in
|
||||||
let fname = Filename.concat dir "index.pck" in
|
let idx = Filename.concat dir "index.pck" in
|
||||||
(match Header_pack.of_string @@ File_store.to_string fname with
|
if not (Sys.file_exists idx) then kv else
|
||||||
| Error s -> prerr_endline s
|
match Header_pack.of_string @@ File_store.to_string (idx) with
|
||||||
|
| Error s -> prerr_endline s; kv
|
||||||
| Ok { info; peers; _ } ->
|
| Ok { info; peers; _ } ->
|
||||||
let kv = let f = Filename.concat dir ".convert.conf" in (* TODO: better place to store convert conf? *)
|
let kv = if Store.KV.mem "Id" kv then kv else Store.KV.add "Id" info.Header_pack.id kv in
|
||||||
if Sys.file_exists f then File_store.of_kv_file f else Store.KV.empty in
|
|
||||||
let kv = if Store.KV.mem "Title" kv then kv else Store.KV.add "Title" info.Header_pack.title kv in
|
let kv = if Store.KV.mem "Title" kv then kv else Store.KV.add "Title" info.Header_pack.title kv in
|
||||||
let kv = Store.KV.add "Locations" (String.concat ";\n" info.Header_pack.locations) kv in
|
let kv = Store.KV.add "Locations" (String.concat ";\n" info.Header_pack.locations) kv in
|
||||||
let kv = Store.KV.add "Peers" (String.concat ";\n" Header_pack.(to_str_list peers)) kv in
|
let kv = Store.KV.add "Peers" (String.concat ";\n" Header_pack.(to_str_list peers)) kv in
|
||||||
let cs = converters types kv in
|
kv
|
||||||
directory cs noindex dir info.Header_pack.id kv)
|
|
||||||
|
let at_path types noindex path = match path with
|
||||||
|
| "" -> prerr_endline "unspecified text file or directory"
|
||||||
| path when Sys.file_exists path ->
|
| path when Sys.file_exists path ->
|
||||||
let repo = Conversion.{
|
if Sys.is_directory path then (
|
||||||
id = ""; dir = ""; kv = Store.KV.empty; topic_roots = [];
|
let kv = load_kv path in
|
||||||
topics = Topic_set.Map.empty; texts = [] } in
|
let repo = { (Conversion.empty ()) with dir = path; kv } in
|
||||||
let cs = converters types repo.kv in
|
directory (converters types kv) noindex repo
|
||||||
(match File_store.to_text path with
|
) else (
|
||||||
| Ok text -> ignore @@ convert cs repo (text, [path])
|
match File_store.to_text path with
|
||||||
| Error s -> prerr_endline s)
|
| Error s -> prerr_endline s
|
||||||
|
| Ok text ->
|
||||||
|
let repo = { (Conversion.empty ()) with dir = ""; kv = load_kv "" } in
|
||||||
|
ignore @@ convert (converters types repo.kv) repo (text, [path])
|
||||||
|
)
|
||||||
| path -> Printf.eprintf "Path doesn't exist: %s" path
|
| path -> Printf.eprintf "Path doesn't exist: %s" path
|
||||||
|
|
||||||
open Cmdliner
|
open Cmdliner
|
||||||
let term =
|
let term =
|
||||||
let path = Arg.(value & pos 0 string "" & info [] ~docv:"path"
|
let path = Arg.(value & pos 0 string "" & info [] ~docv:"path"
|
||||||
~doc:"Text file or directory to convert. Ff directory is provided, it must contain an index.pck (see: txt index)") in
|
~doc:"Text file or directory to convert. If directory is provided, it must contain an index.pck (see: txt index)") in
|
||||||
let types = Arg.(value & opt string "all" & info ["t"; "type"] ~docv:"output type"
|
let types = Arg.(value & opt string "all" & info ["t"; "type"] ~docv:"output type"
|
||||||
~doc:"Convert to file type") in
|
~doc:"Convert to file type") in
|
||||||
let noindex = Arg.(value & flag & info ["noindex"]
|
let noindex = Arg.(value & flag & info ["noindex"]
|
||||||
|
|||||||
26
cli/html.ml
26
cli/html.ml
@@ -1,9 +1,9 @@
|
|||||||
type templates_t = { header: string option; footer: string option }
|
type templates_t = { header: string option; footer: string option }
|
||||||
type t = { templates : templates_t }
|
type t = { templates : templates_t; style : string }
|
||||||
|
|
||||||
let ext = ".htm"
|
let ext = ".htm"
|
||||||
let empty_templates = { header = None; footer = None }
|
let empty_templates = { header = None; footer = None }
|
||||||
let default_opts = { templates = empty_templates }
|
let default_opts = { templates = empty_templates; style = "" }
|
||||||
|
|
||||||
let init kv =
|
let init kv =
|
||||||
let open Logarion in
|
let open Logarion in
|
||||||
@@ -12,27 +12,31 @@ let init kv =
|
|||||||
| exception Not_found -> None in
|
| exception Not_found -> None in
|
||||||
let header = to_string "HTM-header" kv in
|
let header = to_string "HTM-header" kv in
|
||||||
let footer = to_string "HTM-footer" kv in
|
let footer = to_string "HTM-footer" kv in
|
||||||
{ templates = { header; footer} }
|
let style = match to_string "HTM-style" kv with
|
||||||
|
| Some s -> Printf.sprintf "<style>%s</style>" s | None -> "" in
|
||||||
|
{ templates = { header; footer}; style }
|
||||||
|
|
||||||
let wrap conv htm text_title body =
|
let wrap conv htm text_title body =
|
||||||
let site_title = try Logarion.Store.KV.find "Title" conv.Conversion.kv
|
let site_title = try Logarion.Store.KV.find "Title" conv.Conversion.kv with Not_found -> "" in
|
||||||
with Not_found -> "" in
|
|
||||||
let replace x = let open Str in
|
let replace x = let open Str in
|
||||||
global_replace (regexp "{{archive-title}}") site_title x
|
global_replace (regexp "{{archive-title}}") site_title x
|
||||||
|> global_replace (regexp "{{text-title}}") text_title
|
|> global_replace (regexp "{{text-title}}") text_title
|
||||||
in
|
in
|
||||||
|
let feed = try Logarion.Store.KV.find "HTM-feed" conv.Conversion.kv
|
||||||
|
with Not_found -> if Sys.file_exists (Filename.concat conv.Conversion.dir "feed.atom")
|
||||||
|
then "feed.atom" else "" in
|
||||||
let header = match htm.templates.header with
|
let header = match htm.templates.header with
|
||||||
| Some x -> replace x
|
| Some x -> replace x
|
||||||
| None -> "<header><a href='.'>" ^ site_title ^
|
| None -> Printf.(sprintf "<header><a href='.'>%s</a></header>%s" site_title
|
||||||
"</a><nav><a href='feed.atom' id='feed'>feed</a></nav></header>"
|
(if feed <> "" then sprintf "<nav><a href='%s' id='feed'>feed</a></nav>" feed else ""))
|
||||||
in
|
in
|
||||||
let footer = match htm.templates.footer with None -> "" | Some x -> replace x in
|
let footer = match htm.templates.footer with None -> "" | Some x -> replace x in
|
||||||
Printf.sprintf "<!DOCTYPE HTML><html><head><title>%s%s</title>\n\
|
Printf.sprintf "<!DOCTYPE HTML><html><head><title>%s%s</title>\n%s\n%s\
|
||||||
<link rel='stylesheet' href='main.css'>\
|
|
||||||
<link rel='alternate' href='feed.atom' type='application/atom+xml'>\
|
|
||||||
<meta charset='utf-8'/><meta name='viewport' content='width=device-width, initial-scale=1.0'>\
|
<meta charset='utf-8'/><meta name='viewport' content='width=device-width, initial-scale=1.0'>\
|
||||||
</head><body>\n%s%s%s</body></html>"
|
</head><body>\n%s%s%s</body></html>"
|
||||||
text_title (if site_title <> "" then (" • " ^ site_title) else "")
|
text_title (if site_title <> "" then (" • " ^ site_title) else "")
|
||||||
|
htm.style
|
||||||
|
(if feed <> "" then Printf.sprintf "<link rel='alternate' href='%s' type='application/atom+xml'>" feed else "")
|
||||||
header body footer
|
header body footer
|
||||||
|
|
||||||
let topic_link root topic =
|
let topic_link root topic =
|
||||||
@@ -150,7 +154,7 @@ let topic_main_index conv htm topic_roots metas =
|
|||||||
(fold_topic_roots topic_roots
|
(fold_topic_roots topic_roots
|
||||||
^ "<nav><h1>Latest</h1><ul>" ^ to_dated_links ~limit:8 metas
|
^ "<nav><h1>Latest</h1><ul>" ^ to_dated_links ~limit:8 metas
|
||||||
^ {|</ul><a href="index.date.htm">More by date</a>|}
|
^ {|</ul><a href="index.date.htm">More by date</a>|}
|
||||||
^ let peers = Logarion.Store.KV.find "Peers" conv.kv in
|
^ let peers = try Logarion.Store.KV.find "Peers" conv.kv with Not_found -> "" in
|
||||||
(if peers = "" then "" else
|
(if peers = "" then "" else
|
||||||
List.fold_left (fun a s -> Printf.sprintf {|%s<li><a href="%s">%s</a>|} a s s) "<h1>Peers</h1><ul>"
|
List.fold_left (fun a s -> Printf.sprintf {|%s<li><a href="%s">%s</a>|} a s s) "<h1>Peers</h1><ul>"
|
||||||
(Str.split (Str.regexp ";\n") (Logarion.Store.KV.find "Peers" conv.kv))
|
(Str.split (Str.regexp ";\n") (Logarion.Store.KV.find "Peers" conv.kv))
|
||||||
|
|||||||
Reference in New Issue
Block a user