layoutbridge-light 0.0.0-stage → 1.0.1

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.
Files changed (92) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/LICENSE +26 -0
  3. package/README.de.md +367 -0
  4. package/README.md +353 -2
  5. package/THIRD-PARTY-NOTICES.md +2878 -0
  6. package/dist/src/mcp/catalog.js +131 -0
  7. package/dist/src/mcp/config.js +211 -0
  8. package/dist/src/mcp/content-credentials.js +65 -0
  9. package/dist/src/mcp/dispatch.js +171 -0
  10. package/dist/src/mcp/epub-check.js +331 -0
  11. package/dist/src/mcp/epub-orientation.js +132 -0
  12. package/dist/src/mcp/license/free-tools.js +16 -0
  13. package/dist/src/mcp/license/gate.js +210 -0
  14. package/dist/src/mcp/license/index.js +107 -0
  15. package/dist/src/mcp/license/instance-name.js +57 -0
  16. package/dist/src/mcp/license/key-source.js +59 -0
  17. package/dist/src/mcp/license/lemonsqueezy-verifier.js +207 -0
  18. package/dist/src/mcp/license/placeholder-verifier.js +10 -0
  19. package/dist/src/mcp/license/polar-ids.js +100 -0
  20. package/dist/src/mcp/license/polar-verifier.js +285 -0
  21. package/dist/src/mcp/license/product-ids.js +73 -0
  22. package/dist/src/mcp/license/state-store.js +91 -0
  23. package/dist/src/mcp/license/types.js +11 -0
  24. package/dist/src/mcp/logging.js +271 -0
  25. package/dist/src/mcp/pdf-postprocess.js +798 -0
  26. package/dist/src/mcp/product-info.js +54 -0
  27. package/dist/src/mcp/product.js +56 -0
  28. package/dist/src/mcp/server.js +253 -0
  29. package/dist/src/mcp/setup.js +680 -0
  30. package/dist/src/mcp/start.cjs +117 -0
  31. package/dist/src/mcp/target-folder.js +25 -0
  32. package/dist/src/mcp/tool-definition.js +2 -0
  33. package/dist/src/mcp/tools.js +2680 -0
  34. package/dist/src/mcp/typography-rules.js +70 -0
  35. package/dist/src/transport/com.js +436 -0
  36. package/dist/src/transport/osascript.js +171 -0
  37. package/dist/src/transport/queue.js +19 -0
  38. package/dist/src/transport/script-bundle.js +92 -0
  39. package/dist/src/transport/transport.js +52 -0
  40. package/indesign/commands/10-app.js +6 -0
  41. package/indesign/commands/20-documents.js +517 -0
  42. package/indesign/commands/22-document-setup.js +204 -0
  43. package/indesign/commands/23-save-package.js +258 -0
  44. package/indesign/commands/25-export.js +695 -0
  45. package/indesign/commands/26-export-image.js +202 -0
  46. package/indesign/commands/27-textdefaults.js +151 -0
  47. package/indesign/commands/28-selection.js +174 -0
  48. package/indesign/commands/30-pages.js +1032 -0
  49. package/indesign/commands/31-view.js +310 -0
  50. package/indesign/commands/32-sections.js +203 -0
  51. package/indesign/commands/35-parents.js +448 -0
  52. package/indesign/commands/37-layout.js +837 -0
  53. package/indesign/commands/40-frames.js +886 -0
  54. package/indesign/commands/41-shapes.js +505 -0
  55. package/indesign/commands/42-groups.js +117 -0
  56. package/indesign/commands/43-layers.js +310 -0
  57. package/indesign/commands/44-effects.js +274 -0
  58. package/indesign/commands/45-frame-options.js +247 -0
  59. package/indesign/commands/47-anchored.js +473 -0
  60. package/indesign/commands/50-modify.js +803 -0
  61. package/indesign/commands/52-align.js +139 -0
  62. package/indesign/commands/55-fit.js +106 -0
  63. package/indesign/commands/60-images.js +1154 -0
  64. package/indesign/commands/62-embed.js +120 -0
  65. package/indesign/commands/69-placeholders.js +132 -0
  66. package/indesign/commands/70-text.js +710 -0
  67. package/indesign/commands/71-outlines.js +92 -0
  68. package/indesign/commands/72-place-text.js +476 -0
  69. package/indesign/commands/73-story-lock.js +157 -0
  70. package/indesign/commands/74-stories.js +121 -0
  71. package/indesign/commands/75-tables.js +702 -0
  72. package/indesign/commands/76-text-variables.js +260 -0
  73. package/indesign/commands/77-story-options.js +86 -0
  74. package/indesign/commands/78-frame-lines.js +511 -0
  75. package/indesign/commands/79-check-typography.js +480 -0
  76. package/indesign/commands/80-styles.js +1960 -0
  77. package/indesign/commands/81-composition.js +355 -0
  78. package/indesign/commands/82-object-styles.js +263 -0
  79. package/indesign/commands/83-drop-caps.js +87 -0
  80. package/indesign/commands/83-indents-tabs.js +264 -0
  81. package/indesign/commands/84-import-styles.js +142 -0
  82. package/indesign/commands/85-swatches.js +112 -0
  83. package/indesign/commands/86-gradients.js +185 -0
  84. package/indesign/commands/87-replace-swatch.js +180 -0
  85. package/indesign/commands/88-replace-font.js +212 -0
  86. package/indesign/commands/89-toc-index.js +1002 -0
  87. package/indesign/commands/90-print-on-demand.js +495 -0
  88. package/indesign/commands/91-epub.js +629 -0
  89. package/indesign/commands/92-accessibility.js +1131 -0
  90. package/indesign/interpreter.js +829 -0
  91. package/package.json +41 -4
  92. package/rules/typography-rules.json +32 -0
