인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

윤병현님의 프로필 이미지
윤병현

작성한 질문수

직장인에게 꼭 필요한 파이썬-아래아한글 자동화 레시피

페이지를 넘어가는 문제 깔끔하게 정리하기

해결된 질문

작성

·

38

1

안녕하세요 일코님

날씨 많이 추워졌는데 건강 잘 챙기시기 바랍니다 ^^

현재 문제가 텍스트로만 이루어졌을 경우 아래와 같이 BreakPage메소드를 통해 페이지에 걸친 문제가 없도록 정리하고 있씁니다.

while 찾기("#"):                             # 샵 "#"표시는 문제의 시작지점입니다.
        hwp.Run("MoveLineBegin")
        start_page = hwp.KeyIndicator()[3]
        start_pos = hwp.GetPos()              # 
        hwp.Run("MoveParaEnd")
        둘중_빠른것_찾기("#", "<<<")
        현재문단블록처리()
        if 블록내_텍스트_포함_여부("<<<"):
            hwp.Run("MovePageBegin")
            hwp.Run("MoveLeft")
        else:
            hwp.Run("MoveParaBegin")
        위로_찾기_아무거나()            
                # 다음문제로 넘어간뒤, 아무런 텍스트나 위로 찾기 하여 문제의 끝을 특정함
        hwp.Run("MoveParaEnd")
        end_page = hwp.KeyIndicator()[3]
        endpos = hwp.GetPos()
        if end_page != start_page:   # 문제 시작점과 끝점의 페이지가 다를 경우 BreakPage
            hwp.SetPos(*start_pos)
            hwp.Run("BreakPage")
            hwp.Run("MoveParaEnd")

 

문제는, 문제의 형식이 표로 되어 있을 때가 있다는 것인데요.

 

image.png

 

 

이런식으로 표가 존재하고, 이 표가 넘어갈경우에,, 현재 코드를 적용하면 저 "수정"으로 이동하여 endpos의 위치가 잡히게 되네요..

문제가 표로 마무리 될경우에 문제의 끝을 올바르게 특정해서 문제를 깔끔하게 정리할 방법이 없을까요?

 

감사합니다 !

 

답변 2

1

일코님의 프로필 이미지
일코
지식공유자

병현님, 안녕하세요!^^

회신이 조금 늦었습니다.

사실 코드 전체를 추측하면서 읽어보기는 했는데,

어떤 방식으로 처리하고 계신 건지 조금 막연합니다^^;;; (제가 머리가 많이 나빠서ㅜㅜㅜㅜㅜ)

 

당장 코드를 보완해드리기는 어렵지만,

대신 비슷한 문의와 답변을 다른 분과 주고받은 적이 있어

당시 제가 고민했던 내용과, 나름의 솔루션을 공유드려봅니다.

 

특정 문제의 끝점을 찾아내는 프로세스

예전에 경기도 모 학원에서 여러 차례 문의를 준 적이 있었는데,

문의내용 중에 병현님 주신 질문과 비슷한 주제가 있었습니다.

정확히는 "자동넘김"은 아니고,

개별 문제영역을 잘라내기 위해 모든 문제의 시작점과 끝점의 좌표를 알아내는 프로세스였습니다.

 

모든 문제 시작부분에는 수능시험지나 여느 모의고사들처럼

문단번호(또는 "정수." 서식의 텍스트)가 매겨져 있었고,

문제와 문제 사이에는 상당히 많은 수의 줄바꿈이 들어 있어서

한 페이지당 문제가 네 개 내외였습니다.

image.png

 

문제 사이의 빈 줄바꿈은 문제영역에서 제외해야 했는데,

제가 구상했던 간단한 아이디어는

("문단번호모양 찾아가기" 기능을 써서) 특정 문단번호가 시작되는 지점으로 찾아간 후,

hwp.MoveSelPrevParaBegin() 명령어를 통해서 위쪽 방향으로 계속 빈 줄을 선택하다가,

어떤 텍스트가 잡히면, 그 라인이 이전 문제의 끝점이라고 간주하는 거죠.

 

이걸 영상으로 보여드리면,

아래는 "문제2 시작점에서 위로 찾아올라가면서 문제1의 끝점좌표를 출력하는 코드&실행화면"입니다.

