본문 바로가기
아래아한글 자동화/python+hwp 중급

[QnA] (3/5) 문단의 높이와 너비(HwpUnit) 구하기

by 일코 2022. 9. 19.
안녕하세요.
한글 자동화 프로그램을 공부하고 있는데 궁금한 사항이 있어 질문합니다.

<질문>

특정 글자가 들어가 있는 문단을 찾아서 그 곳에 글뒤로 속성으로 표를 삽입하고 싶습니다.
1. 자동으로 표 생성시 속성을 "본문과의배치"에서 "글뒤로" 선택하여 생성할 수 있나요?
이 속성없이 생성시 문단에 삽입되면서 글자가 밀려나는 현상이 발생합니다.

2. 찾은 문단의 위치값을 HWPUNIT 값으로 알 수 있나요?
표 생성시 위치값은 HWPUNIT으로 지정해야 하는데 현재 찾은 위치의 속성은 줄,칸으로 알려주네요.
이상입니다.

문단의 크기를 좌표값으로 구할 수 있다면 얼마나 좋을까요?

그런데 한글에는 그런 기능이 구현되어 있지 않으니

문단의 줄 수, 글자높이(pt)와 줄간격(%)을 더해서 문단의 높이를 직접 계산해보겠습니다.

 

예시문서는 아래와 같습니다.

글자높이는 49pt(4,900HU)이고, 줄간격은 160(%)입니다.

문단이 6줄이므로 4,900 * 1.6 * 6 = 47,040HU (166mm)입니다.

이전 포스팅에서 만든 표_생성 함수에 이 값을 넣어 실행해보면?

단순히 계산했지만 적절한 것 같네요.

아슬아슬하게 다음문단에 걸쳐지는 문제는 높이값을 약간만 보정하면 될 것 같고요.

 

글자pt * 줄간격 * 줄수 - 글자pt * 0.6 / 2 정도면?

음, 보정식을 통해 45,570HU로 줄었는데, 적절한 것 같네요.

이제 각 요소들을 하나씩 계산하는 함수를 알아봅시다.

우선 한/글에서 제공하는 매크로를 최대한 활용해봅시다.

줄간격과 글자크기는 아래 코드로 쉽게 구할 수 있습니다.

# 현재 캐럿의 줄간격(%)
hwp.ParaShape.Item("LineSpacing")
# >>> 160

# 현재 캐럿의 글자크기(HU)
hwp.CharShape.Item("Height")
# >>> 4,900 HU (== 49pt)

문단이 몇 줄인지 구하는 것도 굉장히 단순할 것 같습니다. 캐럿을 내리면서 문단번호가 바뀌는지만 hwp.GetPos() 메서드로 살펴보면 될 것 같네요.

7번째 캐럿을 내렸을 때 다음문단으로 바뀌므로 총 6줄인 것을 알 수 있겠습니다.

while문으로 만들면 되겠네요.

def 줄수계산():
    hwp.Run("MoveParaBegin")
    시작위치 = hwp.GetPos()[1]
    줄수 = 1
    while True:
        hwp.HAction.Run("MoveDown")
        if hwp.GetPos()[1] != 시작위치:
            hwp.HAction.Run("MoveUp")
            hwp.Run("MoveParaBegin")
            break
        else:
            줄수 += 1
    return 줄수

줄수계산()

실행해보면

그럼 최종적으로

문단높이를 구하는 함수는 다음과 같이 만들 수 있겠네요.

"""
현재 캐럿이 위치한 문단의 높이를 구하는 함수
글자pt * 줄간격 * 줄수 - 글자pt * 0.6 / 2
"""


def 줄수계산():
    hwp.Run("MoveParaBegin")
    시작위치 = hwp.GetPos()[1]
    줄수 = 1
    while True:
        hwp.HAction.Run("MoveDown")
        if hwp.GetPos()[1] != 시작위치:
            hwp.HAction.Run("MoveUp")
            hwp.Run("MoveParaBegin")
            break
        else:
            줄수 += 1
    return 줄수


def 문단높이():
    줄수 = 줄수계산()
    글자크기 = hwp.CharShape.Item("Height")  # HU
    줄간격 = hwp.ParaShape.Item("LineSpacing")  # %
    문단높이 = 글자크기 * (줄간격 * 줄수 - 30) / 100
    return 문단높이

문단높이() 함수를 실행해보면?

45,570HU를 리턴하네요. mm로 고치면

45,570 / 283.465 = 160.76mm 입니다.

이 값을 표_계산 함수에 넣어서 최종 확인해보겠습니다.

기왕이면 길이단위는 HU로 통일하면 좋겠는데,

이전 포스팅에서 표_생성 함수를 만들 때 인자를 mm단위로 입력하게 했더니 다소 번거롭네요.

마지막에 가서는 단위를 통일하든지 합시다. 우선은 그대로 두고요. (귀찮아서 그러는 거 아님..)

참고로 문단의 너비는

여기서는 자세히 설명하지 않았지만 용지의 원래 너비(기본 210mm)에서 왼쪽, 오른쪽 여백(기본 30 * 2 = 60)을 빼면

표 너비인 150mm가 나옵니다. 용지너비나 좌우여백은 바뀔 수 있으므로 함수로 구현해야 하는데, 파라미터셋을 이용하면 간단합니다. 여기서는 코드만 보여드리겠습니다. 다소 생소하더라도 "그런가보다" 하고 넘어가 주시기 바랍니다.

def 문단너비():
    Act = hwp.CreateAction("PageSetup")
    Set = Act.CreateSet()
    Act.GetDefault(Set)
    용지너비 = Set.Item("PageDef").Item("PaperWidth")  # HwpUnit
    왼쪽여백 = Set.Item("PageDef").Item("LeftMargin")
    오른쪽여백 = Set.Item("PageDef").Item("RightMargin")
    문단너비 = 용지너비 - 왼쪽여백 - 오른쪽여백
    return 문단너비

위 함수를 실행해보면

210 - 30 - 30 = 150mm 입니다. 잘 정의된 것 같네요.

 

여기까지

다소 긴 호흡으로 포스팅을 작성했습니다.

이번 포스팅에서는 현재 캐럿이 위치한 문단의 높이와 용지너비를 HwpUnit으로 구하는 함수를 만들어보았습니다.

(이전 포스팅에서는 표를 생성하고 글자 뒤로 보내는 함수를 만들어보았고요.)

이제 다음 포스팅에서는

이제 특정 단어를 포함하고 있는 문단을 체크해서 리스트로 만들고,

순회하면서 찾아간 후에 위에서 만든 함수를 실행하기만 하면 되겠네요.

벌써 거의 다 마친 것 같네요.

2022.09.19 - [업무자동화/파이썬-아래아한글 자동화 응용] - [QnA] (4/5) 특정 단어를 포함한 문단 검색하기

 

[QnA] (4/?) 특정 단어를 포함한 문단 검색하기

안녕하세요. 한글 자동화 프로그램을 공부하고 있는데 궁금한 사항이 있어 질문합니다. <질문> 특정 글자가 들어가 있는 문단을 찾아서 그 곳에 글뒤로 속성으로 표를 삽입하고 싶습니다. 1. 자

martinii.fun

 

댓글