about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsternenseemann <git@lukasepple.de>2017-02-14 00:21:01 +0100
committersternenseemann <git@lukasepple.de>2017-02-14 00:21:01 +0100
commite69173be484ce3f42b42c28891ef7f5e909a3f1c (patch)
treee97637ebcc91b111569d4b01e72f36c1da4ef8b1
Initial commit
-rw-r--r--.gitignore8
-rw-r--r--.merlin4
-rw-r--r--.ocp-indent1
-rw-r--r--CHANGES.md4
-rw-r--r--LICENSE.md13
-rw-r--r--README.md37
-rw-r--r--_tags3
-rw-r--r--doc/api.odocl1
-rw-r--r--doc/dev.odocl1
-rw-r--r--doc/style.css252
-rw-r--r--example.log9
-rw-r--r--opam22
-rw-r--r--pkg/META7
-rwxr-xr-xpkg/pkg.ml8
-rw-r--r--src/log.ml112
-rw-r--r--src/log.mli59
-rw-r--r--src/log.mllib1
17 files changed, 542 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b48ed60
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+_build
+tmp
+*~
+\.\#*
+\#*#
+*.install
+*.native
+*.byte
\ No newline at end of file
diff --git a/.merlin b/.merlin
new file mode 100644
index 0000000..68ac453
--- /dev/null
+++ b/.merlin
@@ -0,0 +1,4 @@
+PKG bytes astring angstrom ptime
+S src
+S test
+B _build/**
diff --git a/.ocp-indent b/.ocp-indent
new file mode 100644
index 0000000..6c5b8f4
--- /dev/null
+++ b/.ocp-indent
@@ -0,0 +1 @@
+strict_with=always,match_clause=4,strict_else=never
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 0000000..9bdf255
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,4 @@
+vX.Y.Z YYYY-MM-DD Location
+--------------------------
+
+First release. 
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..d75ea85
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,13 @@
+Copyright (c) 2017 sternenseemann
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..75645d7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+logbook — tool for personal log files
+-------------------------------------------------------------------------------
+%%VERSION%%
+
+logbook is TODO
+
+logbook is distributed under the ISC license.
+
+Homepage: https://sternen.space/ocaml/logbook  
+
+## Installation
+
+logbook can be installed with `opam`:
+
+    opam install logbook
+
+If you don't use `opam` consult the [`opam`](opam) file for build
+instructions.
+
+## Documentation
+
+The documentation and API reference is generated from the source
+interfaces. It can be consulted [online][doc] or via `odig doc
+logbook`.
+
+[doc]: https://sternen.space/logbook/doc
+
+## Sample programs
+
+If you installed logbook with `opam` sample programs are located in
+the directory `opam var logbook:doc`.
+
+In the distribution sample programs and tests are located in the
+[`test`](test) directory of the distribution. They can be built and run
+with:
+
+    topkg build --tests true && topkg test 
diff --git a/_tags b/_tags
new file mode 100644
index 0000000..0dcebae
--- /dev/null
+++ b/_tags
@@ -0,0 +1,3 @@
+true : bin_annot, safe_string, package(bytes ptime angstrom astring)
+
+<src> : include
diff --git a/doc/api.odocl b/doc/api.odocl
new file mode 100644
index 0000000..5258147
--- /dev/null
+++ b/doc/api.odocl
@@ -0,0 +1 @@
+Log
diff --git a/doc/dev.odocl b/doc/dev.odocl
new file mode 100644
index 0000000..5258147
--- /dev/null
+++ b/doc/dev.odocl
@@ -0,0 +1 @@
+Log
diff --git a/doc/style.css b/doc/style.css
new file mode 100644
index 0000000..cd01d86
--- /dev/null
+++ b/doc/style.css
@@ -0,0 +1,252 @@
+@charset "UTF-8";
+/* Copyright (c) 2016 Daniel C. Bünzli. All rights reserved.
+   Distributed under the ISC license, see terms at the end of the file.
+   odig v0.0.1-36-gabe18e1 */
+
+/* Reset a few things. */
+
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,
+a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,
+small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,
+fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,
+article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,
+menu,nav,output,ruby,section,summary,time,mark,audio,video
+{ margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%;
+  font: inherit; line-height: inherit; vertical-align: baseline;
+  text-align: inherit; color: inherit; background: transparent; }
+
+table { border-collapse: collapse; border-spacing: 0; }
+
+html { box-sizing: border-box }
+*, *:before, *:after {  box-sizing: inherit; }
+
+/* Basic page layout */
+
+body
+{ font-family: Helvetica, "DejaVu Sans", Arial, sans-serif;
+  font-weight: normal;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  text-align: left;
+  min-width: 40ex;
+  max-width: 78ex;
+  padding: 1.25rem;
+  margin-left: 3.75rem;
+  color: #222; background: #FAFAFA;  }
+
+b { font-weight: bold }
+em { font-style: italic }
+
+.superscript { vertical-align: super; }
+.subscript { vertical-align: sub; }
+.superscript, .subscript
+{ font-size : 0.75rem; line-height: 0; margin-left: 0.2ex; }
+
+/* ocamldoc markup workaround hacks.
+   See http://caml.inria.fr/mantis/view.php?id=7351 */
+
+hr
+{ display: none } /* Would be nice to have but we cannot get that to
+                     interact well with our h1's because of br markup noise */
+
+br { display: none } /* Annoying, hide them. */
+code br { display: block } /* Except in signatures. */
+
+.codepre br + br { display: none }
+h1 + pre { margin-bottom: 0.625rem } /* Toplevel module description */
+
+/* Links and anchors */
+
+a { text-decoration:none; color:#2C5CBD; }
+a:hover { box-shadow:0 1px 0 0 #2C5CBD; }
+*:target { /* Anchor highlight */ background-color: #FFF8E5;
+           box-shadow: 0 0 0 2px #FFF8E5, 0 0 0 3px #DDDDDD; }
+
+a { text-decoration:none; color:#2C5CBD; }
+a:hover { box-shadow:0 1px 0 0 #2C5CBD; }
+*:target /* Linked highlight */
+{ background-color: #FFF8E5;
+  box-shadow: 0 0 0 2px #FFF8E5, 0 0 0 3px #DDD; }
+
+.anchored:hover a.anchor { visibility: visible; }
+
+a.anchor:before { content: "#" }
+a.anchor:hover {  box-shadow: none; text-decoration: underline }
+a.anchor
+{ visibility: hidden; position: absolute; /* top: 0px; */
+  margin-left: -3ex;
+  font-weight: normal;
+  font-style: normal;
+  padding-right: 1ex; padding-left: 1ex; /* To remain selectable */
+  color: #AAA; }
+
+/* Sections and document divisions
+
+   Many of the modules of the stdlib start at h6, we make it look like
+   h1 and the .7 div (sic) like h2. */
+
+h1, h2, h3, h6, .h7
+{ font-weight: bold; padding-top: 0.625rem; margin-top: 1.25rem }
+
+h1, h6
+{ font-size: 1.25rem;
+  line-height: 2.4375rem; /* 2.5 rem - border width */
+  border-top-style: solid;
+  border-width: 1px;
+  border-color: #DDDDDD; }
+
+h3 { margin-top: 0.625rem; }
+
+br + * { margin-top: 0.625rem; } /* Ideally this would be h1 + * */
+
+h2, .h7 { font-size: 1.125rem; }
+h1 + h2, h6 + .h7 { margin-top: 0.625rem; padding-top: 0rem; }
+
+/* Paragraphs, lists and tables */
+
+p { margin-top: 1.25rem }
+e.info p, li p { margin-top: 0.625rem }
+
+table { margin-top: 0.625rem }
+.info.module.top { margin-left: 0em } /* Toplevel module description */
+.info { margin-left: 1ex; margin-top: 0.15625rem }
+
+td .info { margin:0; padding:0; margin-left: 2em;} /* Description in indexes */
+
+ul, ol { margin-top: 0.625rem; margin-bottom: 0.625rem;
+	       list-style-position: outside }
+ul + p, ol + p { margin-top: 0em }
+ul { list-style-type: square }
+
+ul > li { margin-left: 1.375rem; }
+ol > li { margin-left: 1.7rem; }
+
+/* Preformatted and code */
+
+tt, code, pre
+{ font-family: Menlo, "DejaVu Sans Mono", "Bitstream Vera Sans Mono",
+               monospace;
+  font-weight: normal;
+  font-size: 0.75rem; }
+
+h1 tt, h1 code, h6 tt, h6 code { font-size: 1.125rem }
+h2 tt, h2 code, .h7 tt, .h7 code { font-size: 1rem }
+
+pre {  margin-top: 1.25rem; }
+
+pre.verbatim, pre.codepre
+{ padding-left: 0.25rem;
+  padding-right: 0.25rem;
+  margin-left: -0.25rem;
+  margin-right: -0.25rem;
+  padding-bottom: 0.3125rem;
+  padding-top: 0.3125rem;
+  margin-bottom: 0.265rem; /* Sometimes there's text without <p>
+                              http://caml.inria.fr/mantis/view.php?id=7353 */
+  line-height: 1.1875rem;
+  background: #F1F1F1; }
+
+pre .code { background: inherit; }
+.code {
+  /* If we can avoid it. */
+  /* background: #F1F1F1;
+     padding-top:1px; padding-bottom:1px;
+     padding-left:1px; padding-right:1px;
+     border-radius:2px; */ }
+
+.keyword { font-weight: bold }
+.comment { color: #888; font-style:italic }
+.constructor { color: #208000; }
+.string { color: brown; }
+.warning { color: crimson; }
+
+.typetable { margin-top: 0em }
+
+.paramstable code { margin-left: 1ex; margin-right: 1ex; }
+.sig_block { margin-left: 1em }
+
+/* Images */
+
+img { margin-top: 1.25rem }
+
+/* Index tables */
+
+ul.indexlist { list-style-type: none; margin-left:0; padding:0; }
+ul.indexlist li { margin-left:0; padding: 0; }
+
+/* Odig package index */
+
+.by-name ol, .by-tag ol, .errors ol { list-style-type: none; margin-left:0; }
+.by-name ol ol, .by-tag ol ol { margin-top:0; margin-bottom: 0 }
+.by-name li, .by-tag li, .errors li { margin-left:0; }
+
+.by-name .version { font-size: 0.625rem; color: #AAA }
+.by-name nav { margin-bottom: 0.625rem }
+.by-name nav a
+{ text-transform: uppercase; font-size: 1.125rem;
+  margin-right:1ex; color: #222; display: inline-block; }
+
+.by-tag nav a { margin-right:1ex; color: #222; display: inline-block; }
+.by-tag > ol > li { margin-top: 0.625rem; }
+.by-tag > ol > li > span,
+.by-tag > ol > li > ol,
+.by-tag > ol > li > ol > li { display: inline-block; margin-right: 1ex; }
+
+/* Odig package page */
+
+.package nav { display: inline; font-size: 0.875rem; font-weight: normal; }
+.package .version { font-size: 0.875rem; }
+
+/* This doesn't work in 4.03 because of spurious br's */
+h1 + .indextable, h1 + .sel { margin-top: 0.625rem }
+.sel { font-weight: normal; font-style: italic;
+       font-size:0.875rem; margin-top:1.25rem; }
+.sel + .indextable { margin-top:0.625rem;
+                     margin-bottom: 1.25rem; margin-left: 1ex; }
+
+.package.info { margin: 0;}
+.package.info td:first-child { font-style: italic; padding-right: 2ex; }
+.package.info ul { list-style-type: none; display: inline; margin:0; }
+.package.info li { display: inline-block; margin:0; margin-right:1ex; }
+#info-authors li, #info-maintainers li { display:block; }
+
+/* Odig ocamldoc adjustements. */
+
+#info, .by-name h2, .by-tag h2, .errors h2
+{ font-size: 1.25rem;
+  line-height: 2.4375rem; /* 2.5 rem - border width */
+  border-top-style: solid;
+  border-width: 1px;
+  border-color: #DDDDDD; }
+
+#info + *, .by-name h2 + *, .by-tag h2 + *, .errors h2 { margin-top: 0.625rem; }
+
+body h1:first-child { display: none } /* package page. */
+
+/* Mobile adjustements
+  Can't really do anything we need to get a <meta> for viewport generated */
+
+@media only screen and (max-width: 78ex)
+{ body { margin: auto; } }
+
+/* Print adjustements. */
+
+@media print
+{ body { color: black; background: white; }
+  body nav:first-child { visibility: hidden; }}
+
+/*---------------------------------------------------------------------------
+   Copyright (c) 2016 Daniel C. Bünzli
+
+   Permission to use, copy, modify, and/or distribute this software for any
+   purpose with or without fee is hereby granted, provided that the above
+   copyright notice and this permission notice appear in all copies.
+
+   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+  ---------------------------------------------------------------------------*/
diff --git a/example.log b/example.log
new file mode 100644
index 0000000..0c19185
--- /dev/null
+++ b/example.log
@@ -0,0 +1,9 @@
+[2017-02-14]
+Test
+
++ Hi this is a test
+  Hi?
+  Is this working?
+
+- private
+  foobar?
diff --git a/opam b/opam
new file mode 100644
index 0000000..594bc29
--- /dev/null
+++ b/opam
@@ -0,0 +1,22 @@
+opam-version: "1.2"
+maintainer: "sternenseemann <post@lukasepple.de>"
+authors: ["sternenseemann <post@lukasepple.de>"]
+homepage: "https://sternen.space/ocaml/logbook"
+doc: "https://sternen.space/logbook/doc"
+license: "ISC"
+dev-repo: "https://sternen.space/ocaml/logbook.git"
+bug-reports: "https://sternen.space/ocaml/logbook/issues"
+tags: []
+available: [ ocaml-version >= "4.01.0"]
+depends: [
+  "ocamlfind" {build}
+  "ocamlbuild" {build}
+  "topkg" {build} 
+  "ptime"
+  "angstrom"
+  "astring"
+  ]
+depopts: []
+build: [
+  "ocaml" "pkg/pkg.ml" "build"
+          "--pinned" pinned ]
diff --git a/pkg/META b/pkg/META
new file mode 100644
index 0000000..37cd0b8
--- /dev/null
+++ b/pkg/META
@@ -0,0 +1,7 @@
+description = "tool for personal log files"
+version = "%%VERSION_NUM%%"
+requires = "ptime angstrom astring"
+archive(byte) = "logbook.cma"
+archive(native) = "logbook.cmxa"
+plugin(byte) = "logbook.cma"
+plugin(native) = "logbook.cmxs"
diff --git a/pkg/pkg.ml b/pkg/pkg.ml
new file mode 100755
index 0000000..ec3d818
--- /dev/null
+++ b/pkg/pkg.ml
@@ -0,0 +1,8 @@
+#!/usr/bin/env ocaml
+#use "topfind"
+#require "topkg"
+open Topkg
+
+let () =
+  Pkg.describe "logbook" @@ fun c ->
+  Ok [ Pkg.mllib "src/log.mllib"; ]
diff --git a/src/log.ml b/src/log.ml
new file mode 100644
index 0000000..20d1d03
--- /dev/null
+++ b/src/log.ml
@@ -0,0 +1,112 @@
+(*---------------------------------------------------------------------------
+   Copyright (c) 2017 sternenseemann. All rights reserved.
+   Distributed under the ISC license, see terms at the end of the file.
+   %%NAME%% %%VERSION%%
+  ---------------------------------------------------------------------------*)
+open Angstrom
+open Astring
+
+type privacy_level = Private | Semi_private | Public
+
+let compatible_privacy x mode =
+  match mode with
+  | Private -> true (* who may see private post, may see all posts *)
+  | Semi_private -> x = Semi_private || x = Public
+  | Public -> x = Public
+
+let privacy_level_of_char = function
+  | '+' -> Some Public
+  | '-' -> Some Private
+  | '*' -> Some Semi_private
+  | _   -> None
+
+type item = Item of privacy_level * string * string
+
+type log_entry = Log_entry of Ptime.date * string * item list
+
+type log = log_entry list
+
+(* parser *)
+
+let empty_line = end_of_line
+let non_empty_line = take_while1 (fun c -> c != '\n') <* end_of_line
+
+let editor_comment = string "-*-" *> skip_while (fun c -> c != '\n') *> end_of_line
+
+let single_indent = count 4 (char ' ') *> return ()
+
+let date =
+  char '[' *>
+  take_till (fun c -> c = '-') <* char '-'
+  >>= (fun year ->
+    take 2 <* char '-'
+    >>= (fun month ->
+      take 2 <* char ']' <* end_of_line
+      >>= (fun day ->
+        return (int_of_string year, int_of_string month, int_of_string day))))
+
+let spaced_list p =
+  many (p <* skip_many empty_line)
+
+let rec fail_if_none p =
+  let failer = function
+    | None -> fail "Value is None"
+    | Some x -> return x
+  in p >>= failer
+
+(* TODO rework *)
+let rec block indent =
+  let peeker = function
+    | None -> false
+    | Some '\n' -> false
+    | Some _ -> true
+  in String.append
+    <$> (count indent (char ' ')
+         *> non_empty_line)
+    <*> (peek_char
+      >>= (fun c ->
+        if (peeker c) then (String.append "\n") <$> block indent
+        else return ""))
+
+(* TODO substitution *)
+let itemp =
+  fail_if_none (privacy_level_of_char <$> any_char) <*
+  any_char
+  >>= (fun priv ->
+    non_empty_line
+    >>= (fun title ->
+      block 2
+      >>= (fun text ->
+        return (Item (priv, title, text)))))
+
+let log_entryp =
+  date <* skip_many empty_line
+  >>= (fun date ->
+    block 0
+    >>= (fun summary ->
+      skip_many empty_line *>
+      spaced_list itemp
+      >>= (fun items ->
+        return (Log_entry (date, summary, items)))))
+
+
+let log_parser =
+  (editor_comment <|> return ()) *>
+  skip_many empty_line *>
+  spaced_list log_entryp
+
+(*---------------------------------------------------------------------------
+   Copyright (c) 2017 sternenseemann
+
+   Permission to use, copy, modify, and/or distribute this software for any
+   purpose with or without fee is hereby granted, provided that the above
+   copyright notice and this permission notice appear in all copies.
+
+   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+  ---------------------------------------------------------------------------*)
diff --git a/src/log.mli b/src/log.mli
new file mode 100644
index 0000000..a4bde39
--- /dev/null
+++ b/src/log.mli
@@ -0,0 +1,59 @@
+(*---------------------------------------------------------------------------
+   Copyright (c) 2017 sternenseemann. All rights reserved.
+   Distributed under the ISC license, see terms at the end of the file.
+   %%NAME%% %%VERSION%%
+  ---------------------------------------------------------------------------*)
+
+(** OCaml representation and parsing of the
+    {{:https://gist.github.com/Profpatsch/092ff68fa267b9fa0ccbe13e98149b21}log format}.
+
+    {e %%VERSION%% — {{:%%PKG_HOMEPAGE%% }homepage}} *)
+
+(** {1 Log} *)
+
+(** {2 Log Representation} *)
+
+(** Describes, how private a log item is. Semi-private means “visible to trusted persons” *)
+type privacy_level = Private | Semi_private | Public
+
+(** A log item consisting of a title, a text (formatting/markup unknown) and its privacy level. *)
+type item = Item of privacy_level * string * string
+
+(** A log entry consisting of a date (point in time is sufficient, so Ptime is used), a summary and items *)
+type log_entry = Log_entry of Ptime.date * string * item list
+
+(** A log file consisting of multiple log entries for multiple days *)
+type log = log_entry list
+
+(** A test to check wether a privacy level of e. g. an item is
+    compatible with the (maximum) privacy level available. *)
+val compatible_privacy : privacy_level -> privacy_level -> bool
+
+(** Get the corresponding privacy level for a char *)
+val privacy_level_of_char : char -> privacy_level option
+
+(** {2 Log Parsing} 
+
+    log files are parsed using {{:https://github.com/inhabitedtype/angstrom}angstrom}.
+*)
+
+(** An angstrom parser for log files *)
+val log_parser : log Angstrom.t
+
+(** {2 Log Building} *)
+
+(*---------------------------------------------------------------------------
+   Copyright (c) 2017 sternenseemann
+
+   Permission to use, copy, modify, and/or distribute this software for any
+   purpose with or without fee is hereby granted, provided that the above
+   copyright notice and this permission notice appear in all copies.
+
+   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+  ---------------------------------------------------------------------------*)
diff --git a/src/log.mllib b/src/log.mllib
new file mode 100644
index 0000000..5258147
--- /dev/null
+++ b/src/log.mllib
@@ -0,0 +1 @@
+Log