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

아래아한글 문서의 위치(좌표)체계

by 일코 2022. 9. 8.

아래아한글 문서의 위치체계

아래아한글 문서에는 명확하게 위치체계가 존재하고, 비어있는 공간이 아닌 이상 좌표(?)가 매겨져 있습니다.

마치 3차원 좌표계(x, y, z)처럼 말이죠.

이 글에서 사용하는 "좌표"라는 용어는 제가 편의상 임의로 붙였으며, API의 공식 명칭은 아님을 밝힙니다.

기존에 작성했던 대부분의 포스팅에서는 "누름틀"이나 "필드"를 이용해서 작업을 자동화했기 때문에 굳이 좌표를 계산하거나 추출해야 할 필요가 없었습니다. 그런데 아래 예제 같은 경우에는 좌표개념을 사용하면 작업이 훨씬 수월해집니다.

2022.09.06 - [업무자동화/파이썬-아래아한글 자동화 기초] - [QnA] 한글에서 특정 글꼴 찾아 태그 붙이기

 

[QnA] 한글에서 특정 글꼴 찾아 태그 붙이기

안녕하세요. 우연히 유튜브에서 회사원코딩의 파이썬 hwp 강좌를 보다가 궁금한 점이 있어서 연락드리게 됐습니다. 하나씩 따라하다 보니 아주 간단한 것은 응용이 되는 데, 아래 내용은 아무리

martinii.fun

간단한 예제인데 가볍게 설명을 드리면,

"함초롱바탕"으로 작성된 문서의 일부 구간이 "고딕" 서체로 바뀌어 작성되어 있습니다.

고딕 서체로 표기된 해당구간 앞뒤로, 앞에는 "\b" 태그를, 뒤에는 "\b*" 태그를 추가하고 싶을 때

어떤 명령어를 사용하여 프로그램을 짜면 좋을까요?

 

여러 가지 방법들이 있겠지만, 위 예제에서 제가 사용한 방법은

 

1. "찾기"기능으로 "고딕"서체 구간을 탐색한다. (찾기 메서드는 매번 True를 리턴하다가 한바퀴를 다 돌면 False 리턴)

2. 탐색결과는 블록으로 선택되며, GetSelectedPos() 를 사용하면 선택구간 시작점과 끝점의 좌표를 구할 수 있다.

3. while문을 돌려 해당 좌표를 모두 수집한 후, 문서 끝에서부터 (역순으로) SetPos()로 이동하여 태그를 삽입한다.

 

이처럼 문서의 위치정보를 적극적으로 활용하여 자동화한 사례입니다.

 

이번 포스팅에서는

한/글 문서의 좌표체계에 대해 설명드리겠습니다.

 

흔히 우리가 사용하는 문서위치라면 이런 게 있겠죠.

몇 쪽, 몇 번째 줄, 몇 번째 글자

혹은 이렇게요.

몇 페이지, 몇 번째 단원, 몇 번째 글자

아래아한글에서 인식하는 위치정보도 위와 비슷합니다. 다만, 페이지 대신 "리스트"라는 개념을 사용합니다.

몇 번째 리스트(List), 몇 번째 단원(Para), 몇 번째 글자(Pos)

와 같은 개념을 사용합니다.

 

한/글 좌표 개념을 가장 잘 이해할 수 있는 방법은 아무래도

이런 개념을 가장 쉽고 빠르게 이해할 수 있는 방법은 역시

직접 문서를 열어놓고 현재 캐럿의 좌표를 조회해보고, 찾아가보는 방법일 것 같습니다.

파이썬으로 한/글 빈 문서를 열고 아무 타이핑이나 해놓은 후에 아래 과정을 따라해 보시기 바랍니다.

원문 출처 : 케라스 창시자에게 배우는 딥러닝 개정 2판 표지 뒷면

좌표를 리턴하는 메서드는 hwp.GetPos()입니다.

줄바꿈 기준 네 번째 단락 "쉽고 간결하다!"에서 "간"자 앞에 커서를 놓고 좌표를 구해보면 얼마가 나올까요?

(0, 3, 3) 을 리턴했습니다.

보시는 바와 같이 (0, 3, 3)을 리턴합니다. 모든 인덱스는 0부터 올라가요.

