mindnet_obsidian/docs/12_Heading_Block_Link_Recommendation.md

105 lines
7.1 KiB
Markdown
Raw Permalink Normal View History

# Bewertung & Empfehlung: Überschrift vs. Block-Link (Heading-Match)
**Datum:** Januar 2026
**Kontext:** Exaktes Heading-Matching in Inspect Chains / Chain Workbench vs. Obsidian-Standard und Interview-Assistent.
---
## 1. Obsidian-Standard (Dokumentation & beobachtetes Verhalten)
### 1.1 Drei relevante Link-Formen (bei Überschrift mit Block-ID)
Bei einer Zeile `## Überschrift ^Block` in der Zieldatei:
| Link | Verhalten beim Klick |
|------|----------------------|
| **`[[Titel#Überschrift Block]]`** (ohne `^`) | Obsidian **erzeugt diese Form**, wenn man manuell per UI auf die Überschrift verlinkt – das Zeichen `^` wird **immer entfernt**. Springt auf die Überschrift, **highlighted den kompletten Text unter der Überschrift**. |
| **`[[Titel#Überschrift]]`** (nur Text, ohne „ Block“) | Springt **in die Note, aber nicht auf die Überschrift**. Entspricht dem aktuellen Interview-Assistenten. |
| **`[[Titel#^Block]]`** (Block-Link) | Springt auf die Überschrift, **highlighted nur die Überschrift selbst** (nicht den Abschnitt darunter). Funktioniert auch, wenn man `^` manuell einträgt (Obsidian entfernt `^` nur bei UI-erzeugten Links). |
### 1.2 Beobachtetes Verhalten
- **Obsidian entfernt bei UI-Links das `^`:** Ein manuell gesetzter Wikilink auf eine Überschrift mit Block-ID wird zu `[[Titel#Überschrift Block]]` (mit Leerzeichen, ohne Caret).
- **Drei Schreibweisen bezeichnen dieselbe Sektion:** `Überschrift`, `Überschrift ^Block` (im Quelldokument), `Überschrift Block` (in Obsidian-Links). Für Matching müssen alle drei als dieselbe Sektion gelten.
---
## 2. Aktuelles Verhalten im Plugin
### 2.1 Section-Parser & Graph-Index
- **sectionParser:** Speichert `heading` als **vollständige Zeile** nach den `#`, also z. B. `"Überschrift ^block"` (inkl. Block-ID).
- **graphIndex `parseTarget`:**
- Bei `[[Datei#X]]`: `target.heading = X` (exakt der Teil nach `#`).
- Bei `[[#^block-id]]`: Auflösung über Sektionen → `heading = section.heading` (ebenfalls voller Text, inkl. ` ^block`).
- **Section-Nodes:** Werden aus `section.heading` gebaut → ebenfalls voller Text (z. B. `"Überschrift ^block"`).
### 2.2 Interview-Assistent (LinkTargetPicker + renderNoteEdges)
- **getHeadingsWithSectionTypes** (targetTypeResolver): Liest Überschriften per **eigenem Regex** und **entfernt** den Block-Teil: `(.+?)(?:\s+\^[\w-]+)?\s*$` → `match[2]` ist nur der Text (z. B. `"Überschrift"`).
- **LinkTargetPicker:** Setzt `linkTarget = basename + "#" + h.heading` → es wird **nur** `[[Note#Überschrift]]` erzeugt (ohne „ Block“ / ` ^block`).
- **renderNoteEdges:** Schreibt `[[${toNote}]]`; `toNote` ist bereits `"Note"` oder `"Note#Überschrift"`.
**Fazit:** Der Interview-Assistent erzeugt `[[Note#Überschrift]]`. In Obsidian springt dieser Link **in die Note, aber nicht auf die Überschrift** (siehe Abschnitt 1). Obsidian-typisches Springen auf die Überschrift (inkl. Highlight des Abschnitts) liefert nur `[[Titel#Überschrift Block]]` (UI-erzeugt, ohne `^`).
### 2.3 Inspect Chains & Chain Workbench (Stand: Jan 2026)
- **headingsMatch / normalizeHeadingForMatch** (`src/unresolvedLink/linkHelpers.ts`):
- **Mit ^Block-ID:** `"Überschrift ^Block"` → `"Überschrift"` (Block-Suffix entfernt)
- **Ohne ^:** Rückgabe unverändert (Idempotenz für bereits normalisierte Formen)
- **Matchen:** `"Überschrift ^Block"` und `"Überschrift"` gelten als dieselbe Sektion.
- **Nicht unterstützt:** `"Überschrift Block"` (Obsidian-UI, ohne ^) wird **nicht** zu `"Überschrift"` normalisiert – für zuverlässiges Matching Links mit `^` verwenden.
---
## 3. Bewertung
| Aspekt | Bewertung |
|--------|-----------|
| **Obsidian (UI)** | Beim manuellen Verlinken auf eine Überschrift mit Block-ID: Link wird zu `[[Titel#Überschrift Block]]` (ohne `^`). Klick springt auf Überschrift und highlighted den Abschnitt. |
| **Interview-Assistent** | Erzeugt `[[Note#Überschrift]]`. In Obsidian springt der Link **nicht** auf die Überschrift (nur in die Note). Besseres Spring-Verhalten hätte `[[Note#Überschrift Block]]` (Obsidian-Stil) oder `[[Note#^Block]]`. |
| **Inspect Chains / Workbench** | Exaktes Match ist zu streng: „Überschrift“, „Überschrift ^Block“, „Überschrift Block“ bezeichnen dieselbe Sektion. |
| **Risiko** | Ohne Normalisierung matchen diese drei Schreibweisen nicht; falsche Findings / fehlende Zuordnung. |
---
## 4. Empfehlung
### 4.1 Eine Baustelle zuerst (keine Überladung)
Um nicht zu viele Änderungen gleichzeitig zu öffnen:
- **Nur eine Baustelle:** **Normalisierung in Inspect Chains & Chain Workbench** (zentrale Normalisierungsfunktion + alle Heading-Vergleiche und `dangling_target_heading` auf normalisierte Form umstellen).
- **Interview-Assistent vorerst unverändert:** Weiter `[[Note#Überschrift]]` ausgeben. Eine spätere, **optionale** Anpassung (z. B. Ausgabe `[[Note#Überschrift Block]]` im Obsidian-Stil, damit der Klick auf die Überschrift springt) kann separat erfolgen.
### 4.2 Umsetzte Normalisierungsregel (Stand: Jan 2026)
**Implementiert in `normalizeHeadingForMatch` (linkHelpers.ts):**
1. **Mit ^Block-ID:** Block-Suffix entfernen: `\s*\^[a-zA-Z0-9_-]+\s*$` → z. B. `"Überschrift ^Block"` → `"Überschrift"`, `"Lars ist gut ^PersLars"` → `"Lars ist gut"`.
2. **Ohne ^:** Rückgabe unverändert (Idempotenz). Multi-Wort-Überschriften wie `"Lars ist gut"` werden nicht gekürzt.
**Matchen:** `"Überschrift ^Block"` und `"Überschrift"` gelten als dieselbe Sektion. `"Lars ist gut ^PersLars"` und `"Lars ist gut"` matchen.
**Nicht unterstützt:** `"Überschrift Block"` (Obsidian-UI, ohne ^) wird **nicht** automatisch zu `"Überschrift"` normalisiert – zur Vermeidung von Fehlmatches bei kanonischen Multi-Wort-Überschriften. **Empfehlung:** Für zuverlässiges Matching Links mit `^` verwenden: `[[Note#Überschrift ^Block]]`.
### 4.3 Umsetzte Maßnahmen
1. **Zentrale Normalisierung:** `normalizeHeadingForMatch` und `headingsMatch` in `src/unresolvedLink/linkHelpers.ts` – nur ^Block-Suffix entfernen, sonst Idempotenz.
2. **Inspect Chains & Chain Workbench:** Nutzen `headingsMatch` für alle Heading-Vergleiche.
3. **Interview-Assistent:** Unverändert – erzeugt weiterhin `[[Note#Überschrift]]`.
### 4.4 Optional später (separate Baustelle)
- **Interview-Assistent:** Wenn gewünscht, Links so erzeugen, dass Obsidian auf die Überschrift springt: z. B. `[[Note#Überschrift Block]]` (Block-Teil ohne `^`, wie Obsidian-UI) statt `[[Note#Überschrift]]`. Dann würde der Klick auf den vom Assistenten gesetzten Link dasselbe tun wie bei manuell gesetzten Links.
---
## 5. Kurzfassung (Stand: Jan 2026)
- **Plugin-Normalisierung:** `normalizeHeadingForMatch` entfernt nur `^BlockID`; bei Überschriften ohne `^` wird unverändert zurückgegeben (Idempotenz). Dadurch matchen `"Lars ist gut ^PersLars"` und `"Lars ist gut"` korrekt.
- **Empfehlung:** Für zuverlässiges Matching Links mit `^` verwenden: `[[Note#Überschrift ^Block]]`. Obsidian-Form `[[Titel#Überschrift Block]]` (ohne `^`) wird nicht automatisch normalisiert.
- **Obsidian (beobachtet):** Manueller Link → `[[Titel#Überschrift Block]]` (ohne `^`). Klick springt auf Überschrift. `[[Titel#^Block]]` highlighted nur die Überschrift.