layoutbridge-spm 0.0.1 → 1.0.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 +171 -0
- package/LICENSE +26 -0
- package/README.de.md +318 -0
- package/README.md +304 -4
- package/THIRD-PARTY-NOTICES.md +2878 -0
- package/dist/src/mcp/config.js +125 -0
- package/dist/src/mcp/dispatch.js +123 -0
- package/dist/src/mcp/license/free-tools.js +16 -0
- package/dist/src/mcp/license/gate.js +209 -0
- package/dist/src/mcp/license/index.js +96 -0
- package/dist/src/mcp/license/instance-name.js +56 -0
- package/dist/src/mcp/license/key-source.js +58 -0
- package/dist/src/mcp/license/lemonsqueezy-verifier.js +207 -0
- package/dist/src/mcp/license/placeholder-verifier.js +10 -0
- package/dist/src/mcp/license/polar-ids.js +63 -0
- package/dist/src/mcp/license/polar-verifier.js +265 -0
- package/dist/src/mcp/license/product-ids.js +72 -0
- package/dist/src/mcp/license/state-store.js +91 -0
- package/dist/src/mcp/license/types.js +11 -0
- package/dist/src/mcp/logging.js +270 -0
- package/dist/src/mcp/product-info.js +48 -0
- package/dist/src/mcp/server.js +250 -0
- package/dist/src/mcp/setup.js +608 -0
- package/dist/src/mcp/start.cjs +95 -0
- package/dist/src/mcp/tool-definition.js +2 -0
- package/dist/src/mcp/tools.js +2004 -0
- package/dist/src/mcp/typography-rules.js +70 -0
- package/dist/src/transport/com.js +250 -0
- package/dist/src/transport/osascript.js +171 -0
- package/dist/src/transport/queue.js +19 -0
- package/dist/src/transport/script-bundle.js +92 -0
- package/dist/src/transport/transport.js +30 -0
- package/indesign/commands/10-app.js +6 -0
- package/indesign/commands/20-documents.js +513 -0
- package/indesign/commands/22-document-setup.js +118 -0
- package/indesign/commands/23-save-package.js +255 -0
- package/indesign/commands/25-export.js +379 -0
- package/indesign/commands/26-export-image.js +197 -0
- package/indesign/commands/27-textdefaults.js +151 -0
- package/indesign/commands/28-selection.js +174 -0
- package/indesign/commands/30-pages.js +1032 -0
- package/indesign/commands/31-view.js +210 -0
- package/indesign/commands/32-sections.js +203 -0
- package/indesign/commands/35-parents.js +428 -0
- package/indesign/commands/37-layout.js +760 -0
- package/indesign/commands/40-frames.js +836 -0
- package/indesign/commands/41-shapes.js +505 -0
- package/indesign/commands/42-groups.js +117 -0
- package/indesign/commands/43-layers.js +291 -0
- package/indesign/commands/44-effects.js +274 -0
- package/indesign/commands/45-frame-options.js +247 -0
- package/indesign/commands/47-anchored.js +287 -0
- package/indesign/commands/50-modify.js +781 -0
- package/indesign/commands/52-align.js +139 -0
- package/indesign/commands/55-fit.js +106 -0
- package/indesign/commands/60-images.js +771 -0
- package/indesign/commands/62-embed.js +120 -0
- package/indesign/commands/69-placeholders.js +127 -0
- package/indesign/commands/70-text.js +567 -0
- package/indesign/commands/71-outlines.js +92 -0
- package/indesign/commands/72-place-text.js +366 -0
- package/indesign/commands/74-stories.js +116 -0
- package/indesign/commands/75-tables.js +676 -0
- package/indesign/commands/76-text-variables.js +260 -0
- package/indesign/commands/77-story-options.js +86 -0
- package/indesign/commands/78-frame-lines.js +304 -0
- package/indesign/commands/79-check-typography.js +303 -0
- package/indesign/commands/80-styles.js +1620 -0
- package/indesign/commands/81-composition.js +355 -0
- package/indesign/commands/82-object-styles.js +263 -0
- package/indesign/commands/83-indents-tabs.js +237 -0
- package/indesign/commands/84-import-styles.js +142 -0
- package/indesign/commands/85-swatches.js +112 -0
- package/indesign/commands/86-gradients.js +185 -0
- package/indesign/commands/87-replace-swatch.js +180 -0
- package/indesign/commands/88-replace-font.js +217 -0
- package/indesign/interpreter.js +758 -0
- package/package.json +55 -6
- package/rules/typography-rules.json +31 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/* Wunschliste J (Sitzung 7) – Rahmenoptionen lesen: get_frame_options. */
|
|
2
|
+
|
|
3
|
+
/* first_baseline_offset: Name <-> FirstBaseline-Enumerator. */
|
|
4
|
+
function idcFirstBaselineFor(name) {
|
|
5
|
+
if (typeof FirstBaseline === 'undefined') { return null; }
|
|
6
|
+
if (name === 'ascent') { return FirstBaseline.ASCENT_OFFSET; }
|
|
7
|
+
if (name === 'cap_height') { return FirstBaseline.CAP_HEIGHT; }
|
|
8
|
+
if (name === 'leading') { return FirstBaseline.LEADING_OFFSET; }
|
|
9
|
+
if (name === 'x_height') { return FirstBaseline.X_HEIGHT; }
|
|
10
|
+
if (name === 'fixed') { return FirstBaseline.FIXED_HEIGHT; }
|
|
11
|
+
if (name === 'embox_top') { return FirstBaseline.EMBOX_TOP; }
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function idcFirstBaselineName(value) {
|
|
16
|
+
if (value === undefined || value === null) { return null; }
|
|
17
|
+
if (typeof FirstBaseline === 'undefined') { return String(value); }
|
|
18
|
+
if (IDC.enumIs(value, FirstBaseline.ASCENT_OFFSET)) { return 'ascent'; }
|
|
19
|
+
if (IDC.enumIs(value, FirstBaseline.CAP_HEIGHT)) { return 'cap_height'; }
|
|
20
|
+
if (IDC.enumIs(value, FirstBaseline.LEADING_OFFSET)) { return 'leading'; }
|
|
21
|
+
if (IDC.enumIs(value, FirstBaseline.X_HEIGHT)) { return 'x_height'; }
|
|
22
|
+
if (IDC.enumIs(value, FirstBaseline.FIXED_HEIGHT)) { return 'fixed'; }
|
|
23
|
+
if (IDC.enumIs(value, FirstBaseline.EMBOX_TOP)) { return 'embox_top'; }
|
|
24
|
+
return String(value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function idcVerticalJustificationName(value) {
|
|
28
|
+
if (value === undefined || value === null) { return null; }
|
|
29
|
+
if (typeof VerticalJustification === 'undefined') { return String(value); }
|
|
30
|
+
if (IDC.enumIs(value, VerticalJustification.TOP_ALIGN)) { return 'top'; }
|
|
31
|
+
if (IDC.enumIs(value, VerticalJustification.CENTER_ALIGN)) { return 'center'; }
|
|
32
|
+
if (IDC.enumIs(value, VerticalJustification.BOTTOM_ALIGN)) { return 'bottom'; }
|
|
33
|
+
if (IDC.enumIs(value, VerticalJustification.JUSTIFY_ALIGN)) { return 'justify'; }
|
|
34
|
+
return String(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* Name -> VerticalJustification, null bei unbekanntem Namen. Kein
|
|
39
|
+
* verschachtelter ?:-Ausdruck: ExtendScript klammert ihn links (Fund 3,
|
|
40
|
+
* Sitzung 6, live nachgewiesen am 05.09.2026).
|
|
41
|
+
*/
|
|
42
|
+
function idcVerticalJustificationFor(name) {
|
|
43
|
+
if (typeof VerticalJustification === 'undefined') { return null; }
|
|
44
|
+
if (name === 'top') { return VerticalJustification.TOP_ALIGN; }
|
|
45
|
+
if (name === 'center') { return VerticalJustification.CENTER_ALIGN; }
|
|
46
|
+
if (name === 'bottom') { return VerticalJustification.BOTTOM_ALIGN; }
|
|
47
|
+
if (name === 'justify') { return VerticalJustification.JUSTIFY_ALIGN; }
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function idcColumnTypeName(value) {
|
|
52
|
+
if (value === undefined || value === null) { return null; }
|
|
53
|
+
if (typeof TextColumnType === 'undefined') { return String(value); }
|
|
54
|
+
if (IDC.enumIs(value, TextColumnType.FIXED_NUMBER)) { return 'fixed_number'; }
|
|
55
|
+
if (IDC.enumIs(value, TextColumnType.FIXED_WIDTH)) { return 'fixed_width'; }
|
|
56
|
+
if (IDC.enumIs(value, TextColumnType.FLEXIBLE_WIDTH)) { return 'flexible_width'; }
|
|
57
|
+
return String(value);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* Spaltenart. Adobes DOM (TextFramePreference) fuehrt sie als zwei Schalter
|
|
62
|
+
* useFixedColumnWidth / useFlexibleColumnWidth; ein textColumnType gibt es
|
|
63
|
+
* dort nicht (in 21.5 wirft der Zugriff – Sitzung 7). Erst die Schalter,
|
|
64
|
+
* dann der Rueckfall auf textColumnType fuer Laufzeiten, die ihn kennen.
|
|
65
|
+
*/
|
|
66
|
+
function idcColumnType(prefs) {
|
|
67
|
+
var flexible = null, fixed = null;
|
|
68
|
+
try { flexible = prefs.useFlexibleColumnWidth === true; } catch (e0) { flexible = null; }
|
|
69
|
+
try { fixed = prefs.useFixedColumnWidth === true; } catch (e1) { fixed = null; }
|
|
70
|
+
if (flexible === true) { return 'flexible_width'; }
|
|
71
|
+
if (fixed === true) { return 'fixed_width'; }
|
|
72
|
+
if (flexible === false || fixed === false) { return 'fixed_number'; }
|
|
73
|
+
try { return idcColumnTypeName(prefs.textColumnType); } catch (e2) { return null; }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/*
|
|
77
|
+
* inset_mm beim Anlegen: eine Zahl (alle Kanten) oder { top, left, bottom,
|
|
78
|
+
* right }; fehlende Kanten eines Objekts gelten als 0.
|
|
79
|
+
*/
|
|
80
|
+
function idcInsetArg(spec, field) {
|
|
81
|
+
var keys = ['top', 'left', 'bottom', 'right'];
|
|
82
|
+
var out = {};
|
|
83
|
+
var i, v;
|
|
84
|
+
if (typeof spec === 'number') {
|
|
85
|
+
if (!isFinite(spec) || spec < 0) {
|
|
86
|
+
IDC.fail('invalid_argument', field + ' must be a number of 0 or more (mm).', { value: spec });
|
|
87
|
+
}
|
|
88
|
+
return { top: spec, left: spec, bottom: spec, right: spec };
|
|
89
|
+
}
|
|
90
|
+
if (!spec || typeof spec !== 'object') {
|
|
91
|
+
IDC.fail('invalid_argument', field + ' must be a number or an object { top, left, bottom, right } in mm.', null);
|
|
92
|
+
}
|
|
93
|
+
for (i = 0; i < keys.length; i++) {
|
|
94
|
+
v = spec[keys[i]];
|
|
95
|
+
if (v === undefined || v === null) { out[keys[i]] = 0; continue; }
|
|
96
|
+
if (typeof v !== 'number' || !isFinite(v) || v < 0) {
|
|
97
|
+
IDC.fail('invalid_argument', field + '.' + keys[i] + ' must be a number of 0 or more.', spec);
|
|
98
|
+
}
|
|
99
|
+
out[keys[i]] = v;
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* Rahmenoptionen eines Textrahmens (Objekt > Textrahmenoptionen), gelesen
|
|
106
|
+
* unter Millimeter; Grundlinien-Mindestabstand in Punkt.
|
|
107
|
+
*/
|
|
108
|
+
function idcTextFrameOptions(doc, frame) {
|
|
109
|
+
var prefs = null;
|
|
110
|
+
var out = {
|
|
111
|
+
columns: { count: null, gutter_mm: null, type: null, fixed_width_mm: null },
|
|
112
|
+
inset_mm: null,
|
|
113
|
+
vertical_justification: null,
|
|
114
|
+
vertical_threshold_mm: null,
|
|
115
|
+
first_baseline_offset: null,
|
|
116
|
+
min_first_baseline_pt: null,
|
|
117
|
+
ignore_text_wrap: null,
|
|
118
|
+
optical_margin_alignment: null,
|
|
119
|
+
optical_margin_size_pt: null
|
|
120
|
+
};
|
|
121
|
+
/* A-7.4: storyweite Werte (StoryPreference) unter text, damit get_frame_options sie zeigt. */
|
|
122
|
+
try {
|
|
123
|
+
var storyOptions = idcReadStoryOptions(frame.parentStory);
|
|
124
|
+
out.optical_margin_alignment = storyOptions.optical_margin_alignment;
|
|
125
|
+
out.optical_margin_size_pt = storyOptions.optical_margin_size_pt;
|
|
126
|
+
} catch (eS) { /* bleibt null */ }
|
|
127
|
+
try { prefs = frame.textFramePreferences; } catch (e0) { prefs = null; }
|
|
128
|
+
if (prefs === null || prefs === undefined) { return out; }
|
|
129
|
+
try { out.columns.count = Number(prefs.textColumnCount); } catch (e1) { /* bleibt null */ }
|
|
130
|
+
try { out.columns.gutter_mm = IDC.round(Number(prefs.textColumnGutter)); } catch (e2) { /* bleibt null */ }
|
|
131
|
+
out.columns.type = idcColumnType(prefs);
|
|
132
|
+
try { out.columns.fixed_width_mm = IDC.round(Number(prefs.textColumnFixedWidth)); } catch (e4) { /* bleibt null */ }
|
|
133
|
+
try { out.inset_mm = idcEdgesFromArray(prefs.insetSpacing); } catch (e5) { /* bleibt null */ }
|
|
134
|
+
try { out.vertical_justification = idcVerticalJustificationName(prefs.verticalJustification); } catch (e6) { /* bleibt null */ }
|
|
135
|
+
try { out.vertical_threshold_mm = IDC.round(Number(prefs.verticalThreshold)); } catch (e7) { /* bleibt null */ }
|
|
136
|
+
try { out.first_baseline_offset = idcFirstBaselineName(prefs.firstBaselineOffset); } catch (e8) { /* bleibt null */ }
|
|
137
|
+
try {
|
|
138
|
+
out.min_first_baseline_pt = IDC.inPoints(function () { return IDC.round(Number(prefs.minimumFirstBaselineOffset), 3); });
|
|
139
|
+
} catch (e9) { /* bleibt null */ }
|
|
140
|
+
try { out.ignore_text_wrap = prefs.ignoreWrap === true; } catch (e10) { /* bleibt null */ }
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Verkettung: Story, Stellung des Rahmens in ihr, Nachbarn, Uebersatz. */
|
|
145
|
+
function idcThreading(frame) {
|
|
146
|
+
var out = {
|
|
147
|
+
story_id: null,
|
|
148
|
+
story_length: null,
|
|
149
|
+
frame_index: null,
|
|
150
|
+
frame_count: null,
|
|
151
|
+
previous_frame_id: null,
|
|
152
|
+
next_frame_id: null,
|
|
153
|
+
overset: null,
|
|
154
|
+
story_overset: null
|
|
155
|
+
};
|
|
156
|
+
var story = null, frames, i, prev = null, next = null;
|
|
157
|
+
try { story = frame.parentStory; } catch (e0) { story = null; }
|
|
158
|
+
if (story !== null && story !== undefined) {
|
|
159
|
+
try { out.story_id = Number(story.id); } catch (e1) { /* null */ }
|
|
160
|
+
try { out.story_length = Number(story.characters.length); } catch (e2) { /* null */ }
|
|
161
|
+
try {
|
|
162
|
+
frames = story.textContainers;
|
|
163
|
+
out.frame_count = frames.length;
|
|
164
|
+
for (i = 0; i < frames.length; i++) {
|
|
165
|
+
if (Number(frames[i].id) === Number(frame.id)) { out.frame_index = i; break; }
|
|
166
|
+
}
|
|
167
|
+
} catch (e3) { /* null */ }
|
|
168
|
+
try { out.story_overset = story.overflows === true; } catch (e4) { /* null */ }
|
|
169
|
+
}
|
|
170
|
+
try { prev = frame.previousTextFrame; } catch (e5) { prev = null; }
|
|
171
|
+
try { next = frame.nextTextFrame; } catch (e6) { next = null; }
|
|
172
|
+
try { if (prev !== null && prev !== undefined && prev.isValid === true) { out.previous_frame_id = Number(prev.id); } } catch (e7) { /* null */ }
|
|
173
|
+
try { if (next !== null && next !== undefined && next.isValid === true) { out.next_frame_id = Number(next.id); } } catch (e8) { /* null */ }
|
|
174
|
+
try { out.overset = frame.overflows === true; } catch (e9) { /* null */ }
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/*
|
|
179
|
+
* Grundlinie der ersten Zeile in mm ab Seitenoberkante (Lineal steht fuer
|
|
180
|
+
* den Aufruf auf Seiten-Nullpunkt), null ohne Text. Der direkte Weg, den
|
|
181
|
+
* Sitz einer Bildunterschrift im Grundlinienraster zu pruefen (Fund 3).
|
|
182
|
+
*/
|
|
183
|
+
function idcFirstBaselineMm(frame) {
|
|
184
|
+
try {
|
|
185
|
+
if (frame.lines.length === 0) { return null; }
|
|
186
|
+
return IDC.round(Number(frame.lines.item(0).baseline), 3);
|
|
187
|
+
} catch (e0) { return null; }
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* Textumfluss eines Objekts mit Abstand. */
|
|
191
|
+
function idcTextWrapOptions(item) {
|
|
192
|
+
var out = { mode: null, offset_mm: null };
|
|
193
|
+
var prefs = null, mode;
|
|
194
|
+
try { prefs = item.textWrapPreferences; } catch (e0) { prefs = null; }
|
|
195
|
+
if (prefs === null || prefs === undefined) { return out; }
|
|
196
|
+
mode = idcTextWrapName(item);
|
|
197
|
+
if (mode === 'contour') { mode = 'object_shape'; }
|
|
198
|
+
out.mode = mode;
|
|
199
|
+
try { out.offset_mm = idcEdgesFromArray(prefs.textWrapOffset); } catch (e1) { out.offset_mm = null; }
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
IDC.register('get_frame_options', { needs_document: true, read_only: true, ruler: 'page' },
|
|
204
|
+
function (ctx) {
|
|
205
|
+
var args = ctx.args;
|
|
206
|
+
var doc = ctx.doc;
|
|
207
|
+
var found = idcFrameArg(doc, args, 'frame_id');
|
|
208
|
+
var item = found.item;
|
|
209
|
+
var type = IDC.itemType(item);
|
|
210
|
+
var landing = IDC.landing(item);
|
|
211
|
+
var look = idcAppearanceFull(item);
|
|
212
|
+
var corners = type === 'line' || type === 'group' ? null : idcReadCorners(item);
|
|
213
|
+
var out = {
|
|
214
|
+
frame_id: Number(item.id),
|
|
215
|
+
type: type,
|
|
216
|
+
page_id: landing.page_id,
|
|
217
|
+
page_name: landing.page_name,
|
|
218
|
+
on_parent_page: found.on_parent === true,
|
|
219
|
+
coordinate_space: idcBoundsSpace(item),
|
|
220
|
+
bounds_mm: idcItemBounds(doc, item),
|
|
221
|
+
rotation_deg: idcRotationOf(item),
|
|
222
|
+
text_wrap: idcTextWrapOptions(item),
|
|
223
|
+
appearance: look,
|
|
224
|
+
corners: corners === null ? null : { top_left: corners.top_left, top_right: corners.top_right, bottom_left: corners.bottom_left, bottom_right: corners.bottom_right, uniform: corners.uniform },
|
|
225
|
+
layer: idcLayerSummary(doc, item),
|
|
226
|
+
locked: idcReadBool(item, 'locked') === true,
|
|
227
|
+
anchored: idcAnchorInfo(item),
|
|
228
|
+
effects: null,
|
|
229
|
+
has_effects: null,
|
|
230
|
+
text: null
|
|
231
|
+
};
|
|
232
|
+
/* A-8.6: Effekte des Objekts und ob Flaeche, Kontur, Text abweichen. */
|
|
233
|
+
var effects = idcEffectsSummary(item);
|
|
234
|
+
out.effects = effects.effects;
|
|
235
|
+
out.has_effects = effects.has_effects;
|
|
236
|
+
var parentGroup = null;
|
|
237
|
+
try { if (IDC.className(item.parent) === 'Group') { parentGroup = Number(item.parent.id); } } catch (e0) { parentGroup = null; }
|
|
238
|
+
out.parent_group_id = parentGroup;
|
|
239
|
+
|
|
240
|
+
if (IDC.isTextFrame(item)) {
|
|
241
|
+
out.text = idcTextFrameOptions(doc, item);
|
|
242
|
+
out.text.threading = idcThreading(item);
|
|
243
|
+
out.text.first_baseline_mm = idcFirstBaselineMm(item);
|
|
244
|
+
try { out.text.character_count = Number(item.characters.length); } catch (e1) { out.text.character_count = null; }
|
|
245
|
+
}
|
|
246
|
+
return out;
|
|
247
|
+
});
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/* Wunschliste J2 Nr. 17 (Sitzung 8) – verankerte Objekte: anchor_frame_in_text, unanchor_frame. */
|
|
2
|
+
|
|
3
|
+
var IDC_ANCHOR_POSITIONS = [
|
|
4
|
+
['inline', 'INLINE_POSITION'],
|
|
5
|
+
['above_line', 'ABOVE_LINE'],
|
|
6
|
+
['custom', 'ANCHORED']
|
|
7
|
+
];
|
|
8
|
+
var IDC_ANCHOR_POINTS = [
|
|
9
|
+
['top_left', 'TOP_LEFT_ANCHOR'], ['top_center', 'TOP_CENTER_ANCHOR'], ['top_right', 'TOP_RIGHT_ANCHOR'],
|
|
10
|
+
['left_center', 'LEFT_CENTER_ANCHOR'], ['center', 'CENTER_ANCHOR'], ['right_center', 'RIGHT_CENTER_ANCHOR'],
|
|
11
|
+
['bottom_left', 'BOTTOM_LEFT_ANCHOR'], ['bottom_center', 'BOTTOM_CENTER_ANCHOR'], ['bottom_right', 'BOTTOM_RIGHT_ANCHOR']
|
|
12
|
+
];
|
|
13
|
+
var IDC_H_REFERENCES = [
|
|
14
|
+
['anchor_location', 'ANCHOR_LOCATION'], ['column_edge', 'COLUMN_EDGE'], ['text_frame', 'TEXT_FRAME'],
|
|
15
|
+
['page_margins', 'PAGE_MARGINS'], ['page_edge', 'PAGE_EDGE']
|
|
16
|
+
];
|
|
17
|
+
var IDC_V_REFERENCES = [
|
|
18
|
+
['line_baseline', 'LINE_BASELINE'], ['line_xheight', 'LINE_XHEIGHT'], ['line_ascent', 'LINE_ASCENT'],
|
|
19
|
+
['cap_height', 'CAPHEIGHT'], ['top_of_leading', 'TOP_OF_LEADING'], ['embox_top', 'EMBOX_TOP'],
|
|
20
|
+
['embox_middle', 'EMBOX_MIDDLE'], ['embox_bottom', 'EMBOX_BOTTOM'], ['column_edge', 'COLUMN_EDGE'],
|
|
21
|
+
['text_frame', 'TEXT_FRAME'], ['page_margins', 'PAGE_MARGINS'], ['page_edge', 'PAGE_EDGE']
|
|
22
|
+
];
|
|
23
|
+
var IDC_H_ALIGNMENTS = [['left', 'LEFT_ALIGN'], ['center', 'CENTER_ALIGN'], ['right', 'RIGHT_ALIGN'], ['text', 'TEXT_ALIGN']];
|
|
24
|
+
var IDC_V_ALIGNMENTS = [['top', 'TOP_ALIGN'], ['center', 'CENTER_ALIGN'], ['bottom', 'BOTTOM_ALIGN']];
|
|
25
|
+
|
|
26
|
+
/* Enumeratorwert zu einem Namen aus einer Tabelle; null, wenn die Laufzeit den Enumerator nicht kennt. */
|
|
27
|
+
function idcEnumFor(table, enumObject, name, field) {
|
|
28
|
+
var i;
|
|
29
|
+
for (i = 0; i < table.length; i++) {
|
|
30
|
+
if (table[i][0] === name) {
|
|
31
|
+
if (enumObject === null || enumObject === undefined) { return null; }
|
|
32
|
+
try { return enumObject[table[i][1]]; } catch (e) { return null; }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
IDC.fail('invalid_argument', field + ' must be one of ' + idcTableNames(table).join(', ') + '.', { field: field, value: name });
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function idcTableNames(table) {
|
|
40
|
+
var out = [], i;
|
|
41
|
+
for (i = 0; i < table.length; i++) { out.push(table[i][0]); }
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Name zu einem Enumeratorwert; String(value), wenn kein Name passt. */
|
|
46
|
+
function idcEnumName(table, enumObject, value) {
|
|
47
|
+
var i;
|
|
48
|
+
if (value === undefined || value === null) { return null; }
|
|
49
|
+
if (enumObject === null || enumObject === undefined) { return String(value); }
|
|
50
|
+
for (i = 0; i < table.length; i++) {
|
|
51
|
+
try { if (IDC.enumIs(value, enumObject[table[i][1]])) { return table[i][0]; } } catch (e) { /* naechster */ }
|
|
52
|
+
}
|
|
53
|
+
return String(value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Enumerator-Objekt der Laufzeit ueber seinen Namen, null wenn unbekannt (kein eval). */
|
|
57
|
+
function idcEnumObject(name) {
|
|
58
|
+
if (name === 'AnchorPosition') { return typeof AnchorPosition === 'undefined' ? null : AnchorPosition; }
|
|
59
|
+
if (name === 'AnchorPoint') { return typeof AnchorPoint === 'undefined' ? null : AnchorPoint; }
|
|
60
|
+
if (name === 'AnchoredRelativeTo') { return typeof AnchoredRelativeTo === 'undefined' ? null : AnchoredRelativeTo; }
|
|
61
|
+
if (name === 'VerticallyRelativeTo') { return typeof VerticallyRelativeTo === 'undefined' ? null : VerticallyRelativeTo; }
|
|
62
|
+
if (name === 'HorizontalAlignment') { return typeof HorizontalAlignment === 'undefined' ? null : HorizontalAlignment; }
|
|
63
|
+
if (name === 'VerticalAlignment') { return typeof VerticalAlignment === 'undefined' ? null : VerticalAlignment; }
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Verankert? Der parent eines verankerten Objekts ist eine Textstelle. */
|
|
68
|
+
function idcAnchorInfo(item) {
|
|
69
|
+
var parent = null, name = '', settings = null;
|
|
70
|
+
var out = { story_id: null, index: null, position: null };
|
|
71
|
+
try { parent = item.parent; } catch (e0) { return null; }
|
|
72
|
+
if (parent === null || parent === undefined) { return null; }
|
|
73
|
+
name = IDC.className(parent);
|
|
74
|
+
if (name !== 'Character' && name !== 'InsertionPoint' && name !== 'Text' && name !== 'Word' && name !== 'Line' && name !== 'Paragraph' && name !== 'TextStyleRange') {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
try { out.story_id = Number(parent.parentStory.id); } catch (e1) { /* null */ }
|
|
78
|
+
try { out.index = Number(parent.index); } catch (e2) { /* null */ }
|
|
79
|
+
try { settings = item.anchoredObjectSettings; } catch (e3) { settings = null; }
|
|
80
|
+
if (settings !== null && settings !== undefined) {
|
|
81
|
+
try { out.position = idcEnumName(IDC_ANCHOR_POSITIONS, idcEnumObject('AnchorPosition'), settings.anchoredPosition); } catch (e4) { /* null */ }
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function idcDescribeAnchoredSettings(item) {
|
|
87
|
+
var settings = null;
|
|
88
|
+
var out = { position: null, anchor_point: null, horizontal_reference: null, vertical_reference: null,
|
|
89
|
+
horizontal_alignment: null, vertical_alignment: null, offset_mm: { x: null, y: null }, keep_within_frame: null, lock_position: null };
|
|
90
|
+
try { settings = item.anchoredObjectSettings; } catch (e0) { settings = null; }
|
|
91
|
+
if (settings === null || settings === undefined) { return out; }
|
|
92
|
+
try { out.position = idcEnumName(IDC_ANCHOR_POSITIONS, idcEnumObject('AnchorPosition'), settings.anchoredPosition); } catch (e1) { /* null */ }
|
|
93
|
+
try { out.anchor_point = idcEnumName(IDC_ANCHOR_POINTS, idcEnumObject('AnchorPoint'), settings.anchorPoint); } catch (e2) { /* null */ }
|
|
94
|
+
try { out.horizontal_reference = idcEnumName(IDC_H_REFERENCES, idcEnumObject('AnchoredRelativeTo'), settings.horizontalReferencePoint); } catch (e3) { /* null */ }
|
|
95
|
+
try { out.vertical_reference = idcEnumName(IDC_V_REFERENCES, idcEnumObject('VerticallyRelativeTo'), settings.verticalReferencePoint); } catch (e4) { /* null */ }
|
|
96
|
+
try { out.horizontal_alignment = idcEnumName(IDC_H_ALIGNMENTS, idcEnumObject('HorizontalAlignment'), settings.horizontalAlignment); } catch (e5) { /* null */ }
|
|
97
|
+
try { out.vertical_alignment = idcEnumName(IDC_V_ALIGNMENTS, idcEnumObject('VerticalAlignment'), settings.verticalAlignment); } catch (e6) { /* null */ }
|
|
98
|
+
try { out.offset_mm.x = IDC.round(Number(settings.anchorXoffset), 3); } catch (e7) { /* null */ }
|
|
99
|
+
try { out.offset_mm.y = IDC.round(Number(settings.anchorYoffset), 3); } catch (e8) { /* null */ }
|
|
100
|
+
try { out.keep_within_frame = settings.pinPosition === true; } catch (e9) { /* null */ }
|
|
101
|
+
try { out.lock_position = settings.lockPosition === true; } catch (e10) { /* null */ }
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function idcOffsetArg(value, field) {
|
|
106
|
+
var out = { x: 0, y: 0 };
|
|
107
|
+
if (value === undefined || value === null) { return out; }
|
|
108
|
+
if (typeof value !== 'object') {
|
|
109
|
+
IDC.fail('invalid_argument', field + ' must be an object {x, y} in mm.', { field: field });
|
|
110
|
+
}
|
|
111
|
+
if (value.x !== undefined && value.x !== null) {
|
|
112
|
+
if (typeof value.x !== 'number' || !isFinite(value.x)) { IDC.fail('invalid_argument', field + '.x must be a number (mm).', { field: field }); }
|
|
113
|
+
out.x = value.x;
|
|
114
|
+
}
|
|
115
|
+
if (value.y !== undefined && value.y !== null) {
|
|
116
|
+
if (typeof value.y !== 'number' || !isFinite(value.y)) { IDC.fail('invalid_argument', field + '.y must be a number (mm).', { field: field }); }
|
|
117
|
+
out.y = value.y;
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
IDC.register('anchor_frame_in_text', { needs_document: true, read_only: false, ruler: 'page' },
|
|
123
|
+
function (ctx) {
|
|
124
|
+
var args = ctx.args;
|
|
125
|
+
var doc = ctx.doc;
|
|
126
|
+
var found = idcFrameArg(doc, args, 'frame_id');
|
|
127
|
+
var item = found.item;
|
|
128
|
+
var target = idcTextFrameArg(doc, args, 'target_frame_id');
|
|
129
|
+
var story = idcStoryOf(target.item);
|
|
130
|
+
var position = args.position === undefined || args.position === null ? 'inline' : args.position;
|
|
131
|
+
var offset = idcOffsetArg(args.offset_mm, 'offset_mm');
|
|
132
|
+
var length = 0, index, insertionPoint, settings, anchoredItem = null, result, existing, landing, boundsMm = null;
|
|
133
|
+
var positionValue, value;
|
|
134
|
+
|
|
135
|
+
idcRejectGroupMember(item, args.frame_id, 'anchor_frame_in_text');
|
|
136
|
+
if (Number(item.id) === Number(target.item.id)) {
|
|
137
|
+
IDC.fail('invalid_argument', 'frame_id and target_frame_id must differ.', { frame_id: args.frame_id });
|
|
138
|
+
}
|
|
139
|
+
existing = idcAnchorInfo(item);
|
|
140
|
+
if (existing !== null) {
|
|
141
|
+
IDC.fail('invalid_state', 'Object ' + args.frame_id + ' is already anchored (story ' + existing.story_id + ', index ' + existing.index + '); use unanchor_frame first.',
|
|
142
|
+
{ frame_id: args.frame_id, anchored: existing });
|
|
143
|
+
}
|
|
144
|
+
if (IDC.isTextFrame(item)) {
|
|
145
|
+
try {
|
|
146
|
+
if (Number(item.parentStory.id) === Number(story.id)) {
|
|
147
|
+
IDC.fail('invalid_state', 'The object is a frame of the target story itself.', { frame_id: args.frame_id });
|
|
148
|
+
}
|
|
149
|
+
} catch (e0) { if (e0 && e0.isIdcError) { throw e0; } }
|
|
150
|
+
}
|
|
151
|
+
try { length = Number(story.characters.length); } catch (e1) { length = 0; }
|
|
152
|
+
if (args.index === undefined || args.index === null) {
|
|
153
|
+
index = length;
|
|
154
|
+
} else {
|
|
155
|
+
if (typeof args.index !== 'number' || Math.floor(args.index) !== args.index || args.index < 0 || args.index > length) {
|
|
156
|
+
IDC.fail('invalid_argument', 'index must be a whole number from 0 to the story length (' + length + ').', { index: args.index, story_length: length });
|
|
157
|
+
}
|
|
158
|
+
index = args.index;
|
|
159
|
+
}
|
|
160
|
+
positionValue = idcEnumFor(IDC_ANCHOR_POSITIONS, idcEnumObject('AnchorPosition'), position, 'position');
|
|
161
|
+
if (positionValue === null) {
|
|
162
|
+
IDC.fail('invalid_state', 'This runtime has no AnchorPosition enumeration.', null);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
try { insertionPoint = story.insertionPoints.item(index); } catch (e2) {
|
|
166
|
+
IDC.fail('script_error', 'InDesign could not address insertion point ' + index + '.', { index: index });
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
settings = item.anchoredObjectSettings;
|
|
170
|
+
anchoredItem = settings.insertAnchoredObject(insertionPoint, positionValue);
|
|
171
|
+
} catch (e3) {
|
|
172
|
+
IDC.fail('script_error', 'InDesign could not anchor object ' + args.frame_id + ': ' + String(e3.message ? e3.message : e3),
|
|
173
|
+
{ frame_id: args.frame_id, target_frame_id: args.target_frame_id, index: index });
|
|
174
|
+
}
|
|
175
|
+
if (anchoredItem === null || anchoredItem === undefined) { anchoredItem = item; }
|
|
176
|
+
anchoredItem = IDC.concrete(anchoredItem);
|
|
177
|
+
try { settings = anchoredItem.anchoredObjectSettings; } catch (e4) { settings = null; }
|
|
178
|
+
|
|
179
|
+
if (settings !== null && position === 'custom') {
|
|
180
|
+
try {
|
|
181
|
+
if (args.anchor_point !== undefined && args.anchor_point !== null) {
|
|
182
|
+
value = idcEnumFor(IDC_ANCHOR_POINTS, idcEnumObject('AnchorPoint'), args.anchor_point, 'anchor_point');
|
|
183
|
+
if (value !== null) { settings.anchorPoint = value; }
|
|
184
|
+
}
|
|
185
|
+
if (args.horizontal_reference !== undefined && args.horizontal_reference !== null) {
|
|
186
|
+
value = idcEnumFor(IDC_H_REFERENCES, idcEnumObject('AnchoredRelativeTo'), args.horizontal_reference, 'horizontal_reference');
|
|
187
|
+
if (value !== null) { settings.horizontalReferencePoint = value; }
|
|
188
|
+
}
|
|
189
|
+
if (args.vertical_reference !== undefined && args.vertical_reference !== null) {
|
|
190
|
+
value = idcEnumFor(IDC_V_REFERENCES, idcEnumObject('VerticallyRelativeTo'), args.vertical_reference, 'vertical_reference');
|
|
191
|
+
if (value !== null) { settings.verticalReferencePoint = value; }
|
|
192
|
+
}
|
|
193
|
+
if (args.horizontal_alignment !== undefined && args.horizontal_alignment !== null) {
|
|
194
|
+
value = idcEnumFor(IDC_H_ALIGNMENTS, idcEnumObject('HorizontalAlignment'), args.horizontal_alignment, 'horizontal_alignment');
|
|
195
|
+
if (value !== null) { settings.horizontalAlignment = value; }
|
|
196
|
+
}
|
|
197
|
+
if (args.vertical_alignment !== undefined && args.vertical_alignment !== null) {
|
|
198
|
+
value = idcEnumFor(IDC_V_ALIGNMENTS, idcEnumObject('VerticalAlignment'), args.vertical_alignment, 'vertical_alignment');
|
|
199
|
+
if (value !== null) { settings.verticalAlignment = value; }
|
|
200
|
+
}
|
|
201
|
+
settings.anchorXoffset = offset.x;
|
|
202
|
+
settings.anchorYoffset = offset.y;
|
|
203
|
+
if (args.keep_within_frame !== undefined && args.keep_within_frame !== null) { settings.pinPosition = args.keep_within_frame === true; }
|
|
204
|
+
if (args.lock_position !== undefined && args.lock_position !== null) { settings.lockPosition = args.lock_position === true; }
|
|
205
|
+
} catch (e5) {
|
|
206
|
+
if (e5 && e5.isIdcError) { throw e5; }
|
|
207
|
+
ctx.warn('Some anchored object settings could not be written: ' + String(e5.message ? e5.message : e5));
|
|
208
|
+
}
|
|
209
|
+
} else if (position !== 'custom' && (args.offset_mm !== undefined || args.anchor_point !== undefined || args.horizontal_reference !== undefined || args.vertical_reference !== undefined)) {
|
|
210
|
+
ctx.warn('offset_mm, anchor_point and the reference/alignment parameters apply to position "custom" only; ignored.');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
landing = IDC.landing(anchoredItem);
|
|
214
|
+
try { boundsMm = idcItemBounds(doc, anchoredItem); } catch (e6) { boundsMm = null; }
|
|
215
|
+
result = {
|
|
216
|
+
frame_id: Number(anchoredItem.id),
|
|
217
|
+
previous_frame_id: Number(args.frame_id),
|
|
218
|
+
type: IDC.itemType(anchoredItem),
|
|
219
|
+
story_id: Number(story.id),
|
|
220
|
+
target_frame_id: Number(target.item.id),
|
|
221
|
+
index: index,
|
|
222
|
+
story_length: length + 1,
|
|
223
|
+
settings: idcDescribeAnchoredSettings(anchoredItem),
|
|
224
|
+
bounds_mm: boundsMm,
|
|
225
|
+
page_id: landing.page_id,
|
|
226
|
+
page_name: landing.page_name,
|
|
227
|
+
story_overset: idcOverflows(target.item)
|
|
228
|
+
};
|
|
229
|
+
try { result.story_overset = story.overflows === true; } catch (e7) { /* Rahmenwert bleibt */ }
|
|
230
|
+
if (Number(anchoredItem.id) !== Number(args.frame_id)) {
|
|
231
|
+
ctx.warn('InDesign gave the anchored object a new id (' + Number(anchoredItem.id) + '); use it from now on.');
|
|
232
|
+
}
|
|
233
|
+
if (result.story_overset === true) {
|
|
234
|
+
ctx.warn('The story overflows after anchoring (Übersatz) – the object may sit in the overset text.');
|
|
235
|
+
}
|
|
236
|
+
ctx.changes = { modified_frame_ids: [Number(anchoredItem.id), Number(target.item.id)] };
|
|
237
|
+
return result;
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
IDC.register('unanchor_frame', { needs_document: true, read_only: false, ruler: 'page' },
|
|
241
|
+
function (ctx) {
|
|
242
|
+
var args = ctx.args;
|
|
243
|
+
var doc = ctx.doc;
|
|
244
|
+
var found = idcFrameArg(doc, args, 'frame_id');
|
|
245
|
+
var item = found.item;
|
|
246
|
+
var info = idcAnchorInfo(item);
|
|
247
|
+
var released = null, landing, boundsMm = null, result;
|
|
248
|
+
|
|
249
|
+
if (info === null) {
|
|
250
|
+
IDC.fail('invalid_state', 'Object ' + args.frame_id + ' is not anchored in text.', { frame_id: args.frame_id });
|
|
251
|
+
}
|
|
252
|
+
/*
|
|
253
|
+
* Live 05.09.2026: releaseAnchoredObject() laesst inline und above_line
|
|
254
|
+
* still unveraendert (im Menue gibt es „Loesen“ nur fuer benutzerdefinierte
|
|
255
|
+
* Position). Deshalb erst auf custom umstellen, dann loesen.
|
|
256
|
+
*/
|
|
257
|
+
try {
|
|
258
|
+
if (info.position !== 'custom' && typeof AnchorPosition !== 'undefined') {
|
|
259
|
+
item.anchoredObjectSettings.anchoredPosition = AnchorPosition.ANCHORED;
|
|
260
|
+
}
|
|
261
|
+
released = item.anchoredObjectSettings.releaseAnchoredObject();
|
|
262
|
+
} catch (e0) {
|
|
263
|
+
IDC.fail('script_error', 'InDesign could not release object ' + args.frame_id + ': ' + String(e0.message ? e0.message : e0), { frame_id: args.frame_id });
|
|
264
|
+
}
|
|
265
|
+
if (released === null || released === undefined) { released = item; }
|
|
266
|
+
released = IDC.concrete(released);
|
|
267
|
+
if (idcAnchorInfo(released) !== null) {
|
|
268
|
+
IDC.fail('invalid_state', 'InDesign did not release object ' + args.frame_id + '; it is still anchored.', { frame_id: args.frame_id, anchored: idcAnchorInfo(released) });
|
|
269
|
+
}
|
|
270
|
+
landing = IDC.landing(released);
|
|
271
|
+
try { boundsMm = idcItemBounds(doc, released); } catch (e1) { boundsMm = null; }
|
|
272
|
+
result = {
|
|
273
|
+
frame_id: Number(released.id),
|
|
274
|
+
previous_frame_id: Number(args.frame_id),
|
|
275
|
+
type: IDC.itemType(released),
|
|
276
|
+
was_anchored: info,
|
|
277
|
+
bounds_mm: boundsMm,
|
|
278
|
+
page_id: landing.page_id,
|
|
279
|
+
page_name: landing.page_name,
|
|
280
|
+
on_pasteboard: landing.on_pasteboard
|
|
281
|
+
};
|
|
282
|
+
if (Number(released.id) !== Number(args.frame_id)) {
|
|
283
|
+
ctx.warn('InDesign gave the released object a new id (' + Number(released.id) + '); use it from now on.');
|
|
284
|
+
}
|
|
285
|
+
ctx.changes = { modified_frame_ids: [Number(released.id)] };
|
|
286
|
+
return result;
|
|
287
|
+
});
|