녹화_2024_12_05_21_58_14_364.gif

 

코드는 아래와 같습니다.

# 1번문제 끝점 좌표는 (0, 6, 26)임.
# 아래 코드 실행결과도
# (0, 6, 26)이 나올 것인가?

from time import sleep

while True:
    sleep(0.2)  # 보여주려고;
    hwp.MoveSelPrevParaBegin()
    if hwp.get_selected_text().replace("\r\n", ""):
        break

hwp.Cancel()
hwp.MoveParaEnd()
print(hwp.get_pos())

# (0, 6, 26)이 잘 출력됨.

 

이걸 응용해서 쪼개진 문제 찾기

위 프로세스를 활용하면, 문제의 시작점과 끝점으로 이동할 수 있으니까,

두 지점에서의 쪽번호를 비교하기만 하면

잘린 문제인지 아닌지 쉽게 알아낼 수 있어요.

만약 페이지가 다르면(잘려 있으면) 문제 시작점에서 BreakPage를 실행하기만 하면 되고요.

 

혹시나 실습해보실 분들을 위해 예제파일을 공유해봅니다.

문제 몇 개가 두 페이지에 걸쳐있게 수정해놓은 상태입니다. [링크]

 

우선 문제 시작점(여기선 문단번호)으로 이동하는 함수를 아래처럼 한 번 짜볼게요.

def 다음_문단번호로_이동():
    hwp.SetMessageBoxMode(0x20000)  # 문서 끝에 도착하면 "아니오" 자동선택
    hwp.MoveParaEnd()  # 현재 문단 끝으로
    pset = hwp.HParameterSet.HGotoE  # 찾아가기 파라미터셋 정의
    hwp.HAction.GetDefault("Goto", pset.HSet)  # 찾아가기 액션 정의
    pset.SetSelectionIndex = 5  # "조판부호" 옵션의
    pset.HSet.SetItem("DialogResult", 34)  # "문단번호 모양" 선택
    try:
        return hwp.HAction.Execute("Goto", pset.HSet)  # 이동하면 True
    finally:
        hwp.SetMessageBoxMode(0xf0000)  # 팝업 자동선택 해제
        hwp.MoveParaBegin()  # 현재 문단 시작점(문제번호 앞)으로 이동

 

이제 전체 프로세스를 짜보면..

① 위 함수를 실행해서 각 문제 시작점으로 이동한 후 start_page = hwp.current_page 를 저장하고,

② 한 번 더 실행해서 그 다음 문제 시작점으로 이동

③ "이전 문제의 끝지점을 찾아내는 함수" 실행 후, end_page = hwp.current_page를 저장.

④ start_page와 end_page가 같으면 패스, 다르면 문제 시작점에서 BreakPage 실행.

⑤ "①~④" 반복

 

위 과정을 코드로 옮겨볼게요.

from pyhwpx import Hwp


def 이전문제_끝으로():
    while True:
        hwp.MoveSelPrevParaBegin()
        if hwp.get_selected_text().replace("\r\n", ""):
            break
    hwp.Cancel()
    hwp.MoveParaEnd()


def 다음_문단번호로_이동():
    hwp.SetMessageBoxMode(0x20000)
    hwp.MoveParaEnd()
    pset = hwp.HParameterSet.HGotoE
    hwp.HAction.GetDefault("Goto", pset.HSet)
    pset.HSet.SetItem("DialogResult", 34)
    pset.SetSelectionIndex = 5
    try:
        return hwp.HAction.Execute("Goto", pset.HSet)
    finally:
        hwp.SetMessageBoxMode(0xf0000)
        hwp.MoveParaBegin()

if __name__ == '__main__':
    hwp = Hwp()  # 시험지 파일 연결
    hwp.MoveDocBegin()  # 문서 시작으로 이동
    while 다음_문단번호로_이동():  # 1+..번 문제로 이동하면서
        start_page = hwp.current_page  # 현재페이지 저장
        start_pos = hwp.get_pos()  # 시작위치도 저장(잘렸으면 돌아오려고)
        
        if not 다음_문단번호로_이동():  # 2+..번 문제로 이동 후
            break  # 마지막 문제는 패스해야 무한루프에 안 걸림ㅜ
        
        이전문제_끝으로()  # 이전 문제의 끝점으로 이동
        end_page = hwp.current_page  # 1+..번 문제의 끝페이지 저장

        if start_page != end_page:  # 시작페이지와 끝페이지가 다르면?
            hwp.set_pos(*start_pos)  # 1+..번 시작점으로 이동해서
            hwp.BreakPage()  # 쪽 나누기 실행 (2+..번 문제로 넘어가서 반복)

 

