Skip to content

Commit

Permalink
Release version 1.4 of specification
Browse files Browse the repository at this point in the history
Relicense the specification #173
Allow dashes/hyphens to appear in tags #168
Introduce (optional) values for tags #169
Specify how to deal with invalid input #163
Add footnotes for preserving contextual background info #167
  • Loading branch information
jotaen authored Apr 13, 2022
1 parent abd31b0 commit 32256ec
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 15 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ version numbers of both are independent of each other.

## About

klog is free and open-source software distributed under the [MIT license](LICENSE.txt).
klog is free and open-source software.

- The command line tool is distributed under the [MIT license](LICENSE.txt).
- The file specification is available under the [CC0/OWFa](Specification.md#License) dual license.
97 changes: 84 additions & 13 deletions Specification.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# klog – File Format Specification

**Version 1.3**
**Version 1.4**

klog is a file format for tracking time.

It is free and open-source software distributed under the MIT-License.
## License

Per [Creative Commons CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/),
to the extent possible under law, the editors have waived all copyright and related or
neighbouring rights to this work.
In addition, as of March 2022, the editors have made this specification available under the
[Open Web Foundation Agreement 1.0](https://www.openwebfoundation.org/the-agreements/the-owf-1-0-agreements-granted-claims/owfa-1-0).

## Preface

Expand Down Expand Up @@ -43,6 +49,7 @@ the indentation sequence MUST appear twice.

The indentation style MUST be uniform within *records*.
(It MAY differ between *records*, though.)
[^indst]

### Date
A *date* is a day in the calendar.
Expand Down Expand Up @@ -77,6 +84,7 @@ The *record summary* is considered to be associated with the entire *record*.
It MUST appear underneath the *date*,
and it MAY span multiple lines.
Each of its lines MUST NOT start with “blank characters”.
[^resui]

#### Entry Summary
The *entry summary* is considered to be referring to one particular *entry*.
Expand All @@ -88,15 +96,38 @@ or it MUST start on the subsequent line.
The *entry summary* MAY span multiple lines.
All lines following the *entry* line MUST be indented twice;
they also MUST NOT only consist of “blank characters”.
[^iwses]

#### Tag
The purpose of *tags* is to help categorise *records* and *entries*.

> Examples: `#gym`, `#24hours`, `#home_office`, `#読む`
> Examples: `#gym`, `#home-office`, `#読む`, `#ticket=891`, `#project="22/48.3"`
Any amount of *tags* MAY appear anywhere within *summaries*.
A *tag* MUST be a sequence of “letters”, “digits” or the `_` character,
preceded by a single `#` character.

A *tag* MUST consist of a *tag name*,
which MUST be preceded by a single `#` character.
The *tag name* MAY be followed by a `=` character
and a *tag value*.

The *tag name* MUST only contain
“letters”, “digits”, or the characters `_` or `-`.
It MUST be interpreted as if it was all lower-case.
[^csitn]

The *tag value* MAY be surrounded by a pair of matching quotes,
which MUST either be `"` (RECOMMENDED) or `'`.
- If the *tag value* is quoted, it MAY contain any character
except for the respective quote character itself,
or a “newline”.
In case no matching closing quote appears on the same line,
the *tag value* MUST be treated as absent.
[^qutvl]
- If the *tag value* is not quoted, it MUST only contain
“letters”, “digits”, or the characters `_` or `-`.

An empty *tag value* (e.g. `#tag=` or `#tag=""`)
MUST be treated the same as an absent *tag value* (e.g. `#tag`).

### Entry
*Entry* is an abstract term for time-related data.
Expand Down Expand Up @@ -170,9 +201,11 @@ except that the end *time* MUST be replaced by a placeholder.
The placeholder MUST be denoted by the character `?`,
e.g. `9:00 - ?`.
The `?` MAY be repeated, e.g. `9:00 - ???`.
[^plrep]
The placeholder MUST NOT be *shifted*.

*Open ranges* MUST NOT appear more than once per *record*.
[^oasor]

### Duration
A *duration* is an *entry* that represents a period of time.
Expand Down Expand Up @@ -212,8 +245,6 @@ If the *duration* is supposed to be negative, it MUST be preceded by a `-` chara
## II. Organising records in files

A file MAY hold any amount of *records*.
Apart from that it MUST NOT contain anything
but what is allowed by this specification.

There MUST appear one “blank line” between subsequent *records*;
additional “blank lines” MAY appear.
Expand All @@ -222,15 +253,19 @@ additional “blank lines” MAY appear.

There MAY exist multiple *records* with the same *date*.

A file MUST NOT contain anything but what is allowed by this specification.
Otherwise, it SHOULD NOT be evaluated.
[^fcocr]

The file extension SHOULD be `.klg`, e.g. `times.klg`.
The file encoding MUST be UTF-8.

Newlines MUST be encoded with either the
Newlines MUST be encoded with either the
linefeed character (LF, escape sequence `\n`),
or carriage return and linefeed character (CRLF, escape sequences `\r\n`).
These two styles SHOULD NOT be mixed within the same file.

There SHOULD be a newline at the end of the file.
There SHOULD be a newline at the end of the file.

## III. Evaluating data

Expand All @@ -242,9 +277,8 @@ The resulting *total time* MAY be 0;
it MAY be negative;
it MAY be greater than 24 hours.

Overlapping *ranges* MUST be counted individually
and MUST NOT be offset against each other.
E.g., the two *entries* `12:00 - 13:00` and `12:30 - 13:30` result in *total time* of `2h`.
Overlapping *ranges* MUST each be counted fully.
E.g., the two *entries* `12:00 - 13:00` and `12:30 - 13:30` result in a *total time* of `2h`.

*Ranges* with *shifted times* MUST be fully counted towards
the *date* at which they appear in the *record*.
Expand All @@ -261,16 +295,23 @@ and MUST NOT be combined into a single *record*.
### Glossary of technical terms

- “space”: The character ` ` (U+0020)
- “tab”: The tab character (U+0009), escape sequence `\t`
- “tab”: The tab character (U+0009, escape sequence `\t`)
- “blank character”: A “tab”, or a character as defined by the Unicode Space Separator category (Zs)
- “blank line”: A line that only contains “blank characters”
- “parenthesis”: The opening and closing parentheses `(` and `)` (U+0028 and U+0029)
- “letter”: A character as defined by the Unicode Letter category (L)
- “digit”: Any of 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
- “integer”: An unsigned number without fractional component
- “newline”: Either a linefeed (U+0010, escape sequence `\n`), or a carriage return and linefeed (U+0013 and U+0010, escape sequence `\r\n`)

### Changelog

#### Version 1.4
- Release the specification document under the CC0/OWFa license.
- Support for tags to (optionally) have values assigned to them.
- Allow hyphens (`-`) to appear in tags.
- Add footnotes to make context information explicit.

#### Version 1.3
- Specify additional rules for multiline entry summaries.

Expand All @@ -283,3 +324,33 @@ and MUST NOT be combined into a single *record*.
to be uniform within a record.
- Remove technical term “whitespace”, since its meaning is ambiguous and the definition lacked clarity.
Replace it with “blank character” and base the definition on the Unicode category.

### Footnotes

The following footnotes are purely informational,
to make contextual background information explicit.

[^indst]: The indentation must be uniform, otherwise the levels can’t be determined
unambiguously. E.g., if 4 spaces are encountered at the beginning of the line, it would
be unclear whether that is 2 * 2 spaces or 1 * 4 spaces.
[^resui]: Lines in the record summary can’t start with blank characters, to avoid that they
might be visually confused with the (indented) entries. There is no strict technical
reason for this, though.
[^iwses]: In contrast to record summaries, lines in entry summaries can start with blank
characters. That is for allowing the user to vertically align the summary text on all
entry lines. A by-effect of this rule is that there can never be a third indentation level.
[^csitn]: The character set that a tag is allowed to consist of is deliberately limited,
so that tags can appear as natural words in the flow of a sentence. E.g.:
`#Office day (#coding, #meetings)`. That’s also why tag names are to be interpreted
as case-insensitive. (Tag values, on the other hand, are always to be interpreted literally.)
[^qutvl]: The main use-case for quoted tag values is for literal references, such as a project id,
or a name: `#project="2022/7.2"` or `#call="Liz Jones"`. That’s also why tag values
are always to be interpreted as case-sensitive (in contrast to tag names).
[^plrep]: The `?` placeholder in open ranges can be repeated, to allow users to visually
align it with other entries. E.g. `8:00-?????` has the same width as `8:00-9:00`.
[^oasor]: Open ranges only being allowed to appear once per record has a mere practical motivation:
it’s important for making interactions with tools easier. Otherwise, when stopping activities
via a tool, it might be ambiguous which of the open ranges is meant.
[^fcocr]: By allowing a file to only contain records and nothing else, a klog file can effectively
be perceived as a text-based database. That makes it easy to process files programmatically,
because every record is a self-contained and strictly structured unit of data.
2 changes: 1 addition & 1 deletion src/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

// SPEC_VERSION contains the version number of the file format
// specification which this implementation is based on.
const SPEC_VERSION = "1.3"
const SPEC_VERSION = "1.4"

// Record is a self-contained data container that holds the time tracking
// information associated with a certain date.
Expand Down

0 comments on commit 32256ec

Please sign in to comment.