⚙️ JSON 转 TOML

将 JSON 转换为 TOML 格式,支持顶级键值对、嵌套表、数组、数字、布尔和 ISO 日期字符串。

等待转换...
已复制
const SAMPLE = JSON.stringify({title:"My App",version:"1.0",debug:true,port:8080,database:{host:"localhost",port:5432,pool:10},tags:["a","b","c"],owner:{name:"Alice",email:"alice@example.com"}}, null, 2); function tomlVal(v){ if(v === null) return '""'; if(typeof v === 'boolean') return String(v); if(typeof v === 'number') return String(v); if(typeof v === 'string') return JSON.stringify(v); if(Array.isArray(v)) return '[' + v.map(tomlVal).join(', ') + ']'; if(typeof v === 'object') return JSON.stringify(v); return JSON.stringify(String(v)); } function toToml(v, prefix){ prefix = prefix || ''; let s = ''; const scalar = {}, tables = {}; for(const k in v){ const val = v[k]; if(val && typeof val === 'object' && !Array.isArray(val)){ tables[k] = val; } else if(Array.isArray(val) && val.length && val.every(x => x && typeof x === 'object' && !Array.isArray(x))){ tables[k] = val; } else { scalar[k] = val; } } for(const k in scalar) s += k + ' = ' + tomlVal(scalar[k]) + '\n'; for(const k in tables){ const full = prefix ? prefix + '.' + k : k; if(Array.isArray(tables[k])){ tables[k].forEach(item => { s += '\n[[' + full + ']]\n' + toToml(item, full); }); } else { s += '\n[' + full + ']\n' + toToml(tables[k], full); } } return s; } function doToml(){ setErr(''); try{ const data = JSON.parse(document.getElementById('input').value); if(typeof data !== 'object' || Array.isArray(data) || data === null) throw new Error('需要 JSON 对象'); setOut(toToml(data).trim()); setErr('✅ 转换成功'); }catch(e){ setErr('❌ ' + e.message); } } function doMinToml(){ setErr(''); try{ const data = JSON.parse(document.getElementById('input').value); if(typeof data !== 'object' || Array.isArray(data) || data === null) throw new Error('需要 JSON 对象'); const min = toToml(data).split('\n').filter(l => l.trim()).join('\n'); setOut(min); setErr('✅ 压缩转换'); }catch(e){ setErr('❌ ' + e.message); } } function loadSample(){document.getElementById('input').value = SAMPLE; doToml();} function getIndent(){return ' ';} function setOut(s){document.getElementById('output').textContent = s;} function setErr(s){const e = document.getElementById('err'); e.textContent = s || ''; e.className = 'err' + (s && s.startsWith('✅') ? ' ok' : '');} function clearAll(){document.getElementById('input').value = ''; setOut('等待转换...'); setErr('');} function doValidate(){ doToml(); } function getIndent(){const v=document.getElementById('indent').value;return v==='tab'?'\t':' '.repeat(parseInt(v));} function setOut(s){document.getElementById('output').textContent=s;} function setErr(s){const e=document.getElementById('err');e.textContent=s||'';e.className='err'+(s?'':' ok');} function clearAll(){document.getElementById('input').value='';setOut('等待输入...');setErr('');} function loadSample(){document.getElementById('input').value=SAMPLE;doBeautify();}