kordoc 4.12.0 → 4.12.2
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.
- package/README.md +26 -5
- package/dist/{-B3EUUBPV.js → -EZH6NKTE.js} +8 -8
- package/dist/{chunk-HGUNWAXK.js → chunk-2B7OIEJJ.js} +9 -5
- package/dist/chunk-2B7OIEJJ.js.map +1 -0
- package/dist/{chunk-QKFCGJJY.js → chunk-2HBYWA5X.js} +2 -2
- package/dist/{chunk-HFJWCAJ2.cjs → chunk-2LKYJ4G3.cjs} +6 -6
- package/dist/chunk-2LKYJ4G3.cjs.map +1 -0
- package/dist/{chunk-COGFPMEB.js → chunk-2LO525TL.js} +2 -2
- package/dist/{chunk-TROD36DK.cjs → chunk-2LPBIW2B.cjs} +3 -3
- package/dist/chunk-2LPBIW2B.cjs.map +1 -0
- package/dist/{chunk-BQSWSMRG.cjs → chunk-62IU4NV3.cjs} +2 -2
- package/dist/chunk-62IU4NV3.cjs.map +1 -0
- package/dist/{chunk-SMGSCP57.js → chunk-7XUXSDH5.js} +308 -53
- package/dist/chunk-7XUXSDH5.js.map +1 -0
- package/dist/{chunk-YASFVKDT.js → chunk-DBGEUDBY.js} +2 -2
- package/dist/chunk-DCZVOIEO.cjs.map +1 -1
- package/dist/{chunk-4PKNWBXJ.js → chunk-FBLMVHDK.js} +2 -2
- package/dist/{chunk-I2OETEEL.js → chunk-FVBR7SC3.js} +2 -2
- package/dist/chunk-GS7T56RP.cjs.map +1 -1
- package/dist/{chunk-46UDI56N.js → chunk-IOJX4Q63.js} +3 -3
- package/dist/{chunk-BQE7AMFS.js → chunk-JCMBQC5N.js} +2 -2
- package/dist/{chunk-TF5DS74F.js → chunk-KX7IYCCZ.js} +3 -3
- package/dist/{chunk-PFUW4I4I.js → chunk-LD2K4K5V.js} +170 -18
- package/dist/chunk-LD2K4K5V.js.map +1 -0
- package/dist/{chunk-MJPRWCI5.js → chunk-MUYU4JI5.js} +2 -2
- package/dist/{chunk-SKGYPM6L.js → chunk-OEYECZGV.js} +308 -53
- package/dist/chunk-OEYECZGV.js.map +1 -0
- package/dist/{chunk-AT23GFSK.cjs → chunk-ONNAHSPV.cjs} +323 -68
- package/dist/chunk-ONNAHSPV.cjs.map +1 -0
- package/dist/{chunk-GHVXLV52.js → chunk-Q6ETEJFK.js} +9 -5
- package/dist/chunk-Q6ETEJFK.js.map +1 -0
- package/dist/{chunk-2IR3PEZU.js → chunk-QBCMFNHS.js} +2 -2
- package/dist/{chunk-DRLKMFDV.js → chunk-QM2RSJ2S.js} +3 -3
- package/dist/chunk-T7GRHAIW.cjs.map +1 -1
- package/dist/{chunk-TJYZY2O6.js → chunk-UL2MDA5C.js} +3 -3
- package/dist/{chunk-TYYJSOZS.cjs → chunk-V5BUPZ6I.cjs} +23 -19
- package/dist/chunk-V5BUPZ6I.cjs.map +1 -0
- package/dist/{chunk-7JQ2ITT2.js → chunk-XXDZ2KTW.js} +2 -2
- package/dist/chunks-TT7ZE5QQ.js +10 -0
- package/dist/cli.js +21 -21
- package/dist/cli.js.map +1 -1
- package/dist/{formula-WGKKR5OQ.js → formula-6RQX4NMJ.js} +4 -4
- package/dist/{formula-YMGXXRBQ.cjs → formula-NBEO6CFC.cjs} +9 -9
- package/dist/formula-NBEO6CFC.cjs.map +1 -0
- package/dist/{formula-G4CD5KQ6.js → formula-NW33S4TA.js} +3 -3
- package/dist/{image-ocr-MBWZK3ZT.js → image-ocr-CAVU2TNZ.js} +5 -5
- package/dist/{image-ocr-M4RP4INO.js → image-ocr-SO56VETS.js} +7 -7
- package/dist/{image-ocr-BE2HHMVN.cjs → image-ocr-V4KY373B.cjs} +11 -11
- package/dist/image-ocr-V4KY373B.cjs.map +1 -0
- package/dist/index.cjs +547 -395
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +166 -14
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +15 -15
- package/dist/{model-bundle-BIMP5DIH.js → model-bundle-EIJF34DR.js} +5 -5
- package/dist/{models-QPOEGHVA.js → models-6V4CPQXC.js} +5 -5
- package/dist/page-range-P7SDW6LR.cjs.map +1 -1
- package/dist/{parser-CMNHBVTL.js → parser-GIREMEPD.js} +307 -6
- package/dist/parser-GIREMEPD.js.map +1 -0
- package/dist/{parser-NR3XO4SM.js → parser-OBHNXEQM.js} +307 -6
- package/dist/parser-OBHNXEQM.js.map +1 -0
- package/dist/{parser-QJY5W47V.cjs → parser-OMT25WH2.cjs} +334 -33
- package/dist/parser-OMT25WH2.cjs.map +1 -0
- package/dist/pdf-ocr-IRXQ5GBM.js +13 -0
- package/dist/pdf-ocr-SL4GCOGS.js +16 -0
- package/dist/pdf-ocr-TFYVK4FI.cjs +14 -0
- package/dist/pdf-ocr-TFYVK4FI.cjs.map +1 -0
- package/dist/{profile-io-UZ43CLWX.js → profile-io-PZVMM66V.js} +3 -3
- package/dist/{rasterize-JC2JVVOF.js → rasterize-NRWP2C6L.js} +2 -2
- package/dist/render-V5ZPTZQ7.js +10 -0
- package/dist/seal-LVG2DGAB.js +10 -0
- package/dist/{setup-WDUVPFX3.js → setup-V55AJP6H.js} +3 -3
- package/dist/{watch-UI7OXIES.js → watch-7CQSMDDP.js} +9 -9
- package/package.json +1 -1
- package/dist/chunk-AT23GFSK.cjs.map +0 -1
- package/dist/chunk-BQSWSMRG.cjs.map +0 -1
- package/dist/chunk-GHVXLV52.js.map +0 -1
- package/dist/chunk-HFJWCAJ2.cjs.map +0 -1
- package/dist/chunk-HGUNWAXK.js.map +0 -1
- package/dist/chunk-PFUW4I4I.js.map +0 -1
- package/dist/chunk-SKGYPM6L.js.map +0 -1
- package/dist/chunk-SMGSCP57.js.map +0 -1
- package/dist/chunk-TROD36DK.cjs.map +0 -1
- package/dist/chunk-TYYJSOZS.cjs.map +0 -1
- package/dist/chunks-Q4GCPRRU.js +0 -10
- package/dist/formula-YMGXXRBQ.cjs.map +0 -1
- package/dist/image-ocr-BE2HHMVN.cjs.map +0 -1
- package/dist/parser-CMNHBVTL.js.map +0 -1
- package/dist/parser-NR3XO4SM.js.map +0 -1
- package/dist/parser-QJY5W47V.cjs.map +0 -1
- package/dist/pdf-ocr-DF3OTBKH.js +0 -13
- package/dist/pdf-ocr-R4DIKF4Q.js +0 -16
- package/dist/pdf-ocr-T3RHIZKY.cjs +0 -14
- package/dist/pdf-ocr-T3RHIZKY.cjs.map +0 -1
- package/dist/render-KSQ6UGCP.js +0 -10
- package/dist/seal-EOFFQ4JR.js +0 -10
- /package/dist/{-B3EUUBPV.js.map → -EZH6NKTE.js.map} +0 -0
- /package/dist/{chunk-QKFCGJJY.js.map → chunk-2HBYWA5X.js.map} +0 -0
- /package/dist/{chunk-COGFPMEB.js.map → chunk-2LO525TL.js.map} +0 -0
- /package/dist/{chunk-YASFVKDT.js.map → chunk-DBGEUDBY.js.map} +0 -0
- /package/dist/{chunk-4PKNWBXJ.js.map → chunk-FBLMVHDK.js.map} +0 -0
- /package/dist/{chunk-I2OETEEL.js.map → chunk-FVBR7SC3.js.map} +0 -0
- /package/dist/{chunk-46UDI56N.js.map → chunk-IOJX4Q63.js.map} +0 -0
- /package/dist/{chunk-BQE7AMFS.js.map → chunk-JCMBQC5N.js.map} +0 -0
- /package/dist/{chunk-TF5DS74F.js.map → chunk-KX7IYCCZ.js.map} +0 -0
- /package/dist/{chunk-MJPRWCI5.js.map → chunk-MUYU4JI5.js.map} +0 -0
- /package/dist/{chunk-2IR3PEZU.js.map → chunk-QBCMFNHS.js.map} +0 -0
- /package/dist/{chunk-DRLKMFDV.js.map → chunk-QM2RSJ2S.js.map} +0 -0
- /package/dist/{chunk-TJYZY2O6.js.map → chunk-UL2MDA5C.js.map} +0 -0
- /package/dist/{chunk-7JQ2ITT2.js.map → chunk-XXDZ2KTW.js.map} +0 -0
- /package/dist/{chunks-Q4GCPRRU.js.map → chunks-TT7ZE5QQ.js.map} +0 -0
- /package/dist/{formula-WGKKR5OQ.js.map → formula-6RQX4NMJ.js.map} +0 -0
- /package/dist/{formula-G4CD5KQ6.js.map → formula-NW33S4TA.js.map} +0 -0
- /package/dist/{image-ocr-MBWZK3ZT.js.map → image-ocr-CAVU2TNZ.js.map} +0 -0
- /package/dist/{image-ocr-M4RP4INO.js.map → image-ocr-SO56VETS.js.map} +0 -0
- /package/dist/{model-bundle-BIMP5DIH.js.map → model-bundle-EIJF34DR.js.map} +0 -0
- /package/dist/{models-QPOEGHVA.js.map → models-6V4CPQXC.js.map} +0 -0
- /package/dist/{pdf-ocr-DF3OTBKH.js.map → pdf-ocr-IRXQ5GBM.js.map} +0 -0
- /package/dist/{pdf-ocr-R4DIKF4Q.js.map → pdf-ocr-SL4GCOGS.js.map} +0 -0
- /package/dist/{profile-io-UZ43CLWX.js.map → profile-io-PZVMM66V.js.map} +0 -0
- /package/dist/{rasterize-JC2JVVOF.js.map → rasterize-NRWP2C6L.js.map} +0 -0
- /package/dist/{render-KSQ6UGCP.js.map → render-V5ZPTZQ7.js.map} +0 -0
- /package/dist/{seal-EOFFQ4JR.js.map → seal-LVG2DGAB.js.map} +0 -0
- /package/dist/{setup-WDUVPFX3.js.map → setup-V55AJP6H.js.map} +0 -0
- /package/dist/{watch-UI7OXIES.js.map → watch-7CQSMDDP.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1148,7 +1148,8 @@ declare function unknownFontWarnings(fonts: Record<string, string | undefined>):
|
|
|
1148
1148
|
* 행정안전부 행정업무운영 편람의 날짜·시간·금액·기호 표기법을 정규식으로 검사.
|
|
1149
1149
|
*
|
|
1150
1150
|
* 원전: jkf87/hwpx-skill gonmun_lint.py(2025 편람 기준 13룰)를 kordoc에 맞게 이식
|
|
1151
|
-
* (v4.0.1). URL 쌍점 오탐 가드 등 일부 보강.
|
|
1151
|
+
* (v4.0.1). URL 쌍점 오탐 가드 등 일부 보강. v4.12.1 에 금액 한글 병기·물결표·두음법칙·
|
|
1152
|
+
* 외래어·차별 표현·"끝." 누락 6룰 보강 (pyhwpxlib Gongmun 검사 항목 대조). 검사는 조언용이다 — 생성은 막지 않고
|
|
1152
1153
|
* 경고만 낸다 (A2 폰트경고와 같은 원칙). 별도 CLI `kordoc lint`는 error 시 exit 1.
|
|
1153
1154
|
*/
|
|
1154
1155
|
interface GongmunLintFinding {
|
|
@@ -1166,7 +1167,9 @@ interface GongmunLintFinding {
|
|
|
1166
1167
|
* 텍스트(마크다운 포함) 표기법 검수. 마크다운 펜스 코드블록(``` ~ ```) 안은
|
|
1167
1168
|
* 건너뛴다 — 코드·URL이 날짜/쌍점 규칙에 오탐되는 것 방지.
|
|
1168
1169
|
*/
|
|
1169
|
-
declare function lintGongmunText(text: string
|
|
1170
|
+
declare function lintGongmunText(text: string, opts?: {
|
|
1171
|
+
document?: boolean;
|
|
1172
|
+
}): GongmunLintFinding[];
|
|
1170
1173
|
/** 검수 결과를 사람이 읽는 경고 문자열 배열로 — generate 경고 채널(A2와 동일)용 */
|
|
1171
1174
|
declare function gongmunLintWarnings(text: string, limit?: number): string[];
|
|
1172
1175
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1148,7 +1148,8 @@ declare function unknownFontWarnings(fonts: Record<string, string | undefined>):
|
|
|
1148
1148
|
* 행정안전부 행정업무운영 편람의 날짜·시간·금액·기호 표기법을 정규식으로 검사.
|
|
1149
1149
|
*
|
|
1150
1150
|
* 원전: jkf87/hwpx-skill gonmun_lint.py(2025 편람 기준 13룰)를 kordoc에 맞게 이식
|
|
1151
|
-
* (v4.0.1). URL 쌍점 오탐 가드 등 일부 보강.
|
|
1151
|
+
* (v4.0.1). URL 쌍점 오탐 가드 등 일부 보강. v4.12.1 에 금액 한글 병기·물결표·두음법칙·
|
|
1152
|
+
* 외래어·차별 표현·"끝." 누락 6룰 보강 (pyhwpxlib Gongmun 검사 항목 대조). 검사는 조언용이다 — 생성은 막지 않고
|
|
1152
1153
|
* 경고만 낸다 (A2 폰트경고와 같은 원칙). 별도 CLI `kordoc lint`는 error 시 exit 1.
|
|
1153
1154
|
*/
|
|
1154
1155
|
interface GongmunLintFinding {
|
|
@@ -1166,7 +1167,9 @@ interface GongmunLintFinding {
|
|
|
1166
1167
|
* 텍스트(마크다운 포함) 표기법 검수. 마크다운 펜스 코드블록(``` ~ ```) 안은
|
|
1167
1168
|
* 건너뛴다 — 코드·URL이 날짜/쌍점 규칙에 오탐되는 것 방지.
|
|
1168
1169
|
*/
|
|
1169
|
-
declare function lintGongmunText(text: string
|
|
1170
|
+
declare function lintGongmunText(text: string, opts?: {
|
|
1171
|
+
document?: boolean;
|
|
1172
|
+
}): GongmunLintFinding[];
|
|
1170
1173
|
/** 검수 결과를 사람이 읽는 경고 문자열 배열로 — generate 경고 채널(A2와 동일)용 */
|
|
1171
1174
|
declare function gongmunLintWarnings(text: string, limit?: number): string[];
|
|
1172
1175
|
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
flattenLayoutTables,
|
|
9
9
|
inlineImagesIntoMarkdown,
|
|
10
10
|
mapPuaText
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-2B7OIEJJ.js";
|
|
12
12
|
import {
|
|
13
13
|
parsePageRange
|
|
14
14
|
} from "./chunk-GE43BE46.js";
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
sanitizeHref,
|
|
30
30
|
stripDtd,
|
|
31
31
|
toArrayBuffer
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-MUYU4JI5.js";
|
|
33
33
|
|
|
34
34
|
// src/index.ts
|
|
35
35
|
import { readFile } from "fs/promises";
|
|
@@ -2748,6 +2748,9 @@ function parseDocInfo(records) {
|
|
|
2748
2748
|
function createParaTextState() {
|
|
2749
2749
|
return { text: "", ctrlIdx: 0, fieldStack: [], fieldRanges: [] };
|
|
2750
2750
|
}
|
|
2751
|
+
var HANCOM_FOLDED_PUA_START = 40960;
|
|
2752
|
+
var HANCOM_FOLDED_PUA_END = 42124;
|
|
2753
|
+
var HANCOM_FOLDED_PUA_SHIFT = 983040 - 40960;
|
|
2751
2754
|
function isExtendedOnlyCtrlChar(ch) {
|
|
2752
2755
|
return ch >= 1 && ch <= 3 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= 18 || ch >= 21 && ch <= 23;
|
|
2753
2756
|
}
|
|
@@ -2815,6 +2818,10 @@ function appendParaText(state, data, resolveControl) {
|
|
|
2815
2818
|
i += 14;
|
|
2816
2819
|
}
|
|
2817
2820
|
} else if (ch >= 32) {
|
|
2821
|
+
if (ch >= HANCOM_FOLDED_PUA_START && ch <= HANCOM_FOLDED_PUA_END) {
|
|
2822
|
+
result += String.fromCodePoint(ch + HANCOM_FOLDED_PUA_SHIFT);
|
|
2823
|
+
break;
|
|
2824
|
+
}
|
|
2818
2825
|
if (ch >= 55296 && ch <= 56319 && i + 1 < data.length) {
|
|
2819
2826
|
const lo = data.readUInt16LE(i);
|
|
2820
2827
|
if (lo >= 56320 && lo <= 57343) {
|
|
@@ -21066,10 +21073,9 @@ function extractFormFields(blocks) {
|
|
|
21066
21073
|
const fields = [];
|
|
21067
21074
|
let totalTables = 0;
|
|
21068
21075
|
let formTables = 0;
|
|
21069
|
-
for (const
|
|
21070
|
-
if (block.type !== "table" || !block.table) continue;
|
|
21076
|
+
for (const table2 of collectTables(blocks)) {
|
|
21071
21077
|
totalTables++;
|
|
21072
|
-
const tableFields = extractFromTable(
|
|
21078
|
+
const tableFields = extractFromTable(table2);
|
|
21073
21079
|
if (tableFields.length > 0) {
|
|
21074
21080
|
formTables++;
|
|
21075
21081
|
fields.push(...tableFields);
|
|
@@ -21084,6 +21090,17 @@ function extractFormFields(blocks) {
|
|
|
21084
21090
|
const confidence = totalTables > 0 ? formTables / totalTables : fields.length > 0 ? 0.3 : 0;
|
|
21085
21091
|
return { fields, confidence: Math.min(confidence, 1) };
|
|
21086
21092
|
}
|
|
21093
|
+
function collectTables(blocks, out = [], depth = 0) {
|
|
21094
|
+
if (depth > 12) return out;
|
|
21095
|
+
for (const block of blocks) {
|
|
21096
|
+
if (block.type !== "table" || !block.table) continue;
|
|
21097
|
+
out.push(block.table);
|
|
21098
|
+
for (const row of block.table.cells) {
|
|
21099
|
+
for (const cell2 of row) if (cell2?.blocks?.length) collectTables(cell2.blocks, out, depth + 1);
|
|
21100
|
+
}
|
|
21101
|
+
}
|
|
21102
|
+
return out;
|
|
21103
|
+
}
|
|
21087
21104
|
function extractFromTable(table2) {
|
|
21088
21105
|
const fields = [];
|
|
21089
21106
|
if (table2.cols >= 2) {
|
|
@@ -22282,17 +22299,17 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
|
|
|
22282
22299
|
const matchText = (p) => paraTText(p, xml) ?? p.text;
|
|
22283
22300
|
const cellLabelText = (cell2) => cell2.paragraphs.filter((p) => !p.inTextbox).map((p) => matchText(p)).join("");
|
|
22284
22301
|
const allTables = [];
|
|
22285
|
-
const
|
|
22302
|
+
const collectTables2 = (tables, depth) => {
|
|
22286
22303
|
if (depth > 16) return;
|
|
22287
22304
|
for (const t of tables) {
|
|
22288
22305
|
allTables.push(t);
|
|
22289
22306
|
for (const row of t.rows) {
|
|
22290
|
-
for (const cell2 of row)
|
|
22307
|
+
for (const cell2 of row) collectTables2(cell2.tables, depth + 1);
|
|
22291
22308
|
}
|
|
22292
22309
|
}
|
|
22293
22310
|
};
|
|
22294
|
-
|
|
22295
|
-
|
|
22311
|
+
collectTables2(scan.tables, 0);
|
|
22312
|
+
collectTables2(scan.orphanTables, 0);
|
|
22296
22313
|
const patternApplied = /* @__PURE__ */ new Set();
|
|
22297
22314
|
for (const table2 of allTables) {
|
|
22298
22315
|
for (const row of table2.rows) {
|
|
@@ -25976,10 +25993,13 @@ function footSep(g) {
|
|
|
25976
25993
|
const bodyMm = 210 - g.margins.left - g.margins.right;
|
|
25977
25994
|
return "\u2500".repeat(Math.max(10, Math.round(bodyMm * (46 / 175))));
|
|
25978
25995
|
}
|
|
25996
|
+
function isInternalApproval(to) {
|
|
25997
|
+
return !!to && /^\s*내\s*부\s*결\s*재/.test(to);
|
|
25998
|
+
}
|
|
25979
25999
|
function buildDocFoot(g, ids) {
|
|
25980
26000
|
const f = g.docFoot;
|
|
25981
26001
|
const out = [blank()];
|
|
25982
|
-
if (f.sender) {
|
|
26002
|
+
if (f.sender && !isInternalApproval(g.docHead?.to)) {
|
|
25983
26003
|
out.push(para(f.sender, GONGMUN_CENTER, ids.sender), blank());
|
|
25984
26004
|
}
|
|
25985
26005
|
const foot = (text) => para(text, GONGMUN_TBL_LEFT, ids.foot);
|
|
@@ -27930,6 +27950,77 @@ function unknownFontWarnings(fonts) {
|
|
|
27930
27950
|
}
|
|
27931
27951
|
|
|
27932
27952
|
// src/hwpx/gongmun-lint.ts
|
|
27953
|
+
var LOANWORD_FIXES = [
|
|
27954
|
+
["\uCEE8\uD150\uCE20", "\uCF58\uD150\uCE20"],
|
|
27955
|
+
["\uC5B4\uD50C\uB9AC\uCF00\uC774\uC158", "\uC560\uD50C\uB9AC\uCF00\uC774\uC158"],
|
|
27956
|
+
["\uBA54\uC138\uC9C0", "\uBA54\uC2DC\uC9C0"],
|
|
27957
|
+
["\uB9AC\uB354\uC27D", "\uB9AC\uB354\uC2ED"],
|
|
27958
|
+
["\uC6CC\uD06C\uC0F5", "\uC6CC\uD06C\uC20D"],
|
|
27959
|
+
["\uC2A4\uCF00\uC974", "\uC2A4\uCF00\uC904"],
|
|
27960
|
+
["\uC545\uC138\uC0AC\uB9AC", "\uC561\uC138\uC11C\uB9AC"],
|
|
27961
|
+
["\uB124\uBE44\uAC8C\uC774\uC158", "\uB0B4\uBE44\uAC8C\uC774\uC158"],
|
|
27962
|
+
["\uD0C0\uAC9F", "\uD0C0\uAE43"],
|
|
27963
|
+
["\uD654\uC774\uD305", "\uD30C\uC774\uD305"],
|
|
27964
|
+
["\uBE44\uC9C0\uB2C8\uC2A4", "\uBE44\uC988\uB2C8\uC2A4"],
|
|
27965
|
+
["\uD504\uB9AC\uC820\uD14C\uC774\uC158", "\uD504\uB808\uC820\uD14C\uC774\uC158"],
|
|
27966
|
+
["\uB77C\uC774\uC13C\uC2A4", "\uB77C\uC774\uC120\uC2A4"],
|
|
27967
|
+
["\uCE90\uBE44\uB137", "\uCE90\uBE44\uB2DB"],
|
|
27968
|
+
["\uB80C\uD2B8\uCE74", "\uB80C\uD130\uCE74"],
|
|
27969
|
+
["\uD50C\uB7AD\uCE74\uB4DC", "\uD50C\uB798\uCE74\uB4DC"],
|
|
27970
|
+
["\uD50C\uB79C\uCE74\uB4DC", "\uD50C\uB798\uCE74\uB4DC"],
|
|
27971
|
+
["\uCEE8\uC149", "\uCF58\uC149\uD2B8"],
|
|
27972
|
+
["\uC2EC\uBCFC", "\uC2EC\uBC8C"],
|
|
27973
|
+
["\uCE74\uB2EC\uB85C\uADF8", "\uCE74\uD0C8\uB85C\uADF8"],
|
|
27974
|
+
["\uD31C\uD50C\uB81B", "\uD338\uD50C\uB9BF"],
|
|
27975
|
+
["\uD31C\uD50C\uB9BF", "\uD338\uD50C\uB9BF"],
|
|
27976
|
+
["\uB9AC\uBAA8\uCF58", "\uB9AC\uBAA8\uCEE8"],
|
|
27977
|
+
["\uC5D0\uC5B4\uCF58", "\uC5D0\uC5B4\uCEE8"],
|
|
27978
|
+
["\uC54C\uCF5C", "\uC54C\uCF54\uC62C"],
|
|
27979
|
+
["\uBC1C\uB780\uC2A4", "\uBC38\uB7F0\uC2A4"],
|
|
27980
|
+
["\uB9E4\uB2C8\uC544", "\uB9C8\uB2C8\uC544"],
|
|
27981
|
+
["\uCF54\uBA54\uB514", "\uCF54\uBBF8\uB514"],
|
|
27982
|
+
["\uD310\uB12C", "\uD328\uB110"],
|
|
27983
|
+
["\uC575\uCF5C", "\uC559\uCF54\uB974"],
|
|
27984
|
+
["\uB85C\uBCF4\uD2B8", "\uB85C\uBD07"],
|
|
27985
|
+
["\uBC14\uBCA0\uD050", "\uBC14\uBE44\uD050"],
|
|
27986
|
+
["\uBD80\uD398", "\uBDD4\uD398"],
|
|
27987
|
+
["\uCD08\uCF54\uB81B", "\uCD08\uCF5C\uB9BF"],
|
|
27988
|
+
["\uCE74\uD398\uD2B8", "\uCE74\uD3AB"],
|
|
27989
|
+
["\uCF00\uC78C", "\uCF00\uC774\uD06C"],
|
|
27990
|
+
["\uB3C4\uB108\uCE20", "\uB3C4\uB11B"],
|
|
27991
|
+
["\uC288\uD37C\uB9C8\uCF19", "\uC288\uD37C\uB9C8\uCF13"],
|
|
27992
|
+
["\uC368\uBE44\uC2A4", "\uC11C\uBE44\uC2A4"],
|
|
27993
|
+
["\uC13C\uD0C0", "\uC13C\uD130"]
|
|
27994
|
+
];
|
|
27995
|
+
var LOANWORD_RE = new RegExp(LOANWORD_FIXES.map(([w]) => w).sort((a, b) => b.length - a.length).join("|"), "g");
|
|
27996
|
+
var DISCRIM_FIXES = [
|
|
27997
|
+
["\uC7A5\uC560\uC790", "\uC7A5\uC560\uC778"],
|
|
27998
|
+
["\uC7A5\uC560\uC6B0", "\uC7A5\uC560\uC778"],
|
|
27999
|
+
["\uBD88\uAD6C\uC790", "\uC7A5\uC560\uC778"],
|
|
28000
|
+
["\uC815\uC2E0\uBC15\uC57D", "\uC9C0\uC801\uC7A5\uC560"],
|
|
28001
|
+
["\uC815\uC0C1\uC778", "\uBE44\uC7A5\uC560\uC778"],
|
|
28002
|
+
["\uD3B8\uBD80\uBAA8", "\uD55C\uBD80\uBAA8"],
|
|
28003
|
+
["\uACB0\uC190\uAC00\uC815", "\uD55C\uBD80\uBAA8\uAC00\uC815"],
|
|
28004
|
+
["\uBBF8\uB9DD\uC778", "\uACE0\uC778\uC758 \uBC30\uC6B0\uC790"],
|
|
28005
|
+
["\uD559\uBD80\uD615", "\uD559\uBD80\uBAA8"],
|
|
28006
|
+
["\uBD88\uC6B0\uC774\uC6C3", "\uC5B4\uB824\uC6B4 \uC774\uC6C3"],
|
|
28007
|
+
["\uC720\uBAA8\uCC28", "\uC720\uC544\uCC28"],
|
|
28008
|
+
["\uC800\uCD9C\uC0B0", "\uC800\uCD9C\uC0DD"],
|
|
28009
|
+
["\uC7A1\uC0C1\uC778", "\uC774\uB3D9\uC0C1\uC778"],
|
|
28010
|
+
["\uD30C\uCD9C\uBD80", "\uAC00\uC0AC\uB3C4\uC6B0\uBBF8"],
|
|
28011
|
+
["\uCCAD\uC18C\uBD80", "\uD658\uACBD\uBBF8\uD654\uC6D0"],
|
|
28012
|
+
["\uAC04\uD638\uC6D0", "\uAC04\uD638\uC0AC"],
|
|
28013
|
+
["\uC6B4\uC804\uC218", "\uC6B4\uC804\uAE30\uC0AC"],
|
|
28014
|
+
["\uB178\uAC00\uB2E4", "\uAC74\uC124\uB178\uB3D9\uC790"],
|
|
28015
|
+
["\uC870\uC120\uC871", "\uC911\uAD6D\uB3D9\uD3EC"],
|
|
28016
|
+
["\uB9E4\uB9E4\uCD98", "\uC131\uB9E4\uB9E4"],
|
|
28017
|
+
["\uC0AC\uC0DD\uC544", "\uD63C\uC678\uC790"],
|
|
28018
|
+
["\uBC99\uC5B4\uB9AC", "\uC5B8\uC5B4\uC7A5\uC560\uC778"],
|
|
28019
|
+
["\uC808\uB984\uBC1C\uC774", "\uC9C0\uCCB4\uC7A5\uC560\uC778"],
|
|
28020
|
+
["\uC560\uAFB8\uB208", "\uC2DC\uAC01\uC7A5\uC560\uC778"],
|
|
28021
|
+
["\uADC0\uBA38\uAC70\uB9AC", "\uCCAD\uAC01\uC7A5\uC560\uC778"]
|
|
28022
|
+
];
|
|
28023
|
+
var DISCRIM_RE = new RegExp(DISCRIM_FIXES.map(([w]) => w).sort((a, b) => b.length - a.length).join("|"), "g");
|
|
27933
28024
|
var RULES = [
|
|
27934
28025
|
// 날짜 ─ 온점 뒤 한 칸, 0 패딩 금지, 연도 4자리, 끝 마침표
|
|
27935
28026
|
{
|
|
@@ -28028,6 +28119,51 @@ var RULES = [
|
|
|
28028
28119
|
message: "\uC30D\uC810\uC740 \uC55E\uB9D0\uC5D0 \uBD99\uC774\uACE0 \uB4A4\uB294 \uD55C \uCE78 \uB744\uC6C0",
|
|
28029
28120
|
suggest: "\uC608) \uC6D0\uC7A5: \uAE40\uAC11\uB3D9"
|
|
28030
28121
|
},
|
|
28122
|
+
// ── 편람 보강 (v4.12.1) — pyhwpxlib Gongmun 검사·hwpx-skill gonmun_lint 대조로 빈 축 보충 ──
|
|
28123
|
+
// 금액 한글 병기 — 규정 시행규칙 제2조: 아라비아 숫자 다음 괄호 안에 한글로 적는다
|
|
28124
|
+
{
|
|
28125
|
+
code: "MONEY_NO_HANGUL",
|
|
28126
|
+
severity: "warning",
|
|
28127
|
+
pattern: /금\d[\d,]*원(?![\s]*[((])/g,
|
|
28128
|
+
message: "\uAE08\uC561\uC740 \uC22B\uC790 \uB2E4\uC74C \uAD04\uD638 \uC548\uC5D0 \uD55C\uAE00 \uBCD1\uAE30",
|
|
28129
|
+
suggest: "\uC608) \uAE08113,560\uC6D0(\uAE08\uC77C\uC2ED\uC77C\uB9CC\uC0BC\uCC9C\uC624\uBC31\uC721\uC2ED\uC6D0)"
|
|
28130
|
+
},
|
|
28131
|
+
// 물결표 앞뒤 붙여쓰기 — 기간·범위는 "2. 20.∼2. 24." 처럼 붙여 씀. 숫자·날짜·시각 범위(앞은 숫자·
|
|
28132
|
+
// 온점·괄호·년월일시분, 뒤는 숫자·연도 생략부호)에만 건다 — "기간( 부터 ~ 까지)" 기입란·"~ ※ 비고"·
|
|
28133
|
+
// "~ 수리완료시까지" 처럼 낱말이 붙는 물결표는 범위 표기가 아니다 (v4.12.2, 별지서식 47→30·기안문 32→27 실측)
|
|
28134
|
+
{
|
|
28135
|
+
code: "TILDE_SPACE",
|
|
28136
|
+
severity: "warning",
|
|
28137
|
+
pattern: /(?<=[\d.)일월년시분’'])[ \t]+[∼~~]|[∼~~][ \t]+(?=[\d'’])/g,
|
|
28138
|
+
message: "\uBB3C\uACB0\uD45C(\u223C) \uC55E\uB4A4\uB294 \uBD99\uC5EC \uC500",
|
|
28139
|
+
suggest: "\uC608) 2. 20.\u223C2. 24., 09:00\u223C18:00"
|
|
28140
|
+
},
|
|
28141
|
+
// 두음법칙 — 어두의 "년도·년간·년말…" 은 "연도·연간·연말" (숫자 뒤 '2026년도' 는 정상). 서식의
|
|
28142
|
+
// 기입란(" 년도", "( 년간)", "2026 년도")과 셀 하나가 "년도" 뿐인 표 머리글은 어두가 아니라
|
|
28143
|
+
// 빈칸 뒤 접미라 제외한다 (v4.12.2, 별지서식 실측 28건 전부 이 꼴·기안문 0건)
|
|
28144
|
+
{
|
|
28145
|
+
code: "DUEUM_ERROR",
|
|
28146
|
+
severity: "warning",
|
|
28147
|
+
pattern: /(?<![가-힣\d])(?<!\d[ \t]{1,3})(?<![((>|][ \t]*)(?<![ \t][ \t])년(?:도별|도|간|말|초|차|세|내)(?![가-힣])(?![ \t]*(?:<\/t[dh]>|\|))/g,
|
|
28148
|
+
message: "\uC5B4\uB450\uC758 '\uB144'\uC740 \uB450\uC74C\uBC95\uCE59\uC5D0 \uB530\uB77C '\uC5F0'\uC73C\uB85C \uC801\uC74C",
|
|
28149
|
+
suggest: "\uC608) \uC5F0\uB3C4, \uC5F0\uAC04, \uC5F0\uB9D0, \uC5F0\uCD08"
|
|
28150
|
+
},
|
|
28151
|
+
// 외래어 표기 — 국립국어원 표기법 기준 흔한 오기 (사전 매칭)
|
|
28152
|
+
{
|
|
28153
|
+
code: "LOANWORD_ERROR",
|
|
28154
|
+
severity: "warning",
|
|
28155
|
+
pattern: LOANWORD_RE,
|
|
28156
|
+
message: "\uC678\uB798\uC5B4 \uD45C\uAE30\uBC95\uC5D0 \uB9DE\uC9C0 \uC54A\uB294 \uD45C\uAE30",
|
|
28157
|
+
suggest: "\uC608) \uCF58\uD150\uCE20\xB7\uC560\uD50C\uB9AC\uCF00\uC774\uC158\xB7\uBA54\uC2DC\uC9C0\xB7\uC6CC\uD06C\uC20D\xB7\uC2A4\uCF00\uC904\xB7\uCF58\uC149\uD2B8"
|
|
28158
|
+
},
|
|
28159
|
+
// 차별·비하 표현 — 행안부 공문서 작성 지침·국립국어원 순화어
|
|
28160
|
+
{
|
|
28161
|
+
code: "DISCRIMINATORY_TERM",
|
|
28162
|
+
severity: "warning",
|
|
28163
|
+
pattern: DISCRIM_RE,
|
|
28164
|
+
message: "\uCC28\uBCC4\xB7\uBE44\uD558 \uD45C\uD604\uC740 \uC21C\uD654\uC5B4\uB85C",
|
|
28165
|
+
suggest: "\uC608) \uC7A5\uC560\uC790\u2192\uC7A5\uC560\uC778, \uD3B8\uBD80\uBAA8\u2192\uD55C\uBD80\uBAA8, \uD559\uBD80\uD615\u2192\uD559\uBD80\uBAA8, \uBBF8\uB9DD\uC778\u2192\uACE0\uC778\uC758 \uBC30\uC6B0\uC790"
|
|
28166
|
+
},
|
|
28031
28167
|
// ── AI 문체 흔적(슬롭) — 편람 원전 외 kordoc 자체 룰 (v4.9.0) ──────────────
|
|
28032
28168
|
// 생성형 AI 초안이 공문서로 흘러들 때 남는 기계 문체를 걸러낸다. 조언용 warning.
|
|
28033
28169
|
{
|
|
@@ -28045,7 +28181,7 @@ var RULES = [
|
|
|
28045
28181
|
suggest: "\uB9AC\uB4DC\uC5B4\xB7\uD575\uC2EC \uC218\uCE58 \uD55C \uACF3\uB9CC \uAC15\uC870"
|
|
28046
28182
|
}
|
|
28047
28183
|
];
|
|
28048
|
-
function lintGongmunText(text) {
|
|
28184
|
+
function lintGongmunText(text, opts) {
|
|
28049
28185
|
const findings = [];
|
|
28050
28186
|
let fenceMarker = null;
|
|
28051
28187
|
const lines = text.split(/\r?\n/);
|
|
@@ -28068,13 +28204,29 @@ function lintGongmunText(text) {
|
|
|
28068
28204
|
rule: r.code,
|
|
28069
28205
|
severity: r.severity,
|
|
28070
28206
|
message: r.message,
|
|
28071
|
-
suggest: r.suggest
|
|
28207
|
+
suggest: dictSuggest(r.code, m[0]) ?? r.suggest
|
|
28072
28208
|
});
|
|
28073
28209
|
}
|
|
28074
28210
|
}
|
|
28075
28211
|
}
|
|
28212
|
+
if (opts?.document && /^\s*붙\s*임(?![가-힣])/m.test(text) && !/끝\.\s*$/m.test(text)) {
|
|
28213
|
+
findings.push({
|
|
28214
|
+
line: lines.length,
|
|
28215
|
+
match: "\uBD99\uC784",
|
|
28216
|
+
rule: "END_MARK_MISSING",
|
|
28217
|
+
severity: "warning",
|
|
28218
|
+
message: "\uBD99\uC784 \uD45C\uC2DC \uB4A4\uC5D0 '\uB05D.' \uD45C\uC2DC\uAC00 \uC5C6\uC74C",
|
|
28219
|
+
suggest: "\uC608) \uBD99\uC784 \uACC4\uD68D\uC11C 1\uBD80. \uB05D."
|
|
28220
|
+
});
|
|
28221
|
+
}
|
|
28076
28222
|
return findings;
|
|
28077
28223
|
}
|
|
28224
|
+
function dictSuggest(code, match) {
|
|
28225
|
+
const table2 = code === "LOANWORD_ERROR" ? LOANWORD_FIXES : code === "DISCRIMINATORY_TERM" ? DISCRIM_FIXES : null;
|
|
28226
|
+
if (!table2) return void 0;
|
|
28227
|
+
const hit = table2.find(([w]) => w === match.trim());
|
|
28228
|
+
return hit ? `${hit[0]} \u2192 ${hit[1]}` : void 0;
|
|
28229
|
+
}
|
|
28078
28230
|
function gongmunLintWarnings(text, limit = 10) {
|
|
28079
28231
|
const findings = lintGongmunText(text);
|
|
28080
28232
|
const shown = findings.slice(0, limit).map(
|
|
@@ -32322,7 +32474,7 @@ async function dispatch(format, buffer, opts) {
|
|
|
32322
32474
|
}
|
|
32323
32475
|
async function parseImage(buffer, options) {
|
|
32324
32476
|
try {
|
|
32325
|
-
const { parseImageDocument } = await import("./image-ocr-
|
|
32477
|
+
const { parseImageDocument } = await import("./image-ocr-CAVU2TNZ.js");
|
|
32326
32478
|
const { blocks, warnings } = await parseImageDocument(buffer, options);
|
|
32327
32479
|
return {
|
|
32328
32480
|
success: true,
|
|
@@ -32381,7 +32533,7 @@ async function parseHwp(buffer, options) {
|
|
|
32381
32533
|
async function parsePdf(buffer, options) {
|
|
32382
32534
|
let parsePdfDocument;
|
|
32383
32535
|
try {
|
|
32384
|
-
const mod = await import("./parser-
|
|
32536
|
+
const mod = await import("./parser-GIREMEPD.js");
|
|
32385
32537
|
parsePdfDocument = mod.parsePdfDocument;
|
|
32386
32538
|
} catch {
|
|
32387
32539
|
return {
|