Add starting README
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
b93c29cb7f
commit
43620146aa
1 changed files with 195 additions and 0 deletions
195
README.md
Normal file
195
README.md
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# PLAIn teXT
|
||||
|
||||
Plaixt is a set of conventions and modules to interact with data stored in
|
||||
plain text. It is purpose geared towards storing and interacting with 'real
|
||||
things'. Aka, concrete actions and/or objects.
|
||||
It might not do well with abstract concepts like 'infinity' or mutually
|
||||
recursive events.
|
||||
As a rule of thumb, if it has a date, and possibly a duration.
|
||||
It will probably fit.
|
||||
|
||||
## What do I use this for?
|
||||
|
||||
Plaixt is made to interact with plain text files. It's primary use case is to
|
||||
record data and then process it further.
|
||||
|
||||
This is purposefully kept vague, just like a Hammer is a hard heavy object to
|
||||
hit things with.
|
||||
|
||||
Some things that you can do with Plaixt:
|
||||
|
||||
- Record purchases in your home, making sure that each purchase has an
|
||||
associated receipt, price and warranty expiration date.
|
||||
- Record contacts, personal or professional.
|
||||
- Link between entries, making sure that the links are of correct kinds
|
||||
|
||||
## What is the data format?
|
||||
|
||||
Plaixt uses a plain text, humand readable and writeable format.
|
||||
|
||||
A plaixt repository consists of these parts:
|
||||
|
||||
- A definitions folder
|
||||
- A records folder
|
||||
|
||||
|
||||
### Definitions
|
||||
|
||||
To make sense of the records, plaixt needs to know how records look like.
|
||||
This is so that both tools and humans know what to expect and how to interact
|
||||
with it.
|
||||
|
||||
- Each definition is in a separate file.
|
||||
- The filename is the 'kind' of the record, and may not have whitespaces in it
|
||||
- An optional `.pldef` may be appended to make recognition of these files easier
|
||||
- Definitions are counted in epochs, which is the date from which this
|
||||
definition is considered live.
|
||||
- As definitions may evolve with time, new versions of a definition may be added.
|
||||
- These are appended at the end of the file with a date, making the
|
||||
previous definition now obselete and making this definition the new live
|
||||
one.
|
||||
- Records _before_ this date, per default only have to conform to
|
||||
definitions that were live at the time of event. This can be overriden
|
||||
individually.
|
||||
- 'Migrating' to a newer definition can be done piece-by-piece, or all at
|
||||
once by changing the starting date from which a definition is considered
|
||||
live.
|
||||
- Order of precedence of definition is in reverse declaration order,
|
||||
followed by starting live date order. (e.g. a definition declared later
|
||||
in a file with the same starting live date will take precedence over
|
||||
earlier definitions with the same or later starting live date)
|
||||
|
||||
### Records
|
||||
|
||||
A record is anything one would want to track.
|
||||
Every record must have an associated datetime.
|
||||
Every record may have an associated unique id.
|
||||
Beyond these requirements, each record must have a kind associated with it.
|
||||
The definition of this kind then describes the required data of the record.
|
||||
|
||||
|
||||
## Syntax
|
||||
|
||||
This is still in flux, but the main idea is as following:
|
||||
|
||||
### Definitions
|
||||
|
||||
An example definition:
|
||||
|
||||
**purchase.pldef**
|
||||
```plaixt
|
||||
# This is a comment
|
||||
// You can also use double slashes
|
||||
/* Multi-line comments are ok too */
|
||||
|
||||
# Definitions may use modules to verify records
|
||||
# They can for example check that records are valid between eachother across
|
||||
# the whole database
|
||||
@checkWith "purchase-check"
|
||||
|
||||
# Each new definition needs a date from which it is active
|
||||
# A date suffices, which implies a starting time of 00:00
|
||||
define 26-10-2024T11:00
|
||||
store -> LinkTo[Store]
|
||||
name -> string
|
||||
warranty length -> duration? # A question mark, marks optional fields, a shorthand for Maybe[Field]
|
||||
count -> integer
|
||||
|
||||
# I realized I forgot the price field
|
||||
# Any records before this date won't have a price field
|
||||
define 15-11-2024
|
||||
store -> LinkTo[Store]
|
||||
name -> string
|
||||
warranty length -> duration?
|
||||
count -> integer
|
||||
price -> euros
|
||||
```
|
||||
|
||||
### Records
|
||||
|
||||
An example record:
|
||||
|
||||
**shopping.plrecs**
|
||||
```plaixt
|
||||
purchase 30-10-2024
|
||||
store <- FarmerBernard
|
||||
name <- "Pumpkin"
|
||||
count <- 5
|
||||
# No price here, as the record at this time does not allow adding a price
|
||||
|
||||
# I can force plaixt to use the definition from this specific date
|
||||
purchase@15-11-2024 5-11-2024
|
||||
store <- DIYCo
|
||||
name <- "Nails"
|
||||
count <- 250
|
||||
price <- 3.50 # I have to mention the price, as the definition
|
||||
# from 15-11-2024 has it as an non-optional field
|
||||
```
|
||||
|
||||
|
||||
## Interacting with plaixt
|
||||
|
||||
Once you've defined some records, and wrote down some records, you can now
|
||||
query your database.
|
||||
|
||||
For example, imagine we want to know what items we own that are no longer under
|
||||
warranty.
|
||||
|
||||
```bash
|
||||
plaixt --query "SELECT * FROM purchase WHERE 'warranty length' NOT NULL AND date + 'warranty length' < now()"
|
||||
```
|
||||
|
||||
Of course this is a rather crude way of interacting with the system, and
|
||||
instead one would use helpers:
|
||||
|
||||
```bash
|
||||
plaixt purchases out-of-warranty
|
||||
```
|
||||
|
||||
These helpers are modules that have access to your database and encode the
|
||||
utility of it all.
|
||||
This readme only has a simple example, but imagine a slightly more complete
|
||||
inventory tracking which has acquiring _and_ removing of inventory.
|
||||
The question of 'what I do I have at this point in time' comes out of the data,
|
||||
but is not written into it.
|
||||
|
||||
|
||||
## Why plain text? Couldn't I use sqlite/postgres/mongo/toml/etc... ?
|
||||
|
||||
Technically you can.
|
||||
|
||||
Plaixt is modular and does not _require_ its input to come
|
||||
from text files on a drive.
|
||||
But let me convince you why plain text is the better format to use:
|
||||
|
||||
- It will survive any of these database technologies. It's Unicode in files.
|
||||
Both of which are concepts that are in my opinion way less likely to simply
|
||||
disappear.
|
||||
- Humans can easily interact with it. Everyone should be able to write plaixt
|
||||
records without having to learn it. Simply by looking at the other
|
||||
definitions it should be clear what is going on and how to enter new text.
|
||||
- Any current and future technology is able to interact with it. You don't want
|
||||
to learn Rust? No problem. It's plain text! Write your own logic and helpers
|
||||
in whatever language you want to. If you can read/write bytes from
|
||||
stdin/stdout and/or files, you are set. For databases you will need to have
|
||||
drivers, complex connection handling etc... All of which is not required.
|
||||
(We're also not stopping you though)
|
||||
- Plain text has the big advantage to also be future compatible. You enter
|
||||
records now, and can analyze them later. Due to the flexibility of plain
|
||||
text, you do not need to first change the software to adapt.
|
||||
|
||||
### What about non-plain text data? I have PDFs and images, and they are part of records
|
||||
|
||||
We do take that into account!
|
||||
While plaixt per-default does not have any special handling for binary files,
|
||||
it doesn't preclude you from integrating them into your database.
|
||||
For example, the example above could be adapted to require a receipt in
|
||||
pdf/image form for each purchase.
|
||||
This can take many forms.
|
||||
The simplest would be to only require a file path, relative to the datastore.
|
||||
But integration with other software is also possible.
|
||||
Imagine a module that knows how to speak to a paperless instance.
|
||||
One could simply enter the ID of the document there, and the module only checks
|
||||
for existence.
|
||||
The possibilities here are unbounded, and allow you to custom fit your
|
||||
interactions with your needs.
|
||||
Loading…
Add table
Add a link
Reference in a new issue