
Introduces Store module type. Logarion module: * Removed Entry submodule, it mostly duplicated Meta * Make functor for creating archives given a Store compatible module The output Archive module contains functions for sorting, ordering, selecting and accumulating (storing) notes. Meta module: * Function Path.basename_of_title has been renamed to Meta.string_of_slug This is because slugs are now defined explicitely by 'slug' field or derived from 'title' field. Counting numbers can't be used anymore. Slug has an optional, dedicated field. Function Meta.slug should be used on a Meta to get the appropriate slug (title or slug). * Introduces StringSet type (Set of Strings) Topics, keywords and series are now StringSets * Adds SlugMap and IdMap aliases Note module: * Automatically scan for Markdown heading to use as title in the absence of one File module: * File has a Store compatible signature The implementation has an Lwt hack; Lwt will be fully supported in the future Web module: * Uses new Logarion.Configuration, File store and Archive.t Template module: * Adapted for new types * Currently disabled topics substitution, because this framework needs reconsideration Finally: * Adapts command line interface to work with new store * Adapts Atom feed to work with new store Path module renamed to Lpath to avoid clash with OCaml system module. (Squashed commits from dev)
81 lines
2.5 KiB
OCaml
81 lines
2.5 KiB
OCaml
module Id = Meta.Id
|
|
type slug_t = string
|
|
|
|
module Configuration = struct
|
|
type t = {
|
|
repository : Lpath.repo_t;
|
|
title : string;
|
|
owner : string;
|
|
email : string;
|
|
id : Id.t;
|
|
}
|
|
|
|
let default ?(id=(Id.generate ())) () = {
|
|
repository = Lpath.repo_of_string (Sys.getcwd ());
|
|
title = "Logarion journal";
|
|
owner = "";
|
|
email = "";
|
|
id;
|
|
}
|
|
|
|
let of_toml_file path =
|
|
let result = Toml.Parser.from_filename (Lpath.string_of_config path) in
|
|
match result with
|
|
| `Error (str, loc) -> default ()
|
|
| `Ok toml ->
|
|
let str = Logarion_toml.str toml "general" in
|
|
let default = default () in
|
|
let default_repo = default.repository |> Lpath.string_of_repo in
|
|
{
|
|
repository = Lpath.repo_of_string (str "repository" default_repo);
|
|
title = str "title" default.title;
|
|
owner = str "owner" default.owner;
|
|
email = str "email" default.email;
|
|
id = match Id.of_string (str "uuid" "") with Some id -> id | None -> Id.generate();
|
|
}
|
|
end
|
|
|
|
module SlugMap = Meta.SlugMap
|
|
|
|
module Make (Store : Store.T) = struct
|
|
type t = {
|
|
config : Configuration.t;
|
|
store : Store.t;
|
|
}
|
|
|
|
let note_lens note = note
|
|
let meta_lens note = note.Note.meta
|
|
|
|
let recency_order a b = Meta.(Date.compare b.date a.date)
|
|
|
|
let latest archive =
|
|
Store.to_list ~order:recency_order meta_lens archive.store
|
|
|
|
let listed archive =
|
|
let notes = Store.to_list meta_lens archive.store in
|
|
List.filter Meta.(fun e -> CategorySet.listed e.categories) notes
|
|
|
|
let published archive =
|
|
let notes = Store.to_list meta_lens archive.store in
|
|
List.filter Meta.(fun e -> CategorySet.published e.categories) notes
|
|
|
|
let latest_listed archive =
|
|
let notes = Store.to_list ~order:recency_order meta_lens archive.store in
|
|
List.filter Meta.(fun e -> CategorySet.listed e.categories) notes
|
|
|
|
let topics archive =
|
|
let notes = Store.to_list meta_lens archive.store in
|
|
List.fold_left Meta.(fun a e -> unique_topics a e) Meta.StringSet.empty notes
|
|
|
|
let latest_entry archive fragment =
|
|
let notes = Store.to_list ~order:recency_order meta_lens archive.store in
|
|
try Some (List.find (fun e -> BatString.exists (e.Meta.title) fragment) notes)
|
|
with Not_found -> None
|
|
|
|
let note_with_id archive id = Store.note_with_id archive.store id
|
|
let note_with_alias archive alias = Store.note_with_alias archive.store alias
|
|
|
|
let with_note archive note = Store.with_note archive.store note
|
|
|
|
end
|