YAML: robustere Auto-Fix Einrückung mit Einheits-Erkennung

This commit is contained in:
2026-05-29 19:50:57 +02:00
parent f26d898088
commit 2d2178b172

View File

@@ -122,45 +122,29 @@ function collectPaths(data, path='root', paths=[]) {
// ── YAML Auto-Fix: normalisiert Einrückung bevor js-yaml parst ─────────────── // ── YAML Auto-Fix: normalisiert Einrückung bevor js-yaml parst ───────────────
function fixYamlIndentation(text) { function fixYamlIndentation(text) {
// Normalisiert Tabs → Spaces, erkennt Einrückungs-Inkonsistenz
// Strategie: Einrückung auf Basis des ersten vorkommenden Levels normalisieren
const lines = text.split('\n'); const lines = text.split('\n');
const fixed = [];
for (const line of lines) { // 1. Tabs → Spaces (4 oder 2)
// Tabs zu 2 Spaces const detabbed = lines.map(l => l.replace(/\t/g, ' '));
const noTabs = line.replace(/\t/g, ' ');
fixed.push(noTabs);
}
// Normalisiere die Einrückungslevel auf gerade 2-Vielfache // 2. Finde die kleinste vorkommende Einrückung > 0 (das ist die Einheit)
const result = []; const indents = detabbed
const indentStack = [0]; // Stack der gültigen Einrück-Level .filter(l => l.trim() && !l.trim().startsWith('#'))
.map(l => l.search(/\S/))
.filter(n => n > 0);
const unit = indents.length ? Math.min(...indents) : 2;
for (const line of fixed) { // 3. Remap: jede Einrückung → Niveau * 2 Spaces
if (!line.trim()) { result.push(''); continue; } const remapped = detabbed.map(line => {
if (line.trim().startsWith('#')) { result.push(line); continue; } 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();
});
const current = line.search(/\S/); return remapped.join('\n');
const content = line.trimStart();
// Finde den nächsten passenden Level im Stack
let level = indentStack.length - 1;
while (level > 0 && indentStack[level] > current) level--;
if (current > indentStack[level]) {
// Neue Einrückungstiefe
indentStack.splice(level + 1); // alles nach level entfernen
indentStack.push(current);
level = indentStack.length - 1;
}
// Normalize: depth * 2 spaces
const normalizedIndent = ' '.repeat(level);
result.push(normalizedIndent + content);
}
return result.join('\n');
} }
// ── YAML Tool ───────────────────────────────────────────────────────────────── // ── YAML Tool ─────────────────────────────────────────────────────────────────
@@ -177,29 +161,37 @@ function YamlTool({ mobile }) {
const process = useCallback((text) => { const process = useCallback((text) => {
if (!text.trim()) { setParsed(null); setFormatted(''); setError(''); setWarning(''); return; } if (!text.trim()) { setParsed(null); setFormatted(''); setError(''); setWarning(''); return; }
// Erste Versuch: direkt parsen let obj, parseError = null;
try {
const obj = jsyaml.load(text); // Versuch 1: direkt parsen
setParsed(obj); try { obj = jsyaml.load(text); }
setFormatted(jsyaml.dump(obj, { indent:2, lineWidth:-1, noRefs:true })); catch(e) { parseError = e; }
setError(''); setWarning('');
setCollapsed(new Set()); // Versuch 2: wenn Fehler → Auto-Fix, dann nochmal
return; if (parseError) {
} catch(e) {
// Zweiter Versuch: Auto-Fix und dann parsen
try { try {
const fixed = fixYamlIndentation(text); const fixed = fixYamlIndentation(text);
const obj = jsyaml.load(fixed); obj = jsyaml.load(fixed);
setParsed(obj); setWarning(`⚠ Einrückung automatisch korrigiert: ${parseError.message.split('\n')[0]}`);
setFormatted(jsyaml.dump(obj, { indent:2, lineWidth:-1, noRefs:true }));
setWarning(`⚠ Einrückung automatisch korrigiert: ${e.message.split('\n')[0]}`);
setError('');
setCollapsed(new Set());
} catch(e2) { } catch(e2) {
setError(e.message); // Fix hat auch nicht geholfen originalen Fehler zeigen
setError(parseError.message);
setWarning(''); setWarning('');
setParsed(null); setFormatted(''); setParsed(null); setFormatted('');
return;
} }
} else {
setWarning('');
}
try {
setParsed(obj);
setFormatted(jsyaml.dump(obj, { indent:2, lineWidth:-1, noRefs:true }));
setError('');
setCollapsed(new Set());
} catch(e) {
setError(e.message);
setParsed(null); setFormatted('');
} }
},[]); },[]);