catalog-extractor
Automates the parsing, normalization, and validation of Technion PDF course catalogs into JSON.
Install
mkdir -p .claude/skills/catalog-extractor && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10674" && unzip -o skill.zip -d .claude/skills/catalog-extractor && rm skill.zipInstalls to .claude/skills/catalog-extractor
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Extract academic degree catalogs from Technion PDF course catalogs into structured JSON. Use when asked to extract, parse, or convert a Technion catalog PDF into JSON format.Key capabilities
- →Extract text from Technion PDF course catalogs
- →Parse extracted text into catalog sections
- →Normalize course IDs and bank names
- →Build skeleton catalog JSON from parsed sections
- →Validate JSON against an expected schema
- →Cross-validate catalog JSON against the source PDF
How it works
The skill uses Python scripts to extract text from a Technion PDF, parse it into sections, normalize data, and build a JSON catalog, which is then validated against a schema and the source PDF.
Inputs & outputs
When to use catalog-extractor
- →Extract course data from PDF catalogs
- →Normalize course ID and credit information
- →Build JSON course skeletons from raw text
- →Cross-validate generated JSON against source PDFs
About this skill
Technion Catalog JSON Extractor
Extract academic degree catalogs from Technion PDF course catalogs into structured JSON format for the Sogrim degree-completion checker.
Python Scripts
IMPORTANT: This skill uses pre-built Python scripts in packages/catalog-extractor/. Do NOT recreate these scripts from scratch — use and improve them instead.
Setup (one-time)
cd packages/catalog-extractor
pip install -r requirements.txt
Available scripts
| Script | Purpose |
|---|---|
extract_pdf.py | Downloads PDF (from URL or local path) and extracts text page-by-page |
parse_sections.py | Splits extracted text into catalog sections by detecting bank headers |
normalize.py | Utility: course ID padding, bank name detection, rule mappings |
build_catalog.py | Builds skeleton catalog JSON from parsed sections |
validate_catalog.py | Validates final JSON against expected schema |
validate_against_pdf.py | Cross-validates a catalog JSON against the source PDF — checks courses, credits, banks, chains, overflows |
main.py | All-in-one pipeline combining all steps |
Quick pipeline
cd packages/catalog-extractor
python main.py <pdf_url_or_path> --name "Hebrew catalog name" --reference ../docs/ComputerScience3years2024-2025.json --output ../docs/NewCatalog.json --save-text raw_text.txt --save-sections sections.json
Workflow
- Install dependencies: Run
pip install -r packages/catalog-extractor/requirements.txtif not already installed. - Extract text: Run
python packages/catalog-extractor/extract_pdf.py <pdf_url_or_path> --output raw_text.txtto get the raw PDF text. - Review raw text: Read the extracted text to understand the PDF structure and identify which program/track to extract.
- Ask which program/track: Present the user with the available programs found in the PDF and ask which one to extract.
- Parse and build skeleton: Run the pipeline or manually use
parse_sections.py+build_catalog.pyto get a skeleton JSON. - Refine the JSON: The skeleton will have TODOs. Using the raw text and your understanding of the catalog, fill in:
total_credit— from the PDF's total credit summarydescription— Hebrew description of the program- Bank
creditvalues — from each section's credit requirements credit_overflows— based on the track type (see patterns below)- Complex rules:
Chainsfor שרשרת מדעית,SpecializationGroupsfor קבוצות התמחות catalog_replacements— from replacement notes in the PDF
- Validate schema: Run
python packages/catalog-extractor/validate_catalog.py <output.json> - Cross-validate against PDF: Run
python packages/catalog-extractor/validate_against_pdf.py <output.json> <pdf_url> --verboseto compare courses, credits, banks, chains, and overflows against the source PDF. Fix any ERRORs before proceeding. - Output JSON: Save to
packages/docs/{Faculty}{Track}{Year}.json
Improving the scripts
If the PDF format has changed or the scripts miss something, update the scripts in packages/catalog-extractor/ rather than writing one-off code. This keeps the tooling reusable for future catalogs.
JSON Schema
The output JSON must follow this exact structure:
{
"_id": { "$oid": "" },
"name": "<Hebrew name, e.g., מדמח ארבע שנתי 2024-2025>",
"total_credit": <number>,
"description": "<Hebrew description of the program>",
"course_banks": [ ... ],
"credit_overflows": [ ... ],
"course_to_bank": { ... },
"catalog_replacements": { ... },
"common_replacements": { ... },
"faculty": "<FacultyName>"
}
Field Details
_id
Always {"$oid": ""} for new catalogs (MongoDB will assign on insert).
name
Hebrew name of the catalog. Pattern: "מדמח <track-type> <year-range>".
- 3-year:
"מדמח תלת שנתי 2024-2025" - 4-year:
"מדמח ארבע שנתי 2024-2025"
total_credit
Total credit points required for degree completion. Found in the PDF under "סה"כ נ.ז" or similar.
course_banks
Array of course bank objects. Each bank represents a category of courses:
{
"name": "<Hebrew bank name>",
"rule": "<rule type>",
"credit": <number or null>
}
Common banks and their rules (not all faculties use all banks — read the PDF):
| Bank Name (Hebrew) | Rule | Notes |
|---|---|---|
| חובה | "All" | Mandatory courses - all must be completed |
| שרשרת מדעית | {"Chains": [[...], ...]} | Scientific chain - pick one chain (CS only, not in EE) |
| מתמטי נוסף | {"AccumulateCourses": {"$numberLong": "1"}} | Additional math - accumulate N courses (CS only) |
| רשימה א | "AccumulateCredit" | List A electives (CS) |
| רשימה ב | "AccumulateCredit" | List B electives (CS) |
| ליבה | {"AccumulateCourses": {"$numberLong": "N"}} | Core electives - pick N courses from list |
| קבוצות התמחות | {"SpecializationGroups": {...}} | Specialization groups |
| בחירה פקולטית | "AccumulateCredit" | Faculty electives (EE, CompEng) — often receives overflow from קבוצות התמחות |
| פרויקט | {"AccumulateCourses": {"$numberLong": "N"}} | Project — see Projects section for credit rules |
| סמינר | {"AccumulateCourses": {"$numberLong": "1"}} | Seminar, credit is null |
| בחירת העשרה | "Malag" | Enrichment electives (CS) |
| חינוך גופני | "Sport" | Physical education (CS) |
| בחירה חופשית | "Elective" | Free electives (CS) |
IMPORTANT: The three university-wide banks (בחירת העשרה, חינוך גופני, בחירה חופשית) are standard across ALL Technion faculties — always use these 3 separate banks. Some PDFs group them under "בחירה כלל-טכניונית" as a combined label, but they must be modeled as 3 separate banks with the Malag/Sport/Elective rules. The typical split is: 6 Malag + 2 Sport + 4 Free = 12 total.
Chains rule structure (for שרשרת מדעית):
{
"Chains": [
["01140075"],
["01140052", "01140054"],
["01340058", "01340020"],
["01240120", "01250801"],
["01240120", "01240510"],
["01240120", "01140052"]
]
}
Each inner array is one valid chain. The student must complete one full chain.
SpecializationGroups rule structure (for קבוצות התמחות, 4-year only):
{
"SpecializationGroups": {
"groups_list": [
{
"name": "סיבוכיות של חישובים",
"courses_sum": {"$numberLong": "3"},
"course_list": ["02360306", "02360309", "02360313"],
"mandatory": [["02360313"]]
}
],
"groups_number": {"$numberLong": "3"},
"groups_type": "Double"
}
}
All course IDs in specialization groups must also be 8-digit zero-padded.
groups_type (optional; omit to get the default "Regular" — never write "Regular" explicitly):
"Regular"(default) — a mandatory course shared between groups satisfies the mandatory requirement of every group it appears in; credit/course-count is still attributed to a single group. Use for most tracks."Double"— Regular semantics, and a group carrying adoublespec (below) may count as two groups.{"MandatoryNotShared": ["<id>", ...]}— a mandatory course satisfies at most one group, so distinct mandatory courses are required (e.g. biotech מגמות). The array is the pool of all mandatory courses.
double (optional per-group; only honored when groups_type is "Double"): add it when a group can be
completed as a "double" (PDF: "קבוצה בודדת/כפולה"). A double needs more courses and a stricter mandatory
selection, and counts as two groups. "X and two of {list}" is encoded by repeating the list sublist —
each mandatory sublist must be satisfied by a distinct course:
{
"name": "תקשורת ואינפורמציה",
"courses_sum": {"$numberLong": "3"},
"course_list": ["00460206", "00460205", "02360309"],
"mandatory": [["00460206"], ["00460205", "02360309", "00460204"]],
"double": {
"courses_sum": {"$numberLong": "6"},
"mandatory": [["00460206"], ["00460205", "02360309", "00460204"], ["00460205", "02360309", "00460204"]]
}
}
PDF cues: "קבוצה בודדת תמנה N מקצועות; קבוצה כפולה תמנה M מקצועות" gives single/double courses_sum
(M is not always 2N — e.g. 4→7); "המקצועות המחייבים לקבוצה כפולה" gives the double mandatory. If a track
states a double does not satisfy the requirement (e.g. הנדסת חשמל ומתמטיקה), keep groups_type "Regular"
and omit double.
credit_overflows
Defines how excess credits overflow between banks:
[
{"from": "חובה", "to": "רשימה ב"},
{"from": "רשימה א", "to": "רשימה ב"},
...
]
Overflow patterns vary by faculty and track. The general principle: excess credits flow from more-specific banks to less-specific ones, ending at the broadest elective bank.
Example overflow patterns (CS faculty):
- CS 3-year: חובה→רשימה ב, רשימה א→רשימה ב, פרויקט→רשימה א, שרשרת מדעית→רשימה ב, מתמטי נוסף→רשימה ב, רשימה ב→בחירה חופשית, בחירת העשרה→בחירה חופשית, חינוך גופני→בחירה חופשית
- CS 4-year: Same as above plus: פרויקט→סמינר, סמינר→רשימה א, קבוצות התמחות→רשימה א
- Computer Engineering: חובה→בחירה פקולטית, ליבה→בחירה פקולטית, קבוצות התמחות→בחירה פקולטית, פרויקט→בחירה פקולטית, בחירה פקולטית→בחירה חופשית, בחירת העשרה→בחירה חופשית, חינוך גופני→בחירה חופשית
Example overflow patterns (EE faculty):
- EE main: חובה→בחירה פקולטית, קבוצות התמחות→בחירה פקולטית, בחירה פקולטית→בחירה חופשית, בחירת העשרה→בחירה חופשית, חינוך גופני→בחירה חופשית
- EE Computer & Software Eng: חובה→בחירה פקולטית, ליבה→בחירה פקולטית, קבוצות התמחות→בחירה פקולטית, בחירה פקולטית→בחירה חופשית, בחירת העשרה→בחירה חופשית, חינוך גופני→בחירה חופשית
Always derive overflows from the PDF's credit breakdown. Credits flow from specific → general.
course_to_bank
Maps every course ID to its bank name:
{
"02340114": "חובה",
"02360306": "רשימה א",
"01140075": "שרשרת מדעית",
...
}
CRITICAL: Course ID format — Use 8-digit zero-padded course IDs (e.g., "02340114" not "234114"). This is th
Content truncated.
When not to use it
- →When extracting catalogs from non-Technion PDFs
- →When the output format is not structured JSON
Prerequisites
Limitations
- →The script currently targets the SE (Software Engineering) track using the 159.5-credit anchor.
- →To validate other tracks: Update extract_se_section() to find the correct track anchor
- →Adjust extract_chova_courses() and extract_liba_courses() for that track's structure
How it compares
This skill automates the extraction and structuring of Technion PDF catalog data into JSON, whereas a manual approach would involve tedious data entry and validation.
Compared to similar skills
catalog-extractor side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| catalog-extractor (this skill) | 0 | 28d | Review | Intermediate |
| biorxiv-database | 7 | 9mo | Review | Beginner |
| office-docs | 1 | 6mo | Review | Beginner |
| shinka-inspect | 0 | 5mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
biorxiv-database
lifangda
Efficient database search tool for bioRxiv preprint server. Use this skill when searching for life sciences preprints by keywords, authors, date ranges, or categories, retrieving paper metadata, downloading PDFs, or conducting literature reviews.
office-docs
Xxiii8322766509
Extract text and tables from .docx and .xlsx using local scripts (no external deps).
shinka-inspect
SakanaAI
Load top-performing Shinka programs into agent context using `shinka.utils.load_programs_to_df`, and emit a compact Markdown bundle for iteration planning.
local-deep-research-guide
wentorai
Deep research agent searching 10+ sources with local or cloud LLMs
document-pro
bighardperson
文档处理技能 - 让 AI 能够读取、解析、提取 PDF、DOCX、PPT 等文档的关键信息。当用户要求分析文档、提取内容、总结报告时触发此技能。
quant-analyst
zenobi-us
Expert quantitative analyst specializing in financial modeling, algorithmic trading, and risk analytics. Masters statistical methods, derivatives pricing, and high-frequency trading with focus on mathematical rigor, performance optimization, and profitable strategy development.