Merge pull request #525 from matthiasbeyer/update-doc

Update doc
This commit is contained in:
Matthias Beyer 2016-07-14 21:11:30 +02:00 committed by GitHub
commit 0c5674dd47
65 changed files with 487 additions and 719 deletions

View file

@ -1,7 +1,7 @@
--- ---
title: imag Project title: imag User Documentation
version: 0.1 version: 0.1.0
date: January 2016 date: July 2016
listings: true listings: true
codeBlockCaptions: true codeBlockCaptions: true
figureTitle: "Figure" figureTitle: "Figure"

View file

@ -1,25 +1,10 @@
# Introduction {#sec:introduction} # Introduction {#sec:introduction}
In the following work, we define the architecture, internal interfaces and the This document aims to be the user documentation for imag, the personal
implementation of `imag` (called "the program" in the following chapters). information management suite for the commandline.
The program is intended to be an _Personal Information Management Suite_ If you have any objections, suggestions for improvements, bugs, etc, please file
(PIM-Suite), featuring all components such a suite should have, including them in the github repository you got this documentation from.
contact management, calendar, todo-list functionality, etc.
The program is intended to be used by so-called "power-users", therefor it is a
commandline application which offers a polished interface to the user and is not
bound to an editor, e-mail reader, RSS reader, etc. The program uses standards
as icalendar, vcard, RSS/Atom, Markdown, etc.
The development of this program may adapt other programs. For example, the
todo-module may be implemented with the "taskwarrior" application, if possible,
so we try to re-use functionality which is implemented elsewhere and where other
people put a lot of effort into. We clearly do not want to duplicate
functionality, work and effort or implementations.
"imag" is a single-user, one-shot program. It is not intended to be used by
multiple users with the same storage at the same time.
This may change in the future.
## The Problem {#sec:intro:problem} ## The Problem {#sec:intro:problem}
@ -57,3 +42,6 @@ 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 library of the "imag" distribution to store content in the store of "imag" and
make it visible to "imag" this way. make it visible to "imag" this way.
This is a technical detail a user does not necessarily need to know, but as imag
is intended for power-users anyways, we could say it fits here.

View file

