Convert YouTube content into a chapter-based subpage structure.
Usage
/split-youtube-chapters <week/slug>
Example
/split-youtube-chapters week1/deep-dive-llms
Input/Output
Input
docs/week{N}/{slug}/eng/index.md- Original YouTube content including chapter structuredocs/week{N}/{slug}/kr/index.md- Full translation file (required when generating chapter files)
Output
src/content/readings.tsModified:- Convert the existing Reading into a
isParent: true+childrenarray - Create each chapter as a ChildReading
- Convert the existing Reading into a
docs/week{N}/{slug}/kr/{childSlug}.md- Per-chapter translation files (N)
Conversion example
Before conversion (single page)
'week1/deep-dive-llms': {
slug: 'deep-dive-llms',
week: 1,
title: 'Deep Dive into LLMs like ChatGPT',
titleKr: 'ChatGPT 같은 LLM 심층 분석',
author: 'Andrej Karpathy',
readTime: '약 3시간 31분',
sourceUrl: 'https://www.youtube.com/watch?v=7xTGNNLPyMI',
sourceTitle: 'YouTube - Deep Dive into LLMs like ChatGPT',
published: true,
sections: [
{ title: '1. Introduction (0:00)', content: '...' },
{ title: '2. Pretraining Data (1:00)', content: '...' },
// ... 24개 섹션
],
keyTakeaways: [...]
}
After conversion (parent + child structure)
'week1/deep-dive-llms': {
slug: 'deep-dive-llms',
week: 1,
title: 'Deep Dive into LLMs like ChatGPT',
titleKr: 'ChatGPT 같은 LLM 심층 분석',
author: 'Andrej Karpathy',
readTime: '약 3시간 31분',
sourceUrl: 'https://www.youtube.com/watch?v=7xTGNNLPyMI',
sourceTitle: 'YouTube - Deep Dive into LLMs like ChatGPT',
published: true,
isParent: true,
// 부모 페이지의 sections는 개요 정보
sections: [
{
title: '개요',
content: 'Andrej Karpathy의 LLM 심층 분석 강의입니다...',
}
],
// YouTube 전용 필드 유지
contentType: 'youtube',
duration: '3:31:05',
totalChapters: 24,
tldr: '...',
learningGoals: [...],
chapterSummaries: [...],
// 챕터별 자식 페이지
children: [
{
slug: 'introduction',
title: '1. Introduction',
titleKr: '1. 소개',
sourceUrl: 'https://www.youtube.com/watch?v=7xTGNNLPyMI&t=0s',
published: true, // 번역 파일 있으면 true
hasMarkdown: true, // 마크다운 동적 로딩 활성화
},
{
slug: 'pretraining-data',
title: '2. Pretraining Data',
titleKr: '2. 사전학습 데이터',
sourceUrl: 'https://www.youtube.com/watch?v=7xTGNNLPyMI&t=60s',
published: true,
hasMarkdown: true,
},
// ... 24개 챕터
]
}
Execution instructions
Step 1: Read the original markdown
1. docs/week{N}/{slug}/eng/index.md 파일 읽기
2. 파일이 없으면 에러: "원본 파일을 찾을 수 없습니다."
3. 프론트매터에서 메타데이터 추출:
- source_url
- chapters (또는 본문에서 파싱)
Step 2: Parse the chapter structure
Extract chapters from the Table of Contents or h2 sections of the original markdown:
## Table of Contents
1. [Introduction](#1-introduction) (0:00)
2. [Pretraining Data (Internet)](#2-pretraining-data-internet) (1:00)
3. [Tokenization](#3-tokenization) (7:47)
...
Information to extract from each chapter:
- Number: 1, 2, 3, ...
- English title: Introduction, Pretraining Data, Tokenization
- Timestamp: 0:00, 1:00, 7:47
Step 3: Convert chapter title → slug
| English title | slug |
|---|---|
| Introduction | introduction |
| Pretraining Data (Internet) | pretraining-data |
| Tokenization | tokenization |
| Neural Network I/O | neural-network-io |
| GPT-2: Training and Inference | gpt2-training-inference |
| Llama 3.1 Base Model Inference | llama-31-base-model |
| Hallucinations, Tool Use, Knowledge/Working Memory | hallucinations-tool-use |
| Reinforcement Learning from Human Feedback (RLHF) | rlhf |
Slug generation rules:
- Convert to lowercase English
- Remove special characters (parentheses, colons, slashes, etc.)
- Convert spaces to
-Convert to - Remove consecutive
-removal - If too long, use only key words (within about 30 characters)
Step 4: Translate chapter titles into Korean
| English title | titleKr |
|---|---|
| Introduction | Introduction |
| Pretraining Data | Pretraining data |
| Tokenization | Tokenization |
| Neural Network I/O | Neural network input/output |
| Inference | Inference |
| Reinforcement Learning | Reinforcement learning |
| RLHF | RLHF (Reinforcement Learning from Human Feedback) |
Korean translation rules:
- Translate general technical terms into Korean
- Keep proper nouns (GPT-2, Llama, DeepSeek-R1) as is
- Keep abbreviations (RLHF, I/O) as is + explain in parentheses
- Keep numbers as is: "1. Introduction", "2. Pretraining data"
Step 5: Convert timestamp → YouTube URL
타임스탬프 "1:20:32" → 초 단위 변환 → 4832초
YouTube URL: {sourceUrl}&t=4832s
Step 6: Update readings.ts
- Find the existing Reading
- Add/modify the following fields:
isParent: truesections: Replace with overview information (remove existing sections)children: Add a per-chapter ChildReading array
// 기존 sections 대체
sections: [
{
title: '개요',
content: `${author}의 ${titleKr} 강의입니다. 총 ${totalChapters}개의 챕터로 구성되어 있으며, 약 ${duration} 분량입니다.`,
}
],
// children 추가
// 번역 파일이 있으면 published: true, hasMarkdown: true
// 번역 파일이 없으면 published: false, hasMarkdown: false
children: [
{
slug: 'introduction',
title: '1. Introduction',
titleKr: '1. 소개',
sourceUrl: 'https://www.youtube.com/watch?v=...&t=0s',
published: true, // 번역 파일 있으면 true
hasMarkdown: true, // 번역 파일 있으면 true
},
// ...
]
Step 7: Check the readings.ts update result
After completing the readings.ts update, proceed to the next step.
Step 8: Generate per-chapter translation files (if not --skip-files)
Split each chapter from the full translation file and generate individual files.
8.1 Check the full translation file
파일 경로: docs/week{N}/{slug}/kr/index.md
파일이 없으면:
⚠ 전체 번역 파일이 없습니다.
→ 챕터별 파일 생성 건너뜀
→ readings.ts 업데이트만 완료
8.2 Parse the SUMMARY section
<!-- SUMMARY_START -->
## TL;DR
...
## 챕터별 요약
### 1. 소개 (0:00)
요약 텍스트...
**핵심 포인트:**
- 포인트1
- 포인트2
---
### 2. 사전학습 데이터 - 인터넷 (1:00)
...
<!-- SUMMARY_END -->
Parsing regex:
챕터 헤더: /^### (\d+)\.\s*(.+?)\s*\((\d+:\d+(?::\d+)?)\)/gm
그룹: [1]=번호, [2]=한국어 제목, [3]=타임스탬프
핵심 포인트: /\*\*핵심 (?:포인트|개념):\*\*\n((?:- .+\n?)+)/g
Extracted data:
number: Chapter numbertitleKr: Korean title (excluding number)timestamp: Timestampsummary: Summary textkeyPoints: Core points array
8.3 Parsing the FULL_TRANSLATION section
<!-- FULL_TRANSLATION_START -->
## 전체 번역
### 1. 소개
**요약**: ChatGPT와 같은...
[0:00] 안녕하세요, 여러분...
[0:30] 이 영상을 통해...
### 2. 사전학습 데이터 - 인터넷
**요약**: LLM 사전학습의...
[1:00] 도구를 준비하고...
<!-- FULL_TRANSLATION_END -->
Parsing regex:
챕터 구분: /^### (\d+)\.\s*(.+?)$/gm
타임스탬프 라인: /^\[(\d+:\d+(?::\d+)?)\]\s*(.+)$/gm
Extracted data:
number: Chapter numberfullTranslation: Full translation text including timestamps
8.4 Matching chapter data
Match the data extracted from SUMMARY and FULL_TRANSLATION by chapter number:
interface ChapterData {
number: number;
titleKr: string; // SUMMARY에서
timestamp: string; // SUMMARY에서
summary: string; // SUMMARY에서
keyPoints: string[]; // SUMMARY에서
fullTranslation: string; // FULL_TRANSLATION에서
}
8.5 Creating per-chapter files
Create a file for each chapter:
Output path: docs/week{N}/{parentSlug}/kr/{childSlug}.md
Create directory: docs/week{N}/{parentSlug}/kr/ Create if the directory does not exist
File format:
---
title: "{N}. {English Title}"
titleKr: "{N}. {한국어 제목}"
chapter: {N}
timestamp: "{타임스탬프}"
sourceUrl: "{YouTube URL}&t={초}s"
translatedAt: "{YYYY-MM-DD}"
---
# {N}. {한국어 제목}
[영상 바로가기 ({타임스탬프})]({sourceUrl})
## 요약
{요약 텍스트}
**핵심 개념:**
{핵심 포인트 목록}
---
## 전체 번역
{타임스탬프 포함 번역 텍스트}
8.6 Handling existing files
파일이 이미 존재하는 경우:
--overwrite 옵션: 덮어쓰기
기본: 건너뜀 (⚠ 표시)
Step 9: Check chapter file creation results
Check the chapter file creation results:
On partial success:
✓ 챕터별 번역 파일 생성
- 20개 파일 생성
⚠ 4개 파일 건너뜀 (이미 존재):
- introduction.md
- tokenization.md
No full translation file:
⚠ 전체 번역 파일이 없습니다: docs/week1/kr/deep-dive-llms.md
챕터별 번역 파일 생성을 건너뜁니다.
readings.ts 업데이트만 완료합니다.
(children의 published: false, hasMarkdown: false)
다음 단계:
/translate-reading week1/deep-dive-llms 실행 후 다시 실행하세요.
Detailed chapter parsing rules
Table of Contents format
## Table of Contents
1. [Introduction](#1-introduction) (0:00)
2. [Pretraining Data (Internet)](#2-pretraining-data-internet) (1:00)
Regex:
/^(\d+)\.\s*\[(.+?)\]\(#.+?\)\s*\((\d+:\d+(?::\d+)?)\)/gm
Group:
- Number
- Title
- Timestamp
h2 section format
## 1. Introduction
**요약**: ChatGPT와 같은...
[0:00] hi everyone...
Regex:
/^## (\d+)\.\s*(.+?)$/gm
Error handling
| Situation | Handling |
|---|---|
| No source file | /fetch-reading Run instructions |
| Chapter structure parsing failed | Manual input instructions |
| No entry in readings.ts | First /upload-reading required |
| Already isParent=true | Confirm overwriting existing children |
| No full translation file | Print warning, update only readings.ts |
| No SUMMARY section | Print warning, skip file creation |
| Chapter count mismatch | Create only matching ones, show warning |
| Chapter file already exists | Default: skip / --overwrite: overwrite |
Step 10: Sync the public directory
Once chapter files are created, copy them to the public directory so they can be dynamically loaded on the web.
# 디렉토리 생성
mkdir -p public/readings/week{N}/{parentSlug}/
# 챕터 파일 복사
cp docs/week{N}/{parentSlug}/kr/*.md public/readings/week{N}/{parentSlug}/
Output example:
✓ public 디렉토리 동기화 완료
- 경로: public/readings/week1/deep-dive-llms/
- 파일: 24개
Step 11: Update the hasMarkdown flag
For all children in readings.ts, hasMarkdown: true와 published: trueset .
// Step 6에서 생성한 children 업데이트
children: [
{
slug: 'introduction',
title: '1. Introduction',
titleKr: '1. 소개',
sourceUrl: 'https://www.youtube.com/watch?v=...&t=0s',
published: true, // ← 변경
hasMarkdown: true, // ← 추가
},
// ...
]
Note: If chapter files were not created because there is no translation file, keep hasMarkdown: falseas is.
Step 12: Output final results
✓ YouTube 콘텐츠를 챕터별 하위페이지로 변환 완료
원본: week1/deep-dive-llms
챕터: 24개
readings.ts 업데이트:
- isParent: true 추가
- children: 24개 ChildReading 추가
- hasMarkdown: true (모든 children)
챕터별 번역 파일 생성:
✓ docs/week1/deep-dive-llms/kr/introduction.md
✓ docs/week1/deep-dive-llms/kr/pretraining-data.md
... (24개 파일)
public 디렉토리 동기화:
✓ public/readings/week1/deep-dive-llms/ (24개 파일)
다음 단계:
pnpm dev → /readings/week1/deep-dive-llms
Reference
- Use the same UI structure as prompt-engineering-guide
- Routing:
/readings/week{N}/{parentSlug}/{childSlug} - Provide navigation with the ReadingSidebar component
- Markdown dynamic loading:
fetch(/readings/week1/{slug}/{childSlug}.md)