0번 리스트, 3번 문단의 3번 인덱스의 글자니까 "간" 앞이 맞네요.

조금 허접하지만 아래 그림도 참고해 주시기 바랍니다.

커서 위치에 따른 pos 인덱스

좌표의 첫 번째 원소, 리스트(List)가 뭔지 궁금하시다고요?

문단인덱스인 Para와, 글자인덱스인 Pos는 직관적으로 이해가 되는데, 리스트는 뭔지 모르시겠다고요?

리스트는 간단합니다. 표나 글쓰기 개체, 메모 등 공간이 구분되는 컨트롤 내에서의 텍스트는 리스트번호가 순차적으로 따로 매겨집니다.

위 문서에 표를 몇 개 추가해보겠습니다.

내용은 동일. 다양한 표를 삽입함

표의 각 셀에 들어가서 GetPos를 해 보면 리스트가 올라가는 규칙에 금방 익숙해지실 겁니다.

본문과 셀의 리스트 인덱스

본문 및 표 셀의 리스트 번호를 그려넣어보았습니다.

추가로 재미있는 점이 몇 가지 있습니다. (중요합니다.)

1. 본문(가장 바깥의 텍스트)은 표 아래에 있더라도 본문의 리스트 인덱스는 항상 0입니다.

2. 리스트의 1번 인덱스는 이미 지정되어 있습니다. (문서메모)

3. 표 등 문자열이 삽입되는 개체를 만들면 2부터 순차적으로 리스트인덱스가 올라갑니다.

    (표 안의 표는 다음 셀에 우선하여 인덱스가 매겨집니다...)

4. 문서 시작점의 인덱스는 (0,0,0)이 아닌, (0,0,16)으로 시작합니다. (아마도 문서메모 컨트롤이 숨겨져 있는 듯)

5. 누름틀은 최소 16개의 Pos인덱스를 차지합니다.

    (누름틀 이름이 "asdf"라면 해당 누름틀의 길이는 20Pos입니다.)

6. 표는 셀 갯수와 상관없이 8개의 Pos인덱스를 차지합니다.

7. 각주나 미주, 머릿말 꼬릿말 등도 기호길이나 주석길이와 상관없이 8Pos를 차지합니다.
    (사용되는 공간은 해당 컨트롤이 삽입된 위치입니다.)

 

그리고, 특정 좌표로 찾아가려면 SetPos(List, Para, Pos)를..

지금까지 좌표를 얻는 방법을 알아보았습니다. GetPos()로 리턴되는 좌표는 파이썬의 기본 자료형인 튜플이므로 별도의 자료형에 수집하거나 활용하기 간편합니다.

SetPos가 파라미터 세 개를 받으므로 튜플 언패킹(*)을 사용했습니다.

제법 오래 문의메일을 받다 보니, 정말 자동화할 수 있는 업무들이 무지막지하게 다양하구나 하는 생각이 듭니다.

하지만 그 중 가장 많은 케이스는 스프레드시트와 연동해서 간편하게 필드를 사용하면 거의 해결되곤 했습니다.

그 외에 다소 복잡한 태스크는 위처럼 좌표를 이용하거나, 간혹 다른 라이브러리를 가져다 쓰는 경우도 있었는데,

사실 미미한 수준입니다.

그럼에도 한/글의 좌표 개념을 이해하고 활용할 수 있으면

그럼에도 한/글의 좌표 개념을 이해하고 활용할 수 있으면

특정 소수의 API 메서드에 국한되지 않고 정말 다양하게 자동화 아이디어를 개발할 수 있게 되는 것 같습니다.

저도 그랬고요. 그리고 사실 회사 일이란 게 단순해 보이면서도 파고들어가보면 굉장히 복잡하기도 하더라고요.

 

이번 포스팅은 여기서 마치겠습니다.

분량이 길어지는 것 같아서

다음 포스팅에서 GetAnchorPos나 GetSelectedPos 처럼

좌표를 활용하는 다른 메서드에 대해서도 이어서 다루겠습니다.

 

긴 글 읽어주셔서 감사합니다.

행복한 하루 되세요!

 

 

댓글