change: Textfeld bricht Zeilen nicht mehr um, waagerechter Balken (D49)

Gewünscht — und damit die ausdrückliche Umkehrung der D33-Abwägung
(„Verworfen: wrap=off … der Umbruch ist die wichtigere Eigenschaft"). Der dort
notierte Preis bleibt richtig; nicht bedacht war die andere Seite: Ein weicher
Umbruch zerstört die Einrückung, und die trägt in dieser Notation die
Hierarchie. Die Fortsetzung einer umbrochenen Zeile beginnt am linken Rand und
sieht aus wie ein Wurzelknoten — betroffen sind genau die langen Zeilen, also
die mit ID, Größe und Kommentar, seit D48 praktisch jede Zeile des Plans.

Umgesetzt als `wrap="off"` am Element (Eigenschaft des Feldes, nicht seiner
Gestaltung), `overflow:auto` daneben im Stylesheet.

Der Spiegel musste mit: `syncMirror()` maß mit `white-space:pre-wrap` und
fester Breite — genau die Kombination, die im Spiegel Zeilen umbräche, die im
Textfeld ungebrochen stehen; alles darunter läge zu tief und die
Zeilennummern wanderten weg. Jetzt `pre` und ohne Breitenvorgabe. Gemessen
wird trotzdem weiter statt `Zeilenhöhe × n` zu rechnen: Die Schriftgröße
unterscheidet sich zwischen Telefon und Schreibtisch, die Messung stimmt in
beiden Fällen von selbst.

Der Sprung setzt `scrollLeft` zurück. `jumpToLine()` markiert die ganze Zeile,
woraufhin der Browser von sich aus an deren Ende scrollt — man landete am
rechten Rand, ohne Einrückung, Zeichen und Statusbox zu sehen. Der Sprung
zeigt auf eine Zeile, nicht auf ihr Ende.

Nachgemessen am Plan (903 Zeilen, längste 122 Zeichen): 903 Bildzeilen zu 903
logischen Zeilen in beiden Ansichten; Schiebeweg 211 px am Schreibtisch, 432 px
auf 375 px Breite; der Zeilennummern-Streifen bleibt beim waagerechten
Verschieben stehen (linke Kante unverändert bei 180 px Versatz); Abweichung
der Zahlen am Dateiende 2 px auf 903 Zeilen (Rundung von `offsetTop`, sammelt
sich nicht auf). 236 Tests grün.

SPEC §9 (Zeilennummern) und D49 halten es fest; die D33-Stelle bekommt einen
Verweis, dass die Abwägung umgekehrt wurde — gelöscht wird dort nichts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-23 14:20:25 +02:00
co-authored by Claude Fable 5
parent 623b68799f
commit 1b8bf06973
5 changed files with 114 additions and 22 deletions
+67
View File
@@ -1829,6 +1829,10 @@ waagerechtes Scrollen — im schmalen Spiegel neben einem eingebetteten Pad (D31
oder auf dem Telefon (D17) wäre der Text damit unlesbar. Der Umbruch ist die
wichtigere Eigenschaft.
*(Diese Abwägung ist später umgekehrt worden: **D49** schaltet den Umbruch ab.
Übersehen war, was ein weicher Umbruch mit der **Einrückung** macht — und die
trägt hier die Hierarchie.)*
**Kein Umschalter.** Die Kopfzeile ist eng (D17), und ein Bedienelement kostet
i18n in neun Sprachen für etwas, das keinen Zustand hat, den jemand pflegen
will. Der Streifen ist so schmal wie die Ziffern es verlangen
@@ -3117,3 +3121,66 @@ Beschreibung, **0 Warnungen**, Pfad weiterhin exakt gerechnet mit 24
Stationen. Der Cursor in einem Beschreibungsblock wählt den beschriebenen
Knoten aus (D40-Nachtrag 2) — auf Kopf- wie Textzeile geprüft; der
`---`-Trenner selbst wählt nichts.
## D49 — Das Textfeld bricht nicht mehr um: `wrap="off"` plus waagerechter Balken
Gewünscht vom Nutzer, und damit die ausdrückliche Umkehrung der D33-Abwägung
(„Verworfen: `wrap=off` … der Umbruch ist die wichtigere Eigenschaft"). Der
dort notierte Preis bleibt richtig und wird in Kauf genommen; was dort **nicht**
bedacht war, ist die andere Seite:
**Ein weicher Umbruch zerstört die Einrückung — und die trägt hier die
Hierarchie.** In dieser Notation ist der linke Rand keine Formsache, sondern
die Ebene (§2). Bricht eine Zeile um, beginnt ihre Fortsetzung am linken Rand
und sieht damit aus wie ein Wurzelknoten; wer die Struktur überfliegt, liest
eine Ebene, die es nicht gibt. Das trifft genau die langen Zeilen, also die mit
ID, Größe und Kommentar — und seit D48 ist das praktisch jede Zeile des
mitgelieferten Plans. Waagerechtes Scrollen kostet Bequemlichkeit; der Umbruch
kostete Lesbarkeit der Struktur.
**Umgesetzt am Element, nicht in CSS:** `wrap="off"` am `<textarea>`. Es ist
die Eigenschaft des Feldes, nicht seiner Gestaltung, und es wirkt zuverlässig
in allen Engines; `overflow:auto` steht daneben im Stylesheet.
**Der Spiegel musste mit.** `syncMirror()` (D25/D33) maß mit `white-space:
pre-wrap` und **fester Breite** — genau die Kombination, die im Spiegel Zeilen
umbräche, die im Textfeld ungebrochen stehen. Jede Zeile darunter läge dann zu
tief, und die Zeilennummern wanderten weg. Der Spiegel ist deshalb jetzt `pre`
und ohne Breitenvorgabe.
**Gemessen wird trotzdem weiter.** Ohne Umbruch wäre `Zeilenhöhe × n` richtig
und der Spiegel überflüssig — so hat D33 den Fall beschrieben. Behalten wurde
die Messung dennoch: Die Schriftgröße unterscheidet sich zwischen Telefon und
Schreibtisch (D17-Nachtrag 2), und die Messung stimmt in beiden Fällen von
selbst, ohne eine zweite Stelle, die dieselbe Zahl kennen muss.
**Der Sprung setzt die waagerechte Verschiebung zurück.** `jumpToLine()`
markiert die **ganze** Zeile (D25) — der Browser scrollt dann von sich aus an
deren **Ende**, und man landete am rechten Rand, ohne Einrückung, Zeichen und
Statusbox zu sehen. Also `scrollLeft = 0` nach dem Markieren: Der Sprung zeigt
auf eine Zeile, nicht auf ihr Ende.
**Der Zeilennummern-Streifen bleibt stehen.** Er verschiebt sich weiterhin nur
gegen `src.scrollTop`; den waagerechten Balken macht er nicht mit. Das war
schon so gebaut und ist jetzt das gewünschte Verhalten statt eines
Nebenprodukts — nachgemessen: linke Kante unverändert, während der Text um
180 px verschoben ist.
**Nachgemessen** am mitgelieferten Plan (903 Zeilen, längste 122 Zeichen):
| | Schreibtisch | Telefon (375 px) |
|---|---|---|
| Bildzeilen zu logischen Zeilen | 903 : 903 | 903 : 903 |
| waagerechter Schiebeweg | 211 px | 432 px |
| sichtbare Zeichen | rund 110 | rund 53 |
| Abweichung der Zahlen am Dateiende | — | 2 px auf 903 Zeilen |
Die zwei Pixel stammen daher, dass `offsetTop` ganzzahlig rundet, die
Zeilenhöhe aber 17,408 px beträgt; sie sammeln sich nicht auf (jede Zahl wird
absolut gemessen, nicht fortgeschrieben).
**Der D33-Einwand bleibt bestehen, nur nicht mehr entscheidend:** Im schmalen
Spiegel neben einem eingebetteten Pad (D31) und auf dem Telefon sieht man jetzt
rund 53 Zeichen und muss schieben. Wer dort viel liest, zieht den Splitter auf
oder wechselt in die Textansicht. Ein Umschalter dafür wurde nicht gebaut — aus
demselben Grund wie in D33: ein Bedienelement plus neun Übersetzungen für einen
Zustand, den kaum jemand umstellen will.
+9 -3
View File
@@ -677,14 +677,20 @@ Links neben dem Textfeld steht ein schmaler Streifen mit den **Zeilennummern**
dieselben, die die Warnungen nennen („Zeile 12: …", §4). Ohne ihn muss man sie
im Text abzählen.
- Gezählt werden **logische** Zeilen des Notationstexts. Eine weich umbrochene
Zeile behält **eine** Nummer; die Nummer steht an ihrer ersten Bildzeile.
- **Das Textfeld bricht Zeilen nicht um** (D49). Die Einrückung trägt die
Hierarchie (§2), und ein weicher Umbruch setzt die Fortsetzung an den linken
Rand — die Ebene wäre damit gerade dort nicht mehr abzulesen, wo eine Zeile
lang ist. Zu lange Zeilen bekommen einen **waagerechten Balken**; eine
logische Zeile ist damit immer genau eine Bildzeile.
- Der Streifen scrollt **nur senkrecht** mit: Die Zahlen bleiben stehen, wenn
der Text waagerecht verschoben wird. Ein Sprung auf eine Zeile (§9) setzt die
waagerechte Verschiebung zurück — er zeigt auf eine Zeile, nicht auf ihr Ende.
- Die **Cursor-Zeile** und Zeilen mit einer **Warnung** heben sich ab (Warnung in
`--warn`, `#B45309`) — genau die beiden Fälle, für die man hinsieht.
- Reine Lesehilfe: kein Bestandteil des Notationstexts, nicht im Grafikexport
und nicht im Druck (dort ist ohnehin nur das Diagramm zu sehen).
Siehe D33.
Siehe D33, D49.
### Fokusmarke im Diagramm (`!!!`, §1)
Ein mit `!!!` markierter Knoten trägt einen **Strahlenkranz in Petrol**