docs: add "Voraussetzungen an die Dokumente" to the manual

New section 8: requirements for searching a collection (encoding, size,
split mode vs. structure, metadata via naming scheme, limits) and for
jump anchors (predictable HTML paths, three ways to ids, same Markdown
dialect, keeping source and HTML in sync, consistency check script),
plus a checklist. Following sections renumbered 9-12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
dschlueter 2026-10-12 20:56:43 +02:00
commit d9e495d36a

View file

@ -24,10 +24,11 @@ Version: 0.1.1 · Lizenz: MIT · Repository: https://kitux.de/forgejo/dschlueter
5. [Web-API](#5-web-api) 5. [Web-API](#5-web-api)
6. [Such-Widget](#6-such-widget) 6. [Such-Widget](#6-such-widget)
7. [Betrieb auf einem Server](#7-betrieb-auf-einem-server) 7. [Betrieb auf einem Server](#7-betrieb-auf-einem-server)
8. [Rezepte](#8-rezepte) 8. [Voraussetzungen an die Dokumente](#8-voraussetzungen-an-die-dokumente)
9. [Fehlermeldungen](#9-fehlermeldungen) 9. [Rezepte](#9-rezepte)
10. [Fehlersuche](#10-fehlersuche) 10. [Fehlermeldungen](#10-fehlermeldungen)
11. [Entwicklung & neue Versionen](#11-entwicklung--neue-versionen) 11. [Fehlersuche](#11-fehlersuche)
12. [Entwicklung & neue Versionen](#12-entwicklung--neue-versionen)
--- ---
@ -617,7 +618,109 @@ Für deutlich größere Datenmengen (Hunderte MB) ist ein Index-basiertes Werkze
--- ---
## 8. Rezepte ## 8. Voraussetzungen an die Dokumente
Welche Bedingungen eine Sammlung (z. B. Markdown-Dateien) erfüllen sollte – getrennt nach
„sinnvoll durchsuchen" und „Treffer springen direkt an die Fundstelle".
### 8.1 Für die Suche
1. **Textdateien mit bekannter Kodierung** – Standard UTF-8; sonst `encoding=`. Andere Endungen
als `.md` über `-g '*.txt'` bzw. `pattern=`.
2. **Größe passend zum Ansatz** – mdgrep arbeitet ohne Index: alle Blöcke liegen im Speicher und
werden bei jeder Suche durchlaufen. Bis etwa 50 MB Text unproblematisch (Richtwert: 15 MB →
30–150 ms pro Suche); bei Hunderten MB ist ein Index-basiertes Werkzeug besser.
3. **Gliederung, die zu einem Split-Modus passt** – die UND/ODER/NICHT-Logik gilt **pro Block**,
die Blockgröße bestimmt also die Trefferqualität:
| Aufbau der Dokumente | Split-Modus |
|---|---|
| Absätze, durch Leerzeilen getrennt | `paragraph` |
| Einträge als Listenpunkte (Berichte, Changelogs, Protokolle) | `list` |
| Abschnitte mit Überschriften (Dokumentation, Wiki) | `heading` |
| kurze Einzeldokumente | `file` |
Zu große Blöcke machen `a AND b` beliebig (in einer langen Datei steht fast alles), zu kleine
verfehlen Begriffe, die in benachbarten Sätzen stehen.
4. **Ableitbare Metadaten** – für Filter (Sprache, Kategorie), Sortierung (Datum) und Gruppierung
(gleicher Eintrag in mehreren Dateien) braucht jeder Block Werte in `meta`:
- am einfachsten über ein **einheitliches Datei- oder Pfad-Schema**
(z. B. `2026_10_12_bericht_de.md`) und `meta=lambda pfad: {…}`;
- YAML-Frontmatter wird **nicht** ausgewertet, sondern als Text durchsucht – dafür einen kleinen
Adapter schreiben, der Frontmatter liest und `Block`-Objekte erzeugt (siehe 4.3);
- zum Zusammenfassen von Duplikaten (`group_by`) einen **stabilen Schlüssel** pro Eintrag
(URL, ID).
5. **Grenzen einplanen**
- **Keine Wortstammsuche:** „Haus" findet nicht „Häuser" → `/h(au|äu)s/` oder `haus ODER häuser`.
- **Keine Relevanz-Sortierung:** die Reihenfolge bestimmt `sort_key` (z. B. Datum).
- Markdown-Zeichen (Links, Fett, Code) werden vor der Suche entfernt; **direkt eingebettetes
HTML** (`<dl>`) und Tabellen-Striche bleiben als Text stehen.
### 8.2 Für Sprungmarken
Damit ein Treffer direkt an die Fundstelle einer gerenderten Seite springt, müssen **zwei Seiten
exakt zusammenpassen**: die Blöcke von mdgrep und die IDs im HTML.
1. **Gerenderte Seiten mit vorhersagbarer URL** – aus jeder Quelldatei muss sich ihr HTML-Pfad
berechnen lassen (`docs/a/b.md` → `site/a/b.html`). Diesen Pfad mit Sprungmarke in
`meta["href"]` schreiben (das Widget verlinkt darauf, siehe 6.2).
2. **Jeder Block hat eine ID, die im HTML existiert** – drei Wege:
| Weg | Voraussetzung | Bewertung |
|---|---|---|
| **Überschriften** (`split="heading"`) | Der Renderer erzeugt Überschriften-IDs mit **demselben** Verfahren wie mdgrep (`slugify`, GitHub-Stil) | wenig Aufwand, aber prüfen: Python-Markdown (`toc`), MkDocs, Hugo und GitHub behandeln Umlaute, Sonderzeichen und doppelte Überschriften unterschiedlich |
| **Listenpunkte/Absätze** (`split="list"` / `paragraph`) | Eigenes Nachbearbeitungs-Skript nummeriert die HTML-Elemente nach **derselben Reihenfolge-Regel** wie die Blöcke und setzt `block.anchor` entsprechend | mittlerer Aufwand, robust |
| **Text Fragments** (`seite.html#:~:text=…`) | Aktueller Browser; keine Änderung am HTML. Im Widget über die Option `href(block)` bauen | kein Aufwand, aber unzuverlässig bei mehrdeutigem oder umformatiertem Text |
> **Bekannte Einschränkung:** `slugify` hängt bei **doppelten** Überschriften kein `-1`, `-2` an
> (anders als GitHub). Kommen Überschriften mehrfach vor, springen Treffer zur ersten.
3. **Gleicher Markdown-Dialekt wie der Renderer** – Renderer zerlegen Listen unterschiedlich
(siehe 4.6). Passt `dialect` nicht, verschiebt sich die Nummerierung und Links zeigen auf falsche
Absätze.
4. **Quelle und HTML auf demselben Stand** – nach jeder Änderung einer Quelldatei deren Seite neu
erzeugen; ändert sich die Zählregel, **alle** Seiten.
5. **Einmal vollständig prüfen** – für jeden Block muss die Sprungmarke im HTML existieren **und**
auf ein Element zeigen, das seinen Text enthält. Skizze:
```python
import re
from bs4 import BeautifulSoup
def pruefe(blocks, html_von): # html_von(block) → gerendertes HTML der Seite
fehler = []
for b in blocks:
el = BeautifulSoup(html_von(b), "html.parser").find(id=b.anchor)
probe = re.sub(r"\s+", " ", (b.title or b.text))[:40].lower()
if el is None or probe not in re.sub(r"\s+", " ", el.get_text()).lower():
fehler.append((b.source, b.anchor))
return fehler
```
Das deckt Formatvarianten älterer Dokumente auf, die man sonst übersieht.
### 8.3 Checkliste
| | Bedingung |
|---|---|
| ☐ | Textdateien, bekannte Kodierung, insgesamt höchstens im zweistelligen MB-Bereich |
| ☐ | Gliederung passt zu einem Split-Modus; Blöcke sind sinnvolle Einheiten |
| ☐ | Metadaten über einheitliches Datei-Namensschema (oder Adapter) |
| ☐ | stabiler Schlüssel pro Eintrag, falls Duplikate zusammengefasst werden |
| ☐ | *Sprungmarken:* HTML-Pfad aus Quellpfad berechenbar |
| ☐ | *Sprungmarken:* IDs im HTML nach derselben Regel wie die Blöcke, gleicher Dialekt |
| ☐ | *Sprungmarken:* HTML nach jeder Änderung neu erzeugt; Konsistenz einmal geprüft |
---
## 9. Rezepte
**Notizen nach zwei Begriffen im selben Absatz durchsuchen** **Notizen nach zwei Begriffen im selben Absatz durchsuchen**
@ -665,7 +768,7 @@ HTML-Seiten (`dialect="python-markdown"`).
--- ---
## 9. Fehlermeldungen ## 10. Fehlermeldungen
Ungültige Anfragen liefern einen festen Code (für eigene Übersetzungen), eine Meldung und die Ungültige Anfragen liefern einen festen Code (für eigene Übersetzungen), eine Meldung und die
Position (0-basiert; das Widget zeigt sie 1-basiert an). Position (0-basiert; das Widget zeigt sie 1-basiert an).
@ -695,7 +798,7 @@ mdgrep: Missing closing parenthesis
--- ---
## 10. Fehlersuche ## 11. Fehlersuche
| Problem | Ursache / Lösung | | Problem | Ursache / Lösung |
|---|---| |---|---|
@ -713,7 +816,7 @@ mdgrep: Missing closing parenthesis
--- ---
## 11. Entwicklung & neue Versionen ## 12. Entwicklung & neue Versionen
```bash ```bash
git clone https://kitux.de/forgejo/dschlueter/mdgrep.git && cd mdgrep git clone https://kitux.de/forgejo/dschlueter/mdgrep.git && cd mdgrep