diff options
author | sternenseemann <git@lukasepple.de> | 2017-02-14 00:21:01 +0100 |
---|---|---|
committer | sternenseemann <git@lukasepple.de> | 2017-02-14 00:21:01 +0100 |
commit | e69173be484ce3f42b42c28891ef7f5e909a3f1c (patch) | |
tree | e97637ebcc91b111569d4b01e72f36c1da4ef8b1 |
Initial commit
-rw-r--r-- | .gitignore | 8 | ||||
-rw-r--r-- | .merlin | 4 | ||||
-rw-r--r-- | .ocp-indent | 1 | ||||
-rw-r--r-- | CHANGES.md | 4 | ||||
-rw-r--r-- | LICENSE.md | 13 | ||||
-rw-r--r-- | README.md | 37 | ||||
-rw-r--r-- | _tags | 3 | ||||
-rw-r--r-- | doc/api.odocl | 1 | ||||
-rw-r--r-- | doc/dev.odocl | 1 | ||||
-rw-r--r-- | doc/style.css | 252 | ||||
-rw-r--r-- | example.log | 9 | ||||
-rw-r--r-- | opam | 22 | ||||
-rw-r--r-- | pkg/META | 7 | ||||
-rwxr-xr-x | pkg/pkg.ml | 8 | ||||
-rw-r--r-- | src/log.ml | 112 | ||||
-rw-r--r-- | src/log.mli | 59 | ||||
-rw-r--r-- | src/log.mllib | 1 |
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 |