kordoc 4.4.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +18 -3
  2. package/dist/{-R6NUMPRV.js → -CWYIC4ES.js} +9 -9
  3. package/dist/{chunk-W6CUD7V3.js → chunk-2CF2WXBG.js} +3 -3
  4. package/dist/{chunk-YOZ7ZRCD.js → chunk-45EUJ2P6.js} +310 -76
  5. package/dist/chunk-45EUJ2P6.js.map +1 -0
  6. package/dist/{chunk-HNRULYUH.js → chunk-7ZQKECQT.js} +2 -2
  7. package/dist/{chunk-RZURSA4N.js → chunk-CBUC73JM.js} +3 -3
  8. package/dist/chunk-DCZVOIEO.cjs.map +1 -1
  9. package/dist/{chunk-ONS7JKVA.js → chunk-EYLOFSA5.js} +2 -2
  10. package/dist/{chunk-ONS7JKVA.js.map → chunk-EYLOFSA5.js.map} +1 -1
  11. package/dist/{chunk-YVYU267E.js → chunk-FT2EXMMP.js} +16 -5
  12. package/dist/chunk-FT2EXMMP.js.map +1 -0
  13. package/dist/{chunk-V35DRUJC.js → chunk-GCHH4WHT.js} +2 -2
  14. package/dist/{chunk-UDGPM5R5.cjs → chunk-GLPLLT4Q.cjs} +4 -4
  15. package/dist/chunk-GLPLLT4Q.cjs.map +1 -0
  16. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  17. package/dist/{chunk-HFJF477F.js → chunk-M4I5F6GK.js} +16 -5
  18. package/dist/chunk-M4I5F6GK.js.map +1 -0
  19. package/dist/{chunk-GHGZU2LQ.js → chunk-NBOVSNSR.js} +2 -2
  20. package/dist/{chunk-AB322K3O.cjs → chunk-TCPO6XAY.cjs} +17 -6
  21. package/dist/chunk-TCPO6XAY.cjs.map +1 -0
  22. package/dist/{chunk-5KLE3U23.js → chunk-TP4P7M4I.js} +2 -2
  23. package/dist/{chunk-P7YPCK7C.js → chunk-TTEHX4FN.js} +2 -2
  24. package/dist/{chunk-SKM6KZUH.cjs → chunk-U3ZNF4SO.cjs} +9 -9
  25. package/dist/chunk-U3ZNF4SO.cjs.map +1 -0
  26. package/dist/{chunk-A73RMJ6B.js → chunk-UEWW3DH2.js} +1 -1
  27. package/dist/{chunk-A73RMJ6B.js.map → chunk-UEWW3DH2.js.map} +1 -1
  28. package/dist/{chunk-H2KMJOB6.cjs → chunk-UQ6KDJWE.cjs} +2 -2
  29. package/dist/chunk-UQ6KDJWE.cjs.map +1 -0
  30. package/dist/{chunk-65DYCXGC.js → chunk-WDIPTY3Q.js} +3 -3
  31. package/dist/{chunk-XCIC7U6Y.js → chunk-XYSTZIIL.js} +2 -2
  32. package/dist/{chunk-QXYB74QF.js → chunk-ZHNUH2IW.js} +2 -2
  33. package/dist/chunk-ZV5OKQ3Z.cjs.map +1 -1
  34. package/dist/chunks-EYDY4Y6O.js +10 -0
  35. package/dist/cli.js +54 -19
  36. package/dist/cli.js.map +1 -1
  37. package/dist/formula-CG4S7TWO.cjs.map +1 -1
  38. package/dist/{image-ocr-U2DRRFL3.js → image-ocr-BWQIUUVC.js} +13 -5
  39. package/dist/image-ocr-BWQIUUVC.js.map +1 -0
  40. package/dist/{image-ocr-XC52AQDV.js → image-ocr-EDZOUU6Q.js} +14 -6
  41. package/dist/image-ocr-EDZOUU6Q.js.map +1 -0
  42. package/dist/{image-ocr-F2BQA26V.cjs → image-ocr-KZ4MGVJ3.cjs} +19 -11
  43. package/dist/image-ocr-KZ4MGVJ3.cjs.map +1 -0
  44. package/dist/index.cjs +647 -413
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +42 -2
  47. package/dist/index.d.ts +42 -2
  48. package/dist/index.js +305 -71
  49. package/dist/index.js.map +1 -1
  50. package/dist/mcp.js +63 -30
  51. package/dist/mcp.js.map +1 -1
  52. package/dist/page-range-P7SDW6LR.cjs.map +1 -1
  53. package/dist/{parser-TFPGQWCC.js → parser-6OJOFJ64.js} +5 -5
  54. package/dist/{parser-FFQN67O6.cjs → parser-7G2QFIYZ.cjs} +24 -24
  55. package/dist/parser-7G2QFIYZ.cjs.map +1 -0
  56. package/dist/{parser-ESGFWWCT.js → parser-JLEKXA2Z.js} +6 -6
  57. package/dist/pdf-ocr-364VNE6N.cjs +13 -0
  58. package/dist/pdf-ocr-364VNE6N.cjs.map +1 -0
  59. package/dist/{pdf-ocr-WE5TMRFU.js → pdf-ocr-OWUZLWQ3.js} +5 -5
  60. package/dist/pdf-ocr-YQGMCT53.js +12 -0
  61. package/dist/{profile-io-O6BDCUJN.js → profile-io-FMPT6VEZ.js} +3 -3
  62. package/dist/{rasterize-V22VCCE7.js → rasterize-LARCX6CS.js} +2 -2
  63. package/dist/render-4WHQ7JCX.js +10 -0
  64. package/dist/seal-BX6YA6PI.js +10 -0
  65. package/dist/{watch-HGKBICED.js → watch-Y2VKD2MN.js} +9 -9
  66. package/package.json +1 -1
  67. package/dist/chunk-AB322K3O.cjs.map +0 -1
  68. package/dist/chunk-H2KMJOB6.cjs.map +0 -1
  69. package/dist/chunk-HFJF477F.js.map +0 -1
  70. package/dist/chunk-SKM6KZUH.cjs.map +0 -1
  71. package/dist/chunk-UDGPM5R5.cjs.map +0 -1
  72. package/dist/chunk-YOZ7ZRCD.js.map +0 -1
  73. package/dist/chunk-YVYU267E.js.map +0 -1
  74. package/dist/chunks-QMGCI5DG.js +0 -10
  75. package/dist/image-ocr-F2BQA26V.cjs.map +0 -1
  76. package/dist/image-ocr-U2DRRFL3.js.map +0 -1
  77. package/dist/image-ocr-XC52AQDV.js.map +0 -1
  78. package/dist/parser-FFQN67O6.cjs.map +0 -1
  79. package/dist/pdf-ocr-4R646OO6.js +0 -12
  80. package/dist/pdf-ocr-UQBZH3HE.cjs +0 -13
  81. package/dist/pdf-ocr-UQBZH3HE.cjs.map +0 -1
  82. package/dist/render-3BSVTTZE.js +0 -10
  83. package/dist/seal-6ZSEJVOD.js +0 -10
  84. /package/dist/{-R6NUMPRV.js.map → -CWYIC4ES.js.map} +0 -0
  85. /package/dist/{chunk-W6CUD7V3.js.map → chunk-2CF2WXBG.js.map} +0 -0
  86. /package/dist/{chunk-HNRULYUH.js.map → chunk-7ZQKECQT.js.map} +0 -0
  87. /package/dist/{chunk-RZURSA4N.js.map → chunk-CBUC73JM.js.map} +0 -0
  88. /package/dist/{chunk-V35DRUJC.js.map → chunk-GCHH4WHT.js.map} +0 -0
  89. /package/dist/{chunk-GHGZU2LQ.js.map → chunk-NBOVSNSR.js.map} +0 -0
  90. /package/dist/{chunk-5KLE3U23.js.map → chunk-TP4P7M4I.js.map} +0 -0
  91. /package/dist/{chunk-P7YPCK7C.js.map → chunk-TTEHX4FN.js.map} +0 -0
  92. /package/dist/{chunk-65DYCXGC.js.map → chunk-WDIPTY3Q.js.map} +0 -0
  93. /package/dist/{chunk-XCIC7U6Y.js.map → chunk-XYSTZIIL.js.map} +0 -0
  94. /package/dist/{chunk-QXYB74QF.js.map → chunk-ZHNUH2IW.js.map} +0 -0
  95. /package/dist/{chunks-QMGCI5DG.js.map → chunks-EYDY4Y6O.js.map} +0 -0
  96. /package/dist/{parser-TFPGQWCC.js.map → parser-6OJOFJ64.js.map} +0 -0
  97. /package/dist/{parser-ESGFWWCT.js.map → parser-JLEKXA2Z.js.map} +0 -0
  98. /package/dist/{pdf-ocr-4R646OO6.js.map → pdf-ocr-OWUZLWQ3.js.map} +0 -0
  99. /package/dist/{pdf-ocr-WE5TMRFU.js.map → pdf-ocr-YQGMCT53.js.map} +0 -0
  100. /package/dist/{profile-io-O6BDCUJN.js.map → profile-io-FMPT6VEZ.js.map} +0 -0
  101. /package/dist/{rasterize-V22VCCE7.js.map → rasterize-LARCX6CS.js.map} +0 -0
  102. /package/dist/{render-3BSVTTZE.js.map → render-4WHQ7JCX.js.map} +0 -0
  103. /package/dist/{seal-6ZSEJVOD.js.map → seal-BX6YA6PI.js.map} +0 -0
  104. /package/dist/{watch-HGKBICED.js.map → watch-Y2VKD2MN.js.map} +0 -0
