- Neuer Mitarbeiter Komponist (.claude/agents/komponist.md) - Liederbuch: Plan + Lieder 1, 2, 3, 4, 5, 12 (drehbuecher/lieder/) - Suno: feste Stimme aus dem Favoriten, Stilvorlage, ausgewählte Fassungen (suno-auswahl.md) - Suno-Lizenzantwort für Noa in der Mitte (wissen/) - Werkzeuge für Melodie-Skizzen und Leseseite - Laufende Remotion-, Stimmen- und Figurenarbeiten des Tages Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MyLus898ZL9jjJJDvvxa8
35 lines
3.2 KiB
JavaScript
35 lines
3.2 KiB
JavaScript
import fs from 'fs'; import path from 'path';
|
||
const base = 'C:/Users/lk-lo/youtube/drehbuecher/lieder';
|
||
const dirs = fs.readdirSync(base).filter(d => d.startsWith('lied')).sort();
|
||
const songs = dirs.map(d => ({id: d, md: fs.readFileSync(path.join(base, d, 'de.md'), 'utf8')}));
|
||
const plan = fs.readFileSync(path.join(base, 'plan.md'), 'utf8');
|
||
songs.push({id: 'plan', md: plan});
|
||
const titles = songs.map(s => (s.md.match(/^#\s+(.+)$/m) || [, s.id])[1].replace(/^Lied \d+:\s*/, ''));
|
||
const html = `<!doctype html><html lang="de"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Pinos Liederbuch</title>
|
||
<script src="https://cdn.jsdelivr.net/npm/marked@12.0.2/marked.min.js"></script>
|
||
<style>
|
||
:root{--bg:#fbf7ef;--fg:#2b2620;--muted:#7a6f60;--acc:#c0462e;--line:#e6dccb;--card:#fff}
|
||
@media (prefers-color-scheme:dark){:root{--bg:#1d1a16;--fg:#eee6d8;--muted:#a89c8a;--acc:#f08a6c;--line:#3a332a;--card:#26221c}}
|
||
body{margin:0;background:var(--bg);color:var(--fg);font:16px/1.55 Georgia,serif}
|
||
nav{position:sticky;top:0;background:var(--bg);border-bottom:1px solid var(--line);display:flex;flex-wrap:wrap;gap:6px;padding:10px 16px;z-index:2}
|
||
nav button{font:inherit;font-size:14px;border:1px solid var(--line);background:var(--card);color:var(--fg);border-radius:999px;padding:5px 12px;cursor:pointer}
|
||
nav button.on{background:var(--acc);border-color:var(--acc);color:#fff}
|
||
main{max-width:860px;margin:0 auto;padding:16px}
|
||
h1{font-size:28px;color:var(--acc)} h2{margin-top:2em;border-bottom:1px solid var(--line);padding-bottom:4px}
|
||
table{border-collapse:collapse;width:100%;font-size:14px;display:block;overflow-x:auto} td,th{border:1px solid var(--line);padding:5px 8px;vertical-align:top} th{background:var(--card)}
|
||
pre{background:var(--card);border:1px solid var(--line);padding:12px;overflow-x:auto;font-size:13px;white-space:pre-wrap} code{font-size:13px}
|
||
.hoer{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:12px;margin:8px 0 16px;font-size:14px}.hoer audio{display:block;width:100%;margin-top:8px}
|
||
blockquote{border-left:3px solid var(--acc);margin-left:0;padding-left:12px;color:var(--muted)}
|
||
</style></head><body>
|
||
<nav>${titles.map((t,i)=>`<button data-i="${i}">${i<songs.length-1?songs[i].id.match(/\d+/)[0]*1+'. ':''}${t.replace(/[„“"]/g,'').slice(0,34)}</button>`).join('')}</nav>
|
||
<main id="m"></main>
|
||
<script>
|
||
const S=${JSON.stringify(songs.map(s=>s.md))};const A=${JSON.stringify(songs.map(s=>fs.existsSync('C:/Users/lk-lo/Pino-Kanal/Lieder-Vorschau/'+s.id+'.mp3')?'Lieder-Vorschau/'+s.id+'.mp3':''))};
|
||
const B=[...document.querySelectorAll('nav button')];
|
||
function show(i){document.getElementById('m').innerHTML=(A[i]?'<div class="hoer"><b>▶ Melodie-Vorschau</b> (Refrain – Strophe – Refrain, ohne Gesang; nur zum Hören der Melodie, nicht der Klang des fertigen Lieds)<audio controls preload="none" src="'+A[i]+'"></audio></div>':'')+marked.parse(S[i]);B.forEach((b,j)=>b.classList.toggle('on',i==j));scrollTo(0,0);try{localStorage.lied=i}catch(e){}}
|
||
B.forEach(b=>b.onclick=()=>show(+b.dataset.i));
|
||
let s=0;try{s=+localStorage.lied||0}catch(e){} show(s<S.length?s:0);
|
||
</script></body></html>`;
|
||
fs.writeFileSync('C:/Users/lk-lo/Pino-Kanal/Liederbuch-Entwuerfe.html', html);
|
||
console.log(titles.join('\n'));
|