왜 PDF를 Markdown으로 변환하는 것이 보기보다 더 어려운가

발행: (2026년 1월 2일 오전 10:20 GMT+9)
10 min read
원문: Dev.to

Source: Dev.to

소개

사람들이 “PDF를 Markdown으로” 변환한다는 말을 들으면, 보통 간단한 텍스트 변환 작업처럼 들립니다.
실제로 PDF를 다루는 일—특히 구조를 신경 쓸 경우—은 모든 개발자 도구가 마주할 수 있는 가장 까다로운 파싱 문제 중 하나입니다.

문서 작업과 LLM 워크플로우에서 이 문제를 반복해서 겪었기 때문에, 이를 해결하기 위한 도구를 만들었습니다. 이 글에서는 왜 이 문제가 어려운지, 보통 어떤 문제가 발생하는지, 그리고 구조를 인식하는 파이프라인이 Markdown 출력물을 훨씬 더 활용 가능하게 만드는 방법을 살펴보겠습니다.

PDF 구조 기본

PDF 파일은 HTML이나 Markdown처럼 단락, 헤더, 표를 고수준 개념으로 인코딩하지 않습니다. 대신 다음을 포함합니다:

  • 특정 (x, y) 좌표에 텍스트를 그리는 명령
  • 이미지, 도형, 경로를 위한 그리기 명령
  • 변환 행렬
  • 선택적 메타데이터

포맷에 “단락” 객체가 없습니다. 모든 구조는 다음을 통해 추론해야 합니다:

  • 기하학적 근접성
  • 글꼴 크기 및 스타일
  • 정렬 및 그룹화

이 때문에 PDF → Markdown 변환은 단순한 “텍스트 추출”과 근본적으로 다릅니다.

PDF 유형

네이티브 PDF (텍스트 객체)

많은 PDF에는 원시 텍스트 객체가 포함되어 있어 그대로 읽을 수 있습니다:

  • PyMuPDF 또는 pdf.js와 같은 라이브러리를 통해 추출
  • 스팬별 위치(바운딩 박스) 포함
  • 글꼴, 글리프, 레이아웃 순서 보존

이는 구조 분석에 가장 적합한 경우입니다.

스캔된 PDF (래스터 이미지)

일부 PDF는 스캔 이미지의 집합에 불과합니다:

  • 텍스트 객체가 전혀 없으므로 모든 내용이 OCR을 통해 추출되어야 함
  • 레이아웃 메타데이터가 남아 있지 않음

이 경우 블록 정보가 없으므로 시각적 단서를 통해 문서 구조를 재구성해야 합니다. 어떤 경로를 선택할지 감지하는 것이 필수적인 첫 단계이며, 스캔된 문서와 네이티브 문서를 동일하게 처리하면 품질이 낮은 결과가 나옵니다.

일반적인 실패 모드

  • Flat text dumps – 많은 PDF → Markdown 도구가 텍스트를 읽는 순서대로 단순히 덤프하여 다음과 같은 결과를 초래합니다:

    • 잘못된 위치에 삽입된 줄 바꿈
    • 단락 경계 손실
    • 깨진 목록
    • 의미적 그룹화 누락

    출력은 Markdown 형식일 수 있지만, 실제로 작업하기는 거의 쉽지 않습니다.

  • Unnecessary OCR on native PDFs – 이미 텍스트가 포함된 PDF에 OCR을 적용하면:

    • 노이즈가 발생합니다
    • 포맷이 손실됩니다
    • 불필요한 전처리가 추가됩니다
  • Orphaned images – 흐름에서 이미지가 어디에 위치해야 하는지 모른 채 이미지를 추출하면 의미가 손실됩니다. Markdown에서는 이미지 배치가 중요하기 때문입니다.

레이아웃‑인식 파이프라인

핵심 아이디어는 PDF를 레이아웃 블록들의 집합으로 취급하는 것입니다. 각 블록은 다음을 포함합니다:

  • Bounding box
  • Page number
  • Content type (text / image / table / code)