@ -1,64 +1,67 @@
# The Store {#sec:thestore} # The Store {#sec:thestore}
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.
One could say that the store is simply a databases, 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.
A user should always be able to read her data without great effort and putting
everything in a _real_ database like sqlite or even postgresql would need a user
to install additional software just to read his own data. We don't want that.
Text is readable until the worlds end and we think it is therefor better to
store the data in plain text.
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.
## File Format {#sec:thestore:fileformat} ## File Format {#sec:thestore:fileformat}
The content in the store MUST BE encoded in either Unicode UTF-8 or ASCII. The contents of the store are encoded in either UTF-8 or ASCII. Either way, a
Each "Entry" (File) MUST HAVE a "Header" component as well as a "Content" normal text editor (like `vim` or the other one) will always be sufficient to
component. dog into the store and modify files. For simple viewing even a pager (like
Each "Entry" in the store MUST start with three single dashes ("-") followed `less`) is sufficient.
by a newline character, named "initial marker" in the following chapter.
The Header follows the initial marker (@sec:thestore:fileformat:header). Each entry in the store consists of two parts:
The Header MUST BE followed by a line which contains three single dashes ("-")
and a newline character, called "header-close marker" in the following 1. Header
chapter. 1. Content
The content follows the header-close marker (@sec:thestore:fileformat:content).
The following section describe their purpose.
### Header Format {#sec:thestore:fileformat:header} ### Header Format {#sec:thestore:fileformat:header}
The header format MUST BE "TOML". The header format is where imag stores its data. The header is an area at the
The sections which MAY or MUST be in the header are defined in the following top of every file which is seperated from the content part by three dashes
chapters. (`---`). Between these three dashes there is structured data. imag uses `TOML`
as data format for this structured data, because it fits best and the available
`TOML` parser for the rust programming language is really good.
#### Header section: "imag" {#sec:thestore:fileformat:header:imag} The header can contain any amount of data, but modules (see @sec:modules) are
restricted in their way of altering the data.
The header MUST contain a section called "imag", where the automatically by the So normally there are several sections in the header. One section (`[imag]`) is
program generated data is stored in. always present. It contains a `version` field, which tells imag which version
The contents of this section is edited via commandline calls or by the this file was created with (the version information is _also_ encoded in the
program implicitely and SHOULD NOT be edited by the user. filename, just in case things change in the future). It also contains a `links`
field which is an Array of values. This `links` field is for linking (see
@sec:thestore:linking) to other entries in the store.
This "imag" section MUST contain the following keys 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
1. A "version" Key. The version stored here is the version of the Store, the read other sections than its own. This is not enforced by imag itself, though.
Entry was created with.
The "imag" section MAY contain
1. A section "imag.links" where a module is allowed to store URIs in a flat
list
1. A section "imag.content", used for referring to external content.
The key "uri" is the only one which is required, it refers to external
content.
An explicitely suggested key is "file" for referring to a _local Mirror_ of
the content.
#### Header section: "custom" {#sec:thestore:fileformat:header:custom}
The header MAY contain a section named "custom".
The user is free to store arbitrary data here.
The user is also free to edit this section by either commandline or editor.
#### Module Header section {#sec:thestore:fileformat:header:module}
The header MAY contain a section named after a module.
The corrosponding module is allowed to store arbitrary data in this section.
### Content Format {#sec:thestore:fileformat:content} ### Content Format {#sec:thestore:fileformat:content}
The content is the part of the file where the user is free to enter any The content is the part of the file where the user is free to enter any textual
textual content. content. The content may be rendered as Markdown or other markup format for the
The content MAY BE rendered as Markdown or other markup format for the users users convenience. The store does never expect and specific markup and actually
convenience. the markup implementation is not inside the very code of imag.
The Store library MUST NOT expect any particular markup format.
Technically it would be possible that the content part of a file is used to
store binary data. We don't want this, though.
### Example {#sec:thestore:fileformat:example} ### Example {#sec:thestore:fileformat:example}
@ -69,17 +72,10 @@ An example for a file in the store follows.
[imag] [imag]
version = "0.2.0" version = "0.2.0"
[imag.content] imag.links = ["/home/user/more_kittens.mpeg"]
url = "file://home/user/kittens.mpeg"
imag.links = [
"imag://home/user/more_kittens.mpeg"
]
[examplemodule] [examplemodule]
arbitrary = data arbitrary = "data"
[custom]
truth = 42
--- ---
This is an example text, written by the user. This is an example text, written by the user.
@ -89,23 +85,25 @@ This is an example text, written by the user.
## File organization {#sec:thestore:fileorganization} ## File organization {#sec:thestore:fileorganization}
The "Entries" are stored as files in the "Store", which is a directory the The "Entries" are stored as files in the "Store", which is a directory the
user has access to. user has access to. The store may exist in the users Home-directory or any
The store MAY exist in the users Home-directory or any other directory the other directory the user has read-write-Access to.
user has Read-Write-Access to.
The Path of each File is shown as absolute path in this paper, while the root Each module stores its data in an own subdirectory in the store. This is because
is always the store directory. we like to keep things ordered and clean, not because it is technically
This Path is named "Storepath". necessary.
So if the store exists in `/home/user/store/`, a file with the Storepath
We name the path to a file in the store "Store id" or "Storepath" and we often
refer to it by using the store location as root.
So if the store exists in `/home/user/store/`, a file with the storepath
`/example.file` is (on the filesystem) located at `/example.file` is (on the filesystem) located at
`/home/user/store/example.file`. `/home/user/store/example.file`.
A Storepath contains predefined parts: A storepath contains predefined parts:
* The module name of the Module the Entry belongs to. * The module name of the Module the Entry belongs to, as said above.
This part is a directory. This part is always a directory.
* The version (semantic versioning applies) of the module storing the Entry * The version (semantic versioning applies) of the module storing the entry.
This part is a postfix to the filename This part is a postfix to the filename.
The pattern for the storepath is The pattern for the storepath is
@ -113,66 +111,38 @@ The pattern for the storepath is
/<module name>/<optional sub-folders>/<file name>~<sem version> /<module name>/<optional sub-folders>/<file name>~<sem version>
``` ```
So if a Module named "ExampleModule" with version "0.1" stores a file in the So if a module named "example-module" with version "0.1.0" stores a file in the
Store, the Storepath for a file with the name "example" is Store, the storepath for a file with the name "example" is
"/ExampleModule/example~0.1". "/example-module/example~0.1.0".
Any number of subdirectories MAY BE used, so creating folder hierarchies is Any number of subdirectories may be used, so creating folder hierarchies is
possible and valid. possible and valid. A file "example" for a module "module" in version "0.1.0"
A file "example" for a module "module" in version "0.1" would be stored in would be stored in sub-folders like this:
sub-folders like this:
``` ```
/module/some/sub/folder/example~0.1 /module/some/sub/folder/example~0.1.0
``` ```
A given file MUST only exist once with the same path. For example, it is valid if these files exist at the same time:
For example, it is invalid if these files exist at the same time:
* /foo/bar~0.2 * /foo/bar~0.2
* /foo/bar~1.3 * /foo/bar~1.3
To future-proof the System it is thus necessary to create a disambiguation at It might not be sane, though.
the store level. Thus if a library wants to retrieve a file from the Store
it MUST at least accept files from it's current advertised version. It MAY
accept older files and it MAY transform them and resubmit them in the newer
version.
For this there will be an enum returned for each given Entry. It will have these To future-proof the system it is necessary to provide a way for modules to
members: differentiate in their versions on the store level. Thus if a module wants to
retrieve a file from the store it must at least accept files from it's current
- `Compatible`, for version matches advertised version. It may accept older files and it may transform them and
- `PossiblyIncompatible`, if the current version is at least a major number resubmit them in the newer version.
further
- `Incompatible`, if the file is a at least a major number further
## Store path links {#sec:thestore:links} ## Store path links {#sec:thestore:links}
Linking entries MUST BE version independent. Linking entries is version independent.
This means if an entry "a" from a module "A" gets written to the store, it may This means if an entry "a" from a module "A" gets written to the store, it may
link to an entry "b" from a module "B", which is in version "0.1" at the moment. link to an entry "b" from a module "B", which is in version "0.1.0" at the
If the module "B" gets updated, it might update its entries in the store as moment. If the module "B" gets updated, it might update its entries in the store
well. as well. The link from the "a" should never get invalid in this case, though it
The link from the "a" MUST NOT get invalid in this case. is not ensured by the core of imag itself.
This is accomplished by linking without the version number: So a link for the
entry
```
/module/some/sub/folder/example~0.1
```
is
```
imag://module/some/sub/folder/example
```
As shown in the example, a link to imag-internal entries, the link is prefixed
with a "imag://" identifier.
This prefix is optional.
A link to external content MUST NEVER be prefixed this way.
The path of the internal link MUST NEVER be relative, but always absolute from
the root directory of the store.

