Give the interpreter real Celtic Cross meanings and --format/--lang support
- guidance.c now prints last, after the full spread; both it and main.c's new Celtic Cross readout pull real Waite card meanings via tarot_data.c instead of just naming cards. - interpreter-cli gains --format text|html|json and --lang en|de, matching deck-engine - required linking engine/src/tarot_data.c and i18n.c into the interpreter binary (a narrow, documented exception to its earlier "no engine .c files" policy) and writing German translations for narrative.c's/guidance.c's own text.
This commit is contained in:
+225
-36
@@ -4,9 +4,10 @@ See [`architecture.md`](architecture.md) for how these fit together.
|
||||
There are two ways to provide input (direct CLI flags, or `run-engine.sh`
|
||||
+ `user.properties`) and three output formats (`text`, `html`, `json`); the
|
||||
`DailyReading` struct is the programmatic form all three are rendered
|
||||
from, and the one the future watchapp will consume directly. `json` is
|
||||
also `interpreter-cli`'s input format — see "The interpreter" at the
|
||||
bottom of this file.
|
||||
from, and the one watch UI code consumes directly. `json` is also
|
||||
`interpreter-cli`'s input format — see "The interpreter" at the bottom
|
||||
of this file, which supports the same three output formats (and the
|
||||
same `--lang`) for its own report, independently of `deck-engine`.
|
||||
|
||||
## Input
|
||||
|
||||
@@ -90,8 +91,8 @@ build, like `dist/img/`). Adding a language is just dropping another
|
||||
### `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.
|
||||
ways of rendering the struct it fills in. This is what watch UI code
|
||||
reads directly.
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
@@ -227,16 +228,39 @@ read.
|
||||
`dist/interpreter-cli` is a separate binary — see `CLAUDE.md`'s
|
||||
"Interpretation" section for the full architecture — that reads a
|
||||
`--format json` document and scores how significant today's transits
|
||||
are. It never links the engine; it only depends on the JSON shape
|
||||
above.
|
||||
are. It never links `astro.c`/`tarot.c`/`reading.c` (or the vendored
|
||||
Astronomy Engine) — only `engine/src/tarot_data.c`/`i18n.c` are linked
|
||||
in, for real card/position names and Waite meaning text (see
|
||||
`CLAUDE.md`'s `INTERP_TAROT_TEXT_OBJS` note). Otherwise it depends only
|
||||
on the JSON shape above.
|
||||
|
||||
Like `deck-engine`, its own output supports `--format text|html|json`
|
||||
and `--lang <code>`/`--i18n-dir <path>`:
|
||||
|
||||
| Flag | Required | Format | Meaning |
|
||||
|---|---|---|---|
|
||||
| `[reading.json]` | no | file path or `-` | Input file; stdin (or `-`) if omitted. |
|
||||
| `--format` | no | `text` \| `html` \| `json` | This binary's **own output** format, defaults to `text`. Entirely independent of the `--format json` that produced its *input* - see below. |
|
||||
| `--lang` | no | language code, e.g. `en`, `de` | This binary's **own output** language, defaults to `en`. Same `<code>.lang`/`--i18n-dir` convention as `deck-engine` (see "Translations" above) - `main.c` calls `i18n_load()` itself, so `narrative.c`'s/`guidance.c`'s own text (in `engine/i18n/*.lang` under `narrative.*`/`guidance.*` keys) is translated too, not just the card/position/body/sign/aspect vocabulary it shares with `deck-engine`. |
|
||||
| `--i18n-dir` | no | path | Same convention as `deck-engine`'s: defaults to an `i18n/` directory next to this binary. |
|
||||
|
||||
**This `--lang` is unrelated to whatever `--lang` `deck-engine` was run
|
||||
with to produce the `--format json` input** - that JSON is always
|
||||
language-independent (slugs only, see above), so it doesn't matter what
|
||||
language `deck-engine` printed anything in, or whether it was even asked
|
||||
to print anything at all (`--format json` never touches `--lang`
|
||||
either). The two `--lang` flags, on the two sides of the pipe, are
|
||||
independent settings.
|
||||
|
||||
```bash
|
||||
dist/deck-engine ... --format json | dist/interpreter-cli
|
||||
dist/deck-engine ... --format json | dist/interpreter-cli --format html --lang de
|
||||
# or:
|
||||
dist/deck-engine ... --format json > reading.json
|
||||
dist/interpreter-cli reading.json
|
||||
# or, for daily use (OS clock + user.properties, same inputs as run-engine.sh):
|
||||
dist/run-interpreter.sh
|
||||
dist/interpreter-cli --format json reading.json
|
||||
# or, for daily use (OS clock + user.properties, same inputs as run-engine.sh,
|
||||
# including user.properties' lang=):
|
||||
dist/run-interpreter.sh # text output, language from user.properties
|
||||
dist/run-interpreter.sh html de # override format/language for this run
|
||||
```
|
||||
|
||||
- **Input**: a file path argument, or stdin if no argument (or `-`) is
|
||||
@@ -244,30 +268,195 @@ dist/run-interpreter.sh
|
||||
means "no notable transits today"; a missing key is treated as invalid
|
||||
input) and drives scoring. `"natal"."bodies"`/`"transits"."bodies"` are
|
||||
read too, for the sign/house context printed alongside each event below
|
||||
(not for scoring) — an entry naming an unrecognized body, or a missing
|
||||
`house`, is silently skipped rather than failing the load (see
|
||||
`parse_bodies()` in `reading_io.c`); `spread` is always ignored.
|
||||
- **Output**: a plain-text report — the day's overall significance level
|
||||
(`Quiet`/`Notable`/`Significant`/`Major`, plus its rank out of the 4
|
||||
defined levels, e.g. `Notable (2/4)`), a "worth a deeper Celtic Cross
|
||||
look" line on `Major` days only, and up to 5 of today's aspects ranked
|
||||
by score, each naming the sign and natal house the transiting planet
|
||||
currently occupies and the sign and house of the natal planet it's
|
||||
aspecting, followed by a short narrative sentence about what that
|
||||
transiting planet classically signifies *and which area of life its
|
||||
current house governs* (see `CLAUDE.md`'s `narrative.c` bullet) —
|
||||
omitted only if the source material has nothing to say for that
|
||||
planet/aspect combination:
|
||||
(not for scoring), and `"spread"."positions"` is read for the full
|
||||
Celtic Cross readout and the guidance paragraph below — an entry naming
|
||||
an unrecognized body/card/position, a missing `house`, or a missing
|
||||
`"spread"` key entirely is silently skipped/zeroed rather than failing
|
||||
the load (see `parse_bodies()`/`parse_spread()` in `reading_io.c`).
|
||||
- **Input**: same for all three output formats above - only how the
|
||||
parsed data gets rendered differs.
|
||||
|
||||
```
|
||||
Day significance: Significant (3/4)
|
||||
(a major transit today - worth a deeper Celtic Cross look)
|
||||
### `--format text`
|
||||
|
||||
Top 3 significant transits:
|
||||
1. Transiting Saturn in Aries (house 2) Square natal Sun in Taurus (house 3) (orb 0.5°, score 8.10)
|
||||
In matters of money, possessions, and personal values (house 2). Brings depression, stagnation, hindrances and obstacles, and some deprivation of the usual benefits.
|
||||
2. Transiting Pluto in Aquarius (house 12) Opposition natal Moon in Capricorn (house 11) (orb 0.2°, score 7.92)
|
||||
In matters of solitude, the subconscious, and hidden matters (house 12). Brings deep, often hidden transformation - the surfacing or dismantling of something that has outgrown its old form.
|
||||
3. Transiting Jupiter in Leo (house 5) Trine natal Venus in Aries (house 2) (orb 2.1°, score 3.40)
|
||||
In matters of romance, creativity, and children (house 5). Brings increase and expansion - fullness of fortune and health, and a generally fortunate time.
|
||||
```
|
||||
A plain-text report, printed in a fixed order —
|
||||
1. the day's overall significance level (`Quiet`/`Notable`/
|
||||
`Significant`/`Major`, plus its rank out of the 4 defined levels,
|
||||
e.g. `Notable (2/4)`), with a "worth a deeper Celtic Cross look"
|
||||
line on `Major` days only;
|
||||
2. up to 5 of today's aspects ranked by score, each naming the sign
|
||||
and natal house the transiting planet currently occupies and the
|
||||
sign and house of the natal planet it's aspecting, followed by a
|
||||
short narrative sentence about what that transiting planet
|
||||
classically signifies *and which area of life its current house
|
||||
governs* (see `CLAUDE.md`'s `narrative.c` bullet) — omitted only if
|
||||
the source material has nothing to say for that planet/aspect
|
||||
combination;
|
||||
3. the full 10-position Celtic Cross spread, in Waite's own drawing
|
||||
order, each with its card (and orientation), the position's own
|
||||
description, and that card's actual meaning;
|
||||
4. finally, a guidance paragraph tying the day's top transit to the
|
||||
spread's Attitude/Outcome cards, with its opening sentence tailored
|
||||
to `day_level` (stronger wording on `Major`, softer on
|
||||
`Quiet`/`Notable`, falling back to a transit-free reading of the
|
||||
Attitude card alone on a day with no aspects at all) and, for the
|
||||
Attitude/Outcome cards it names, their actual Waite meaning for the
|
||||
orientation they landed in — see `CLAUDE.md`'s `guidance.c` bullet.
|
||||
This is printed last, as the closing takeaway after the reader has
|
||||
seen the full spread it references.
|
||||
|
||||
```
|
||||
Day significance: Major (4/4)
|
||||
(a major transit today - worth a deeper Celtic Cross look)
|
||||
|
||||
Top 5 significant transits:
|
||||
1. Transiting Pluto in Aquarius (house 3) Conjunction natal Moon in Aquarius (house 3) (orb 2.9°, score 9.60)
|
||||
In matters of communication, siblings, and everyday learning (house 3). Brings deep, often hidden transformation - the surfacing or dismantling of something that has outgrown its old form.
|
||||
2. Transiting Neptune in Aries (house 5) Sextile natal Moon in Aquarius (house 3) (orb 2.5°, score 9.25)
|
||||
In matters of romance, creativity, and children (house 5). Brings a state of chaos and confusion - an involved, uncertain condition of affairs, with plots, subtlety, or unseen influences at work.
|
||||
3. Transiting Uranus in Gemini (house 7) Trine natal Moon in Aquarius (house 3) (orb 2.0°, score 8.96)
|
||||
In matters of partnerships and close relationships (house 7). Brings separations, estrangements, sudden dislocations and violent upsets. Success through official or civic channels, and beneficial changes or appointments, are possible.
|
||||
|
||||
Celtic Cross:
|
||||
1. The Present: The Emperor (Reversed)
|
||||
This covers him: the general influence affecting the matter.
|
||||
Benevolence, compassion, credit; also confusion to enemies, obstruction, immaturity.
|
||||
2. The Challenge: The Devil
|
||||
This crosses him: the nature of the obstacle in the matter.
|
||||
Ravage, violence, vehemence, extraordinary efforts, force, fatality.
|
||||
...
|
||||
7. Himself: The Magician
|
||||
His position or attitude in the circumstances.
|
||||
Skill, diplomacy, address, subtlety; self-confidence, will.
|
||||
...
|
||||
10. The Outcome: Strength
|
||||
What will come: the final result of the matter.
|
||||
Power, energy, action, courage, magnanimity; complete success and honours.
|
||||
|
||||
With Pluto as today's dominant influence: Today concentrates whatever you already
|
||||
bring to it - your current approach will be amplified, so make sure it's the one
|
||||
you want.
|
||||
Your Attitude card is The Magician: Skill, diplomacy, address, subtlety; self-confidence, will.
|
||||
The spread's likely Outcome is Strength: Power, energy, action, courage, magnanimity; complete success and honours.
|
||||
```
|
||||
|
||||
On a quieter day, only the opening of the guidance paragraph changes:
|
||||
|
||||
```
|
||||
Day significance: Notable (2/4)
|
||||
...
|
||||
With a mild touch from Jupiter today: Your instincts are sound, but the day is
|
||||
testing them - hold your position without forcing the issue.
|
||||
Your Attitude card is The Sun: Material happiness, fortunate marriage, contentment.
|
||||
The spread's likely Outcome is Justice: Equity, rightness, probity, executive; triumph of the deserving side in law.
|
||||
```
|
||||
|
||||
The same report with `--lang de` (same input as the Major example
|
||||
above):
|
||||
|
||||
```
|
||||
Bedeutung des Tages: Einschneidend (4/4)
|
||||
(ein einschneidender Transit heute - ein genauerer Blick auf das Keltische Kreuz lohnt sich)
|
||||
|
||||
Top 5 wichtige Transits:
|
||||
1. Transit Pluto in Wassermann (Haus 3) Konjunktion natal Mond in Wassermann (Haus 3) (Orbis 2.9°, Punktzahl 9.60)
|
||||
In Fragen von Kommunikation, Geschwistern und alltäglichem Lernen (Haus 3). Bringt tiefgreifenden, oft verborgenen Wandel - das Auftauchen oder die Auflösung von etwas, das seine alte Form überwachsen hat.
|
||||
...
|
||||
|
||||
Keltisches Kreuz:
|
||||
1. Die Gegenwart: Der Herrscher (Umgekehrt)
|
||||
Dies bedeckt ihn: der allgemeine Einfluss, der die Angelegenheit betrifft.
|
||||
Wohlwollen, Mitgefühl, Ansehen; auch Verwirrung der Feinde, Behinderung, Unreife.
|
||||
...
|
||||
|
||||
Pluto ist heute der bestimmende Einfluss: Der heutige Tag verstärkt, was du bereits
|
||||
mitbringst - deine derzeitige Herangehensweise wird verstärkt, also stelle sicher,
|
||||
dass es die richtige ist.
|
||||
Deine Haltungskarte ist Der Magier: Geschick, Diplomatie, Gewandtheit, Feinsinn; Selbstvertrauen, Wille.
|
||||
Das wahrscheinliche Ergebnis des Blatts ist Kraft: Macht, Energie, Tatkraft, Mut, Großmut; voller Erfolg und Ehren.
|
||||
```
|
||||
|
||||
### `--format html`
|
||||
|
||||
A single self-contained HTML page, same inline-CSS/no-JS approach as
|
||||
`deck-engine`'s own `--format html`, and the same three sections as text
|
||||
(significant transits as a table, the full Celtic Cross as an image
|
||||
grid, guidance as a closing callout) - reusing the exact same
|
||||
`img/<file>` card-art convention (`tarot_card_image_file()`), so it
|
||||
expects to sit next to an `img/` directory just like `deck-engine`'s
|
||||
HTML output:
|
||||
|
||||
```html
|
||||
<div class="card">
|
||||
<div class="position">The Present</div>
|
||||
<img class="reversed" src="img/RWS_Tarot_04_Emperor.jpeg" alt="The Emperor">
|
||||
<div class="name">The Emperor (Reversed)</div>
|
||||
<div class="desc">This covers him: the general influence affecting the matter.</div>
|
||||
<div class="meaning">Benevolence, compassion, credit; also confusion to enemies, obstruction, immaturity.</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
The guidance section renders as one `<p>` per line of the same text
|
||||
`--format text` prints last (intro sentence, Attitude line, Outcome
|
||||
line), inside a `<div class="guidance">`.
|
||||
|
||||
### `--format json`
|
||||
|
||||
Unlike `deck-engine`'s own `--format json` - which is deliberately
|
||||
**language-independent** (slugs only, no `--lang`-dependent prose, since
|
||||
it's a machine interchange format between the two binaries) -
|
||||
`interpreter-cli`'s `--format json` embeds the *same localized
|
||||
narrative/guidance prose* `--format text` prints, in whatever `--lang`
|
||||
was loaded, **alongside** stable, language-independent slug fields. This
|
||||
is a deliberate difference: rendering that prose is this module's whole
|
||||
job, so a JSON consumer that wants it doesn't have to reimplement
|
||||
`narrative.c`/`guidance.c`'s logic itself - but a consumer that only
|
||||
wants structured data (e.g. watch UI code with its own rendering) still
|
||||
has the slugs to work with directly.
|
||||
|
||||
```json
|
||||
{
|
||||
"day_significance": {
|
||||
"level": "major",
|
||||
"rank": 4,
|
||||
"count": 4,
|
||||
"deserves_framing": true
|
||||
},
|
||||
"significant_transits": [
|
||||
{
|
||||
"transiting_planet": "pluto",
|
||||
"transiting_sign": "aquarius",
|
||||
"transiting_house": 3,
|
||||
"natal_planet": "moon",
|
||||
"natal_sign": "aquarius",
|
||||
"natal_house": 3,
|
||||
"aspect": "conjunction",
|
||||
"orb": 2.8821,
|
||||
"score": 9.5961,
|
||||
"narrative": "In matters of communication, siblings, and everyday learning (house 3). Brings deep, often hidden transformation - the surfacing or dismantling of something that has outgrown its old form."
|
||||
}
|
||||
],
|
||||
"celtic_cross": [
|
||||
{
|
||||
"position": "present",
|
||||
"card": "emperor",
|
||||
"reversed": true,
|
||||
"card_name": "The Emperor",
|
||||
"meaning": "Benevolence, compassion, credit; also confusion to enemies, obstruction, immaturity."
|
||||
}
|
||||
],
|
||||
"guidance": "With Pluto as today's dominant influence: Today concentrates whatever you already bring to it - your current approach will be amplified, so make sure it's the one you want.\nYour Attitude card is The Magician: Skill, diplomacy, address, subtlety; self-confidence, will.\nThe spread's likely Outcome is Strength: Power, energy, action, courage, magnanimity; complete success and honours."
|
||||
}
|
||||
```
|
||||
|
||||
- `significant_transits` has `interp.top_item_count` entries (0-5, same
|
||||
ranking as `--format text`); `celtic_cross` always has exactly 10, in
|
||||
`CelticCrossPosition` enum order (same order as `deck-engine`'s own
|
||||
`spread.positions`).
|
||||
- `orb`/`score` are `%.4f`, matching `deck-engine`'s own JSON precision
|
||||
for angles.
|
||||
- `guidance` is always present and non-empty (unlike
|
||||
`significant_transits`, which can be `[]` on a genuinely quiet day) -
|
||||
see `guidance.c`'s no-aspects-at-all fallback in `CLAUDE.md`.
|
||||
- With `--lang de`, every string value above except the slugs
|
||||
(`"level"`, `"transiting_planet"`, `"aspect"`, `"card"`, `"position"`,
|
||||
etc.) changes language; the slugs never do.
|
||||
|
||||
Reference in New Issue
Block a user