실습파일에다 위 코드를 적용하는 과정을 영상으로 보여드리면,

기존에는 4, 9, 14, 19번이 아래처럼 페이지 중간에 걸친 상태인데요.

image.pngimage.png

 

코드를 실행하고 나면,

녹화_2024_12_05_22_35_05_334.gif

페이지 중간에 걸쳐있던 문제들이

모두 다음페이지로 잘 넘어간 것을 확인하실 수 있습니다.

의외로 간단하죠?

 

조금만 더 응용하면

마무리하기 전에,

이런 방식으로 페이지를 쪼개다 보면, 페이지 시작 부분에 줄바꿈이 많이 남아서 예쁘지가 않아요ㅜ

이것도, hwp.goto_page(n) 메서드로 각 페이지 시작점으로 이동한 후

"현재 문단이 빈 줄이면, 계속해서 hwp.Delete()를 실행"하는 방식으로 정리하는 것도 가능하고요.

다단으로 잘리는 문제들도 위와 유사한 방식으로 처리해볼 수 있고요.

 

마치며

의외로 단순한 액션들의 조합만으로 해결된 것 같지 않나요?^^;

만약 의도하셨던 것과 제 답변의 방향이 다르거나 도움이 안 되었다면ㅜㅜㅜㅜㅜㅜㅜㅜ

조금만 구체적으로 다시 질문 주시면 다시 꼼꼼하게 살펴보겠습니다.

 

부디 도움이 되었길 바랍니다ㅎ

행복한 하루 되세요!!!

1

안녕하세요, 인프런 AI 인턴입니다.

윤병현님께서 파이썬을 사용하여 한글 문서에서 문제를 처리하고 계시는군요. 표로 마무리되는 문제에서 페이지가 넘어갈 경우, 현재 코드로는 문제가 완전히 정리되지 않는다고 하셨는데요.

해결책을 찾는 데 도움이 될 수 있는 몇 가지 접근법을 소개해 드리겠습니다:

  1. 표내 위치 제어: 표가 있는 페이지에서 문제의 시작과 끝을 체크할 때, 표의 첫 셀과 마지막 셀을 기준으로 조건문을 추가하여 처리할 수 있습니다. GetPosSetPos와 같은 위치 조정 메서드를 사용하여 해당 셀의 위치를 더 정확히 잡도록 할 수 있습니다.

  2. 블록 설정: 표에서도 텍스트를 검색하고 블록 설정을 통해 해당 표가 페이지에 걸쳐 있는지 여부를 체크할 수 있습니다. 코드 내에서 표가 시작되고 끝나는 위치를 hwp.Action.ListupField()를 사용하여 셀의 경계를 지정하는 방법을 고려해보세요.

  3. 이중 블록 처리를 통한 확인: 더블 블록 처리를 하여 텍스트와 표를 상호 비교하면서 테이블의 경계와 문제의 경계를 처리합니다. 이는 매번 MoveParaEnd와 같은 코드를 따로 적용하여, 구조가 복잡한 문서에 유용할 수 있습니다.

  4. 문제 해결을 위한 포맷 구분: 표와 일반 텍스트를 구분할 수 있는 별도의 마커나 태그를 문서에 삽입하여, 스크립트가 이를 통해 구분할 수 있도록 설계하는 것도 방법이 될 수 있습니다. 이는 주로 문서에서 일관된 구조가 유지될 때 효과적입니다.

이와 관련한 구체적인 방법이나 예제를 알고 싶으시다면, 관련 내용이 더 다루어진 지식 공유자님의 질문 예시를 확인하시는 것도 좋습니다. 예를 들어, 이전에 유사한 문제를 다룬 적이 있는 한글 오피스 자동화 관련 질문에서 표 안에 자료가 포함된 문서의 처리 방법을 확인해 보실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.

현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏

추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

윤병현님의 프로필 이미지
윤병현

작성한 질문수

질문하기