diff --git a/frontend/src/tools/devtools.jsx b/frontend/src/tools/devtools.jsx index d8de6ed..da48e23 100644 --- a/frontend/src/tools/devtools.jsx +++ b/frontend/src/tools/devtools.jsx @@ -120,31 +120,40 @@ function collectPaths(data, path='root', paths=[]) { return paths; } -// ── YAML Auto-Fix: normalisiert Einrückung bevor js-yaml parst ─────────────── +// ── YAML Auto-Fix: Stack-basierter Strukturerhalter ────────────────────────── function fixYamlIndentation(text) { - const lines = text.split('\n'); + const lines = text.split('\n').map(l => l.replace(/\t/g, ' ')); + const stack = [{ indent: -1, depth: -1 }]; + const result = []; - // 1. Tabs → Spaces (4 oder 2) - const detabbed = lines.map(l => l.replace(/\t/g, ' ')); + for (const line of lines) { + if (!line.trim()) { result.push(''); continue; } - // 2. Finde die kleinste vorkommende Einrückung > 0 (das ist die Einheit) - const indents = detabbed - .filter(l => l.trim() && !l.trim().startsWith('#')) - .map(l => l.search(/\S/)) - .filter(n => n > 0); - const unit = indents.length ? Math.min(...indents) : 2; + const indent = line.search(/\S/); + const content = line.trim(); - // 3. Remap: jede Einrückung → Niveau * 2 Spaces - const remapped = detabbed.map(line => { - if (!line.trim()) return ''; - if (line.trim().startsWith('#')) return line.trimEnd(); - const spaces = line.search(/\S/); - if (spaces <= 0) return line.trimEnd(); - const level = Math.round(spaces / unit); - return ' '.repeat(level) + line.trimStart().trimEnd(); - }); + if (content.startsWith('#')) { + result.push(' '.repeat(Math.max(0, stack[stack.length-1].depth + 1)) + content); + continue; + } - return remapped.join('\n'); + // Pop stack-Einträge die >= aktuelle Einrückung haben + while (stack.length > 1 && stack[stack.length-1].indent >= indent) { + stack.pop(); + } + + const depth = stack[stack.length-1].depth + 1; + stack.push({ indent, depth }); + result.push(' '.repeat(depth) + content); + } + + return result.join('\n'); +} + +// Versucht einen lesbaren Fehler aus dem js-yaml Fehler zu bauen +function shortError(e) { + const first = e.message.split('\n')[0]; + return first.length > 120 ? first.slice(0,120)+'…' : first; } // ── YAML Tool ───────────────────────────────────────────────────────────────── @@ -160,24 +169,25 @@ function YamlTool({ mobile }) { const process = useCallback((text) => { if (!text.trim()) { setParsed(null); setFormatted(''); setError(''); setWarning(''); return; } - + let obj, parseError = null; // Versuch 1: direkt parsen try { obj = jsyaml.load(text); } catch(e) { parseError = e; } - // Versuch 2: wenn Fehler → Auto-Fix, dann nochmal + // Versuch 2: Auto-Fix, dann nochmal if (parseError) { + const fixed = fixYamlIndentation(text); try { - const fixed = fixYamlIndentation(text); obj = jsyaml.load(fixed); - setWarning(`⚠ Einrückung automatisch korrigiert: ${parseError.message.split('\n')[0]}`); + setWarning(`⚠ Einrückung automatisch korrigiert – bitte Ergebnis prüfen`); } catch(e2) { - // Fix hat auch nicht geholfen – originalen Fehler zeigen - setError(parseError.message); - setWarning(''); - setParsed(null); setFormatted(''); + // Auch nach Fix nicht parsebar → best-effort Text trotzdem anzeigen + setError(shortError(parseError)); + setWarning('Struktur zu stark beschädigt – nur Einrückung wurde normalisiert. Bitte manuell korrigieren.'); + setParsed(null); + setFormatted(fixed); // zeige korrigierten Text zum manuellen Nachbessern return; } } else { @@ -260,17 +270,26 @@ function YamlTool({ mobile }) { - {error ? ( + {error && !formatted ? (