feat: add interactive MCQ and code-sort exercise widgets to tutorial lessons
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
31
src/oj/learn/composables/useExerciseParse.ts
Normal file
31
src/oj/learn/composables/useExerciseParse.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Exercise } from "utils/types"
|
||||
|
||||
type Segment =
|
||||
| { type: "md"; content: string }
|
||||
| { type: "exercise"; exercise: Exercise }
|
||||
|
||||
export function parseExercises(content: string, exercises: Exercise[]): Segment[] {
|
||||
const exerciseMap = new Map(exercises.map((e) => [e.id, e]))
|
||||
const segments: Segment[] = []
|
||||
const regex = /\[\[exercise:(\d+)\]\]/g
|
||||
let lastIndex = 0
|
||||
let match: RegExpExecArray | null
|
||||
|
||||
while ((match = regex.exec(content)) !== null) {
|
||||
if (match.index > lastIndex) {
|
||||
segments.push({ type: "md", content: content.slice(lastIndex, match.index) })
|
||||
}
|
||||
const id = parseInt(match[1])
|
||||
const exercise = exerciseMap.get(id)
|
||||
if (exercise) {
|
||||
segments.push({ type: "exercise", exercise })
|
||||
}
|
||||
lastIndex = regex.lastIndex
|
||||
}
|
||||
|
||||
if (lastIndex < content.length) {
|
||||
segments.push({ type: "md", content: content.slice(lastIndex) })
|
||||
}
|
||||
|
||||
return segments
|
||||
}
|
||||
Reference in New Issue
Block a user