feat(notation): Schlagworte &tag gebaut — taiga.<slug> benennt das Projekt je Teilbaum, vererbt (SPEC §1, D91)

SPEC zuerst: §1 Schritt 5b samt Block und Referenz-Regex, §11 auf
'umgesetzt' umgestellt; llms.md nachgezogen. Parser extrahiert
alleinstehende &-Token als node.marks (Zitier-Konvention gilt),
taigaSlugs() in model.js vererbt das taiga.*-Schlagwort wie die
@-Tags beim Engpass. Sichtbar im Tooltip und aria-label (a11yMarks,
9 Sprachen). Plan-Labels mit &-Erwähnungen eingeklammert; 12 neue
Tests, Gegenprobe: ohne Alleinstehend-Anker fallen genau die zwei
Zitier-Tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-27 16:20:03 +02:00
co-authored by Claude Fable 5
parent c712e81970
commit 5a18505571
9 changed files with 207 additions and 42 deletions
+25
View File
@@ -565,6 +565,31 @@ export function personFoldSet(roots, tag){
return set;
}
/* ---------- Taiga-Projekt-Schlagwort (SPEC §1/§11, D91) ----------
`&taiga.<slug>` benennt das Taiga-Projekt eines Teilbaums und vererbt sich
auf die Nachkommen wie die `@`-Tags beim Zuständigen-Engpass (D71): der
nächste Vorfahr mit einem `taiga.*`-Schlagwort gewinnt, ein eigenes am
Knoten übersteuert; trägt eine Zeile mehrere, gilt das erste. Map
Knoten -> Slug, nur für Knoten, die (geerbt) eines haben — Konsument ist
die Vorbelegung des Projekt-Dialogs der Ticket-Anlage. */
export function taigaSlugs(roots){
const map = new Map();
const own = n => {
for(const m of n.marks || [])
if(m.startsWith('taiga.') && m.length > 'taiga.'.length) return m.slice('taiga.'.length);
return null;
};
const walk = (ns, inherited) => {
for(const n of ns){
const slug = own(n) || inherited;
if(slug) map.set(n, slug);
walk(n.children, slug);
}
};
walk(roots, null);
return map;
}
/* Alle vergebenen Personen-Tags in Dokumentreihenfolge — die Einträge der
Personen-Leiste (D87). */
export function allTags(roots){