feat(docs): docs viewer, API reference generator, markdown rendering
- Add YAML frontmatter (title/order/category) to 13 docs/*.md files
- Add services/docs_service.py: mtime-cache, frontmatter parsing w/ fallback,
bleach sanitize, path traversal protection
- Add routes/docs.py: GET /api/docs, GET /api/docs/<slug>, GET /api/docs/api-reference
- Register docs_bp in app.py
- Add frontend /docs + /docs/[slug] routes (sidebar nav + markdown render)
- Add frontend/src/types/docs.ts interfaces
- Add link from /help page to /docs viewer
- Add scripts/validate_docs.py: frontmatter + broken link validation
- Add elemes.sh docs-validate command
Endpoints documented in API reference: /quiz-attempts/<lesson>,
/sessions, /bab/<folder>, /compile/sessions, /lesson/<slug>.json + all 30 routes
2026-08-17 11:29:43 +07:00
---
title: Slide Presentasi
order: 9
category: slides
---
2026-08-08 11:57:08 +07:00
# 09. Slide Presentasi Interaktif
Blok `---slide-start---` dan `---slide-end---` di materi markdown membuat carousel presentasi interaktif dengan fullscreen mode.
## Format
```markdown
---slide-start---
## Slide 1: Judul
Konten slide ini mendukung teks, gambar, code fence, dan embed.
```c
int main() {
printf("Hello, World!\n");
return 0;
}
```
---slide-end---
```
## Fitur
- **Fullscreen mode** — tombol fullscreen untuk setiap slide
- **Embed support** — Canva, YouTube, Google Docs, Figma di dalam slide
- **Auto-save indicator** — indikator penyimpanan otomatis
- **Progress indicator** — menunjukkan slide ke berapa dari total
## Contoh
Lihat `examples/content/dasar/rangkaian_dasar.md` untuk contoh slide dengan embed Canva dan circuit.
## Catatan
feat(quiz): taksonomi key quiz per jenis + MCQ berbobot (partial credit)
Fitur B — setiap jenis soal kini punya key sendiri sehingga model
penilaiannya eksplisit, tidak ditebak dari isi konten:
- ---QUIZ_MCQ--- pilihan ganda biner (tepat satu [x]; larang [N])
- ---QUIZ_WEIGHTED--- pilihan ganda berbobot ([N] >= 1, minimal satu [ ],
bobot tertinggi unik = kunci; poin parsial)
- ---FLASHCARD--- kartu hafalan tanpa penilaian (larang opsi)
- legacy ---QUIZ_FLASHCARD--- / ---INITIAL_QUIZ--- tetap dibaca tanpa
perubahan perilaku (regex opsi legacy sengaja tidak berubah — baris
'- [10]' di konten lama BUKAN opsi); dihapus dari docs/template
- ::diagnostic tetap kategori di dalam QUIZ_MCQ & tetap masuk skor resmi
Model skor: rata-rata persentase per jenis yang ada, Math.round,
lulus >= 75. statusString: "X/Y" bila hanya MCQ/legacy, "P/100" bila ada
weighted, "completed" bila hanya flashcard (auto-lulus). Satu sesi/
attempt untuk semua jenis; soal flat urut dokumen.
Parser (backend & frontend mirror, ekstraksi multi-blok per key urut
dokumen via loop marker-start paling awal; id q-N deterministik):
- lesson_service.py: regex [ xX]?[0-9]* utk key baru, _iter_option_lines
kind-aware, _validate_quiz_options per kind, _parse_flashcards(kind,
id_offset), _extract_quiz_sections + guard loop maju (marker end
hilang tidak lagi infinite loop), get_lesson_quiz_total -> 100 bila
ada weighted (round-trip CSV "P/100")
- parseFlashcards.ts / index.ts / detectActiveTabs.ts / extractSections.ts:
mirror perilaku; heading soal <h3> kini fence-aware (fix fixture stale)
Payload attempt baru: quiz_type, earned_points, question_max_points —
opsional di validasi backend supaya klien lama tetap diterima; poin
di-recompute dari konten saat resume/review.
UI: QuizTab skor via statusString + alert berbasis percent, badge
weighted (✓ 10 / 🟡 7/10 / ✗ 0) di review, preview guru badge bobot +
"Berbobot (total N)", laporan guru badge MCQ/Bobot + tooltip, CSV
progress 2 kolom baru per lesson (_quiz_mcq, _quiz_weighted), template
editor konten QUIZ_MCQ/Quiz Bobot/Flashcard.
Tooling & docs: scripts/convert_quiz_keys.py (konversi legacy -> key
baru per run jenis, idempoten, verifikasi parse identik; examples/
content dikonversi), scanner mendukung semua key, docs/07 ditulis ulang,
docs/15 direvisi ke desain final, README/documentation/docs 02/04/09
diperbarui.
Tes: backend 444 lulus (+33: validasi ketat per key, urutan dokumen,
multi-blok, zero regression, field selalu di-emit), frontend 249 lulus
(+13 parser key baru, +11 model skor), parity fixture diregenerasi,
svelte-check 0 error, vite build OK.
2026-10-25 20:16:56 +07:00
- Slide mendukung semua blok markdown kecuali blok quiz (`---QUIZ_MCQ---`, `---QUIZ_WEIGHTED---` , `---FLASHCARD---` ) dan `---slide-start---` di dalam slide
2026-08-08 11:57:08 +07:00
- Embed di dalam slide diproses otomatis oleh backend (`_process_embed_embeds()` di loop slide)
- Gambar di slide menggunakan path relatif `/assets/` atau URL absolut