diff --git a/.travis.yml b/.travis.yml index 8ca0083b..d8c711ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,18 @@ matrix: - bash ./scripts/license-headers-updated - bash ./scripts/branch-contains-no-tmp-commits - bash ./scripts/version-updated + - language: rust + rust: stable + name: userdoc + cache: + directories: + - /home/travis/.cargo + before_cache: + - rm -rf /home/travis/.cargo/registry + install: + - cargo install mdbook --force + script: + - cd doc/user && mdbook build || exit 1 - language: rust rust: 1.35.0 cache: diff --git a/doc/user/.gitignore b/doc/user/.gitignore new file mode 100644 index 00000000..7585238e --- /dev/null +++ b/doc/user/.gitignore @@ -0,0 +1 @@ +book diff --git a/doc/user/book.toml b/doc/user/book.toml new file mode 100644 index 00000000..c866c6e4 --- /dev/null +++ b/doc/user/book.toml @@ -0,0 +1,6 @@ +[book] +authors = ["Matthias Beyer"] +language = "en" +multilingual = false +src = "src" +title = "imag-documentation" diff --git a/doc/user/src/SUMMARY.md b/doc/user/src/SUMMARY.md new file mode 100644 index 00000000..1dd182a8 --- /dev/null +++ b/doc/user/src/SUMMARY.md @@ -0,0 +1,8 @@ +# Summary + +- [Introduction](./intro.md) +- [Approach](./approach.md) +- [Conventions](./conventions.md) +- [Good to know](./good-to-know.md) +- [Examples](./examples.md) + diff --git a/doc/user/src/approach.md b/doc/user/src/approach.md new file mode 100644 index 00000000..ae69b997 --- /dev/null +++ b/doc/user/src/approach.md @@ -0,0 +1,74 @@ +# The Approach + +The approach "imag" takes on solving this problem is to store content in a +plain text storage (the "store") on the filesystem and persisting content in a +unified way. + +## The Store + +The imag "store" is nothing more than a directory on the filesystem, ususally +`~/.imag/store`. +Imag stores each "entry" under a unique "StoreId" which is nothing more than a +part of the path of the actual file on disk: + + +``` +/home/user/.imag/store/some/entry +| | || | + \ / / \ / + ------------- | ------ +| "RTP" | "Id" + \ / + ------------------ + "Store path" +``` + +* The "RTP" is the Runtimepath of imag, where imag looks for the config file + (`~/.imag/imagrc.toml`) and the `store` directory. + +* The "Store path" is where imag looks for the store root. The "Store path" can + be set explicitely in the imag commandline, but end-users normally don't need + to do this. + +* The "StoreId" (abbreviated with "Id") is what the user uses when referring to + an entry of the store. + + +## Entry + +One imag entry contains two parts: The Header and the Content part. The header, +which is stored in +[TOML](https://en.wikipedia.org/wiki/TOML), +contains structured data. This data is most of the time generated by imag +itself, depending on the module that stores the data. +An imag entry contains always a version information header part: + +``` +[imag] +version = "0.10.0" +``` + +Each imag module is free to store data under its own header section, where the +name of the section is defined by the module storing it. Thus, "imag-diary" +stores its data in `[diary]`. +A module may store arbitrary textual data. +Of course, imag provides utility commandline tools for querying this data. + +An example imag entry could look like this: + +``` +--- +[habit.instance] +comment = 'Eat one fruit per day' +date = '2019-06-28' +is_habit_instance = true +name = 'eat_fruit' + +[imag] +version = '0.10.0' + +[links] +internal = ['habit/template/eat_fruit'] +--- +``` + diff --git a/doc/user/src/conventions.md b/doc/user/src/conventions.md new file mode 100644 index 00000000..2bf61acf --- /dev/null +++ b/doc/user/src/conventions.md @@ -0,0 +1,46 @@ +# Conventions + +imag has a few conventions which we try to enforce in all module +implementations. This chapter explains the conventions an end-user of imag can +rely on. + + +## Commandline interface + +The commandline interface of every subcommand has a "--help" flag which can be +used to print helptext for the subcommand. + +Every imag module implementation can be used for scripting, where it behaves in +the following ways: + +* If the standard input is a pipe, imag module implementations assume that store + ids are written to that pipe line by line. +* If the standard output is a pipe, every imag module prints the StoreIDs it + touched while running to the pipe. + All other output is written to stderr. + Piping can be used to combine imag commands. +* If the standard output is not a pipe, the imag module does not print the + StoreIDs it touched. + +This behaviour can be overridden with the `--ignore-ids` flag. + +## Versioning + +imag modules are compatible to eachother as long as the version number is in the +`0.x.y` range. +Modules from different imag versions are not supported to be compatible to +eachother. + + +## Commandline capabilities + +The imag commands can be used to access _all_ data that is stored in the imag +store. +Alternatively, standard unix commandline tools (like `grep`, `cut`, `sed`, ...) +can be used to access all data and all data-points. + +In short: All data imag stores is stored in plain text, containing a structured +part (in the markup language "toml") and a plain-text part (which should be +UTF-8 encoded). + + diff --git a/doc/user/src/examples.md b/doc/user/src/examples.md new file mode 100644 index 00000000..fd6e57c6 --- /dev/null +++ b/doc/user/src/examples.md @@ -0,0 +1,22 @@ +# Examples + +imag commands can be chained by piping the output. +This can be used to create, tag and categorize an entry in one step. + +``` +imag log --to personal "Some personal note" | \ + imag tag add foobar | \ + imag category set somecategory +``` + +imag can be configured to use aliases for module commands, so combining a basi +alias `alias i=imag` with imag module aliaes, this can be condensed to: + +``` +i l --to personal "Some personal note" | \ + i t add foobar | \ + i c set somecategory +``` + +for example. + diff --git a/doc/user/src/good-to-know.md b/doc/user/src/good-to-know.md new file mode 100644 index 00000000..70bdaae5 --- /dev/null +++ b/doc/user/src/good-to-know.md @@ -0,0 +1,34 @@ +# Good to know + +There are some things in the imag space that a user might want to know before +using imag. + + +## Tags + +Tags are text values that can be added to _any_ entry in the imag store. +The tag has to satisfy some invariants to be valid: + +1. it has to be all-lowercase +1. it has no spaces +1. all characters are alphanumeric + +Any entry can have any number of tags. Spelling is not checked. + +Finding all entries for a tag "foo" is `O(n)` where `n` is the number of entries +in the store. + + +## Categories + +Categories are more restrictive, but also more powerful. +First of all, a category has to exist before an entry can be _linked_ to a +category. A category therefor is represented by an entry and if an entry has a +category, it is linked to said entry. + +So, if you create only category with the name "foo", you cannot set the category +"bar" for some entry. + +Because categories are linked, finding all entries for a category is trivial and +a `O(1)` operation. + diff --git a/doc/user/src/intro.md b/doc/user/src/intro.md new file mode 100644 index 00000000..f474673a --- /dev/null +++ b/doc/user/src/intro.md @@ -0,0 +1,15 @@ +# Introduction + +This document is the end-user documentation for imag, the plain-text personal +information management suite for the commandline. + +The imag project wants to provide a set of tools (called "modules") for managing +personal information data on the commandline, where the data is stored in plain +text. +The modules should be scriptable, composable, traverseable and queryable. +The target audience for imag are power-users and commandline natives. + +If you have any objections, suggestions for improvements, bugs, etc, please file +them. + +