summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/blog/2019-12-24-imag-0-10-0.md81
-rw-r--r--content/doc.md4
-rw-r--r--content/doc/man/0.10.0/imag.53361
-rw-r--r--content/doc/pdf/0.10.0.pdfbin0 -> 254833 bytes
-rw-r--r--content/doc/web/0.10.0/index.html1491
5 files changed, 4937 insertions, 0 deletions
diff --git a/content/blog/2019-12-24-imag-0-10-0.md b/content/blog/2019-12-24-imag-0-10-0.md
new file mode 100644
index 0000000..a7f4bb3
--- /dev/null
+++ b/content/blog/2019-12-24-imag-0-10-0.md
@@ -0,0 +1,81 @@
+---
+title: "imag 0.10.0"
+slug: "imag-0-10-0"
+date: "2019-12-24T11:10:09"
+tags: [ "linux", "open source", "programming", "rust", "software", "tools", "imag" ]
+---
+
+<!-- more -->
+
+I know it is christmas, so I'll make this one short:
+imag v0.10.0 is released! Yippie!
+
+
+# What's in there
+
+* 741 commits
+* 78 merge-commits / 663 non-merge commits
+* 495 files changed
+* 21537 insertions(+), 14066 deletions(-)
+
+Some more statistics about the codebase (thank you,
+[tokei](https://github.com/Aaronepower/tokei)), because why not:
+
+```
+-------------------------------------------------------------------------------
+ Language Files Lines Code Comments Blanks
+-------------------------------------------------------------------------------
+ BASH 8 181 119 18 44
+ CSS 1 27 24 0 3
+ Makefile 1 161 97 29 35
+ Markdown 67 3290 3290 0 0
+ Nix 2 99 67 11 21
+ Rust 349 39431 25132 8257 6042
+ Shell 12 518 288 152 78
+ TOML 69 3617 2671 293 653
+-------------------------------------------------------------------------------
+ Total 509 47324 31688 8760 6876
+-------------------------------------------------------------------------------
+```
+
+The highlights:
+
+* All binary crates propagate errors to their main() function now rather than
+ calling exit() somewhere in between.
+* Clippy linting was enabled for the repository
+* UI testing was introduced, though not many binaries are tested yet.
+* Annotations (imag-annotate) are now unnamed.
+* New CLI tool: imag-header
+* libimagentryref was rewritten
+* The code for the libimagmail and related crates was rewritten
+* libimagnotification was removed
+* The "edit" command for imag-contact was added
+* imag-ref can list dead references now
+* imag-markdown was added to print markdown representation of entries
+* imag-create was added for creating entries
+* libimagcalendar was added
+* imag-calendar was added
+* Preparations for compiling imag into a single binary and provide commandline
+* libimagtodo was rewritten from scratch and so was imag-todo
+* imag-bookmark does no longer contain the concept of "collections"
+* imag-bookmark can now call a command to open links
+
+The full
+[changelog](http://git.imag-pim.org/imag/tree/CHANGELOG.md?h=v0.10.0)
+is rather long, because a lot of stuff was changed and fixed
+(and not even the changelog contains all changes).
+Its best to look up the changes there and in the
+[git commit history](https://git.imag-pim.org/imag/).
+
+
+## What will be in imag 0.11.0
+
+The next version will focus on "imag mail" entirely. Of course there will be
+smaller fixes and changes to the other tools as well, but the main focus will be
+imag-mail and as soon as I'm satisfied with that, I will release imag version
+0.11.0!
+
+
+<hr>
+
+And now, have a merry christmas and a happy new year!
diff --git a/content/doc.md b/content/doc.md
index 0101a08..628418f 100644
--- a/content/doc.md
+++ b/content/doc.md
@@ -9,6 +9,10 @@ is the latest release for which documentation is published.
The source-documentation is hosted with
[docs.rs](https://docs.rs/releases/search?query=imag).
+* v0.10.0
+ * [pdf](/doc/pdf/0.10.0.pdf)
+ * [html](/doc/web/0.10.0/)
+ * [man](/doc/man/0.10.0/imag.5)
* v0.8.0
* [pdf](/doc/pdf/0.8.0.pdf)
* [html](/doc/web/0.8.0/)
diff --git a/content/doc/man/0.10.0/imag.5 b/content/doc/man/0.10.0/imag.5
new file mode 100644
index 0000000..d1867cb
--- /dev/null
+++ b/content/doc/man/0.10.0/imag.5
@@ -0,0 +1,3361 @@
+.\" Automatically generated by Pandoc 2.7.1
+.\"
+.TH "imag User Documentation" "5" "May 2018" "" ""
+.hy
+.SH Introduction
+.PP
+This document is the user documentation for imag, the personal
+information management suite for the commandline.
+.PP
+\f[B]Basically: This is Hobby stuff. Expect incompleteness, false
+statements and generally read with grain of salt.\f[R]
+.PP
+If you have any objections, suggestions for improvements, bugs, etc,
+please file them (See Section\ 8).
+A way to reach out to the imag project maintainer(s) is described in the
+Section\ 8 section.
+.SS The Problem
+.PP
+The problem this project tries to solve is to provide a modular
+commandline application for personal information management.
+.PP
+It targets \[lq]power users\[rq] or \[lq]commandline users\[rq], uses
+plain text as a storage format and tries to be as scriptable as
+possible.
+imag offers the ability to link data from different \[lq]PIM
+aspects\[rq] (such as \[lq]diary\[rq], \[lq]contacts\[rq] and
+\[lq]bookmark\[rq] for example).
+.PP
+One major goal of imag is to make the PIM data traverseable and
+queryable.
+For example: a wiki article can be linked to an appointment which is
+linked to a todo which is linked to a note which is linked to a contact.
+.PP
+imag wants to offer an all-in-one scriptable modular commandline
+personal information management suite for all PIM aspects one could
+possibly think of.
+Because imag uses plain text (TOML headers for structured data and plain
+text which can be rendered using markdown, for example, for continuous
+text) the user is always able to access their data without the imag
+tools at hand.
+.SS The Approach
+.PP
+The approach \[lq]imag\[rq] takes on solving this problem is to store
+content in a \[lq]store\[rq] and persisting content in a unified way.
+Meta-information is attached to the content which can be used to store
+structured data.
+This can be used to implement a variety of \[lq]domain modules\[rq]
+using the store.
+While content is stored in \f[I]one\f[R] place, imag does not duplicate
+content.
+imag does not copy or move icalendar files, emails, vcard files, music
+or movies to the store, but tries to remember the actual files are and
+stores meta-information about them in the store.
+.PP
+Detailed explanation on this approach follows in the chapters of this
+work.
+.SS Implementation
+.PP
+The program is written in the Rust programming language.
+.PP
+The program consists of libraries which can be re-used by other projects
+to implement and adapt imag functionality.
+An external program may use a library of the imag distribution to store
+content in the store of imag and make it visible to imag this way.
+.PP
+This is a technical detail a user does not necessarily need to know, but
+as imag is intended for power-users anyways, we would say it fits here.
+.SS Alternative Projects
+.PP
+imag is not the only project which tries to solve that particular
+problem.
+For example there is org mode (https://orgmode.org) for the
+emacs (https://www.gnu.org/software/emacs/) text editor.
+There is also zim (http://zim-wiki.org/), a desktop wiki editor which is
+intended to be used for a personal wiki.
+.PP
+The difference between imag and the mentioned projects is: * emacs
+orgmode is (from what I know and see) for \f[I]orgabizing\f[R] things.
+imag is intended not only for organizing, but also for recording,
+tracking and querying.
+* zim is a wiki, which could be used for PIM but is not specialized for
+it.
+Recording habits might be possible, but not that simple as with imag
+.PP
+imag is not there yet, though.
+Some parts can be used, though it is far away from being
+feature-complete.
+.PP
+In addition: imag is text-editor independent and other tools than imag
+might be used to access data stored in the imag store.
+For example, one could \[lq]grep\[rq], \[lq]awk\[rq] and \[lq]sed\[rq]
+entries without much hassle and even write bash scripts for
+automatically filling imag entries with data.
+.SH Architecture of the imag code
+.PP
+The imag codebase has a rather simple overall architecture.
+In this chapter the types of crates, architecture of an imag module and
+the type structure are described.
+.SS Crate types
+.PP
+There are different types of crates in the imag world.
+A crate is a rust project.
+.PP
+First of all, there are core crates.
+These crates provide the very core of imag and almost all other crates
+use them:
+.IP \[bu] 2
+libimagstore - The imag store is the abstraction over the filesystem.
+It provides primitives to get, write and manipulate store entries and
+their header information.
+.IP \[bu] 2
+libimagrt - The runtime library, which provides functionality to create
+a store object from libimagstore, helps with configurarion loading and
+commandline argument handling (through the external \[lq]clap\[rq]
+crate).
+.IP \[bu] 2
+libimagerror - Error handling library for handling errors the imag way.
+Used in all other crates, even the store itself.
+It also offers functionality to log and trace errors as well as exiting
+the application, if necessary.
+.IP \[bu] 2
+libimagutil - Utilities.
+.PP
+The next type of imag crates are entry extension libraries.
+Those provide extensional functionality for the types from libimagstore.
+For example, there is \[lq]libimagentrylink\[rq] which provides
+functionality to link two entries in the store.
+.PP
+The third kind of crate is the one that offers end-user functionality
+for a imag domain, for example \[lq]libimagtodo\[rq] provides
+functionality to track todos.
+.PP
+And last, but not least, the commandline frontend crates provide the
+user interface.
+These are the kind of crates that are not library crates, but binaries.
+.PP
+Besides these, there are some other utility crates.
+.SS Architecture of an imag module
+.PP
+With the things from above, a module could have the following
+architecture:
+.IP
+.nf
+\f[C]
++---------------------------------------------+
+| imag-foo |
++-----------------------------------+---------+
+| libimagfoo | |
++-----------------+-----------------+ |
+| | | |
+| libimagentrybar | libimagentrybaz | |
+| | | lib |
++-----------------+-----------------+ |
+| | |
+| ... | |
+| | imag |
++-----------------------------------+ |
+| | |
+| libimagrt | |
+| | error |
++-----------------------------------+ |
+| | |
+| libimagstore | |
+| | |
++-----------------------------------+---------+
+\f[R]
+.fi
+.PP
+The foundation of all imag modules is the store, as one can see in the
+visualization from above.
+Above the store library there is the libimagrt, which provides the basic
+runtime and access to the \f[C]Store\f[R] object.
+Cross-cutting, there is the error library (and possibly the util
+library, but we do not care about this one here), which is used through
+all levels.
+The highest level of all imag modules is the commandline interface on
+top of the domain library.
+In between can be any number of entry extension libraries, or none if
+not needed.
+.PP
+Theoretically, the commandline interface crate could be replaced to
+build a terminal user interface, graphical user interface or web
+interface.
+.SS Types
+.PP
+The imag core, hence the libimagstore, libimagrt and libimagerror,
+provide a set of types that a user (as in a library writer) should be
+aware of.
+.PP
+First of all, there is the \f[C]Runtime\f[R] type which is provided by
+the libimagrt.
+It provides basic access to whether debugging or verbosity is enabled as
+well as the most important core object: The \f[C]Store\f[R].
+.PP
+The \f[C]Store\f[R] type is provided by the libimagstore library, the
+heart of everything.
+.PP
+When interacting with the store, two types are visible:
+\f[C]FileLockEntry\f[R] and \f[C]Entry\f[R] whereas the former derefs to
+the latter, which basically means that the former wraps the latter.
+The \f[C]FileLockEntry\f[R] is a necessary wrapper for ensuring that
+when working concurrently with the store, an entry is only
+\f[I]borrowed\f[R] once from the store.
+It also ensures that the object is alive as long as the store is.
+.PP
+The \f[C]Entry\f[R] type provides functionality like reading the actual
+content, its header and so on.
+Extensions for its functionality are implemented on this type, not on
+the \f[C]FileLockEntry\f[R].
+.PP
+The \f[C]Entry\f[R] provides access to its header, which is a
+\f[C]toml::Value\f[R], where toml is the toml-rs crate (external
+project).
+Convenience functionality is provided via the \f[C]toml-query\f[R]
+crate, which is an external project which was initiated and extracted
+from the imag project.
+.PP
+Error types are also important.
+All errors in imag projects should be created with
+\f[C]error-chain\f[R].
+libimagerror provides functionality to enhance the experience with
+\f[C]Result\f[R] types and general tracing of errors.
+.SH The Store
+.PP
+The store is where all the good things happen.
+The store is basically just a directory on the filesystem imag manages
+and keeps its state in.
+.PP
+One could say that the store is simply a database, and it really is.
+We opted to go for plain text, though, as we believe that plain text is
+the only sane way to do such a thing, especially because the amount of
+data which is to be expected in this domain is in the lower Megabytes
+range and even if it is \f[I]really\f[R] much won\[cq]t exceed the
+Gigabytes ever.
+.PP
+Having a storage format which is plain-text based is the superior
+approach, as text editors will always be there.
+.PP
+A user should always be able to read her data without great effort and
+putting everything in a \f[I]real\f[R] database like sqlite or even
+postgresql would need a user to install additional software just to read
+his own data.
+We don\[cq]t want that.
+Text is readable until the worlds end and we think it is therefore
+better to store the data in plain text.
+.PP
+The following sections describe the store and the file format we use to
+store data.
+One may skip the following sections, they are included for users who
+want to dig into the store with their editors.
+.SS File Format
+.PP
+The contents of the store are encoded in UTF-8.
+A normal text editor (like \f[C]vim\f[R] or the other one) will always
+be sufficient to dig into the store and modify files.
+For simple viewing even a pager (like \f[C]less\f[R]) is sufficient.
+.PP
+Each entry in the store consists of two parts:
+.IP "1." 3
+Header
+.IP "2." 3
+Content
+.PP
+The following section describe their purpose.
+.SS Header Format
+.PP
+The header format is where imag stores its data.
+The header is an area at the top of every file which is seperated from
+the content part by three dashes (\f[C]---\f[R]).
+Between these three dashes there is structured data.
+imag uses \f[C]TOML\f[R] as data format for this structured data,
+because it fits best and the available \f[C]TOML\f[R] parser for the
+rust programming language is really good.
+.PP
+The header can contain any amount of data, but modules (see Section\ 6)
+are restricted in their way of altering the data.
+.PP
+So normally there are several sections in the header.
+One section (\f[C][imag]\f[R]) is always present.
+It contains a \f[C]version\f[R] field, which tells imag which version
+this file was created with.
+.PP
+Other sections are named like the modules which created them.
+Every module is allowed to store arbitrary data under its own section
+and a module may never read other sections than its own.
+.PP
+These conventions are not enforced by imag itself, though.
+.SS Content Format
+.PP
+The content is the part of the file where the user is free to enter any
+textual content.
+The content may be rendered as Markdown or other markup format for the
+users convenience.
+The store does never expect and specific markup and actually the markup
+implementation is not inside the very core of imag.
+.PP
+Technically it would be possible that the content part of a file is used
+to store binary data.
+We don\[cq]t want this, though, as it is contrary to the goals of imag.
+.SS Example
+.PP
+An example for a file in the store follows.
+.IP
+.nf
+\f[C]
+
+---
+[imag]
+version = \[dq]0.10.0\[dq]
+
+[note]
+name = \[dq]foo\[dq]
+
+[link]
+internal = [\[dq]some/other/imag/entry\[dq]]
+---
+
+This is an example text, written by the user.
+\f[R]
+.fi
+.SS File organization
+.PP
+The \[lq]Entries\[rq] are stored as files in the \[lq]Store\[rq], which
+is a directory the user has access to.
+The store may exist in the users Home-directory or any other directory
+the user has read-write-access to.
+.PP
+Each module stores its data in an own subdirectory in the store.
+This is because we like to keep things ordered and clean, not because it
+is technically necessary.
+.PP
+We name the path to a file in the store \[lq]Store id\[rq] or
+\[lq]Storepath\[rq] and we often refer to it by using the store location
+as root.
+So if the store exists in \f[C]/home/user/store/\f[R], a file with the
+storepath \f[C]example.file\f[R] is (on the filesystem) located at
+\f[C]/home/user/store/example.file\f[R].
+.PP
+By convention, each \f[C]libimagentry<name>\f[R] and
+\f[C]libimag<name>\f[R] module stores its entries in in
+\f[C]<name>/\f[R].
+.PP
+So, the pattern for the storepath is
+.IP
+.nf
+\f[C]
+<module name>/<optional sub-folders>/<file name>
+\f[R]
+.fi
+.PP
+Any number of subdirectories may be used, so creating folder hierarchies
+is possible and valid.
+A file \[lq]example\[rq] for a module \[lq]module\[rq] could be stored
+in sub-folders like this:
+.IP
+.nf
+\f[C]
+module/some/sub/folder/example
+\f[R]
+.fi
+.PP
+The above is not enforced or a strict rule, but rather a \[lq]rule of
+thumb\[rq].
+.SS Backends
+.PP
+The store itself also has a backend.
+This backend is the \[lq]filesystem abstraction\[rq] code.
+.PP
+Note: This is a very core thing.
+Casual users might want to skip this section.
+.SS Problem
+.PP
+First, we had a compiletime backend for the store.
+This means that the actual filesystem operations were compiled into the
+store either as real filesystem operations (in a normal debug or release
+build) but as a in-memory variant in the `test' case.
+So tests did not hit the filesystem when running.
+This gave us us the possibility to run tests concurrently with multiple
+stores that did not interfere with each other.
+.PP
+This approach worked perfectly well until we started to test not the
+store itself but crates that depend on the store implementation.
+When running tests in a crate that depends on the store, the store
+itself was compiled with the filesystem-hitting-backend.
+This was problematic, as tests could not be implemented without hitting
+the filesystem and mess up other currently-running tests.
+.PP
+Hence we implemented store backends.
+.SS Implementation
+.PP
+The filesystem is abstracted via a trait \f[C]FileAbstraction\f[R] which
+contains the essential functions for working with the filesystem.
+.PP
+Two implementations are provided in the code:
+.IP \[bu] 2
+FSFileAbstraction
+.IP \[bu] 2
+InMemoryFileAbstraction
+.PP
+whereas the first actually works with the filesystem and the latter
+works with an in-memory HashMap that is used as filesystem.
+.PP
+Further, the trait \f[C]FileAbstractionInstance\f[R] was introduced for
+functions which are executed on actual instances of content from the
+filesystem, which was previousely tied into the general abstraction
+mechanism.
+.PP
+So, the \f[C]FileAbstraction\f[R] trait is for working with the
+filesystem, the \f[C]FileAbstractionInstance\f[R] trait is for working
+with instances of content from the filesystem (speak: actual Files).
+.PP
+In case of the \f[C]FSFileAbstractionInstance\f[R], which is the
+implementation of the \f[C]FileAbstractionInstance\f[R] for the actual
+filesystem-hitting code, the underlying resource is managed like with
+the old code before.
+The \f[C]InMemoryFileAbstractionInstance\f[R] implementation is
+corrosponding to the \f[C]InMemoryFileAbstraction\f[R] implementation -
+for the in-memory \[lq]filesystem\[rq].
+.SH Conventions, best practices
+.PP
+This section explains conventions used in the imag codebase.
+It is mainly focused on developers, but a user may read it for getting
+to know how imag works.
+.PP
+Lets work our way up from the store and how to extend it to the
+commandline user interface.
+.SS Versioning
+.PP
+All imag crates are versioned with the same version number until we
+reach some \f[C]\[dq]1.0.0\[dq]\f[R] version.
+This means that all imag tools are only tested for compatibility with
+libraries and such if their version numbers match.
+It might not be possible to import one imag library in version 0.3.0 and
+another one in 0.4.0 and make them work together.
+It also means that if new tools are introduced into the imag codebase,
+they might start with their first version not at 0.1.0 but at something
+like 0.5.0.
+.SS Store and Entry functionality
+.PP
+A \f[C]Entry\f[R] does not offer much functionality by itself.
+So its the job of libraries to \f[I]extend\f[R] its functionality.
+This should never be done by wrapping the \f[C]Entry\f[R] type itself
+but by providing and implementing an extension trait on it.
+.PP
+Same goes for extending the \f[C]Store\f[R] type: never wrap it, always
+provide an extension trait for it.
+.PP
+These two rules ensure that the type does not lose any functionality
+from a wrapping.
+\f[C]Deref\f[R] could do that, but not over muliple levels, so extension
+traits it is.
+It also most likely results in functions inside the extension trait
+which all return a \f[C]Result<_, _>\f[R].
+.SS Libraries
+.PP
+In the next few sections, conventions and best practices for writing a
+imag library are written down.
+.PP
+A developer of imag should read this carefully, a user may skip this
+section or cross-read it for better understanding of the imag project.
+.SS Library naming
+.PP
+Libraries which provide functionality for entries or the store but no
+domain-functionality should be named \[lq]libimagentrything\[rq] whereas
+\[lq]thing\[rq] stands for what the library provides.
+.PP
+All domain libraries should be prefixed with \[lq]libimag\[rq].
+.SS Library scope
+.PP
+A library should never introduce utility functionality which could be
+useful for other libraries as well.
+If there is no such functionality available, the \[lq]libimagutil\[rq]
+or \[lq]libimagentryutil\[rq] might be a place where such a function
+would go to.
+.PP
+If a library has to introduce free functions in its public interface,
+one should think hard whether this is really necessary.
+.SS Library error types/kinds
+.PP
+Libraries must use \[lq]failure\[rq] to create error objects.
+.SS Libraries with commandline frontends
+.PP
+Libraries with commandline frontends provide end-user functionality.
+They are called \[lq]domain\[rq] libraries.
+Normally, they depend on one or more \[lq]libimagentrything\[rq]
+libraries.
+They should be named \[lq]libimagthing\[rq], though.
+For example: \[lq]libimagdiary\[rq], \[lq]libimagtimetrack\[rq] or
+\[lq]libimagwiki\[rq], whereas the commandline frontends would be
+\[lq]imag-diary\[rq], \[lq]imag-timetrack\[rq] and \[lq]imag-wiki\[rq],
+respectively.
+.PP
+If such a library needs to depend on another \[lq]libimagthing\[rq], for
+example if \[lq]libimagdiary\[rq] needs to depend on
+\[lq]libimagnote\[rq], one should think about this and whether the
+functionality could be outsourced to a more general
+\[lq]libimagentrything\[rq].
+.SS Library testing
+.PP
+All libraries should be tested as much as possible.
+Sometimes it may not be possible without a lot of effort, but still:
+more tests = better!
+.SS Commandline tools
+.PP
+The commandline tools are the CLI-frontends for their respective
+libraries.
+So \f[C]libimagdiary\f[R] has a CLI frontend \f[C]imag-diary\f[R].
+.PP
+Those CLI frontends use functionality from \f[C]libimagrt\f[R] to build
+a commandline interface which is consistent with the rest of the
+ecosystem.
+.PP
+Commandline applications use the runtime interfaces for receiving IDs
+from the CLI or IDs which are piped into the application.
+Commandline applications use the `stdin'/`stdout'/`stderr' wrappers
+provided by the runtime (see section below).
+.PP
+Commandline applications are \f[I]only\f[R] interactive when specified
+by the user (normally via a \f[C]--interactive\f[R] flag).
+An application \f[I]must\f[R] provide the full functionality via its
+commandline interface, thus it is not allowed to provide functionality
+which is only usable in interactive mode.
+.SS IO
+.PP
+There are minor restrictions how imag tools should do IO.
+A good rule of thumb is (but most certainly only applicable when
+programming an imag tool in Rust): use \f[C]libimagrt\f[R] to do IO of
+any kind.
+.PP
+For more information, or if not using Rust as programming language: the
+documentation of \f[C]libimagrt\f[R] describes how IO should happen
+(which output stream to use, how input should be done).
+.SH Writing an imag module
+.PP
+So you want to write a module for imag.
+That\[cq]s nice.
+.PP
+This guide helps you getting started.
+It also can help you understanding how imag modules work, so even if you
+do not want to write a full new module, but extend or alter one, this
+guide may help you.
+.SS Data layout
+.PP
+First, you have to think about what data you want to store.
+What functionality do you want to provide and what data that creates.
+.PP
+In this example, we\[cq]re writing a module that stores numbers.
+We\[cq]re writing the appropriate library for that as well as a
+commandline frontend.
+.SS libimagnumberstorage
+.PP
+We\[cq]re writing a \f[C]libimagnumberstorage\f[R] which provides the
+core functionality of our module: Storing numbers.
+.PP
+That library can then be used by other library authors and by the
+commandline interface implementation.
+.SS Setup
+.PP
+So what do we need to do to write this library:
+.IP "1." 3
+Create a new \[lq]lib\[rq] crate.
+Because we\[cq]re writing a \[lq]domain\[rq] library, we\[cq]re doing
+this in the \f[C]lib/domain\f[R] subdirectory:
+\f[C]cd lib/domain; cargo new --lib libimagnumberstorage\f[R].
+.IP "2." 3
+After creating the library, we have to add the new library to the
+\f[C]/Cargo.toml\f[R] field and add the missing metadata in the new
+\f[C]/lib/domain/libimagnumberstorage/Cargo.toml\f[R] file.
+.PP
+That was the setup part.
+Now we can implement our functionality.
+For that, we need to \f[I]extend\f[R] two types from
+\f[C]libimagstore\f[R], so we have our first dependency here.
+.SS Dependencies to other libraries
+.IP "3." 3
+Put \f[C]libimagstore\f[R] as a dependency in the
+\f[C]/lib/domain/libimagnumberstorage/Cargo.toml\f[R] file.
+By using
+\f[C]libimagstore = { version = \[dq]0.10.0\[dq], path = \[dq]../../../lib/core/libimagstore\[dq] }\f[R]
+we automatically get all the goodness of Cargo, so that releases
+automagically work as expected, but when developing locally, the local
+version of \f[C]libimagstore\f[R] is used.
+Of course, the \f[C]version\f[R] has to be the latest released version.
+.IP "4." 3
+For error handling, we also need to import \f[C]libimagerror\f[R].
+.IP "5." 3
+For easy header-editing, we import \f[C]toml\f[R] and
+\f[C]toml-query\f[R].
+.IP "6." 3
+For error-type creating, we import \f[C]error-chain\f[R].
+.SS Interface
+.IP "7." 3
+Then, we have to \f[I]extend\f[R] two types:
+.RS 4
+.IP "1." 3
+\f[C]libimagstore::store::Store\f[R] has to be extended so we can
+implement a CRUD interface for our special entries.
+.IP "2." 3
+\f[C]libimagstore::store::Entry\f[R] has to be extended so we can get
+our stored numbers in a convenient way.
+.RE
+.PP
+Our interface should roughly look like this:
+.IP
+.nf
+\f[C]
+store.get_stored_number(\[dq]5\[dq]) -> Result<FileLockEntry, _>
+store.store_number(\[dq]5\[dq]) -> Result<FileLockEntry, _>
+store.delete_number(\[dq]5\[dq]) -> Result<(), _>
+\f[R]
+.fi
+.PP
+You notice that the \f[C]Store\f[R] returns \f[C]FileLockEntry\f[R]
+objects rather than \f[C]Entry\f[R] objects.
+And that\[cq]s ok.
+A \f[C]FileLockEntry\f[R] is a \f[C]Entry\f[R], but ensures that we are
+the only ones editing that entry.
+So, we have to implement our number-storing-interface on \f[C]Entry\f[R]
+as well:
+.IP
+.nf
+\f[C]
+entry.get_number() -> Result<usize>
+entry.set_number(usize) -> Result<()>
+\f[R]
+.fi
+.PP
+All those \[lq]extensions\[rq] are implemented as traits which are then
+implemented for \f[C]Store\f[R] and \f[C]Entry\f[R].
+.PP
+Normally, we create new files for that, as well as for the error types
+we need:
+.IP \[bu] 2
+\f[C]/lib/domain/libimagnumberstorage/src/store.rs\f[R]
+.IP \[bu] 2
+\f[C]/lib/domain/libimagnumberstorage/src/entry.rs\f[R]
+.IP \[bu] 2
+\f[C]/lib/domain/libimagnumberstorage/src/error.rs\f[R]
+.PP
+where \f[C]store.rs\f[R] contains a trait \f[C]NumberStorage\f[R] and
+\f[C]entry.rs\f[R] contains a trait \f[C]NumberEntry\f[R].
+\f[C]error.rs\f[R] contains the invocation of the
+\f[C]error_chain!{}\f[R] macro.
+Error types from \f[C]libimagstore\f[R] and others are linked in.
+.SH Modules
+.PP
+A module is a functionality of the program.
+There is a huge list of modules available in the imag core distribution.
+.PP
+Some of the modules shipped with imag cover core functionality such as
+linking, tagging or references to files outside of the store or even the
+store interface itself.
+Others cover things like diary, notes, wiki or bookmarks.
+These are also called \[lq]domains\[rq].
+.PP
+We try really hard to offer a consistent commandline user interface over
+all of these modules.
+.PP
+The following sections describe each module in detail, including its
+purpose and its provided functionality.
+.SS Bookmarks
+.PP
+The Bookmarks module is for keeping URLs as bookmarks, tagging and
+categorizing them and finally also open them in the browser.
+.SS Category
+.PP
+A tool to create categories and set/get them for entries.
+.PP
+The difference between a category and a tag is that a category must
+exist before it can be used and all entries of a category are linked to
+the \[lq]category entry\[rq] internally.
+.SS Diary
+.PP
+The diary module is for keeping your diary notes.
+.PP
+The diary module giv3s you the possibility to write your diary in imag.
+It offers daily, hourly and minutely entries (the latter beeing more
+like a private tumble-blog).
+.PP
+Exporting the diary is possible, so one can write it in markdown and
+later pass that to pandoc, if desired, to generate a website or book
+from it.
+.SS Edit
+.PP
+The \f[C]imag-edit\f[R] command is for simply editing store entries with
+the \f[C]$EDITOR\f[R].
+.PP
+It is based on libimagentryedit (Section\ 7.7).
+.SS Entry
+.PP
+Plumbing tool for modifying and querying structured data in entries.
+.SS Init
+.PP
+This is the only \f[C]imag-*\f[R] command which does \f[I]not\f[R] set
+up a runtime and check whether the store is available.
+This command can be used to set up a imag store.
+.PP
+It also puts a default configuration in the right place and initializes
+a git repository, if there is a \f[C]git\f[R] command in \f[C]$PATH\f[R]
+(via calling git on the commandline, not via \f[C]libgit2\f[R] or some
+other library).
+.SS Link
+.PP
+The linking module \f[C]imag-link\f[R] is one of the plumbing modules.
+It offers the possibility to link entries in the store.
+.PP
+It also offers the functionality to link to external sources.
+This functionality \f[I]can\f[R] be used to link to external URLs, but
+the bookmarking module should be used to do this (see Section\ 6.1).
+.PP
+The linking module offers functionality to add, remove and list both
+internal (store entry to store entry) and external (store entry to URL)
+links.
+.SS Internal linking
+.SS External linking
+.PP
+A store entry can only have \f[I]one\f[R] external link.
+Therefor, when you create an external link, the linking module creates a
+new entry in the store which links to this URL.
+The linking module then links you entry with this new entry by using an
+internal link.
+This way one entry can have multiple external links attached to it and
+external links are deduplicated automatically.
+.SS Log
+.PP
+The \[lq]imag-log\[rq] module is a lightweight interface to the
+\[lq]imag-diary\[rq] command.
+.PP
+It is intended as a tumbeblog-like diary, where one does not care to
+fire up an editor and type in a long text, but rather type a few words
+and forget about it:
+.SS Usage
+.PP
+Logs can be created via an entry in the configuration file in the
+section \f[C]log\f[R]:
+.IP
+.nf
+\f[C]
+[log]
+logs = [\[dq]work\[dq], \[dq]hobby\[dq], \[dq]music\[dq]]
+default = \[dq]hobby\[dq]
+\f[R]
+.fi
+.PP
+The \f[C]default\f[R] key is required and the name which is used here
+\f[I]must\f[R] appear in the \f[C]logs\f[R] array.
+.PP
+In the above configuration snippet, the logs \f[C]work\f[R],
+\f[C]hobby\f[R] and \f[C]music\f[R] are created.
+The user may now log to one of these logs with:
+.IP
+.nf
+\f[C]
+imag log --to <logname> \[dq]Some message\[dq]
+# or
+imag log -t <logname> \[dq]Some message\[dq]
+# or, to the default log:
+imag log \[dq]Some message\[dq]
+\f[R]
+.fi
+.PP
+Logs can be read by naming the log:
+.IP
+.nf
+\f[C]
+imag log show work
+\f[R]
+.fi
+.PP
+which prints one log per line (including time it was logged).
+.SS Mails
+.PP
+ * * * * *
+.PP
+\f[B]NOTE:\f[R] This is mostly a todo-list for the \f[C]imag-mail\f[R]
+command.
+Nothing shown here is implemented.
+This \[lq]documentation-to-be\[rq] should be moved to
+\f[C]imag-mail --help\f[R] eventually.
+This list might be incomplete, details might be not possible to
+implement in the way described or other dragons.
+.PP
+\f[B]Target audience:\f[R] People who want to implement
+\f[C]imag-mail\f[R].
+.PP
+ * * * * *
+.PP
+The Mails module implements a commandline email client.
+Emails can be written (via \f[C]$EDITOR\f[R]) and viewed, also in
+threads.
+Emails can be crawled for creating new contacts.
+.PP
+A Text User Interface is not planned, but might be there at some point.
+.PP
+The mail module implements a minimal Email client.
+It does not handle IMAP syncing or SMTP things, it is just a
+\f[I]viewer\f[R] for emails (a MUA).
+.PP
+The goal of the initial implementation is only a CLI, not a TUI like
+mutt offers, for example (but that might be implemented later).
+As this is an imag module, it also creates references to mails inside
+the imag store which can be used by other tools then (for example
+\f[C]imag-link\f[R] to link an entry with a mail - or the imag entry
+representing that mail).
+.PP
+So this module offers functionality to read (Maildir) mailboxes, search
+for and list mails and mail-threads and reply to mails (by spawning the
+\f[C]$EDITOR\f[R]).
+.PP
+Outgoing mails are pushed to a special directory and can later on be
+send via \f[C]imag-mail\f[R] which calls a MTA (for example msmtp) and
+also creates store entries for the outgoing mails.
+.SS Configuration
+.PP
+The following configuration variables are available for the imag-mail
+command:
+.IP \[bu] 2
+\f[C]mail.defaultaccount\f[R]: The name of the default account to use if
+the commandline parameters do not specify which account to use.
+The name must be in the \f[C]mail.accounts\f[R] array.
+.IP \[bu] 2
+\f[C]mail.accounts\f[R]: An array of account configuration.
+Each element in the array is a table of the following key-value pairs:
+.RS 2
+.IP \[bu] 2
+\f[C]name\f[R]: the name of the account.
+Names must be unique.
+Required.
+.IP \[bu] 2
+\f[C]outgoingbox\f[R]: Path to mailbox to use for outgoing email.
+Required.
+.IP \[bu] 2
+\f[C]draftbox\f[R]: Path to mailbox to use for outgoing email.
+Required.
+.IP \[bu] 2
+\f[C]sentbox\f[R]: Path to mailbox to use for sent email.
+Required.
+\f[C]\f[R]maildirroot\[ga]: Path to folder where all mailboxes for this
+account are located.
+Required.
+.IP \[bu] 2
+\f[C]fetchcommand\f[R]: What commandline to invoke for fetching mails
+for this account.
+Optional - if not used, the global \f[C]mail.fetchcommand\f[R] will be
+used.
+.IP \[bu] 2
+\f[C]postfetchcommand\f[R]: What commandline to invoke after fetching
+mails for this account.
+Optional - if not used, the global \f[C]mail.postfetchcommand\f[R] will
+be used.
+.IP \[bu] 2
+\f[C]sendcommand\f[R]: What commandline to invoke for sending mails for
+this account.
+Optional - if not used, the global \f[C]mail.sendcommand\f[R] will be
+used.
+.IP \[bu] 2
+\f[C]postsendcommand\f[R]: What commandline to invoke after sending
+mails for this account.
+Optional - if not used, the global \f[C]mail.postsendcommand\f[R] will
+be used.
+.RE
+.IP \[bu] 2
+\f[C]mail.fetchcommand\f[R]: Command to use for fetching mail if no
+account-specific command was specified Available variables:
+.RS 2
+.IP \[bu] 2
+\f[C]{{accountname}}\f[R] - name of the account to fetch mail for.
+.IP \[bu] 2
+\f[C]{{boxes}}\f[R] - a list of maildir paths to the boxes to fetch
+email for.
+imag provides primitives to transform this array.
+An example configuration for fetching with \f[C]offlineimap\f[R] might
+look like this:
+\f[C]offlineimap -a {{accountname}} -f {{concatsep \[dq],\[dq] (replace \[dq]/home/user/mails/\[dq] \[dq]\[dq] boxes)}}\f[R]
+to concatenate all boxes with a comm