package/README.md CHANGED
@@ -73,7 +73,7 @@ MCP 등록 대신 스킬(SKILL.md) 형태로 쓰려면:
73
73
  단순한 텍스트 추출을 넘어, **공문서 처리를 위한 모든 과정**을 자동화합니다.
74
74
 
75
75
  * **📄 어떤 문서든 마크다운으로**: `HWP3` (구버전), `HWP`(5.x), `HWPX`, `HWPML`, `PDF`, `XLS`, `XLSX`, `DOCX` 파일은 물론 `PNG`/`JPG`/`WebP` 이미지(자동 OCR)까지 즉시 `Markdown`으로 변환합니다. AI(LLM)가 문서를 읽고 분석하기 가장 좋은 상태로 만들어줍니다.
76
- * **📊 복잡한 표(Table) 완벽 재현**: 선이 없는 PDF나 복잡하게 병합된 HWP 표도 구조를 분석하여 정확한 마크다운 테이블로 복원합니다. 법령 개정안 PDF의 신구조문대비표도 통째로 살립니다 (v3.16.2).
76
+ * **📊 복잡한 표(Table) 복원 숫자로 잠금**: 병합·중첩 표를 구조 그대로 살립니다. HWPX 코퍼스 291문서 **표 1,673/1,673·셀 27,714/27,714 무손실**(독립 추출기 대조 게이트 1.0), 동일문서 hwpx↔pdf 대조(6쌍 69표)는 **매칭 98.6%·완전일치 65.2%**. 선 없는 PDF 표도 감지해 복원하고, 법령 개정안 PDF의 신구조문대비표도 통째로 살립니다 (v3.16.2).
77
77
  * **🔍 신구대조표 자동 생성**: 두 문서의 차이점을 분석하여 무엇이 바뀌었는지 한눈에 보여줍니다. (HWP와 HWPX 간의 비교도 가능!)
