@shuji-bonji/pdf-writer-mcp 0.9.1 → 0.9.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/CHANGELOG.md +49 -0
- package/dist/services/annotation.js +53 -2
- package/dist/services/annotation.js.map +1 -1
- package/dist/services/attachment.js +36 -2
- package/dist/services/attachment.js.map +1 -1
- package/dist/services/outline.js +22 -7
- package/dist/services/outline.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.9.2] - 2026-07-17
|
|
6
|
+
|
|
7
|
+
SPEC-AUDIT Phase 1: the editing tools were audited clause-by-clause against
|
|
8
|
+
ISO 32000-2 with pdf-spec-mcp (see `docs/SPEC-AUDIT.md` for the full table).
|
|
9
|
+
Three shall-violations and two determinism leaks were found and fixed.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Annotations now carry appearance streams (`/AP /N`)** — ISO 32000-2
|
|
14
|
+
Table 166 obliges the *writer* to include an appearance dictionary (the
|
|
15
|
+
only exceptions are degenerate rects and Popup/Projection/Link). This was
|
|
16
|
+
optional in ISO 32000-1, which is why veraPDF (PDF/UA-1 is 32000-1-based)
|
|
17
|
+
never flagged it. `add_annotation` now generates Form XObjects: a note
|
|
18
|
+
icon for `text`, a Multiply-blended bar for `highlight` (so underlying
|
|
19
|
+
text shows through), and a stroked/filled rectangle for `square`.
|
|
20
|
+
Practical win: poppler-based viewers previously rendered nothing for
|
|
21
|
+
these annotations. Verified: veraPDF ua1 still COMPLIANT (106/106) on
|
|
22
|
+
tagged documents; rendering visually confirmed via pdftoppm.
|
|
23
|
+
- **Outline `/Count` semantics (§12.3.3)** — item counts now follow the
|
|
24
|
+
spec's recursive *visible descendants* procedure (children inside a
|
|
25
|
+
collapsed branch are not counted; previously the total descendant count
|
|
26
|
+
was used), and the root `/Count` is omitted when the outline has no open
|
|
27
|
+
entries (it is written only when required, and never negative).
|
|
28
|
+
- **Embedded-files name tree is sorted (§7.9.6)** — name tree keys shall be
|
|
29
|
+
lexically ordered, but pdf-lib's `attach()` appends in insertion order
|
|
30
|
+
(and materialises the tree lazily, so sorting requires `flush()` first).
|
|
31
|
+
Attaching a second file used to produce an out-of-order tree.
|
|
32
|
+
|
|
33
|
+
- **Determinism leaks (E-6)** — the annotation `/M` date and attachment
|
|
34
|
+
creation/modification dates bypassed `SOURCE_DATE_EPOCH` via bare
|
|
35
|
+
`new Date()`. Both now go through `outputDate()`; pinned by a
|
|
36
|
+
byte-identity regression test covering annotate + attach.
|
|
37
|
+
|
|
38
|
+
### Audit notes
|
|
39
|
+
|
|
40
|
+
- Confirmed conforming: annotation common entries (Table 166), text icon
|
|
41
|
+
names (Table 177), outline linking (§12.3.3), embedded-file structure
|
|
42
|
+
(§7.11.3–4, §14.13), form filling (§12.7, appearances self-generated so
|
|
43
|
+
the Widget AP obligation is met, no `NeedAppearances`), page rotation
|
|
44
|
+
(Table 31, normalised multiples of 90).
|
|
45
|
+
- QuadPoints order: implementation keeps the industry-standard Z-order
|
|
46
|
+
(TL, TR, BL, BR). The ISO prose says "counterclockwise", a well-known
|
|
47
|
+
spec/reality divergence — every major viewer requires Z-order.
|
|
48
|
+
- New gap tracked as **B-9**: `set_metadata` updates the Info dictionary
|
|
49
|
+
only; on documents that carry XMP (e.g. tagged output) this can leave
|
|
50
|
+
`dc:title` etc. inconsistent (§14.3.3 deprecates Info in PDF 2.0).
|
|
51
|
+
- Tooling feedback: pdf-spec-mcp drops table rows that cross a page break
|
|
52
|
+
(Table 182's QuadPoints row) — recorded in pdf-spec's alignment doc.
|
|
53
|
+
|
|
5
54
|
## [0.9.1] - 2026-07-17
|
|
6
55
|
|
|
7
56
|
Clause-by-clause audit of the v0.9.0 incremental writer against ISO 32000-2,
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 座標系は PDF 準拠(左下原点・pt)。生成系レンダラの top 基準とは異なる点に注意。
|
|
11
11
|
*/
|
|
12
|
-
import { PDFArray, PDFHexString, PDFName, PDFNumber, PDFString, rgb, } from 'pdf-lib';
|
|
12
|
+
import { fill, fillAndStroke, lineTo, moveTo, PDFArray, PDFHexString, PDFName, PDFNumber, PDFString, rectangle, rgb, setFillingRgbColor, setGraphicsState, setLineWidth, setStrokingRgbColor, stroke, } from 'pdf-lib';
|
|
13
|
+
import { outputDate } from '../config.js';
|
|
13
14
|
/** #rrggbb / #rgb を pdf-lib の RGB へ */
|
|
14
15
|
export function parseHexColor(hex) {
|
|
15
16
|
const m = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
@@ -44,7 +45,8 @@ export function addAnnotation(doc, args) {
|
|
|
44
45
|
dict.set(PDFName.of('Contents'), PDFHexString.fromText(args.contents ?? ''));
|
|
45
46
|
if (args.author)
|
|
46
47
|
dict.set(PDFName.of('T'), PDFHexString.fromText(args.author));
|
|
47
|
-
|
|
48
|
+
// SOURCE_DATE_EPOCH(E-6)に従う。書式は §7.9.4 の日付文字列
|
|
49
|
+
dict.set(PDFName.of('M'), PDFString.fromDate(outputDate()));
|
|
48
50
|
// /F: bit3 Print(印刷に含める)
|
|
49
51
|
dict.set(PDFName.of('F'), PDFNumber.of(4));
|
|
50
52
|
const color = parseHexColor(args.color ?? defaultColor(args.type));
|
|
@@ -69,6 +71,14 @@ export function addAnnotation(doc, args) {
|
|
|
69
71
|
}
|
|
70
72
|
break;
|
|
71
73
|
}
|
|
74
|
+
// ISO 32000-2 Table 166: 「PDF writer は書き込み時に外観辞書を含めなければならない」
|
|
75
|
+
// (shall。例外は退化 Rect と Popup/Projection/Link のみ — 本ツールの 3 種は全て対象)。
|
|
76
|
+
// 32000-1 では Optional だったため v0.9.1 まで欠けていた(SPEC-AUDIT Phase 1 で発見)。
|
|
77
|
+
const w = r.x2 - r.x1;
|
|
78
|
+
const h = r.y2 - r.y1;
|
|
79
|
+
const ap = context.obj({});
|
|
80
|
+
ap.set(PDFName.of('N'), buildAppearance(doc, args, color, w, h));
|
|
81
|
+
dict.set(PDFName.of('AP'), ap);
|
|
72
82
|
let annots = page.node.lookup(PDFName.of('Annots'));
|
|
73
83
|
if (!(annots instanceof PDFArray)) {
|
|
74
84
|
annots = context.obj([]);
|
|
@@ -78,6 +88,47 @@ export function addAnnotation(doc, args) {
|
|
|
78
88
|
annots.push(ref);
|
|
79
89
|
return { count: annots.size(), ref, page };
|
|
80
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* 通常外観(/AP /N)の Form XObject を組み立てて登録する。
|
|
93
|
+
* BBox は [0 0 w h] で、ビューアが /Rect へ写像する。
|
|
94
|
+
*/
|
|
95
|
+
function buildAppearance(doc, args, color, w, h) {
|
|
96
|
+
const { context } = doc;
|
|
97
|
+
const ops = [];
|
|
98
|
+
const extras = {};
|
|
99
|
+
switch (args.type) {
|
|
100
|
+
case 'highlight': {
|
|
101
|
+
// Multiply ブレンドで下のテキストが透ける、いわゆる蛍光ペン
|
|
102
|
+
extras.Resources = context.obj({
|
|
103
|
+
ExtGState: { GS0: { Type: 'ExtGState', BM: 'Multiply' } },
|
|
104
|
+
});
|
|
105
|
+
ops.push(setGraphicsState('GS0'), setFillingRgbColor(color.red, color.green, color.blue), rectangle(0, 0, w, h), fill());
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case 'square': {
|
|
109
|
+
const lw = 1.5;
|
|
110
|
+
ops.push(setLineWidth(lw), setStrokingRgbColor(color.red, color.green, color.blue));
|
|
111
|
+
if (args.interiorColor) {
|
|
112
|
+
const ic = parseHexColor(args.interiorColor);
|
|
113
|
+
ops.push(setFillingRgbColor(ic.red, ic.green, ic.blue), rectangle(lw / 2, lw / 2, w - lw, h - lw), fillAndStroke());
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
ops.push(rectangle(lw / 2, lw / 2, w - lw, h - lw), stroke());
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
default: {
|
|
121
|
+
// text: 付箋アイコン(地色の紙面 + 枠 + 罫線 3 本の簡易ノート)
|
|
122
|
+
ops.push(setFillingRgbColor(color.red, color.green, color.blue), rectangle(0, 0, w, h), fill(), setLineWidth(Math.max(0.75, h * 0.04)), setStrokingRgbColor(0.25, 0.25, 0.25), rectangle(0.5, 0.5, w - 1, h - 1), stroke());
|
|
123
|
+
for (const frac of [0.3, 0.5, 0.7]) {
|
|
124
|
+
ops.push(moveTo(w * 0.2, h * frac), lineTo(w * 0.8, h * frac), stroke());
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const xobj = context.formXObject(ops, { BBox: context.obj([0, 0, w, h]), ...extras });
|
|
130
|
+
return context.register(xobj);
|
|
131
|
+
}
|
|
81
132
|
function defaultColor(type) {
|
|
82
133
|
switch (type) {
|
|
83
134
|
case 'highlight':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotation.js","sourceRoot":"","sources":["../../src/services/annotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,QAAQ,EAGR,YAAY,EACZ,OAAO,EACP,SAAS,
|
|
1
|
+
{"version":3,"file":"annotation.js","sourceRoot":"","sources":["../../src/services/annotation.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { readFile } from 'node:fs/promises';
|
|
20
20
|
import { basename, extname, resolve } from 'node:path';
|
|
21
|
-
import { AFRelationship, PDFArray, PDFDict, PDFName } from 'pdf-lib';
|
|
21
|
+
import { AFRelationship, PDFArray, PDFDict, PDFName, } from 'pdf-lib';
|
|
22
|
+
import { outputDate } from '../config.js';
|
|
22
23
|
import { LIMITS } from '../constants.js';
|
|
23
24
|
/** 拡張子 → MIME 型(電帳法・請求まわりで実際に使うものに絞る) */
|
|
24
25
|
const MIME_TYPES = {
|
|
@@ -133,13 +134,46 @@ export async function attachFile(doc, options) {
|
|
|
133
134
|
}
|
|
134
135
|
const mimeType = options.mimeType ?? guessMimeType(name);
|
|
135
136
|
const relationship = options.relationship ?? 'Unspecified';
|
|
136
|
-
|
|
137
|
+
// SOURCE_DATE_EPOCH(E-6)に従う(v0.9.1 まで new Date() 直書きで決定論性が漏れていた)
|
|
138
|
+
const stat = { creationDate: outputDate(), modificationDate: outputDate() };
|
|
137
139
|
await doc.attach(bytes, name, {
|
|
138
140
|
mimeType,
|
|
139
141
|
description: options.description,
|
|
140
142
|
afRelationship: toAFRelationship(relationship),
|
|
141
143
|
...stat,
|
|
142
144
|
});
|
|
145
|
+
// §7.9.6: 名前ツリーのキーは辞書順でなければならない(shall)。
|
|
146
|
+
// pdf-lib の attach は「保存時まで実体化しない遅延埋め込み」かつ挿入順で追記するため、
|
|
147
|
+
// flush() で名前ツリーを実体化してから並べ直す(SPEC-AUDIT Phase 1 で実測・是正)
|
|
148
|
+
await doc.flush();
|
|
149
|
+
sortEmbeddedFileNames(doc);
|
|
143
150
|
return { name, bytes: bytes.length, mimeType, relationship };
|
|
144
151
|
}
|
|
152
|
+
/** /Names /EmbeddedFiles の名前ツリー(平坦な /Names 配列)をキーの辞書順に並べ直す */
|
|
153
|
+
function sortEmbeddedFileNames(doc) {
|
|
154
|
+
const names = doc.catalog.lookup(PDFName.of('Names'));
|
|
155
|
+
if (!(names instanceof PDFDict))
|
|
156
|
+
return;
|
|
157
|
+
const ef = names.lookup(PDFName.of('EmbeddedFiles'));
|
|
158
|
+
if (!(ef instanceof PDFDict))
|
|
159
|
+
return;
|
|
160
|
+
const arr = ef.lookup(PDFName.of('Names'));
|
|
161
|
+
if (!(arr instanceof PDFArray))
|
|
162
|
+
return;
|
|
163
|
+
const pairs = [];
|
|
164
|
+
for (let i = 0; i + 1 < arr.size(); i += 2) {
|
|
165
|
+
pairs.push({
|
|
166
|
+
key: decodeName(arr.lookup(i)) ?? '',
|
|
167
|
+
k: arr.get(i),
|
|
168
|
+
v: arr.get(i + 1),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
pairs.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
|
|
172
|
+
while (arr.size() > 0)
|
|
173
|
+
arr.remove(arr.size() - 1);
|
|
174
|
+
for (const p of pairs) {
|
|
175
|
+
arr.push(p.k);
|
|
176
|
+
arr.push(p.v);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
145
179
|
//# sourceMappingURL=attachment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/services/attachment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,
|
|
1
|
+
{"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/services/attachment.ts"],"names":[],"mappings":"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"}
|
package/dist/services/outline.js
CHANGED
|
@@ -21,6 +21,8 @@ export function setBookmarks(doc, bookmarks) {
|
|
|
21
21
|
const rootRef = context.nextRef();
|
|
22
22
|
const rootDict = context.obj({ Type: 'Outlines' });
|
|
23
23
|
let total = 0;
|
|
24
|
+
/** 「開いた outline 項目」(子を持ち open な項目)が 1 つでもあるか */
|
|
25
|
+
let anyOpenEntry = false;
|
|
24
26
|
/** items を兄弟として構築し、親 parentRef に連結する */
|
|
25
27
|
const buildLevel = (items, parentRef, depth) => {
|
|
26
28
|
if (depth > LIMITS.BOOKMARK_MAX_DEPTH) {
|
|
@@ -47,14 +49,24 @@ export function setBookmarks(doc, bookmarks) {
|
|
|
47
49
|
dict.set(PDFName.of('Title'), PDFHexString.fromText(item.title));
|
|
48
50
|
dict.set(PDFName.of('Parent'), parentRef);
|
|
49
51
|
dict.set(PDFName.of('Dest'), dest);
|
|
50
|
-
const node = {
|
|
52
|
+
const node = {
|
|
53
|
+
ref,
|
|
54
|
+
dict,
|
|
55
|
+
visibleDescendants: 0,
|
|
56
|
+
open: item.open ?? true,
|
|
57
|
+
hasChildren: false,
|
|
58
|
+
};
|
|
51
59
|
if (item.children && item.children.length > 0) {
|
|
60
|
+
node.hasChildren = true;
|
|
61
|
+
if (node.open)
|
|
62
|
+
anyOpenEntry = true;
|
|
52
63
|
const children = buildLevel(item.children, ref, depth + 1);
|
|
53
|
-
|
|
64
|
+
// §12.3.3 の再帰手続き: 直下の子 + 「開いている」子の可視子孫のみ
|
|
65
|
+
node.visibleDescendants = children.reduce((sum, c) => sum + 1 + (c.open && c.hasChildren ? c.visibleDescendants : 0), 0);
|
|
54
66
|
dict.set(PDFName.of('First'), children[0].ref);
|
|
55
67
|
dict.set(PDFName.of('Last'), children[children.length - 1].ref);
|
|
56
|
-
// 開:
|
|
57
|
-
dict.set(PDFName.of('Count'), PDFNumber.of(node.open ? node.
|
|
68
|
+
// 開: 正の可視子孫数 / 閉: 負(絶対値 = 開いたときに可視になる数)
|
|
69
|
+
dict.set(PDFName.of('Count'), PDFNumber.of(node.open ? node.visibleDescendants : -node.visibleDescendants));
|
|
58
70
|
}
|
|
59
71
|
nodes.push(node);
|
|
60
72
|
}
|
|
@@ -73,9 +85,12 @@ export function setBookmarks(doc, bookmarks) {
|
|
|
73
85
|
rootDict.set(PDFName.of('First'), top[0].ref);
|
|
74
86
|
rootDict.set(PDFName.of('Last'), top[top.length - 1].ref);
|
|
75
87
|
}
|
|
76
|
-
// ルートの /Count
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
// ルートの /Count(Table 150): 全階層の可視項目の総数。負にできない。
|
|
89
|
+
// 「開いた項目が 1 つも無ければ省略しなければならない」(shall — SPEC-AUDIT Phase 1 で是正)
|
|
90
|
+
if (anyOpenEntry) {
|
|
91
|
+
const visible = top.reduce((sum, n) => sum + 1 + (n.open && n.hasChildren ? n.visibleDescendants : 0), 0);
|
|
92
|
+
rootDict.set(PDFName.of('Count'), PDFNumber.of(visible));
|
|
93
|
+
}
|
|
79
94
|
context.assign(rootRef, rootDict);
|
|
80
95
|
doc.catalog.set(PDFName.of('Outlines'), rootRef);
|
|
81
96
|
return total;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outline.js","sourceRoot":"","sources":["../../src/services/outline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAIL,YAAY,EACZ,OAAO,EACP,SAAS,GAEV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"outline.js","sourceRoot":"","sources":["../../src/services/outline.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shuji-bonji/pdf-writer-mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "MCP server that generates and edits PDFs (text/Markdown/table creation, metadata & page operations) using pdf-lib, with Japanese font embedding (fontkit subset).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|