57deb62b51
Every planet position now carries its whole-sign house (1-12); transits report the natal house each transiting planet currently occupies rather than a fresh "houses for right now" chart, matching how transits are normally read. Surfaced in both text and HTML output, fully translated.
159 lines
6.8 KiB
Markdown
159 lines
6.8 KiB
Markdown
# Input & output formats
|
|
|
|
See [`architecture.md`](architecture.md) for how these fit together.
|
|
There are two ways to provide input (direct CLI flags, or `run.sh` +
|
|
`user.properties`) and two output formats (`text`, `html`); the
|
|
`DailyReading` struct is the programmatic form both outputs are rendered
|
|
from, and the one the future watchapp will consume directly.
|
|
|
|
## Input
|
|
|
|
### Direct CLI flags (`dist/deck-engine`)
|
|
|
|
```
|
|
deck-engine --seed <string> --birth-date YYYY-MM-DD --birth-time HH:MM
|
|
--birth-utc-offset <hours> --birth-lat <deg> --birth-lon <deg>
|
|
[--date YYYY-MM-DDTHH:MM] [--format text|html]
|
|
```
|
|
|
|
| Flag | Required | Format | Meaning |
|
|
|---|---|---|---|
|
|
| `--seed` | yes | any string | Tarot seed. The same seed always produces the same 10-card spread, positions, and orientations (see `rng.c`/`tarot.c`). |
|
|
| `--birth-date` | yes | `YYYY-MM-DD` | Birth date, local calendar. |
|
|
| `--birth-time` | yes | `HH:MM` (24h) | Birth time, local clock. |
|
|
| `--birth-utc-offset` | yes | decimal hours, e.g. `2` or `-5.5` | Hours to **subtract** from local birth time to get UTC (e.g. `2` for CEST). |
|
|
| `--birth-lat` | yes | decimal degrees | Birth latitude, north positive. |
|
|
| `--birth-lon` | yes | decimal degrees | Birth longitude, east positive. |
|
|
| `--date` | no | `YYYY-MM-DDTHH:MM[:SS]` | UTC moment used for today's transits and as the moment the tarot seed is drawn against. Defaults to the current system time. |
|
|
| `--format` | no | `text` \| `html` | Output format, defaults to `text`. |
|
|
| `--lang` | no | language code, e.g. `en`, `de` | Reading language, defaults to `en`. Matches a file named `<code>.lang` in `--i18n-dir` (see "Translations" below). Unknown codes or missing files fall back to English with a warning on stderr. |
|
|
| `--i18n-dir` | no | path | Directory to look for `<lang>.lang` in. Defaults to an `i18n/` directory next to the binary itself (resolved from `argv[0]`, so `dist/deck-engine` finds `dist/i18n/` regardless of the caller's working directory). |
|
|
|
|
Birth latitude/longitude only affect the Ascendant/houses — planet signs
|
|
are geocentric and location-independent.
|
|
|
|
### `run.sh` + `user.properties`
|
|
|
|
`dist/run.sh [text|html] [lang]` wraps the binary for daily use:
|
|
|
|
- **Seed and `--date`** come from the OS clock: `date +%Y-%m-%d` (stable
|
|
all day) and `date -u +%Y-%m-%dT%H:%M`.
|
|
- **Birth data and language** are read from `dist/user.properties`, a
|
|
`key=value` properties file next to the script (`#`-prefixed lines and
|
|
blank lines are comments; whitespace around `=` is trimmed):
|
|
|
|
```properties
|
|
birth_date=1990-05-14
|
|
birth_time=14:32
|
|
birth_utc_offset=2
|
|
birth_lat=52.5200
|
|
birth_lon=13.4050
|
|
lang=en
|
|
```
|
|
|
|
The file is seeded once from `engine/scripts/user.properties.template`
|
|
with placeholder values (`YOUR_BIRTH_DATE_HERE`, etc.) and is **never
|
|
overwritten by later builds**. `run.sh` checks every birth field for an
|
|
empty value or a leftover `YOUR_` placeholder and refuses to run with a
|
|
clear error until the file is filled in; `lang` has no such check since
|
|
it always has a usable default (`en`).
|
|
- The optional second argument overrides `lang=` for a single run without
|
|
editing the file, e.g. `dist/run.sh html de`.
|
|
|
|
### Translations (`--lang`, `dist/i18n/`)
|
|
|
|
Every piece of display text — planet/sign/moon-phase/aspect names, tarot
|
|
card names and meanings, Celtic Cross position names, and the section
|
|
headers in the `text`/`html` output — is looked up in a translation
|
|
catalog with the built-in English text as the fallback for any key the
|
|
catalog doesn't have. See `CLAUDE.md`'s "Translations" section for the
|
|
key-naming convention and how to add a new language.
|
|
|
|
`engine/i18n/en.lang` and `de.lang` are the shipped translation files;
|
|
`make` copies `engine/i18n/*.lang` to `dist/i18n/` (refreshed on every
|
|
build, like `dist/img/`). Adding a language is just dropping another
|
|
`<code>.lang` file into `engine/i18n/` — no code changes needed.
|
|
|
|
## Output
|
|
|
|
### `DailyReading` (the real output — `reading.h`)
|
|
|
|
`reading_generate()` is the actual API; `text`/`html` below are just two
|
|
ways of rendering the struct it fills in. This is what the watchapp will
|
|
read directly once it exists.
|
|
|
|
```c
|
|
typedef struct {
|
|
NatalChart natal;
|
|
DailyTransits transits;
|
|
CelticCrossSpread spread;
|
|
} DailyReading;
|
|
```
|
|
|
|
- **`NatalChart`** (`astro.h`): `bodies[10]` (Sun..Pluto, each a sign +
|
|
degree-in-sign + raw ecliptic longitude + whole-sign `house` 1-12),
|
|
`ascendant_longitude`, `houses[12]` (whole-sign: `houses[0]` is the
|
|
Ascendant's sign).
|
|
- **`DailyTransits`** (`astro.h`): `bodies[10]` (today's positions, same
|
|
shape as above — `house` here is the natal chart's house the
|
|
transiting planet currently occupies, not a fresh "houses for right
|
|
now" chart), `moon_phase` (one of 8 named phases), `aspects[]` +
|
|
`aspect_count` (each aspect names a transiting planet, a natal planet,
|
|
an `AspectType` — conjunction/sextile/square/trine/opposition — and
|
|
the orb in degrees).
|
|
- **`CelticCrossSpread`** (`tarot.h`): `positions[10]`, indexed by
|
|
`CelticCrossPosition` (Present, Challenge, Crown, Foundation, Recent
|
|
Past, Near Future, Attitude, Environment, Hopes and Fears, Outcome —
|
|
Waite's own drawing order), each holding a `TarotCard` and a `reversed`
|
|
bool.
|
|
|
|
### `--format text`
|
|
|
|
Four `=====`-delimited sections, in order: natal chart (each body's sign
|
|
+ degree + house, then the Ascendant), today's sky (Moon phase, then each
|
|
body's transiting position + the natal house it currently occupies),
|
|
today's aspects to the natal chart (one line per aspect, with orb), and
|
|
the Celtic Cross (one block per position: name, card, `(Reversed)` if
|
|
applicable, the position's meaning, then the card's meaning).
|
|
|
|
```
|
|
===== Natal Chart =====
|
|
Sun 23.5° Taurus (House 3)
|
|
Moon 15.2° Capricorn (House 11)
|
|
...
|
|
Ascendant 18.4° Pisces
|
|
|
|
===== Today's Sky =====
|
|
Moon phase: Waning Gibbous
|
|
Sun 11.5° Cancer (House 5)
|
|
...
|
|
|
|
===== Today's Aspects to Natal Chart =====
|
|
Transiting Sun Opposition natal Moon (orb 3.7°)
|
|
...
|
|
|
|
===== Celtic Cross =====
|
|
The Present The High Priestess (Reversed)
|
|
This covers him: the general influence affecting the matter.
|
|
Passion, moral or physical ardour, conceit, surface knowledge.
|
|
...
|
|
```
|
|
|
|
### `--format html`
|
|
|
|
A single self-contained HTML page (inline `<style>`, no JS, no external
|
|
requests) with the same four sections, plus each of the 10 Celtic Cross
|
|
cards rendered as an image:
|
|
|
|
```html
|
|
<img class="reversed" src="img/RWS_Tarot_02_High_Priestess.jpeg" alt="The High Priestess">
|
|
```
|
|
|
|
- `src="img/<file>"` is relative to the **HTML file's own location** —
|
|
it expects to sit next to an `img/` directory, exactly like
|
|
`dist/reading.html` next to `dist/img/` (which `make images` populates
|
|
from `res/img/`). Saving the HTML output anywhere else breaks the
|
|
image links.
|
|
- Reversed cards get `class="reversed"`, styled with `transform:
|
|
rotate(180deg)` in the page's inline CSS.
|