View file

@ -1,35 +1,29 @@
## Linking from an store entry {#sec:thestore:linking} ## Linking from an store entry {#sec:thestore:linking}
In @sec:thestore:fileformat:header:imag it was already defined that there MUST As described in @sec:intro:problem the purpose of imag is to _link_ content
BE a section "imag" in the header. This section can be used to link to together. The following section describes, from a technical view, how this is
"internal" and "external" content, whereas "internal content" refers to entries done in imag.
which are stored in the very same store as the entry which links.
The term "external content" means content which is not stored in the
store, but elsewhere on the filesystem or the network (thus, an URL is valid
external content).
Entries can be referenced from the content part. For example, if the content There are two ways of linking in imag. You can either link internally or
part is written in Markdown, the user is able to link content within the externally. The following sections describe the differences.
Markdown text.
These links could be either links to internal content or external content.
### Linking to internal content {#sec:thestore:linking:internal} ### Linking to internal content {#sec:thestore:linking:internal}
Links to internal content are stored in the Array "imag.links = []". Internal links are links between store entries themselfes. This means that one
Each entry in this array MUST BE a String which is an absolute path to a store store entry can link to another. Actually, links are not pointers but rather
entry (@sec:thestore:links). tries between entries, meaning that an link is not directed, but always a
two-way pointer.
As links from within the content part of a module is not cross-compatible over How linking works from the user interface is described in @sec:modules:link.
modules, each module SHOULD store the links which are in the content
part also in the "imag.links" Array. This way, other modules can read the links
without having knowledge about how to parse the content part of an entry.
### Linking to external content {#sec:thestore:linking:external} ### Linking to external content {#sec:thestore:linking:external}
Each Entry can store _one link to external content at most_. Linking to external content means linking to files or directories which do not
live inside the store itself but outside of it.
This link is stored in the header field "imag.content.uri" Each store entry can store _one link to external content at most_.
(@sec:thestore:fileformat:header:imag).
A key "imag.content.file" COULD be used for a local mirror of the content which External linking should not be used from the user interface but rather the
is referenced by "imag.content.uri". `ref` feature (@sec:modules:ref) should be used.
@sec:modules:ref describes why that is.

