지난 포스팅에서
한/글 문서의 위치정보에 대해 설명드렸습니다.
2022.09.08 - [업무자동화/파이썬-아래아한글 자동화 기초] - 아래아한글 문서의 위치(좌표)체계
(List, Para, Pos)로 구성된 3차원 벡터는 마치 좌표를 연상하게 하는데요.
굳이 누름틀이나 필드를 이용하지 않고도 얼마든지 자유롭게 원하는 위치로, 혹은 오프셋 이동이 가능하기 때문에, 다양한 방법으로 활용할 수 있겠습니다.
이번 포스팅은 "이미지마다 캡션 텍스트 달기"
위치정보를 활용하는 메서드인 GetAnchorPos를 간단한 예제를 통해 설명드리겠습니다.
이런 작업을 하고 싶다고 가정해봅시다. 문서 안에 다음과 같은 8장의 사진이 삽입되어 있고,
각 사진에 대한 캡션을 스프레드시트에서 다음과 같이 파이썬 리스트 자료형으로 가져온 상태입니다.
caption_list = [
"구름 낀 하늘",
"푸른 하늘",
"사막의 잔디",
"강 주변",
"아프리카 강",
"해저 모래",
"해저 바닥",
"삼엽충"]
각 사진의 아래에 <구름 낀 하늘>, <푸른 하늘>, ... 식으로 텍스트를 삽입하는 작업을 자동화할 수 있을까요?
아래처럼 말예요.
문서 안에 단순하게 그림만 삽입되어 있는 상태라면..
무식하게 키매크로를 활용해서
"아래, 순차대로 텍스트입력, 엔터엔터, <반복>"
이런 식으로 작업할 수는 있겠습니다.
그런데 그림 외에도 표나 텍스트가 삽입되어 있는 경우라면?
이런 경우에
그림.GetAnchorPos()를 활용하면 좀 더 정확하고 우아하게 처리할 수 있습니다.
먼저 GetAnchorPos가 어떤 메서드인지 알아봅시다.
그럼 GetAnchorPos는 어떤 명령어인가요?
GetAnchorPos는 컨트롤객체(표, 그리기개체 등)의 위치정보를 리턴해주는 메서드입니다.
한/글에서는 좌표체계 외에도, 컨트롤만 순회하며 탐색할 수 있는 기능을 제공하고 있어요.
(hwp.HeadCtrl, hwp.LastCtrl, .Next, .Prev 등.. 링크드리스트 형식임)
컨트롤을 변수로 지정한 상태에서 정보조회, 수정, 삭제 등 간편하게 조작할 수 있어요.
예) 아래는 문서의 두 번째 컨트롤개체(푸른하늘 사진)을 지우는 코드예요.
예) 이미지의 너비를 조회하고 싶을 때는 이렇게 하면 돼요.
정확하네요.
[A4용지의 가로너비] 210mm - [좌우측 여백] 30mm * 2 = 150mm이니까요.
다시 본론으로 돌아와서, GetAnchorPos는
해당 컨트롤의 위치를 파라미터셋 개체로 리턴해줘요. 파이썬의 리스트나 튜플 자료형이 아니라서, 리턴받은 값을 조회할 때는 Item이라는 메서드를 사용해야 해요.
세 번째 그림이 삽입되어 있는 위치를 얻어오려면?
위의 영상에서 작성한 코드입니다.
pic_index = 3
count = 0
while True:
if ctrl.UserDesc == "그림":
count += 1
if count == pic_index:
loc = ctrl.GetAnchorPos(0)
break
else:
ctrl = ctrl.Next
else:
ctrl = ctrl.Next
loc.Item("List")
# >>> 0
loc.Item("Para")
# >>> 5
loc.Item("Pos")
# >>> 0
위 정보를 활용해서 세 번째 그림의 앞으로 이동한 후
아래에 줄바꿈을 하나 삽입하고, "<사막의 잔디>"라는 텍스트를 입력하겠습니다.
참고로 텍스트 입력 함수는 아래와 같이 정의합니다.
def 문자열삽입(문자열):
hwp.HAction.GetDefault("InsertText", hwp.HParameterSet.HInsertText.HSet)
hwp.HParameterSet.HInsertText.Text = 문자열
hwp.HAction.Execute("InsertText", hwp.HParameterSet.HInsertText.HSet)
위 영상에서 사용한 코드입니다.
ctrl = hwp.HeadCtrl
while True:
if ctrl.UserDesc == "그림":
count += 1
if count == pic_index:
loc = ctrl.GetAnchorPos(0)
break
else:
ctrl = ctrl.Next
else:
ctrl = ctrl.Next
hwp.SetPos(*[loc.Item(i) for i in ["List", "Para", "Pos"]])
hwp.Run("MoveLineEnd")
hwp.Run("BreakPara")
문자열삽입("<사막의 잔디>")
최종코드 : 각 이미지에 캡션 삽입
그럼 위 코드를 조합해서 이미지 전체에 캡션(엄밀히는 캡션이 아님ㅜ)을 삽입하는 코드를 작성해보겠습니다.
성공적으로 캡션이 삽입되었습니다.
위에서 작성한 스크립트는 아래와 같습니다.
def 문자열삽입(문자열):
hwp.HAction.GetDefault("InsertText", hwp.HParameterSet.HInsertText.HSet)
hwp.HParameterSet.HInsertText.Text = 문자열
hwp.HAction.Execute("InsertText", hwp.HParameterSet.HInsertText.HSet)
caption_list = [
"구름 낀 하늘",
"푸른 하늘",
"사막의 잔디",
"강 주변",
"아프리카 강",
"해저 모래",
"해저 바닥",
"삼엽충"]
ctrl = hwp.HeadCtrl
image_loc = []
while True:
if ctrl.UserDesc == "그림":
image_loc.append(ctrl.GetAnchorPos(0))
ctrl = ctrl.Next
else:
ctrl = ctrl.Next
for idx, loc in enumerate(image_loc[::-1]): # 역순으로 탐색
hwp.SetPos(*[loc.Item(i) for i in ["List", "Para", "Pos"]])
hwp.Run("MoveLineEnd")
hwp.Run("BreakPara")
문자열삽입(f"<{caption_list[::-1][idx]}>") # 캡션도 역순으로 입력
참고로, 찾아가기도 역순으로, 덩달아 캡션도 역순으로 붙인 이유는
줄바꿈 때문에 아래쪽 모든 그림들의 좌표(Para 요소)값이 바뀌어 버리기 때문입니다.
역순으로 삽입하면 그런 문제가 해결됩니다.
'아래아한글 자동화 > python+hwp 중급' 카테고리의 다른 글
SetPos 대신 SetPosBySet을 쓰면 훨씬 유용한 경우 : GetAnchorPos와 연계할 때 (0) | 2022.09.15 |
---|---|
아래아한글 문서의 위치(좌표)체계 (0) | 2022.09.08 |
[QnA] 한글에서 특정 글꼴 찾아 태그 붙이기 (0) | 2022.09.06 |
댓글