notation: Faltmarke rückt hinter die Statusbox (D34-Nachtrag 2)
`- > [x] Backend` wird zu `- [x] > Backend`. Die alte Stellung verschob die Statusbox um genau eine Einrückungsstufe — die Box einer gefalteten Zeile stand damit in der Spalte der Boxen ihrer eigenen Kinder. Vor dem Label kostet die Verschiebung nichts, weil Labels ohnehin ausgefranst sind. Nebengewinn: Die Regel wird einfacher. Statt „zwischen Zeichen und Statusbox, bei Wurzelknoten am Zeilenanfang" heißt sie jetzt ausnahmslos „unmittelbar vor dem Label"; für Zeilen ohne Statusbox ändert sich nichts. Die alte Stellung wird weiter gelesen (Pads und ?sourceUrl=-Quellen lassen sich nicht migrieren), aber nie mehr geschrieben — setFoldMark() löst sie in die neue auf. SPEC §1 hält zusätzlich fest, dass `<` gelesen, aber nie erzeugt wird. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
321bdc9dfa
commit
be729239ce
+6
-1
@@ -296,7 +296,12 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
|
||||
`freshPrevRoots` (Basis, einmal geparst). Basis je Dokument in `werkbaum-seen`,
|
||||
fortgeschrieben **erst beim Bestätigen** über `#freshBtn`.
|
||||
- Faltmarken `>`/`<` (SPEC §1/§9, D38): Parser setzt nur `fold` ('>'|'<'|null,
|
||||
Leerraum-Regel); den wirksamen Anfangszustand rechnet `initialCollapsed()`
|
||||
Leerraum-Regel). **Stellung ist unmittelbar vor dem Label**, also hinter der
|
||||
Statusbox (`- [x] > …`, D34-Nachtrag 2); die alte Stellung **davor**
|
||||
(`- > [x] …`) wird weiter gelesen — daher zwei Marken-Gruppen im Zeilen-Regex,
|
||||
die erste gewinnt —, aber `setFoldMark()` schreibt immer die neue und löst
|
||||
eine alte dabei auf. Wer die Gruppen anfasst: Der Rest der Zeile ist `m[6]`,
|
||||
nicht `m[5]`. Den wirksamen Anfangszustand rechnet `initialCollapsed()`
|
||||
in model.js — `<` (und die Fokusmarke) wandert die Faltung die Pfad-Ebenen
|
||||
**hinunter** statt Vorfahren bloß zu öffnen. `render()` überlagert ihn mit
|
||||
`foldOverrides` (Schlüssel = Label-Pfad via `nodeKeys()`, Sitzung, beim
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@
|
||||
Abhängigkeiten mit <code>:#name,#name</code> — erscheinen im Tooltip.
|
||||
Die Knotenfarbe zeigt den effektiven Status (mit Abhängigkeiten); ist der eigene weiter, steht er als Marke unten links.
|
||||
Beschreibungen: <code>"</code> Zeile unter dem Knoten; Langtext hinter <code>---</code> als eingerückter <code>#id</code>-Block — beides im Tooltip (”).
|
||||
Falten: <code>- > [x] …</code> startet eingeklappt, <code><</code> holt hervor; ▾/▸ am Knoten klappt um (Tastatur: ←/→).
|
||||
Falten: <code>- [x] > …</code> startet eingeklappt, <code><</code> holt hervor; ▾/▸ am Knoten klappt um (Tastatur: ←/→).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+10
-5
@@ -14,7 +14,7 @@ https://werkbaum.javagil.de renders the notation as a diagram;
|
||||
|
||||
## Line format
|
||||
|
||||
[indent][gate] [fold] [status] Label (SIZE) URL @person #id :#id,#id !!! %% comment
|
||||
[indent][gate] [status] [fold] Label (SIZE) URL @person #id :#id,#id !!! %% comment
|
||||
|
||||
One node per line. Everything except the label is optional.
|
||||
|
||||
@@ -46,12 +46,17 @@ One node per line. Everything except the label is optional.
|
||||
- Optionality (`+`) is orthogonal to status: an optional node can be long
|
||||
`[^]`. Optional nodes never count toward the cheapest path.
|
||||
|
||||
### Fold mark (between gate and status box; on root lines at line start)
|
||||
### Fold mark (immediately before the label, i.e. after the status box)
|
||||
|
||||
- `>` — this subtree starts **collapsed** when the document opens.
|
||||
- `<` — inside a collapsed region, bring this subtree back into view.
|
||||
- Recognized only with following whitespace (`- >Careful` stays a label).
|
||||
Presentation only: no effect on meaning, costs or warnings.
|
||||
- Recognized only with following whitespace (`- [x] >Careful` stays a label).
|
||||
- **Write it after the status box** (`- [x] > Concept`). The older position
|
||||
between gate and box (`- > [x] Concept`) is still read, but never written:
|
||||
it shifts the box by one indent step, so a folded parent's box lines up with
|
||||
its children's boxes.
|
||||
- Describes the document's fold state: opening restores it, and folding in the
|
||||
diagram writes the mark back. No effect on meaning, costs or warnings.
|
||||
|
||||
### Status box
|
||||
|
||||
@@ -163,7 +168,7 @@ One node per line. Everything except the label is optional.
|
||||
%% Project structure – Sprint 14
|
||||
[~] Website relaunch (XL) https://wiki.example.com/relaunch
|
||||
" Folded chapters are done.
|
||||
- > [x] Concept (M)
|
||||
- [x] > Concept (M)
|
||||
- [x] Audience analysis (S)
|
||||
- [x] Sitemap (XS)
|
||||
- [~] Implementation (XL)
|
||||
|
||||
+10
-10
@@ -13,7 +13,7 @@ import WERKBAUM_DOC from '../../docs/examples/werkbaum.werkbaum?raw';
|
||||
const INITIAL = `%% Project structure – Sprint 14
|
||||
[~] Website relaunch (XL) https://wiki.example.com/relaunch
|
||||
" Folded chapters are done — click the ▸ to peek inside.
|
||||
- > [x] Concept (M)
|
||||
- [x] > Concept (M)
|
||||
- [x] Audience analysis (S)
|
||||
- [x] Sitemap (XS)
|
||||
- [~] Implementation (XL)
|
||||
@@ -1511,7 +1511,7 @@ const I18N = {
|
||||
hint_deps:"Abhängigkeiten mit :#name,#name — erscheinen im Tooltip.",
|
||||
hint_eff:"Die Knotenfarbe zeigt den effektiven Status (mit Abhängigkeiten); ist der eigene weiter, steht er als Marke unten links.",
|
||||
hint_desc:"Beschreibungen: \" Zeile unter dem Knoten; Langtext hinter --- als eingerückter #id-Block — beides im Tooltip (”).",
|
||||
hint_fold:"Falten: - > [x] … startet eingeklappt, < holt hervor; ▾/▸ am Knoten klappt um (Tastatur: ←/→).",
|
||||
hint_fold:"Falten: - [x] > … startet eingeklappt, < holt hervor; ▾/▸ am Knoten klappt um (Tastatur: ←/→).",
|
||||
hint_jump:"Alt+Klick auf einen Knoten (mobil: langer Druck) springt zur zugehörigen Textzeile; Alt+Klick im Text holt den Knoten ins Bild."
|
||||
},
|
||||
en: {
|
||||
@@ -1591,7 +1591,7 @@ const I18N = {
|
||||
hint_deps:"Dependencies with :#name,#name — shown in the tooltip.",
|
||||
hint_eff:"Node colour shows the effective status (with dependencies); if its own is further along, it appears as a mark at the bottom left.",
|
||||
hint_desc:"Descriptions: a \" line below the node; long text behind --- as an indented #id block — both in the tooltip (”).",
|
||||
hint_fold:"Folding: - > [x] … starts collapsed, < brings it back; ▾/▸ on a node toggles (keyboard: ←/→).",
|
||||
hint_fold:"Folding: - [x] > … starts collapsed, < brings it back; ▾/▸ on a node toggles (keyboard: ←/→).",
|
||||
hint_jump:"Alt+click a node (long press on touch) jumps to its line in the text; Alt+click in the text brings the node into view."
|
||||
},
|
||||
es: {
|
||||
@@ -1671,7 +1671,7 @@ const I18N = {
|
||||
hint_deps:"Dependencias con :#nombre,#nombre — visibles en el tooltip.",
|
||||
hint_eff:"El color del nodo muestra el estado efectivo (con dependencias); si el propio va más adelante, aparece como marca abajo a la izquierda.",
|
||||
hint_desc:"Descripciones: línea \" bajo el nodo; texto largo tras --- como bloque #id sangrado — ambos en el tooltip (”).",
|
||||
hint_fold:"Plegado: - > [x] … empieza plegado, < lo recupera; ▾/▸ en el nodo alterna (teclado: ←/→).",
|
||||
hint_fold:"Plegado: - [x] > … empieza plegado, < lo recupera; ▾/▸ en el nodo alterna (teclado: ←/→).",
|
||||
hint_jump:"Alt+clic en un nodo (pulsación larga en táctil) salta a su línea en el texto; Alt+clic en el texto trae el nodo a la vista."
|
||||
},
|
||||
fr: {
|
||||
@@ -1751,7 +1751,7 @@ const I18N = {
|
||||
hint_deps:"Dépendances avec :#nom,#nom — visibles dans l’infobulle.",
|
||||
hint_eff:"La couleur du nœud montre le statut effectif (avec dépendances) ; si le sien est plus avancé, il apparaît en marque en bas à gauche.",
|
||||
hint_desc:"Descriptions : ligne \" sous le nœud ; texte long après --- en bloc #id indenté — les deux dans l’infobulle (”).",
|
||||
hint_fold:"Pliage : - > [x] … démarre replié, < le fait ressortir ; ▾/▸ sur le nœud bascule (clavier : ←/→).",
|
||||
hint_fold:"Pliage : - [x] > … démarre replié, < le fait ressortir ; ▾/▸ sur le nœud bascule (clavier : ←/→).",
|
||||
hint_jump:"Alt+clic sur un nœud (appui long sur tactile) saute à sa ligne dans le texte ; Alt+clic dans le texte amène le nœud à l’écran."
|
||||
},
|
||||
pl: {
|
||||
@@ -1831,7 +1831,7 @@ const I18N = {
|
||||
hint_deps:"Zależności przez :#nazwa,#nazwa — widoczne w podpowiedzi.",
|
||||
hint_eff:"Kolor węzła pokazuje status efektywny (z zależnościami); jeśli własny jest dalej, widnieje jako znacznik u dołu po lewej.",
|
||||
hint_desc:"Opisy: wiersz \" pod węzłem; dłuższy tekst za --- jako wcięty blok #id — oba w podpowiedzi (”).",
|
||||
hint_fold:"Zwijanie: - > [x] … zaczyna zwinięte, < przywraca; ▾/▸ na węźle przełącza (klawiatura: ←/→).",
|
||||
hint_fold:"Zwijanie: - [x] > … zaczyna zwinięte, < przywraca; ▾/▸ na węźle przełącza (klawiatura: ←/→).",
|
||||
hint_jump:"Alt+kliknięcie węzła (długie naciśnięcie na dotyku) przechodzi do jego wiersza w tekście; Alt+kliknięcie w tekście pokazuje węzeł na diagramie."
|
||||
},
|
||||
ru: {
|
||||
@@ -1911,7 +1911,7 @@ const I18N = {
|
||||
hint_deps:"Зависимости через :#имя,#имя — видны в подсказке.",
|
||||
hint_eff:"Цвет узла показывает фактический статус (с учётом зависимостей); если собственный дальше, он показан меткой слева внизу.",
|
||||
hint_desc:"Описания: строка \" под узлом; длинный текст после --- как блок #id с отступом — оба в подсказке (”).",
|
||||
hint_fold:"Сворачивание: - > [x] … открывается свёрнутым, < возвращает; ▾/▸ на узле переключает (клавиши: ←/→).",
|
||||
hint_fold:"Сворачивание: - [x] > … открывается свёрнутым, < возвращает; ▾/▸ на узле переключает (клавиши: ←/→).",
|
||||
hint_jump:"Alt+клик по узлу (долгое нажатие на сенсоре) переходит к его строке в тексте; Alt+клик в тексте показывает узел на диаграмме."
|
||||
},
|
||||
hi: {
|
||||
@@ -1991,7 +1991,7 @@ const I18N = {
|
||||
hint_deps:":#नाम,#नाम से निर्भरताएँ — टूलटिप में दिखती हैं।",
|
||||
hint_eff:"नोड का रंग प्रभावी स्थिति दिखाता है (निर्भरताओं सहित); यदि अपनी स्थिति आगे है, तो वह नीचे-बाएँ चिह्न के रूप में दिखती है।",
|
||||
hint_desc:"विवरण: नोड के नीचे \" पंक्ति; --- के बाद #id ब्लॉक में लंबा पाठ — दोनों टूलटिप में (”)।",
|
||||
hint_fold:"फ़ोल्डिंग: - > [x] … समेटा हुआ खुलता है, < वापस लाता है; नोड पर ▾/▸ टॉगल करता है (कीबोर्ड: ←/→)।",
|
||||
hint_fold:"फ़ोल्डिंग: - [x] > … समेटा हुआ खुलता है, < वापस लाता है; नोड पर ▾/▸ टॉगल करता है (कीबोर्ड: ←/→)।",
|
||||
hint_jump:"किसी नोड पर Alt+क्लिक (टच पर लंबा दबाव) टेक्स्ट में उसकी पंक्ति पर ले जाता है; टेक्स्ट में Alt+क्लिक उस नोड को आरेख में दिखाता है।"
|
||||
},
|
||||
zh: {
|
||||
@@ -2071,7 +2071,7 @@ const I18N = {
|
||||
hint_deps:"用 :#名称,#名称 表示依赖——显示在提示中。",
|
||||
hint_eff:"节点颜色显示实际状态(含依赖);若自身状态更靠前,会以左下角标记显示。",
|
||||
hint_desc:"描述:节点下方的 \" 行;--- 之后的缩进 #id 块为长文本——均显示在提示中(”)。",
|
||||
hint_fold:"折叠:- > [x] … 打开时即折叠,< 将其展开;节点上的 ▾/▸ 切换(键盘:←/→)。",
|
||||
hint_fold:"折叠:- [x] > … 打开时即折叠,< 将其展开;节点上的 ▾/▸ 切换(键盘:←/→)。",
|
||||
hint_jump:"Alt+点击节点(触摸屏为长按)可跳转到文本中对应的行;在文本中 Alt+点击则把该节点带入视野。"
|
||||
},
|
||||
ja: {
|
||||
@@ -2151,7 +2151,7 @@ const I18N = {
|
||||
hint_deps:":#名前,#名前 で依存関係 — ツールチップに表示されます。",
|
||||
hint_eff:"ノードの色は実効ステータス(依存関係込み)を示します。自身が先行している場合は左下のマークで表示されます。",
|
||||
hint_desc:"説明:ノード直下の \" 行。--- 以降は #id ブロック(字下げ)で長文 — どちらもツールチップに表示(”)。",
|
||||
hint_fold:"折りたたみ:- > [x] … は折りたたんだ状態で開き、< は呼び戻します。ノードの ▾/▸ で切替(キー:←/→)。",
|
||||
hint_fold:"折りたたみ:- [x] > … は折りたたんだ状態で開き、< は呼び戻します。ノードの ▾/▸ で切替(キー:←/→)。",
|
||||
hint_jump:"ノードを Alt+クリック(タッチでは長押し)すると、テキストの該当行へ移動します。テキスト内で Alt+クリックすると、そのノードが図の中央に表示されます。"
|
||||
}
|
||||
};
|
||||
|
||||
+15
-9
@@ -27,9 +27,13 @@ export const STATUS_BY_CODE = {
|
||||
ungewöhnlicher Spaltung wie `- [x] X`. Wurzelzeilen (ohne Zeichen) bekommen
|
||||
die Marke am Zeilenanfang, wie SPEC §1 es verlangt. */
|
||||
export function setFoldMark(line, mark){
|
||||
const m = line.match(/^([ \t]*(?:[-|+]|=(?=[ \t]))?[ \t]*)((?:[><](?=[ \t])[ \t]*)?)/);
|
||||
const head = m[1], alt = m[2];
|
||||
return head + (mark ? mark + ' ' : '') + line.slice(head.length + alt.length);
|
||||
/* Geschrieben wird IMMER die kanonische Stellung: unmittelbar vor dem Label,
|
||||
also hinter der Statusbox (SPEC §1, D34-Nachtrag 2). Eine Marke in der
|
||||
alten Stellung (zwischen Zeichen und Box) wird dabei aufgelöst — sie wird
|
||||
weiterhin gelesen, aber nicht mehr erzeugt. */
|
||||
const m = line.match(
|
||||
/^([ \t]*(?:[-|+]|=(?=[ \t]))?[ \t]*)(?:[><](?=[ \t])[ \t]*)?((?:\[[^\]]\][ \t]*)?)(?:[><](?=[ \t])[ \t]*)?/);
|
||||
return m[1] + m[2] + (mark ? mark + ' ' : '') + line.slice(m[0].length);
|
||||
}
|
||||
|
||||
/* Status, die als „realisiert" zählen (XOR-Regel, SPEC §3/D35): Kosten sind
|
||||
@@ -142,17 +146,19 @@ export function parse(text){
|
||||
(fehlertolerant: die Zeile geht nicht verloren). */
|
||||
/* `=` (XOR, SPEC §3) nur mit folgendem Leerraum — die Leerraum-Regel hält
|
||||
Labels wie `=SUMME(A1:B2)` heraus; `-`/`+`/`|` bleiben wie bisher.
|
||||
Die Faltmarke `>`/`<` (SPEC §1, D38) steht zwischen Zeichen und
|
||||
Statusbox (bei Wurzeln am Zeilenanfang), ebenfalls nur mit folgendem
|
||||
Leerraum — `- >Achtung` bleibt ein Label. */
|
||||
const m = raw.match(/^([ \t]*)([-|+]|=(?=[ \t]))?\s*(?:([><])(?=[ \t])\s*)?(?:\[([^\]])\]\s*)?(.*)$/);
|
||||
Die Faltmarke `>`/`<` (SPEC §1, D38) steht unmittelbar vor dem Label,
|
||||
also hinter der Statusbox — ebenfalls nur mit folgendem Leerraum,
|
||||
`- [x] >Achtung` bleibt ein Label. Die frühere Stellung ZWISCHEN Zeichen
|
||||
und Box wird weiter gelesen (D34-Nachtrag 2), aber nicht mehr
|
||||
geschrieben; deshalb zwei Marken-Gruppen, die erste gewinnt. */
|
||||
const m = raw.match(/^([ \t]*)([-|+]|=(?=[ \t]))?\s*(?:([><])(?=[ \t])\s*)?(?:\[([^\]])\]\s*)?(?:([><])(?=[ \t])\s*)?(.*)$/);
|
||||
const width = m[1].replace(/\t/g,' ').length;
|
||||
const type = m[2] === '|' ? 'or' : m[2] === '=' ? 'xor' : 'and';
|
||||
const optional = m[2] === '+';
|
||||
const fold = m[3] || null;
|
||||
const fold = m[3] || m[5] || null;
|
||||
const boxChar = m[4]; // undefined, wenn keine Statusbox
|
||||
|
||||
let rest = m[5], url = null, size = null;
|
||||
let rest = m[6], url = null, size = null;
|
||||
const tags = [];
|
||||
rest = rest.replace(/https?:\/\/\S+/i, s => { url = s; return ''; });
|
||||
rest = rest.replace(/\((XXL|XS|XL|S|M|L)\)/i, (s, g) => { size = g.toUpperCase(); return ''; });
|
||||
|
||||
+48
-21
@@ -18,23 +18,31 @@ const collapsedLabels = (txt, rescueFocus = true) =>
|
||||
[...initialCollapsed(roots(txt), rescueFocus)].map(n => n.label).sort();
|
||||
|
||||
/* Faltmarken `>`/`<` (SPEC §1/§9, D38): Anfangszustand der Faltung im Text. */
|
||||
describe('Parser — Faltmarke zwischen Zeichen und Statusbox', () => {
|
||||
it('erkennt `>` und `<` und nimmt sie aus dem Label', () => {
|
||||
const [wurzel] = roots(`[ ] Wurzel\n - > [x] Zu (M)\n - < [ ] Auf`);
|
||||
describe('Parser — Faltmarke unmittelbar vor dem Label', () => {
|
||||
it('erkennt `>` und `<` hinter der Statusbox und nimmt sie aus dem Label', () => {
|
||||
const [wurzel] = roots(`[ ] Wurzel\n - [x] > Zu (M)\n - [ ] < Auf`);
|
||||
expect(wurzel.children.map(k => [k.label, k.fold, k.status?.key]))
|
||||
.toEqual([['Zu', '>', 'fertig'], ['Auf', '<', 'geplant']]);
|
||||
expect(wurzel.fold).toBe(null);
|
||||
});
|
||||
|
||||
it('erkennt die Marke am Wurzelknoten (ohne Zeichen) am Zeilenanfang', () => {
|
||||
const [wurzel] = roots(`> [~] Kapitel\n - [ ] Kind`);
|
||||
expect([wurzel.fold, wurzel.label]).toEqual(['>', 'Kapitel']);
|
||||
it('liest die alte Stellung (vor der Box) weiter — D34-Nachtrag 2', () => {
|
||||
const [wurzel] = roots(`[ ] Wurzel\n - > [x] Zu (M)\n - < [ ] Auf`);
|
||||
expect(wurzel.children.map(k => [k.label, k.fold, k.status?.key]))
|
||||
.toEqual([['Zu', '>', 'fertig'], ['Auf', '<', 'geplant']]);
|
||||
});
|
||||
|
||||
it('verlangt folgenden Leerraum — `- >Achtung` bleibt ein Label', () => {
|
||||
const [wurzel] = roots(`[ ] Wurzel\n - >Achtung`);
|
||||
it('erkennt die Marke ohne Statusbox direkt hinter dem Zeichen', () => {
|
||||
const [wurzel] = roots(`> [~] Kapitel\n - > Kind ohne Box`);
|
||||
expect([wurzel.fold, wurzel.label]).toEqual(['>', 'Kapitel']);
|
||||
expect(wurzel.children.map(k => [k.label, k.fold]))
|
||||
.toEqual([['>Achtung', null]]);
|
||||
.toEqual([['Kind ohne Box', '>']]);
|
||||
});
|
||||
|
||||
it('verlangt folgenden Leerraum — `[x] >Achtung` bleibt ein Label', () => {
|
||||
const [wurzel] = roots(`[ ] Wurzel\n - >Achtung\n - [x] >Achtung`);
|
||||
expect(wurzel.children.map(k => [k.label, k.fold]))
|
||||
.toEqual([['>Achtung', null], ['>Achtung', null]]);
|
||||
});
|
||||
|
||||
it('lässt ein `>` mitten im Label unberührt', () => {
|
||||
@@ -46,32 +54,51 @@ describe('Parser — Faltmarke zwischen Zeichen und Statusbox', () => {
|
||||
/* Umkehrung der Marken-Extraktion fürs Zurückschreiben aus dem Diagramm
|
||||
(SPEC §1, D38-Nachtrag 2): Angefasst wird nur die Marke samt Leerraum. */
|
||||
describe('setFoldMark — Faltmarke setzen und entfernen', () => {
|
||||
it('setzt `>` hinter das Zerlegungszeichen', () => {
|
||||
expect(setFoldMark(' - [x] Concept (M)', '>')).toBe(' - > [x] Concept (M)');
|
||||
it('setzt `>` hinter die Statusbox, unmittelbar vor das Label', () => {
|
||||
expect(setFoldMark(' - [x] Concept (M)', '>')).toBe(' - [x] > Concept (M)');
|
||||
});
|
||||
|
||||
it('entfernt eine vorhandene Marke', () => {
|
||||
expect(setFoldMark(' - > [x] Concept (M)', null)).toBe(' - [x] Concept (M)');
|
||||
expect(setFoldMark(' - [x] > Concept (M)', null)).toBe(' - [x] Concept (M)');
|
||||
});
|
||||
|
||||
it('ersetzt `<` durch `>`', () => {
|
||||
expect(setFoldMark(' - < [ ] B1', '>')).toBe(' - > [ ] B1');
|
||||
expect(setFoldMark(' - [ ] < B1', '>')).toBe(' - [ ] > B1');
|
||||
});
|
||||
|
||||
it('setzt die Marke bei Wurzelzeilen an den Zeilenanfang', () => {
|
||||
expect(setFoldMark('[~] Wurzel', '>')).toBe('> [~] Wurzel');
|
||||
expect(setFoldMark('> [~] Wurzel', null)).toBe('[~] Wurzel');
|
||||
it('löst die alte Stellung (vor der Box) in die neue auf', () => {
|
||||
/* Gelesen wird sie weiter (D34-Nachtrag 2), geschrieben nie. */
|
||||
expect(setFoldMark(' - > [x] Concept (M)', '>')).toBe(' - [x] > Concept (M)');
|
||||
expect(setFoldMark(' - < [x] Concept (M)', '>')).toBe(' - [x] > Concept (M)');
|
||||
expect(setFoldMark(' - > [x] Concept (M)', null)).toBe(' - [x] Concept (M)');
|
||||
});
|
||||
|
||||
it('setzt die Marke ohne Statusbox direkt hinter das Zeichen', () => {
|
||||
expect(setFoldMark(' - Konzeption', '>')).toBe(' - > Konzeption');
|
||||
expect(setFoldMark('[~] Wurzel', '>')).toBe('[~] > Wurzel');
|
||||
expect(setFoldMark('[~] > Wurzel', null)).toBe('[~] Wurzel');
|
||||
expect(setFoldMark('Wurzel ohne Box', '>')).toBe('> Wurzel ohne Box');
|
||||
});
|
||||
|
||||
it('lässt ungewöhnliche Spaltung stehen', () => {
|
||||
expect(setFoldMark(' - [x] X', '>')).toBe(' - > [x] X');
|
||||
expect(setFoldMark('\t= [ ] Cloud', '>')).toBe('\t= > [ ] Cloud');
|
||||
expect(setFoldMark(' - [x] X', '>')).toBe(' - [x] > X');
|
||||
expect(setFoldMark('\t= [ ] Cloud', '>')).toBe('\t= [ ] > Cloud');
|
||||
});
|
||||
|
||||
it('fasst ein `>` im Label nicht an (Leerraum-Regel)', () => {
|
||||
/* `- >Achtung` ist ein Label, keine Marke — die neue Marke kommt davor. */
|
||||
expect(setFoldMark(' - >Achtung', '>')).toBe(' - > >Achtung');
|
||||
expect(setFoldMark(' - >Achtung', null)).toBe(' - >Achtung');
|
||||
/* `[x] >Achtung` ist ein Label, keine Marke — die neue Marke kommt davor. */
|
||||
expect(setFoldMark(' - [x] >Achtung', '>')).toBe(' - [x] > >Achtung');
|
||||
expect(setFoldMark(' - [x] >Achtung', null)).toBe(' - [x] >Achtung');
|
||||
});
|
||||
|
||||
it('hält die Statusbox-Spalte über die Ebenen hinweg bündig', () => {
|
||||
/* Der Grund für die Stellung (D34-Nachtrag 2): Vor der Box geschrieben,
|
||||
rückte die Box der gefalteten Zeile um genau eine Einrückungsstufe ein
|
||||
und stand dann in der Spalte der Boxen ihrer eigenen Kinder. */
|
||||
const eltern = setFoldMark(' - [ ] erster Schritt', '>');
|
||||
const kind = ' - [ ] Schritt 1a';
|
||||
expect(eltern.indexOf('[')).toBe(4);
|
||||
expect(kind.indexOf('[')).toBe(6);
|
||||
});
|
||||
|
||||
it('ist verlustfrei umkehrbar', () => {
|
||||
|
||||
Reference in New Issue
Block a user