View file

@ -1,13 +0,0 @@
## Tagging entries {#sec:thestore:tagging}
A store entry MAY be tagged. A tag is a String which matches the
regular expression in @lst:tagging:regex
```{#lst:tagging:regex .numberLines caption="Regular Expression for Tags"}
/^[a-zA-Z]([a-zA-Z0-9_-]*)$/
```
Tags MUST BE stored in the header section "imag" in the key "tags" as an Array
of Strings.
The tags MUST BE sorted in alphabetical order.

View file

@ -1,71 +0,0 @@
# libutil {#sec:libutil}
<!--
Might not get this big, but its here for DRYness
-->
The utility library of the project contains utility functionality which is
used by all other libraries and/or binaries.
It is explicitely not intended for module-use only, but for all other libraries.
## Key-Value split {#sec:libutil:kvsplit}
This helper implements functionality to split key-value string into two parts.
It was introduced to simplify commandline specification for header fields (see
@lst:kvsplit:headerspec).
```{#lst:kvsplit:headerspec .bash .numberLines caption="Headerfield spec"}
imag store create --path /some.entry entry --header field=foo
# ^^^^^^^^^
```
It is implemented by introducing a `KeyValue` type which is generic over Key
and Value. This type gets implemented `KeyValue<String, String> for String` to
be able to split a `String` into two `String` objects, key and value
respectively. The implementation is realized via Regex.
The `KeyValue` type implementes `Into<(K, V)>` for convenience.
## Error tracing {#sec:libutil:errortrace}
The error tracing functions are functions which help printing an error chain
to the user.
It allows to trace nested errors like @lst:errtrace:exampleerror to the user
in a backtrace-ish way (@lst:errtrace:exampletrace).
```{#lst:errtrace:exampleerror.rust .numberLines caption="Error chain"}
ErrA::new(a_errorkind,
Some(Box::new(ErrB::new(b_errorkind,
Some(Box::new(ErrC::new(c_errorkind,
None)))
)))
)
```
The variants of the function allow limiting the trace to a certain depth or
printing the error trace to the debug output stream.
```{#lst:errtrace:exampletrace .numberLines caption="Error trace"}
[Error][c_errorkind]: Some C-error text -- caused:
[Error][b_errorkind]: Some B-error text -- caused:
[Error][a_errorkind]: Some A-error text
```
## Variant generator {#sec:libutil:vargen}
The `generate_variants()` function can be used to generate variants of a base
vector value.
```{#lst:vargen:exampleuse .rust .numberLines caption="Variant generation"}
let base = 1;
let vars = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let res = generate_variants(base, vars, &|base, var| base + var);
assert!(res == vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
```
As shown in @lst:vargen:exampleuse (from the tests), can this function
be used to generate values from a base value.

View file

