|
206 | 206 | } |
207 | 207 |
|
208 | 208 | /* ===== syntax docs (collapsed) ===== */ |
209 | | -#syntax-docs { background: #fafafa; border-top: 2px solid #ccc; padding: 0 16px 28px; font-size: 13px; line-height: 1.5; } |
210 | | -#syntax-docs > summary { cursor: pointer; padding: 12px 0; font-weight: 600; font-size: 14px; color: #1976d2; list-style: none; } |
211 | | -#syntax-docs > summary::-webkit-details-marker { display: none; } |
212 | | -#syntax-docs > summary::before { content: "\25B8 "; } |
213 | | -#syntax-docs[open] > summary::before { content: "\25BE "; } |
214 | | -#syntax-docs .docs-body { max-width: 880px; } |
215 | | -#syntax-docs h3 { margin: 20px 0 6px; font-size: 14px; border-bottom: 1px solid #ddd; padding-bottom: 3px; } |
216 | | -#syntax-docs h4 { margin: 14px 0 4px; font-size: 13px; } |
217 | | -#syntax-docs p { margin: 6px 0; } |
218 | | -#syntax-docs code { background: #eceff1; padding: 1px 4px; border-radius: 3px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; } |
219 | | -#syntax-docs pre { background: #263238; color: #eceff1; padding: 10px 12px; border-radius: 6px; overflow: auto; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.4; } |
220 | | -#syntax-docs pre code { background: none; padding: 0; color: inherit; } |
221 | | -#syntax-docs table { border-collapse: collapse; margin: 6px 0; width: 100%; } |
222 | | -#syntax-docs th, #syntax-docs td { border: 1px solid #ddd; padding: 3px 8px; text-align: left; vertical-align: top; font-size: 12px; } |
223 | | -#syntax-docs th { background: #eceff1; } |
224 | | -#syntax-docs ul { margin: 4px 0; padding-left: 20px; } |
225 | | -#syntax-docs li { margin: 2px 0; } |
| 209 | +.syntax-docs { background: #fafafa; border-top: 2px solid #ccc; padding: 0 16px 28px; font-size: 13px; line-height: 1.5; } |
| 210 | +.syntax-docs > summary { cursor: pointer; padding: 12px 0; font-weight: 600; font-size: 14px; color: #1976d2; list-style: none; } |
| 211 | +.syntax-docs > summary::-webkit-details-marker { display: none; } |
| 212 | +.syntax-docs > summary::before { content: "\25B8 "; } |
| 213 | +.syntax-docs[open] > summary::before { content: "\25BE "; } |
| 214 | +.syntax-docs .docs-body { max-width: 880px; } |
| 215 | +.syntax-docs h3 { margin: 20px 0 6px; font-size: 14px; border-bottom: 1px solid #ddd; padding-bottom: 3px; } |
| 216 | +.syntax-docs h4 { margin: 14px 0 4px; font-size: 13px; } |
| 217 | +.syntax-docs p { margin: 6px 0; } |
| 218 | +.syntax-docs code { background: #eceff1; padding: 1px 4px; border-radius: 3px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; } |
| 219 | +.syntax-docs pre { background: #263238; color: #eceff1; padding: 10px 12px; border-radius: 6px; overflow: auto; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.4; } |
| 220 | +.syntax-docs pre code { background: none; padding: 0; color: inherit; } |
| 221 | +.syntax-docs table { border-collapse: collapse; margin: 6px 0; width: 100%; } |
| 222 | +.syntax-docs th, .syntax-docs td { border: 1px solid #ddd; padding: 3px 8px; text-align: left; vertical-align: top; font-size: 12px; } |
| 223 | +.syntax-docs th { background: #eceff1; } |
| 224 | +.syntax-docs ul { margin: 4px 0; padding-left: 20px; } |
| 225 | +.syntax-docs li { margin: 2px 0; } |
226 | 226 | </style> |
227 | 227 | </head> |
228 | 228 | <body> |
@@ -259,8 +259,8 @@ <h1>Song Editor — Alkitab (REM-21)</h1> |
259 | 259 | </div> |
260 | 260 | </div> |
261 | 261 |
|
262 | | -<details id="syntax-docs"> |
263 | | -<summary>txt syntax reference — legacy & <code>@doc</code> formats</summary> |
| 262 | +<details class="syntax-docs"> |
| 263 | +<summary>txt syntax reference (English) — legacy & <code>@doc</code> formats</summary> |
264 | 264 | <div class="docs-body"> |
265 | 265 |
|
266 | 266 | <p>The editor parses a <strong>single song</strong>. A line starting with <code>===</code> ends the song (anything after is ignored). Every line is trimmed before parsing. Format detection is per song: if a line that is exactly <code>@doc</code> follows the <code>code</code>/<code>no</code> header, the song is parsed as the new <strong>document format</strong>; otherwise the <strong>legacy format</strong> is used.</p> |
@@ -362,6 +362,109 @@ <h4><code>@doc</code> example</h4> |
362 | 362 | </div> |
363 | 363 | </details> |
364 | 364 |
|
| 365 | +<details class="syntax-docs"> |
| 366 | +<summary>Referensi sintaks txt (Bahasa Indonesia) — format legacy & <code>@doc</code></summary> |
| 367 | +<div class="docs-body"> |
| 368 | + |
| 369 | +<p>Editor mem-parse <strong>satu lagu saja</strong>. Baris yang diawali <code>===</code> mengakhiri lagu (sisanya diabaikan). Setiap baris di-<em>trim</em> sebelum diproses. Deteksi format per lagu: jika ada baris yang persis <code>@doc</code> setelah header <code>code</code>/<code>no</code>, lagu diproses sebagai <strong>format dokumen</strong> baru; jika tidak, dipakai <strong>format lama (legacy)</strong>.</p> |
| 370 | + |
| 371 | +<h3>Gaya inline (kedua format)</h3> |
| 372 | +<p>Di dalam baris teks/lirik, <code><u>…</u></code>, <code><b>…</b></code>, <code><i>…</i></code> menandai garis bawah / tebal / miring dan menjadi span bergaya. Markup lain disimpan sebagai teks literal (di-<em>escape</em> saat render). Hanya <code>u</code>/<code>b</code>/<code>i</code> yang dikenali.</p> |
| 373 | + |
| 374 | +<h3>Format lama (legacy)</h3> |
| 375 | +<p>Berbasis baris. Lagu diawali baris-baris header, lalu baris lirik begitu muncul penanda <code>*</code>.</p> |
| 376 | + |
| 377 | +<h4>Kata kunci header</h4> |
| 378 | +<p>Bentuk: <code>kata_kunci nilai</code> (dipisah pada spasi pertama). Kata kunci bahasa Indonesia dan Inggris dapat dipakai bergantian.</p> |
| 379 | +<table> |
| 380 | +<tr><th>Indonesia</th><th>Inggris</th><th>Memetakan ke</th><th>Catatan</th></tr> |
| 381 | +<tr><td><code>no</code></td><td><code>code</code></td><td>code</td><td>nomor lagu / kunci pencarian</td></tr> |
| 382 | +<tr><td><code>judul</code></td><td><code>title</code></td><td>title</td><td></td></tr> |
| 383 | +<tr><td><code>judul_asli</code></td><td><code>title_original</code></td><td>title_original</td><td>judul bahasa asli</td></tr> |
| 384 | +<tr><td><code>tune</code></td><td><code>tune</code></td><td>tune</td><td></td></tr> |
| 385 | +<tr><td><code>lirik</code></td><td><code>authors_lyric</code></td><td>authors_lyric</td><td>dipisah dengan <code>;</code> menjadi list</td></tr> |
| 386 | +<tr><td><code>musik</code></td><td><code>authors_music</code></td><td>authors_music</td><td>dipisah dengan <code>;</code> menjadi list</td></tr> |
| 387 | +<tr><td><code>ayat</code></td><td><code>scriptureReferences</code></td><td>scripture</td><td>OSIS, mis. <code>Rev.5.13</code></td></tr> |
| 388 | +<tr><td><code>tempo</code></td><td>—</td><td>(dibuang)</td><td>dikenali tetapi dibuang</td></tr> |
| 389 | +</table> |
| 390 | + |
| 391 | +<h4>Baris header polos (tanpa kata kunci)</h4> |
| 392 | +<ul> |
| 393 | +<li><strong>Nada dasar</strong> — cocok dengan <code>[1-7]=[ABCDEFG](is|s|es|b)?</code>, mis. <code>1=Bes</code>, <code>1=Ab</code> (alternatif dipisah koma diperbolehkan).</li> |
| 394 | +<li><strong>Tanda birama</strong> — cocok dengan <code>n/n</code>, mis. <code>4/4</code>, <code>6/8</code>.</li> |
| 395 | +</ul> |
| 396 | + |
| 397 | +<h4>Penanda lirik (baris diawali <code>*</code>)</h4> |
| 398 | +<table> |
| 399 | +<tr><th>Penanda</th><th>Efek</th></tr> |
| 400 | +<tr><td><code>*N</code> (mis. <code>*1</code>)</td><td>bait normal, nomor <code>N</code>. Jika <code>N ≤</code> nomor normal sebelumnya, <strong>grup lirik baru</strong> dimulai (begini cara bait Indonesia→Inggris yang dinomori ulang terpisah).</td></tr> |
| 401 | +<tr><td><code>*reff</code> / <code>*ref</code> (opsional <code>*reff2</code>)</td><td>bait refrain</td></tr> |
| 402 | +<tr><td><code>*text</code> (opsional <code>*text2</code>)</td><td>bait ucapan / instruksi (tanpa nomor)</td></tr> |
| 403 | +<tr><td><code>*versi <caption></code> / <code>*version <caption></code></td><td>mulai grup lirik baru dengan caption tersebut</td></tr> |
| 404 | +</table> |
| 405 | +<p>Baris setelah penanda adalah baris-baris bait. <strong>Baris kosong TIDAK mengakhiri bait</strong> (bait berlanjut sampai penanda berikutnya atau <code>===</code>). <code>//</code> mengawali baris komentar (diabaikan).</p> |
| 406 | + |
| 407 | +<h4>Contoh format lama</h4> |
| 408 | +<pre><code>code 25 |
| 409 | +title Malam Kudus |
| 410 | +1=Bes |
| 411 | +6/8 |
| 412 | +tune STILLE NACHT |
| 413 | +title_original Silent Night |
| 414 | +authors_lyric Joseph Mohr |
| 415 | +authors_music Franz X. Gruber |
| 416 | + |
| 417 | +*1 |
| 418 | +Malam Kudus, sunyi senyap, |
| 419 | +<u>Sia</u>pa yang b'lum lelap; |
| 420 | + |
| 421 | +*reff |
| 422 | +Maka jiwaku pun memuji-Mu,</code></pre> |
| 423 | + |
| 424 | +<h3>Format dokumen (<code>@doc</code>)</h3> |
| 425 | +<p>Diaktifkan per lagu: baris <code>code <KODE></code> (atau <code>no</code>), lalu baris yang persis <code>@doc</code>. Di bawah <code>@doc</code>, setiap baris memetakan ke satu blok <strong>sesuai urutan penulisan</strong>.</p> |
| 426 | + |
| 427 | +<h4>Aturan baris</h4> |
| 428 | +<ul> |
| 429 | +<li><strong>Default</strong> — baris tanpa awalan <code>@</code> atau <code>*</code> → blok <code>p</code> (paragraf), tanpa role.</li> |
| 430 | +<li><strong>Paragraf bertag</strong> — satu atau beberapa <code>@</code>-tag di depan, lalu teks. Tag dapat digabung, mis. <code>@size=2.0 Teks besar</code> atau <code>@size=0.5 @musical Do=C</code>. |
| 431 | + <ul> |
| 432 | + <li>Tag role → <code>p.role</code>: <code>@title</code>, <code>@title_original</code>, <code>@tune</code>, <code>@musical</code>, <code>@authors_lyric</code>, <code>@authors_music</code>, <code>@note</code>, <code>@copyright</code>, <code>@body</code>, … (role membawa format default; <code>title</code> = tebal + rata tengah, dst).</li> |
| 433 | + <li>Tag format: <code>@size=<float></code> (1 = normal) dan <code>@align=<start|center|end></code>.</li> |
| 434 | + </ul> |
| 435 | +</li> |
| 436 | +<li><code>@scripture <osis></code> → blok <code>scripture</code> (OSIS, mis. <code>John.3.16; Rom.5.8</code>; dilokalkan saat render sesuai versi Alkitab aktif).</li> |
| 437 | +<li><code>@youtube <videoId></code> → blok <code>youtube</code>.</li> |
| 438 | +<li><code>@row</code> … <code>@/row</code> → blok <code>row</code>; setiap baris di antara penanda menjadi item <code>p</code> (tag role/size/align-nya sendiri berlaku). Item tersebar start → end, mis. pengarang lirik di kiri / pengarang musik di kanan.</li> |
| 439 | +<li><strong>Penanda lirik</strong> <code>*N</code>, <code>*ref</code>[N]/<code>*reff</code>[N], <code>*text</code>[N], <code>*versi</code>/<code>*version <caption></code> — semantik + auto-grup sama seperti legacy. Baris bait mendukung <code>@size=</code> / <code>@align=</code> di depan (format per baris).</li> |
| 440 | +<li><strong>Baris kosong mengakhiri bait</strong> saat ini (kembali ke mode paragraf); penanda <code>*</code> berikutnya membuka kembali mode lirik.</li> |
| 441 | +<li><strong>Escape</strong> — baris diawali <code>\</code> akan menghapus backslash dan diperlakukan sebagai teks paragraf literal, sehingga dapat diawali <code>*</code>, <code>@</code>, <code>//</code>, atau <code>==</code>.</li> |
| 442 | +<li><code>@directive</code> tak dikenal → diberi peringatan dan dilewati (tidak fatal).</li> |
| 443 | +</ul> |
| 444 | + |
| 445 | +<h4>Contoh <code>@doc</code></h4> |
| 446 | +<pre><code>code 25 |
| 447 | +@doc |
| 448 | +@title Malam Kudus |
| 449 | +@title_original Silent Night |
| 450 | +@tune STILLE NACHT |
| 451 | +@row |
| 452 | +@authors_lyric Joseph Mohr |
| 453 | +@authors_music Franz X. Gruber |
| 454 | +@/row |
| 455 | +@scripture Luke.2.7 |
| 456 | +@musical 1=Bes 6/8 |
| 457 | + |
| 458 | +*1 |
| 459 | +Malam Kudus, sunyi senyap, |
| 460 | +@size=1.3 <u>Sia</u>pa yang b'lum lelap; |
| 461 | + |
| 462 | +*reff |
| 463 | +Maka jiwaku pun memuji-Mu,</code></pre> |
| 464 | + |
| 465 | +</div> |
| 466 | +</details> |
| 467 | + |
365 | 468 | <script> |
366 | 469 | 'use strict'; |
367 | 470 |
|
|
0 commit comments