diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2016-07-14 21:11:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-14 21:11:30 +0200 |
commit | 0c5674dd471d439bcbe82439f649b13e90e5064b (patch) | |
tree | 58b45cfdd7eb7e1801062291127834e79b27c64a /doc | |
parent | 76601c8fa87b3901cc648a616e91250e9b81921d (diff) | |
parent | 046bec83a11a33f3f024eab00bad25ff9f9503b3 (diff) |
Merge pull request #525 from matthiasbeyer/update-doc
Update doc
Diffstat (limited to 'doc')
60 files changed, 483 insertions, 692 deletions
diff --git a/doc/src/00000.md b/doc/src/00000.md index 131d16a3..41ecb4b5 100644 --- a/doc/src/00000.md +++ b/doc/src/00000.md @@ -1,7 +1,7 @@ --- -title: imag Project -version: 0.1 -date: January 2016 +title: imag User Documentation +version: 0.1.0 +date: July 2016 listings: true codeBlockCaptions: true figureTitle: "Figure" diff --git a/doc/src/01000-intro.md b/doc/src/01000-intro.md index eb504776..37653f6b 100644 --- a/doc/src/01000-intro.md +++ b/doc/src/01000-intro.md @@ -1,25 +1,10 @@ # Introduction {#sec:introduction} -In the following work, we define the architecture, internal interfaces and the -implementation of `imag` (called "the program" in the following chapters). - -The program is intended to be an _Personal Information Management Suite_ -(PIM-Suite), featuring all components such a suite should have, including -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. +This document aims to be the user documentation for imag, the personal +information management suite for the commandline. + +If you have any objections, suggestions for improvements, bugs, etc, please file +them in the github repository you got this documentation from. ## 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 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. + diff --git a/doc/src/02000-store.md b/doc/src/02000-store.md index d7b7d22e..7faafca9 100644 --- a/doc/src/02000-store.md +++ b/doc/src/02000-store.md @@ -1,64 +1,67 @@ # The Store {#sec:thestore} -## File Format {#sec:thestore:fileformat} - -The content in the store MUST BE encoded in either Unicode UTF-8 or ASCII. -Each "Entry" (File) MUST HAVE a "Header" component as well as a "Content" -component. -Each "Entry" in the store MUST start with three single dashes ("-") followed -by a newline character, named "initial marker" in the following chapter. -The Header follows the initial marker (@sec:thestore:fileformat:header). -The Header MUST BE followed by a line which contains three single dashes ("-") -and a newline character, called "header-close marker" in the following -chapter. -The content follows the header-close marker (@sec:thestore:fileformat:content). - -### Header Format {#sec:thestore:fileformat:header} - -The header format MUST BE "TOML". -The sections which MAY or MUST be in the header are defined in the following -chapters. +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. -#### Header section: "imag" {#sec:thestore:fileformat:header:imag} +## File Format {#sec:thestore:fileformat} -The header MUST contain a section called "imag", where the automatically by the -program generated data is stored in. -The contents of this section is edited via commandline calls or by the -program implicitely and SHOULD NOT be edited by the user. +The contents of the store are encoded in either UTF-8 or ASCII. Either way, a +normal text editor (like `vim` or the other one) will always be sufficient to +dog into the store and modify files. For simple viewing even a pager (like +`less`) is sufficient. -This "imag" section MUST contain the following keys +Each entry in the store consists of two parts: -1. A "version" Key. The version stored here is the version of the Store, the - Entry was created with. +1. Header +1. Content -The "imag" section MAY contain +The following section describe their purpose. -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 Format {#sec:thestore:fileformat:header} -#### Header section: "custom" {#sec:thestore:fileformat:header:custom} +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 +(`---`). 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. -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. +The header can contain any amount of data, but modules (see @sec:modules) are +restricted in their way of altering the data. -#### Module Header section {#sec:thestore:fileformat:header:module} +So normally there are several sections in the header. One section (`[imag]`) is +always present. It contains a `version` field, which tells imag which version +this file was created with (the version information is _also_ encoded in the +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. -The header MAY contain a section named after a module. -The corrosponding module is allowed to store arbitrary data in this section. +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. This is not enforced by imag itself, though. ### Content Format {#sec:thestore:fileformat:content} -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 library MUST NOT expect any particular markup format. +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 code of imag. + +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} @@ -69,17 +72,10 @@ An example for a file in the store follows. [imag] version = "0.2.0" -[imag.content] -url = "file://home/user/kittens.mpeg" - -imag.links = [ - "imag://home/user/more_kittens.mpeg" -] +imag.links = ["/home/user/more_kittens.mpeg"] [examplemodule] -arbitrary = data -[custom] -truth = 42 +arbitrary = "data" --- 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} The "Entries" are stored as files in the "Store", 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. - -The Path of each File is shown as absolute path in this paper, while the root -is always the store directory. -This Path is named "Storepath". -So if the store exists in `/home/user/store/`, a file with the Storepath +user has access to. The store may exist in the users Home-directory or any +other directory the user has read-write-Access to. + +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. + +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 `/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. - This part is a directory. -* The version (semantic versioning applies) of the module storing the Entry - This part is a postfix to the filename +* The module name of the Module the Entry belongs to, as said above. + This part is always a directory. +* The version (semantic versioning applies) of the module storing the entry. + This part is a postfix to the filename. 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> ``` -So if a Module named "ExampleModule" with version "0.1" stores a file in the -Store, the Storepath for a file with the name "example" is -"/ExampleModule/example~0.1". +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 +"/example-module/example~0.1.0". -Any number of subdirectories MAY BE used, so creating folder hierarchies is -possible and valid. -A file "example" for a module "module" in version "0.1" would be stored in -sub-folders like this: +Any number of subdirectories may be used, so creating folder hierarchies is +possible and valid. A file "example" for a module "module" in version "0.1.0" +would be stored in 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 invalid if these files exist at the same time: +For example, it is valid if these files exist at the same time: * /foo/bar~0.2 * /foo/bar~1.3 -To future-proof the System it is thus necessary to create a disambiguation at -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. +It might not be sane, though. -For this there will be an enum returned for each given Entry. It will have these -members: - -- `Compatible`, for version matches -- `PossiblyIncompatible`, if the current version is at least a major number - further -- `Incompatible`, if the file is a at least a major number further +To future-proof the system it is necessary to provide a way for modules to +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 +advertised version. It may accept older files and it may transform them and +resubmit them in the newer version. ## 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 -link to an entry "b" from a module "B", which is in version "0.1" at the moment. -If the module "B" gets updated, it might update its entries in the store as -well. -The link from the "a" MUST NOT get invalid in this case. - -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. +link to an entry "b" from a module "B", which is in version "0.1.0" at the +moment. If the module "B" gets updated, it might update its entries in the store +as well. The link from the "a" should never get invalid in this case, though it +is not ensured by the core of imag itself. diff --git a/doc/src/02010-linking.md b/doc/src/02010-linking.md index 7ad09cb4..ba62ec0c 100644 --- a/doc/src/02010-linking.md +++ b/doc/src/02010-linking.md @@ -1,35 +1,29 @@ ## Linking from an store entry {#sec:thestore:linking} -In @sec:thestore:fileformat:header:imag it was already defined that there MUST -BE a section "imag" in the header. This section can be used to link to -"internal" and "external" content, whereas "internal content" refers to entries -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 -part is written in Markdown, the user is able to link content within the -Markdown text. -These links could be either links to internal content or external content. +As described in @sec:intro:problem the purpose of imag is to _link_ content +together. The following section describes, from a technical view, how this is +done in imag. + +There are two ways of linking in imag. You can either link internally or +externally. The following sections describe the differences. ### Linking to internal content {#sec:thestore:linking:internal} -Links to internal content are stored in the Array "imag.links = []". -Each entry in this array MUST BE a String which is an absolute path to a store -entry (@sec:thestore:links). +Internal links are links between store entries themselfes. This means that one +store entry can link to another. Actually, links are not pointers but rather +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 -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. +How linking works from the user interface is described in @sec:modules:link. ### 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. + +Each store entry can store _one link to external content at most_. -This link is stored in the header field "imag.content.uri" -(@sec:thestore:fileformat:header:imag). -A key "imag.content.file" COULD be used for a local mirror of the content which -is referenced by "imag.content.uri". +External linking should not be used from the user interface but rather the +`ref` feature (@sec:modules:ref) should be used. +@sec:modules:ref describes why that is. diff --git a/doc/src/02020-tagging.md b/doc/src/02020-tagging.md deleted file mode 100644 index 93fad092..00000000 --- a/doc/src/02020-tagging.md +++ /dev/null @@ -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. - diff --git a/doc/src/03000-lib-util.md b/doc/src/03000-lib-util.md deleted file mode 100644 index 6c397ba6..00000000 --- a/doc/src/03000-lib-util.md +++ /dev/null @@ -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. - diff --git a/doc/src/03100-lib-rt.md b/doc/src/03100-lib-rt.md deleted file mode 100644 index 4dedcd17..00000000 --- a/doc/src/03100-lib-rt.md +++ /dev/null @@ -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} |