kordoc 3.4.0 → 3.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 (85) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +590 -584
  3. package/dist/{-56JCPGII.js → -GKNSTVEZ.js} +9 -5
  4. package/dist/{chunk-MOL7MDBG.js → chunk-3TBUDJDE.js} +1 -1
  5. package/dist/chunk-3TBUDJDE.js.map +1 -0
  6. package/dist/{chunk-YYKQN7SA.cjs → chunk-4JLD2IT7.cjs} +2 -2
  7. package/dist/chunk-4JLD2IT7.cjs.map +1 -0
  8. package/dist/{chunk-MHYDBT2Q.js → chunk-A4LSWJEC.js} +2 -2
  9. package/dist/chunk-A4LSWJEC.js.map +1 -0
  10. package/dist/{chunk-ZPLRG2SJ.js → chunk-AHDNELBR.js} +2 -2
  11. package/dist/chunk-AHDNELBR.js.map +1 -0
  12. package/dist/{chunk-GE43BE46.js → chunk-AIQ3ISQU.js} +1 -1
  13. package/dist/chunk-AIQ3ISQU.js.map +1 -0
  14. package/dist/{chunk-MEPHGCPQ.js → chunk-CFQLK3LM.js} +1 -1
  15. package/dist/chunk-CFQLK3LM.js.map +1 -0
  16. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  17. package/dist/{chunk-YFNBHLLM.js → chunk-GTCJQANY.js} +199 -30
  18. package/dist/chunk-GTCJQANY.js.map +1 -0
  19. package/dist/{chunk-DCZVOIEO.cjs → chunk-X34YWRL5.cjs} +1 -1
  20. package/dist/chunk-X34YWRL5.cjs.map +1 -0
  21. package/dist/cli.js +10 -27
  22. package/dist/cli.js.map +1 -1
  23. package/dist/{detect-RI2MQ33K.js → detect-NTR2FUEG.js} +2 -2
  24. package/dist/{formula-JCNF43NE.js → formula-KOQV353G.js} +1 -1
  25. package/dist/formula-KOQV353G.js.map +1 -0
  26. package/dist/{formula-RXVSQPXI.js → formula-MEDGYQXS.js} +1 -1
  27. package/dist/formula-MEDGYQXS.js.map +1 -0
  28. package/dist/{formula-5NKVS2LR.cjs → formula-ZYUDQHD3.cjs} +1 -1
  29. package/dist/formula-ZYUDQHD3.cjs.map +1 -0
  30. package/dist/index.cjs +368 -199
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +9 -3
  33. package/dist/index.d.ts +9 -3
  34. package/dist/index.js +197 -28
  35. package/dist/index.js.map +1 -1
  36. package/dist/mcp.js +42 -6
  37. package/dist/mcp.js.map +1 -1
  38. package/dist/page-range-CIRRJPXJ.js +7 -0
  39. package/dist/page-range-OF5I4PQY.js +8 -0
  40. package/dist/page-range-TPIRSA3J.cjs +8 -0
  41. package/dist/page-range-TPIRSA3J.cjs.map +1 -0
  42. package/dist/{parser-XDW6I25C.cjs → parser-25ISHR7Q.cjs} +18 -18
  43. package/dist/parser-25ISHR7Q.cjs.map +1 -0
  44. package/dist/{parser-VZL3MK5X.js → parser-LBLPN3KY.js} +5 -5
  45. package/dist/parser-LBLPN3KY.js.map +1 -0
  46. package/dist/{parser-PQDICHD5.js → parser-LMBDB7RM.js} +5 -5
  47. package/dist/parser-LMBDB7RM.js.map +1 -0
  48. package/dist/{provider-G4C2V2PD.cjs → provider-5K7O3Z2O.cjs} +1 -1
  49. package/dist/provider-5K7O3Z2O.cjs.map +1 -0
  50. package/dist/{provider-AKROB7WQ.js → provider-7H4CPZYS.js} +1 -1
  51. package/dist/provider-7H4CPZYS.js.map +1 -0
  52. package/dist/{provider-4ZJKV3DC.js → provider-H4WWSPOV.js} +1 -1
  53. package/dist/provider-H4WWSPOV.js.map +1 -0
  54. package/dist/{setup-57FB3LSP.js → setup-QSJ2INNS.js} +1 -1
  55. package/dist/setup-QSJ2INNS.js.map +1 -0
  56. package/dist/{watch-KERZCCNR.js → watch-77CYT54V.js} +5 -5
  57. package/dist/watch-77CYT54V.js.map +1 -0
  58. package/package.json +98 -98
  59. package/dist/chunk-DCZVOIEO.cjs.map +0 -1
  60. package/dist/chunk-GE43BE46.js.map +0 -1
  61. package/dist/chunk-MEPHGCPQ.js.map +0 -1
  62. package/dist/chunk-MHYDBT2Q.js.map +0 -1
  63. package/dist/chunk-MOL7MDBG.js.map +0 -1
  64. package/dist/chunk-YFNBHLLM.js.map +0 -1
  65. package/dist/chunk-YYKQN7SA.cjs.map +0 -1
  66. package/dist/chunk-ZPLRG2SJ.js.map +0 -1
  67. package/dist/formula-5NKVS2LR.cjs.map +0 -1
  68. package/dist/formula-JCNF43NE.js.map +0 -1
  69. package/dist/formula-RXVSQPXI.js.map +0 -1
  70. package/dist/page-range-737B4EZW.js +0 -8
  71. package/dist/page-range-LNMXJU6W.js +0 -7
  72. package/dist/page-range-P7SDW6LR.cjs +0 -8
  73. package/dist/page-range-P7SDW6LR.cjs.map +0 -1
  74. package/dist/parser-PQDICHD5.js.map +0 -1
  75. package/dist/parser-VZL3MK5X.js.map +0 -1
  76. package/dist/parser-XDW6I25C.cjs.map +0 -1
  77. package/dist/provider-4ZJKV3DC.js.map +0 -1
  78. package/dist/provider-AKROB7WQ.js.map +0 -1
  79. package/dist/provider-G4C2V2PD.cjs.map +0 -1
  80. package/dist/setup-57FB3LSP.js.map +0 -1
  81. package/dist/watch-KERZCCNR.js.map +0 -1
  82. /package/dist/{-56JCPGII.js.map → -GKNSTVEZ.js.map} +0 -0
  83. /package/dist/{detect-RI2MQ33K.js.map → detect-NTR2FUEG.js.map} +0 -0
  84. /package/dist/{page-range-737B4EZW.js.map → page-range-CIRRJPXJ.js.map} +0 -0
  85. /package/dist/{page-range-LNMXJU6W.js.map → page-range-OF5I4PQY.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -435,10 +435,12 @@ declare function fillHwpx(hwpxBuffer: ArrayBuffer, values: Record<string, string
435
435
  type GongmunPreset = "official" | "report" | "plan" | "notice" | "minutes";
436
436
  type GongmunNumbering = "standard" | "report";
437
437
  type GongmunFont = "myeongjo" | "gothic";
438
+ /** 프리셋 입력값 — 영문 키 또는 한글 별칭(기안문·보고서·계획서·통지·회의록 등) */
439
+ type GongmunPresetInput = GongmunPreset | "기안문" | "시행문" | "공문" | "공문서" | "보고서" | "계획서" | "계획" | "통지" | "알림" | "안내" | "회의록";
438
440
  /** 공문서 모드 옵션 (전부 선택 — 프리셋 기본값을 개별 override) */
439
441
  interface GongmunOptions {
440
- /** 문서 종류 프리셋. 기본 'official'(일반 기안문) */
441
- preset?: GongmunPreset;
442
+ /** 문서 종류 프리셋(영문 키 또는 한글 별칭). 기본 'official'(일반 기안문) */
443
+ preset?: GongmunPresetInput;
442
444
  /** 본문 글꼴. 'myeongjo'=함초롬바탕(명조, 보고서·대외공문 관행) / 'gothic'=맑은 고딕(전자결재 기본) */
443
445
  bodyFont?: GongmunFont;
444
446
  /** 본문 글자 크기(pt). 기본 15 */
@@ -457,6 +459,10 @@ interface GongmunOptions {
457
459
  /** 문서 제목(첫 h1)을 가운데 정렬. 기본 true (행정기관명·보고서 제목) */
458
460
  centerTitle?: boolean;
459
461
  }
462
+ /** 프리셋 별칭(한글/영문) → 내부 preset 키. CLI·라이브러리 공용 */
463
+ declare const PRESET_ALIAS: Record<string, GongmunPreset>;
464
+ /** 프리셋 입력(영문 키 또는 한글 별칭)을 내부 GongmunPreset로 정규화. 미상은 'official' */
465
+ declare function normalizeGongmunPreset(preset?: string): GongmunPreset;
460
466
 
461
467
  /**
462
468
  * Markdown → HWPX 역변환
@@ -903,4 +909,4 @@ interface FillFormOutput {
903
909
  */
904
910
  declare function fillForm(input: string | ArrayBuffer | Buffer, values: Record<string, string>, outputFormat?: FillOutputFormat): Promise<FillFormOutput>;
905
911
 
906
- export { type BlockCapability, type BlockCapabilityInfo, type BlockDiff, type BlockEdit, type BlockSourceRef, type BoundingBox, type CellCapability, type CellContext, type CellDiff, type DiffChangeType, type DiffResult, type DocumentMetadata, type DocumentQualitySummary, type ErrorCode, type ExtractedImage, type FileType, type FillFormOutput, type FillOutputFormat, type FillResult, type FormField, type FormFieldSchema, type FormFieldType, type FormResult, type FormSchemaResult, type GongmunFont, type GongmunNumbering, type GongmunOptions, type GongmunPreset, type HwpxFillResult, HwpxSession, type HwpxTheme, type IRBlock, type IRBlockType, type IRCell, type IRTable, type ImageData, type InlineStyle, type MarkdownToHwpxOptions, type OcrProvider, type OutlineItem, type PageMargin, type PageQuality, type ParseFailure, type ParseOptions, type ParseResult, type ParseSuccess, type ParseWarning, type PatchOptions, type PatchResult, type PatchSkip, type PrintOptions, type PrintPreset, type ScanCell, type ScanParaKind, type ScanParagraph, type ScanTable, type SectionScan, type SpliceEdit, type TRange, VERSION, type WarningCode, type WatchOptions, applySplices, blocksToMarkdown, blocksToPdf, buildParagraphSplices, buildRangeSplices, compare, detectFormat, detectOle2Format, detectZipFormat, diffBlocks, extractFormFields, extractFormSchema, fillForm, fillFormFields, fillHwpx, inferFieldType, isHwpxFile, isLabelCell, isOldHwpFile, isPdfFile, isZipFile, markdownToHwpx, markdownToPdf, openHwpxDocument, parse, parseDocx, parseHwp, parseHwp3, parseHwpml, parseHwpx, parsePdf, parseXls, parseXlsx, patchHwp, patchHwpx, patchHwpxBlocks, renderHtml, scanSectionXml };
912
+ export { type BlockCapability, type BlockCapabilityInfo, type BlockDiff, type BlockEdit, type BlockSourceRef, type BoundingBox, type CellCapability, type CellContext, type CellDiff, type DiffChangeType, type DiffResult, type DocumentMetadata, type DocumentQualitySummary, type ErrorCode, type ExtractedImage, type FileType, type FillFormOutput, type FillOutputFormat, type FillResult, type FormField, type FormFieldSchema, type FormFieldType, type FormResult, type FormSchemaResult, type GongmunFont, type GongmunNumbering, type GongmunOptions, type GongmunPreset, type GongmunPresetInput, type HwpxFillResult, HwpxSession, type HwpxTheme, type IRBlock, type IRBlockType, type IRCell, type IRTable, type ImageData, type InlineStyle, type MarkdownToHwpxOptions, type OcrProvider, type OutlineItem, PRESET_ALIAS, type PageMargin, type PageQuality, type ParseFailure, type ParseOptions, type ParseResult, type ParseSuccess, type ParseWarning, type PatchOptions, type PatchResult, type PatchSkip, type PrintOptions, type PrintPreset, type ScanCell, type ScanParaKind, type ScanParagraph, type ScanTable, type SectionScan, type SpliceEdit, type TRange, VERSION, type WarningCode, type WatchOptions, applySplices, blocksToMarkdown, blocksToPdf, buildParagraphSplices, buildRangeSplices, compare, detectFormat, detectOle2Format, detectZipFormat, diffBlocks, extractFormFields, extractFormSchema, fillForm, fillFormFields, fillHwpx, inferFieldType, isHwpxFile, isLabelCell, isOldHwpFile, isPdfFile, isZipFile, markdownToHwpx, markdownToPdf, normalizeGongmunPreset, openHwpxDocument, parse, parseDocx, parseHwp, parseHwp3, parseHwpml, parseHwpx, parsePdf, parseXls, parseXlsx, patchHwp, patchHwpx, patchHwpxBlocks, renderHtml, scanSectionXml };
package/dist/index.d.ts CHANGED
@@ -435,10 +435,12 @@ declare function fillHwpx(hwpxBuffer: ArrayBuffer, values: Record<string, string
435
435
  type GongmunPreset = "official" | "report" | "plan" | "notice" | "minutes";
436
436
  type GongmunNumbering = "standard" | "report";
437
437
  type GongmunFont = "myeongjo" | "gothic";
438
+ /** 프리셋 입력값 — 영문 키 또는 한글 별칭(기안문·보고서·계획서·통지·회의록 등) */
439
+ type GongmunPresetInput = GongmunPreset | "기안문" | "시행문" | "공문" | "공문서" | "보고서" | "계획서" | "계획" | "통지" | "알림" | "안내" | "회의록";
438
440
  /** 공문서 모드 옵션 (전부 선택 — 프리셋 기본값을 개별 override) */
439
441
  interface GongmunOptions {
440
- /** 문서 종류 프리셋. 기본 'official'(일반 기안문) */
441
- preset?: GongmunPreset;
442
+ /** 문서 종류 프리셋(영문 키 또는 한글 별칭). 기본 'official'(일반 기안문) */
443
+ preset?: GongmunPresetInput;
442
444
  /** 본문 글꼴. 'myeongjo'=함초롬바탕(명조, 보고서·대외공문 관행) / 'gothic'=맑은 고딕(전자결재 기본) */
443
445
  bodyFont?: GongmunFont;
444
446
  /** 본문 글자 크기(pt). 기본 15 */
@@ -457,6 +459,10 @@ interface GongmunOptions {
457
459
  /** 문서 제목(첫 h1)을 가운데 정렬. 기본 true (행정기관명·보고서 제목) */
458
460
  centerTitle?: boolean;
459
461
  }
462
+ /** 프리셋 별칭(한글/영문) → 내부 preset 키. CLI·라이브러리 공용 */
463
+ declare const PRESET_ALIAS: Record<string, GongmunPreset>;
464
+ /** 프리셋 입력(영문 키 또는 한글 별칭)을 내부 GongmunPreset로 정규화. 미상은 'official' */
465
+ declare function normalizeGongmunPreset(preset?: string): GongmunPreset;
460
466
 
461
467
  /**
462
468
  * Markdown → HWPX 역변환
@@ -903,4 +909,4 @@ interface FillFormOutput {
903
909
  */
904
910
  declare function fillForm(input: string | ArrayBuffer | Buffer, values: Record<string, string>, outputFormat?: FillOutputFormat): Promise<FillFormOutput>;
905
911
 
906
- export { type BlockCapability, type BlockCapabilityInfo, type BlockDiff, type BlockEdit, type BlockSourceRef, type BoundingBox, type CellCapability, type CellContext, type CellDiff, type DiffChangeType, type DiffResult, type DocumentMetadata, type DocumentQualitySummary, type ErrorCode, type ExtractedImage, type FileType, type FillFormOutput, type FillOutputFormat, type FillResult, type FormField, type FormFieldSchema, type FormFieldType, type FormResult, type FormSchemaResult, type GongmunFont, type GongmunNumbering, type GongmunOptions, type GongmunPreset, type HwpxFillResult, HwpxSession, type HwpxTheme, type IRBlock, type IRBlockType, type IRCell, type IRTable, type ImageData, type InlineStyle, type MarkdownToHwpxOptions, type OcrProvider, type OutlineItem, type PageMargin, type PageQuality, type ParseFailure, type ParseOptions, type ParseResult, type ParseSuccess, type ParseWarning, type PatchOptions, type PatchResult, type PatchSkip, type PrintOptions, type PrintPreset, type ScanCell, type ScanParaKind, type ScanParagraph, type ScanTable, type SectionScan, type SpliceEdit, type TRange, VERSION, type WarningCode, type WatchOptions, applySplices, blocksToMarkdown, blocksToPdf, buildParagraphSplices, buildRangeSplices, compare, detectFormat, detectOle2Format, detectZipFormat, diffBlocks, extractFormFields, extractFormSchema, fillForm, fillFormFields, fillHwpx, inferFieldType, isHwpxFile, isLabelCell, isOldHwpFile, isPdfFile, isZipFile, markdownToHwpx, markdownToPdf, openHwpxDocument, parse, parseDocx, parseHwp, parseHwp3, parseHwpml, parseHwpx, parsePdf, parseXls, parseXlsx, patchHwp, patchHwpx, patchHwpxBlocks, renderHtml, scanSectionXml };
912
+ export { type BlockCapability, type BlockCapabilityInfo, type BlockDiff, type BlockEdit, type BlockSourceRef, type BoundingBox, type CellCapability, type CellContext, type CellDiff, type DiffChangeType, type DiffResult, type DocumentMetadata, type DocumentQualitySummary, type ErrorCode, type ExtractedImage, type FileType, type FillFormOutput, type FillOutputFormat, type FillResult, type FormField, type FormFieldSchema, type FormFieldType, type FormResult, type FormSchemaResult, type GongmunFont, type GongmunNumbering, type GongmunOptions, type GongmunPreset, type GongmunPresetInput, type HwpxFillResult, HwpxSession, type HwpxTheme, type IRBlock, type IRBlockType, type IRCell, type IRTable, type ImageData, type InlineStyle, type MarkdownToHwpxOptions, type OcrProvider, type OutlineItem, PRESET_ALIAS, type PageMargin, type PageQuality, type ParseFailure, type ParseOptions, type ParseResult, type ParseSuccess, type ParseWarning, type PatchOptions, type PatchResult, type PatchSkip, type PrintOptions, type PrintPreset, type ScanCell, type ScanParaKind, type ScanParagraph, type ScanTable, type SectionScan, type SpliceEdit, type TRange, VERSION, type WarningCode, type WatchOptions, applySplices, blocksToMarkdown, blocksToPdf, buildParagraphSplices, buildRangeSplices, compare, detectFormat, detectOle2Format, detectZipFormat, diffBlocks, extractFormFields, extractFormSchema, fillForm, fillFormFields, fillHwpx, inferFieldType, isHwpxFile, isLabelCell, isOldHwpFile, isPdfFile, isZipFile, markdownToHwpx, markdownToPdf, normalizeGongmunPreset, openHwpxDocument, parse, parseDocx, parseHwp, parseHwp3, parseHwpml, parseHwpx, parsePdf, parseXls, parseXlsx, patchHwp, patchHwpx, patchHwpxBlocks, renderHtml, scanSectionXml };
package/dist/index.js CHANGED
@@ -17,10 +17,10 @@ import {
17
17
  sanitizeHref,
18
18
  stripDtd,
19
19
  toArrayBuffer
20
- } from "./chunk-ZPLRG2SJ.js";
20
+ } from "./chunk-AHDNELBR.js";
21
21
  import {
22
22
  parsePageRange
23
- } from "./chunk-GE43BE46.js";
23
+ } from "./chunk-AIQ3ISQU.js";
24
24
 
25
25
  // src/index.ts
26
26
  import { readFile } from "fs/promises";
@@ -16907,7 +16907,7 @@ async function parseXlsxDocument(buffer, options) {
16907
16907
  }
16908
16908
  let pageFilter = null;
16909
16909
  if (options?.pages) {
16910
- const { parsePageRange: parsePageRange2 } = await import("./page-range-LNMXJU6W.js");
16910
+ const { parsePageRange: parsePageRange2 } = await import("./page-range-CIRRJPXJ.js");
16911
16911
  pageFilter = parsePageRange2(options.pages, sheets.length);
16912
16912
  }
16913
16913
  const blocks = [];
@@ -17545,7 +17545,7 @@ async function parseXlsDocument(buffer, options) {
17545
17545
  const totalSheets = Math.min(globals.sheets.length, MAX_SHEETS2);
17546
17546
  let pageFilter = null;
17547
17547
  if (options?.pages) {
17548
- const { parsePageRange: parsePageRange2 } = await import("./page-range-LNMXJU6W.js");
17548
+ const { parsePageRange: parsePageRange2 } = await import("./page-range-CIRRJPXJ.js");
17549
17549
  pageFilter = parsePageRange2(options.pages, totalSheets);
17550
17550
  }
17551
17551
  const allBlocks = [];
@@ -17968,20 +17968,32 @@ function isDisplayMath(el) {
17968
17968
 
17969
17969
  // src/docx/parser.ts
17970
17970
  var MAX_DECOMPRESS_SIZE4 = 100 * 1024 * 1024;
17971
- function getChildElements(parent, localName2) {
17971
+ function matchesLocal(el, localName2) {
17972
+ return el.localName === localName2 || (el.tagName?.endsWith(`:${localName2}`) ?? false);
17973
+ }
17974
+ function effectiveChildElements(parent) {
17972
17975
  const result = [];
17973
17976
  const children = parent.childNodes;
17974
17977
  for (let i = 0; i < children.length; i++) {
17975
17978
  const node = children[i];
17976
- if (node.nodeType === 1) {
17977
- const el = node;
17978
- if (el.localName === localName2 || el.tagName?.endsWith(`:${localName2}`)) {
17979
- result.push(el);
17979
+ if (node.nodeType !== 1) continue;
17980
+ const el = node;
17981
+ if (matchesLocal(el, "sdt")) {
17982
+ for (let j = 0; j < el.childNodes.length; j++) {
17983
+ const c = el.childNodes[j];
17984
+ if (c.nodeType === 1 && matchesLocal(c, "sdtContent")) {
17985
+ result.push(...effectiveChildElements(c));
17986
+ }
17980
17987
  }
17988
+ } else {
17989
+ result.push(el);
17981
17990
  }
17982
17991
  }
17983
17992
  return result;
17984
17993
  }
17994
+ function getChildElements(parent, localName2) {
17995
+ return effectiveChildElements(parent).filter((el) => matchesLocal(el, localName2));
17996
+ }
17985
17997
  function findElements(parent, localName2) {
17986
17998
  const result = [];
17987
17999
  const walk = (node) => {
@@ -18372,11 +18384,8 @@ async function parseDocxDocument(buffer, options) {
18372
18384
  }
18373
18385
  const blocks = [];
18374
18386
  const bodyEl = body[0];
18375
- const children = bodyEl.childNodes;
18376
- for (let i = 0; i < children.length; i++) {
18377
- const node = children[i];
18378
- if (node.nodeType !== 1) continue;
18379
- const el = node;
18387
+ const topLevel = effectiveChildElements(bodyEl);
18388
+ for (const el of topLevel) {
18380
18389
  const localName2 = el.localName ?? el.tagName?.split(":").pop();
18381
18390
  if (localName2 === "p") {
18382
18391
  const block = parseParagraph2(el, styles, numbering, footnotes, rels);
@@ -18882,8 +18891,9 @@ function extractFromTable(table) {
18882
18891
  if (table.cols >= 2) {
18883
18892
  for (let r = 0; r < table.rows; r++) {
18884
18893
  for (let c = 0; c < table.cols - 1; c++) {
18885
- const labelCell = table.cells[r][c];
18886
- const valueCell = table.cells[r][c + 1];
18894
+ const labelCell = table.cells[r]?.[c];
18895
+ const valueCell = table.cells[r]?.[c + 1];
18896
+ if (!labelCell || !valueCell) continue;
18887
18897
  if (isLabelCell(labelCell.text)) {
18888
18898
  fields.push({
18889
18899
  label: labelCell.text.trim().replace(/[::]\s*$/, ""),
@@ -18904,8 +18914,8 @@ function extractFromTable(table) {
18904
18914
  if (allLabels) {
18905
18915
  for (let r = 1; r < table.rows; r++) {
18906
18916
  for (let c = 0; c < table.cols; c++) {
18907
- const label = headerRow[c].text.trim();
18908
- const value = table.cells[r][c].text.trim();
18917
+ const label = headerRow[c]?.text.trim() ?? "";
18918
+ const value = table.cells[r]?.[c]?.text.trim() ?? "";
18909
18919
  if (label && value) {
18910
18920
  fields.push({ label, value, row: r, col: c });
18911
18921
  }
@@ -19059,15 +19069,18 @@ function fillTable(table, values, filled, matchedLabels, patternFilledCells) {
19059
19069
  if (!allLabels) return;
19060
19070
  for (let r = 1; r < table.rows; r++) {
19061
19071
  for (let c = 0; c < table.cols; c++) {
19062
- const headerLabel = normalizeLabel(headerRow[c].text);
19072
+ const headerCell = headerRow[c];
19073
+ const valueCell = table.cells[r]?.[c];
19074
+ if (!headerCell || !valueCell) continue;
19075
+ const headerLabel = normalizeLabel(headerCell.text);
19063
19076
  const matchKey = findMatchingKey(headerLabel, values);
19064
19077
  if (matchKey === void 0) continue;
19065
19078
  if (matchedLabels.has(matchKey)) continue;
19066
19079
  const newValue = values.get(matchKey);
19067
- table.cells[r][c].text = newValue;
19080
+ valueCell.text = newValue;
19068
19081
  matchedLabels.add(matchKey);
19069
19082
  filled.push({
19070
- label: headerRow[c].text.trim(),
19083
+ label: headerCell.text.trim(),
19071
19084
  value: newValue,
19072
19085
  row: r,
19073
19086
  col: c
@@ -19997,8 +20010,30 @@ var PRESET_DEFAULTS = {
19997
20010
  notice: { bodyPt: 15, lineSpacing: 160, numbering: "standard" },
19998
20011
  minutes: { bodyPt: 14, lineSpacing: 130, numbering: "standard" }
19999
20012
  };
20013
+ var PRESET_ALIAS = {
20014
+ official: "official",
20015
+ \uAE30\uC548\uBB38: "official",
20016
+ \uC2DC\uD589\uBB38: "official",
20017
+ \uACF5\uBB38: "official",
20018
+ \uACF5\uBB38\uC11C: "official",
20019
+ report: "report",
20020
+ \uBCF4\uACE0\uC11C: "report",
20021
+ plan: "plan",
20022
+ \uACC4\uD68D\uC11C: "plan",
20023
+ \uACC4\uD68D: "plan",
20024
+ notice: "notice",
20025
+ \uD1B5\uC9C0: "notice",
20026
+ \uC54C\uB9BC: "notice",
20027
+ \uC548\uB0B4: "notice",
20028
+ minutes: "minutes",
20029
+ \uD68C\uC758\uB85D: "minutes"
20030
+ };
20031
+ function normalizeGongmunPreset(preset) {
20032
+ if (!preset) return "official";
20033
+ return PRESET_ALIAS[preset.trim()] ?? "official";
20034
+ }
20000
20035
  function resolveGongmun(opts) {
20001
- const preset = opts.preset ?? "official";
20036
+ const preset = normalizeGongmunPreset(opts.preset);
20002
20037
  const d = PRESET_DEFAULTS[preset];
20003
20038
  const bodyPt = opts.bodyPt ?? d.bodyPt;
20004
20039
  return {
@@ -21368,6 +21403,67 @@ function applyCellEdit(table, scanTable, gridR, gridC, newLines, ctx, before, af
21368
21403
  return 1;
21369
21404
  }
21370
21405
 
21406
+ // src/roundtrip/table-insert.ts
21407
+ var TABLE_USABLE_WIDTH = 44e3;
21408
+ var TABLE_ROW_HEIGHT = 1500;
21409
+ function collectMaxNumericId(xmls) {
21410
+ let max = -1;
21411
+ for (const xml of xmls) {
21412
+ for (const m of xml.matchAll(/\bid(?:Ref)?="(\d{1,10})"/g)) {
21413
+ const v = parseInt(m[1], 10);
21414
+ if (!isNaN(v) && v > max) max = v;
21415
+ }
21416
+ }
21417
+ return max;
21418
+ }
21419
+ function cellBorderFillXml(id) {
21420
+ return `<hh:borderFill id="${id}" threeD="0" shadow="0" centerLine="0" breakCellSeparateLine="0"><hh:slash type="NONE" Crooked="0" isCounter="0"/><hh:backSlash type="NONE" Crooked="0" isCounter="0"/><hh:leftBorder type="SOLID" width="0.12 mm" color="#000000"/><hh:rightBorder type="SOLID" width="0.12 mm" color="#000000"/><hh:topBorder type="SOLID" width="0.12 mm" color="#000000"/><hh:bottomBorder type="SOLID" width="0.12 mm" color="#000000"/><hh:diagonal type="NONE" width="0.1 mm" color="#000000"/><hh:fillInfo/></hh:borderFill>`;
21421
+ }
21422
+ function injectCellBorderFill(headerXml, newId) {
21423
+ const openM = headerXml.match(/<hh:borderFills\b([^>]*)>/);
21424
+ if (!openM || openM.index === void 0) return null;
21425
+ const closeIdx = headerXml.indexOf("</hh:borderFills>");
21426
+ if (closeIdx < 0) return null;
21427
+ const splices = [];
21428
+ const itemCntM = openM[1].match(/\bitemCnt="(\d+)"/);
21429
+ if (itemCntM && itemCntM.index !== void 0) {
21430
+ const cnt = parseInt(itemCntM[1], 10);
21431
+ const attrStart = openM.index + "<hh:borderFills".length + itemCntM.index;
21432
+ const valStart = attrStart + itemCntM[0].indexOf('"') + 1;
21433
+ const valEnd = valStart + String(cnt).length;
21434
+ splices.push({ start: valStart, end: valEnd, replacement: String(cnt + 1) });
21435
+ }
21436
+ splices.push({ start: closeIdx, end: closeIdx, replacement: cellBorderFillXml(newId) });
21437
+ return { borderFillId: newId, headerSplices: splices };
21438
+ }
21439
+ function cellPlainText(raw) {
21440
+ let t = unescapeGfmCell(raw);
21441
+ t = t.replace(/\*\*\*([^*]+)\*\*\*/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/`([^`]+)`/g, "$1");
21442
+ return t.replace(/\s*\n\s*/g, " ").trim();
21443
+ }
21444
+ function buildTableParagraphXml(rows, opts) {
21445
+ const { borderFillId, outerParaPrId, cellParaPrId, cellCharPrId, tableId } = opts;
21446
+ const rowCnt = rows.length;
21447
+ const colCnt = Math.max(...rows.map((r) => r.length), 1);
21448
+ const cellW = Math.floor(TABLE_USABLE_WIDTH / colCnt);
21449
+ const cellH = TABLE_ROW_HEIGHT;
21450
+ const tblW = cellW * colCnt;
21451
+ const tblH = cellH * rowCnt;
21452
+ const trElements = rows.map((row, rowIdx) => {
21453
+ const cells = row.length < colCnt ? [...row, ...Array(colCnt - row.length).fill("")] : row;
21454
+ const isHeaderRow = rowIdx === 0;
21455
+ const tdElements = cells.map((cell, colIdx) => {
21456
+ const text = escapeXmlText(cellPlainText(cell));
21457
+ const cellP = `<hp:p paraPrIDRef="${cellParaPrId}" styleIDRef="0"><hp:run charPrIDRef="${cellCharPrId}"><hp:t>${text}</hp:t></hp:run></hp:p>`;
21458
+ return `<hp:tc name="" header="${isHeaderRow ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="${borderFillId}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${cellP}</hp:subList><hp:cellAddr colAddr="${colIdx}" rowAddr="${rowIdx}"/><hp:cellSpan colSpan="1" rowSpan="1"/><hp:cellSz width="${cellW}" height="${cellH}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
21459
+ }).join("");
21460
+ return `<hp:tr>${tdElements}</hp:tr>`;
21461
+ }).join("");
21462
+ const tblInner = `<hp:sz width="${tblW}" widthRelTo="ABSOLUTE" height="${tblH}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="0" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="0" right="0" top="0" bottom="0"/><hp:inMargin left="510" right="510" top="141" bottom="141"/>` + trElements;
21463
+ const tbl = `<hp:tbl id="${tableId}" zOrder="0" numberingType="TABLE" pageBreak="CELL" repeatHeader="0" rowCnt="${rowCnt}" colCnt="${colCnt}" cellSpacing="0" borderFillIDRef="${borderFillId}" noShading="0">${tblInner}</hp:tbl>`;
21464
+ return `<hp:p paraPrIDRef="${outerParaPrId}" styleIDRef="0"><hp:run charPrIDRef="${cellCharPrId}">${tbl}</hp:run></hp:p>`;
21465
+ }
21466
+
21371
21467
  // src/roundtrip/hwpx-entries.ts
21372
21468
  async function resolveSectionEntryNames(zip) {
21373
21469
  for (const mp of ["Contents/content.hpf", "content.hpf"]) {
@@ -21429,6 +21525,13 @@ async function patchHwpx(original, editedMarkdown, options) {
21429
21525
  const xml = await zip.file(sectionPaths[i]).async("text");
21430
21526
  scans.push(scanSectionXml(xml, i));
21431
21527
  }
21528
+ let tableInsert;
21529
+ const headerEntryName = await resolveHeaderEntryName(zip);
21530
+ if (headerEntryName) {
21531
+ const headerXml = await zip.file(headerEntryName).async("text");
21532
+ const maxId = collectMaxNumericId([...scans.map((s) => s.xml), headerXml]);
21533
+ tableInsert = { headerEntryName, headerXml, headerSplices: [], borderFillId: null, nextId: maxId + 1 };
21534
+ }
21432
21535
  const origUnits = buildOrigUnits(origBlocks);
21433
21536
  const editedUnits = splitMarkdownUnits(editedMarkdown);
21434
21537
  const pairs = alignUnits(origUnits.map((u) => u.raw), editedUnits.map((u) => u.raw));
@@ -21448,7 +21551,8 @@ async function patchHwpx(original, editedMarkdown, options) {
21448
21551
  scanTables,
21449
21552
  obTableOrdinals,
21450
21553
  sectionSplices,
21451
- skipped
21554
+ skipped,
21555
+ tableInsert
21452
21556
  });
21453
21557
  } else if (oi !== null) {
21454
21558
  skipped.push({ reason: "\uBE14\uB85D \uC0AD\uC81C\uB294 \uBBF8\uC9C0\uC6D0 (v1) \u2014 \uC6D0\uBCF8 \uC720\uC9C0", before: summarize(origUnits[oi].raw) });
@@ -21465,6 +21569,10 @@ async function patchHwpx(original, editedMarkdown, options) {
21465
21569
  const newXml = applySplices(scans[i].xml, sectionSplices[i]);
21466
21570
  replacements.set(sectionPaths[i], encoder.encode(newXml));
21467
21571
  }
21572
+ if (tableInsert && tableInsert.headerSplices.length > 0) {
21573
+ const newHeader = applySplices(tableInsert.headerXml, tableInsert.headerSplices);
21574
+ replacements.set(tableInsert.headerEntryName, encoder.encode(newHeader));
21575
+ }
21468
21576
  } catch (err) {
21469
21577
  return { success: false, applied: 0, skipped, error: `\uC18C\uC2A4\uB9F5 splice \uC2E4\uD328: ${err instanceof Error ? err.message : String(err)}` };
21470
21578
  }
@@ -21677,11 +21785,49 @@ function handleModifiedUnit(orig, edited, ctx) {
21677
21785
  if (orig.kind === "html-table") return patchHtmlTable(block.table, scanTable, orig, edited, ctx, skip);
21678
21786
  return patchTextChunkTable(block.table, scanTable, orig, edited, ctx, skip);
21679
21787
  }
21680
- if ((block.type === "paragraph" || block.type === "heading") && orig.kind === "text" && edited.kind === "text") {
21681
- return patchParagraphUnit(block, orig, edited, ctx, skip);
21788
+ if ((block.type === "paragraph" || block.type === "heading") && orig.kind === "text") {
21789
+ if (edited.kind === "text") return patchParagraphUnit(block, orig, edited, ctx, skip);
21790
+ if (edited.kind === "gfm-table") return convertParagraphToTable(block, orig, edited, ctx, skip);
21791
+ if (edited.kind === "html-table") return skip("\uBB38\uB2E8\u2192\uBCD1\uD569\uD45C(HTML) \uBCC0\uD658\uC740 \uBBF8\uC9C0\uC6D0 \u2014 GFM \uD45C(| \uD5E4\uB354 | \u2026 |)\uB85C \uC791\uC131\uD558\uC138\uC694");
21682
21792
  }
21683
21793
  return skip("\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uBE14\uB85D \uC720\uD615 \uBCC0\uACBD");
21684
21794
  }
21795
+ function extractParaPrIdRef(xml, start) {
21796
+ const gt = xml.indexOf(">", start);
21797
+ if (gt < 0) return null;
21798
+ const m = xml.slice(start, gt + 1).match(/paraPrIDRef="(\d+)"/);
21799
+ return m ? parseInt(m[1], 10) : null;
21800
+ }
21801
+ function convertParagraphToTable(block, orig, edited, ctx, skip) {
21802
+ const ti = ctx.tableInsert;
21803
+ if (!ti) return skip("\uBB38\uB2E8\u2192\uD45C \uBCC0\uD658 \uBD88\uAC00 \u2014 header \uC5D4\uD2B8\uB9AC(borderFills) \uD574\uC11D \uC2E4\uD328");
21804
+ const mapping = ctx.paraMap.get(orig.blockIdx);
21805
+ if (!mapping?.para) return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED) \u2014 \uD45C \uBCC0\uD658 \uBD88\uAC00");
21806
+ const para = mapping.para;
21807
+ if (para.kind !== "body") return skip("\uBCF8\uBB38 \uC678 \uC601\uC5ED(\uD45C \uC140/\uAE00\uC0C1\uC790) \uBB38\uB2E8\uC758 \uD45C \uBCC0\uD658\uC740 \uBBF8\uC9C0\uC6D0");
21808
+ const scan = ctx.scans[para.sectionIndex];
21809
+ if (!scan) return skip("\uC139\uC158 \uB9E4\uD551 \uC2E4\uD328");
21810
+ const pEnd = findElementEnd(scan.xml, para.start);
21811
+ if (pEnd < 0) return skip("\uBB38\uB2E8 \uB05D \uC704\uCE58 \uD0D0\uC0C9 \uC2E4\uD328");
21812
+ const rows = parseGfmTable(edited.lines);
21813
+ if (rows.length === 0 || rows.every((r) => r.length === 0)) return skip("\uD45C \uB0B4\uC6A9\uC774 \uBE44\uC5B4 \uC788\uC74C");
21814
+ if (ti.borderFillId === null) {
21815
+ const inj = injectCellBorderFill(ti.headerXml, ti.nextId++);
21816
+ if (!inj) return skip("header <hh:borderFills> \uAD6C\uC870\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4 \uD45C \uD14C\uB450\uB9AC \uC0DD\uC131 \uBD88\uAC00");
21817
+ ti.borderFillId = inj.borderFillId;
21818
+ ti.headerSplices.push(...inj.headerSplices);
21819
+ }
21820
+ const outerParaPrId = extractParaPrIdRef(scan.xml, para.start) ?? 0;
21821
+ const tableXml = buildTableParagraphXml(rows, {
21822
+ borderFillId: ti.borderFillId,
21823
+ outerParaPrId,
21824
+ cellParaPrId: 0,
21825
+ cellCharPrId: 0,
21826
+ tableId: ti.nextId++
21827
+ });
21828
+ ctx.sectionSplices[para.sectionIndex].push({ start: para.start, end: pEnd, replacement: tableXml });
21829
+ return 1;
21830
+ }
21685
21831
  function patchParagraphUnit(block, orig, edited, ctx, skip) {
21686
21832
  const mapping = ctx.paraMap.get(orig.blockIdx);
21687
21833
  if (!mapping?.para) return skip("\uBB38\uB2E8 \uC18C\uC2A4\uB9F5 \uB9E4\uD551 \uC2E4\uD328 (\uBA38\uB9AC\uB9D0/\uAE00\uC0C1\uC790/\uCEA1\uC158 \uC601\uC5ED\uC774\uAC70\uB098 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)");
@@ -21762,6 +21908,24 @@ function unitToBlock(u) {
21762
21908
  function u8ToArrayBuffer(u8) {
21763
21909
  return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength);
21764
21910
  }
21911
+ async function resolveHeaderEntryName(zip) {
21912
+ for (const p of ["Contents/header.xml", "header.xml"]) {
21913
+ if (zip.file(p)) return p;
21914
+ }
21915
+ for (const mp of ["Contents/content.hpf", "content.hpf"]) {
21916
+ const f = zip.file(mp);
21917
+ if (!f) continue;
21918
+ const xml = await f.async("text");
21919
+ const m = xml.match(/<opf:item\b[^>]*\bid="header"[^>]*\bhref="([^"]+)"/i) || xml.match(/<opf:item\b[^>]*\bhref="([^"]*header[^"]*\.xml)"/i);
21920
+ if (m) {
21921
+ let href = m[1];
21922
+ if (!href.startsWith("/") && !href.startsWith("Contents/")) href = "Contents/" + href;
21923
+ if (zip.file(href)) return href;
21924
+ }
21925
+ }
21926
+ const found = Object.keys(zip.files).find((n) => /header\.xml$/i.test(n));
21927
+ return found ?? null;
21928
+ }
21765
21929
 
21766
21930
  // src/roundtrip/hwp5-patch.ts
21767
21931
  import { deflateRawSync as deflateRawSync2 } from "zlib";
@@ -22400,8 +22564,11 @@ function handleModified(orig, edited, ctx) {
22400
22564
  if (orig.kind === "html-table") return patchHtmlCells5(block.table, scanTable, orig, edited, ctx, skip);
22401
22565
  return patchTextChunk5(block.table, scanTable, orig, edited, ctx, skip);
22402
22566
  }
22403
- if ((block.type === "paragraph" || block.type === "heading") && orig.kind === "text" && edited.kind === "text") {
22404
- return patchParagraph(block, orig, edited, ctx, skip);
22567
+ if ((block.type === "paragraph" || block.type === "heading") && orig.kind === "text") {
22568
+ if (edited.kind === "text") return patchParagraph(block, orig, edited, ctx, skip);
22569
+ if (edited.kind === "gfm-table" || edited.kind === "html-table") {
22570
+ return skip("HWP5(.hwp) \uBC14\uC774\uB108\uB9AC\uB294 \uBB38\uB2E8\u2192\uD45C \uC778\uD50C\uB808\uC774\uC2A4 \uBCC0\uD658 \uBBF8\uC9C0\uC6D0 \u2014 generate\uB85C \uC0C8 \uBB38\uC11C\uB97C \uB9CC\uB4E4\uAC70\uB098, HWPX(.hwpx)\uB85C \uC800\uC7A5 \uD6C4 patch\uD558\uC138\uC694");
22571
+ }
22405
22572
  }
22406
22573
  return skip("\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uBE14\uB85D \uC720\uD615 \uBCC0\uACBD");
22407
22574
  }
@@ -23338,7 +23505,7 @@ async function parseHwp(buffer, options) {
23338
23505
  async function parsePdf(buffer, options) {
23339
23506
  let parsePdfDocument;
23340
23507
  try {
23341
- const mod = await import("./parser-VZL3MK5X.js");
23508
+ const mod = await import("./parser-LBLPN3KY.js");
23342
23509
  parsePdfDocument = mod.parsePdfDocument;
23343
23510
  } catch {
23344
23511
  return {
@@ -23429,6 +23596,7 @@ async function fillForm(input, values, outputFormat = "markdown") {
23429
23596
  }
23430
23597
  export {
23431
23598
  HwpxSession,
23599
+ PRESET_ALIAS,
23432
23600
  VERSION,
23433
23601
  applySplices,
23434
23602
  blocksToMarkdown,
@@ -23453,6 +23621,7 @@ export {
23453
23621
  isZipFile,
23454
23622
  markdownToHwpx,
23455
23623
  markdownToPdf,
23624
+ normalizeGongmunPreset,
23456
23625
  openHwpxDocument,
23457
23626
  parse,
23458
23627
  parseDocx,