직접 만들고, 내 생각을 더하다
세상의 트렌드를 읽고 싶어하는 한 사람으로, 목공 DIY를 좋아하고, AI, n8n을 사용해 자동화 프로세스를 배우고 있다.

HWP-MD 변환 개선 : HWP 표 변환 개선 여정

HWP 파일을 마크다운으로 변환 시 표 구조 손실 문제 해결 방법을 소개합니다. Python과 olefile 라이브러리를 활용한 표 추출 기법, 실제 구현 코드, 그리고 변환 품질 개선 팁을 상세히 다룹니다.

완벽한 변환은 존재할까? HWP 표 변환 개선 여정 🎯

"90%는 쉽다. 하지만 99%까지 가는 마지막 10%가 전체 시간의 90%를 차지한다"

📝 시작은 단순했다

HWP 파일을 마크다운으로 변환하는 프로젝트를 시작했을 때, 난 이렇게 생각했다.
"텍스트 추출이야 뭐 어렵겠어?" 그런데 막상 표(테이블)를 만나는 순간, 모든 게 달라졌지.

정말 여러 번의 개선을 시도해 봤다.
여러 번, 여러 번, 여러 번(이제 몇번이나 시도했는지 세지도 못하겠음).
하지만 정확하게 변환하는 것은 불가능했다. 왜냐고? 가장 근본적인 문제를 발견했거든.

💡 핵심 문제: 마크다운 포맷 자체가 셀 병합이나 셀 안의 셀 같은 복잡한 표 구조를 처리하지 못한다는 거다.

🔍 첫 번째 해결책: 텍스트만 추출

그래서 처음엔 타협했다.
"그래, 완벽한 변환은 포기하고 텍스트만 깔끔하게 추출하자."
기본적으로 HWP 표 변환은 텍스트만 추출하는 것으로 정리했지.

이 방식은 나름 작동했다.
최소한 내용은 다 가져올 수 있었으니까.
하지만 뭔가 아쉬웠어. 표의 구조가 완전히 무너지니까 말이야.
특히 복잡한 표 구조의 내용이나 기획서 같은 문서는 표 구조가 정말 중요한데...

💡 돌파구: 옵시디언의 HTML 지원

그러던 중 흥미로운 사실을 발견했다.
옵시디언에서는 HTML이 포함된 마크다운 파일을 잘 읽어들인다는 거야! 이건 또 다른 게임의 시작이었지. 😊

생각해 보자.
마크다운 포맷으로는 셀 병합을 표현할 수 없지만, HTML 테이블로는 가능하잖아?
그래서 표 형식은 HTML로 작성된 상태로 변환하는 기능을 추가했다.

<table>
  <tr>
    <td rowspan="2">병합된 셀</td>
    <td>일반 셀</td>
  </tr>
  <tr>
    <td>일반 셀</td>
  </tr>
</table>

옵시디언에서 테스트해봤다. 와... 만족스럽게 변환되더라!
셀 병합도 잘 되고, 복잡한 표 구조도 거의 원본 그대로 나타났어.
드디어 해냈다고 생각했지.

😅 그런데... 노션은 달랐다

문제는 노션이었다.
노션은 HTML이 포함된 마크다운 파일을 제대로 읽어들이지 못했어.
표가 깨지거나 이상하게 나타나는 거야.

물론 방법이 아예 없는 건 아니었어. 옵시디언에서 읽어들인 내용을 Ctrl+C, Ctrl+V로 노션에 붙여 넣으면 어느 정도 테이블을 유지하면서 가져올 수 있었거든. 하지만 솔직히 만족스럽지는 않았다.

  • 처리 단계가 늘어났어 (HWP → 옵시디언 → 노션)
  • 복사-붙여넣기라는 수동 작업이 추가됐어
  • 여전히 완벽하지 않았어

그래서 결론을 내렸어.
노션 사용자들은 텍스트만 추출해서 변환하는 게 더 좋겠다는 생각이 들었고, 옵시디언 사용자들은 HTML 테이블이 포함된 변환이 좋겠다는 생각이 들었지.

[ 옵시디언노션에서의 표 변환 결과]

🔧 해결책: 토글 버튼으로 선택의 자유를

