영어 활동지는 단어가 잘리는 순간 읽는 과제 자체가 달라질 수 있다. 실제 PDF 생성기의 줄바꿈 코드를 읽고, 예쁜 문단보다 단어를 보존하는 규칙과 실패한 레이아웃을 알아내는 방법을 먼저 정리했다.

글자 수로 폭을 대신하지 않았다

같은 글자 수라도 좁은 글자와 넓은 글자의 조합에 따라 실제 길이는 다르다. 기존 생성기는 글꼴의 문자열 폭을 기준으로 단어를 한 줄에 넣을지 결정한다. 나는 이 판단을 독립 wrap 함수로 옮기되 폭을 재는 함수를 외부에서 받게 했다. 계산 규칙과 특정 글꼴을 연결하는 부분을 나눈 것이다.

테스트에서는 길이를 재는 단순 함수를 써서 경계를 확인하고 실제 PDF에서는 Helvetica의 폭 함수를 연결한다. 둘을 같은 증거로 부르지 않았다. 단순 폭 테스트는 알고리즘을 설명하고 실제 글꼴을 사용한 생성과 렌더링은 완성 결과를 확인한다. 다른 언어와 글꼴로 바꾸면 그 측정과 줄 나누기 정책을 다시 검수해야 한다.

긴 단어가 나오는 순서를 바꿔 봤다

한 줄의 첫 단어가 너무 길 때만 검사하면 앞에 짧은 단어가 있는 경우를 놓칠 수 있다. 새 함수는 모든 단어 자체의 폭을 먼저 확인한다. ok 뒤에 너무 긴 단어가 와도 폭을 넘으면 거절한다. 이미 채워진 줄을 비우거나 다음 줄로 옮긴다고 단어 자체가 짧아지는 것은 아니기 때문이다.

이 예제는 단어를 임의로 쪼개지 않는다. 교육 목적상 음절이나 낱말 단위 분절이 필요하다면 별도 정책을 정해야 한다. 오류가 났다는 사실은 글이 잘못됐다는 뜻이 아니라 현재 프레임과 글꼴, 내용 조합으로는 계약을 지킬 수 없다는 뜻이다. 제작자는 폭을 늘릴지 문장을 다듬을지 판단할 수 있다.

줄 수를 넘겼다고 내용을 버리지 않는다

최대 줄 수를 정해 두고 남은 내용을 잘라 버리면 PDF 생성은 성공해도 지시문 일부가 사라질 수 있다. wrap은 max_lines를 넘으면 실패한다. baselines도 마지막 줄이 예약한 하단보다 내려가면 거절한다. 두 검사는 각각 가로 배치와 세로 공간을 다루며 하나가 다른 하나를 대신하지 않는다.

같은 문장이 다른 글꼴에서 줄 수가 늘어날 수 있으므로 글꼴 변경 뒤에는 다시 생성해야 한다. 현재 예제는 줄 높이와 기준선을 선언하며 글자의 실제 높이를 모두 측정하지 않는다. 넉넉한 프레임과 실제 렌더링을 함께 확인한 이유다. 자동화된 검산 뒤에도 사람이 완성된 페이지를 읽는 단계가 필요하다.

실제 PDF로 판단을 남겼다

새 PDF는 한 페이지의 영어 지시문과 원·사각형·삼각형으로 구성했다. 원래 활동지의 문장과 이미지, 수업 사진을 가져오지 않았다. make_pdf는 명시한 출력 경로에만 쓰며 실행 기록 생성기는 파일을 만들지 않는다. 문서 작성과 기록 뷰어가 하는 일을 나눠 다운로드 후에도 예상하기 쉽게 했다.

생성 후 텍스트 추출로 문장과 사용 안내가 남았는지 확인하고 전체 페이지를 이미지로 렌더링해 눈으로 검토했다. 제목과 본문, 도형과 절취선, 안내와 페이지 번호가 겹치지 않았다. 실제 프린터의 축소 설정과 물리적 사용성을 검수한 것은 아니므로 결과 설명에 그 차이를 남겼다.

재사용할 때 남겨야 할 질문

소스와 ZIP 추출 환경에서 12개 테스트가 통과했다. 단어 보존과 긴 단어의 위치, 줄 수 초과와 하단 경계, 절취선 끝점이 포함된다. PDF 생성에는 ReportLab 4.4.9가 필요하고 순수 기하 테스트는 표준 라이브러리로 실행한다. 내려받기에는 실제 검토한 합성 PDF도 있다.

다른 자료를 만들 때는 문장을 줄이는 일이 학습 목표를 바꾸지 않는지 먼저 생각해야 한다. 작은 글꼴로 억지로 맞추기보다 읽는 사람과 과제의 의미를 기준으로 배치를 다시 정하는 편이 좋다. 나는 생성 성공 표시를 얻는 것보다 내용이 온전히 남았다는 근거와 바꾸어야 할 조건을 함께 공개하고 싶었다.

실패를 제작자에게 돌려주는 이유

자동 생성이 멈추면 운영자는 이유를 알아야 한다. 너무 긴 단어인지 줄 수 초과인지 구분하면 문장을 바꿀지 프레임을 바꿀지 판단할 수 있다. 오류를 묻고 파일만 내보내는 것보다 다음 편집의 근거를 남기는 방법이다. 이번 예제의 오류는 사용자에게 그대로 노출할 완성 문구가 아니므로 실제 화면에서는 의미를 풀어 안내해야 한다.