파이프라인은 다음과 같이 진행됩니다:

  1. Sort 모든 블록을 (page, y, x) 오름차순으로 정렬합니다.
  2. Merge 스팬을 문단으로, 문단을 더 높은 수준의 구조로 병합합니다.
  3. Reconstruct 기하학적 휴리스틱을 이용해 리스트와 테이블을 재구성합니다.
  4. Insert 이미지가 텍스트 블록과 상대적으로 가장 잘 맞는 위치에 삽입합니다.

이 접근 방식은 숨겨진 의미를 마법처럼 발견해 내지는 않지만, 다음과 같은 Markdown을 생성합니다:

  • 읽기 쉬움
  • 몇 시간에 달하는 정리 작업이 필요 없음
  • 평면 추출보다 구조적 관계를 더 잘 보존

스캔된 PDF 처리

네이티브 텍스트 블록이 없을 경우, 모든 블록은 시각적 콘텐츠에서 파생되어야 합니다:

  • 레이아웃 정보가 손실 → OCR이 텍스트를 제공함.
  • 블록은 시각적 영역 감지를 통해 구축됨.

이는 네이티브 파싱과 근본적으로 다른 프로세스이며, 그렇게 취급해야 합니다. 도구들은 자동으로 스캔된 PDF를 감지하고 OCR 기반 추출로 라우팅합니다. OCR 결과는 네이티브 텍스트 추출보다 본질적으로 노이즈가 많지만, 단순 파싱이 실패하는 경우에도 사용 가능한 Markdown을 제공합니다.

테이블

PDF는 테이블을 명시적으로 나타내지 않습니다. 구조는 다음을 통해 추론합니다:

  • 열 정렬
  • 행 근접성
  • 격자선(있는 경우)

표준 Markdown 테이블은 rowspan/colspan을 표현할 수 없습니다. 복잡한 레이아웃의 경우 HTML 테이블을 대체로 사용하는 것이 종종 바람직합니다.

목록

불릿과 들여쓰기는 시각적 단서일 뿐입니다. 중첩 리스트를 재구성하려면 다음이 필요합니다:

  • 불릿 패턴 감지
  • 상대 들여쓰기 비교
  • 라인 간 그룹화

이러한 휴리스틱은 신중히 구현하면 꽤 잘 작동합니다.

코드 블록

코드는 종종 다음과 같은 특징으로 구분됩니다:

  • 고정폭 글꼴
  • 일관된 수직 간격
  • 목록/표 마커의 부재

코드를 정확히 구분하면 기술 문서의 출력 가독성을 향상시킵니다.

제한 사항

PDF에서 Markdown으로의 완벽한 라운드트립은 엄밀히 말하면 불가능합니다:

  • PDF에는 의미론적 문서 모델이 없습니다.
  • OCR은 고유한 오류율을 가지고 있습니다.
  • 레이아웃 추론은 휴리스틱 방식입니다.

그럼에도 불구하고 “충분히 좋은” 솔루션은 다음과 같은 경우입니다:

  • Markdown이 읽기 쉽습니다.
  • 구조적 요소가 손상되지 않습니다.
  • 이미지와 표가 고립되지 않습니다.
  • 최소한의 수동 정리가 필요합니다.

문서화, 필기, 혹은 LLM 워크플로우에서는 이것이 픽셀 단위의 완벽한 정확성보다 훨씬 중요합니다.

결론

PDF는 인쇄와 시각적 충실도를 위해 설계되었으며, 의미적 재사용을 위해 설계된 것이 아닙니다. PDF를 Markdown으로 변환하는 것은 본질적으로 기하학에서 구조로의 번역 문제입니다. 구조‑인식 파이프라인은 단순 추출보다 이 번역을 훨씬 더 신뢰할 수 있게 만들며, 원본 PDF와 스캔된 PDF 모두를 견고하게 처리하는 것이 실제 사용에 필수적입니다.

이 아이디어들의 실용적인 구현을 직접 보고 싶다면, 를 확인해 보세요. 피드백 및 엣지‑케이스 예시는 언제든 환영합니다.

Back to Blog

관련 글

더 보기 »

C#에서 RTF를 PDF로 변환하기

개요 RTF(Rich Text Format)는 문서 편집 및 데이터 교환에 널리 사용되는 크로스‑플랫폼 형식입니다. 반면 PDF는 문서 배포에 이상적입니다.