78
78
  * **📝 마크다운을 다시 HWPX로**: AI가 작성한 내용을 다시 보고서 양식(`HWPX`)으로 되돌려줍니다. 이제 복사-붙여넣기 노가다에서 해방되세요.
79
79
  * **🏛️ 정부 표준 공문서 생성 (v4.0)**: 실제 정부 양식 16종 + 실결재 기안문 60건을 전수 디코드·대조해 만든 공문서 엔진. 개조식 보고서(표지·목차 배너·로마숫자 장헤더·쪽번호·결재란), 기안문(별지 제1호서식 두문·결문, "끝." 자동), 공고문·보도자료 프리셋, 항목부호 8단계(1. 가. 1) 가)…) 자동, 공문서 표기법 검수 13룰(`kordoc lint`)까지 — 한글 COM 실렌더로 조판까지 실측 검증했습니다.
@@ -86,13 +86,28 @@ MCP 등록 대신 스킬(SKILL.md) 형태로 쓰려면:
86
86
 
87
87
  ---
88
88
 
89
+ ## v4.5.0 변경사항
90
+
91
+ - **📄 페이지 옵션 신설**: 용지 크기(A4·A3·B4·B5·Letter·커스텀 mm)·**가로 방향**·**다단**(1~8단)·**머리말/꼬리말**을 생성 옵션으로 지원합니다 — API `page`, CLI `--paper/--landscape/--columns/--header/--footer`, MCP `generate_document` 동명 파라미터. 머리말/꼬리말은 실물 저장본과 동일한 `<hp:header>`/`<hp:footer>` 구조라 한글에서 그대로 조판됩니다.
92
+ - **🔗 하이퍼링크 생성**: `[text](url)`이 텍스트로 뭉개지지 않고 실측 6-param `HYPERLINK` 필드로 방출됩니다 — 한글에서 실제 클릭 가능, 재파싱하면 `[text](url)` 복원(왕복 보존). 표 셀 안 링크 포함.
93
+ - **📎 각주 개체 생성**: `[^1]` 마커 + `[^1]: 본문` 정의가 진짜 `<hp:footNote>` 개체로 방출돼 한글이 페이지 하단에 각주를 조판합니다.
94
+ - **🖼️ 이미지 실데이터 임베드**: `images` 옵션(url→바이트)·`data:` URI·CLI/MCP `--image-dir`로 PNG/JPEG/GIF/BMP를 BinData에 실제로 넣습니다 — 픽셀 치수 자동 환산(96dpi)·본문폭 초과 시 비례 축소. 바이트가 없으면 종전처럼 참조를 placeholder로 보존합니다.
95
+ - **🔍 OCR 저신뢰 폐기 관측**: 내장 OCR이 신뢰도<0.5로 조용히 버리던 라인 수를 `OCR_LOW_CONF` 경고로 노출합니다.
96
+ - **📏 스캔 표 실측 채점 교정**: 표 구조가 아닌 정답(클립아트 장식 그리드·1×1 텍스트박스, 비어있지 않은 셀 <3)을 모수에서 제외하고 제외 수를 투명하게 노출 — 교정 후 스캔 표 매칭 **71.4%**·cellF1 **0.595** (문자 recall·CER은 v4.4.1 실측과 동일).
97
+
98
+ ## v4.4.1 변경사항
99
+
100
+ - **🖼️ MCP 이미지 입력 수리**: `parse_document` 등 파싱 도구가 PNG/JPG/WebP를 확장자 단계에서 거부하던 것(CLI는 정상, MCP만 차단)을 해제 — 스크린샷·스캔 이미지를 MCP로도 바로 변환합니다.
101
+ - **📏 내장 OCR 정확도 첫 실측** (`bench/ocr-accuracy.mjs` 신설): 코퍼스 PDF 41문서 82페이지, 클린 텍스트층 대조 — 문자 recall 90.0%(글꼴 미렌더 1건 제외 94.0%)·precision 95.1%, 한글 음절 recall median 99.9%, 0.96s/페이지. 스캔 표 구조는 매칭 63%·cellF1 0.50로 아직 약한 지점입니다. 정답이 클린 렌더라 실스캔 노이즈는 미반영(상한치).
102
+
89
103
  ## v4.4.0 변경사항
