Context scopes

charshape_scope, parashape_scope, styled_text

왜 scope 인가

HWP 스크립팅에는 반복되는 세 가지 패턴이 있습니다.

  1. “같은 스타일을 공유하는 몇 줄을 삽입한 뒤, 원래 커서 스타일로 계속 진행한다.”
  2. “다음 블록만 문단 단위 프로퍼티(정렬, 줄 간격)를 바꾸고 복원한다.”
  3. “한 문장 안에 스타일이 적용된 짧은 구절을 끼워 넣는다.”

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 서식

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")
# 커서 스타일 복원됨

받아들이는 친화적 키 (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") 또는 숫자 코드 (04) 를 전달할 수 있습니다.

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_textcharshape_scope 를 열고, InsertText 를 한 번 호출한 뒤, scope 의 __exit__ 가 복원하도록 둡니다. context manager 가 아닌 평범한 함수이므로 종료 시 복원이 암묵적입니다.

App 의 메서드가 아닌가

두 가지 이유가 있습니다.

  1. 조합성. 문서 핸들만 가진 스크립트의 일부에 대해, 또는 app 을 받는 여러 헬퍼에 걸쳐 scope 를 동작시킬 수 있습니다. 모듈 레벨 함수가 의존성을 명시적으로 유지합니다.
  2. 슬림한 facade. v2 App 은 공개 멤버 ≤15개를 약속합니다. 각 scope 는 v1 App 의 82개 멤버 중 하나였습니다 — 이를 빼내는 것은 미적이 아니라 필수적이었습니다.

예외 안전성

세 scope 모두 contextlib.contextmanager 를 사용하고 본문을 try/finally 로 감쌉니다. 블록에서 예외가 발생해도 예외가 전파되기 전에 커서 모양은 복원됩니다.

try:
    with charshape_scope(app, bold=True):
        app.doc.insert_text("이건 동작합니다\n")
        raise RuntimeError("쾅")
except RuntimeError:
    pass
# 커서는 블록 진입 전 스타일로 돌아와 있음

더 보기

맨 위로