• 카테고리

    질문 & 답변
  • 세부 분야

    업무 자동화

  • 해결 여부

    해결됨

자간 자동조정 프로그램 만들어보기 관련 문의

23.03.01 02:17 작성 23.03.01 14:48 수정 조회수 419

1

 

자간 자동 조정 코드를 적용하던 도중에

가나다라마바사아자차카타파하

가나다라마바사아자차카타파

가나다라마바사아자차카타

가나다라마바사아자차카

가나다라마바사아자차

가나다라마바사아자

가나다라마바사아

 

이런 식으로 문장 중간중간 엔터가 입력되어 있는 경우에는 중간에서 계속 선택구간 텍스트만을 반복하는 경우가 발생하였습니다 ㅠㅠ

 

혼자 코드를 수정해가면서 고쳐보려고 했으나 잘 되지 않네요 ㅠㅠ 혹시 도움을 주실 수 있을까요?

 

그리고 단이 나눠져 있는 문서의 경우에는 "MoveDown"을 사용할 경우에는 한 쪽 단 만을 점검하고 내려가게 되는 것 같아 이 부분도 혹시 반영할 코드를 짤 수 있을까요??

 

그리고.. 질문이 너무 많고 계속 추가하고 수정해서 죄송한데 ㅠㅠ

글과 표가 섞여있는 경우에 두 가지를 해결하지 못해서요.

1) 첫 시작이 표인경우에는 "MoveDown"을 사용하면 표 안으로 들어가는게 아니라 그 다음줄로 이동하는데 이것도 방법이 있을까요..??

2) 중간에 표가 있는 경우에도 표 안에서 멈춘 후에 이후에 나가지 못하는 것 같습니다. 아무래도 표 안쪽과 바깥 글 사이에 "MoveSelRight"가 안 되는게 원인인것 같은데 해결책을 찾지 못하였습니다 ㅠㅠ

답변 1

답변을 작성해보세요.

1

하나씩 차근차근 답변을 드려보겠습니다^^

 

  1. 이런 식으로 문장 중간중간 엔터가 입력되어 있는 경우에는 중간에서 계속 선택구간 텍스트만을 반복하는 경우가 발생하였습니다 ㅠㅠ

이건 제 프로세스의 버그입니다ㅜ (부끄럽습니다.)
답변 마지막의 수정된 프로그램을 참고해 주시기 바랍니다.

 

  1. 그리고 단이 나눠져 있는 문서의 경우에는 "MoveDown"을 사용할 경우에는 한 쪽 단 만을 점검하고 내려가게 되는 것 같아 이 부분도 혹시 반영할 코드를 짤 수 있을까요??

간단합니다. hwp.Run("MoveDown") 대신

hwp.Run("MoveLineEnd")
hwp.Run("MoveNextPosEx")

방식으로 두 줄로 입력하시면 다단 건너뛰기 없이 수행됩니다.

 

  1. 첫 시작이 표인경우에는 "MoveDown"을 사용하면 표 안으로 들어가는게 아니라 그 다음줄로 이동하는데 이것도 방법이 있을까요..??

 

가능은 합니다. 표 앞에서 hwp.FindCtrl()hwp.Run("ShapeObjTableSelCell");hwp.Run("Calcel")을 실행하면 됩니다.

그런데 커서를 옮길 때마다 매번 표가 있는지 탐색하는 것은 비효율적이라고 생각이 되어서,
본문 자간조정 후에 아예 컨트롤을 싹 모아다가 자간조정하는 방식을
아래처럼 구현해보았습니다.

120줄 정도로 다소 깁니다.
차근차근 읽어보시고 나서 원하시는 문서에 적용해 보신 뒤에
결과나 오류를 알려주시면 적극 보완하도록 하겠습니다.

테스트 케이스를 만드는 게 쉽지 않아서
이것저것 만들어 적용해보았는데
예외가 훨씬 많을 것 같아서 불안합니다.

import os
from tkinter.filedialog import askopenfilenames

import win32com.client as win32


def 한글_시작():
    """
    아래아한글 시작 함수
    """
    hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject")
    hwp.XHwpWindows.Item(0).Visible = True
    hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule")
    return hwp


