from hwpapi.context import charshape_scope
with charshape_scope(app, bold=True, size=14, color="#C0392B"):
app.doc.insert_text("제목\n")
app.doc.insert_text("여전히 굵은 빨강\n")
# 커서 스타일 복원됨Context scopes
charshape_scope, parashape_scope, styled_text
왜 scope 인가
HWP 스크립팅에는 반복되는 세 가지 패턴이 있습니다.
- “같은 스타일을 공유하는 몇 줄을 삽입한 뒤, 원래 커서 스타일로 계속 진행한다.”
- “다음 블록만 문단 단위 프로퍼티(정렬, 줄 간격)를 바꾸고 복원한다.”
- “한 문장 안에 스타일이 적용된 짧은 구절을 끼워 넣는다.”
v1 은 이를 App.charshape_scope(...), App.parashape_scope(...), App.styled_text(...) 로 처리했습니다. v2 는 이 셋을 모두 App 에서 빼서 모듈 레벨에 두었기 때문에 어떤 App 인스턴스에 대해서도 균일하게 동작합니다.
from hwpapi.context import charshape_scope, parashape_scope, styled_text결정 트리
한 줄에 살짝 변경? → styled_text(app, "…", …)
char 서식을 공유하는 여러 작업? → with charshape_scope(app, …):
문단 정렬/줄 간격이 적용되는 블록? → with parashape_scope(app, …):
charshape_scope — 블록 단위 char 서식
받아들이는 친화적 키 (alias → HWP CharShape 키):
| 친화적 키 | HWP 프로퍼티 |
|---|---|
bold |
Bold |
italic |
Italic |
underline |
UnderlineType |
size, height |
Height (HWPUNIT, 100/pt) |
color, text_color |
TextColor |
shade_color |
ShadeColor |
face, face_name, font |
FaceNameHangul |
alias 맵에 없는 키는 그대로 전달됩니다 — 따라서 charshape_scope(app, Height=1200) 도 고급 사용자에게 잘 동작합니다.
이 scope 는 진입 시 커서의 현재 모양을 스냅샷 하고(곧 덮어쓸 키들을 미리 읽어두고), 사용자의 override 를 적용한 뒤, 종료 시 — 블록에서 예외가 발생했더라도 — 스냅샷을 복원합니다.
parashape_scope — 블록 단위 문단 서식
from hwpapi.context import parashape_scope
with parashape_scope(app, align="center", line_spacing=180):
app.doc.insert_text("가운데 정렬 문단\n")
app.doc.insert_text("이것도 가운데 정렬, 180% 줄 간격\n")친화적 키:
| 친화적 키 | HWP 프로퍼티 |
|---|---|
align, alignment |
AlignType |
line_spacing |
LineSpacing |
left_margin |
LeftMargin |
right_margin |
RightMargin |
indentation |
Indentation |
prev_spacing |
PrevSpacing |
next_spacing |
NextSpacing |
align 에는 문자열 ("left", "center", "right", "justify", "distribute") 또는 숫자 코드 (0–4) 를 전달할 수 있습니다.
styled_text — 일회성 inline 삽입
from hwpapi.context import styled_text
app.doc.insert_text("이 단어는 ")
styled_text(app, "긴급", bold=True, color="#E74C3C")
app.doc.insert_text(" 이고 나머지는 평범합니다.\n")내부적으로 styled_text 는 charshape_scope 를 열고, InsertText 를 한 번 호출한 뒤, scope 의 __exit__ 가 복원하도록 둡니다. context manager 가 아닌 평범한 함수이므로 종료 시 복원이 암묵적입니다.
왜 App 의 메서드가 아닌가
두 가지 이유가 있습니다.
- 조합성. 문서 핸들만 가진 스크립트의 일부에 대해, 또는
app을 받는 여러 헬퍼에 걸쳐 scope 를 동작시킬 수 있습니다. 모듈 레벨 함수가 의존성을 명시적으로 유지합니다. - 슬림한 facade. v2
App은 공개 멤버 ≤15개를 약속합니다. 각 scope 는 v1App의 82개 멤버 중 하나였습니다 — 이를 빼내는 것은 미적이 아니라 필수적이었습니다.
예외 안전성
세 scope 모두 contextlib.contextmanager 를 사용하고 본문을 try/finally 로 감쌉니다. 블록에서 예외가 발생해도 예외가 전파되기 전에 커서 모양은 복원됩니다.
try:
with charshape_scope(app, bold=True):
app.doc.insert_text("이건 동작합니다\n")
raise RuntimeError("쾅")
except RuntimeError:
pass
# 커서는 블록 진입 전 스타일로 돌아와 있음더 보기
- Reference: context.scopes
- Elements — element 단위 서식 (특정 문단/run 핸들이 있을 때의 대안)
- 마이그레이션 가이드 — v1
App.charshape_scope→ v2hwpapi.context.charshape_scope