import json import os import re # ========================================== # CONFIGURATION # ========================================== # Point this to your new flat JSON generated by split_syllabus.py INPUT_FILE = 'syllabus_flat.json' OUTPUT_DIR = 'syllabus_out' # Rename to 'syllabus' before pushing to GitHub # Load JSON Data with open(INPUT_FILE, 'r', encoding='utf-8') as f: flat_data = json.load(f) os.makedirs(OUTPUT_DIR, exist_ok=True) # ========================================== # RESTRUCTURE FLAT JSON TO GROUPED DICTIONARY # ========================================== # Converts flat array into: { "Branch": { "S1": [subjects], "S2": [subjects] } } data = {} for item in flat_data: branch = item['branch'] sem = item['semester'] if branch not in data: data[branch] = {} if sem not in data[branch]: data[branch][sem] = [] data[branch][sem].append(item) # ========================================== # HELPER FUNCTIONS & SORTING # ========================================== def slugify(text): text = text.lower() text = re.sub(r'[^a-z0-9]+', '-', text) return text.strip('-') def clean_name(name): return re.sub(r'\s*-\s*\(.*?\)', '', name).strip() def get_branch_acronym(branch_name): b = branch_name.upper() if 'COMPUTER' in b: return 'CSE' if 'MECHANICAL' in b: return 'ME' if 'CIVIL' in b: return 'CE' if 'ELECTRICAL AND ELECTRONICS' in b: return 'EEE' if 'ELECTRONICS AND COMMUNICATION' in b: return 'ECE' if 'INFORMATION TECHNOLOGY' in b: return 'IT' return "".join([word[0] for word in branch_name.split() if word.isalpha()]) def get_branch_priority(branch_name): b = branch_name.upper() if 'COMPUTER' in b: return 1 # CSE First if 'CIVIL' in b: return 2 # Civil Second if 'MECHANICAL' in b: return 3 if 'ELECTRICAL AND ELECTRONICS' in b: return 4 if 'ELECTRONICS AND COMMUNICATION' in b: return 5 return 99 def get_branch_theme(branch_name): b = branch_name.upper() if 'COMPUTER' in b: return ('indigo', 'fa-laptop-code') if 'CIVIL' in b: return ('emerald', 'fa-building') if 'MECHANICAL' in b: return ('orange', 'fa-cogs') if 'ELECTRICAL AND ELECTRONICS' in b: return ('amber', 'fa-bolt') if 'ELECTRONICS AND COMMUNICATION' in b: return ('purple', 'fa-microchip') return ('blue', 'fa-graduation-cap') # ========================================== # HTML TEMPLATES # ========================================== def get_header(title, desc): return f""" {title}
""" def get_footer(): return f"""
""" # ========================================== # 1. GENERATE MAIN HUB (index.html) # ========================================== sorted_branches = sorted(data.keys(), key=lambda x: (get_branch_priority(x), x)) main_html = get_header("KTU B.Tech Syllabus 2024 Scheme | All Branches", "Download official KTU B.Tech syllabus PDFs for the 2024 scheme.") main_html += """
Official Curriculum

B.Tech Syllabus 2024

Select your engineering branch below to access beautifully organized, semester-wise syllabus PDFs.

""" for branch in sorted_branches: branch_slug = slugify(branch) branch_acronym = get_branch_acronym(branch) color, icon = get_branch_theme(branch) main_html += f"""
B.TECH

{branch_acronym}

{branch}

""" main_html += "
" + get_footer() with open(os.path.join(OUTPUT_DIR, 'index.html'), 'w', encoding='utf-8') as f: f.write(main_html) # ========================================== # 2. GENERATE BRANCH & SEMESTER PAGES # ========================================== for branch in sorted_branches: all_sems = data[branch] branch_slug = slugify(branch) branch_dir = os.path.join(OUTPUT_DIR, branch_slug) os.makedirs(branch_dir, exist_ok=True) branch_acronym = get_branch_acronym(branch) color, icon = get_branch_theme(branch) def get_sem_num(sem_str): m = re.search(r'\d+', sem_str) return int(m.group()) if m else 99 sorted_sem_keys = sorted(all_sems.keys(), key=get_sem_num) branch_html = get_header(f"KTU B.Tech {branch_acronym} Syllabus 2024 Scheme", f"Download complete KTU B.Tech {branch_acronym} syllabus PDFs for the 2024 scheme. All semesters available.") branch_html += f"""
Hub {branch_acronym}

KTU {branch_acronym} Syllabus

B.Tech 2024 Scheme • {branch}

""" for semester in sorted_sem_keys: subjects_list = all_sems[semester] sem_slug = slugify(semester) short_sem = semester.replace('Semester ', 'S') sub_count = len(subjects_list) branch_html += f"""
{short_sem}

{short_sem}

{sub_count} Subjects

""" sem_page_title = f"KTU B.Tech {short_sem} {branch_acronym} Syllabus 2024 Scheme" sem_page_desc = f"Download individual subject syllabus PDFs for KTU B.Tech {short_sem} {branch_acronym} (2024 Scheme)." sem_html = get_header(sem_page_title, sem_page_desc) sem_html += f"""
Hub {branch_acronym} {short_sem}
{short_sem}

{branch_acronym} Syllabus

2024 Scheme • {sub_count} Subjects Available

""" for subject in subjects_list: # Re-mapped to the new JSON keys sub_name = clean_name(subject.get('subject_name', 'Unknown Subject')) sub_code = subject.get('course_code', 'KTU') # Make sure we map the path correctly assuming your site structure sub_link = "/" + subject.get('pdf_file', '#') if sub_link == '/#': btn_classes = "w-full bg-slate-100 text-slate-400 cursor-not-allowed font-bold text-sm px-4 py-2.5 rounded-xl flex items-center justify-center gap-2 border border-slate-200" btn_text = "Link Unavailable" target = "" else: btn_classes = f"w-full bg-slate-50 hover:bg-{color}-600 text-slate-600 hover:text-white border border-slate-200 hover:border-{color}-600 font-bold text-sm px-4 py-2.5 rounded-xl flex items-center justify-center gap-2 transition-all shadow-sm hover:shadow-lg hover:shadow-{color}-500/20" btn_text = "Download PDF" target = 'target="_blank"' sem_html += f"""
{short_sem}
B.TECH {short_sem} {sub_code}

{sub_name}

{btn_text}
""" sem_html += "
" + get_footer() with open(os.path.join(branch_dir, f"{sem_slug}.html"), 'w', encoding='utf-8') as f: f.write(sem_html) branch_html += "
" + get_footer() with open(os.path.join(branch_dir, 'index.html'), 'w', encoding='utf-8') as f: f.write(branch_html) print("✅ SUCCESS! The compact, Auto-Sorted UI Syllabus site is generated in the 'syllabus_out' folder.")