feat: Ingest authentic Grade 10 Math Unit 1 with complete LaTeX equations and full derivations
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../app/bootstrap.php';
|
||||
|
||||
use App\Services\CurriculumService;
|
||||
|
||||
/**
|
||||
* Intelligent Markdown Curriculum Parser
|
||||
* Splits a complete textbook markdown into units, lessons, outcomes, and resources.
|
||||
*/
|
||||
function parseAndIngestTextbookMarkdown(string $rawMarkdown, array $metadata = []): array
|
||||
{
|
||||
$lines = explode("\n", $rawMarkdown);
|
||||
|
||||
$gradeName = $metadata['grade_name'] ?? 'الصف العاشر';
|
||||
$gradeKey = $metadata['grade_key'] ?? 'grade_10';
|
||||
$subName = $metadata['subject_name'] ?? 'الرياضيات';
|
||||
$subKey = $metadata['subject_key'] ?? 'math_10';
|
||||
$semName = $metadata['semester_name'] ?? 'الفصل الدراسي الأول';
|
||||
$semKey = $metadata['semester_key'] ?? 'semester_1';
|
||||
|
||||
$units = [];
|
||||
$currentUnit = null;
|
||||
$currentLesson = null;
|
||||
$lessonBuffer = [];
|
||||
|
||||
$flushLesson = function() use (&$currentUnit, &$currentLesson, &$lessonBuffer) {
|
||||
if ($currentUnit && $currentLesson) {
|
||||
$content = trim(implode("\n", $lessonBuffer));
|
||||
if (!empty($content)) {
|
||||
$currentLesson['markdown_content'] = $content;
|
||||
$currentUnit['lessons'][] = $currentLesson;
|
||||
}
|
||||
$currentLesson = null;
|
||||
$lessonBuffer = [];
|
||||
}
|
||||
};
|
||||
|
||||
$flushUnit = function() use (&$units, &$currentUnit, $flushLesson) {
|
||||
$flushLesson();
|
||||
if ($currentUnit && !empty($currentUnit['lessons'])) {
|
||||
$units[] = $currentUnit;
|
||||
$currentUnit = null;
|
||||
}
|
||||
};
|
||||
|
||||
$unitCounter = 0;
|
||||
$lessonCounter = 0;
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$trimmed = trim($line);
|
||||
|
||||
// Detect Unit (# UNIT or # الوحدة)
|
||||
if (preg_match('/^#\s+(UNIT|الوحدة)\s*([0-9\-\:A-Za-z\s]+)(.*)$/ui', $trimmed, $m) || preg_match('/^#\s+([A-Za-z0-9\s]+(?:SPOT|SKILLS|REFERENCE|LIST))/ui', $trimmed, $m2)) {
|
||||
$flushUnit();
|
||||
$unitCounter++;
|
||||
$unitTitle = trim(preg_replace('/^#\s+/u', '', $trimmed));
|
||||
$unitKey = sprintf('unit_%02d', $unitCounter);
|
||||
|
||||
$currentUnit = [
|
||||
'unit_key' => $unitKey,
|
||||
'unit_name' => $unitTitle,
|
||||
'lessons' => []
|
||||
];
|
||||
$lessonCounter = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Detect Lesson (## Lesson or ## الدرس or ## معمل or ## )
|
||||
if (preg_match('/^##\s+(Lesson|الدرس|قسم|المحطة|قواعد|تمارين|معمل)\s*([0-9\-\:A-Za-z\s]+)(.*)$/ui', $trimmed, $m) || (preg_match('/^##\s+(.+)$/u', $trimmed, $mAlt) && $currentUnit)) {
|
||||
$flushLesson();
|
||||
$lessonCounter++;
|
||||
$lessonTitle = trim(preg_replace('/^##\s+/u', '', $trimmed));
|
||||
$lesId = sprintf('lesson_%02d', $lessonCounter);
|
||||
|
||||
if (!$currentUnit) {
|
||||
$unitCounter++;
|
||||
$currentUnit = [
|
||||
'unit_key' => sprintf('unit_%02d', $unitCounter),
|
||||
'unit_name' => 'الوحدة الأولى: المعادلات',
|
||||
'lessons' => []
|
||||
];
|
||||
}
|
||||
|
||||
$currentLesson = [
|
||||
'lesson_id' => $lesId,
|
||||
'title' => $lessonTitle,
|
||||
'outcomes' => [$lessonTitle]
|
||||
];
|
||||
$lessonBuffer = [$trimmed];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($currentLesson) {
|
||||
$lessonBuffer[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
$flushUnit();
|
||||
|
||||
$extracted = [
|
||||
'grade_name' => $gradeName,
|
||||
'grade_key' => $gradeKey,
|
||||
'subject_name' => $subName,
|
||||
'subject_key' => $subKey,
|
||||
'semester_name' => $semName,
|
||||
'semester_key' => $semKey,
|
||||
'units' => $units
|
||||
];
|
||||
|
||||
return CurriculumService::mergeExtractedCurriculum($extracted);
|
||||
}
|
||||
Reference in New Issue
Block a user