docs: Noter og Kalender havde ingen sider, mens forsiden lovede begge
Landingssiden reklamerer for noter og for en kalender, og dokumentationen havde hverken en side om den ene eller den anden. Det hul blev skrevet ned i morges og er det her. **Noter** siger, hvad der er værd at vide, og hvad der ikke virker: at første linje *er* titlen og udledes ved hver gemning, at arkivet og papirkurven er to forskellige ting, at søgningen finder `grøn` når man skriver `gron` og `keepInventory` når man skriver `inventory` — og at notekroppe ligger i klartekst i hver sikkerhedskopi, man kan hente. Det sidste hører hjemme dér, hvor nogen står med en note og overvejer at skrive et kodeord i den. **Kalender** samler det, der før var spredt: gitteret, ugen som et døgn, træk der sætter et klokkeslæt, abonnementer på ICS og webcal, og Google-forbindelsen med det forbehold, den skal have — den er skrevet efter dokumentationen og har aldrig kørt mod Google. `caldav.md` er nu den anden retning alene: verdandes egne opgaver læst af noget andet. En ting, byggeriet lærte: `</>` i inline-kode vælter Pythons html-parser på 3.9 med "we should not get here!". CI kører 3.12 og er ligeglad, men en side, der ikke kan bygges lokalt, er en side ingen retter. Knappen er beskrevet med ord i stedet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
868588de10
commit
f64b7c1f01
+7
-35
@@ -1,9 +1,10 @@
|
|||||||
# Calendar and CalDAV
|
# Calendar and CalDAV
|
||||||
|
|
||||||
Two ways to get your tasks into a calendar, one way to get a calendar into
|
Two ways to get your tasks into a calendar. Getting somebody else's calendar
|
||||||
verdande, and none of the three is the same thing.
|
*into* verdande is the other direction and has its own page — see
|
||||||
|
[Calendar](calendar.md).
|
||||||
|
|
||||||
| | [Feed](#subscribing-to-a-feed) | [CalDAV](#connecting-a-caldav-client) | [Google Calendar](#showing-a-google-calendar-in-verdande) |
|
| | [Feed](#subscribing-to-a-feed) | [CalDAV](#connecting-a-caldav-client) | [Calendars in](calendar.md) |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Direction | Tasks out, read only | Tasks out, two-way | Events **in**, read only |
|
| Direction | Tasks out, read only | Tasks out, two-way | Events **in**, read only |
|
||||||
| Works with | Anything that subscribes to a URL | Apple Reminders, Thunderbird, DAVx⁵ | A Google account |
|
| Works with | Anything that subscribes to a URL | Apple Reminders, Thunderbird, DAVx⁵ | A Google account |
|
||||||
@@ -42,39 +43,10 @@ most people actually keep.
|
|||||||
|
|
||||||
## Showing a Google calendar in verdande
|
## Showing a Google calendar in verdande
|
||||||
|
|
||||||
The two sections above send your tasks *out*. This is the other direction: your
|
Moved. Connecting a Google account, subscribing to an address, and what the grid
|
||||||
Google calendar drawn underneath them, so one screen answers "what does this day
|
does with either now live on their own page — see [Calendar](calendar.md).
|
||||||
already have in it".
|
|
||||||
|
|
||||||
**Settings → Integrations → Google Calendar → Connect**, then tick the calendars
|
This page is the other direction: verdande's own tasks, read by something else.
|
||||||
you want and press Save. They appear in **Calendar** in the sidebar, in Google's
|
|
||||||
own colour for each one, beside your own tasks with due dates.
|
|
||||||
|
|
||||||
It needs the same OAuth client Gmail uses, with the Calendar API enabled and the
|
|
||||||
second redirect URI registered — see [Configuration](configuration.md#google).
|
|
||||||
|
|
||||||
!!! warning "Read only"
|
|
||||||
verdande never writes to your Google calendar. An event cannot be dragged,
|
|
||||||
edited or ticked off here; clicking one opens it in Google, which is where it
|
|
||||||
can be changed. Your own tasks in the same grid still drag to another day as
|
|
||||||
they always have.
|
|
||||||
|
|
||||||
Writing would need the `calendar.events` scope and an answer to what should
|
|
||||||
happen when both sides moved the same meeting — which is a synchronisation
|
|
||||||
model rather than a scope, and it is deliberately not built yet.
|
|
||||||
|
|
||||||
!!! note "The Internal client applies here too"
|
|
||||||
An OAuth client registered as *Internal* in a Google Workspace can only be
|
|
||||||
used by accounts in that workspace, calendars included. A personal
|
|
||||||
`@gmail.com` address is refused with `org_internal`. For one personal account
|
|
||||||
the shorter road is the calendar's own secret address: in Google Calendar,
|
|
||||||
**Settings → the calendar → Integrate calendar → Secret address in iCal
|
|
||||||
format**. Nothing in verdande subscribes to one yet — it is the next piece of
|
|
||||||
this feature.
|
|
||||||
|
|
||||||
Events are kept for ninety days back and a year forward, refreshed every fifteen
|
|
||||||
minutes and whenever you press **Fetch now**. Paging the grid past that window
|
|
||||||
says so rather than showing an empty month.
|
|
||||||
|
|
||||||
## Connecting a CalDAV client
|
## Connecting a CalDAV client
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Calendar
|
||||||
|
|
||||||
|
Your dated tasks as a grid, with other people's calendars laid under them.
|
||||||
|
|
||||||
|
**Calendar** in the menu shows a month or a week. The week is a day: hours down the
|
||||||
|
side, and everything with a time on it in its place. Two things at ten o'clock sit
|
||||||
|
beside each other, because that is a clash you should be able to see rather than
|
||||||
|
read.
|
||||||
|
|
||||||
|
## What is in it
|
||||||
|
|
||||||
|
- **Your tasks**, on the day they are due — and at the time, if they have one.
|
||||||
|
- **Events from calendars you have connected**, read-only.
|
||||||
|
|
||||||
|
Drag a task to another day to move it. Drop it on the hour column and it takes that
|
||||||
|
time; drop it in the band across the top and it keeps the day and loses the time.
|
||||||
|
Events cannot be dragged: verdande holds a copy of somebody else's calendar, and a
|
||||||
|
chip that lets itself be moved is a promise the server cannot keep.
|
||||||
|
|
||||||
|
A project's own calendar is under **Calendar** on the project page, with the same
|
||||||
|
week and month.
|
||||||
|
|
||||||
|
## Subscribing to a calendar
|
||||||
|
|
||||||
|
**Settings → Integrations → Subscriptions.** Paste an address and it is fetched at
|
||||||
|
once.
|
||||||
|
|
||||||
|
This works with anything that publishes an `.ics` file: public holidays, a club's
|
||||||
|
fixtures, a shared calendar from work, your own calendar's secret address from
|
||||||
|
Google, Apple or Fastmail.
|
||||||
|
|
||||||
|
- **`webcal://` addresses work.** They are the same URL over https with a scheme
|
||||||
|
that makes a desktop hand it to the calendar app; it is rewritten for you.
|
||||||
|
- **Several at a time.** Unlike the Google connection, which is one account, a
|
||||||
|
subscription is one address and you can have as many as you like.
|
||||||
|
- **Read-only, refreshed every fifteen minutes.**
|
||||||
|
- The address is fetched once before it is stored, so a typo tells you now rather
|
||||||
|
than by silently never filling.
|
||||||
|
|
||||||
|
!!! note "This is the way in for a private account"
|
||||||
|
If the instance's Google registration is *Internal*, Google refuses accounts
|
||||||
|
from outside the organisation with `org_internal` — no setting on your side
|
||||||
|
changes that. Your calendar's own secret ICS address goes through this panel
|
||||||
|
and works regardless.
|
||||||
|
|
||||||
|
## Connecting Google Calendar
|
||||||
|
|
||||||
|
**Settings → Integrations → Google Calendar.** It shares the OAuth client Gmail
|
||||||
|
uses, so the instance needs that registration first — see
|
||||||
|
[Configuration](configuration.md#google).
|
||||||
|
|
||||||
|
Two things have to be true in Google Cloud, and only the owner of the registration
|
||||||
|
can do them:
|
||||||
|
|
||||||
|
1. **Google Calendar API** is enabled for the project.
|
||||||
|
2. The calendar callback is listed as an authorised redirect URI. The exact string
|
||||||
|
is printed in the panel — copy it from there rather than typing it. Google
|
||||||
|
compares it exactly: scheme, host, path, no trailing slash. `redirect_uri_mismatch`
|
||||||
|
almost always means one of those four differs.
|
||||||
|
|
||||||
|
Once connected, tick the calendars you want to see. The list is refreshed on every
|
||||||
|
sync, so a calendar added or renamed since last time appears under its new name.
|
||||||
|
|
||||||
|
!!! warning "Written to the specification, not yet proven against Google"
|
||||||
|
The Google Calendar half is implemented from Google's documentation and tested
|
||||||
|
against a stand-in server. It has not been exercised against Google itself.
|
||||||
|
The subscription route above and the outgoing feed below have.
|
||||||
|
|
||||||
|
## Your own calendar, elsewhere
|
||||||
|
|
||||||
|
Two ways out, for two different jobs:
|
||||||
|
|
||||||
|
- **[The ICS feed](caldav.md#subscribing-to-a-feed)** — a read-only address for Apple Calendar,
|
||||||
|
Google or Thunderbird. Your tasks appear as dated entries.
|
||||||
|
- **[CalDAV](caldav.md)** — two-way. Tick something off in Apple Reminders and it
|
||||||
|
is ticked off here.
|
||||||
|
|
||||||
|
The feed address is a credential in itself: anybody holding it can read your tasks
|
||||||
|
without logging in, because a calendar client cannot sign in. Rotate it from
|
||||||
|
**Settings → Integrations** if it gets out.
|
||||||
|
|
||||||
|
## What it does not do
|
||||||
|
|
||||||
|
- **It does not write to a connected calendar.** Events are a copy.
|
||||||
|
- **It does not expand repeating events** from a subscribed file. A weekly meeting
|
||||||
|
in somebody else's calendar is stored as its first occurrence.
|
||||||
|
- **It does not resolve named time zones** from a subscribed file. An event carrying
|
||||||
|
`TZID=Europe/Copenhagen` shows the clock the file wrote, rather than one this
|
||||||
|
server has moved.
|
||||||
|
- **Only Google, and only reading**, for account connections. Everything else goes
|
||||||
|
through a subscription.
|
||||||
+157
@@ -0,0 +1,157 @@
|
|||||||
|
# Notes
|
||||||
|
|
||||||
|
Markdown in, Markdown out. Nothing in between.
|
||||||
|
|
||||||
|
A note is written as rich text — headings, lists, quotations, code — and stored as
|
||||||
|
the Markdown it looks like. That is not a detail about the database: it is what
|
||||||
|
makes a note yours. Export gives you the same text you were looking at, and on the
|
||||||
|
day this program is gone, every note opens in any editor.
|
||||||
|
|
||||||
|
## Writing
|
||||||
|
|
||||||
|
Start typing. **The first line is the title** — always, and re-derived every time
|
||||||
|
you save, so a note you rewrite the top of is called by what it now says rather
|
||||||
|
than by what it once did.
|
||||||
|
|
||||||
|
| Style | Written as | Shortcut |
|
||||||
|
|---|---|---|
|
||||||
|
| Title | `# ` at the start of the line | pick it in **Aa** |
|
||||||
|
| Heading | `## ` | |
|
||||||
|
| Subheading | `### ` | |
|
||||||
|
| Quote | `> ` | |
|
||||||
|
| Code block | three backticks, with an optional language | |
|
||||||
|
| Bullet and numbered lists | `- ` and `1. `, nested with Tab | |
|
||||||
|
| Bold | two asterisks around the words | ⌘B |
|
||||||
|
| Italic | one asterisk around the words | ⌘I |
|
||||||
|
| Underline | a `u` tag around the words | ⌘U |
|
||||||
|
| Strikethrough | two tildes around the words | |
|
||||||
|
| Code | one backtick around the words | |
|
||||||
|
|
||||||
|
Every line becomes exactly one block. Markdown would normally join consecutive
|
||||||
|
lines into a paragraph; here it does not, because you typed a line and expect to
|
||||||
|
get it back.
|
||||||
|
|
||||||
|
Press the source button in the toolbar to see the note as the file it is. Edits there are edits to the
|
||||||
|
note.
|
||||||
|
|
||||||
|
### Pictures
|
||||||
|
|
||||||
|
Paste one, or drag it onto the note. It is stored with the note and travels with
|
||||||
|
it in an export. Every raster format works; SVG is stored but not shown inline —
|
||||||
|
it is a document that can run script, and a note is not a place to run somebody
|
||||||
|
else's.
|
||||||
|
|
||||||
|
### Code blocks
|
||||||
|
|
||||||
|
A fenced block is coloured for the language it names, and guesses when it does not.
|
||||||
|
Each one carries a **Copy** button in its corner.
|
||||||
|
|
||||||
|
## Linking
|
||||||
|
|
||||||
|
Three kinds of reference, parsed out of the text as you write it:
|
||||||
|
|
||||||
|
| You type | It means |
|
||||||
|
|---|---|
|
||||||
|
| `#Firma` | The project — the same `#Firma` quick add understands, not a second kind of tag |
|
||||||
|
| `[[Møde med Anders]]` | Another note, by its title |
|
||||||
|
| A pasted task link | That task |
|
||||||
|
|
||||||
|
Links are an index over the text, rebuilt every time the note is saved. The text
|
||||||
|
stays the truth.
|
||||||
|
|
||||||
|
**The interesting direction is backwards.** A task shows what has been written
|
||||||
|
about it, and a project shows the notes filed in it — without anybody having to
|
||||||
|
remember to attach anything. Write `#Firma` in a note and it appears on that
|
||||||
|
project's page.
|
||||||
|
|
||||||
|
A link to something that has been deleted reads as a dead link. It is a fact about
|
||||||
|
the note, and it should not vanish because something it mentioned did.
|
||||||
|
|
||||||
|
## Filing and sharing
|
||||||
|
|
||||||
|
A note belongs to a project, or to nobody.
|
||||||
|
|
||||||
|
- **In a project:** everybody who can read the project can read the note, and an
|
||||||
|
editor can change it. Choose it under **Share in** at the foot of the note.
|
||||||
|
- **In no project:** yours, and nobody else's.
|
||||||
|
|
||||||
|
There is no folder tree. Projects, groups and labels already exist, are already
|
||||||
|
shared and already have roles — a second hierarchy to file things in is one too
|
||||||
|
many, and a note in a project inherits every one of those answers.
|
||||||
|
|
||||||
|
## Finding
|
||||||
|
|
||||||
|
The list groups itself: favourites first, then **Today**, **Yesterday**, **This
|
||||||
|
week**, and then by month. Sort by created, last touched or name, and the grouping
|
||||||
|
follows — sorted by name it groups by first letter instead.
|
||||||
|
|
||||||
|
Search finds a word wherever it is:
|
||||||
|
|
||||||
|
- **`gron` finds `grøn`.** Unicode does not consider `ø` an accented `o`, so
|
||||||
|
stripping diacritics is not enough for Danish. A folded copy of every note is
|
||||||
|
indexed beside the original.
|
||||||
|
- **`inventory` finds `keepInventory`.** An index is built of whole words, and a
|
||||||
|
decade of notes is full of commands and identifiers that are several words in
|
||||||
|
one. When the index has nothing, the text itself is read.
|
||||||
|
- Results are ranked by how well they match, with the title weighted ten times the
|
||||||
|
body. A word in the title is what the note is about; the same word once in a long
|
||||||
|
body is a mention.
|
||||||
|
|
||||||
|
## Putting notes away
|
||||||
|
|
||||||
|
Two different things, and the difference matters:
|
||||||
|
|
||||||
|
- **Archive** — this is finished and I do not want to read past it. It stays
|
||||||
|
findable and comes back whenever you ask.
|
||||||
|
- **Trash** — this was a mistake. It is gone in thirty days.
|
||||||
|
|
||||||
|
Select several with ⌘-click and shift-click to archive or delete them together.
|
||||||
|
|
||||||
|
## In and out
|
||||||
|
|
||||||
|
**Export** gives you a zip of Markdown files, one per note, with the dates in a
|
||||||
|
YAML front matter block that Obsidian and Bear also read:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
created: 2019-04-02T10:15:00Z
|
||||||
|
modified: 2024-11-30T21:04:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Møde med Anders
|
||||||
|
|
||||||
|
Han vil gerne have kaffe hver uge.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Import** takes the same shape back. Pictures travel in the zip beside the notes,
|
||||||
|
and the links in the text are relative — so a note and its pictures must be in the
|
||||||
|
same archive, which matters when a large export is split into parts.
|
||||||
|
|
||||||
|
Two things to know before importing:
|
||||||
|
|
||||||
|
- **Nothing is merged.** Every run creates new notes. Importing the same archive
|
||||||
|
twice gives you two of everything.
|
||||||
|
- **The dates are read from the front matter.** Without them, a move of a thousand
|
||||||
|
notes is a pile that was all written the same evening — and the order they were
|
||||||
|
written in is half of what an archive is.
|
||||||
|
|
||||||
|
### From Apple Notes
|
||||||
|
|
||||||
|
`tools/apple-notes-til-markdown.py` in the repository exports Apple Notes to
|
||||||
|
exactly this shape, front matter and pictures included. It is macOS-only, because
|
||||||
|
Apple Notes is.
|
||||||
|
|
||||||
|
For a large library, `tools/pak-noter-i-portioner.py` splits the export into
|
||||||
|
uploadable parts, keeping each note with its own pictures.
|
||||||
|
|
||||||
|
## What is not encrypted
|
||||||
|
|
||||||
|
Note bodies are stored as plain text. **A note holding a password or an API key is
|
||||||
|
holding it in plain text in every backup you can download.** The mailbox
|
||||||
|
credentials, OAuth tokens and AI keys are sealed; note bodies are not, and neither
|
||||||
|
are task titles, descriptions or comments.
|
||||||
|
|
||||||
|
Encrypting them is on the list and is bigger than it sounds — the full-text index
|
||||||
|
and the folded search copy are both derived from the body, so both would have to go
|
||||||
|
and search would have to be rewritten. Until then: keep secrets somewhere built for
|
||||||
|
them.
|
||||||
+3
-1
@@ -50,10 +50,12 @@ nav:
|
|||||||
- Using it:
|
- Using it:
|
||||||
- Signing in: signing-in.md
|
- Signing in: signing-in.md
|
||||||
- Quick add: quick-add.md
|
- Quick add: quick-add.md
|
||||||
|
- Notes: notes.md
|
||||||
- Filters: filters.md
|
- Filters: filters.md
|
||||||
- Importing from Todoist: import.md
|
- Importing from Todoist: import.md
|
||||||
- Connecting things:
|
- Connecting things:
|
||||||
- Calendar and CalDAV: caldav.md
|
- Calendar: calendar.md
|
||||||
|
- Feeds and CalDAV: caldav.md
|
||||||
- Mail to task: mail.md
|
- Mail to task: mail.md
|
||||||
- Mailboxes: mailboxes.md
|
- Mailboxes: mailboxes.md
|
||||||
- Claude (MCP): mcp.md
|
- Claude (MCP): mcp.md
|
||||||
|
|||||||
Reference in New Issue
Block a user