@@ -0,0 +1,204 @@
1
+ /* Wunschliste J2 Nr. 21 (Sitzung 8) – Dokumenteinrichtung nachtraeglich: set_document_setup. */
2
+
3
+ function idcDescribeSetup(doc) {
4
+ var prefs = doc.documentPreferences;
5
+ var out = { page_width_mm: null, page_height_mm: null, facing_pages: null, page_count: null, start_page_number: null, allow_page_shuffle: null };
6
+ try { out.page_width_mm = IDC.round(Number(prefs.pageWidth)); } catch (e0) { /* null */ }
7
+ try { out.page_height_mm = IDC.round(Number(prefs.pageHeight)); } catch (e1) { /* null */ }
8
+ try { out.facing_pages = prefs.facingPages === true; } catch (e2) { /* null */ }
9
+ try { out.page_count = Number(doc.pages.length); } catch (e3) { /* null */ }
10
+ try { out.start_page_number = Number(prefs.startPageNumber); } catch (e4) { /* null */ }
11
+ try { out.allow_page_shuffle = prefs.allowPageShuffle === true; } catch (e5) { /* null */ }
12
+ return out;
13
+ }
14
+
15
+ IDC.register('set_document_setup', { needs_document: true, read_only: false, ruler: 'none' },
16
+ function (ctx) {
17
+ var args = ctx.args;
18
+ var doc = ctx.doc;
19
+ var prefs = doc.documentPreferences;
20
+ var before = idcDescribeSetup(doc);
21
+ var width = before.page_width_mm, height = before.page_height_mm, swap = false, sizeGiven = false;
22
+ var given = 0, after, i, page, removed = [], added = [], pageIds = [];
23
+
24
+ if (args.preset !== undefined && args.preset !== null) {
25
+ if (!IDC_PAGE_PRESETS[String(args.preset)]) {
26
+ IDC.fail('invalid_argument', 'preset must be one of A4, Letter, Legal, Tabloid.', { preset: String(args.preset) });
27
+ }
28
+ width = IDC_PAGE_PRESETS[String(args.preset)].width;
29
+ height = IDC_PAGE_PRESETS[String(args.preset)].height;
30
+ sizeGiven = true; given += 1;
31
+ }
32
+ if (args.width_mm !== undefined && args.width_mm !== null) {
33
+ if (!idcIsNumber(args.width_mm) || args.width_mm <= 0 || args.width_mm > 5486) { IDC.fail('invalid_argument', 'width_mm must be a number above 0 (mm).', { width_mm: args.width_mm }); }
34
+ width = args.width_mm; sizeGiven = true; given += 1;
35
+ }
36
+ if (args.height_mm !== undefined && args.height_mm !== null) {
37
+ if (!idcIsNumber(args.height_mm) || args.height_mm <= 0 || args.height_mm > 5486) { IDC.fail('invalid_argument', 'height_mm must be a number above 0 (mm).', { height_mm: args.height_mm }); }
38
+ height = args.height_mm; sizeGiven = true; given += 1;
39
+ }
40
+ if (args.orientation !== undefined && args.orientation !== null) {
41
+ if (args.orientation === 'landscape') { swap = width < height; }
42
+ else if (args.orientation === 'portrait') { swap = width > height; }
43
+ else { IDC.fail('invalid_argument', 'orientation must be "portrait" or "landscape".', { orientation: String(args.orientation) }); }
44
+ if (swap) { sizeGiven = true; }
45
+ given += 1;
46
+ }
47
+ if (args.facing_pages !== undefined && args.facing_pages !== null) {
48
+ if (args.facing_pages !== true && args.facing_pages !== false) { IDC.fail('invalid_argument', 'facing_pages must be true or false.', null); }
49
+ given += 1;
50
+ }
51
+ if (args.pages !== undefined && args.pages !== null) {
52
+ if (!idcIsNumber(args.pages) || args.pages < 1 || Math.floor(args.pages) !== args.pages || args.pages > 9999) {
53
+ IDC.fail('invalid_argument', 'pages must be a whole number from 1 to 9999.', { pages: args.pages });
54
+ }
55
+ if (args.pages < before.page_count && args.allow_page_removal !== true) {
56
+ IDC.fail('invalid_argument', 'pages ' + args.pages + ' is below the current page count ' + before.page_count + '; InDesign would delete the last pages with their contents. Pass allow_page_removal true to confirm, or use delete_page.',
57
+ { pages: args.pages, page_count: before.page_count });
58
+ }
59
+ given += 1;
60
+ }
61
+ if (args.start_page_number !== undefined && args.start_page_number !== null) {
62
+ if (!idcIsNumber(args.start_page_number) || args.start_page_number < 1 || Math.floor(args.start_page_number) !== args.start_page_number) {
63
+ IDC.fail('invalid_argument', 'start_page_number must be a whole number of 1 or more.', { start_page_number: args.start_page_number });
64
+ }
65
+ given += 1;
66
+ }
67
+ var adjust = null;
68
+ if (args.adjust_layout !== undefined && args.adjust_layout !== null) {
69
+ if (args.adjust_layout !== true && args.adjust_layout !== false) {
70
+ IDC.fail('invalid_argument', 'adjust_layout must be true or false.', { adjust_layout: args.adjust_layout });
71
+ }
72
+ adjust = args.adjust_layout;
73
+ }
74
+ if (given === 0) {
75
+ IDC.fail('invalid_argument', 'Pass at least one of preset, width_mm, height_mm, orientation, facing_pages, pages, start_page_number.', null);
76
+ }
77
+ if (swap) { i = width; width = height; height = i; }
78
+
79
+ for (i = 0; i < doc.pages.length; i++) { try { pageIds.push(Number(doc.pages.item(i).id)); } catch (e0) { /* ohne */ } }
80
+
81
+ var layoutState = idcSuspendLayoutAdjustment(doc, adjust);
82
+ try {
83
+ if (args.facing_pages !== undefined && args.facing_pages !== null) { prefs.facingPages = args.facing_pages; }
84
+ if (sizeGiven) {
85
+ prefs.pageWidth = width;
86
+ prefs.pageHeight = height;
87
+ }
88
+ if (args.pages !== undefined && args.pages !== null) { prefs.pagesPerDocument = args.pages; }
89
+ if (args.start_page_number !== undefined && args.start_page_number !== null) { prefs.startPageNumber = args.start_page_number; }
90
+ } catch (e1) {
91
+ IDC.fail('script_error', 'InDesign could not change the document setup: ' + String(e1.message ? e1.message : e1), null);
92
+ } finally {
93
+ idcRestoreLayoutAdjustment(ctx, doc, layoutState);
94
+ }
95
+
96
+ after = idcDescribeSetup(doc);
97
+ /* Welche Seiten sind weg, welche neu? */
98
+ var current = {};
99
+ for (i = 0; i < doc.pages.length; i++) {
100
+ try { page = doc.pages.item(i); current[Number(page.id)] = true; if (!idcIdIn(pageIds, Number(page.id))) { added.push(Number(page.id)); } } catch (e2) { /* ohne */ }
101
+ }
102
+ for (i = 0; i < pageIds.length; i++) { if (!current[pageIds[i]]) { removed.push(pageIds[i]); } }
103
+
104
+ if (sizeGiven && (after.page_width_mm !== IDC.round(width) || after.page_height_mm !== IDC.round(height))) {
105
+ ctx.warn('InDesign reports the page size ' + after.page_width_mm + ' x ' + after.page_height_mm + ' mm after the change.');
106
+ }
107
+ if (sizeGiven && (before.page_width_mm !== after.page_width_mm || before.page_height_mm !== after.page_height_mm)) {
108
+ ctx.warn('The page size changed; objects and margins are not adjusted automatically – check get_layout_grid and get_page_state.');
109
+ }
110
+ if (args.facing_pages !== undefined && args.facing_pages !== null && before.facing_pages !== after.facing_pages) {
111
+ ctx.warn('facing_pages changed; spreads and parent pages were rearranged by InDesign – read list_pages and list_parent_pages again.');
112
+ }
113
+ if (removed.length > 0) { ctx.warn(removed.length + ' page(s) were removed with their contents.'); }
114
+ ctx.changes = { modified_document_ids: [Number(doc.id)], created_page_ids: added, removed_page_ids: removed };
115
+ if (sizeGiven && adjust === null && layoutState.active.length > 0) {
116
+ ctx.warn('Layout adjustment was active (' + layoutState.active.join(', ') + '); InDesign may have moved or scaled objects with the page size. Pass adjust_layout false to keep them as they are.');
117
+ }
118
+ return {
119
+ setup: after,
120
+ previous: before,
121
+ pages_added: added,
122
+ pages_removed: removed,
123
+ changed: IDC.stringify(before) !== IDC.stringify(after),
124
+ layout_adjustment: {
125
+ requested: adjust,
126
+ active_before: layoutState.active,
127
+ layout_rules_suspended: layoutState.rules.length
128
+ }
129
+ };
130
+ });
131
+
132
+ /*
133
+ * Layoutanpassung fuer einen Aufruf (A-43 Nr. 4, KDP-Befund 4). Live-Probe
134
+ * 09.10.2026 (InDesign 21.6): Rahmen wachsen bei geaenderter Seitengroesse,
135
+ * wenn eine fluessige Layoutregel (page.layoutRule, z. B. SCALE) gilt;
136
+ * "Layout anpassen" (adjustLayoutPreferences.enableAdjustLayout) verschiebt
137
+ * sie. adjust false schaltet beides fuer den Aufruf ab (Regeln der Dokument-
138
+ * und Musterseiten voruebergehend OFF), true schaltet "Layout anpassen" an,
139
+ * null laesst alles. Gemeldet wird, was vorher aktiv war.
140
+ */
141
+ function idcLayoutRuleName(rule) {
142
+ if (typeof LayoutRuleOptions === 'undefined') { return String(rule); }
143
+ if (IDC.enumIs(rule, LayoutRuleOptions.OFF)) { return 'off'; }
144
+ if (IDC.enumIs(rule, LayoutRuleOptions.USE_MASTER)) { return 'use_master'; }
145
+ if (IDC.enumIs(rule, LayoutRuleOptions.SCALE)) { return 'scale'; }
146
+ if (IDC.enumIs(rule, LayoutRuleOptions.RECENTER)) { return 'recenter'; }
147
+ if (IDC.enumIs(rule, LayoutRuleOptions.GUIDE_BASED)) { return 'guide_based'; }
148
+ if (IDC.enumIs(rule, LayoutRuleOptions.OBJECT_BASED)) { return 'object_based'; }
149
+ return String(rule);
150
+ }
151
+
152
+ function idcSuspendLayoutAdjustment(doc, adjust) {
153
+ var state = { active: [], prevAdjust: null, adjustSet: false, rules: [] };
154
+ var pages = [], i, j, spread, name, enabled = null, seen = {};
155
+ try { enabled = doc.adjustLayoutPreferences.enableAdjustLayout === true; } catch (e0) { enabled = null; }
156
+ if (enabled === true) { state.active.push('adjust_layout'); }
157
+ for (i = 0; i < doc.pages.length; i++) { pages.push(doc.pages.item(i)); }
158
+ try {
159
+ for (i = 0; i < doc.masterSpreads.length; i++) {
160
+ spread = doc.masterSpreads.item(i);
161
+ for (j = 0; j < spread.pages.length; j++) { pages.push(spread.pages.item(j)); }
162
+ }
163
+ } catch (e1) { /* ohne Musterseiten */ }
164
+ for (i = 0; i < pages.length; i++) {
165
+ try { name = idcLayoutRuleName(pages[i].layoutRule); } catch (e2) { continue; }
166
+ if (name === 'off' || name === 'use_master') { continue; }
167
+ if (!IDC.hasOwn(seen, name)) { seen[name] = true; state.active.push('layout_rule ' + name); }
168
+ if (adjust === false) { state.rules.push({ page: pages[i], rule: pages[i].layoutRule }); }
169
+ }
170
+ if (adjust !== null && enabled !== null && enabled !== adjust) {
171
+ try {
172
+ state.prevAdjust = enabled;
173
+ doc.adjustLayoutPreferences.enableAdjustLayout = adjust;
174
+ state.adjustSet = true;
175
+ } catch (e3) { state.adjustSet = false; }
176
+ }
177
+ for (i = 0; i < state.rules.length; i++) {
178
+ try { state.rules[i].page.layoutRule = LayoutRuleOptions.OFF; } catch (e4) { /* bleibt */ }
179
+ }
180
+ return state;
181
+ }
182
+
183
+ function idcRestoreLayoutAdjustment(ctx, doc, state) {
184
+ var i;
185
+ for (i = 0; i < state.rules.length; i++) {
186
+ try {
187
+ if (state.rules[i].page.isValid !== true) { continue; }
188
+ state.rules[i].page.layoutRule = state.rules[i].rule;
189
+ } catch (e0) {
190
+ ctx.warn('Could not restore the liquid layout rule of a page.');
191
+ }
192
+ }
193
+ if (state.adjustSet) {
194
+ try { doc.adjustLayoutPreferences.enableAdjustLayout = state.prevAdjust; } catch (e1) {
195
+ ctx.warn('Could not restore the Adjust Layout setting.');
196
+ }
197
+ }
198
+ }
199
+
200
+ function idcIdIn(list, id) {
201
+ var i;
202
+ for (i = 0; i < list.length; i++) { if (list[i] === id) { return true; } }
203
+ return false;
204
+ }
@@ -0,0 +1,258 @@
1
+ /* Wunschliste J2 Nr. 23 (Sitzung 8) – Kopie speichern und Verpacken: save_document_as, package_document. */
2
+
3
+ function idcTargetFileArg(path, field, extensions) {
4
+ var file, lower, i, ok = false;
5
+ if (typeof path !== 'string' || path.length === 0) {
6
+ IDC.fail('invalid_argument', field + ' must be a non-empty file path.', null);
7
+ }
8
+ lower = path.toLowerCase();
9
+ for (i = 0; i < extensions.length; i++) {
10
+ if (lower.length > extensions[i].length && lower.substring(lower.length - extensions[i].length) === extensions[i]) { ok = true; break; }
11
+ }
12
+ if (!ok) {
13
+ IDC.fail('invalid_argument', field + ' must end in ' + extensions.join(' or ') + '.', { path: path });
14
+ }
15
+ file = IDC.fileFor(path);
16
+ if (!IDC.fileParentExists(file)) {
17
+ IDC.fail('io_error', 'The folder for ' + field + ' does not exist: ' + path, { path: path });
18
+ }
19
+ return file;
20
+ }
21
+
22
+ IDC.register('save_document_as', { needs_document: true, read_only: false, ruler: 'none' },
23
+ function (ctx) {
24
+ var args = ctx.args;
25
+ var doc = ctx.doc;
26
+ var mode = args.mode === undefined || args.mode === null ? 'copy' : args.mode;
27
+ var overwrite = args.overwrite === true;
28
+ var extensions = ['.indd', '.indt'];
29
+ var file, own = idcDocumentPath(doc), nameBefore, existed, result;
30
+
31
+ if (mode !== 'copy' && mode !== 'switch') {
32
+ IDC.fail('invalid_argument', 'mode must be copy (the open document keeps its file) or switch (the open document continues under the new name).', { mode: mode });
33
+ }
34
+ file = idcTargetFileArg(args.path, 'path', extensions);
35
+ if (own !== '' && IDC.fsPath(file) === own) {
36
+ IDC.fail('invalid_argument', 'path is the file of the document itself; use save_document.', { path: args.path });
37
+ }
38
+ existed = file.exists === true;
39
+ if (existed && !overwrite) {
40
+ IDC.fail('io_error', 'A file exists at path already; pass overwrite true to replace it.', { path: args.path });
41
+ }
42
+ try { nameBefore = String(doc.name); } catch (e0) { nameBefore = ''; }
43
+ try {
44
+ if (mode === 'copy') {
45
+ doc.saveACopy(file, args.template === true);
46
+ } else {
47
+ doc.save(file, args.template === true);
48
+ }
49
+ } catch (e1) {
50
+ IDC.fail('io_error', 'InDesign could not save ' + (mode === 'copy' ? 'a copy' : 'the document') + ' to ' + args.path + ': ' + String(e1.message ? e1.message : e1), { path: args.path });
51
+ }
52
+ result = {
53
+ document_id: Number(doc.id),
54
+ mode: mode,
55
+ path: IDC.fsPath(file) || args.path,
56
+ bytes: IDC.fileSize(file),
57
+ overwritten: existed,
58
+ template: args.template === true,
59
+ name: String(doc.name),
60
+ document_path: idcDocumentPath(doc),
61
+ name_before: nameBefore
62
+ };
63
+ idcManagedSaveWarning(ctx, doc, mode === 'copy' ? 'The copy links to the same story files but is not bound to the editorial workflow.' :
64
+ 'The document now continues under the new file and still links to the same story files; it is not bound to the editorial workflow under the new name.');
65
+ if (mode === 'copy' && result.document_path === '') {
66
+ ctx.warn('The open document itself is still unsaved (untitled); only the copy was written.');
67
+ }
68
+ ctx.changes = mode === 'copy' ? { written_files: [result.path] } : { saved_document_ids: [Number(doc.id)], written_files: [result.path] };
69
+ return result;
70
+ });
71
+
72
+ IDC.register('package_document', { needs_document: true, read_only: false, ruler: 'none' },
73
+ function (ctx) {
74
+ var args = ctx.args;
75
+ var doc = ctx.doc;
76
+ var folder, issues, ok = false, pdfPreset = '', result, count = 0, reportFile;
77
+ var copyFonts = args.copy_fonts !== false;
78
+ var copyGraphics = args.copy_graphics !== false;
79
+ var copyProfiles = args.copy_profiles === true;
80
+ var updateGraphics = args.update_graphics !== false;
81
+ var includeHidden = args.include_hidden_layers === true;
82
+ var ignorePreflight = args.ignore_preflight_errors !== false;
83
+ var createReport = args.create_report !== false;
84
+ var includeIdml = args.include_idml === true;
85
+ var includePdf = args.include_pdf === true;
86
+
87
+ if (typeof args.folder_path !== 'string' || args.folder_path.length === 0) {
88
+ IDC.fail('invalid_argument', 'folder_path is required (the package folder InDesign creates or fills).', null);
89
+ }
90
+ if (idcDocumentPath(doc) === '') {
91
+ IDC.fail('invalid_state', 'The document has never been saved; save_document with path first.', null);
92
+ }
93
+ folder = IDC.folderFor(args.folder_path);
94
+ if (!IDC.fileParentExists(folder)) {
95
+ IDC.fail('io_error', 'The parent folder of folder_path does not exist: ' + args.folder_path, { folder_path: args.folder_path });
96
+ }
97
+ if (includePdf) {
98
+ if (args.pdf_preset !== undefined && args.pdf_preset !== null) {
99
+ if (typeof args.pdf_preset !== 'string' || args.pdf_preset === '') { IDC.fail('invalid_argument', 'pdf_preset must be a preset name.', null); }
100
+ if (idcPdfPresetByName(args.pdf_preset) === null) {
101
+ IDC.fail('not_found', 'PDF preset "' + args.pdf_preset + '" not found.', { pdf_preset: args.pdf_preset, available: idcPdfPresetNames() });
102
+ }
103
+ pdfPreset = args.pdf_preset;
104
+ } else {
105
+ try { pdfPreset = String(idcHighQualityPreset().name); } catch (e0) { pdfPreset = ''; }
106
+ }
107
+ }
108
+ issues = idcDocumentIssues(doc);
109
+ if (issues.missing_links && issues.missing_links.length > 0) {
110
+ ctx.warn(issues.missing_links.length + ' missing link(s) cannot be packaged: ' + issues.missing_links.join(', '));
111
+ }
112
+ if (issues.missing_fonts && issues.missing_fonts.length > 0) {
113
+ ctx.warn(issues.missing_fonts.length + ' missing font(s): ' + issues.missing_fonts.join(', '));
114
+ }
115
+ try {
116
+ ok = doc.packageForPrint(folder, copyFonts, copyGraphics, copyProfiles, updateGraphics, includeHidden, ignorePreflight, createReport,
117
+ includeIdml, includePdf, pdfPreset, false, '', true);
118
+ } catch (e1) {
119
+ IDC.fail('io_error', 'InDesign could not package the document: ' + String(e1.message ? e1.message : e1), { folder_path: args.folder_path });
120
+ }
121
+ if (ok !== true) {
122
+ IDC.fail('io_error', 'InDesign reported that packaging did not succeed (preflight errors? missing links?).', { folder_path: args.folder_path, missing_links: issues.missing_links, missing_fonts: issues.missing_fonts });
123
+ }
124
+ result = {
125
+ document_id: Number(doc.id),
126
+ folder_path: IDC.fsPath(folder) || args.folder_path,
127
+ copy_fonts: copyFonts,
128
+ copy_graphics: copyGraphics,
129
+ copy_profiles: copyProfiles,
130
+ update_graphics: updateGraphics,
131
+ include_hidden_layers: includeHidden,
132
+ ignore_preflight_errors: ignorePreflight,
133
+ create_report: createReport,
134
+ include_idml: includeIdml,
135
+ include_pdf: includePdf,
136
+ pdf_preset: includePdf ? pdfPreset : null,
137
+ missing_links: issues.missing_links || [],
138
+ missing_fonts: issues.missing_fonts || [],
139
+ document_path: idcDocumentPath(doc)
140
+ };
141
+ try {
142
+ count = folder.getFiles ? folder.getFiles().length : null;
143
+ } catch (e2) { count = null; }
144
+ result.entries_in_folder = count;
145
+
146
+ /* Demo-Heft-Befund 6 (Sitzung 10): welche Schriften liegen im Paket, welche nicht. */
147
+ var fontReport = idcPackagedFontReport(doc, folder, copyFonts);
148
+ result.fonts = fontReport.fonts;
149
+ result.fonts_total = fontReport.fonts.length;
150
+ result.fonts_packaged_count = fontReport.packaged_count;
151
+ result.fonts_not_packaged = fontReport.not_packaged;
152
+ result.fonts_folder = fontReport.folder;
153
+ if (copyFonts && fontReport.not_packaged.length > 0) {
154
+ ctx.warn(fontReport.not_packaged.length + ' font(s) are not in the package folder: ' + fontReport.not_packaged.join(', ') +
155
+ ' – fonts from Adobe Fonts (Creative Cloud) and other protected fonts are never copied by InDesign; the printer needs them installed.');
156
+ }
157
+ idcManagedSaveWarning(ctx, doc, 'The package holds copies of their story files; the package is not bound to the editorial workflow.');
158
+ ctx.changes = { written_folders: [result.folder_path] };
159
+ return result;
160
+ });
161
+
162
+ /* ------------------------------------------- Schriften im Paket (Befund 6) */
163
+
164
+ /*
165
+ * FontTypes nach indesignjs.de (Adobes Seite liefert 404; live am 05.09.2026
166
+ * zu bestaetigen): TYPE_1, TRUETYPE, CID, ATC, BITMAP, OCF, OPENTYPE_CFF,
167
+ * OPENTYPE_TT, OPENTYPE_CID, UNKNOWN.
168
+ */
169
+ function idcFontTypeName(value) {
170
+ if (typeof FontTypes === 'undefined' || value === undefined || value === null) { return null; }
171
+ if (IDC.enumIs(value, FontTypes.TYPE_1)) { return 'type1'; }
172
+ if (IDC.enumIs(value, FontTypes.TRUETYPE)) { return 'truetype'; }
173
+ if (IDC.enumIs(value, FontTypes.OPENTYPE_CFF)) { return 'opentype_cff'; }
174
+ if (IDC.enumIs(value, FontTypes.OPENTYPE_TT)) { return 'opentype_tt'; }
175
+ if (IDC.enumIs(value, FontTypes.OPENTYPE_CID)) { return 'opentype_cid'; }
176
+ if (IDC.enumIs(value, FontTypes.CID)) { return 'cid'; }
177
+ if (IDC.enumIs(value, FontTypes.ATC)) { return 'atc'; }
178
+ if (IDC.enumIs(value, FontTypes.BITMAP)) { return 'bitmap'; }
179
+ if (IDC.enumIs(value, FontTypes.OCF)) { return 'ocf'; }
180
+ return 'unknown';
181
+ }
182
+
183
+ function idcBaseName(path) {
184
+ return String(path).replace(/^.*[\/\\]/, '');
185
+ }
186
+
187
+ /* Dateinamen (klein geschrieben) im Ordner "Document fonts" des Pakets. */
188
+ function idcPackagedFontFiles(folder) {
189
+ var out = { exists: false, names: [] };
190
+ var base = IDC.fsPath(folder);
191
+ var sub, files, i, entry, name;
192
+ if (base === '') { return out; }
193
+ try { sub = IDC.folderFor(base + '/Document fonts'); } catch (e0) { return out; }
194
+ try { if (sub.exists !== true) { return out; } } catch (e1) { return out; }
195
+ out.exists = true;
196
+ try {
197
+ files = sub.getFiles();
198
+ for (i = 0; i < files.length; i++) {
199
+ entry = files[i];
200
+ name = null;
201
+ try { if (entry && entry.name !== undefined) { name = String(entry.name); } } catch (e2) { name = null; }
202
+ if (name === null) { name = idcBaseName(entry); }
203
+ out.names.push(name.toLowerCase());
204
+ }
205
+ } catch (e3) { /* Liste bleibt, so weit sie kam */ }
206
+ return out;
207
+ }
208
+
209
+ function idcIsAdobeFontsLocation(location) {
210
+ var text = String(location).toLowerCase();
211
+ return text.indexOf('/coresync/') >= 0 || text.indexOf('livetype') >= 0 || text.indexOf('/adobe fonts') >= 0;
212
+ }
213
+
214
+ /* Schriften des Dokuments mit Paketstatus. */
215
+ function idcPackagedFontReport(doc, folder, copyFonts) {
216
+ var files = copyFonts ? idcPackagedFontFiles(folder) : { exists: false, names: [] };
217
+ var out = { fonts: [], packaged_count: 0, not_packaged: [], folder: files.exists ? IDC.fsPath(folder) + '/Document fonts' : null };
218
+ var i, j, font, entry, location, base, status;
219
+ try {
220
+ for (i = 0; i < doc.fonts.length; i++) {
221
+ font = doc.fonts.item(i);
222
+ entry = { family: null, style: null, name: null, postscript_name: null, type: null, status: 'installed', location: null, packaged: null, reason: null };
223
+ try { entry.family = String(font.fontFamily); } catch (e0) { /* bleibt null */ }
224
+ try { entry.style = String(font.fontStyleName); } catch (e1) { /* bleibt null */ }
225
+ try { entry.name = String(font.name); } catch (e2) { /* bleibt null */ }
226
+ try { entry.postscript_name = String(font.postscriptName); } catch (e3) { /* bleibt null */ }
227
+ try { entry.type = idcFontTypeName(font.fontType); } catch (e4) { /* bleibt null */ }
228
+ try { status = font.status; entry.status = idcFontStatusName(status); } catch (e5) { entry.status = 'installed'; }
229
+ location = '';
230
+ try { location = String(font.location); } catch (e6) { location = ''; }
231
+ entry.location = location === '' ? null : location;
232
+ if (!copyFonts) {
233
+ entry.packaged = false;
234
+ entry.reason = 'copy_fonts_off';
235
+ } else if (entry.status !== 'installed') {
236
+ entry.packaged = false;
237
+ entry.reason = 'not_installed';
238
+ } else if (location === '' || !files.exists) {
239
+ entry.packaged = null;
240
+ entry.reason = files.exists ? 'location_unknown' : 'fonts_folder_missing';
241
+ } else {
242
+ base = idcBaseName(location).toLowerCase();
243
+ entry.packaged = false;
244
+ for (j = 0; j < files.names.length; j++) {
245
+ if (files.names[j] === base) { entry.packaged = true; break; }
246
+ }
247
+ if (!entry.packaged) {
248
+ entry.reason = idcIsAdobeFontsLocation(location) ? 'adobe_fonts' : 'not_copied';
249
+ }
250
+ }
251
+ if (entry.packaged === true) { out.packaged_count += 1; }
252
+ if (entry.packaged === false && entry.reason !== 'copy_fonts_off') { out.not_packaged.push(entry.name === null ? String(entry.family) : entry.name); }
253
+ out.fonts.push(entry);
254
+ }
255
+ } catch (e7) { /* Liste bleibt, so weit sie kam */ }
256
+ return out;
257
+ }
258
+