def 파일선택():
    """
    파일선택 함수
    """
    filelist = askopenfilenames(title="수정할 한/글문서를 모두 선택해주세요.",
                     initialdir=os.getcwd(),
                     filetypes=[("한/글파일", "*.hwp *.hwpx")])
    return filelist


def 현재선택영역_글자수():
    """
    자간자동조정 함수에서
    라인 끝에 걸쳐진 단어의
    앞뒤길이를 각각 계산하기 위함.
    """
    hwp.InitScan(Range=0xff)
    _, text = hwp.GetText()
    hwp.ReleaseScan()
    return len(text)


def 자간자동조정():
    """
    모든 라인을 순회하면서
    끝에 걸쳐친 단어를 탐색함.

    잘린 단어의 앞이 길면
    라인 전체의 자간을 줄이고,

    잘린 단어의 뒤가 길면
    라인 전체의 자간을 늘임.

    한 줄 문단이 되거나
    걸쳐진 단어가 없으면 종료.
    """
    while True:
        hwp.Run("MoveLineEnd")
        hwp.Run("MoveSelWordBegin")
        앞부분길이 = 현재선택영역_글자수()
        if 앞부분길이 == 0:  # 단어가 잘려있지 않으면 자간조정 중지
            break
        hwp.Run("MoveSelWordEnd")
        뒷부분길이 = 현재선택영역_글자수()
        if not (앞부분길이 and 뒷부분길이):  # 한 줄 문단이면 자간조정 중지
            hwp.Run("Cancel")
            break
        hwp.Run("MoveWordBegin")
        hwp.Run("MoveLineEnd")
        hwp.Run("MoveSelLineBegin")
        if 앞부분길이 >= 뒷부분길이:  # 앞이 길면
            hwp.Run("CharShapeSpacingDecrease")  # 라인 자간 -1%
        else:  # 뒤가 길면
            hwp.Run("CharShapeSpacingIncrease")  # 라인 자간 +1%
        hwp.Run("Cancel")


def 컨트롤_내부_자간조정():
    """
    표나 글상자 등 텍스트가 들어가는
    모든 영역의 자간을 조정하기 위함
    """
    area = 2
    while True:
        hwp.SetPos(area, 0, 0)
        if hwp.GetPos()[0] == 0:
            break
        while True:
            자간자동조정()
            hwp.Run("MoveLineEnd")
            hwp.Run("MoveNextPosEx")
            if hwp.GetPos()[0] == 0:
                break
        area += 1


def 끝위치추출():
    """
    본문 탐색 while문의 종료 조건으로
    "문서 끝에 도착하면 반복종료"를 구현하기 위해
    문서 끝 위치를 미리 추출해 둠
    """
    hwp.Run("MoveDocEnd")
    end_pos = hwp.GetPos()  # 종료위치 저장
    hwp.Run("MoveDocBegin")
    return end_pos


if __name__ == '__main__':
    hwp = 한글_시작()
    파일목록 = 파일선택()
    for 파일 in 파일목록:
        hwp.Open(파일)
        끝위치 = 끝위치추출()

        # 본문 자간조정
        while hwp.GetPos() != 끝위치:
            자간자동조정()
            hwp.Run("MoveLineEnd")
            hwp.Run("MoveNextPosEx")

        # 표 및 글상자 자간조정
        컨트롤_내부_자간조정()
        print("자간조정 작업 끝!")
        hwp.SaveAs(Path=hwp.Path.replace(".hwp", "(자간조정).hwp"), Format=hwp.XHwpDocuments.Item(0).Format)

어느 정도 프로그램 보완이 완성되는 것 같으면
강의 말미에 설명영상을 추가하도록 하겠습니다.

부디 도움이 되었길 바라고,
질문 전혀 많지 않았는데요?^^
오히려, 배려를 담아 질문해 주셔서 감사한 마음이 컸습니다.

 

행복한 하루 되세요^^

혁님의 프로필

질문자

2023.03.01

감사합니다! 잘 작동이 됩니다 ㅎㅎ 작성해주신 내용도 잘 이해할 수 있도록 공부해보겠습니다. 항상 감사드립니다 ㅎㅎ