@shuji-bonji/pdf-writer-mcp 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +128 -0
- package/README.ja.md +141 -0
- package/README.md +91 -172
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -1
- package/dist/services/annotation.d.ts +17 -0
- package/dist/services/annotation.js +90 -0
- package/dist/services/annotation.js.map +1 -0
- package/dist/services/editor.d.ts +3 -1
- package/dist/services/editor.js +17 -0
- package/dist/services/editor.js.map +1 -1
- package/dist/services/outline.d.ts +20 -0
- package/dist/services/outline.js +93 -0
- package/dist/services/outline.js.map +1 -0
- package/dist/tools/definitions.d.ts +132 -0
- package/dist/tools/definitions.js +77 -0
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/handlers.d.ts +2 -0
- package/dist/tools/handlers.js +12 -2
- package/dist/tools/handlers.js.map +1 -1
- package/dist/types/index.d.ts +43 -0
- package/dist/utils/validation.d.ts +3 -1
- package/dist/utils/validation.js +61 -1
- package/dist/utils/validation.js.map +1 -1
- package/package.json +6 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.4.0] - 2026-07-16
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Editing tools (Tier A, wave 2)**:
|
|
10
|
+
- `add_bookmarks` — set the document outline. Nestable via `children` (up to 8
|
|
11
|
+
levels, 2000 entries). Replaces any existing outline. Titles are written as
|
|
12
|
+
UTF-16BE so CJK round-trips correctly. Open items carry a positive `/Count`,
|
|
13
|
+
collapsed items a negative one, per ISO 32000-1 §12.3.3.
|
|
14
|
+
- `add_annotation` — add a `text` (sticky note), `highlight`, or `square`
|
|
15
|
+
annotation. Coordinates use PDF space (origin bottom-left, points). Colors
|
|
16
|
+
are `#rrggbb`; `contents` and `author` accept CJK.
|
|
17
|
+
|
|
18
|
+
pdf-lib exposes no outline or annotation API, so both are built from the
|
|
19
|
+
low-level object model (`services/outline.ts`, `services/annotation.ts`).
|
|
20
|
+
|
|
21
|
+
## [0.3.1] - 2026-07-16
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **Text extraction broken for digits in Latin context** (regression introduced in
|
|
26
|
+
0.3.0): `subsetFont` is now called with `noLayoutClosure: true`.
|
|
27
|
+
|
|
28
|
+
pdf-lib's `CustomFontEmbedder` (used with `subset: false`) derives glyphs
|
|
29
|
+
through two independent paths: the CIDs written into the content stream come
|
|
30
|
+
from `font.layout(text)` — **after** GSUB substitution — while the ToUnicode
|
|
31
|
+
CMap is built from `font.characterSet` → `glyphForCodePoint` — **before**
|
|
32
|
+
substitution. Noto Sans JP substitutes ASCII digits with alternate forms in
|
|
33
|
+
Latin context (`layout('English 0')` yields glyph 17460, not 17), so the two
|
|
34
|
+
disagreed and extraction returned wrong characters (`v0.3.0` → `vô.õ.ô`, and
|
|
35
|
+
poppler dropped the digits entirely). Rendering was correct throughout, which
|
|
36
|
+
made this easy to miss.
|
|
37
|
+
|
|
38
|
+
Excluding layout-reachable glyphs from the subset prevents the substitution
|
|
39
|
+
altogether, so `layout()` and `glyphsForString()` agree again. Subsets also got
|
|
40
|
+
smaller as a side effect (9.1 KB → 4.5 KB for a typical page).
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- `render.test.ts` now asserts that the CIDs written to the page match the
|
|
45
|
+
ToUnicode CMap, so this class of regression fails the suite.
|
|
46
|
+
|
|
47
|
+
## [0.3.0] - 2026-07-16
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- **Japanese text rendered as blank boxes in every viewer** (Chrome, Firefox,
|
|
52
|
+
Acrobat, poppler, Claude Desktop). Font subsetting no longer goes through
|
|
53
|
+
pdf-lib's `embedFont(subset: true)`: fonts are now pre-subset with harfbuzz
|
|
54
|
+
([subset-font](https://github.com/papandreou/subset-font)) and embedded with
|
|
55
|
+
`subset: false`.
|
|
56
|
+
|
|
57
|
+
fontkit's subsetter drops glyph outlines for CJK fonts. Because the ToUnicode
|
|
58
|
+
CMap stayed correct, text extraction kept working and the existing tests
|
|
59
|
+
passed while the visible output was broken.
|
|
60
|
+
|
|
61
|
+
| Approach | PDF size | Rendering |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| fontkit `subset: true` (previous) | 24 KB | broken |
|
|
64
|
+
| pdf-lib `subset: false` alone | 3.9 MB | correct |
|
|
65
|
+
| harfbuzz + `subset: false` (current) | 14.5 KB | correct |
|
|
66
|
+
|
|
67
|
+
- The note in the design doc claiming poppler's `Embedded font file may be
|
|
68
|
+
invalid` warning was harmless is retracted — poppler followed it with
|
|
69
|
+
`Couldn't create a font`, i.e. the warning was the breakage.
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- `render.test.ts`: extracts the embedded font program from generated PDFs and
|
|
74
|
+
verifies that every rendered character retains a real glyph outline. Verified
|
|
75
|
+
to fail against the pre-0.3.0 implementation.
|
|
76
|
+
- CI fetches Noto Sans JP and sets `TEST_FONT_PATH`, so the font-dependent tests
|
|
77
|
+
no longer skip.
|
|
78
|
+
|
|
79
|
+
### Changed
|
|
80
|
+
|
|
81
|
+
- `loadFont` split into `openFont` (read + glyph coverage) and `embedFontFor`
|
|
82
|
+
(subset + embed). Subsetting depends on the text being drawn, so embedding is
|
|
83
|
+
deferred until the input is final.
|
|
84
|
+
- **Dependency added**: `subset-font` (harfbuzz/wasm, no native binaries).
|
|
85
|
+
|
|
86
|
+
## [0.2.1] - 2026-07-16
|
|
87
|
+
|
|
88
|
+
### Added
|
|
89
|
+
|
|
90
|
+
- **`onMissingGlyph` option** for the create tools. Characters absent from the
|
|
91
|
+
font (e.g. ✔ U+2714, which Noto Sans JP does not include) were previously
|
|
92
|
+
embedded as `.notdef` and rendered as silent blanks.
|
|
93
|
+
- `error` (default) — list the offending characters and fail
|
|
94
|
+
- `replace` — substitute 〓 and report via `warnings`
|
|
95
|
+
- `ignore` — render as before and report via `warnings`
|
|
96
|
+
- `CreateResult.warnings` reports substituted or ignored characters.
|
|
97
|
+
|
|
98
|
+
## [0.2.0] - 2026-07-16
|
|
99
|
+
|
|
100
|
+
### Added
|
|
101
|
+
|
|
102
|
+
- **Editing tools (Tier A, wave 1)** — the server now edits existing PDFs in
|
|
103
|
+
addition to creating them:
|
|
104
|
+
- `set_metadata` — update Info dictionary fields, preserving the rest
|
|
105
|
+
- `merge_pdfs` — concatenate in order (metadata inherited from the first file)
|
|
106
|
+
- `split_pdf` — one file per page range
|
|
107
|
+
- `extract_pages` — extract in the requested order (doubles as reordering)
|
|
108
|
+
- `delete_pages` — remove pages (deleting all is rejected)
|
|
109
|
+
- `reorder_pages` — reorder by an explicit permutation
|
|
110
|
+
- `rotate_pages` — rotate clockwise, accumulating over existing rotation
|
|
111
|
+
- **Signature guard**: editing a PDF with `/ByteRange` fails by default, since
|
|
112
|
+
pdf-lib rewrites the whole file and would invalidate existing signatures.
|
|
113
|
+
Pass `allowBreakingSignatures: true` to proceed anyway.
|
|
114
|
+
- Page specs (`"1,3-5,8-"`, 1-based, order-preserving, duplicates removed).
|
|
115
|
+
- CI (`ci.yml`) and npm publish via Trusted Publisher / OIDC (`publish.yml`).
|
|
116
|
+
|
|
117
|
+
## [0.1.0] - 2026-07-15
|
|
118
|
+
|
|
119
|
+
Initial release.
|
|
120
|
+
|
|
121
|
+
### Added
|
|
122
|
+
|
|
123
|
+
- `create_text_pdf` — plain text with paragraph breaks, wrapping, pagination
|
|
124
|
+
- `create_markdown_pdf` — headings, lists, code blocks, quotes, rules, tables
|
|
125
|
+
- `create_table_pdf` — ruled tables with automatic column widths and repeated
|
|
126
|
+
headers across page breaks
|
|
127
|
+
- Japanese font embedding, ToUnicode CMap (extractable/searchable text),
|
|
128
|
+
file or base64 output, `asserts`-based input validation.
|
package/README.ja.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# pdf-writer-mcp
|
|
2
|
+
|
|
3
|
+
[](https://github.com/shuji-bonji/pdf-writer-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@shuji-bonji/pdf-writer-mcp)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
7
|
+
[English](./README.md)
|
|
8
|
+
|
|
9
|
+
テキスト / Markdown / 表データからの **PDF 生成** と、既存 PDF の **編集**(メタデータ・ページ操作)を行う MCP (Model Context Protocol) サーバです。[pdf-lib](https://pdf-lib.js.org/) をコアに、harfbuzz サブセットによる日本語フォント埋め込みに対応します。
|
|
10
|
+
|
|
11
|
+
[pdf-reader-mcp](https://github.com/shuji-bonji/pdf-reader-mcp)(構造解析)、[pdf-verify-mcp](https://github.com/shuji-bonji/pdf-verify-mcp)(真正性検証)と同じ PDF family の一員です。`pdf-reader-mcp` が「何があるか」を読み、`pdf-verify-mcp` が「本物か」を検証するのに対し、`pdf-writer-mcp` は「それを書く」役割を担います。
|
|
12
|
+
|
|
13
|
+
## ツール
|
|
14
|
+
|
|
15
|
+
### 生成
|
|
16
|
+
|
|
17
|
+
| ツール | 役割 |
|
|
18
|
+
|--------|------|
|
|
19
|
+
| `create_text_pdf` | プレーンテキスト — `\n` で改行、空行で段落区切り、長い行は自動折り返し |
|
|
20
|
+
| `create_markdown_pdf` | Markdown — 見出し / 段落 / 箇条書き・番号リスト / コードブロック / 引用 / 水平線 / 表 |
|
|
21
|
+
| `create_table_pdf` | 罫線付き表 — 列幅の自動算出、セル内折り返し、改ページ時のヘッダ再描画 |
|
|
22
|
+
|
|
23
|
+
共通オプション: `outputPath` / `returnBase64` / `fontPath` / `fontSize` / `pageSize`(A4/A3/A5/LETTER/LEGAL)/ `margin` / `title` / `author` / `onMissingGlyph`。
|
|
24
|
+
|
|
25
|
+
### 編集
|
|
26
|
+
|
|
27
|
+
| ツール | 役割 |
|
|
28
|
+
|--------|------|
|
|
29
|
+
| `set_metadata` | Info 辞書の更新(`title` / `author` / `subject` / `keywords` / `creator`)。指定フィールドのみ変更し、他は保持 |
|
|
30
|
+
| `merge_pdfs` | 2〜50 個の PDF を指定順に結合。メタデータは先頭ファイルから引き継ぎ |
|
|
31
|
+
| `split_pdf` | ページ範囲ごとに 1 ファイルへ分割 |
|
|
32
|
+
| `extract_pages` | 指定順を保持して抽出(並べ替えを兼ねる) |
|
|
33
|
+
| `delete_pages` | ページ削除(全ページの削除はエラー) |
|
|
34
|
+
| `reorder_pages` | 全ページの順列による並べ替え |
|
|
35
|
+
| `rotate_pages` | 時計回りに回転(90/180/270)。既存の回転に加算 |
|
|
36
|
+
| `add_bookmarks` | しおり(アウトライン)の設定。`children` で入れ子にでき、既存のしおりは置換 |
|
|
37
|
+
| `add_annotation` | 付箋(`text`)/ ハイライト(`highlight`)/ 矩形(`square`)の注釈を追加 |
|
|
38
|
+
|
|
39
|
+
共通オプション: `outputPath` / `returnBase64` / `allowBreakingSignatures`。
|
|
40
|
+
|
|
41
|
+
ページ指定は `"1,3-5,8-"` 形式(1 始まり。`-3` は先頭から 3 ページまで、`8-` は 8 ページから最終まで)。指定順を保持し、重複は除去します。
|
|
42
|
+
|
|
43
|
+
> **署名について**: pdf-lib は保存時にファイル全体を再構築するため、編集すると既存の電子署名は必ず無効化されます。`/ByteRange` を含む PDF は既定でエラーとし、`allowBreakingSignatures: true` を指定したときのみ続行します。署名を保持する増分更新はロードマップ参照。
|
|
44
|
+
|
|
45
|
+
## インストール
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"mcpServers": {
|
|
50
|
+
"pdf-writer": {
|
|
51
|
+
"command": "npx",
|
|
52
|
+
"args": ["-y", "@shuji-bonji/pdf-writer-mcp"],
|
|
53
|
+
"env": {
|
|
54
|
+
"PDF_WRITER_FONT": "/absolute/path/to/NotoSansJP-Regular.otf"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`PDF_WRITER_FONT` を設定しておくと、各ツールで `fontPath` を省略しても日本語が出せます。
|
|
62
|
+
|
|
63
|
+
## フォント
|
|
64
|
+
|
|
65
|
+
標準 PDF フォント(Helvetica)は **ASCII のみ** です。日本語など非ラテン文字を描画するには、`fontPath` または `PDF_WRITER_FONT` で埋め込み可能な**単一フェイス**のフォント(`.ttf` / `.otf`)を指定してください。
|
|
66
|
+
|
|
67
|
+
- 推奨入手先: [Noto Sans JP (SubsetOTF/JP)](https://github.com/notofonts/noto-cjk/tree/main/Sans/SubsetOTF/JP) — 静的・単一フェイス・SIL OFL。
|
|
68
|
+
- **`.ttc`(TrueTypeCollection)は非対応**です。検知してエラーにするため、単一フェイスを抽出してください:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
python3 -c "from fontTools.ttLib import TTCollection; \
|
|
72
|
+
TTCollection('NotoSansCJK-Regular.ttc').fonts[0].save('NotoSansCJKjp-Regular.otf')"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### フォント未収録文字(グリフ欠落)
|
|
76
|
+
|
|
77
|
+
フォントに存在しない文字(例: Noto Sans JP に無い ✔ U+2714)は、そのままだと `.notdef` として埋め込まれ、無警告で空白になります。`onMissingGlyph` でこの挙動を選べます。
|
|
78
|
+
|
|
79
|
+
| 値 | 挙動 |
|
|
80
|
+
|----|------|
|
|
81
|
+
| `error`(既定) | 欠落文字を `"✔" (U+2714)` 形式で列挙してエラー |
|
|
82
|
+
| `replace` | 〓 に置換して生成し、`warnings` で報告 |
|
|
83
|
+
| `ignore` | 空白のまま生成し、`warnings` で報告 |
|
|
84
|
+
|
|
85
|
+
## 返り値
|
|
86
|
+
|
|
87
|
+
```jsonc
|
|
88
|
+
{
|
|
89
|
+
"path": "/abs/out.pdf", // outputPath 指定時
|
|
90
|
+
"base64": "JVBERi0xLj...", // returnBase64 指定時、または outputPath 省略時
|
|
91
|
+
"pageCount": 3,
|
|
92
|
+
"bytes": 91788,
|
|
93
|
+
"font": "NotoSansJP-Regular.otf",
|
|
94
|
+
"warnings": ["Replaced 1 unsupported character(s) with \"〓\": \"✔\" (U+2714)"]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
編集ツールは `font` を除いた同じ形を返します。`split_pdf` は `{ files: [...], count }` を返します。
|
|
99
|
+
|
|
100
|
+
## テキスト抽出
|
|
101
|
+
|
|
102
|
+
生成される PDF はテキストの選択・コピー・全文検索・スクリーンリーダ読み上げが可能です。埋め込みサブセットフォントでも pdf-lib が ToUnicode CMap を出力するためで、この性質は回帰テスト(`extract.test.ts` / `render.test.ts`)で担保しています。
|
|
103
|
+
|
|
104
|
+
> poppler 系のビューアは、OTF/CFF フォントを CIDFontType0 として埋め込む際に `Mismatch between font type and embedded font file` という警告を表示することがあります。これは無害で、描画・抽出とも正常です。
|
|
105
|
+
|
|
106
|
+
## 開発
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm install
|
|
110
|
+
npm run build # dist/ に出力
|
|
111
|
+
npm test # vitest
|
|
112
|
+
npm run typecheck # tsc --noEmit
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
日本語フォント依存のテストは `TEST_FONT_PATH` を指定すると有効になります。
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
TEST_FONT_PATH=/path/to/NotoSansJP-Regular.otf npm test
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 既知の制約
|
|
122
|
+
|
|
123
|
+
- **インライン装飾**: 太字・斜体はサイズ / 字面のみで、書体としては反映されません(1 文書につき単一フォントを埋め込むため)。
|
|
124
|
+
- **`.ttc` フォント**: 単一フェイスへの抽出が必要です(上記参照)。
|
|
125
|
+
- **サブセット名の接頭辞**: 慣習的な `ABCDEF+` を付けないため、一部ツールがサブセットでないと誤認します。描画・抽出には影響せず、PDF/A の厳密対応時のみ問題になります。
|
|
126
|
+
|
|
127
|
+
## ロードマップ
|
|
128
|
+
|
|
129
|
+
- [x] 編集系 Tier A 第1波 — メタデータ・ページ操作(v0.2.0)
|
|
130
|
+
- [x] 編集系 Tier A 第2波 — しおり・注釈(v0.4.0)
|
|
131
|
+
- [ ] 編集系 Tier B — フォーム記入 / フラット化、透かし、添付ファイル、ページ番号スタンプ
|
|
132
|
+
- [ ] タグ付き PDF / PDF/UA(スクリーンリーダ向けの構造タグ)
|
|
133
|
+
- [ ] `.ttc` からのフェイス自動抽出
|
|
134
|
+
- [ ] 見出し用と本文用のフォント分け(太字フェイス埋め込み)
|
|
135
|
+
- [ ] 画像埋め込み、ヘッダー / フッター
|
|
136
|
+
- [ ] Tier C — 署名を保持する増分更新、本文テキスト編集、タグ木の保守
|
|
137
|
+
- [ ] PDF/A 変換
|
|
138
|
+
|
|
139
|
+
## ライセンス
|
|
140
|
+
|
|
141
|
+
MIT © shuji-bonji
|
package/README.md
CHANGED
|
@@ -1,73 +1,55 @@
|
|
|
1
1
|
# pdf-writer-mcp
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[
|
|
6
|
-
|
|
7
|
-
## 位置づけ
|
|
8
|
-
|
|
9
|
-
`shuji-bonji` の PDF 系 MCP エコシステムにおける「生成(write)」担当です。
|
|
10
|
-
読み取り・検証系とは責務を分けています。
|
|
11
|
-
|
|
12
|
-
```mermaid
|
|
13
|
-
graph LR
|
|
14
|
-
subgraph 生成
|
|
15
|
-
W[pdf-writer-mcp<br/>text/md/table→PDF]
|
|
16
|
-
end
|
|
17
|
-
subgraph 読取
|
|
18
|
-
R[pdf-reader-mcp<br/>抽出・検査]
|
|
19
|
-
end
|
|
20
|
-
subgraph 検証
|
|
21
|
-
V[pdf-verify-mcp<br/>署名・準拠性]
|
|
22
|
-
end
|
|
23
|
-
subgraph 仕様参照
|
|
24
|
-
S[pdf-spec-mcp<br/>ISO 32000]
|
|
25
|
-
end
|
|
26
|
-
W --> R
|
|
27
|
-
R --> V
|
|
28
|
-
S -.仕様根拠.-> W
|
|
29
|
-
S -.仕様根拠.-> V
|
|
30
|
-
```
|
|
3
|
+
[](https://github.com/shuji-bonji/pdf-writer-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@shuji-bonji/pdf-writer-mcp)
|
|
5
|
+
[](./LICENSE)
|
|
31
6
|
|
|
32
|
-
|
|
7
|
+
[日本語](./README.ja.md)
|
|
33
8
|
|
|
34
|
-
|
|
35
|
-
- **7 つの編集ツール**: メタデータ更新、結合・分割・抽出・削除・並べ替え・回転
|
|
36
|
-
- **署名ガード**: 電子署名済み PDF(`/ByteRange` 検知)の編集は既定でエラーにし、
|
|
37
|
-
署名の意図しない無効化を防止(`allowBreakingSignatures: true` で明示的に続行可能)
|
|
38
|
-
- **日本語対応**: `.ttf` / `.otf` フォントを harfbuzz でサブセット埋め込み(4.5MB のフォントでも出力は数十 KB)
|
|
39
|
-
- **抽出・検索・コピー可能**: 埋め込みフォントでも ToUnicode CMap が付与されるため、
|
|
40
|
-
生成した PDF のテキストは選択・コピー・全文検索・スクリーンリーダ読み上げが可能
|
|
41
|
-
- **自動レイアウト**: テキスト折り返し(日英混在・長語の強制分割)、改ページ、表の改ページ時ヘッダ再描画
|
|
42
|
-
- **出力先の柔軟性**: ファイル保存 / base64 返却の両対応
|
|
43
|
-
- **堅牢な入力検査**: `asserts` によるバリデーションで不正値を早期に弾く
|
|
9
|
+
MCP server that **creates** PDFs from text, Markdown, or tabular data and **edits** existing ones (metadata and page operations). Built on [pdf-lib](https://pdf-lib.js.org/), with CJK font embedding via harfbuzz subsetting.
|
|
44
10
|
|
|
45
|
-
|
|
11
|
+
Part of the PDF family alongside [pdf-reader-mcp](https://github.com/shuji-bonji/pdf-reader-mcp) (structure analysis) and [pdf-verify-mcp](https://github.com/shuji-bonji/pdf-verify-mcp) (authenticity verification). Where `pdf-reader-mcp` tells you *what is in* a PDF and `pdf-verify-mcp` tells you *whether it is genuine*, `pdf-writer-mcp` is the one that *writes it*.
|
|
46
12
|
|
|
47
|
-
|
|
13
|
+
## Tools
|
|
48
14
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"PDF_WRITER_FONT": "/absolute/path/to/NotoSansJP-Regular.otf"
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
```
|
|
15
|
+
### Creation
|
|
16
|
+
|
|
17
|
+
| Tool | Purpose |
|
|
18
|
+
|------|---------|
|
|
19
|
+
| `create_text_pdf` | Plain text — honours `\n`, blank lines separate paragraphs, long lines wrap |
|
|
20
|
+
| `create_markdown_pdf` | Markdown — headings, paragraphs, bullet/ordered lists, code blocks, quotes, rules, tables |
|
|
21
|
+
| `create_table_pdf` | Ruled tables — automatic column widths, cell wrapping, headers repeated across page breaks |
|
|
62
22
|
|
|
63
|
-
|
|
23
|
+
Shared options: `outputPath`, `returnBase64`, `fontPath`, `fontSize`, `pageSize` (A4/A3/A5/LETTER/LEGAL), `margin`, `title`, `author`, `onMissingGlyph`.
|
|
24
|
+
|
|
25
|
+
### Editing
|
|
26
|
+
|
|
27
|
+
| Tool | Purpose |
|
|
28
|
+
|------|---------|
|
|
29
|
+
| `set_metadata` | Update Info dictionary fields (`title` / `author` / `subject` / `keywords` / `creator`), preserving the rest |
|
|
30
|
+
| `merge_pdfs` | Concatenate 2–50 PDFs in order; metadata inherited from the first file |
|
|
31
|
+
| `split_pdf` | One output file per page range |
|
|
32
|
+
| `extract_pages` | Extract pages in the requested order (doubles as reordering) |
|
|
33
|
+
| `delete_pages` | Remove pages (deleting every page is rejected) |
|
|
34
|
+
| `reorder_pages` | Reorder by an explicit permutation of all pages |
|
|
35
|
+
| `rotate_pages` | Rotate clockwise (90/180/270), accumulating over existing rotation |
|
|
36
|
+
| `add_bookmarks` | Set the outline (bookmarks); nestable via `children`, replaces any existing outline |
|
|
37
|
+
| `add_annotation` | Add a sticky note (`text`), `highlight`, or `square` annotation to a page |
|
|
38
|
+
|
|
39
|
+
Shared options: `outputPath`, `returnBase64`, `allowBreakingSignatures`.
|
|
40
|
+
|
|
41
|
+
Page specs use `"1,3-5,8-"` (1-based; `-3` means up to page 3, `8-` means page 8 to the end). Order is preserved and duplicates are removed.
|
|
42
|
+
|
|
43
|
+
> **Signatures**: pdf-lib rewrites the whole file on save, so editing always invalidates existing signatures. PDFs containing `/ByteRange` are rejected by default; pass `allowBreakingSignatures: true` to proceed anyway. Signature-preserving incremental updates are on the roadmap.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
64
46
|
|
|
65
47
|
```json
|
|
66
48
|
{
|
|
67
49
|
"mcpServers": {
|
|
68
50
|
"pdf-writer": {
|
|
69
|
-
"command": "
|
|
70
|
-
"args": ["/
|
|
51
|
+
"command": "npx",
|
|
52
|
+
"args": ["-y", "@shuji-bonji/pdf-writer-mcp"],
|
|
71
53
|
"env": {
|
|
72
54
|
"PDF_WRITER_FONT": "/absolute/path/to/NotoSansJP-Regular.otf"
|
|
73
55
|
}
|
|
@@ -76,147 +58,84 @@ graph LR
|
|
|
76
58
|
}
|
|
77
59
|
```
|
|
78
60
|
|
|
79
|
-
`PDF_WRITER_FONT`
|
|
80
|
-
|
|
81
|
-
## 開発
|
|
61
|
+
`PDF_WRITER_FONT` lets every tool omit `fontPath` and still render CJK text.
|
|
82
62
|
|
|
83
|
-
|
|
84
|
-
npm install
|
|
85
|
-
npm run build # dist/ に出力
|
|
86
|
-
npm test # vitest
|
|
87
|
-
npm run typecheck # tsc --noEmit
|
|
88
|
-
```
|
|
63
|
+
## Fonts
|
|
89
64
|
|
|
90
|
-
|
|
65
|
+
The standard PDF font (Helvetica) covers **ASCII only**. To render Japanese or any non-Latin text, point `fontPath` or `PDF_WRITER_FONT` at an embeddable **single-face** font (`.ttf` / `.otf`).
|
|
91
66
|
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
- **`.ttc`(TrueTypeCollection)は非対応**です(pdf-lib がサブセット化できないため、検知してエラーにします)。
|
|
95
|
-
`.ttc` しか手元にない場合は、単一フェイスを抽出してください。
|
|
67
|
+
- Recommended source: [Noto Sans JP (SubsetOTF/JP)](https://github.com/notofonts/noto-cjk/tree/main/Sans/SubsetOTF/JP) — static, single-face, SIL OFL.
|
|
68
|
+
- **`.ttc` (TrueType Collection) is not supported** — the file is detected and rejected. Extract a single face first:
|
|
96
69
|
|
|
97
70
|
```bash
|
|
98
|
-
# 例: Noto Sans CJK の .ttc から日本語フェイス(index 0)を .otf として取り出す
|
|
99
71
|
python3 -c "from fontTools.ttLib import TTCollection; \
|
|
100
72
|
TTCollection('NotoSansCJK-Regular.ttc').fonts[0].save('NotoSansCJKjp-Regular.otf')"
|
|
101
73
|
```
|
|
102
74
|
|
|
103
|
-
|
|
104
|
-
[notofonts/noto-cjk の日本語サブセット OTF](https://github.com/notofonts/noto-cjk/tree/main/Sans/SubsetOTF/JP)(SIL OFL、静的・単一フェイス)。
|
|
75
|
+
### Missing glyphs
|
|
105
76
|
|
|
106
|
-
|
|
77
|
+
Characters absent from the font (e.g. ✔ U+2714, which Noto Sans JP does not include) would otherwise be embedded as `.notdef` and render as silent blanks. `onMissingGlyph` controls this:
|
|
107
78
|
|
|
108
|
-
|
|
109
|
-
|
|
79
|
+
| Value | Behaviour |
|
|
80
|
+
|-------|-----------|
|
|
81
|
+
| `error` (default) | Fail, listing the offending characters as `"✔" (U+2714)` |
|
|
82
|
+
| `replace` | Substitute 〓 and report via `warnings` |
|
|
83
|
+
| `ignore` | Render as blanks and report via `warnings` |
|
|
110
84
|
|
|
111
|
-
|
|
112
|
-
|----|------|
|
|
113
|
-
| `error`(既定) | 欠落文字を `"✔" (U+2714)` 形式で列挙してエラー。無警告の空白出力を防ぐ |
|
|
114
|
-
| `replace` | 〓(下駄記号)に置換して生成し、`warnings` で報告 |
|
|
115
|
-
| `ignore` | そのまま生成(該当文字は空白になる)し、`warnings` で報告 |
|
|
116
|
-
|
|
117
|
-
## ツール
|
|
118
|
-
|
|
119
|
-
### `create_text_pdf`
|
|
120
|
-
|
|
121
|
-
プレーンテキスト → PDF。`\n` で改行、空行で段落区切り。長い行は自動折り返し。
|
|
122
|
-
|
|
123
|
-
| 引数 | 型 | 必須 | 説明 |
|
|
124
|
-
|------|----|:---:|------|
|
|
125
|
-
| `text` | string | ✓ | 本文 |
|
|
126
|
-
| `outputPath` | string | | 保存先。省略時は base64 を返す |
|
|
127
|
-
| `returnBase64` | boolean | | 保存に加えて base64 も返す |
|
|
128
|
-
| `fontPath` | string | | 埋め込むフォント(日本語は必須) |
|
|
129
|
-
| `fontSize` | number | | 本文サイズ pt(既定 11、4〜96) |
|
|
130
|
-
| `pageSize` | enum | | A4/A3/A5/LETTER/LEGAL(既定 A4) |
|
|
131
|
-
| `margin` | number | | 余白 pt(既定 56、0〜300) |
|
|
132
|
-
| `title` | string | | タイトル(メタデータ+冒頭見出し) |
|
|
133
|
-
| `author` | string | | 作成者(メタデータ) |
|
|
134
|
-
| `onMissingGlyph` | enum | | フォント未収録文字の扱い: error(既定)/ replace / ignore |
|
|
135
|
-
|
|
136
|
-
### `create_markdown_pdf`
|
|
137
|
-
|
|
138
|
-
Markdown → PDF。対応要素: 見出し / 段落 / 箇条書き・番号リスト / コードブロック / 引用 / 水平線 / 表。
|
|
139
|
-
インライン装飾(`**bold**` など)は単一フォントのため **記号を除去して字面のみ** 反映します。
|
|
140
|
-
|
|
141
|
-
引数は `text` の代わりに `markdown`(string, 必須)。その他は共通。
|
|
142
|
-
|
|
143
|
-
### `create_table_pdf`
|
|
144
|
-
|
|
145
|
-
ヘッダ + 行データ → 罫線付きの表 PDF。列幅は内容から自動算出、セル内は折り返し、改ページ時はヘッダを再描画。
|
|
146
|
-
|
|
147
|
-
| 引数 | 型 | 必須 | 説明 |
|
|
148
|
-
|------|----|:---:|------|
|
|
149
|
-
| `headers` | string[] | ✓ | 列見出し |
|
|
150
|
-
| `rows` | string[][] | ✓ | データ行(各行は headers と同数の列を推奨) |
|
|
151
|
-
|
|
152
|
-
その他は共通引数。
|
|
153
|
-
|
|
154
|
-
## 編集ツール(v0.2.0〜)
|
|
155
|
-
|
|
156
|
-
既存 PDF に対する操作です。共通引数: `outputPath`(省略時は base64 返却)/ `returnBase64` /
|
|
157
|
-
`allowBreakingSignatures`(署名済み PDF の編集続行フラグ、既定 false)。
|
|
158
|
-
|
|
159
|
-
ページ指定は `"1,3-5,8-"` 形式(1 始まり。`-3` = 先頭から 3 まで、`8-` = 8 から最終まで)。
|
|
160
|
-
|
|
161
|
-
| ツール | 主な引数 | 説明 |
|
|
162
|
-
|--------|----------|------|
|
|
163
|
-
| `set_metadata` | `inputPath`, `title` / `author` / `subject` / `keywords` / `creator` | 指定フィールドのみ更新、他は保持 |
|
|
164
|
-
| `merge_pdfs` | `inputPaths: string[]` | 指定順に結合(2〜50 ファイル) |
|
|
165
|
-
| `split_pdf` | `inputPath`, `ranges: string[]`, `outputDir`, `prefix?` | 範囲ごとに連番ファイルへ分割 |
|
|
166
|
-
| `extract_pages` | `inputPath`, `pages` | 指定順を保持して抽出(並べ替えを兼ねる) |
|
|
167
|
-
| `delete_pages` | `inputPath`, `pages` | ページ削除(全削除はエラー) |
|
|
168
|
-
| `reorder_pages` | `inputPath`, `order: number[]` | 全ページの順列で並べ替え |
|
|
169
|
-
| `rotate_pages` | `inputPath`, `rotation: 90\|180\|270`, `pages?` | 時計回りに回転(既存回転に加算) |
|
|
170
|
-
|
|
171
|
-
> **署名について**: pdf-lib はファイル全体を再構築して保存するため、編集すると既存の電子署名は
|
|
172
|
-
> 必ず無効化されます。署名(`/ByteRange`)を検知した場合は既定でエラーとし、
|
|
173
|
-
> `allowBreakingSignatures: true` を指定したときのみ続行します。
|
|
174
|
-
> 署名を保持する増分更新は将来対応(ロードマップ参照)。
|
|
175
|
-
|
|
176
|
-
### 返り値(共通)
|
|
85
|
+
## Result
|
|
177
86
|
|
|
178
87
|
```jsonc
|
|
179
88
|
{
|
|
180
|
-
"path": "/abs/out.pdf",
|
|
181
|
-
"base64": "JVBERi0xLj...",
|
|
89
|
+
"path": "/abs/out.pdf", // when outputPath is given
|
|
90
|
+
"base64": "JVBERi0xLj...", // when returnBase64, or outputPath is omitted
|
|
182
91
|
"pageCount": 3,
|
|
183
92
|
"bytes": 91788,
|
|
184
|
-
"font": "NotoSansJP-Regular.otf"
|
|
93
|
+
"font": "NotoSansJP-Regular.otf",
|
|
94
|
+
"warnings": ["Replaced 1 unsupported character(s) with \"〓\": \"✔\" (U+2714)"]
|
|
185
95
|
}
|
|
186
96
|
```
|
|
187
97
|
|
|
188
|
-
|
|
98
|
+
Editing tools return the same shape without `font`; `split_pdf` returns `{ files: [...], count }`.
|
|
99
|
+
|
|
100
|
+
## Text extraction
|
|
101
|
+
|
|
102
|
+
Generated PDFs are selectable, copyable, searchable, and screen-reader accessible: pdf-lib emits a ToUnicode CMap even for embedded subset fonts. This is covered by regression tests (`extract.test.ts`, `render.test.ts`).
|
|
103
|
+
|
|
104
|
+
> Some poppler-based viewers print `Mismatch between font type and embedded font file` for OTF/CFF fonts embedded as CIDFontType0. This is harmless — rendering and extraction are both correct.
|
|
105
|
+
|
|
106
|
+
## Development
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm install
|
|
110
|
+
npm run build # emits dist/
|
|
111
|
+
npm test # vitest
|
|
112
|
+
npm run typecheck # tsc --noEmit
|
|
113
|
+
```
|
|
189
114
|
|
|
190
|
-
|
|
191
|
-
埋め込みフォント使用時も pdf-lib が ToUnicode CMap(CID→Unicode の逆引き)を出力するため、
|
|
192
|
-
`pdftotext` 等で本文を抽出できます。この性質は `tests/extract.test.ts` の回帰テストで担保しています
|
|
193
|
-
(ToUnicode に `日 → U+65E5` のマッピングが含まれることを検証)。
|
|
115
|
+
Font-dependent tests activate when `TEST_FONT_PATH` points at a CJK font:
|
|
194
116
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
> 切り替え、サイズはより小さく(実測 24KB → 14.5KB)、描画は正常になっています。
|
|
117
|
+
```bash
|
|
118
|
+
TEST_FONT_PATH=/path/to/NotoSansJP-Regular.otf npm test
|
|
119
|
+
```
|
|
199
120
|
|
|
200
|
-
##
|
|
121
|
+
## Known limitations
|
|
201
122
|
|
|
202
|
-
-
|
|
203
|
-
|
|
204
|
-
-
|
|
205
|
-
- **サブセット名の接頭辞**: pdf-lib は慣習的な `ABCDEF+` 接頭辞を付けないため、
|
|
206
|
-
一部ツールがサブセットでないと誤認します(表示・抽出には無影響。PDF/A 厳密対応時の項目)。
|
|
123
|
+
- **Inline styling**: bold/italic affect size and glyph text only, not typeface — a single font is embedded per document.
|
|
124
|
+
- **`.ttc` fonts** require extracting a single face (see above).
|
|
125
|
+
- **Subset name prefix**: the conventional `ABCDEF+` prefix is not applied, so some tools report the font as non-subset. No effect on rendering or extraction; relevant only for strict PDF/A work.
|
|
207
126
|
|
|
208
|
-
##
|
|
127
|
+
## Roadmap
|
|
209
128
|
|
|
210
|
-
- [x]
|
|
211
|
-
- [
|
|
212
|
-
- [ ]
|
|
213
|
-
- [ ]
|
|
214
|
-
- [ ] `.ttc`
|
|
215
|
-
- [ ]
|
|
216
|
-
- [ ]
|
|
217
|
-
- [ ]
|
|
218
|
-
- [ ] PDF/A
|
|
129
|
+
- [x] Editing Tier A wave 1 — metadata and page operations (v0.2.0)
|
|
130
|
+
- [x] Editing Tier A wave 2 — bookmarks and annotations (v0.4.0)
|
|
131
|
+
- [ ] Editing Tier B — form filling/flattening, watermarks, attachments, page-number stamping
|
|
132
|
+
- [ ] Tagged PDF / PDF/UA (structure tags for screen readers)
|
|
133
|
+
- [ ] Automatic face extraction from `.ttc`
|
|
134
|
+
- [ ] Separate faces for headings and body (bold face embedding)
|
|
135
|
+
- [ ] Image embedding, headers/footers
|
|
136
|
+
- [ ] Tier C — signature-preserving incremental updates, body text editing, tag tree maintenance
|
|
137
|
+
- [ ] PDF/A conversion
|
|
219
138
|
|
|
220
|
-
##
|
|
139
|
+
## License
|
|
221
140
|
|
|
222
141
|
MIT © shuji-bonji
|
package/dist/constants.d.ts
CHANGED
|
@@ -33,7 +33,14 @@ export declare const LIMITS: {
|
|
|
33
33
|
readonly MERGE_MAX_INPUTS: 50;
|
|
34
34
|
/** split の最大分割数。暴走防止 */
|
|
35
35
|
readonly SPLIT_MAX_PARTS: 200;
|
|
36
|
+
/** しおりの最大総数・最大ネスト深さ */
|
|
37
|
+
readonly BOOKMARK_MAX_TOTAL: 2000;
|
|
38
|
+
readonly BOOKMARK_MAX_DEPTH: 8;
|
|
36
39
|
};
|
|
40
|
+
/** add_annotation が受け付ける注釈種別 */
|
|
41
|
+
export declare const ANNOTATION_TYPES: readonly ['text', 'highlight', 'square'];
|
|
42
|
+
/** text 注釈のアイコン名(ISO 32000-1 Table 172 の一般的な値) */
|
|
43
|
+
export declare const ANNOTATION_ICONS: readonly ['Note', 'Comment', 'Key', 'Help', 'NewParagraph', 'Paragraph', 'Insert'];
|
|
37
44
|
/** rotate_pages が受け付ける回転角(時計回り・度) */
|
|
38
45
|
export declare const ROTATION_ANGLES: readonly [90, 180, 270];
|
|
39
46
|
/**
|
package/dist/constants.js
CHANGED
|
@@ -32,7 +32,22 @@ export const LIMITS = {
|
|
|
32
32
|
MERGE_MAX_INPUTS: 50,
|
|
33
33
|
/** split の最大分割数。暴走防止 */
|
|
34
34
|
SPLIT_MAX_PARTS: 200,
|
|
35
|
+
/** しおりの最大総数・最大ネスト深さ */
|
|
36
|
+
BOOKMARK_MAX_TOTAL: 2_000,
|
|
37
|
+
BOOKMARK_MAX_DEPTH: 8,
|
|
35
38
|
};
|
|
39
|
+
/** add_annotation が受け付ける注釈種別 */
|
|
40
|
+
export const ANNOTATION_TYPES = ['text', 'highlight', 'square'];
|
|
41
|
+
/** text 注釈のアイコン名(ISO 32000-1 Table 172 の一般的な値) */
|
|
42
|
+
export const ANNOTATION_ICONS = [
|
|
43
|
+
'Note',
|
|
44
|
+
'Comment',
|
|
45
|
+
'Key',
|
|
46
|
+
'Help',
|
|
47
|
+
'NewParagraph',
|
|
48
|
+
'Paragraph',
|
|
49
|
+
'Insert',
|
|
50
|
+
];
|
|
36
51
|
/** rotate_pages が受け付ける回転角(時計回り・度) */
|
|
37
52
|
export const ROTATION_ANGLES = [90, 180, 270];
|
|
38
53
|
/**
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;IACrB,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC;CACV,CAAC;AAIX;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,qBAAqB;IACrB,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,EAAE;IACjB,sCAAsC;IACtC,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,GAAG;IACf,6CAA6C;IAC7C,eAAe,EAAE,OAAO;IACxB,+BAA+B;IAC/B,cAAc,EAAE,EAAE;IAClB,cAAc,EAAE,KAAK;IACrB,4BAA4B;IAC5B,gBAAgB,EAAE,EAAE;IACpB,wBAAwB;IACxB,eAAe,EAAE,GAAG;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;IACrB,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC;CACV,CAAC;AAIX;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,qBAAqB;IACrB,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,EAAE;IACjB,sCAAsC;IACtC,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,GAAG;IACf,6CAA6C;IAC7C,eAAe,EAAE,OAAO;IACxB,+BAA+B;IAC/B,cAAc,EAAE,EAAE;IAClB,cAAc,EAAE,KAAK;IACrB,4BAA4B;IAC5B,gBAAgB,EAAE,EAAE;IACpB,wBAAwB;IACxB,eAAe,EAAE,GAAG;IACpB,uBAAuB;IACvB,kBAAkB,EAAE,KAAK;IACzB,kBAAkB,EAAE,CAAC;CACb,CAAC;AAEX,gCAAgC;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAU,CAAC;AAEzE,kDAAkD;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,MAAM;IACN,SAAS;IACT,KAAK;IACL,MAAM;IACN,cAAc;IACd,WAAW;IACX,QAAQ;CACA,CAAC;AAEX,qCAAqC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAEvD;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,mCAAmC;IACnC,GAAG,EAAE,MAAM;CACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Annotation
|
|
3
|
+
* pdf-lib の低レベル API で注釈辞書を組み立て、ページの /Annots に追加する。
|
|
4
|
+
*
|
|
5
|
+
* 対応(ISO 32000-1 §12.5.6):
|
|
6
|
+
* - text : 付箋(Text annotation)。/Rect の左上にアイコン表示
|
|
7
|
+
* - highlight : ハイライト(Highlight)。/QuadPoints が必須
|
|
8
|
+
* - square : 矩形(Square)
|
|
9
|
+
*
|
|
10
|
+
* 座標系は PDF 準拠(左下原点・pt)。生成系レンダラの top 基準とは異なる点に注意。
|
|
11
|
+
*/
|
|
12
|
+
import { PDFDocument, type RGB } from 'pdf-lib';
|
|
13
|
+
import type { AddAnnotationArgs } from '../types/index.js';
|
|
14
|
+
/** #rrggbb / #rgb を pdf-lib の RGB へ */
|
|
15
|
+
export declare function parseHexColor(hex: string): RGB;
|
|
16
|
+
/** 注釈をページに追加する。@returns 追加後のそのページの注釈数 */
|
|
17
|
+
export declare function addAnnotation(doc: PDFDocument, args: AddAnnotationArgs): number;
|