math-hwpx
수학 수식 문제지 HWPX 생성 (중1~고3, 학력평가/수능 형식)
Source facts
- Repository
- Canine89/hwpxskill-math
- Last source activity
- February 23, 2026 at 14:24
- Detected SKILL.md language
- Korean
- Stars
- 6
- Forks
- 1
Install options
The review-first prompt is selected by default. You can switch to a direct command or download a local copy.
Review the source files
Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.
Showing SKILL.md
SKILL.md
Source instructions · Read-only preview- name
- math-hwpx
- description
- 수학 수식 문제지 HWPX 생성 (중1~고3, 학력평가/수능 형식)
# math-hwpx — 수학 수식 문제지 HWPX 생성 스킬
수학 수식(`hp:equation`)을 포함한 **2열 문제지**를 HWPX 파일로 생성하는 스킬.
중학교 1학년 ~ 고등학교 3학년 범위의 수학 문제를 한컴오피스 수식 편집기 스크립트 문법으로 작성한다.
hwpx 스킬과 동일한 XML-first 워크플로우를 따르며, 기존 hwpx 스킬의 빌드/검증 도구와 호환된다.
**두 가지 형식 지원:**
- **exam** (기본값, 학력평가/수능): 전국연합학력평가/수능 형식 시험지 (헤더, 가로 선택지, 배점, 페이지 번호 등)
- **worksheet** (`--exam-type worksheet` 명시 필요): 단순 2열 수학 문제지
## 환경
```
# SKILL_DIR는 이 SKILL.md가 위치한 디렉토리의 절대 경로로 설정
SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)" # 스크립트 내에서
# hwpx 기본 스킬 경로 (검증/추출 도구 사용 시)
HWPX_SKILL_DIR="<hwpx 스킬 설치 경로>"
# Python 가상환경 (프로젝트에 맞게 설정)
VENV="<프로젝트>/.venv/bin/activate"
```
모든 Python 실행 시:
```bash
# 프로젝트의 .venv를 활성화 (pip install lxml 필요)
source "$VENV"
```
## 디렉토리 구조
```
.claude/skills/math-hwpx/
├── SKILL.md # 이 파일
├── scripts/
│ ├── build_math_hwpx.py # CLI + build 오케스트레이션 (~170줄)
│ ├── xml_primitives.py # IDGen, STYLE 상수, 기본 문단/수식 생성기
│ ├── exam_helpers.py # 시험지 전용 XML 생성기 (배점, 선택지, 이미지)
│ ├── table_layout.py # 투명 테이블 2×2 레이아웃 로직
│ ├── section_generators.py # worksheet/exam section0.xml 조립
│ ├── hwpx_utils.py # 검증/패키징/메타데이터
│ ├── graph_generator.py # 그래프 PNG 생성 (matplotlib)
│ └── test_refactor.py # 리그레션 테스트 스크립트
├── templates/
│ ├── base/ # 2단 레이아웃 기본 템플릿
│ │ ├── mimetype, META-INF/*, version.xml, settings.xml, Preview/*
│ │ └── Contents/ (header.xml, section0.xml, content.hpf)
│ └── worksheet/ # (확장용) 오버레이 템플릿
├── examples/
│ ├── sample_middle_school.json # 중학교 문제 예시
│ ├── sample_high_school.json # 고등학교 문제 예시
│ ├── sample_exam_2020_march.json # 학력평가 형식 예시
│ ├── 01_middle_school_worksheet.sh # 빌드 예제
│ ├── 02_high_school_worksheet.sh # 빌드 예제
│ └── 03_exam_paper.sh # 학력평가 시험지 빌드 예제
└── references/ # 리그레션 테스트 레퍼런스 XML
```
### 모듈 의존 구조
```
build_math_hwpx.py (CLI + build 오케스트레이션)
├── hwpx_utils.py (validate_xml, pack_hwpx, validate_hwpx, update_metadata, _add_images_to_manifest)
├── section_generators.py (generate_worksheet_section_xml, generate_exam_section_xml)
│ ├── table_layout.py (_make_problem_cell_content, make_problem_table)
│ │ ├── xml_primitives.py (IDGen, STYLE, make_*_para, _make_equation_run)
│ │ └── exam_helpers.py (make_exam_problem_para, make_picture_para)
│ └── xml_primitives.py
└── graph_generator.py (변경 없음)
```
의존 방향: `primitives → helpers → table → section → build` (순환 없음)
---
## 핵심 워크플로우: JSON → HWPX 문제지
### 1. 문제 JSON 작성
**반드시 아래 형식을 따를 것. `exam_type`, `year`, `month`, `grade`, `points`, `choices` 등 학력평가 필드를 포함해야 한다.**
```json
{
"exam_type": "학력평가",
"year": 2025,
"month": 3,
"grade": "중2",
"session": 2,
"subject_area": "수학",
"total_pages": 4,
"question_type_label": "5지선다형",
"problems": [
{
"text": "의 값은?",
"equation": "2x + 3 = 7",
"points": 4,
"choices": ["1", "2", "3", "4", "5"]
},
{
"text": "을 간단히 한 것은?",
"equation": "sqrt 12 + sqrt 27",
"points": 5,
"choices": ["$3 sqrt 3$", "$4 sqrt 3$", "$5 sqrt 3$", "$6 sqrt 3$", "$7 sqrt 3$"]
},
{
"text": "다음 중 옳은 것은?",
"points": 4,
"choices": ["$sqrt 4 = 2$", "$sqrt 9 = +- 3$", "$(-2)^2 = -4$", "$sqrt {16} = 4$", "$sqrt 25 = -5$"]
},
{
"section_label": "주관식",
"text": "을 인수분해하시오.",
"equation": "x^2 - 5x + 6",
"points": 5
}
]
}
```
### 2. 빌드
```bash
source "$VENV"
# 학력평가 형식 (기본값 — exam_type 지정 불필요)
python3 "$SKILL_DIR/scripts/build_math_hwpx.py" \
--problems problems.json \
--creator "수학교사" \
--output exam.hwpx
# 단순 worksheet 형식 (명시적 지정 필요)
python3 "$SKILL_DIR/scripts/build_math_hwpx.py" \
--problems problems.json \
--exam-type worksheet \
--title "중2 일차방정식" \
--output worksheet.hwpx
```
### 3. 검증 (hwpx 스킬의 validate.py 사용)
```bash
python3 "$HWPX_SKILL_DIR/scripts/validate.py" worksheet.hwpx
```
---
## 문제 JSON 형식 (학력평가 — 기본값)
**중요: 모든 문제 JSON은 반드시 학력평가 형식으로 작성한다. title/subtitle/info는 사용하지 않는다.**
```json
{
"exam_type": "학력평가",
"year": 2025,
"month": 3,
"grade": "중3",
"session": 2,
"subject_area": "수학",
"total_pages": 4,
"question_type_label": "5지선다형",
"problems": [
{
"text": "문제 본문 (수식 앞뒤 텍스트)",
"equation": "한컴 수식 스크립트",
"points": 4,
"choices": ["선택지1", "$수식선택지$", "선택지3", "선택지4", "선택지5"]
},
{
"text": "소문제가 있는 경우",
"equation": "메인 수식",
"points": 5,
"sub_problems": [
{"equation": "소문제 수식"}
],
"choices": ["1", "2", "3", "4", "5"]
},
{
"section_label": "주관식",
"text": "을 인수분해하시오.",
"equation": "x^2 - 5x + 6",
"points": 5
}
]
}
```
### 필드 설명
| 필드 | 필수 | 설명 |
|------|------|------|
| `exam_type` | **O** | **반드시 `"학력평가"` 지정** |
| `year` | O | 학년도 (예: 2025) |
| `month` | O | 시행 월 (예: 3, 6, 9, 11) |
| `grade` | O | 학년 (예: "중1", "중2", "중3", "고1", "고2", "고3") |
| `session` | X | 교시 (기본: 2) |
| `subject_area` | X | 과목 영역 (기본: "수학") |
| `total_pages` | X | 총 페이지 (기본: 문제 수에 따라 자동) |
| `question_type_label` | X | 문항유형 라벨 (기본: "5지선다형") |
| `problems` | O | 문제 배열 |
| `problems[].text` | X | 문제 텍스트 |
| `problems[].equation` | X | 독립 수식 (display 모드) |
| `problems[].points` | **O** | **배점 (정수, `[N점]` 형태로 표시)** |
| `problems[].choices` | X | 객관식 5지선다 (`$...$`로 감싸면 수식) |
| `problems[].sub_problems` | X | 소문제 배열 [{text, equation}] |
| `problems[].section_label` | X | 섹션 구분 라벨 (예: "주관식") |
---
## 한컴 수식 스크립트 문법 (hp:equation)
### 기본 규칙
| 규칙 | 설명 |
|------|------|
| `{ }` | 그룹화 (여러 항을 하나로) |
| `~` | 공백 (1em) |
| `` ` `` | 1/4 공백 |
| `#` | 줄바꿈 (수식 내) |
| `&` | 열 정렬 (행렬, 연립방정식) |
| `"..."` | 텍스트 모드 (수식 해석 비활성) |
### 분수와 루트
| 수식 | 스크립트 | 예시 |
|------|----------|------|
| 분수 | `a over b` | `{x+1} over {x-1}` |
| 제곱근 | `sqrt {x}` | `sqrt {b^2 - 4ac}` |
| n제곱근 | `root n of {x}` | `root 3 of {27}` |
### 위·아래 첨자
| 수식 | 스크립트 |
|------|----------|
| 위첨자 | `x^2` 또는 `x SUP 2` |
| 아래첨자 | `x_i` 또는 `x SUB i` |
| 둘 다 | `x_i ^2` |
### 적분·합·곱
| 수식 | 스크립트 |
|------|----------|
| 정적분 | `int _{a} ^{b} f(x) dx` |
| 이중적분 | `dint f(x,y) dxdy` |
| 삼중적분 | `tint f dxdydz` |
| 급수(시그마) | `sum _{k=1} ^{n} a_k` |
| 곱(파이) | `prod _{i=1} ^{n} x_i` |
### 극한
| 수식 | 스크립트 |
|------|----------|
| 극한 | `lim _{x -> 0} f(x)` |
| 대문자 | `Lim _{n -> inf}` |
### 괄호
| 수식 | 스크립트 |
|------|----------|
| 자동 크기 소괄호 | `left ( {a over b} right )` |
| 자동 크기 대괄호 | `left [ x right ]` |
| 자동 크기 중괄호 | `left lbrace x right rbrace` |
| 절댓값 | `left | x right |` |
### 행렬
| 수식 | 스크립트 |
|------|----------|
| 기본 행렬 | `matrix {a & b # c & d}` |
| 소괄호 행렬 | `pmatrix {a & b # c & d}` |
| 대괄호 행렬 | `bmatrix {1 & 0 # 0 & 1}` |
| 행렬식 | `dmatrix {a & b # c & d}` |
### 연립방정식·조건
| 수식 | 스크립트 |
|------|----------|
| 연립방정식 | `cases {2x+y=5 # 3x-2y=4}` |
| 정렬 수식 | `eqalign {a &= b # c &= d}` |
| 수직 스택 | `pile {a # b # c}` |
### 장식(위·아래)
| 장식 | 스크립트 |
|------|----------|
| 모자(^) | `hat a` |
| 물결 | `tilde a` |
| 벡터 화살표 | `vec v` |
| 윗줄 | `bar x` |
| 밑줄 | `under x` |
| 점 1개 | `dot a` |
| 점 2개 | `ddot a` |
### 그리스 문자
View on GitHubThis SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub