feat: add markdown link support for lesson prerequisites
- Update lesson_service.py to parse markdown link format [title](path) - Convert all lesson files to use markdown link format for prerequisites - Backend now extracts slug directly from link path - Supports both plain text and markdown link formats
This commit is contained in:
parent
cf3131bed3
commit
d6bb2073ac
|
|
@ -8,9 +8,9 @@ Pelajaran Arduino: Membaca input tombol dan mengontrol LED.
|
|||
- Menghubungkan push button dan LED ke Arduino
|
||||
|
||||
**Prerequisites:**
|
||||
- Hello, World!
|
||||
- LED Blink
|
||||
- Hello Serial
|
||||
- [Hello, World!](lesson/hello_world.md)
|
||||
- [LED Blink](lesson/led_blink_arduino.md)
|
||||
- [Hello Serial](lesson/hello_serial_arduino.md)
|
||||
---END_LESSON_INFO---
|
||||
|
||||
# Button Input — Membaca Tombol
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ Pelajaran Arduino: Komunikasi Serial Monitor dan debugging.
|
|||
- Menggunakan `millis()` untuk tracking waktu
|
||||
|
||||
**Prerequisites:**
|
||||
- Hello, World!
|
||||
- [Hello, World!](lesson/hello_world.md)
|
||||
---END_LESSON_INFO---
|
||||
|
||||
# Hello Serial — Komunikasi Serial Arduino
|
||||
|
||||
Serial Monitor adalah **alat debugging utama** saat bekerja dengan Arduino.
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@ Pelajaran Arduino: Mengedipkan LED menggunakan simulator Velxio.
|
|||
- Menggunakan `Serial.print()` untuk debugging
|
||||
|
||||
**Prerequisites:**
|
||||
- Hello, World!
|
||||
- [Hello, World!](lesson/hello_world.md)
|
||||
---END_LESSON_INFO---
|
||||
|
||||
# LED Blink dengan Arduino
|
||||
|
||||
Proyek pertama setiap programmer Arduino: **mengedipkan LED!**
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ Pelajaran Arduino: Membuat simulasi lampu lalu lintas dengan 3 LED.
|
|||
- Menggunakan `const int` untuk nama pin yang mudah dibaca
|
||||
|
||||
**Prerequisites:**
|
||||
- Hello, World!
|
||||
- LED Blink
|
||||
- Hello Serial
|
||||
- Button Input
|
||||
- [Hello, World!](lesson/hello_world.md)
|
||||
- [LED Blink](lesson/led_blink_arduino.md)
|
||||
- [Hello Serial](lesson/hello_serial_arduino.md)
|
||||
- [Button Input](lesson/button_input_arduino.md)
|
||||
---END_LESSON_INFO---
|
||||
|
||||
# Traffic Light — Lampu Lalu Lintas
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ Pelajaran hybrid: Pemrograman C + Simulator Rangkaian Elektronika.
|
|||
- Menggunakan simulator rangkaian
|
||||
|
||||
**Prerequisites:**
|
||||
- Hello, World!
|
||||
- Variabel
|
||||
- [Hello, World!](lesson/hello_world.md)
|
||||
- [Variabel](lesson/variabel.md)
|
||||
---END_LESSON_INFO---
|
||||
|
||||
# Rangkaian Voltage Divider
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
- Membuat siklus perulangan (LOOP) untuk pemantauan berkelanjutan.
|
||||
|
||||
**Prerequisites:**
|
||||
- Variabel
|
||||
- [Variabel](lesson/variabel.md)
|
||||
|
||||
**Challenge:**
|
||||
Buatlah flowchart untuk **Sistem Penyiraman Tanaman Otomatis**.
|
||||
|
|
@ -69,4 +69,4 @@ check --> on
|
|||
check --> off
|
||||
on --> read
|
||||
off --> read
|
||||
---END_EXPECTED_FLOWCHART---
|
||||
---END_EXPECTED_FLOWCHART---
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
- Belajar menggunakan printf untuk menampilkan output
|
||||
|
||||
**Prerequisites:**
|
||||
- Tidak ada persyaratan khusus
|
||||
- Tidak ada
|
||||
---END_LESSON_INFO---
|
||||
|
||||
# Hello, World!
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
- Mengenal tipe data dasar: int, float, char
|
||||
|
||||
**Prerequisites:**
|
||||
- Hello, World!
|
||||
- [Hello, World!](lesson/hello_world.md)
|
||||
---END_LESSON_INFO---
|
||||
|
||||
# Variabel dalam C
|
||||
|
|
|
|||
|
|
@ -174,18 +174,31 @@ def get_lessons_with_learning_objectives():
|
|||
prereq_start = lesson_info_section.find('**Prerequisites:**')
|
||||
if prereq_start != -1:
|
||||
prereq_section = lesson_info_section[prereq_start + len('**Prerequisites:**'):]
|
||||
# Look for bullet points
|
||||
prerequisite_titles = re.findall(r'- ([^\n]+)', prereq_section)
|
||||
if not prerequisite_titles:
|
||||
# Fallback to lines until next bold or end
|
||||
next_bold = prereq_section.find('**')
|
||||
if next_bold != -1:
|
||||
prereq_section = prereq_section[:next_bold]
|
||||
prerequisite_titles = [l.strip() for l in prereq_section.split('\n') if l.strip()]
|
||||
# Look for bullet points - support both plain text and markdown link format
|
||||
# Plain text: - Hello, World!
|
||||
# Markdown link: - [Hello, World!](lesson/hello_world.md)
|
||||
bullet_lines = re.findall(r'- ([^\n]+)', prereq_section)
|
||||
|
||||
# Filter out "None" or "Tidak ada"
|
||||
prerequisite_titles = [t.strip() for t in prerequisite_titles
|
||||
if t.strip().lower() not in ('tidak ada', 'none', '-', '')]
|
||||
prerequisite_slugs = []
|
||||
for bullet in bullet_lines:
|
||||
bullet = bullet.strip()
|
||||
# Filter out "None" or "Tidak ada"
|
||||
if bullet.lower() in ('tidak ada', 'none', '-', ''):
|
||||
continue
|
||||
|
||||
# Check if it's a markdown link format [title](path)
|
||||
md_link_match = re.match(r'\[([^\]]+)\]\(([^)]+)\)', bullet)
|
||||
if md_link_match:
|
||||
# Extract slug from the link path
|
||||
link_path = md_link_match.group(2)
|
||||
# Handle paths like lesson/hello_world.md or just hello_world.md
|
||||
slug = link_path.replace('.md', '').split('/')[-1]
|
||||
prerequisite_slugs.append(slug)
|
||||
else:
|
||||
# Plain text - keep as title for later resolution
|
||||
prerequisite_slugs.append(bullet)
|
||||
|
||||
prerequisite_titles = prerequisite_slugs
|
||||
|
||||
content_after_info = content[lesson_info_end + len('---END_LESSON_INFO---'):].strip()
|
||||
for line in content_after_info.split('\n'):
|
||||
|
|
@ -232,9 +245,18 @@ def get_ordered_lessons_with_learning_objectives(progress=None):
|
|||
else:
|
||||
lesson['completed'] = False
|
||||
|
||||
# Resolve prerequisite titles to slugs
|
||||
titles = lesson.get('prerequisite_titles', [])
|
||||
lesson['prerequisites'] = [title_to_slug[t] for t in titles if t in title_to_slug]
|
||||
# Resolve prerequisites - now contains slugs directly from markdown links
|
||||
# or still contains plain text titles that need resolution
|
||||
items = lesson.get('prerequisite_titles', [])
|
||||
resolved_prereqs = []
|
||||
for item in items:
|
||||
# If it's already a valid slug (exists in all_lessons), use it directly
|
||||
if item in title_to_slug.values():
|
||||
resolved_prereqs.append(item)
|
||||
# Otherwise try to resolve via title mapping
|
||||
elif item in title_to_slug:
|
||||
resolved_prereqs.append(title_to_slug[item])
|
||||
lesson['prerequisites'] = resolved_prereqs
|
||||
return lesson
|
||||
|
||||
if lesson_links:
|
||||
|
|
|
|||
Loading…
Reference in New Issue