auto-hwpx 0.1.0 → 0.1.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 +50 -86
- package/dist/cli-v2.d.ts +3 -0
- package/dist/cli-v2.d.ts.map +1 -0
- package/dist/cli-v2.js +119 -0
- package/dist/cli-v2.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/render-hwpx-v2.d.ts +33 -0
- package/dist/render-hwpx-v2.d.ts.map +1 -0
- package/dist/render-hwpx-v2.js +247 -0
- package/dist/render-hwpx-v2.js.map +1 -0
- package/package.json +5 -8
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -68
- package/dist/cli.js.map +0 -1
- package/dist/render-hwpx.d.ts +0 -16
- package/dist/render-hwpx.d.ts.map +0 -1
- package/dist/render-hwpx.js +0 -518
- package/dist/render-hwpx.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,120 +1,78 @@
|
|
|
1
1
|
# auto-hwpx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Utility to replace `{{key}}` and `{{@imgKey}}` placeholders in `.hwpx` files and emit a new `.hwpx`.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Placeholder syntax
|
|
8
|
-
|
|
9
|
-
- Text placeholder: `<@key@>`
|
|
10
|
-
- Text placeholder with default: `<@key=default text@>`
|
|
11
|
-
- Image placeholder: `<@imgKey@>`
|
|
12
|
-
|
|
13
|
-
The renderer supports both raw token form and XML-escaped form (`<@...@>`) inside HWPX XML entries.
|
|
14
|
-
|
|
15
|
-
## Behavior
|
|
16
|
-
|
|
17
|
-
- Scans `.xml`, `.txt`, and `.hpf` entries in the HWPX zip.
|
|
18
|
-
- For missing text keys:
|
|
19
|
-
- If default exists, default is used.
|
|
20
|
-
- If default does not exist, placeholder is left unchanged.
|
|
21
|
-
- Image placeholders are replaced with a donor `hp:pic` structure loaded from a template HWPX (default: `hwpx-examples/with-img.hwpx`).
|
|
5
|
+
*Note: Written by Codex.*
|
|
22
6
|
|
|
23
7
|
## Install
|
|
24
8
|
|
|
25
9
|
```bash
|
|
26
|
-
npm install
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Demo script
|
|
30
|
-
|
|
31
|
-
Run a one-command demo that:
|
|
32
|
-
- finds `hwpx-examples/*.example.hwpx`
|
|
33
|
-
- creates a tiny demo image
|
|
34
|
-
- fills text + image placeholders
|
|
35
|
-
- writes `demo-output/demo-result.hwpx`
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npm run demo
|
|
10
|
+
npm install -g auto-hwpx@latest
|
|
39
11
|
```
|
|
40
12
|
|
|
41
|
-
##
|
|
13
|
+
## Usage
|
|
42
14
|
|
|
43
|
-
This package is configured as a global CLI with command name:
|
|
44
15
|
|
|
45
16
|
```bash
|
|
46
|
-
auto-hwpx
|
|
17
|
+
$ auto-hwpx template.hwpx -o output.hwpx title="아무도안읽음" @img1="어린왕자.jpg"
|
|
47
18
|
```
|
|
48
19
|
|
|
49
|
-
|
|
20
|
+
The above command will replace the following placeholders in `template.hwpx`:
|
|
21
|
+
- `{{title}}` into "아무도안읽음",
|
|
22
|
+
- and image right after `{{@img1}}` into user given image `"어린왕자.jpg"`.
|
|
50
23
|
|
|
51
|
-
|
|
52
|
-
npm install
|
|
53
|
-
npm run test
|
|
54
|
-
npm run build
|
|
55
|
-
npm pack --dry-run
|
|
56
|
-
```
|
|
24
|
+
## Placeholder syntax
|
|
57
25
|
|
|
58
|
-
|
|
26
|
+
- Text placeholder: `{{key}}`
|
|
27
|
+
- Text placeholder with default: `{{key=default text}}`
|
|
28
|
+
- Image placeholder: `{{@imgKey}}`
|
|
59
29
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
npm publish
|
|
63
|
-
```
|
|
30
|
+
## Demo
|
|
31
|
+

|
|
64
32
|
|
|
65
|
-
If you later move to a scoped package (for example `@your-scope/auto-hwpx`), publish with:
|
|
66
33
|
|
|
34
|
+
**Command:**
|
|
67
35
|
```bash
|
|
68
|
-
|
|
36
|
+
auto-hwpx \
|
|
37
|
+
template.hwpx \
|
|
38
|
+
-o output.hwpx \ # or output/directory (same file name as input)
|
|
39
|
+
title="아무도안읽음" \
|
|
40
|
+
name="차 은 우" \
|
|
41
|
+
content_line1="줄바꿈 지원은 하지 않습니다. 따로 placeholder를 사용해야 합니다." \
|
|
42
|
+
content_line2="HWPX 포맷이 좀 까다롭고, 대단한걸 원하는게 아니여서 구현하기 귗낳습니다." \
|
|
43
|
+
content_line3="**주의**: {{key}} 치환이후에 포맷이 바뀌어버리면 문제가 발생합니다." \
|
|
44
|
+
content_line4="예를들어, {{very_long_long_ 다음줄 long_long_key}} -> 토마토 의 경우 " \
|
|
45
|
+
content_line5="두줄에서 한줄이 되어버리므로 변환이 실패합니다." \
|
|
46
|
+
location="한강뷰 아파트" \
|
|
47
|
+
caption1="캡션도 가능!" \
|
|
48
|
+
@img1="어린왕자.jpg"
|
|
69
49
|
```
|
|
70
50
|
|
|
71
|
-
|
|
51
|
+
<!-- - `input.hwpx`: -->
|
|
72
52
|
|
|
73
|
-
|
|
74
|
-
npm install -g auto-hwpx
|
|
75
|
-
auto-hwpx --help
|
|
76
|
-
```
|
|
53
|
+
<!-- <img src="./ex-input.png" style="height:70ex">
|
|
77
54
|
|
|
78
|
-
## CLI usage
|
|
79
55
|
|
|
80
|
-
|
|
81
|
-
npm run start -- \
|
|
82
|
-
--input hwpx-examples/초과근무내역서.example.hwpx \
|
|
83
|
-
--output /tmp/output.hwpx \
|
|
84
|
-
--text-json '{"name":"홍길동","content":"작업 내용"}' \
|
|
85
|
-
--images-json '{"img":"/absolute/path/to/image.png"}'
|
|
86
|
-
```
|
|
56
|
+
- ==> `output.hwpx`:
|
|
87
57
|
|
|
88
|
-
|
|
58
|
+
<img src="./ex-output.png" style="height:70ex"> -->
|
|
89
59
|
|
|
90
|
-
```bash
|
|
91
|
-
npm run start -- \
|
|
92
|
-
--input hwpx-examples/초과근무내역서.example.hwpx \
|
|
93
|
-
--output /tmp/output.hwpx \
|
|
94
|
-
--text-json '{}' \
|
|
95
|
-
--images-json '{"img":"/absolute/path/to/image.png"}' \
|
|
96
|
-
--image-template hwpx-examples/with-img.hwpx
|
|
97
|
-
```
|
|
98
60
|
|
|
99
|
-
Both `--text-json` and `--images-json` accept either inline JSON text or a path to a JSON file.
|
|
100
61
|
|
|
101
62
|
## Programmatic API
|
|
102
63
|
|
|
103
64
|
```ts
|
|
104
|
-
import {
|
|
65
|
+
import { replaceHwpxPlaceholdersV2 } from "./src/render-hwpx-v2.js";
|
|
105
66
|
|
|
106
|
-
const result = await
|
|
107
|
-
inputPath: "
|
|
67
|
+
const result = await replaceHwpxPlaceholdersV2({
|
|
68
|
+
inputPath: "demo-assets/example.hwpx",
|
|
108
69
|
outputPath: "/tmp/output.hwpx",
|
|
109
70
|
replacements: {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
},
|
|
114
|
-
images: {
|
|
115
|
-
img: "/absolute/path/to/image.png",
|
|
116
|
-
},
|
|
71
|
+
name: "홍길동",
|
|
72
|
+
content: "작업 내용",
|
|
73
|
+
"@img1": "/absolute/path/to/image.png",
|
|
117
74
|
},
|
|
75
|
+
removeUnresolvedPlaceholders: true, // default true
|
|
118
76
|
});
|
|
119
77
|
|
|
120
78
|
console.log(result);
|
|
@@ -123,15 +81,21 @@ console.log(result);
|
|
|
123
81
|
Return shape:
|
|
124
82
|
|
|
125
83
|
```ts
|
|
126
|
-
interface
|
|
127
|
-
|
|
84
|
+
interface ReplaceHwpxV2Result {
|
|
85
|
+
replacements: number;
|
|
128
86
|
imageReplacements: number;
|
|
129
87
|
unresolvedPlaceholders: string[];
|
|
130
88
|
}
|
|
131
89
|
```
|
|
132
90
|
|
|
133
|
-
|
|
91
|
+
List keys API:
|
|
134
92
|
|
|
135
|
-
```
|
|
136
|
-
|
|
93
|
+
```ts
|
|
94
|
+
import { listHwpxPlaceholderKeysV2 } from "./src/render-hwpx-v2.js";
|
|
95
|
+
|
|
96
|
+
const keys = await listHwpxPlaceholderKeysV2({
|
|
97
|
+
inputPath: "demo-assets/example.hwpx",
|
|
98
|
+
});
|
|
137
99
|
```
|
|
100
|
+
|
|
101
|
+
|
package/dist/cli-v2.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-v2.d.ts","sourceRoot":"","sources":["../src/cli-v2.ts"],"names":[],"mappings":""}
|
package/dist/cli-v2.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { listHwpxPlaceholderKeysV2, replaceHwpxPlaceholdersV2, } from "./render-hwpx-v2.js";
|
|
6
|
+
function parseAssignments(values) {
|
|
7
|
+
if (!values || values.length === 0) {
|
|
8
|
+
return {};
|
|
9
|
+
}
|
|
10
|
+
const result = {};
|
|
11
|
+
for (const entry of values) {
|
|
12
|
+
const separatorIndex = entry.indexOf("=");
|
|
13
|
+
if (separatorIndex <= 0) {
|
|
14
|
+
throw new Error(`Invalid assignment "${entry}". Expected key=value format.`);
|
|
15
|
+
}
|
|
16
|
+
const key = entry.slice(0, separatorIndex).trim();
|
|
17
|
+
const value = entry.slice(separatorIndex + 1);
|
|
18
|
+
if (!key) {
|
|
19
|
+
throw new Error(`Invalid assignment "${entry}". Key cannot be empty.`);
|
|
20
|
+
}
|
|
21
|
+
result[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
async function resolveOutputFilePath(inputPath, rawOutputPath) {
|
|
26
|
+
const normalizedOutput = path.resolve(rawOutputPath);
|
|
27
|
+
const looksLikeDirectory = rawOutputPath.endsWith("/") || rawOutputPath.endsWith(path.sep);
|
|
28
|
+
let outputIsDirectory = looksLikeDirectory;
|
|
29
|
+
try {
|
|
30
|
+
const stat = await fs.stat(normalizedOutput);
|
|
31
|
+
outputIsDirectory = stat.isDirectory();
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
if (looksLikeDirectory || path.extname(normalizedOutput) === "") {
|
|
35
|
+
outputIsDirectory = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (outputIsDirectory) {
|
|
39
|
+
await fs.mkdir(normalizedOutput, { recursive: true });
|
|
40
|
+
return path.join(normalizedOutput, path.basename(inputPath));
|
|
41
|
+
}
|
|
42
|
+
await fs.mkdir(path.dirname(normalizedOutput), { recursive: true });
|
|
43
|
+
return normalizedOutput;
|
|
44
|
+
}
|
|
45
|
+
async function main() {
|
|
46
|
+
const program = new Command();
|
|
47
|
+
program
|
|
48
|
+
.name("auto-hwpx")
|
|
49
|
+
.description("Replace {{key}} text and {{@key}} image placeholders in an .hwpx file.")
|
|
50
|
+
.showHelpAfterError("(Run with --help for usage and examples)")
|
|
51
|
+
.argument("<inputPath>", "Input .hwpx file path")
|
|
52
|
+
.argument("[assignments...]", "Replacement pairs as key=value. Use @key=/path/to/image for image replacement.")
|
|
53
|
+
.option("-o, --output <path>", "Output file path or directory (directories are created automatically)")
|
|
54
|
+
.option("-l, --list-keys", "List all placeholder keys in the input .hwpx and exit.")
|
|
55
|
+
.option("--remove-placeholder", "Remove unresolved placeholders (default behavior).")
|
|
56
|
+
.option("-k, --keep-placeholder", "Keep unresolved placeholders ({{key}} and {{@key}}).")
|
|
57
|
+
.addHelpText("after", `
|
|
58
|
+
Examples:
|
|
59
|
+
# Write to an explicit output file
|
|
60
|
+
$ auto-hwpx ./template.hwpx -o ./out/result.hwpx name="Alice" cost="12000" @img1="./receipt.jpg"
|
|
61
|
+
|
|
62
|
+
# If output is a directory, output file keeps the input file name
|
|
63
|
+
$ auto-hwpx ./template.hwpx -o ./out name="Alice" @img2="./photo.png"
|
|
64
|
+
-> writes ./out/template.hwpx
|
|
65
|
+
|
|
66
|
+
# Keep unresolved placeholders
|
|
67
|
+
$ auto-hwpx ./template.hwpx -o ./out/result.hwpx -k name="Alice"
|
|
68
|
+
|
|
69
|
+
# List all keys from the template
|
|
70
|
+
$ auto-hwpx ./template.hwpx -l
|
|
71
|
+
|
|
72
|
+
Notes:
|
|
73
|
+
- {{@img_key}} placeholder should be placed before the target image.
|
|
74
|
+
- The target image must be configured as "글자처럼 취급".
|
|
75
|
+
`);
|
|
76
|
+
program.parse(process.argv);
|
|
77
|
+
const options = program.opts();
|
|
78
|
+
const inputPath = program.processedArgs[0];
|
|
79
|
+
if (options.listKeys) {
|
|
80
|
+
const listed = await listHwpxPlaceholderKeysV2({ inputPath });
|
|
81
|
+
process.stdout.write(`${JSON.stringify({
|
|
82
|
+
inputPath: path.resolve(inputPath),
|
|
83
|
+
keyCount: listed.allKeys.length,
|
|
84
|
+
keys: listed.allKeys,
|
|
85
|
+
textKeys: listed.textKeys,
|
|
86
|
+
imageKeys: listed.imageKeys,
|
|
87
|
+
}, null, 2)}\n`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (options.removePlaceholder && options.keepPlaceholder) {
|
|
91
|
+
throw new Error("Use either --remove-placeholder or --keep-placeholder, not both.");
|
|
92
|
+
}
|
|
93
|
+
if (!options.output) {
|
|
94
|
+
throw new Error("Missing required option: -o, --output <path> (or use -l, --list-keys).");
|
|
95
|
+
}
|
|
96
|
+
const removeUnresolvedPlaceholders = options.keepPlaceholder ? false : true;
|
|
97
|
+
const rawAssignments = program.processedArgs[1];
|
|
98
|
+
const assignments = Array.isArray(rawAssignments)
|
|
99
|
+
? rawAssignments
|
|
100
|
+
: program.processedArgs.slice(1);
|
|
101
|
+
const outputFilePath = await resolveOutputFilePath(inputPath, options.output);
|
|
102
|
+
const result = await replaceHwpxPlaceholdersV2({
|
|
103
|
+
inputPath,
|
|
104
|
+
outputPath: outputFilePath,
|
|
105
|
+
replacements: parseAssignments(assignments),
|
|
106
|
+
removeUnresolvedPlaceholders,
|
|
107
|
+
});
|
|
108
|
+
process.stdout.write(`${JSON.stringify({
|
|
109
|
+
outputPath: outputFilePath,
|
|
110
|
+
textReplacements: result.replacements,
|
|
111
|
+
imageReplacements: result.imageReplacements,
|
|
112
|
+
unresolvedPlaceholders: result.unresolvedPlaceholders,
|
|
113
|
+
}, null, 2)}\n`);
|
|
114
|
+
}
|
|
115
|
+
main().catch((error) => {
|
|
116
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
117
|
+
process.exitCode = 1;
|
|
118
|
+
});
|
|
119
|
+
//# sourceMappingURL=cli-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-v2.js","sourceRoot":"","sources":["../src/cli-v2.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { findBinaryItemIdRefByImagePlaceholder, listHwpxPlaceholderKeysV2, replaceUnzippedBinDataImage, replaceHwpxPlaceholdersV2, type ListHwpxV2KeysInput, type ListHwpxV2KeysResult, type ReplaceUnzippedBinDataImageInput, type ReplaceUnzippedBinDataImageResult, type ReplaceHwpxV2Input, type ReplaceHwpxV2Result, } from "./render-hwpx-v2.js";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qCAAqC,EACrC,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,EACrC,KAAK,iCAAiC,EACtC,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { findBinaryItemIdRefByImagePlaceholder, listHwpxPlaceholderKeysV2, replaceUnzippedBinDataImage, replaceHwpxPlaceholdersV2, } from "./render-hwpx-v2.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qCAAqC,EACrC,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,GAO1B,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface ReplaceHwpxV2Input {
|
|
2
|
+
inputPath: string;
|
|
3
|
+
outputPath: string;
|
|
4
|
+
replacements: Record<string, string>;
|
|
5
|
+
removeUnresolvedPlaceholders?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ListHwpxV2KeysInput {
|
|
8
|
+
inputPath: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ListHwpxV2KeysResult {
|
|
11
|
+
allKeys: string[];
|
|
12
|
+
textKeys: string[];
|
|
13
|
+
imageKeys: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface ReplaceHwpxV2Result {
|
|
16
|
+
replacements: number;
|
|
17
|
+
imageReplacements: number;
|
|
18
|
+
unresolvedPlaceholders: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface ReplaceUnzippedBinDataImageInput {
|
|
21
|
+
unzippedRootPath: string;
|
|
22
|
+
binaryItemIdRef: string;
|
|
23
|
+
sourceImagePath: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ReplaceUnzippedBinDataImageResult {
|
|
26
|
+
targetImagePath: string;
|
|
27
|
+
bytesWritten: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function findBinaryItemIdRefByImagePlaceholder(sectionXml: string, imagePlaceholderKey: string): string | null;
|
|
30
|
+
export declare function listHwpxPlaceholderKeysV2(input: ListHwpxV2KeysInput): Promise<ListHwpxV2KeysResult>;
|
|
31
|
+
export declare function replaceUnzippedBinDataImage(input: ReplaceUnzippedBinDataImageInput): Promise<ReplaceUnzippedBinDataImageResult>;
|
|
32
|
+
export declare function replaceHwpxPlaceholdersV2(input: ReplaceHwpxV2Input): Promise<ReplaceHwpxV2Result>;
|
|
33
|
+
//# sourceMappingURL=render-hwpx-v2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-hwpx-v2.d.ts","sourceRoot":"","sources":["../src/render-hwpx-v2.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,gCAAgC;IAC/C,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iCAAiC;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AA4HD,wBAAgB,qCAAqC,CACnD,UAAU,EAAE,MAAM,EAClB,mBAAmB,EAAE,MAAM,GAC1B,MAAM,GAAG,IAAI,CAaf;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CA8B/B;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,gCAAgC,GACtC,OAAO,CAAC,iCAAiC,CAAC,CAgC5C;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CA8G9B"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import JSZip from "jszip";
|
|
4
|
+
const PLACEHOLDER_RE = /\{\{([^}=\s]+)(?:=([^}]*))?\}\}/g;
|
|
5
|
+
const IMG_BINARY_REF_RE = /<(?:hc|hp):img\b[^>]*\bbinaryItemIDRef=(["'])([^"']+)\1/;
|
|
6
|
+
function isTextEntry(fileName) {
|
|
7
|
+
return (fileName.endsWith(".xml") ||
|
|
8
|
+
fileName.endsWith(".txt") ||
|
|
9
|
+
fileName.endsWith(".hpf"));
|
|
10
|
+
}
|
|
11
|
+
function isSectionEntry(fileName) {
|
|
12
|
+
return /^Contents\/section\d+\.xml$/.test(fileName);
|
|
13
|
+
}
|
|
14
|
+
function splitReplacementEntries(replacements) {
|
|
15
|
+
const textValues = {};
|
|
16
|
+
const imageValues = {};
|
|
17
|
+
for (const [key, value] of Object.entries(replacements)) {
|
|
18
|
+
if (key.startsWith("@")) {
|
|
19
|
+
imageValues[key] = value;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
textValues[key] = value;
|
|
23
|
+
}
|
|
24
|
+
return { textValues, imageValues };
|
|
25
|
+
}
|
|
26
|
+
function replaceTokens(params) {
|
|
27
|
+
let replaced = 0;
|
|
28
|
+
const output = params.input.replaceAll(PLACEHOLDER_RE, (fullMatch, key, defaultValue) => {
|
|
29
|
+
if (key.startsWith("@")) {
|
|
30
|
+
if (defaultValue !== undefined) {
|
|
31
|
+
return fullMatch;
|
|
32
|
+
}
|
|
33
|
+
if (!params.imageKeys.has(key)) {
|
|
34
|
+
params.unresolved.add(key);
|
|
35
|
+
}
|
|
36
|
+
return fullMatch;
|
|
37
|
+
}
|
|
38
|
+
const explicit = params.textValues[key];
|
|
39
|
+
if (explicit !== undefined) {
|
|
40
|
+
replaced += 1;
|
|
41
|
+
return params.escapeOutput ? escapeXmlText(explicit) : explicit;
|
|
42
|
+
}
|
|
43
|
+
if (defaultValue !== undefined) {
|
|
44
|
+
replaced += 1;
|
|
45
|
+
return params.escapeOutput ? escapeXmlText(defaultValue) : defaultValue;
|
|
46
|
+
}
|
|
47
|
+
params.unresolved.add(key);
|
|
48
|
+
return fullMatch;
|
|
49
|
+
});
|
|
50
|
+
return { output, replaced };
|
|
51
|
+
}
|
|
52
|
+
function escapeXmlText(text) {
|
|
53
|
+
return text
|
|
54
|
+
.replaceAll("&", "&")
|
|
55
|
+
.replaceAll("<", "<")
|
|
56
|
+
.replaceAll(">", ">")
|
|
57
|
+
.replaceAll('"', """)
|
|
58
|
+
.replaceAll("'", "'");
|
|
59
|
+
}
|
|
60
|
+
function cleanupPlaceholders(params) {
|
|
61
|
+
return params.input.replaceAll(PLACEHOLDER_RE, (fullMatch, key) => {
|
|
62
|
+
if (key.startsWith("@")) {
|
|
63
|
+
if (params.resolvedImageKeys.has(key)) {
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
return params.removeUnresolvedPlaceholders ? "" : fullMatch;
|
|
67
|
+
}
|
|
68
|
+
return params.removeUnresolvedPlaceholders ? "" : fullMatch;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function findBinDataEntryName(zip, binaryItemIdRef) {
|
|
72
|
+
const prefix = `BinData/${binaryItemIdRef}.`;
|
|
73
|
+
const matched = Object.keys(zip.files)
|
|
74
|
+
.filter((fileName) => {
|
|
75
|
+
const entry = zip.files[fileName];
|
|
76
|
+
return !entry.dir && fileName.startsWith(prefix);
|
|
77
|
+
})
|
|
78
|
+
.sort();
|
|
79
|
+
if (matched.length === 0) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
if (matched.length > 1) {
|
|
83
|
+
throw new Error(`Multiple BinData entries found for binaryItemIDRef "${binaryItemIdRef}": ${matched.join(", ")}`);
|
|
84
|
+
}
|
|
85
|
+
return matched[0];
|
|
86
|
+
}
|
|
87
|
+
export function findBinaryItemIdRefByImagePlaceholder(sectionXml, imagePlaceholderKey) {
|
|
88
|
+
const normalizedKey = imagePlaceholderKey.startsWith("@")
|
|
89
|
+
? imagePlaceholderKey
|
|
90
|
+
: `@${imagePlaceholderKey}`;
|
|
91
|
+
const token = `{{${normalizedKey}}}`;
|
|
92
|
+
const tokenIndex = sectionXml.indexOf(token);
|
|
93
|
+
if (tokenIndex < 0) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const tail = sectionXml.slice(tokenIndex + token.length);
|
|
97
|
+
const imgMatch = IMG_BINARY_REF_RE.exec(tail);
|
|
98
|
+
return imgMatch?.[2] ?? null;
|
|
99
|
+
}
|
|
100
|
+
export async function listHwpxPlaceholderKeysV2(input) {
|
|
101
|
+
const bytes = await fs.readFile(input.inputPath);
|
|
102
|
+
const zip = await JSZip.loadAsync(bytes);
|
|
103
|
+
const keySet = new Set();
|
|
104
|
+
for (const entryName of Object.keys(zip.files)) {
|
|
105
|
+
const entry = zip.file(entryName);
|
|
106
|
+
if (!entry || !isTextEntry(entryName)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const sourceText = await entry.async("string");
|
|
110
|
+
const matcher = new RegExp(PLACEHOLDER_RE.source, "g");
|
|
111
|
+
for (const match of sourceText.matchAll(matcher)) {
|
|
112
|
+
const key = match[1];
|
|
113
|
+
if (key) {
|
|
114
|
+
keySet.add(key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const allKeys = [...keySet].sort();
|
|
119
|
+
const imageKeys = allKeys.filter((key) => key.startsWith("@"));
|
|
120
|
+
const textKeys = allKeys.filter((key) => !key.startsWith("@"));
|
|
121
|
+
return {
|
|
122
|
+
allKeys,
|
|
123
|
+
textKeys,
|
|
124
|
+
imageKeys,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export async function replaceUnzippedBinDataImage(input) {
|
|
128
|
+
const binaryItemIdRef = input.binaryItemIdRef.trim();
|
|
129
|
+
if (!binaryItemIdRef) {
|
|
130
|
+
throw new Error("binaryItemIdRef cannot be empty.");
|
|
131
|
+
}
|
|
132
|
+
const binDataDir = path.join(input.unzippedRootPath, "BinData");
|
|
133
|
+
const entries = await fs.readdir(binDataDir, { withFileTypes: true });
|
|
134
|
+
const matched = entries
|
|
135
|
+
.filter((entry) => entry.isFile() && entry.name.startsWith(`${binaryItemIdRef}.`))
|
|
136
|
+
.map((entry) => entry.name)
|
|
137
|
+
.sort();
|
|
138
|
+
if (matched.length === 0) {
|
|
139
|
+
throw new Error(`No BinData file found for binaryItemIdRef "${binaryItemIdRef}" in ${binDataDir}`);
|
|
140
|
+
}
|
|
141
|
+
if (matched.length > 1) {
|
|
142
|
+
throw new Error(`Multiple BinData files found for binaryItemIdRef "${binaryItemIdRef}": ${matched.join(", ")}`);
|
|
143
|
+
}
|
|
144
|
+
const sourceBytes = await fs.readFile(input.sourceImagePath);
|
|
145
|
+
const targetImagePath = path.join(binDataDir, matched[0]);
|
|
146
|
+
await fs.writeFile(targetImagePath, sourceBytes);
|
|
147
|
+
return {
|
|
148
|
+
targetImagePath,
|
|
149
|
+
bytesWritten: sourceBytes.byteLength,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
export async function replaceHwpxPlaceholdersV2(input) {
|
|
153
|
+
const removeUnresolvedPlaceholders = input.removeUnresolvedPlaceholders ?? true;
|
|
154
|
+
const { textValues, imageValues } = splitReplacementEntries(input.replacements);
|
|
155
|
+
const imageKeys = new Set(Object.keys(imageValues));
|
|
156
|
+
const bytes = await fs.readFile(input.inputPath);
|
|
157
|
+
const zip = await JSZip.loadAsync(bytes);
|
|
158
|
+
const unresolved = new Set();
|
|
159
|
+
const sectionTexts = new Map();
|
|
160
|
+
let textReplacementCount = 0;
|
|
161
|
+
let imageReplacementCount = 0;
|
|
162
|
+
for (const entryName of Object.keys(zip.files)) {
|
|
163
|
+
const entry = zip.file(entryName);
|
|
164
|
+
if (!entry || !isTextEntry(entryName)) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const sourceText = await entry.async("string");
|
|
168
|
+
const replaced = replaceTokens({
|
|
169
|
+
input: sourceText,
|
|
170
|
+
textValues,
|
|
171
|
+
imageKeys,
|
|
172
|
+
unresolved,
|
|
173
|
+
escapeOutput: entryName.endsWith(".xml") || entryName.endsWith(".hpf"),
|
|
174
|
+
});
|
|
175
|
+
textReplacementCount += replaced.replaced;
|
|
176
|
+
if (isSectionEntry(entryName)) {
|
|
177
|
+
sectionTexts.set(entryName, replaced.output);
|
|
178
|
+
}
|
|
179
|
+
if (replaced.output !== sourceText) {
|
|
180
|
+
zip.file(entryName, replaced.output);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const sortedSections = [...sectionTexts.entries()].sort(([a], [b]) => a.localeCompare(b));
|
|
184
|
+
const imageBytesCache = new Map();
|
|
185
|
+
const resolvedImageKeys = new Set();
|
|
186
|
+
for (const [imageKey, imagePath] of Object.entries(imageValues)) {
|
|
187
|
+
let binaryItemIdRef = null;
|
|
188
|
+
for (const [, sectionXml] of sortedSections) {
|
|
189
|
+
const found = findBinaryItemIdRefByImagePlaceholder(sectionXml, imageKey);
|
|
190
|
+
if (found) {
|
|
191
|
+
binaryItemIdRef = found;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (!binaryItemIdRef) {
|
|
196
|
+
unresolved.add(imageKey);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const targetEntryName = findBinDataEntryName(zip, binaryItemIdRef);
|
|
200
|
+
if (!targetEntryName) {
|
|
201
|
+
throw new Error(`No BinData entry found for binaryItemIDRef "${binaryItemIdRef}" (placeholder ${imageKey}).`);
|
|
202
|
+
}
|
|
203
|
+
let sourceBytes = imageBytesCache.get(imagePath);
|
|
204
|
+
if (!sourceBytes) {
|
|
205
|
+
try {
|
|
206
|
+
sourceBytes = await fs.readFile(imagePath);
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
throw new Error(`Image file not found for key "${imageKey}": ${imagePath}`, {
|
|
210
|
+
cause: error,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
imageBytesCache.set(imagePath, sourceBytes);
|
|
214
|
+
}
|
|
215
|
+
zip.file(targetEntryName, sourceBytes);
|
|
216
|
+
imageReplacementCount += 1;
|
|
217
|
+
resolvedImageKeys.add(imageKey);
|
|
218
|
+
}
|
|
219
|
+
for (const entryName of Object.keys(zip.files)) {
|
|
220
|
+
const entry = zip.file(entryName);
|
|
221
|
+
if (!entry || !isTextEntry(entryName)) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const sourceText = await entry.async("string");
|
|
225
|
+
const cleaned = cleanupPlaceholders({
|
|
226
|
+
input: sourceText,
|
|
227
|
+
removeUnresolvedPlaceholders,
|
|
228
|
+
resolvedImageKeys,
|
|
229
|
+
});
|
|
230
|
+
if (cleaned !== sourceText) {
|
|
231
|
+
zip.file(entryName, cleaned);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const outputBytes = await zip.generateAsync({
|
|
235
|
+
type: "nodebuffer",
|
|
236
|
+
compression: "DEFLATE",
|
|
237
|
+
compressionOptions: { level: 9 },
|
|
238
|
+
});
|
|
239
|
+
await fs.mkdir(path.dirname(input.outputPath), { recursive: true });
|
|
240
|
+
await fs.writeFile(input.outputPath, outputBytes);
|
|
241
|
+
return {
|
|
242
|
+
replacements: textReplacementCount,
|
|
243
|
+
imageReplacements: imageReplacementCount,
|
|
244
|
+
unresolvedPlaceholders: [...unresolved].sort(),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=render-hwpx-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-hwpx-v2.js","sourceRoot":"","sources":["../src/render-hwpx-v2.ts"],"names":[],"mappings":"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"}
|