Add core engine: tarot + astrology reading generator with CLI and i18n
Plain-C, dependency-free engine that produces a personalized daily Celtic Cross tarot spread and natal-chart/transit astrology reading, plus a standalone CLI (dist/deck-engine) and run.sh wrapper. Includes English/German output via a simple key=value translation format, and docs/diagrams describing the architecture and I/O.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
digraph architecture {
|
||||
rankdir=LR;
|
||||
pad="0.3";
|
||||
fontname="Helvetica";
|
||||
node [shape=box, style="rounded,filled", fontname="Helvetica", fontsize=12, margin="0.15,0.1"];
|
||||
edge [fontname="Helvetica", fontsize=10];
|
||||
|
||||
labelloc="t";
|
||||
label="Deck in a Dash — component architecture";
|
||||
fontsize=16;
|
||||
|
||||
subgraph cluster_res {
|
||||
label="res/ (source assets)";
|
||||
style="dashed"; color=gray40; fontsize=11;
|
||||
images [label="22 RWS Major Arcana\nJPEGs (res/img/)", fillcolor="#fdf3d0"];
|
||||
pdf [label="Waite's \"Pictorial Key\nto the Tarot\" (PDF,\npublic domain)", fillcolor="#fdf3d0"];
|
||||
{ rank=same; images; pdf; }
|
||||
}
|
||||
|
||||
subgraph cluster_thirdparty {
|
||||
label="engine/third_party/astronomy/";
|
||||
style="dashed"; color=gray40; fontsize=11;
|
||||
astronomy [label="Astronomy Engine\n(vendored, MIT,\npinned commit)", fillcolor="#fdf3d0"];
|
||||
}
|
||||
|
||||
subgraph cluster_i18nsrc {
|
||||
label="engine/i18n/ (translation sources)";
|
||||
style="dashed"; color=gray40; fontsize=11;
|
||||
langfiles [label="en.lang, de.lang, ...\nkey=value per language", fillcolor="#fdf3d0"];
|
||||
}
|
||||
|
||||
subgraph cluster_engine {
|
||||
label="engine/src/ (core engine — plain C, no I/O assumptions except reading_print_*/main.c/i18n_load)";
|
||||
style="solid"; color=black; fontsize=11;
|
||||
|
||||
rng [label="rng.c\nstring-seeded PRNG\n(FNV-1a + splitmix64)", fillcolor="#cfe8fb"];
|
||||
tarot [label="tarot.c\nCeltic Cross draw", fillcolor="#cfe8fb"];
|
||||
tarot_data [label="tarot_data.c\ncard + position text", fillcolor="#cfe8fb"];
|
||||
astro [label="astro.c\nnatal chart + transits", fillcolor="#cfe8fb"];
|
||||
i18n [label="i18n.c\ntranslation catalog\n+ English fallback", fillcolor="#cfe8fb"];
|
||||
reading [label="reading.c\nDailyReading\norchestration + text/HTML", fillcolor="#c8f0c8"];
|
||||
main [label="main.c\nCLI arg parsing", fillcolor="#e3e3e3"];
|
||||
{ rank=same; main; reading; }
|
||||
{ rank=same; tarot; astro; i18n; }
|
||||
}
|
||||
|
||||
subgraph cluster_dist {
|
||||
label="dist/ (build output, generated by `make`)";
|
||||
style="dashed"; color=gray40; fontsize=11;
|
||||
binary [label="deck-engine", fillcolor="#fde0d0"];
|
||||
distimg [label="img/\n(copied JPEGs)", fillcolor="#fde0d0"];
|
||||
disti18n [label="i18n/\n(copied .lang files)", fillcolor="#fde0d0"];
|
||||
runsh [label="run.sh", fillcolor="#fde0d0"];
|
||||
props [label="user.properties\n(birth data + lang)", fillcolor="#fde0d0"];
|
||||
{ rank=same; binary; distimg; disti18n; runsh; props; }
|
||||
}
|
||||
|
||||
subgraph cluster_watch {
|
||||
label="Pebble watchapp — not built yet";
|
||||
style="dashed"; color=firebrick; fontsize=11; fontcolor=firebrick;
|
||||
watch [label="watchapp C / UI\n(future)", fillcolor=white, color=firebrick, fontcolor=firebrick, style="rounded,dashed"];
|
||||
}
|
||||
|
||||
pdf -> tarot_data [label="sourced from", style=dotted, color=gray40];
|
||||
|
||||
tarot -> rng;
|
||||
tarot -> tarot_data;
|
||||
astro -> astronomy;
|
||||
tarot_data -> i18n [label="looks up\ntranslated text", style=dotted, color=gray40];
|
||||
astro -> i18n [label="looks up\ntranslated text", style=dotted, color=gray40];
|
||||
reading -> i18n [label="looks up\nUI labels", style=dotted, color=gray40];
|
||||
reading -> tarot;
|
||||
reading -> astro;
|
||||
main -> reading [label="CLI only"];
|
||||
main -> i18n [label="i18n_load(\n--lang, --i18n-dir)"];
|
||||
|
||||
main -> binary [label="`make` builds", style=dotted, color=gray40];
|
||||
images -> distimg [label="`make images`\ncopies", style=dotted, color=gray40];
|
||||
langfiles -> disti18n [label="`make i18n`\ncopies", style=dotted, color=gray40];
|
||||
runsh -> props [label="reads at\nrun time", style=dotted, color=gray40];
|
||||
|
||||
watch -> reading [label="will call\nreading_generate()\ndirectly", style=dashed, color=firebrick, fontcolor=firebrick];
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
digraph dataflow {
|
||||
rankdir=TB;
|
||||
pad="0.3";
|
||||
fontname="Helvetica";
|
||||
node [fontname="Helvetica", fontsize=12, margin="0.15,0.1"];
|
||||
edge [fontname="Helvetica", fontsize=10];
|
||||
|
||||
labelloc="t";
|
||||
label="Deck in a Dash — dataflow for one reading";
|
||||
fontsize=16;
|
||||
|
||||
node [shape=box, style="rounded,filled"];
|
||||
|
||||
subgraph cluster_inputs {
|
||||
label="Inputs (two equivalent entry points)"; style=dashed; color=gray40; fontsize=11;
|
||||
cli [label="Direct CLI flags\n--seed --birth-* --date --format", fillcolor="#e3e3e3"];
|
||||
runsh [label="run.sh:\nOS clock -> seed + --date\nuser.properties -> birth-*", fillcolor="#e3e3e3"];
|
||||
}
|
||||
|
||||
main [label="main.c\nparses args into:\nseed (string), BirthData, utc_moment", fillcolor="#cfe8fb"];
|
||||
|
||||
reading_generate [label="reading_generate()\nreading.c", shape=box, style="rounded,filled", fillcolor="#9fd3f5", peripheries=2];
|
||||
|
||||
natal_fn [label="astro_compute_natal_chart()\nastro.c", fillcolor="#cfe8fb"];
|
||||
transit_fn [label="astro_compute_daily_transits()\nastro.c", fillcolor="#cfe8fb"];
|
||||
tarot_fn [label="tarot_draw_celtic_cross()\ntarot.c", fillcolor="#cfe8fb"];
|
||||
|
||||
natal_data [label="NatalChart\nbodies[10]: sign + degree\nascendant_longitude\nhouses[12] (whole-sign)", shape=note, fillcolor="#fdf3d0"];
|
||||
transit_data [label="DailyTransits\nbodies[10]\nmoon_phase\naspects[]: transiting/natal\nplanet, type, orb", shape=note, fillcolor="#fdf3d0"];
|
||||
spread_data [label="CelticCrossSpread\npositions[10]: card, reversed", shape=note, fillcolor="#fdf3d0"];
|
||||
|
||||
daily_reading [label="DailyReading\n{ natal, transits, spread }", shape=note, fillcolor="#fbe3c8", peripheries=2];
|
||||
|
||||
print_text [label="reading_print_text()", fillcolor="#cfe8fb"];
|
||||
print_html [label="reading_print_html()", fillcolor="#cfe8fb"];
|
||||
watch_fn [label="watchapp UI code\n(future — walks the struct\ndirectly, no print_* call)", fillcolor=white, color=firebrick, fontcolor=firebrick, style="rounded,dashed"];
|
||||
|
||||
out_text [label="stdout: plain-text report", shape=parallelogram, fillcolor="#c8f0c8"];
|
||||
out_html [label="stdout: reading.html\n(<img src=\"img/...\"> per card)", shape=parallelogram, fillcolor="#c8f0c8"];
|
||||
out_watch [label="watch screens\n(future)", shape=parallelogram, fillcolor=white, color=firebrick, fontcolor=firebrick, style="dashed"];
|
||||
|
||||
cli -> main;
|
||||
runsh -> main;
|
||||
main -> reading_generate [label="seed, birth,\nutc_moment"];
|
||||
|
||||
reading_generate -> natal_fn [label="birth"];
|
||||
natal_fn -> natal_data;
|
||||
|
||||
reading_generate -> transit_fn [label="utc_moment,\nNatalChart"];
|
||||
natal_data -> transit_fn [style=dotted, color=gray40, label="natal chart\nread-only"];
|
||||
transit_fn -> transit_data;
|
||||
|
||||
reading_generate -> tarot_fn [label="seed"];
|
||||
tarot_fn -> spread_data;
|
||||
|
||||
natal_data -> daily_reading;
|
||||
transit_data -> daily_reading;
|
||||
spread_data -> daily_reading;
|
||||
|
||||
daily_reading -> print_text;
|
||||
daily_reading -> print_html;
|
||||
daily_reading -> watch_fn [style=dashed, color=firebrick];
|
||||
|
||||
print_text -> out_text;
|
||||
print_html -> out_html;
|
||||
watch_fn -> out_watch [style=dashed, color=firebrick];
|
||||
}
|
||||
Reference in New Issue
Block a user