그래서 만들었다. 토글 버튼. 사용자가 둘 중에 하나를 선택할 수 있게 말이야.

📋 변환 옵션

  1. 옵시디언 모드: HTML 테이블 포함 (셀 병합 지원)
  2. 노션 모드: 순수 텍스트 추출 (호환성 최우선)

이렇게 하니까 각자의 환경에 맞는 최적의 결과를 얻을 수 있게 됐다.
옵시디언 사용자는 구조를 유지하고, 노션 사용자는 깔끔한 텍스트를 얻는 거지.

HWPX 파일은 어떻게 했냐고? HWPX는 기본적으로 변환이 잘 되기 때문에 전체 MD 포맷으로 변환하도록 했다. 물론 셀 병합은 여전히 안 되는 점이 있어서 이건 첫 화면에 안내하도록 했지.

🤔 90%에서 99%로 가는 길

여기서 깨달은 게 있어.
90% 수준으로 만드는 것은 그래도 어렵지 않아.
기본 기능 구현하고, 대부분의 케이스를 처리하면 돼.
하지만 내가 만족하는 99%까지 끌어올리는 데는 정말 많은 노력과 인내가 필요하더라.

"이제 거의 다 왔어!"라고 생각하면 또 다른 문제가 나타나.
셀 병합 문제를 해결하면 중첩 테이블 문제가 나타나고, 그걸 해결하면 특수 문자 인코딩 문제가 나타나고... 끝이 없어. 😅

질문: 어느 정도까지 완성해야 할까? 쉽지 않은 문제다. 난 계속 앞으로 나아가고 싶기 때문에 끊임없이 개선하게 돼. 그렇게 하다 보면 정말 어려운 고비의 순간이 나를 막고 또 막아.

🤖 AI와 함께하는 개발의 양면성

이것도 언젠가 AI가 더 향상된다면 나아지겠지 생각해 본다. 하지만 생각해보니 재밌는 게 있어.
인간은 만족을 모르잖아? 우리는 태생적으로 반복되는 일상에는 흥미를 급격하게 잃어.

새로운 변화와 도파민이 분비되는 과정이 있어야 삶이 충족되는 게 아닐까?
그래서 항상 더 나아지거나 더 새로운 무언가를 찾게 되는 거 같아.
그렇기 때문에 완성이란 것은 존재하지 않을 거야.

예전에는 코딩을 못해서 포기했던 일들이 가능해지고, 익숙해지면서 더 많은 것을 원하게 돼.
오히려 AI가 내 말을 못 알아듣는다고 "이 바보!"라며 화를 내게 되더라고. 🤦‍♂️

내가 직접 코딩하면 백 년이 걸려도 못 할 일을 AI가 몇 분~몇십 분 만에 해내고 있는데 말이야.
참 아이러니하지?

✨ 욕심을 내려놓으며

그래서 결심했어. 욕심을 좀 내려놓아야겠다라고.
100% 완벽한 변환은 아닐지라도, 90%의 사용자가 만족할 수 있는 수준이면 충분한 거 아닐까?

어쨌든 여러 시행착오를 거치며, 내가 원하는 기능 하나를 추가했어.
옵시디언과 노션 사용자 모두 각자의 환경에 맞는 텍스트 파일을 얻게 됐지.

🎯 이번 개선의 핵심

  • HTML 테이블 변환 옵션 추가 (옵시디언 최적화)
  • 순수 텍스트 추출 옵션 유지 (노션 호환성)
  • 토글 버튼으로 사용자 선택권 제공
  • HWPX 전용 최적화 경로 구현

🚀 다음 도전을 향해

완벽함을 추구하는 건 좋지만, 그 과정에서 지치면 안 되겠더라.
작은 개선 하나하나가 모여서 결국 더 나은 도구가 되는 거니까.

다음 편에서는 HWP 파일 내의 이미지 추출과 변환에 대해 다뤄볼 예정이야.
표는 어느 정도 해결했으니, 이제 이미지 차례지 뭐. 😊
(갈수록 복잡해져서 언제 구현될지 장담은 못해)

혹시 여러분도 HWP 표 변환하면서 비슷한 고민 했어?
댓글로 경험 공유해 줘! 같이 더 나은 방법을 찾아보자고. 🙌

댓글 쓰기