@ -1,77 +0,0 @@
# librt {#sec:librt}
The runtime library provides types and functions which MUST be used by the
modules to implement the commandline interface, configuration file parsing and
logging.
The runtime library provides basic functionality for configuration file parsing
and logging setup.
The runtime library also provides helper functions for building a commandline
interface.
## Configuration file {#sec:librt:cfg}
The runtime library SHOULD read the configuration file, if it can be found.
If the configuration file cannot be found, the following variables are set to
their default values as shown in @tbl:librt:cfg:defaultvalues.
| Variable | Value |
| :------------- | :------------------- |
| verbosity | false |
| debugging | false |
| store location | `$HOME/.imag/store/` |
Table: Default values for configuration if configuration file unavailable
{#tbl:librt:cfg:defaultvalues}
### Location of the configuration file {#sec:librt:cfg:location}
For the configuration file is searched at the following locations:
1. Path: `$runtimepath/config`
1. Path: `$runtimepath/config.toml`
1. Path: `$runtimepath/imagrc`
1. Path: `$runtimepath/imagrc.toml`
1. Path: `$HOME/.imag/config`
1. Path: `$HOME/.imag/config.toml`
1. Path: `$HOME/.imag/imagrc`
1. Path: `$HOME/.imag/imagrc.toml`
1. Path: `$XDG_CONFIG_DIR/imag/config`
1. Path: `$XDG_CONFIG_DIR/imag/config.toml`
1. Path: `$XDG_CONFIG_DIR/imag/imagrc`
1. Path: `$XDG_CONFIG_DIR/imag/imagrc.toml`
1. Path in the environment variable `$IMAG_CONFIG`
If neither of these configuration files are found, the program MUST USE the
default values for the minimum required variables
(@tbl:librt:cfg:defaultvalues).
### Contents of the configuration file {#sec:librt:cfg:contents}
The contents of the configuration file MUST BE encoded in Unicode UTF-8.
The contents of the configuration file are structured as TOML, regardless of the
file extension.
The configuration file contains several sections:
1. The `base` section, which contains basic variables
(@tbl:librt:cfg:contents:base)
1. The `modules` section, which contains a section for each module.
1. The `store` section, which contains configuration on the behaviour of the
store (@tbl:librt:cfg:contents:store)
| Variable | Type |
| :------------- | :------ |
| verbosity | boolean |
| debugging | boolean |
| store location | Path |
Table: "Base" variables in the configuration file {#tbl:librt:cfg:contents:base}
| Variable | Type | Meaning |
| :-------- | :------ | :----------------------------------------------- |
| git-vcs | boolean | Whether the store is version controlled with git |
Table: "store" variables in the configuration file {#tbl:librt:cfg:contents:store}

View file

@ -1,166 +0,0 @@
# libstore {#sec:libstore}
<!--
Store functionality
-->
The "libstore" MUST define the programming-language level interface to the
store on the file system.
The library therefor MUST define and export types which can be used to get data
from the filesystem.
## Types {#sec:libstore:types}
The types in @tbl:libstore:types are exported by the library.
| Type | Meaning |
| :------------ | :----------------------------------------------- |
| Entry | Entity on the Filesystem, File |
| EntryContent | User-Content of the Entry |
| EntryHeader | Header of the Entry |
| Store | Store interface |
| FileLockEntry | Handle to an Entry |
Table: Types the store library exports {#tbl:libstore:types}
Each of these types MUST export functions to work with the data the objects of
the types contain.
### Entry {#sec:libstore:types:entry}
The `Entry` type MUST hold the following content:
- A path where on the filesystem the acutal file lives
- An instance of `EntryContent` as interface to the content of the file
(@sec:libstore:types:entrycontent).
- An instance of `EntryHeader` as interface to the header of the file
(@sec:libstore:types:entryheader).
The entry type MUST export functions to get
- The content object
- The header object
- The path of the actual file
The entry type MUST export functions to set
- The header object
- The content object
### EntryContent {#sec:libstore:types:entrycontent}
The `EntryContent` type is an type-alias for `String`.
### EntryHeader {#sec:libstore:types:entryheader}
The `EntryHeader` type is an wrapper around the type, the TOML-Parser library
exports.
It SHOULD contain utility functions to work with the header in a convenient way.
### Store {#sec:libstore:types:store}
The `Store` type MUST represent the interface to the store on the filesystem.
It MUST contain CRUD-functionality to work with the entries in the store.
It MUST contain a variable which contains the path of the store on the
filesystem which is represented by an object of this type.
It also MUST contain a getter for this variable.
It MUST NOT contain a setter for this variable, as changing the store while the
programm is running is not allowed.
## Hook system {#sec:libstore:hooks}
The store library includes a hook system, which can be used to execute arbitrary
code before or after the store was accessed. The following hooks are available:
* `PreReadHook`
* `PostReadHook`
* `PreCreateHook`
* `PostCreateHook`
* `PreUpdateHook`
* `PostUpdateHook`
* `PreDeleteHook`
* `PostDeleteHook`
These are called "Hook positions" in the following.
Which are executed before or after the store action is executed. The `Pre`-Hooks
can deny the execution by returning an error. The `Post`-Hooks can (for the
appropriate store actions) alter the hook result.
Registering hooks with the store is implemented via functions on the `Store`
type itself. Hooks MUST NEVER be removed from the `Store` object during runtime,
only adding hooks to the store is allowed.
As the hooks are simply trait objects, one is able to implement arbitrary hooks,
for example
* Simple consistency-checks for the store
* Version control system adaption for the store (via git for example)
* Encryption of store entries (via gnupg for example)
* Automatic backup on every change to the store (via rsnapshot for example)
Some hooks MAY be shipped with the imag source distribution and be enabled by
default.
Execution order of the hooks is a not-yet-solved problem.
### Hook-Aspects {#sec:libstore:hooks:aspects}
Each hook can be assigned to an "Aspect". There MAY BE zero or more aspects for
each Hook position. Aspects can be sorted and configured via the configuration
file, whereas each aspect has its own configuration section:
```{#lst:hooks:aspects:cfg .toml .numberLines caption="Hook config section"}
[store]
// Defines order of aspects for the pre-read hook position
pre-read-aspects = [ "misc" ]
// Defines order of aspects for the post-read hook position
post-read-aspects = [ "decryption" ]
// ...
// configuration for the "misc" hook aspect
[[aspects.misc]]
parallel-execution = true
// configuration for the "decryption" hook aspect
[[aspects.decryption]]
parallel-execution = false
```
Aspects are executed in the same order they appear in the configuration (in the
`pre-read-aspects = []` array, for example).
Aspects _could_ be sorted in different order for each hook position.
Aspect names are unique, so one aspect "misc" in "pre-read-aspects" is the
same as in "post-read-aspects" and both be configured via `aspects.misc`, though
they do not share hooks.
Aspects where parallel execution is enabled MAY BE executed in sequence if one
of the hooks wants mutable access to the data they hook into.
Hooks can then be assigned to one hook aspect. Hooks MUST never be assigned to
more than one hook aspect. Hooks which are not assigned to any aspect MUST never
be executed.
```{#lst:hooks:cfg .toml .numberLines caption="Hook configuration"}
[hooks]
// decrypt hook with gnupg. An appropriate "gnupg-encrypt" hook must be defined
// to be fully operational, of course
[[gnupg-decrypt]]
aspect = "decryption"
key = "0x123456789"
// version control hook. Sorted into aspect "misc" here.
[[git]]
aspect = "misc"
// ...
```
Hooks MAY HAVE arbitrary configuration keys.

13
doc/src/04000-modules.md Normal file
View file

@ -0,0 +1,13 @@
# Modules {#sec:modules}
A module is a functionality of the program.
There is a huge list of modules available in the imag core distribution.
From a naming perspective, we do not differ between low-level and high-level
modules. 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 (which by the way shouldn't be used by the end-user at all).
Others cover things like diary, notes, wiki or bookmarks.
The modules try to offer a consistent commandline user interface.

View file

@ -0,0 +1,12 @@
## Bibliography {#sec:modules:bibliography}
The Bibliography module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Bookmarks {#sec:modules:bookmarks}
The Bookmarks module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,11 @@
## Borrow {#sec:modules:borrow}
The Borrow module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,13 @@
## Calendar {#sec:modules:calendar}
The Calendar module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,13 @@
## Contacts {#sec:modules:contacts}
The Contacts module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,32 @@
## Counter {#sec:modules:counter}
The Counter module helps you counting things.
### Description
In its current state the counter module is capable of simple counting. You can
create, list and delete counters which are simply numbers and incremet,
decrement, set and reset them.
Future plans include counting functionality which is able to save date and
possibly timestamp of your increments/decrements, so you can export this and use
(for example) R to visualize this data.
Filters for selecting only certain time ranges when listing/exporting your
counters will be added as well.
### Examples
Here are some examples how to use the counter module:
```bash
imag counter create --name example --initval 42 # or: -n example -i 42
imag counter --inc example # or -i example
imag counter --reset example
imag counter --dec example # or -d example
```
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Cuecards {#sec:modules:cuecards}
The Cuecards module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,23 @@
## Diary {#sec:modules:diary}
The Diary module.
### Description
The diary module is for keeping your diary notes. It offers a self-implemented
diary which creates the entries in the store.
As of now there is only the possibility to create daily entries, but the
possibility to implement hourly or even minutely entries is there.
The module offers commands to create, delete, edit and list diary entries.
### Backends
At this moment, only the imag store is an available backend and therefor diary
entries are written to the imag store.
There is no implementation for other diary software planned _yet_, but there
might be a [jrnl](http://jrnl.sh/) backend some time, but not as long as `jrnl`
does not provide a multi-file storage system.

View file

@ -0,0 +1,12 @@
## Images {#sec:modules:images}
The Images module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Ledger {#sec:modules:ledger}
The Ledger module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,33 @@
## Link {#sec:modules:link}
The Linking module.
### Description
The linking module `imag-link` is one of the plumbing modules.
It offers the possibility to link entries in the store.
It also offers the functionality to link to external sources. This functionality
_can_ be used to link to external URLs, but the bookmarking module should be
used to do this (see @sec:modules:bookmarks).
The linking module offers functionality to add, remove and list both internal
(store entry to store entry) and external (store entry to URL) links.
#### Internal linking
<!-- internal linking description remains to be written -->
#### External linking
A store entry can only have _one_ 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.
### Backends
As this is a plumbing module and only intended to be used with the imag store,
there is no reason to have other backends.

View file

@ -0,0 +1,12 @@
## Mails {#sec:modules:mails}
The Mails module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,13 @@
## Movies {#sec:modules:movies}
The Movies module.
### Description
#
#<!-- Description of the module -->
#
#### Backends
#
#<!-- Backends the module supports including links to external resources -->
#

View file

@ -0,0 +1,12 @@
## Music {#sec:modules:music}
The Music module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## News {#sec:modules:news}
The News module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Password {#sec:modules:password}
The Password module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Reference {#sec:modules:ref}
The Reference module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Shoppinglists {#sec:modules:shoppinglists}
The Shoppinglists module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Store {#sec:modules:store}
The Store module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Tagging {#sec:modules:tag}
The Tagging module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Todos {#sec:modules:todos}
The Todos module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## View {#sec:modules:view}
The View module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Weather {#sec:modules:weather}
The Weather module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -0,0 +1,12 @@
## Wiki {#sec:modules:wiki}
The Wiki module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View file

@ -1,42 +0,0 @@
# liblink {#sec:liblink}
The "liblink" library contains functionality for linking from entries to
internal and external content.
The utilities provided by "liblink" contain functions to
* Get internal links from arbitraty entries
* Access an "EntryHeader" object to
* get internal links
* set internal links
* get "Entry" objects for links from a header
## Linking internal content with liblink {#sec:liblink:internal}
As one entry MAY contain zero or more interal links in the header section
"imag.links", the "liblink" library provides functionality to
* get the link from an EntryHeader object
* set the links in a EntryHeader object
* query for a specific link in a EntryHeader object
* by regex
* by module name
* by filename
as well as functionality to get "Entry" objects for each entry in the Header.
## Linking external content with liblink {#sec:liblink:external}
As one "EntryHeader" MUST NOT contain more than one link to external content (as
defined in @sec:thestore:linking:external, the following scheme for linking to
external content MUST BE provided by "liblink":
* Generate a "link" entry in the store
* with store path starting with "/link/"
* where the header field "imag.content.uri" MUST BE set
* with optional content which can be stored in the section of the "liblink"
module section (section name "link", as defined by
@sec:thestore:fileformat:header:module).
* Get an external link by store path (looking up the store path entry and
getting the link to the external content from it)

View file

@ -1,18 +0,0 @@
# libtag {#sec:libtag}
The "libtag" library contains functionality for tagging entries.
The following functionality for entries is provided:
* Adding a tag to an entry
* Removing a tag from an entry
* Fetching the list of tags from an entry
* Checking whether a tag is set in an entry
The following additional functionality is provided:
* Fetching all entries which contain a tag
* Fetching all entries which contain a list of tags
* Fetching all entries which fulfill a set of tag-requirements (either
present, or not present, chained by logical operators)

View file

@ -1,20 +0,0 @@
# Modules {#sec:modules}
A module is a functionality of the program.
A module MAY store data in the store (@sec:thestore).
It MAY include user input in the data it stores in the store.
A module MUST HAVE a commandline interface, though a module always consists of
two parts:
- A Library
- A Binary, which
* is executable by the user
* implements a commandline frontend to the libray of the module
By definition, the Binary depends on the Library.
By definition, the Library depends on the libstore (@sec:libstore).
A module MUST use the runtime library to implement the commandline
interface as defined in @sec:librt.

View file

@ -1,8 +0,0 @@
## Utils {#sec:modules:utils}
Some utility modules are provided to alter entries directly.
### Link utility {#sec:modules:utils:link}
### Tag utility {#sec:modules:utils:tag}

View file

@ -1,6 +0,0 @@
<!--
## Bibliography {#sec:modules:bibliography}
The Bibliography module.
-->

View file

@ -1,4 +0,0 @@
## Bookmarks {#sec:modules:bookmarks}
The Bookmarks module.

View file

@ -1,6 +0,0 @@
<!--
## Borrow {#sec:modules:borrow}
-->

View file

@ -1,5 +0,0 @@
## Calendar {#sec:modules:calendar}
The Calendar module.

View file

@ -1,5 +0,0 @@
## Contacts {#sec:modules:contacts}
The Contacts module.

View file

@ -1,15 +0,0 @@
## Counter {#sec:modules:counter}
The Counter module helps you counting things.
In its current state it is capable of simple counting. You can create, list and
delete counters which are simply numbers and incremet, decrement, set and reset
them.
Future plans include counting functionality which is able to save date and
possibly timestamp of your increments/decrements, so you can export this and use
(for example) R to visualize this data.
Filters for selecting only certain time ranges when listing/exporting your
counters will be added as well.

View file

@ -1,6 +0,0 @@
<!--
## Cuecards {#sec:modules:cuecards}
-->

View file

@ -1,6 +0,0 @@
<!--
## Diary {#sec:modules:diary}
-->

View file

@ -1,6 +0,0 @@
<!--
## Images {#sec:modules:images}
The Images module.
-->

View file

@ -1,6 +0,0 @@
<!--
## Ledger {#sec:modules:ledger}
-->

View file

@ -1,4 +0,0 @@
## Mails {#sec:modules:mails}
The Mails module.

View file

@ -1,7 +0,0 @@
<!--
## Movies {#sec:modules:movies}
The Movies module.
-->

View file

@ -1,6 +0,0 @@
<!--
## Music {#sec:modules:music}
The Music module.
-->

View file

@ -1,6 +0,0 @@
<!--
## News {#sec:modules:news}
The News module.
-->

View file

@ -1,6 +0,0 @@
<!--
## Password {#sec:modules:password}
-->

View file

@ -1,6 +0,0 @@
<!--
## Shoppinglists {#sec:modules:shoppinglists}
The Shoppinglists module.
-->

View file

@ -1,4 +0,0 @@
## Todos {#sec:modules:todos}
The Todos module.

View file

@ -1,6 +0,0 @@
<!--
## Weather {#sec:modules:weather}
-->

View file

@ -1,4 +0,0 @@
## Wiki {#sec:modules:wiki}
The Wiki module.

View file

@ -0,0 +1,2 @@
# Technical details {#sec:techdetails}

2
doc/src/09100-store.md Normal file
View file

@ -0,0 +1,2 @@
## The store {#sec:techdetails:store}

View file

@ -47,10 +47,19 @@ $endfor$
\begin{document} \begin{document}
\thispagestyle{empty}
\begin{center} \begin{center}
{\bf $title$} {\bf imag $version$}
{\bf User Documentation}
$date$
\end{center} \end{center}
\newpage{}
\tableofcontents
\newpage{}
$body$ $body$
\end{document} \end{document}

View file

@ -1,11 +0,0 @@
# imag-counter
A simple module to count things.
```bash
imag counter create --name example --initval 42 # or: -n example -i 42
imag counter --inc example # or -i example
imag counter --reset example
imag counter --dev example # or -d example
```

1
imag-counter/README.md Symbolic link
View file

@ -0,0 +1 @@
../doc/src/04020-module-counter.md

View file

@ -1,5 +0,0 @@
# imag-link
Utility to link entries. Not meant to be called by normal users but by
developers to investigate the store.

1
imag-link/README.md Symbolic link
View file

@ -0,0 +1 @@
../doc/src/04020-module-link.md

View file

@ -1,4 +0,0 @@
# imag-store
Minimal commandline interface for the store. Not meant to be called by users but
by developers to investigate the store.

1
imag-store/README.md Symbolic link
View file

@ -0,0 +1 @@
../doc/src/04020-module-store.md

View file

@ -1,4 +0,0 @@
# imag-tag
Commandline frontend for the tagging library. Not meant to be called by the user
but by developers to investigate tags of entries.

1
imag-tag/README.md Symbolic link
View file

@ -0,0 +1 @@
../doc/src/04020-module-tag.md

View file

@ -1,4 +0,0 @@
# imag-view
Simple commandline utility to print entries to the commandline output.

1
imag-view/README.md Symbolic link
View file

@ -0,0 +1 @@
../doc/src/04020-module-view.md