kordoc 4.0.0 → 4.0.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/dist/{-URVKBXYK.js → -XMKVL3NX.js} +11 -7
- package/dist/{chunk-IA5UZZKV.js → chunk-3IYQYBUF.js} +2 -2
- package/dist/{chunk-THZVBYHE.js → chunk-67RANGFQ.js} +3 -3
- package/dist/{chunk-JUJEKFUF.js → chunk-6SD4X5PT.js} +3 -3
- package/dist/{chunk-7ETIIYGI.js → chunk-6YIYFWO2.js} +2 -2
- package/dist/{chunk-PGWAF755.js → chunk-AHWRAGXN.js} +477 -89
- package/dist/chunk-AHWRAGXN.js.map +1 -0
- package/dist/{chunk-DVUNWK6W.js → chunk-IKBIIEVJ.js} +2 -2
- package/dist/{chunk-ZKG6SBHV.js → chunk-STMLZDKR.js} +2 -2
- package/dist/{chunk-EBSCV3JC.cjs → chunk-WN7LZHII.cjs} +2 -2
- package/dist/{chunk-EBSCV3JC.cjs.map → chunk-WN7LZHII.cjs.map} +1 -1
- package/dist/cli.js +72 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +730 -342
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -6
- package/dist/index.d.ts +93 -6
- package/dist/index.js +472 -84
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +60 -14
- package/dist/mcp.js.map +1 -1
- package/dist/{parser-NXHY37WH.js → parser-2Q2YKEJG.js} +2 -2
- package/dist/{parser-LHUO6UUA.js → parser-3HM2VYKK.js} +3 -3
- package/dist/{parser-6TV6JKHF.cjs → parser-6AYYGX6J.cjs} +14 -14
- package/dist/{parser-6TV6JKHF.cjs.map → parser-6AYYGX6J.cjs.map} +1 -1
- package/dist/render-W4VCJE6N.js +10 -0
- package/dist/seal-DRPTNHOP.js +10 -0
- package/dist/{watch-PNXTAWDR.js → watch-6OHF727O.js} +7 -7
- package/package.json +1 -1
- package/dist/chunk-PGWAF755.js.map +0 -1
- package/dist/render-T5O6QHBJ.js +0 -10
- package/dist/seal-7KNR5WFH.js +0 -10
- /package/dist/{-URVKBXYK.js.map → -XMKVL3NX.js.map} +0 -0
- /package/dist/{chunk-IA5UZZKV.js.map → chunk-3IYQYBUF.js.map} +0 -0
- /package/dist/{chunk-THZVBYHE.js.map → chunk-67RANGFQ.js.map} +0 -0
- /package/dist/{chunk-JUJEKFUF.js.map → chunk-6SD4X5PT.js.map} +0 -0
- /package/dist/{chunk-7ETIIYGI.js.map → chunk-6YIYFWO2.js.map} +0 -0
- /package/dist/{chunk-DVUNWK6W.js.map → chunk-IKBIIEVJ.js.map} +0 -0
- /package/dist/{chunk-ZKG6SBHV.js.map → chunk-STMLZDKR.js.map} +0 -0
- /package/dist/{parser-NXHY37WH.js.map → parser-2Q2YKEJG.js.map} +0 -0
- /package/dist/{parser-LHUO6UUA.js.map → parser-3HM2VYKK.js.map} +0 -0
- /package/dist/{render-T5O6QHBJ.js.map → render-W4VCJE6N.js.map} +0 -0
- /package/dist/{seal-7KNR5WFH.js.map → seal-DRPTNHOP.js.map} +0 -0
- /package/dist/{watch-PNXTAWDR.js.map → watch-6OHF727O.js.map} +0 -0
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
dedupeRunningHeaders,
|
|
12
12
|
flattenLayoutTables,
|
|
13
13
|
mapPuaText
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6YIYFWO2.js";
|
|
15
15
|
import {
|
|
16
16
|
detectFormat,
|
|
17
17
|
detectOle2Format,
|
|
@@ -32,14 +32,14 @@ import {
|
|
|
32
32
|
paraTextPureT,
|
|
33
33
|
patchZipEntries,
|
|
34
34
|
scanSectionXml
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-67RANGFQ.js";
|
|
36
36
|
import {
|
|
37
37
|
SPACE_EM_FIXED,
|
|
38
38
|
charWidthEm1000,
|
|
39
39
|
fitRatioForFewerLines,
|
|
40
40
|
measureTextWidth,
|
|
41
41
|
simulateWrap
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-6SD4X5PT.js";
|
|
43
43
|
import {
|
|
44
44
|
MAX_DECOMPRESS_SIZE,
|
|
45
45
|
MAX_XML_DEPTH,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
createXmlParser,
|
|
51
51
|
extractTextFromNode,
|
|
52
52
|
findChildByLocalName
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-IKBIIEVJ.js";
|
|
54
54
|
import {
|
|
55
55
|
KordocError,
|
|
56
56
|
classifyError,
|
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
sanitizeHref,
|
|
62
62
|
stripDtd,
|
|
63
63
|
toArrayBuffer
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-STMLZDKR.js";
|
|
65
65
|
|
|
66
66
|
// src/index.ts
|
|
67
67
|
import { readFile } from "fs/promises";
|
|
@@ -19746,8 +19746,9 @@ async function fillHwpx(hwpxBuffer, values, blockedLabels) {
|
|
|
19746
19746
|
import JSZip6 from "jszip";
|
|
19747
19747
|
|
|
19748
19748
|
// src/hwpx/gaejosik.ts
|
|
19749
|
-
var GAEJOSIK_BULLETS = ["\u25A1", "\u25CB", "
|
|
19750
|
-
function gaejosikMarker(depth) {
|
|
19749
|
+
var GAEJOSIK_BULLETS = ["\u25A1", "\u25CB", "-", "\u318D"];
|
|
19750
|
+
function gaejosikMarker(depth, bullet2 = "\u25CB") {
|
|
19751
|
+
if (depth === 1) return bullet2;
|
|
19751
19752
|
return GAEJOSIK_BULLETS[Math.min(depth, GAEJOSIK_BULLETS.length - 1)];
|
|
19752
19753
|
}
|
|
19753
19754
|
function gaejosikSizes(bodyHeight, ov = {}) {
|
|
@@ -19783,11 +19784,11 @@ function gaejosikSpaceBefore(depth, bodyHeight) {
|
|
|
19783
19784
|
const ui = [3e3, 2e3, 1200, 600][Math.min(depth, 3)];
|
|
19784
19785
|
return Math.round(ui * s);
|
|
19785
19786
|
}
|
|
19786
|
-
function gaejosikLevelIndent(depth, bodyHeight, sizes = {}) {
|
|
19787
|
+
function gaejosikLevelIndent(depth, bodyHeight, sizes = {}, bullet2 = "\u25CB") {
|
|
19787
19788
|
const lefts = [0, 1, 1.5, 2];
|
|
19788
19789
|
const left = depth <= 3 ? Math.round(lefts[depth] * bodyHeight) : Math.round((2 + (depth - 3) * 0.5) * bodyHeight);
|
|
19789
19790
|
const h = depth === 0 ? gaejosikSizes(bodyHeight, sizes).dae : bodyHeight;
|
|
19790
|
-
return { left, indent: -markerWidth(gaejosikMarker(depth), h) };
|
|
19791
|
+
return { left, indent: -markerWidth(gaejosikMarker(depth, bullet2), h) };
|
|
19791
19792
|
}
|
|
19792
19793
|
function gaejosikChamIndent(bodyHeight, sizes = {}) {
|
|
19793
19794
|
const cham = gaejosikSizes(bodyHeight, sizes).cham;
|
|
@@ -19855,7 +19856,7 @@ function bodyTitleGeom(bodyHeight, ov = {}) {
|
|
|
19855
19856
|
}
|
|
19856
19857
|
|
|
19857
19858
|
// src/hwpx/gongmun.ts
|
|
19858
|
-
var OFFICIAL_MARGINS = { top: 20, bottom:
|
|
19859
|
+
var OFFICIAL_MARGINS = { top: 20, bottom: 15, left: 20, right: 15 };
|
|
19859
19860
|
var GAEJOSIK_MARGINS = { top: 15, bottom: 15, left: 20, right: 20 };
|
|
19860
19861
|
var GAEJOSIK_HEADER_FOOTER = 4251;
|
|
19861
19862
|
var PRESET_DEFAULTS = {
|
|
@@ -19864,7 +19865,9 @@ var PRESET_DEFAULTS = {
|
|
|
19864
19865
|
plan: { bodyPt: 15, lineSpacing: 160, numbering: "standard" },
|
|
19865
19866
|
notice: { bodyPt: 15, lineSpacing: 160, numbering: "standard" },
|
|
19866
19867
|
minutes: { bodyPt: 14, lineSpacing: 130, numbering: "standard" },
|
|
19867
|
-
gaejosik: { bodyPt: 15, lineSpacing: 160, numbering: "gaejosik" }
|
|
19868
|
+
gaejosik: { bodyPt: 15, lineSpacing: 160, numbering: "gaejosik" },
|
|
19869
|
+
// 보도자료 — 실측(국토부 실물): 본문 바탕 14pt 160%, □→ㅇ→*(각주) 부호
|
|
19870
|
+
press: { bodyPt: 14, lineSpacing: 160, numbering: "report" }
|
|
19868
19871
|
};
|
|
19869
19872
|
var PRESET_ALIAS = {
|
|
19870
19873
|
official: "official",
|
|
@@ -19887,12 +19890,17 @@ var PRESET_ALIAS = {
|
|
|
19887
19890
|
\uAC1C\uC870\uC2DD: "gaejosik",
|
|
19888
19891
|
\uAC1C\uC870\uC2DD\uBCF4\uACE0\uC11C: "gaejosik",
|
|
19889
19892
|
\uC815\uBD80\uBCF4\uACE0\uC11C: "gaejosik",
|
|
19890
|
-
\uC815\uBD80\uD45C\uC900\uAC1C\uC870\uC2DD\uBCF4\uACE0\uC11C: "gaejosik"
|
|
19893
|
+
\uC815\uBD80\uD45C\uC900\uAC1C\uC870\uC2DD\uBCF4\uACE0\uC11C: "gaejosik",
|
|
19894
|
+
press: "press",
|
|
19895
|
+
\uBCF4\uB3C4\uC790\uB8CC: "press"
|
|
19891
19896
|
};
|
|
19892
19897
|
function normalizeGongmunPreset(preset) {
|
|
19893
19898
|
if (!preset) return "official";
|
|
19894
19899
|
return PRESET_ALIAS[preset.trim()] ?? "official";
|
|
19895
19900
|
}
|
|
19901
|
+
function usesReportFonts(preset) {
|
|
19902
|
+
return preset === "gaejosik" || preset === "report" || preset === "plan";
|
|
19903
|
+
}
|
|
19896
19904
|
function resolveGongmun(opts) {
|
|
19897
19905
|
const preset = normalizeGongmunPreset(opts.preset);
|
|
19898
19906
|
const d = PRESET_DEFAULTS[preset];
|
|
@@ -19901,13 +19909,14 @@ function resolveGongmun(opts) {
|
|
|
19901
19909
|
const coverOn = opts.cover !== void 0 ? opts.cover !== false : preset === "gaejosik";
|
|
19902
19910
|
const coverOpts = typeof opts.cover === "object" ? opts.cover : {};
|
|
19903
19911
|
const gaejosik = preset === "gaejosik";
|
|
19912
|
+
const reportFamily = gaejosik || preset === "report" || preset === "plan" || preset === "notice" || preset === "press";
|
|
19904
19913
|
return {
|
|
19905
19914
|
preset,
|
|
19906
19915
|
bodyFont: opts.bodyFont ?? "myeongjo",
|
|
19907
19916
|
bodyHeight: Math.round(bodyPt * 100),
|
|
19908
19917
|
lineSpacing: opts.lineSpacing ?? d.lineSpacing,
|
|
19909
19918
|
numbering: opts.numbering ?? d.numbering,
|
|
19910
|
-
margins: opts.margins ?? (
|
|
19919
|
+
margins: opts.margins ?? (reportFamily ? GAEJOSIK_MARGINS : OFFICIAL_MARGINS),
|
|
19911
19920
|
centerTitle: opts.centerTitle ?? true,
|
|
19912
19921
|
autoFitMinRatio,
|
|
19913
19922
|
cover: coverOn ? { date: coverOpts.date ?? null, org: coverOpts.org ?? "" } : null,
|
|
@@ -19916,12 +19925,26 @@ function resolveGongmun(opts) {
|
|
|
19916
19925
|
sizes: opts.sizes ?? {},
|
|
19917
19926
|
// 쪽번호 — 보고서 계열 관행(실측: 2_보고서 양식·추진계획·공고문 전부 하단 중앙)
|
|
19918
19927
|
pageNumbers: opts.pageNumbers ?? (gaejosik || preset === "report" || preset === "plan"),
|
|
19919
|
-
|
|
19928
|
+
// 머리말·꼬리말 — 실측: 보고서 계열 15mm(GT3·t2·춘천·브라더), 공고·보도 10mm,
|
|
19929
|
+
// 기안문 0(실결재 41/60건 h0/f0)
|
|
19930
|
+
headerFooter: usesReportFonts(preset) ? GAEJOSIK_HEADER_FOOTER : preset === "notice" || preset === "press" ? 2835 : 0,
|
|
19920
19931
|
// "끝." — 기안문 규정(본문 끝 2타+"끝."). 그 외는 opt-in
|
|
19921
19932
|
endMark: opts.endMark ?? preset === "official",
|
|
19922
19933
|
approval: opts.approval && opts.approval.length > 0 ? opts.approval : null,
|
|
19923
19934
|
// 본문 제목박스 — 실측(GT3·GT12): 목차 뒤 본문 시작에 제목 반복. 표지 켜진 개조식 기본
|
|
19924
|
-
bodyTitleBox: opts.bodyTitleBox ?? (gaejosik && coverOn)
|
|
19935
|
+
bodyTitleBox: opts.bodyTitleBox ?? (gaejosik && coverOn),
|
|
19936
|
+
// h2 말머리 — 실측: 보고서 양식 □ 대항목(QA-2), 공고문 아라비아("1. 사업개요", 바이오헬스 실측)
|
|
19937
|
+
h2Marker: opts.h2Marker ?? (preset === "report" || preset === "plan" ? "box" : preset === "notice" ? "number" : "none"),
|
|
19938
|
+
// 2단계 부호 — 실결재 기안문·공고문 ㅇ 지배(60건 중 ㅇ134:○5), 보고서 양식 계열 ○
|
|
19939
|
+
bullet2: opts.bullet2 ?? (preset === "notice" || preset === "press" ? "\u3147" : "\u25CB"),
|
|
19940
|
+
// 단일 형제 부호 생략 — 규정이지만 부호 없는 계단이 실무 눈에 어색 (실무자 QA)
|
|
19941
|
+
suppressSingle: opts.suppressSingle ?? false,
|
|
19942
|
+
docHead: preset === "official" && opts.docHead ? opts.docHead : null,
|
|
19943
|
+
docFoot: preset === "official" && opts.docFoot ? opts.docFoot : null,
|
|
19944
|
+
reportInfo: opts.reportInfo?.trim() || null,
|
|
19945
|
+
noticeHead: preset === "notice" && opts.noticeHead ? opts.noticeHead : null,
|
|
19946
|
+
// 보도자료 머리박스는 프리셋 자체가 요구 — 옵션 미지정이어도 빈 객체
|
|
19947
|
+
press: preset === "press" ? opts.press ?? {} : null
|
|
19925
19948
|
};
|
|
19926
19949
|
}
|
|
19927
19950
|
var HANGUL_INITIALS = [0, 2, 3, 5, 6, 7, 9, 11, 12, 14, 15, 16, 17, 18];
|
|
@@ -19939,6 +19962,7 @@ function circledHangul(n) {
|
|
|
19939
19962
|
return String.fromCodePoint(12910 + n % 14);
|
|
19940
19963
|
}
|
|
19941
19964
|
var REPORT_BULLETS = ["\u25A1", "\u25CB", "-", "\u318D"];
|
|
19965
|
+
var PRESS_BULLETS = ["\u25A1", "\u3147", "*", "\u318D"];
|
|
19942
19966
|
function standardMarker(depth, n) {
|
|
19943
19967
|
switch (depth) {
|
|
19944
19968
|
case 0:
|
|
@@ -19961,17 +19985,19 @@ function standardMarker(depth, n) {
|
|
|
19961
19985
|
return circledHangul(n);
|
|
19962
19986
|
}
|
|
19963
19987
|
}
|
|
19964
|
-
function reportMarker(depth) {
|
|
19965
|
-
|
|
19988
|
+
function reportMarker(depth, bullet2 = "\u25CB", press = false) {
|
|
19989
|
+
const bullets = press ? PRESS_BULLETS : REPORT_BULLETS;
|
|
19990
|
+
const m = bullets[Math.min(depth, bullets.length - 1)];
|
|
19991
|
+
return depth === 1 && !press ? bullet2 : m;
|
|
19966
19992
|
}
|
|
19967
19993
|
function markerWidth(marker, bodyHeight) {
|
|
19968
19994
|
let em = SPACE_EM_FIXED;
|
|
19969
19995
|
for (const c of marker) em += charWidthEm1000(c.codePointAt(0));
|
|
19970
19996
|
return Math.round(em / 1e3 * bodyHeight);
|
|
19971
19997
|
}
|
|
19972
|
-
function levelIndent(depth, bodyHeight, numbering, sizes = {}) {
|
|
19973
|
-
if (numbering === "gaejosik") return gaejosikLevelIndent(depth, bodyHeight, sizes);
|
|
19974
|
-
const marker = numbering === "report" ? reportMarker(depth) : standardMarker(depth, 0);
|
|
19998
|
+
function levelIndent(depth, bodyHeight, numbering, sizes = {}, bullet2 = "\u25CB", press = false) {
|
|
19999
|
+
if (numbering === "gaejosik") return gaejosikLevelIndent(depth, bodyHeight, sizes, bullet2);
|
|
20000
|
+
const marker = numbering === "report" ? reportMarker(depth, bullet2, press) : standardMarker(depth, 0);
|
|
19975
20001
|
return { left: Math.round(depth * bodyHeight), indent: -markerWidth(marker, bodyHeight) };
|
|
19976
20002
|
}
|
|
19977
20003
|
function computeSuppression(depths) {
|
|
@@ -19988,8 +20014,10 @@ function computeSuppression(depths) {
|
|
|
19988
20014
|
return keys.map((k) => (counts.get(k) ?? 0) <= 1);
|
|
19989
20015
|
}
|
|
19990
20016
|
var GongmunNumberer = class {
|
|
19991
|
-
constructor(numbering) {
|
|
20017
|
+
constructor(numbering, bullet2 = "\u25CB", press = false) {
|
|
19992
20018
|
this.numbering = numbering;
|
|
20019
|
+
this.bullet2 = bullet2;
|
|
20020
|
+
this.press = press;
|
|
19993
20021
|
}
|
|
19994
20022
|
counts = [];
|
|
19995
20023
|
/** depth 항목 하나에 대한 마커. suppress=true면 빈 문자열(부호 없음) */
|
|
@@ -19998,8 +20026,8 @@ var GongmunNumberer = class {
|
|
|
19998
20026
|
const n = this.counts[depth] ?? 0;
|
|
19999
20027
|
this.counts[depth] = n + 1;
|
|
20000
20028
|
if (suppress) return "";
|
|
20001
|
-
if (this.numbering === "gaejosik") return gaejosikMarker(depth);
|
|
20002
|
-
return this.numbering === "report" ? reportMarker(depth) : standardMarker(depth, n);
|
|
20029
|
+
if (this.numbering === "gaejosik") return gaejosikMarker(depth, this.bullet2);
|
|
20030
|
+
return this.numbering === "report" ? reportMarker(depth, this.bullet2, this.press) : standardMarker(depth, n);
|
|
20003
20031
|
}
|
|
20004
20032
|
reset() {
|
|
20005
20033
|
this.counts = [];
|
|
@@ -20066,10 +20094,10 @@ function headingCharPrId(level) {
|
|
|
20066
20094
|
if (level === 3) return CHAR_H3;
|
|
20067
20095
|
return CHAR_H4;
|
|
20068
20096
|
}
|
|
20069
|
-
function charPr(id, height, bold, italic, fontId = 0, textColor = DEFAULT_TEXT_COLOR, ratioPct = 100
|
|
20097
|
+
function charPr(id, height, bold, italic, fontId = 0, textColor = DEFAULT_TEXT_COLOR, ratioPct = 100) {
|
|
20070
20098
|
const boldAttr = bold ? ` bold="1"` : "";
|
|
20071
20099
|
const italicAttr = italic ? ` italic="1"` : "";
|
|
20072
|
-
const effFont =
|
|
20100
|
+
const effFont = fontId;
|
|
20073
20101
|
const boldEl = bold ? `<hh:bold/>` : "";
|
|
20074
20102
|
return ` <hh:charPr id="${id}" height="${height}" textColor="${textColor}" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="1"${boldAttr}${italicAttr}>
|
|
20075
20103
|
<hh:fontRef hangul="${effFont}" latin="${effFont}" hanja="${effFont}" japanese="${effFont}" other="${effFont}" symbol="${effFont}" user="${effFont}"/>
|
|
@@ -20121,6 +20149,7 @@ var GJ_PARA_COVER = 21;
|
|
|
20121
20149
|
var GJ_PARA_TOC_ITEM = 22;
|
|
20122
20150
|
var GJ_PARA_CHAPTER = 23;
|
|
20123
20151
|
var GJ_PARA_BAR = 24;
|
|
20152
|
+
var GONGMUN_LIST_PLAIN_BASE = 25;
|
|
20124
20153
|
var GJ_BF_CHAPTER_NUM = 3;
|
|
20125
20154
|
var GJ_BF_CHAPTER_GAP = 4;
|
|
20126
20155
|
var GJ_BF_CHAPTER_TITLE = 5;
|
|
@@ -20159,9 +20188,13 @@ function newPageNumCtrl(num2 = 1) {
|
|
|
20159
20188
|
function pageHidingCtrl(hideHeader = false) {
|
|
20160
20189
|
return `<hp:ctrl><hp:pageHiding hideHeader="${hideHeader ? 1 : 0}" hideFooter="0" hideMasterPage="0" hideBorder="0" hideFill="0" hidePageNum="1"/></hp:ctrl>`;
|
|
20161
20190
|
}
|
|
20191
|
+
var GONGMUN_TBL_CHAR = 11;
|
|
20192
|
+
var GONGMUN_TBL_CHAR_BOLD = 12;
|
|
20193
|
+
var GONGMUN_TBL_PT = 1200;
|
|
20162
20194
|
var CHAR_VARIANT_BASE = 11;
|
|
20163
|
-
function charVariantBase(
|
|
20164
|
-
|
|
20195
|
+
function charVariantBase(measured, isGongmun = true) {
|
|
20196
|
+
if (!isGongmun) return CHAR_VARIANT_BASE;
|
|
20197
|
+
return measured ? 11 + GJ_CHAR_COUNT : 11 + 2;
|
|
20165
20198
|
}
|
|
20166
20199
|
var GONGMUN_BODY_RATIO = 95;
|
|
20167
20200
|
|
|
@@ -20409,7 +20442,7 @@ function generateManifest(chartParts = []) {
|
|
|
20409
20442
|
</opf:package>`;
|
|
20410
20443
|
}
|
|
20411
20444
|
function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls = []) {
|
|
20412
|
-
const
|
|
20445
|
+
const measured = !!gongmun && usesReportFonts(gongmun.preset);
|
|
20413
20446
|
let body = 1e3, code = 900, h1 = 1800, h2 = 1400, h3 = 1200, h4 = 1100;
|
|
20414
20447
|
if (gongmun) {
|
|
20415
20448
|
body = gongmun.bodyHeight;
|
|
@@ -20419,7 +20452,9 @@ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls
|
|
|
20419
20452
|
h3 = body;
|
|
20420
20453
|
h4 = Math.max(body - 100, 1300);
|
|
20421
20454
|
}
|
|
20422
|
-
const bodyFont =
|
|
20455
|
+
const bodyFont = measured ? 4 : 0;
|
|
20456
|
+
const hFont = measured ? 3 : 1;
|
|
20457
|
+
const hBold = !measured;
|
|
20423
20458
|
const bodyRatio = gongmun ? GONGMUN_BODY_RATIO : 100;
|
|
20424
20459
|
const rows = [
|
|
20425
20460
|
charPr(0, body, false, false, bodyFont, theme.body, bodyRatio),
|
|
@@ -20427,25 +20462,31 @@ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls
|
|
|
20427
20462
|
charPr(2, body, false, true, bodyFont, theme.body, bodyRatio),
|
|
20428
20463
|
charPr(3, body, true, true, bodyFont, theme.body, bodyRatio),
|
|
20429
20464
|
charPr(4, code, false, false, 1),
|
|
20430
|
-
charPr(5, h1,
|
|
20431
|
-
charPr(6, h2,
|
|
20432
|
-
charPr(7, h3,
|
|
20433
|
-
charPr(8, h4,
|
|
20465
|
+
charPr(5, h1, hBold, false, hFont, theme.h1),
|
|
20466
|
+
charPr(6, h2, hBold, false, hFont, theme.h2),
|
|
20467
|
+
charPr(7, h3, hBold, false, hFont, theme.h3),
|
|
20468
|
+
charPr(8, h4, hBold, false, hFont, theme.h4),
|
|
20434
20469
|
charPr(CHAR_TABLE_HEADER, body, theme.tableHeaderBold, false, bodyFont, theme.tableHeader),
|
|
20435
20470
|
charPr(CHAR_QUOTE, body, false, true, bodyFont, theme.quote)
|
|
20436
20471
|
];
|
|
20437
|
-
if (
|
|
20472
|
+
if (gongmun && !measured) {
|
|
20473
|
+
rows.push(
|
|
20474
|
+
charPr(11, GONGMUN_TBL_PT, false, false, bodyFont, theme.body),
|
|
20475
|
+
charPr(12, GONGMUN_TBL_PT, true, false, bodyFont, theme.body)
|
|
20476
|
+
);
|
|
20477
|
+
}
|
|
20478
|
+
if (measured) {
|
|
20438
20479
|
const sz = gaejosikSizes(body, gongmun.sizes);
|
|
20439
20480
|
rows.push(
|
|
20440
20481
|
charPr(11, sz.dae, false, false, 3),
|
|
20441
20482
|
// □ HY헤드라인M
|
|
20442
|
-
charPr(12, sz.dae, true, false, 3
|
|
20483
|
+
charPr(12, sz.dae, true, false, 3),
|
|
20443
20484
|
// □ bold
|
|
20444
20485
|
charPr(13, sz.cham, false, false, 5),
|
|
20445
20486
|
// ※ 한양중고딕
|
|
20446
|
-
charPr(14, sz.cham, true, false, 5
|
|
20487
|
+
charPr(14, sz.cham, true, false, 5),
|
|
20447
20488
|
// ※ bold
|
|
20448
|
-
charPr(15, sz.chapter, true, false, 4, "#FFFFFF"
|
|
20489
|
+
charPr(15, sz.chapter, true, false, 4, "#FFFFFF"),
|
|
20449
20490
|
// 장 로마숫자(흰)
|
|
20450
20491
|
charPr(16, sz.chapter, false, false, 3),
|
|
20451
20492
|
// 장 제목
|
|
@@ -20453,15 +20494,15 @@ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls
|
|
|
20453
20494
|
// 표지 제목
|
|
20454
20495
|
charPr(18, sz.coverSub, false, false, 3),
|
|
20455
20496
|
// 표지 날짜·기관명
|
|
20456
|
-
charPr(19, sz.tocLabel, true, false, 3
|
|
20497
|
+
charPr(19, sz.tocLabel, true, false, 3),
|
|
20457
20498
|
// 목 차
|
|
20458
|
-
charPr(20, sz.tocRoman, true, false, 6
|
|
20499
|
+
charPr(20, sz.tocRoman, true, false, 6),
|
|
20459
20500
|
// 목차 로마숫자(한양신명조)
|
|
20460
20501
|
charPr(21, sz.tocItem, false, false, 3),
|
|
20461
20502
|
// 목차 항목
|
|
20462
20503
|
charPr(22, sz.table, false, false, 7),
|
|
20463
20504
|
// 표 셀(맑은 고딕 12pt)
|
|
20464
|
-
charPr(23, sz.table, true, false, 7
|
|
20505
|
+
charPr(23, sz.table, true, false, 7),
|
|
20465
20506
|
// 표 셀 bold
|
|
20466
20507
|
charPr(24, sz.bar, false, false, 4),
|
|
20467
20508
|
// 표지 바 셀 빈 문단(6pt)
|
|
@@ -20500,10 +20541,11 @@ ${base2.join("\n")}
|
|
|
20500
20541
|
}
|
|
20501
20542
|
const ls = gongmun.lineSpacing;
|
|
20502
20543
|
const titleAlign = gongmun.centerTitle ? "CENTER" : "LEFT";
|
|
20544
|
+
const h2Geom = gongmun.h2Marker !== "none" ? { spaceBefore: Math.round(gongmun.bodyHeight * 2), spaceAfter: 0, indent: -markerWidth(gongmun.h2Marker === "box" ? "\u25A1" : "1.", 1600) } : { spaceBefore: 600, spaceAfter: 150 };
|
|
20503
20545
|
const base = [
|
|
20504
20546
|
paraPr(0, { lineSpacing: ls, keepWord: true }),
|
|
20505
20547
|
paraPr(1, { align: titleAlign, spaceBefore: 400, spaceAfter: 400, lineSpacing: ls, keepWord: true }),
|
|
20506
|
-
paraPr(2, { align: "LEFT",
|
|
20548
|
+
paraPr(2, { align: "LEFT", ...h2Geom, lineSpacing: ls, keepWord: true }),
|
|
20507
20549
|
paraPr(3, { align: "LEFT", spaceBefore: 400, spaceAfter: 100, lineSpacing: ls, keepWord: true }),
|
|
20508
20550
|
paraPr(4, { align: "LEFT", spaceBefore: 300, spaceAfter: 100, lineSpacing: ls, keepWord: true }),
|
|
20509
20551
|
paraPr(5, { align: "LEFT", lineSpacing: 130, indent: 400, keepWord: true }),
|
|
@@ -20511,16 +20553,16 @@ ${base2.join("\n")}
|
|
|
20511
20553
|
paraPr(7, { align: "LEFT", lineSpacing: ls, indent: 600, keepWord: true })
|
|
20512
20554
|
];
|
|
20513
20555
|
for (let d = 0; d < GONGMUN_LIST_LEVELS; d++) {
|
|
20514
|
-
const { left, indent } = levelIndent(d, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes);
|
|
20515
|
-
const sectionGap = gongmun.numbering === "gaejosik"
|
|
20516
|
-
const keepNext = gongmun.numbering === "gaejosik" && d === 0;
|
|
20556
|
+
const { left, indent } = levelIndent(d, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, gongmun.preset === "press");
|
|
20557
|
+
const sectionGap = gongmun.numbering === "gaejosik" || gongmun.numbering === "report" ? gaejosikSpaceBefore(d, gongmun.bodyHeight) : 0;
|
|
20558
|
+
const keepNext = (gongmun.numbering === "gaejosik" || gongmun.numbering === "report") && d === 0;
|
|
20517
20559
|
base.push(paraPr(GONGMUN_LIST_BASE + d, { align: "JUSTIFY", lineSpacing: ls, left, indent, spaceBefore: sectionGap, keepWord: true, keepWithNext: keepNext }));
|
|
20518
20560
|
}
|
|
20519
20561
|
base.push(paraPr(GONGMUN_CENTER, { align: "CENTER", lineSpacing: ls, keepWord: true }));
|
|
20520
20562
|
base.push(paraPr(GONGMUN_RIGHT, { align: "RIGHT", lineSpacing: ls, keepWord: true }));
|
|
20521
20563
|
base.push(paraPr(GONGMUN_TBL_CENTER, { align: "CENTER", lineSpacing: 130, keepWord: true }));
|
|
20522
20564
|
base.push(paraPr(GONGMUN_TBL_LEFT, { align: "LEFT", lineSpacing: 130, keepWord: true }));
|
|
20523
|
-
|
|
20565
|
+
{
|
|
20524
20566
|
const cham = gaejosikChamIndent(gongmun.bodyHeight, gongmun.sizes);
|
|
20525
20567
|
const toc = gaejosikTocItemIndent(gongmun.bodyHeight, gongmun.sizes);
|
|
20526
20568
|
base.push(
|
|
@@ -20533,6 +20575,11 @@ ${base2.join("\n")}
|
|
|
20533
20575
|
paraPr(GJ_PARA_BAR, { align: "CENTER", lineSpacing: 70, keepWord: true })
|
|
20534
20576
|
);
|
|
20535
20577
|
}
|
|
20578
|
+
for (let d = 0; d < GONGMUN_LIST_LEVELS; d++) {
|
|
20579
|
+
const { left } = levelIndent(d, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, gongmun.preset === "press");
|
|
20580
|
+
const sectionGap = gongmun.numbering === "gaejosik" || gongmun.numbering === "report" ? gaejosikSpaceBefore(d, gongmun.bodyHeight) : 0;
|
|
20581
|
+
base.push(paraPr(GONGMUN_LIST_PLAIN_BASE + d, { align: "JUSTIFY", lineSpacing: ls, left, indent: 0, spaceBefore: sectionGap, keepWord: true }));
|
|
20582
|
+
}
|
|
20536
20583
|
return `<hh:paraProperties itemCnt="${base.length}">
|
|
20537
20584
|
${base.join("\n")}
|
|
20538
20585
|
</hh:paraProperties>`;
|
|
@@ -20554,14 +20601,15 @@ function fontEntry(id, face, weight = 6) {
|
|
|
20554
20601
|
</hh:font>`;
|
|
20555
20602
|
}
|
|
20556
20603
|
function buildFontFaces(gongmun, bodyFace) {
|
|
20557
|
-
if (gongmun
|
|
20604
|
+
if (gongmun && usesReportFonts(gongmun.preset)) {
|
|
20558
20605
|
const ov = gongmun.fonts;
|
|
20606
|
+
const bodyDefault = gongmun.preset !== "gaejosik" && gongmun.bodyFont === "gothic" ? "\uB9D1\uC740 \uACE0\uB515" : "\uD734\uBA3C\uBA85\uC870";
|
|
20559
20607
|
const faces = [
|
|
20560
20608
|
"\uD568\uCD08\uB86C\uBC14\uD0D5",
|
|
20561
20609
|
"\uD568\uCD08\uB86C\uB3CB\uC6C0",
|
|
20562
20610
|
"HY\uACAC\uACE0\uB515",
|
|
20563
20611
|
ov.heading ?? "HY\uD5E4\uB4DC\uB77C\uC778M",
|
|
20564
|
-
ov.body ??
|
|
20612
|
+
ov.body ?? bodyDefault,
|
|
20565
20613
|
ov.ref ?? "\uD55C\uC591\uC911\uACE0\uB515",
|
|
20566
20614
|
"\uD55C\uC591\uC2E0\uBA85\uC870",
|
|
20567
20615
|
ov.table ?? "\uB9D1\uC740 \uACE0\uB515"
|
|
@@ -20911,7 +20959,9 @@ function computeGongmunFitPlan(blocks, gongmun, gongmunList) {
|
|
|
20911
20959
|
if (gongmun.numbering === "gaejosik" && (depth === 0 || (block.text || "").trimStart().startsWith("\u203B"))) continue;
|
|
20912
20960
|
const content = plainRenderText(block.text || "");
|
|
20913
20961
|
text = marker ? `${marker} ${content}` : content;
|
|
20914
|
-
const
|
|
20962
|
+
const li = levelIndent(depth, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, gongmun.preset === "press");
|
|
20963
|
+
const left = li.left;
|
|
20964
|
+
const indent = marker ? li.indent : 0;
|
|
20915
20965
|
firstW = pageW - left - Math.max(indent, 0);
|
|
20916
20966
|
contW = pageW - left - Math.max(-indent, 0);
|
|
20917
20967
|
} else if (block.type === "paragraph") {
|
|
@@ -20939,7 +20989,7 @@ function variantMapper(fit, blockIdx, base = CHAR_VARIANT_BASE) {
|
|
|
20939
20989
|
}
|
|
20940
20990
|
function precomputeGongmunList(blocks, gongmun) {
|
|
20941
20991
|
const result = /* @__PURE__ */ new Map();
|
|
20942
|
-
const depthOffset = gongmun.numbering === "gaejosik" && blocks.some((b) => b.type === "heading" && b.level === 3) ? 1 : 0;
|
|
20992
|
+
const depthOffset = gongmun.numbering === "gaejosik" && blocks.some((b) => b.type === "heading" && b.level === 3) || gongmun.numbering === "standard" && gongmun.h2Marker === "number" && blocks.some((b) => b.type === "heading" && b.level === 2) ? 1 : 0;
|
|
20943
20993
|
let i = 0;
|
|
20944
20994
|
while (i < blocks.length) {
|
|
20945
20995
|
if (blocks[i].type !== "list_item") {
|
|
@@ -20966,8 +21016,8 @@ function precomputeGongmunList(blocks, gongmun) {
|
|
|
20966
21016
|
break;
|
|
20967
21017
|
}
|
|
20968
21018
|
const depths = run.map((bi) => Math.min(Math.max((blocks[bi].indent || 0) + depthOffset, 0), GONGMUN_LIST_LEVELS - 1));
|
|
20969
|
-
const suppress = gongmun.numbering === "standard" ? computeSuppression(depths) : depths.map(() => false);
|
|
20970
|
-
const numberer = new GongmunNumberer(gongmun.numbering);
|
|
21019
|
+
const suppress = gongmun.suppressSingle && gongmun.numbering === "standard" ? computeSuppression(depths) : depths.map(() => false);
|
|
21020
|
+
const numberer = new GongmunNumberer(gongmun.numbering, gongmun.bullet2, gongmun.preset === "press");
|
|
20971
21021
|
run.forEach((bi, k) => {
|
|
20972
21022
|
const marker = numberer.next(depths[k], suppress[k]);
|
|
20973
21023
|
result.set(bi, { marker, depth: depths[k] });
|
|
@@ -20997,7 +21047,8 @@ function cell(opts) {
|
|
|
20997
21047
|
return `<hp:tc name="" header="0" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="${opts.bf}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="${opts.vertAlign ?? "CENTER"}" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${paras}</hp:subList><hp:cellAddr colAddr="${opts.col}" rowAddr="${opts.row ?? 0}"/><hp:cellSpan colSpan="${opts.colSpan ?? 1}" rowSpan="1"/><hp:cellSz width="${opts.w}" height="${opts.h}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
|
|
20998
21048
|
}
|
|
20999
21049
|
function table(rows, w, h, cols, tblBf = 1) {
|
|
21000
|
-
|
|
21050
|
+
const outLR = w + 566 > 48e3 ? 0 : 283;
|
|
21051
|
+
return `<hp:tbl id="${++gjTableId}" zOrder="0" numberingType="TABLE" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" pageBreak="CELL" repeatHeader="0" rowCnt="${rows.length}" colCnt="${cols}" cellSpacing="0" borderFillIDRef="${tblBf}" noAdjust="1"><hp:sz width="${w}" widthRelTo="ABSOLUTE" height="${h}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="${outLR}" right="${outLR}" top="283" bottom="283"/><hp:inMargin left="141" right="141" top="141" bottom="141"/>` + rows.map((r) => `<hp:tr>${r}</hp:tr>`).join("") + `</hp:tbl>`;
|
|
21001
21052
|
}
|
|
21002
21053
|
function buildGaejosikCover(title, gongmun) {
|
|
21003
21054
|
const g = coverGeom(gongmun.bodyHeight, gongmun.sizes);
|
|
@@ -21660,7 +21711,7 @@ function profileColWidths(tp, colCnt) {
|
|
|
21660
21711
|
if (tp.width) return Array(colCnt).fill(Math.floor(tp.width / colCnt));
|
|
21661
21712
|
return null;
|
|
21662
21713
|
}
|
|
21663
|
-
var CELL_PAD =
|
|
21714
|
+
var CELL_PAD = 1200;
|
|
21664
21715
|
function cellContentWidth(text, charHeight) {
|
|
21665
21716
|
let max = 0;
|
|
21666
21717
|
for (const seg of text.replace(/\*\*|__|`/g, "").split(/<br\s*\/?>/i)) {
|
|
@@ -21669,35 +21720,51 @@ function cellContentWidth(text, charHeight) {
|
|
|
21669
21720
|
}
|
|
21670
21721
|
return max;
|
|
21671
21722
|
}
|
|
21672
|
-
function
|
|
21723
|
+
function cellMinWordWidth(text, charHeight) {
|
|
21724
|
+
let max = 0;
|
|
21725
|
+
for (const seg of text.replace(/\*\*|__|`/g, "").split(/<br\s*\/?>/i)) {
|
|
21726
|
+
for (const word of seg.trim().split(/\s+/)) {
|
|
21727
|
+
const w = measureTextWidth(word, charHeight, 100);
|
|
21728
|
+
if (w > max) max = w;
|
|
21729
|
+
}
|
|
21730
|
+
}
|
|
21731
|
+
return max;
|
|
21732
|
+
}
|
|
21733
|
+
function computeColWidths(colMax, totalWidth, colMinWord = []) {
|
|
21673
21734
|
const colCnt = colMax.length;
|
|
21674
21735
|
const minW = Math.min(Math.max(2e3, Math.round(totalWidth * 0.06)), Math.floor(totalWidth / colCnt));
|
|
21675
21736
|
const cap = Math.round(totalWidth * 0.8);
|
|
21676
21737
|
const raw = colMax.map((w) => Math.min(Math.max(w + CELL_PAD, minW), cap));
|
|
21738
|
+
const floor = raw.map((r, i) => Math.min(Math.max(minW, (colMinWord[i] ?? 0) + CELL_PAD), r, cap));
|
|
21677
21739
|
const widths = Array(colCnt).fill(0);
|
|
21678
21740
|
const free = new Set(raw.map((_, i) => i));
|
|
21679
21741
|
let budget = totalWidth;
|
|
21680
|
-
|
|
21681
|
-
for (
|
|
21682
|
-
|
|
21683
|
-
|
|
21684
|
-
|
|
21685
|
-
|
|
21686
|
-
|
|
21687
|
-
|
|
21688
|
-
|
|
21689
|
-
|
|
21742
|
+
let sumFloorFree = floor.reduce((a, b) => a + b, 0);
|
|
21743
|
+
for (const i of [...raw.keys()].sort((a, b) => raw[a] - raw[b])) {
|
|
21744
|
+
if (free.size <= 1) break;
|
|
21745
|
+
const fixed = Math.round(raw[i] * 1.12);
|
|
21746
|
+
if (budget - fixed < sumFloorFree - floor[i]) break;
|
|
21747
|
+
widths[i] = fixed;
|
|
21748
|
+
free.delete(i);
|
|
21749
|
+
budget -= fixed;
|
|
21750
|
+
sumFloorFree -= floor[i];
|
|
21751
|
+
}
|
|
21752
|
+
const sumFreeRaw = [...free].reduce((a, i) => a + raw[i], 0);
|
|
21753
|
+
if (budget > sumFreeRaw * 1.6) {
|
|
21690
21754
|
const sumRaw = raw.reduce((a, b) => a + b, 0);
|
|
21691
|
-
for (let i = 0; i < colCnt; i++) widths[i]
|
|
21755
|
+
for (let i = 0; i < colCnt; i++) widths[i] = raw[i] + Math.floor(raw[i] / sumRaw * (totalWidth - sumRaw));
|
|
21756
|
+
free.clear();
|
|
21692
21757
|
} else {
|
|
21693
21758
|
for (; ; ) {
|
|
21694
21759
|
const sum2 = [...free].reduce((a, i) => a + raw[i], 0);
|
|
21695
|
-
const short = [...free].filter((i) => raw[i] / sum2 * budget <
|
|
21760
|
+
const short = [...free].filter((i) => raw[i] / sum2 * budget < floor[i]);
|
|
21696
21761
|
if (short.length === 0) break;
|
|
21762
|
+
const shortSum = short.reduce((a, i) => a + floor[i], 0);
|
|
21763
|
+
const scale = Math.min(1, (budget - (free.size - short.length) * minW) / shortSum);
|
|
21697
21764
|
for (const i of short) {
|
|
21698
|
-
widths[i] = minW;
|
|
21765
|
+
widths[i] = Math.max(minW, Math.floor(floor[i] * scale));
|
|
21699
21766
|
free.delete(i);
|
|
21700
|
-
budget -=
|
|
21767
|
+
budget -= widths[i];
|
|
21701
21768
|
}
|
|
21702
21769
|
if (free.size === 0) break;
|
|
21703
21770
|
}
|
|
@@ -21730,12 +21797,15 @@ function generateTable(rows, theme, style = null, remap = null, seq = 0) {
|
|
|
21730
21797
|
const prof = takeProfile(remap, rowCnt, colCnt, anchorOfMarkdownCell(rows[0]?.[0] ?? ""), seq);
|
|
21731
21798
|
const colMax = Array(colCnt).fill(0);
|
|
21732
21799
|
const colMaxBody = Array(colCnt).fill(0);
|
|
21800
|
+
const colMinWord = Array(colCnt).fill(0);
|
|
21733
21801
|
rows.forEach((row, r) => row.forEach((cell2, c) => {
|
|
21734
21802
|
const w = cellContentWidth(cell2, measureH);
|
|
21735
21803
|
if (w > colMax[c]) colMax[c] = w;
|
|
21736
21804
|
if (r > 0 && w > colMaxBody[c]) colMaxBody[c] = w;
|
|
21805
|
+
const mw = cellMinWordWidth(cell2, measureH);
|
|
21806
|
+
if (mw > colMinWord[c]) colMinWord[c] = mw;
|
|
21737
21807
|
}));
|
|
21738
|
-
const colWidths = profileColWidths(prof, colCnt) ?? computeColWidths(colMax, totalW);
|
|
21808
|
+
const colWidths = profileColWidths(prof, colCnt) ?? computeColWidths(colMax, totalW, colMinWord);
|
|
21739
21809
|
const colCentered = colWidths.map((w, c) => colMaxBody[c] + CELL_PAD <= w);
|
|
21740
21810
|
const labelCol0 = !!reg && colCnt === 2 && colCentered[0] && rows.every((r) => (r[0] ?? "").replace(/\*\*|__|`/g, "").length <= 12);
|
|
21741
21811
|
const tblId = nextTableId();
|
|
@@ -21814,16 +21884,19 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
|
|
|
21814
21884
|
const prof = takeProfile(remap, rowCnt, colCnt, first ? anchorOfHtmlCell(first.inner) : "", seq);
|
|
21815
21885
|
const colMax = Array(colCnt).fill(0);
|
|
21816
21886
|
const colMaxBody = Array(colCnt).fill(0);
|
|
21887
|
+
const colMinWord = Array(colCnt).fill(0);
|
|
21817
21888
|
const cellLines = placed.map((cell2) => htmlCellInnerToLines(cell2.inner).lines);
|
|
21818
21889
|
placed.forEach((cell2, i) => {
|
|
21819
21890
|
const w = Math.max(...cellLines[i].map((l) => measureTextWidth(unescapeHtml(l).trim(), measureH, 100)), 0) / cell2.colSpan;
|
|
21891
|
+
const mw = cell2.colSpan === 1 ? Math.max(...cellLines[i].map((l) => cellMinWordWidth(unescapeHtml(l), measureH)), 0) : 0;
|
|
21820
21892
|
for (let dc = 0; dc < cell2.colSpan; dc++) {
|
|
21821
21893
|
const c = cell2.c + dc;
|
|
21822
21894
|
if (w > colMax[c]) colMax[c] = w;
|
|
21823
21895
|
if (!cell2.isHeader && w > colMaxBody[c]) colMaxBody[c] = w;
|
|
21896
|
+
if (dc === 0 && mw > colMinWord[c]) colMinWord[c] = mw;
|
|
21824
21897
|
}
|
|
21825
21898
|
});
|
|
21826
|
-
const colWidths = profileColWidths(prof, colCnt) ?? computeColWidths(colMax, totalWidth);
|
|
21899
|
+
const colWidths = profileColWidths(prof, colCnt) ?? computeColWidths(colMax, totalWidth, colMinWord);
|
|
21827
21900
|
const colCentered = colWidths.map((w, c) => colMaxBody[c] + CELL_PAD <= w);
|
|
21828
21901
|
const cellH = style ? Math.round(measureH * 1.6) + 282 : 1500;
|
|
21829
21902
|
const tblW = colWidths.reduce((a, b) => a + b, 0);
|
|
@@ -21935,6 +22008,118 @@ function buildTitleBox(title, titleCharPr, bodyWidth, reg) {
|
|
|
21935
22008
|
return `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${table2}</hp:run></hp:p>`;
|
|
21936
22009
|
}
|
|
21937
22010
|
|
|
22011
|
+
// src/hwpx/gen-docframe.ts
|
|
22012
|
+
function docframeIds(base) {
|
|
22013
|
+
return { org: base, sender: base + 1, foot: base + 2, small: base + 3, pressLabel: base + 4, pressHead: base + 5, pressTitle: base + 6, pressSub: base + 7, pressContact: base + 8 };
|
|
22014
|
+
}
|
|
22015
|
+
function docframeActive(g) {
|
|
22016
|
+
return !!(g.docHead || g.docFoot || g.reportInfo || g.noticeHead || g.press);
|
|
22017
|
+
}
|
|
22018
|
+
function docframeCharPrXmls(base, measured) {
|
|
22019
|
+
const body = measured ? 4 : 0;
|
|
22020
|
+
const ids = docframeIds(base);
|
|
22021
|
+
return [
|
|
22022
|
+
charPr(ids.org, 1800, true, false, body),
|
|
22023
|
+
charPr(ids.sender, 2200, true, false, body),
|
|
22024
|
+
charPr(ids.foot, 900, false, false, body),
|
|
22025
|
+
charPr(ids.small, 1200, false, false, body),
|
|
22026
|
+
charPr(ids.pressLabel, 2e3, true, false, body),
|
|
22027
|
+
charPr(ids.pressHead, 1e3, true, false, body),
|
|
22028
|
+
charPr(ids.pressTitle, 2500, true, false, body),
|
|
22029
|
+
charPr(ids.pressSub, 1500, true, false, body),
|
|
22030
|
+
charPr(ids.pressContact, 1e3, false, false, body)
|
|
22031
|
+
];
|
|
22032
|
+
}
|
|
22033
|
+
function labeled(label, value, paraPrId) {
|
|
22034
|
+
return `<hp:p paraPrIDRef="${paraPrId}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_BOLD}"><hp:t>${escapeXml(label)}</hp:t></hp:run><hp:run charPrIDRef="${CHAR_NORMAL}"><hp:t>${escapeXml(value)}</hp:t></hp:run></hp:p>`;
|
|
22035
|
+
}
|
|
22036
|
+
function blank() {
|
|
22037
|
+
return `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}"><hp:t></hp:t></hp:run></hp:p>`;
|
|
22038
|
+
}
|
|
22039
|
+
function buildDocHead(g, ids) {
|
|
22040
|
+
const h = g.docHead;
|
|
22041
|
+
const out = [];
|
|
22042
|
+
if (h.org) {
|
|
22043
|
+
out.push(para(h.org, GONGMUN_CENTER, ids.org), blank());
|
|
22044
|
+
}
|
|
22045
|
+
if (h.to !== void 0) out.push(labeled("\uC218\uC2E0 ", h.to, PARA_NORMAL));
|
|
22046
|
+
out.push(para(h.via ? `(\uACBD\uC720) ${h.via}` : "(\uACBD\uC720)", PARA_NORMAL, CHAR_NORMAL));
|
|
22047
|
+
if (h.title !== void 0) out.push(labeled("\uC81C\uBAA9 ", h.title, PARA_NORMAL));
|
|
22048
|
+
out.push(blank());
|
|
22049
|
+
return out;
|
|
22050
|
+
}
|
|
22051
|
+
var FOOT_SEP = "\u2500".repeat(46);
|
|
22052
|
+
function buildDocFoot(g, ids) {
|
|
22053
|
+
const f = g.docFoot;
|
|
22054
|
+
const out = [blank()];
|
|
22055
|
+
if (f.sender) {
|
|
22056
|
+
out.push(para(f.sender, GONGMUN_CENTER, ids.sender), blank());
|
|
22057
|
+
}
|
|
22058
|
+
const foot = (text) => para(text, GONGMUN_TBL_LEFT, ids.foot);
|
|
22059
|
+
out.push(foot(FOOT_SEP));
|
|
22060
|
+
if (f.drafter || f.reviewer || f.approver)
|
|
22061
|
+
out.push(foot(`\uAE30\uC548\uC790 ${f.drafter ?? ""} \uAC80\uD1A0\uC790 ${f.reviewer ?? ""} \uACB0\uC7AC\uAD8C\uC790 ${f.approver ?? ""}`));
|
|
22062
|
+
if (f.cooperator) out.push(foot(`\uD611\uC870\uC790 ${f.cooperator}`));
|
|
22063
|
+
if (f.docNum || f.receive) out.push(foot(`\uC2DC\uD589 ${f.docNum ?? ""} \uC811\uC218 ${f.receive ?? ""}`));
|
|
22064
|
+
if (f.address || f.site) out.push(foot(`${f.address ?? ""} / ${f.site ?? ""}`));
|
|
22065
|
+
if (f.phone || f.fax || f.email || f.disclosure)
|
|
22066
|
+
out.push(foot(`\uC804\uD654 ${f.phone ?? ""} \uC804\uC1A1 ${f.fax ?? ""} / ${f.email ?? ""} / ${f.disclosure ?? ""}`));
|
|
22067
|
+
return out;
|
|
22068
|
+
}
|
|
22069
|
+
function buildReportInfo(g, ids) {
|
|
22070
|
+
return para(g.reportInfo, GONGMUN_RIGHT, ids.small);
|
|
22071
|
+
}
|
|
22072
|
+
function buildNoticeHead(g) {
|
|
22073
|
+
const n = g.noticeHead;
|
|
22074
|
+
return n.no ? [para(n.no, PARA_NORMAL, CHAR_BOLD), blank()] : [];
|
|
22075
|
+
}
|
|
22076
|
+
function buildNoticeFoot(g) {
|
|
22077
|
+
const n = g.noticeHead;
|
|
22078
|
+
const out = [];
|
|
22079
|
+
if (n.date) out.push(blank(), para(n.date, GONGMUN_RIGHT, CHAR_NORMAL));
|
|
22080
|
+
if (n.sender) out.push(blank(), para(n.sender, GONGMUN_RIGHT, CHAR_BOLD));
|
|
22081
|
+
return out;
|
|
22082
|
+
}
|
|
22083
|
+
var PRESS_LABEL_H = 3200;
|
|
22084
|
+
var PRESS_HEAD_H = 900;
|
|
22085
|
+
function buildPressHead(g, ids, bodyWidth, reg) {
|
|
22086
|
+
const p = g.press;
|
|
22087
|
+
const w = bodyWidth - 280;
|
|
22088
|
+
const thick = { t: "thick", b: "thick", l: "thick", r: "thick" };
|
|
22089
|
+
const rows = [tc({ bf: reg.get({ ...thick, b: "thin" }), row: 0, col: 0, w, h: PRESS_LABEL_H, paras: para("\uBCF4\uB3C4\uC790\uB8CC", GONGMUN_TBL_CENTER, ids.pressLabel) })];
|
|
22090
|
+
const headLine = [
|
|
22091
|
+
p.release ? `\uBCF4\uB3C4\uC2DC\uC810 : ${p.release}` : "",
|
|
22092
|
+
p.distribute ? `\uBC30\uD3EC : ${p.distribute}` : ""
|
|
22093
|
+
].filter(Boolean).join(" / ");
|
|
22094
|
+
if (headLine) rows.push(tc({ bf: reg.get({ ...thick, t: "thin" }), row: 1, col: 0, w, h: PRESS_HEAD_H, paras: para(headLine, GONGMUN_TBL_CENTER, ids.pressHead) }));
|
|
22095
|
+
const table2 = tbl(rows, w, PRESS_LABEL_H + (headLine ? PRESS_HEAD_H : 0), 1);
|
|
22096
|
+
return [`<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${table2}</hp:run></hp:p>`, blank()];
|
|
22097
|
+
}
|
|
22098
|
+
function buildPressContact(g, ids, bodyWidth, reg) {
|
|
22099
|
+
const c = g.press?.contact;
|
|
22100
|
+
if (!c || !c.dept && !c.manager && !c.phone) return [];
|
|
22101
|
+
const w = bodyWidth - 280;
|
|
22102
|
+
const cells = [["\uB2F4\uB2F9 \uBD80\uC11C", c.dept ?? ""], ["\uB2F4\uB2F9\uC790", c.manager ?? ""], ["\uC5F0\uB77D\uCC98", c.phone ?? ""]];
|
|
22103
|
+
const labelW = Math.round(w * 0.14);
|
|
22104
|
+
const valueW = Math.round(w / 3) - labelW;
|
|
22105
|
+
let col = 0;
|
|
22106
|
+
const row = cells.flatMap(([label, value], i) => {
|
|
22107
|
+
const bf = (first) => reg.get({
|
|
22108
|
+
t: "thick",
|
|
22109
|
+
b: "thick",
|
|
22110
|
+
l: first && i === 0 ? "thick" : "thin",
|
|
22111
|
+
r: !first && i === cells.length - 1 ? "thick" : "thin",
|
|
22112
|
+
fill: first ? "#E6E6E6" : void 0
|
|
22113
|
+
});
|
|
22114
|
+
return [
|
|
22115
|
+
tc({ bf: bf(true), row: 0, col: col++, w: labelW, h: 1100, paras: para(label, GONGMUN_TBL_CENTER, ids.pressHead) }),
|
|
22116
|
+
tc({ bf: bf(false), row: 0, col: col++, w: valueW, h: 1100, paras: para(value, GONGMUN_TBL_CENTER, ids.pressContact) })
|
|
22117
|
+
];
|
|
22118
|
+
});
|
|
22119
|
+
const table2 = tbl([row.join("")], w, 1100, cells.length * 2);
|
|
22120
|
+
return [blank(), `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${table2}</hp:run></hp:p>`];
|
|
22121
|
+
}
|
|
22122
|
+
|
|
21938
22123
|
// src/hwpx/equation-generate.ts
|
|
21939
22124
|
var MAX_EQUATION_SOURCE = 1e4;
|
|
21940
22125
|
var MAX_GROUP_DEPTH = 64;
|
|
@@ -22227,21 +22412,25 @@ function generateSecPr(gongmun) {
|
|
|
22227
22412
|
m.footer = gongmun.headerFooter;
|
|
22228
22413
|
}
|
|
22229
22414
|
const secPr = `<hp:secPr textDirection="HORIZONTAL" spaceColumns="1134" tabStop="8000" outlineShapeIDRef="1" memoShapeIDRef="0" textVerticalWidthHead="0" masterPageCnt="0"><hp:grid lineGrid="0" charGrid="0" wonggojiFormat="0"/><hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/><hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/><hp:pagePr landscape="WIDELY" width="59528" height="84188" gutterType="LEFT_ONLY"><hp:margin header="${m.header}" footer="${m.footer}" gutter="0" left="${m.left}" right="${m.right}" top="${m.top}" bottom="${m.bottom}"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="EACH_COLUMN" beneathText="0"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="END_OF_DOCUMENT" beneathText="0"/></hp:endNotePr></hp:secPr>`;
|
|
22230
|
-
|
|
22415
|
+
const colPr = `<hp:ctrl><hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="1" sameSz="1" sameGap="0"/></hp:ctrl>`;
|
|
22416
|
+
return secPr + colPr + (gongmun?.pageNumbers ? pageNumCtrl() : "");
|
|
22231
22417
|
}
|
|
22232
|
-
function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, bfReg = null, remap = null) {
|
|
22418
|
+
function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, bfReg = null, remap = null, dfIds = null) {
|
|
22233
22419
|
const paraXmls = [];
|
|
22234
22420
|
let isFirst = true;
|
|
22235
22421
|
let tableSeq = 0;
|
|
22236
22422
|
const orderedCounters = {};
|
|
22237
22423
|
let prevWasOrdered = false;
|
|
22238
22424
|
const gaejosik = gongmun?.preset === "gaejosik";
|
|
22239
|
-
const
|
|
22425
|
+
const measured = !!gongmun && usesReportFonts(gongmun.preset);
|
|
22426
|
+
const vBase = charVariantBase(measured, !!gongmun);
|
|
22240
22427
|
const tableStyle = gongmun ? {
|
|
22241
22428
|
totalWidth: mmToHwpunit(210 - gongmun.margins.left - gongmun.margins.right),
|
|
22242
|
-
|
|
22243
|
-
|
|
22244
|
-
|
|
22429
|
+
// 표 셀 크기 — 실측: 실측 프리셋 맑은 고딕 12pt(22·23), 비실측도 12pt(11·12,
|
|
22430
|
+
// 실결재 지배값 — 본문 크기 셀은 열폭 부족으로 서술 열 세로 신장, v4.0.2 QA)
|
|
22431
|
+
charPr: measured ? GJ_CHAR_TABLE : GONGMUN_TBL_CHAR,
|
|
22432
|
+
boldCharPr: measured ? GJ_CHAR_TABLE_BOLD : GONGMUN_TBL_CHAR_BOLD,
|
|
22433
|
+
charHeight: measured ? gaejosikSizes(gongmun.bodyHeight, gongmun.sizes).table : GONGMUN_TBL_PT,
|
|
22245
22434
|
headerBf: gongmunTableHeaderBf(gaejosik),
|
|
22246
22435
|
centerParaPr: GONGMUN_CENTER,
|
|
22247
22436
|
tblCenterParaPr: GONGMUN_TBL_CENTER,
|
|
@@ -22251,15 +22440,29 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
|
|
|
22251
22440
|
} : null;
|
|
22252
22441
|
const chamMap = (id) => id === CHAR_BOLD ? GJ_CHAR_CHAM_BOLD : id;
|
|
22253
22442
|
let chapterNo = 0;
|
|
22443
|
+
let h2Seq = 0;
|
|
22254
22444
|
let coverH1Idx = -1;
|
|
22255
22445
|
let pendingPageBreak = false;
|
|
22256
22446
|
let pendingNewNum = false;
|
|
22257
22447
|
let titleBoxH1Idx = -1;
|
|
22448
|
+
let pressH1Idx = -1;
|
|
22258
22449
|
let hasFrontPages = false;
|
|
22259
22450
|
const preamble = [];
|
|
22451
|
+
if (gongmun?.reportInfo && dfIds) {
|
|
22452
|
+
preamble.push(buildReportInfo(gongmun, dfIds));
|
|
22453
|
+
}
|
|
22260
22454
|
if (gongmun?.approval && bfReg) {
|
|
22261
22455
|
preamble.push(buildApprovalTable(gongmun.approval, gongmun, bfReg));
|
|
22262
22456
|
}
|
|
22457
|
+
if (gongmun?.docHead && dfIds) {
|
|
22458
|
+
preamble.push(...buildDocHead(gongmun, dfIds));
|
|
22459
|
+
}
|
|
22460
|
+
if (gongmun?.noticeHead && dfIds) {
|
|
22461
|
+
preamble.push(...buildNoticeHead(gongmun));
|
|
22462
|
+
}
|
|
22463
|
+
if (gongmun?.press && dfIds && bfReg && tableStyle) {
|
|
22464
|
+
preamble.push(...buildPressHead(gongmun, dfIds, tableStyle.totalWidth, bfReg));
|
|
22465
|
+
}
|
|
22263
22466
|
if (gaejosik && gongmun) {
|
|
22264
22467
|
const h1Idx = blocks.findIndex((b) => b.type === "heading" && (b.level ?? 1) === 1);
|
|
22265
22468
|
const chapters = blocks.filter((b) => b.type === "heading" && b.level === 2).map((b) => stripChapterNumber(b.text || ""));
|
|
@@ -22284,6 +22487,8 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
|
|
|
22284
22487
|
}
|
|
22285
22488
|
} else if (gongmun && !gaejosik && bfReg && (gongmun.preset === "report" || gongmun.preset === "plan" || gongmun.preset === "notice")) {
|
|
22286
22489
|
titleBoxH1Idx = blocks.findIndex((b) => b.type === "heading" && (b.level ?? 1) === 1);
|
|
22490
|
+
} else if (gongmun?.press && dfIds) {
|
|
22491
|
+
pressH1Idx = blocks.findIndex((b) => b.type === "heading" && (b.level ?? 1) === 1);
|
|
22287
22492
|
}
|
|
22288
22493
|
if (preamble.length > 0) {
|
|
22289
22494
|
preamble[0] = preamble[0].replace(` pageBreak="1"`, "").replace(/<hp:run charPrIDRef="(\d+)">/, `<hp:run charPrIDRef="$1">${generateSecPr(gongmun)}`);
|
|
@@ -22303,8 +22508,16 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
|
|
|
22303
22508
|
}
|
|
22304
22509
|
switch (block.type) {
|
|
22305
22510
|
case "heading": {
|
|
22511
|
+
if (gongmun && blockIdx === pressH1Idx && dfIds) {
|
|
22512
|
+
const parts = [generateParagraph((block.text || "").trim(), GONGMUN_CENTER, dfIds.pressTitle)];
|
|
22513
|
+
for (const s of gongmun.press?.sub ?? []) {
|
|
22514
|
+
parts.push(generateParagraph(`- ${s} -`, GONGMUN_CENTER, dfIds.pressSub));
|
|
22515
|
+
}
|
|
22516
|
+
xml = parts.join("\n ");
|
|
22517
|
+
break;
|
|
22518
|
+
}
|
|
22306
22519
|
if (gongmun && blockIdx === titleBoxH1Idx && tableStyle && bfReg) {
|
|
22307
|
-
xml = buildTitleBox((block.text || "").trim(), CHAR_H1, tableStyle.totalWidth, bfReg);
|
|
22520
|
+
xml = buildTitleBox((block.text || "").trim(), measured ? GJ_CHAR_BODY_TITLE : CHAR_H1, tableStyle.totalWidth, bfReg);
|
|
22308
22521
|
break;
|
|
22309
22522
|
}
|
|
22310
22523
|
if (gaejosik) {
|
|
@@ -22321,18 +22534,24 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
|
|
|
22321
22534
|
(id) => id === CHAR_BOLD ? GJ_CHAR_DAE_BOLD : id
|
|
22322
22535
|
);
|
|
22323
22536
|
} else {
|
|
22324
|
-
xml = generateParagraph(
|
|
22537
|
+
xml = generateParagraph(`${gongmun.bullet2} ${block.text || ""}`, GONGMUN_LIST_BASE + 1, CHAR_NORMAL);
|
|
22325
22538
|
}
|
|
22326
22539
|
break;
|
|
22327
22540
|
}
|
|
22328
22541
|
const pId = headingParaPrId(block.level || 1);
|
|
22329
22542
|
const cId = headingCharPrId(block.level || 1);
|
|
22330
22543
|
const styleId = gongmun ? Math.min(block.level || 1, 4) : 0;
|
|
22331
|
-
|
|
22544
|
+
let hText = block.text || "";
|
|
22545
|
+
if (gongmun && (block.level || 1) === 2 && gongmun.h2Marker !== "none") {
|
|
22546
|
+
const title = stripChapterNumber(hText);
|
|
22547
|
+
hText = gongmun.h2Marker === "box" ? `\u25A1 ${title}` : `${++h2Seq}. ${title}`;
|
|
22548
|
+
}
|
|
22549
|
+
xml = generateParagraph(hText, pId, cId, void 0, styleId);
|
|
22332
22550
|
break;
|
|
22333
22551
|
}
|
|
22334
22552
|
case "paragraph": {
|
|
22335
|
-
|
|
22553
|
+
const pTrim = (block.text || "").trimStart();
|
|
22554
|
+
if (measured && (pTrim.startsWith("\u203B") || /^\*\s/.test(pTrim))) {
|
|
22336
22555
|
xml = generateParagraph((block.text || "").trim(), GJ_PARA_CHAM, GJ_CHAR_CHAM, chamMap);
|
|
22337
22556
|
break;
|
|
22338
22557
|
}
|
|
@@ -22377,7 +22596,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
|
|
|
22377
22596
|
break;
|
|
22378
22597
|
}
|
|
22379
22598
|
case "blockquote": {
|
|
22380
|
-
if (
|
|
22599
|
+
if (measured) {
|
|
22381
22600
|
const t = (block.text || "").trim();
|
|
22382
22601
|
if (t) xml = generateParagraph(t.startsWith("\u203B") ? t : `\u203B ${t}`, GJ_PARA_CHAM, GJ_CHAR_CHAM, chamMap);
|
|
22383
22602
|
break;
|
|
@@ -22395,18 +22614,30 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
|
|
|
22395
22614
|
const depth = info?.depth ?? 0;
|
|
22396
22615
|
const marker2 = info?.marker ?? "";
|
|
22397
22616
|
const content = block.text || "";
|
|
22398
|
-
if (
|
|
22617
|
+
if (measured && content.trimStart().startsWith("\u203B")) {
|
|
22399
22618
|
xml = generateParagraph(content.trim(), GJ_PARA_CHAM, GJ_CHAR_CHAM, chamMap);
|
|
22400
22619
|
break;
|
|
22401
22620
|
}
|
|
22621
|
+
if (measured && block.marker === "*") {
|
|
22622
|
+
xml = generateParagraph(`* ${content.trim()}`, GJ_PARA_CHAM, GJ_CHAR_CHAM, chamMap);
|
|
22623
|
+
break;
|
|
22624
|
+
}
|
|
22402
22625
|
const text = marker2 ? `${marker2} ${content}` : content;
|
|
22626
|
+
const listParaPr = marker2 ? GONGMUN_LIST_BASE + depth : GONGMUN_LIST_PLAIN_BASE + depth;
|
|
22403
22627
|
let listCharPr = gongmun.numbering === "report" && depth === 0 ? CHAR_BOLD : CHAR_NORMAL;
|
|
22404
22628
|
let mapId = fit ? variantMapper(fit, blockIdx, vBase) : void 0;
|
|
22405
|
-
if (
|
|
22629
|
+
if (measured && depth === 0 && gongmun.numbering !== "standard") {
|
|
22406
22630
|
listCharPr = GJ_CHAR_DAE;
|
|
22407
22631
|
mapId = (id) => id === CHAR_BOLD ? GJ_CHAR_DAE_BOLD : id;
|
|
22408
22632
|
}
|
|
22409
|
-
|
|
22633
|
+
if (gongmun.preset === "press") {
|
|
22634
|
+
if (depth === 0) listCharPr = CHAR_NORMAL;
|
|
22635
|
+
if (depth >= 2 && dfIds) {
|
|
22636
|
+
listCharPr = dfIds.small;
|
|
22637
|
+
mapId = void 0;
|
|
22638
|
+
}
|
|
22639
|
+
}
|
|
22640
|
+
xml = generateParagraph(text, listParaPr, listCharPr, mapId);
|
|
22410
22641
|
break;
|
|
22411
22642
|
}
|
|
22412
22643
|
const indent = block.indent || 0;
|
|
@@ -22480,10 +22711,19 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
|
|
|
22480
22711
|
}
|
|
22481
22712
|
paraXmls.push(xml);
|
|
22482
22713
|
}
|
|
22714
|
+
if (gongmun?.noticeHead && dfIds) {
|
|
22715
|
+
paraXmls.push(...buildNoticeFoot(gongmun));
|
|
22716
|
+
}
|
|
22483
22717
|
if (gongmun?.endMark && paraXmls.length > 0) {
|
|
22484
22718
|
const lastText = [...blocks].reverse().find((b) => (b.type === "paragraph" || b.type === "list_item") && (b.text || "").trim())?.text ?? "";
|
|
22485
22719
|
if (!hasEndMark(lastText)) paraXmls.push(buildEndMark());
|
|
22486
22720
|
}
|
|
22721
|
+
if (gongmun?.docFoot && dfIds) {
|
|
22722
|
+
paraXmls.push(...buildDocFoot(gongmun, dfIds));
|
|
22723
|
+
}
|
|
22724
|
+
if (gongmun?.press && dfIds && bfReg && tableStyle) {
|
|
22725
|
+
paraXmls.push(...buildPressContact(gongmun, dfIds, tableStyle.totalWidth, bfReg));
|
|
22726
|
+
}
|
|
22487
22727
|
if (paraXmls.length === 0) {
|
|
22488
22728
|
paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${generateSecPr(gongmun)}<hp:t></hp:t></hp:run></hp:p>`);
|
|
22489
22729
|
}
|
|
@@ -22498,14 +22738,18 @@ async function markdownToHwpx(markdown, options) {
|
|
|
22498
22738
|
const theme = resolveTheme(options?.theme);
|
|
22499
22739
|
const gongmun = options?.gongmun ? resolveGongmun(options.gongmun) : null;
|
|
22500
22740
|
const gaejosik = gongmun?.preset === "gaejosik";
|
|
22741
|
+
const measured = !!gongmun && usesReportFonts(gongmun.preset);
|
|
22501
22742
|
const blocks = parseMarkdownToBlocks(markdown);
|
|
22502
22743
|
const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
|
|
22503
22744
|
const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
|
|
22504
22745
|
const staticBfEnd = gongmun ? gaejosik ? 11 : 4 : 3;
|
|
22505
|
-
const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(
|
|
22746
|
+
const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(measured, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd) : null;
|
|
22506
22747
|
const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (remap?.borderFillXmls.length ?? 0)) : null;
|
|
22748
|
+
const dfActive = !!gongmun && docframeActive(gongmun);
|
|
22749
|
+
const dfBase = charVariantBase(measured, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
|
|
22750
|
+
const dfIds = dfActive ? docframeIds(dfBase) : null;
|
|
22507
22751
|
const chartParts = [];
|
|
22508
|
-
const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap);
|
|
22752
|
+
const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap, dfIds);
|
|
22509
22753
|
if (remap && remap.tables.length > 0) {
|
|
22510
22754
|
const unused = remap.tables.filter((t) => !t.used).length;
|
|
22511
22755
|
if (unused === remap.tables.length) {
|
|
@@ -22517,7 +22761,13 @@ async function markdownToHwpx(markdown, options) {
|
|
|
22517
22761
|
zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
|
|
22518
22762
|
zip.file("META-INF/container.xml", generateContainerXml());
|
|
22519
22763
|
zip.file("Contents/content.hpf", generateManifest(chartParts));
|
|
22520
|
-
zip.file("Contents/header.xml", generateHeaderXml(
|
|
22764
|
+
zip.file("Contents/header.xml", generateHeaderXml(
|
|
22765
|
+
theme,
|
|
22766
|
+
gongmun,
|
|
22767
|
+
fit?.variants ?? [],
|
|
22768
|
+
extraBorderFills,
|
|
22769
|
+
[...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, measured) : []]
|
|
22770
|
+
));
|
|
22521
22771
|
zip.file("Contents/section0.xml", sectionXml);
|
|
22522
22772
|
for (const part of chartParts) zip.file(part.name, part.xml);
|
|
22523
22773
|
zip.file("Preview/PrvText.txt", buildPrvText(blocks));
|
|
@@ -23003,6 +23253,142 @@ function unknownFontWarnings(fonts) {
|
|
|
23003
23253
|
return warnings;
|
|
23004
23254
|
}
|
|
23005
23255
|
|
|
23256
|
+
// src/hwpx/gongmun-lint.ts
|
|
23257
|
+
var RULES = [
|
|
23258
|
+
// 날짜 ─ 온점 뒤 한 칸, 0 패딩 금지, 연도 4자리, 끝 마침표
|
|
23259
|
+
{
|
|
23260
|
+
code: "DATE_NO_SPACE",
|
|
23261
|
+
severity: "error",
|
|
23262
|
+
pattern: /\b\d{4}\.\d{1,2}\.\d{1,2}\.?/g,
|
|
23263
|
+
message: "\uB0A0\uC9DC \uC628\uC810 \uB4A4\uC5D0 \uD55C \uCE78\uC529 \uB744\uC6CC\uC57C \uD568",
|
|
23264
|
+
suggest: "\uC608) 2025. 1. 6."
|
|
23265
|
+
},
|
|
23266
|
+
{
|
|
23267
|
+
code: "DATE_ZERO_PAD",
|
|
23268
|
+
severity: "error",
|
|
23269
|
+
pattern: /\b\d{4}\.\s*0\d\.|\.\s*0\d\./g,
|
|
23270
|
+
message: "\uC6D4\xB7\uC77C \uC55E\uC758 '0'\uC740 \uD45C\uAE30\uD558\uC9C0 \uC54A\uC74C",
|
|
23271
|
+
suggest: "\uC608) 2025. 1. 6. (2025. 01. 06. \u2715)"
|
|
23272
|
+
},
|
|
23273
|
+
{
|
|
23274
|
+
code: "DATE_2DIGIT_YR",
|
|
23275
|
+
severity: "error",
|
|
23276
|
+
pattern: /(?<!\d)['’]\d{2}\.\s*\d/g,
|
|
23277
|
+
message: "\uC5F0\uB3C4\uB294 \uB124 \uC790\uB9AC\uB85C \uD45C\uAE30('24 \u2715)",
|
|
23278
|
+
suggest: "\uC608) 2025. 1. 6."
|
|
23279
|
+
},
|
|
23280
|
+
{
|
|
23281
|
+
code: "DATE_NO_END_DOT",
|
|
23282
|
+
severity: "warning",
|
|
23283
|
+
pattern: /\b\d{4}\.\s\d{1,2}\.\s\d{1,2}(?!\s*[.\d(])/g,
|
|
23284
|
+
message: "\uB0A0\uC9DC\uC758 '\uC77C' \uB2E4\uC74C\uC5D0 \uB9C8\uCE68\uD45C(.)\uB97C \uCC0D\uC5B4\uC57C \uD568",
|
|
23285
|
+
suggest: "\uC608) 2025. 1. 6."
|
|
23286
|
+
},
|
|
23287
|
+
// 시간 ─ 24시각제, 쌍점 붙여쓰기
|
|
23288
|
+
{
|
|
23289
|
+
code: "TIME_AMPM",
|
|
23290
|
+
severity: "error",
|
|
23291
|
+
pattern: /(오전|오후|아침|밤|낮)\s*\d{1,2}\s*시/g,
|
|
23292
|
+
message: "24\uC2DC\uAC01\uC81C \uC22B\uC790\uB85C \uD45C\uAE30(\uC624\uC804/\uC624\uD6C4 \uC0AC\uC6A9 \uC548 \uD568)",
|
|
23293
|
+
suggest: "\uC608) 09:00, 15:30"
|
|
23294
|
+
},
|
|
23295
|
+
{
|
|
23296
|
+
code: "TIME_24H",
|
|
23297
|
+
severity: "warning",
|
|
23298
|
+
pattern: /(?<!\d)24\s*시(?!각)/g,
|
|
23299
|
+
message: "'24\uC2DC'\uBCF4\uB2E4 \uC775\uC77C 00:00 \uB610\uB294 '18:00\uAE4C\uC9C0' \uAD8C\uC7A5",
|
|
23300
|
+
suggest: "\uC608) 18:00"
|
|
23301
|
+
},
|
|
23302
|
+
{
|
|
23303
|
+
code: "TIME_COLON_SP",
|
|
23304
|
+
severity: "error",
|
|
23305
|
+
pattern: /\b\d{1,2}\s+:\s*\d{2}\b|\b\d{1,2}:\s+\d{2}\b/g,
|
|
23306
|
+
message: "\uC2DC\uC640 \uBD84 \uC0AC\uC774 \uC30D\uC810\uC740 \uC591\uCABD\uC744 \uBD99\uC5EC \uC500",
|
|
23307
|
+
suggest: "\uC608) 13:20"
|
|
23308
|
+
},
|
|
23309
|
+
// 금액 ─ '천원' 금지, 금+숫자 붙여쓰기
|
|
23310
|
+
{
|
|
23311
|
+
code: "MONEY_CHEONWON",
|
|
23312
|
+
severity: "error",
|
|
23313
|
+
pattern: /\d+\s*천\s*원/g,
|
|
23314
|
+
message: "\uAE08\uC561\uC740 '\uCC9C\uC6D0'\uC73C\uB85C \uC904\uC774\uC9C0 \uC54A\uACE0 \uC544\uB77C\uBE44\uC544 \uC22B\uC790\uB85C",
|
|
23315
|
+
suggest: "\uC608) 345,000\uC6D0"
|
|
23316
|
+
},
|
|
23317
|
+
{
|
|
23318
|
+
code: "MONEY_GEUM_SP",
|
|
23319
|
+
severity: "warning",
|
|
23320
|
+
pattern: /금\s+\d/g,
|
|
23321
|
+
message: "'\uAE08'\uACFC \uC22B\uC790 \uC0AC\uC774\uB294 \uBD99\uC5EC \uC4F0\uB294 \uAC83\uC774 \uC6D0\uCE59",
|
|
23322
|
+
suggest: "\uC608) \uAE08113,560\uC6D0"
|
|
23323
|
+
},
|
|
23324
|
+
// 붙임 ─ 쌍점 금지(2타 띄움)
|
|
23325
|
+
{
|
|
23326
|
+
code: "BUNIM_COLON",
|
|
23327
|
+
severity: "error",
|
|
23328
|
+
pattern: /붙\s*임\s*:/g,
|
|
23329
|
+
message: "'\uBD99\uC784' \uB2E4\uC74C\uC5D0 \uC30D\uC810(:)\uC744 \uBD99\uC774\uC9C0 \uC54A\uC74C(2\uD0C0 \uB744\uC6C0)",
|
|
23330
|
+
suggest: "\uC608) \uBD99\uC784 \uACC4\uD68D\uC11C 1\uBD80."
|
|
23331
|
+
},
|
|
23332
|
+
// 표기 ─ 물결표+까지 중복, 한글 먼저, 쌍점 띄어쓰기
|
|
23333
|
+
{
|
|
23334
|
+
code: "KKAJI_DUP",
|
|
23335
|
+
severity: "error",
|
|
23336
|
+
pattern: /[∼~~][^\n]{0,20}?까지/g,
|
|
23337
|
+
message: "\uBB3C\uACB0\uD45C(\u223C)\uC640 '\uAE4C\uC9C0'\uB97C \uD568\uAED8 \uC4F0\uC9C0 \uC54A\uC74C",
|
|
23338
|
+
suggest: "\uC608) 2. 20.\u223C2. 24."
|
|
23339
|
+
},
|
|
23340
|
+
{
|
|
23341
|
+
code: "FOREIGN_FIRST",
|
|
23342
|
+
severity: "warning",
|
|
23343
|
+
pattern: /\b[A-Z]{2,5}\s*\([가-힣]/g,
|
|
23344
|
+
message: "\uD55C\uAE00\uC744 \uBA3C\uC800 \uC4F0\uACE0 \uAD04\uD638 \uC548\uC5D0 \uC678\uAD6D\uC5B4\uB97C \uBCD1\uAE30",
|
|
23345
|
+
suggest: "\uC608) \uC5C5\uBB34 \uD611\uC57D(MOU)"
|
|
23346
|
+
},
|
|
23347
|
+
// 쌍점 — URL(https:// 등)·시각(13:20)은 제외
|
|
23348
|
+
{
|
|
23349
|
+
code: "COLON_SPACE",
|
|
23350
|
+
severity: "warning",
|
|
23351
|
+
pattern: /\S\s+:\S|\S:(?!\/\/)[^\s\d]/g,
|
|
23352
|
+
message: "\uC30D\uC810\uC740 \uC55E\uB9D0\uC5D0 \uBD99\uC774\uACE0 \uB4A4\uB294 \uD55C \uCE78 \uB744\uC6C0",
|
|
23353
|
+
suggest: "\uC608) \uC6D0\uC7A5: \uAE40\uAC11\uB3D9"
|
|
23354
|
+
}
|
|
23355
|
+
];
|
|
23356
|
+
function lintGongmunText(text) {
|
|
23357
|
+
const findings = [];
|
|
23358
|
+
let inFence = false;
|
|
23359
|
+
const lines = text.split(/\r?\n/);
|
|
23360
|
+
for (let i = 0; i < lines.length; i++) {
|
|
23361
|
+
const line = lines[i];
|
|
23362
|
+
if (/^\s*(```|~~~)/.test(line)) {
|
|
23363
|
+
inFence = !inFence;
|
|
23364
|
+
continue;
|
|
23365
|
+
}
|
|
23366
|
+
if (inFence) continue;
|
|
23367
|
+
for (const r of RULES) {
|
|
23368
|
+
r.pattern.lastIndex = 0;
|
|
23369
|
+
for (const m of line.matchAll(r.pattern)) {
|
|
23370
|
+
findings.push({
|
|
23371
|
+
line: i + 1,
|
|
23372
|
+
match: m[0].trim(),
|
|
23373
|
+
rule: r.code,
|
|
23374
|
+
severity: r.severity,
|
|
23375
|
+
message: r.message,
|
|
23376
|
+
suggest: r.suggest
|
|
23377
|
+
});
|
|
23378
|
+
}
|
|
23379
|
+
}
|
|
23380
|
+
}
|
|
23381
|
+
return findings;
|
|
23382
|
+
}
|
|
23383
|
+
function gongmunLintWarnings(text, limit = 10) {
|
|
23384
|
+
const findings = lintGongmunText(text);
|
|
23385
|
+
const shown = findings.slice(0, limit).map(
|
|
23386
|
+
(f) => `\uD45C\uAE30\uBC95 [${f.rule}] L${f.line} "${f.match}" \u2014 ${f.message}${f.suggest ? ` (${f.suggest})` : ""}`
|
|
23387
|
+
);
|
|
23388
|
+
if (findings.length > limit) shown.push(`\uD45C\uAE30\uBC95 \uACBD\uACE0 ${findings.length - limit}\uAC74 \uB354 \uC788\uC74C \u2014 kordoc lint\uB85C \uC804\uCCB4 \uD655\uC778`);
|
|
23389
|
+
return shown;
|
|
23390
|
+
}
|
|
23391
|
+
|
|
23006
23392
|
// src/roundtrip/patcher.ts
|
|
23007
23393
|
import JSZip8 from "jszip";
|
|
23008
23394
|
|
|
@@ -25734,7 +26120,7 @@ async function parseHwp(buffer, options) {
|
|
|
25734
26120
|
async function parsePdf(buffer, options) {
|
|
25735
26121
|
let parsePdfDocument;
|
|
25736
26122
|
try {
|
|
25737
|
-
const mod = await import("./parser-
|
|
26123
|
+
const mod = await import("./parser-3HM2VYKK.js");
|
|
25738
26124
|
parsePdfDocument = mod.parsePdfDocument;
|
|
25739
26125
|
} catch {
|
|
25740
26126
|
return {
|
|
@@ -25844,6 +26230,8 @@ export {
|
|
|
25844
26230
|
hwpxToProfile,
|
|
25845
26231
|
isKnownFont,
|
|
25846
26232
|
unknownFontWarnings,
|
|
26233
|
+
lintGongmunText,
|
|
26234
|
+
gongmunLintWarnings,
|
|
25847
26235
|
patchHwpx,
|
|
25848
26236
|
patchHwp,
|
|
25849
26237
|
validateHwpx,
|
|
@@ -25864,4 +26252,4 @@ export {
|
|
|
25864
26252
|
parseHwpml,
|
|
25865
26253
|
fillForm
|
|
25866
26254
|
};
|
|
25867
|
-
//# sourceMappingURL=chunk-
|
|
26255
|
+
//# sourceMappingURL=chunk-AHWRAGXN.js.map
|