90
104
 
91
105
  - **🔑 비밀번호 문서 열기 (#59)**: 열기 암호가 걸린 **HWPX·HWP3·HWP5** 문서를 `--password`(CLI) / `password`(API·MCP)로 엽니다. 세 포맷의 암호화 방식이 각각 다릅니다 — HWPX는 ODF 표준(AES-256-CBC + PBKDF2), HWP3는 단일 DES-ECB, HWP5는 EncryptVersion 4의 비트 단위 CFB. 틀린 비밀번호는 성공으로 위장하지 않고 `ENCRYPTED`로 실패합니다. (한컴 DRM 문서보안은 별개라 해당 없음, @jangster77 제보)
92
106
  - **🩹 HWP3 본문 대량 유실 수리**: 그림 뒤에 오는 캡션 문단 리스트를 읽지 않아 그림 하나당 43바이트씩 스트림이 어긋났고, 어긋난 자리가 "문단 끝" 표식으로 읽히면 **경고 없이** 나머지를 통째로 버렸습니다. 945KB 문서가 0자로 나오던 수준입니다(rhwp 대조 실측 6종 복구, 최대 100만 자). 표 셀 상한 256도 실존 문서(367셀)를 죽여 잔여 스트림 기준으로 교체했습니다.
93
107
  - **🔤 CDATA 텍스트 소실 수리**: `<hp:t><![CDATA[본문]]></hp:t>` 로 저장된 텍스트를 경고 없이 버리던 결함 — 공용 XML 헬퍼에 있어 HWPX·HWPML·DOCX 세 포맷에 걸쳐 있었습니다.
94
108
  - **🔣 사라지던 글자 복원**: 한컴 검증 PUA 11종(결재란 `(인)`, 편람 글머리표, 사각 안 숫자 ①~⑳ 등)과 HWP3 johab 매핑 2종(표 셀 글머리표 ▸, 머리말 회사명) — 매핑에 없는 코드는 삭제되는 구조라 누락이 곧 글자 증발이었습니다.
95
- - **🐛 외**: 동명 누름틀이 여러 곳에 있는 서식에서 `require_unique`가 곳도 채우지 않던 것, 수식 토큰이 `constructor`·`toString`이면 출력이 오염되던 프로토타입 체인 결함.
109
+ - **ᄒᆞᆫ HWP3 아래아(옛한글) 복원**: 완성형에 대응 음절이 없어 통째로 빠지던 아래아 음절('ᄒᆞᆫ글 97' 등)을 한컴 HWP5/HWPX 변환본과 같은 자모열(초성+ᆞ+종성)로 보존합니다.
110
+ - **🐛 그 외**: 동명 누름틀이 여러 곳에 있는 서식에서 `require_unique`가 한 곳도 채우지 않던 것, 수식 토큰이 `constructor`·`toString`이면 출력이 오염되던 프로토타입 체인 결함, 빈 셀 채우기가 엔티티(`&#32;`) 원문을 지우던 것(fail-closed 통일), fill 계열 ZIP 폭탄 가드, CLI `--format json`의 실패 JSON 출력(원인 코드 포함). npm 배포본에 NOTICE·THIRD_PARTY 라이선스 고지도 포함됩니다.
96
111
 
97
112
  ## v4.3.0 변경사항
98
113
 
@@ -377,7 +392,7 @@ MCP 등록 대신 스킬(SKILL.md) 형태로 쓰려면:
377
392
 
378
393
  ## v2.9.0 변경사항
379
394
 
380
- - **📊 PDF 텍스트 품질 신호 + OCR 필요 판정** — PDF는 텍스트층이 있어도 ToUnicode/CMap 이 깨져 한글이 깨진 글리프로 떨어지거나 NUL 등 제어문자가 섞이는 경우가 많습니다. `parsePdf` 결과에 페이지별 품질 신호(`pageQuality`)와 문서 요약(`qualitySummary`)을 추가 — `needsOcr`/`ocrReason` 으로 OCR 큐 자동 라우팅이 가능. kordoc OCR 기본 탑재하지 않고 **신호만** 노출합니다. 전국 지자체 주요업무계획 PDF 190건(45,399쪽) 대량 처리 중 도출. (아래 [PDF 텍스트 품질 신호](#pdf-텍스트-품질-신호-v290) 참고)
395
+ - **📊 PDF 텍스트 품질 신호 + OCR 필요 판정** — PDF는 텍스트층이 있어도 ToUnicode/CMap 이 깨져 한글이 깨진 글리프로 떨어지거나 NUL 등 제어문자가 섞이는 경우가 많습니다. `parsePdf` 결과에 페이지별 품질 신호(`pageQuality`)와 문서 요약(`qualitySummary`)을 추가 — `needsOcr`/`ocrReason` 으로 OCR 큐 자동 라우팅이 가능. (당시에는 신호만 노출 — **v4.2.0부터 내장 OCR 탑재**, 신호가 내장 OCR의 자동 발동 조건으로 쓰입니다.) 전국 지자체 주요업무계획 PDF 190건(45,399쪽) 대량 처리 중 도출. (아래 [PDF 텍스트 품질 신호](#pdf-텍스트-품질-신호-v290) 참고)
381
396
 
382
397
  ## v2.8.0 변경사항
383
398
 
@@ -52,9 +52,9 @@ import {
52
52
  resolveBuiltinTemplate,
53
53
  unknownFontWarnings,
54
54
  validateHwpx
55
- } from "./chunk-YOZ7ZRCD.js";
55
+ } from "./chunk-45EUJ2P6.js";
56
56
  import "./chunk-7FCNOKOR.js";
57
- import "./chunk-A73RMJ6B.js";
57
+ import "./chunk-UEWW3DH2.js";
58
58
  import "./chunk-MOL7MDBG.js";
59
59
  import {
60
60
  applySplices,
@@ -62,7 +62,7 @@ import {
62
62
  buildRangeSplices,
63
63
  placeSealHwpx,
64
64
  scanSectionXml
65
- } from "./chunk-RZURSA4N.js";
65
+ } from "./chunk-CBUC73JM.js";
66
66
  import {
67
67
  DEFAULT_REDACT_RULES,
68
68
  redactMarkdown,
@@ -70,10 +70,10 @@ import {
70
70
  } from "./chunk-DZIXKL7E.js";
71
71
  import {
72
72
  blocksToChunks
73
- } from "./chunk-HNRULYUH.js";
73
+ } from "./chunk-7ZQKECQT.js";
74
74
  import {
75
75
  blocksToMarkdown
76
- } from "./chunk-QXYB74QF.js";
76
+ } from "./chunk-ZHNUH2IW.js";
77
77
  import {
78
78
  SPACE_EM_FIXED,
79
79
  SPACE_EM_FONT,
@@ -83,11 +83,11 @@ import {
83
83
  renderHwpxToSvg,
84
84
  simulateWrap,
85
85
  simulateWrapKeepWord
86
- } from "./chunk-65DYCXGC.js";
87
- import "./chunk-5KLE3U23.js";
86
+ } from "./chunk-WDIPTY3Q.js";
87
+ import "./chunk-TP4P7M4I.js";
88
88
  import {
89
89
  VERSION
90
- } from "./chunk-P7YPCK7C.js";
90
+ } from "./chunk-TTEHX4FN.js";
91
91
  export {
92
92
  BUILTIN_TEMPLATES,
93
93
  DEFAULT_REDACT_RULES,
@@ -161,4 +161,4 @@ export {
161
161
  unknownFontWarnings,
162
162
  validateHwpx
163
163
  };
164
- //# sourceMappingURL=-R6NUMPRV.js.map
164
+ //# sourceMappingURL=-CWYIC4ES.js.map
@@ -3,11 +3,11 @@ import {
3
3
  HEADING_RATIO_H1,
4
4
  HEADING_RATIO_H2,
5
5
  HEADING_RATIO_H3
6
- } from "./chunk-A73RMJ6B.js";
6
+ } from "./chunk-UEWW3DH2.js";
7
7
  import {
8
8
  safeMax,
9
9
  safeMin
10
- } from "./chunk-P7YPCK7C.js";
10
+ } from "./chunk-TTEHX4FN.js";
11
11
 
12
12
  // src/pdf/image-regions.ts
13
13
  import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
@@ -3374,4 +3374,4 @@ export {
3374
3374
  extractPageBlocksWithLines,
3375
3375
  mergeCrossPageTables
3376
3376
  };
3377
- //# sourceMappingURL=chunk-W6CUD7V3.js.map
3377
+ //# sourceMappingURL=chunk-2CF2WXBG.js.map