layoutbridge-light 0.0.0-stage → 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 +22 -0
- package/LICENSE +26 -0
- package/README.de.md +338 -0
- package/README.md +325 -2
- package/THIRD-PARTY-NOTICES.md +2878 -0
- package/dist/src/mcp/catalog.js +126 -0
- package/dist/src/mcp/config.js +211 -0
- package/dist/src/mcp/dispatch.js +164 -0
- package/dist/src/mcp/epub-check.js +331 -0
- package/dist/src/mcp/epub-orientation.js +132 -0
- package/dist/src/mcp/license/free-tools.js +16 -0
- package/dist/src/mcp/license/gate.js +210 -0
- package/dist/src/mcp/license/index.js +107 -0
- package/dist/src/mcp/license/instance-name.js +57 -0
- package/dist/src/mcp/license/key-source.js +59 -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 +100 -0
- package/dist/src/mcp/license/polar-verifier.js +285 -0
- package/dist/src/mcp/license/product-ids.js +73 -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 +271 -0
- package/dist/src/mcp/product-info.js +54 -0
- package/dist/src/mcp/product.js +56 -0
- package/dist/src/mcp/server.js +253 -0
- package/dist/src/mcp/setup.js +680 -0
- package/dist/src/mcp/start.cjs +117 -0
- package/dist/src/mcp/tool-definition.js +2 -0
- package/dist/src/mcp/tools.js +2425 -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 +517 -0
- package/indesign/commands/22-document-setup.js +204 -0
- package/indesign/commands/23-save-package.js +258 -0
- package/indesign/commands/25-export.js +448 -0
- package/indesign/commands/26-export-image.js +202 -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 +837 -0
- package/indesign/commands/40-frames.js +851 -0
- package/indesign/commands/41-shapes.js +505 -0
- package/indesign/commands/42-groups.js +117 -0
- package/indesign/commands/43-layers.js +310 -0
- package/indesign/commands/44-effects.js +274 -0
- package/indesign/commands/45-frame-options.js +247 -0
- package/indesign/commands/47-anchored.js +331 -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 +1128 -0
- package/indesign/commands/62-embed.js +120 -0
- package/indesign/commands/69-placeholders.js +127 -0
- package/indesign/commands/70-text.js +675 -0
- package/indesign/commands/71-outlines.js +92 -0
- package/indesign/commands/72-place-text.js +476 -0
- package/indesign/commands/73-story-lock.js +157 -0
- package/indesign/commands/74-stories.js +121 -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 +452 -0
- package/indesign/commands/79-check-typography.js +341 -0
- package/indesign/commands/80-styles.js +1865 -0
- package/indesign/commands/81-composition.js +355 -0
- package/indesign/commands/82-object-styles.js +263 -0
- package/indesign/commands/83-drop-caps.js +87 -0
- package/indesign/commands/83-indents-tabs.js +264 -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 +212 -0
- package/indesign/commands/89-toc-index.js +945 -0
- package/indesign/commands/90-print-on-demand.js +495 -0
- package/indesign/commands/91-epub.js +546 -0
- package/indesign/interpreter.js +779 -0
- package/package.json +41 -4
- package/rules/typography-rules.json +31 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
/* Bereich G – Text lesen und schreiben. */
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Zeilenumbrueche im Parameter: ein echter Zeilenumbruch (LF, CRLF) wird zur
|
|
5
|
+
* Absatzmarke (CR, wie InDesign sie fuehrt). U+2028 bleibt ein weicher
|
|
6
|
+
* Zeilenumbruch, alles andere unveraendert (E-30).
|
|
7
|
+
*/
|
|
8
|
+
function idcNormaliseText(text) {
|
|
9
|
+
var s = String(text);
|
|
10
|
+
var out = '';
|
|
11
|
+
var i, ch;
|
|
12
|
+
for (i = 0; i < s.length; i++) {
|
|
13
|
+
ch = s.charAt(i);
|
|
14
|
+
if (ch === '\r') {
|
|
15
|
+
out += '\r';
|
|
16
|
+
if (i + 1 < s.length && s.charAt(i + 1) === '\n') { i += 1; }
|
|
17
|
+
} else if (ch === '\n') {
|
|
18
|
+
out += '\r';
|
|
19
|
+
} else {
|
|
20
|
+
out += ch;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Enumeratorname des letzten Zeichens (SpecialCharacters) in die Absatzende-Art. */
|
|
27
|
+
function idcBreakTypeFromEnum(name, fallback) {
|
|
28
|
+
if (name === 'COLUMN_BREAK') { return 'column'; }
|
|
29
|
+
if (name === 'FRAME_BREAK') { return 'frame'; }
|
|
30
|
+
if (name === 'PAGE_BREAK') { return 'page'; }
|
|
31
|
+
if (name === 'ODD_PAGE_BREAK') { return 'odd_page'; }
|
|
32
|
+
if (name === 'EVEN_PAGE_BREAK') { return 'even_page'; }
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Absatzende-Art am letzten Zeichen eines Absatzes. */
|
|
37
|
+
function idcBreakType(lastChar) {
|
|
38
|
+
var code = lastChar.length === 0 ? -1 : lastChar.charCodeAt(0);
|
|
39
|
+
if (code === 13) { return 'paragraph'; }
|
|
40
|
+
if (code === 14) { return 'column'; }
|
|
41
|
+
if (code === 15) { return 'frame'; }
|
|
42
|
+
if (code === 16) { return 'page'; }
|
|
43
|
+
if (code === 17) { return 'odd_page'; }
|
|
44
|
+
if (code === 18) { return 'even_page'; }
|
|
45
|
+
return 'none';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function idcStoryOf(frame) {
|
|
49
|
+
var story = null;
|
|
50
|
+
try { story = frame.parentStory; } catch (e) { story = null; }
|
|
51
|
+
if (story === null || story === undefined) {
|
|
52
|
+
IDC.fail('invalid_state', 'Text frame ' + Number(frame.id) + ' has no story.', { frame_id: Number(frame.id) });
|
|
53
|
+
}
|
|
54
|
+
return story;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function idcOverflows(frame) {
|
|
58
|
+
try { return frame.overflows === true; } catch (e) { return null; }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function idcParagraphStyleName(paragraph) {
|
|
62
|
+
try { return String(paragraph.appliedParagraphStyle.name); } catch (e) { return null; }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* ----------------------------------------------------------- get_frame_text */
|
|
66
|
+
|
|
67
|
+
IDC.register('get_frame_text', { needs_document: true, read_only: true, ruler: 'none' },
|
|
68
|
+
function (ctx) {
|
|
69
|
+
var args = ctx.args;
|
|
70
|
+
var doc = ctx.doc;
|
|
71
|
+
var found = idcTextFrameArg(doc, args, 'frame_id');
|
|
72
|
+
var frame = found.item;
|
|
73
|
+
var story = idcStoryOf(frame);
|
|
74
|
+
var paragraphs = [];
|
|
75
|
+
var storyLength = 0;
|
|
76
|
+
var i, p, text, length, last, breakType, position = 0, endExcl, frameStart = null, frameEnd = null, frameChars = null;
|
|
77
|
+
var onlyPortion = args.only_frame_portion === true;
|
|
78
|
+
var showPlaceholders = args.show_placeholders === true;
|
|
79
|
+
var maxChars = args.max_chars === undefined || args.max_chars === null ? null : args.max_chars;
|
|
80
|
+
var kept, used = 0, omitted = 0, truncated = false, entry, from, to;
|
|
81
|
+
var lockInfo = idcStoryLockInfo(story);
|
|
82
|
+
|
|
83
|
+
if (args.include_overset !== undefined) {
|
|
84
|
+
IDC.fail('invalid_argument', 'get_frame_text has no include_overset parameter; use only_frame_portion true for the part of the story in this frame.', null);
|
|
85
|
+
}
|
|
86
|
+
if (args.only_frame_portion !== undefined && args.only_frame_portion !== null && typeof args.only_frame_portion !== 'boolean') {
|
|
87
|
+
IDC.fail('invalid_argument', 'only_frame_portion must be true or false.', { only_frame_portion: args.only_frame_portion });
|
|
88
|
+
}
|
|
89
|
+
if (maxChars !== null && (typeof maxChars !== 'number' || maxChars < 1 || Math.floor(maxChars) !== maxChars)) {
|
|
90
|
+
IDC.fail('invalid_argument', 'max_chars must be a whole number of 1 or more.', { max_chars: maxChars });
|
|
91
|
+
}
|
|
92
|
+
try { storyLength = Number(story.characters.length); } catch (e0) { storyLength = 0; }
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
for (i = 0; i < story.paragraphs.length; i++) {
|
|
96
|
+
p = story.paragraphs.item(i);
|
|
97
|
+
text = '';
|
|
98
|
+
try { text = String(p.contents); } catch (e1) { text = ''; }
|
|
99
|
+
try { length = Number(p.characters.length); } catch (e2) { length = text.length; }
|
|
100
|
+
last = text.length > 0 ? text.charAt(text.length - 1) : '';
|
|
101
|
+
breakType = idcBreakType(last);
|
|
102
|
+
/*
|
|
103
|
+
* Live 05.09.2026: im Absatztext (String) erscheinen Spalten-, Rahmen-
|
|
104
|
+
* und Seitenumbruch als "\r"; erst das letzte Zeichen einzeln gelesen
|
|
105
|
+
* nennt den Enumerator (COLUMN_BREAK ...). Deshalb nachfassen.
|
|
106
|
+
*/
|
|
107
|
+
if (breakType === 'paragraph' && length > 0) {
|
|
108
|
+
try { breakType = idcBreakTypeFromEnum(String(p.characters.item(length - 1).contents), breakType); } catch (eBT) { /* bleibt */ }
|
|
109
|
+
}
|
|
110
|
+
endExcl = breakType === 'none' ? position + length : position + length - 1;
|
|
111
|
+
paragraphs.push({
|
|
112
|
+
index: i,
|
|
113
|
+
start_index: position,
|
|
114
|
+
end_index: endExcl,
|
|
115
|
+
end_index_incl_break: position + length,
|
|
116
|
+
paragraph_style: idcParagraphStyleName(p),
|
|
117
|
+
text: (function () { var t = breakType === 'none' ? text : text.substr(0, text.length - 1); return showPlaceholders ? idcShowPlaceholders(t) : t; })(),
|
|
118
|
+
is_empty: endExcl === position,
|
|
119
|
+
break_type: breakType
|
|
120
|
+
});
|
|
121
|
+
position += length;
|
|
122
|
+
}
|
|
123
|
+
} catch (e) {
|
|
124
|
+
IDC.fail('script_error', 'InDesign could not read the paragraphs of frame ' + args.frame_id + ': ' + String(e.message ? e.message : e),
|
|
125
|
+
{ frame_id: args.frame_id, paragraphs_read: paragraphs.length });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Anteil dieses Rahmens an der Story (verkettete Rahmen). */
|
|
129
|
+
try {
|
|
130
|
+
var portion = frame.texts.item(0);
|
|
131
|
+
frameChars = Number(portion.characters.length);
|
|
132
|
+
if (frameChars > 0) {
|
|
133
|
+
frameStart = Number(portion.characters.item(0).index);
|
|
134
|
+
frameEnd = frameStart + frameChars;
|
|
135
|
+
} else {
|
|
136
|
+
/* Leerer Rahmen am Ende der Kette: Anteil 0, Indizes ohne Aussage. */
|
|
137
|
+
frameStart = null; frameEnd = null;
|
|
138
|
+
}
|
|
139
|
+
} catch (e3) { frameStart = null; frameEnd = null; frameChars = null; }
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
* only_frame_portion: nur Absaetze, die diesen Rahmen beruehren; Text an
|
|
143
|
+
* den Rahmengrenzen beschnitten (Fund 5, Hefttest). max_chars: Textbudget
|
|
144
|
+
* ueber alle gelieferten Absaetze, danach nur noch Zaehlung.
|
|
145
|
+
*/
|
|
146
|
+
if (onlyPortion) {
|
|
147
|
+
kept = [];
|
|
148
|
+
if (frameStart !== null) {
|
|
149
|
+
for (i = 0; i < paragraphs.length; i++) {
|
|
150
|
+
entry = paragraphs[i];
|
|
151
|
+
if (entry.end_index_incl_break <= frameStart || entry.start_index >= frameEnd) { continue; }
|
|
152
|
+
from = Math.max(entry.start_index, frameStart);
|
|
153
|
+
to = Math.min(entry.end_index, frameEnd);
|
|
154
|
+
entry.clipped_start = from > entry.start_index;
|
|
155
|
+
entry.clipped_end = to < entry.end_index;
|
|
156
|
+
if (entry.clipped_start || entry.clipped_end) {
|
|
157
|
+
entry.text = entry.text.substr(from - entry.start_index, Math.max(0, to - from));
|
|
158
|
+
}
|
|
159
|
+
kept.push(entry);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
paragraphs = kept;
|
|
163
|
+
}
|
|
164
|
+
if (maxChars !== null) {
|
|
165
|
+
kept = [];
|
|
166
|
+
for (i = 0; i < paragraphs.length; i++) {
|
|
167
|
+
entry = paragraphs[i];
|
|
168
|
+
if (used >= maxChars) { omitted += 1; truncated = true; continue; }
|
|
169
|
+
if (used + entry.text.length > maxChars) {
|
|
170
|
+
entry.text = entry.text.substr(0, maxChars - used);
|
|
171
|
+
entry.clipped_end = true;
|
|
172
|
+
truncated = true;
|
|
173
|
+
}
|
|
174
|
+
used += entry.text.length;
|
|
175
|
+
kept.push(entry);
|
|
176
|
+
}
|
|
177
|
+
paragraphs = kept;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
frame_id: Number(frame.id),
|
|
182
|
+
story_id: (function () { try { return Number(story.id); } catch (e4) { return null; } })(),
|
|
183
|
+
story_length: storyLength,
|
|
184
|
+
paragraphs: paragraphs,
|
|
185
|
+
paragraph_count: paragraphs.length,
|
|
186
|
+
only_frame_portion: onlyPortion,
|
|
187
|
+
show_placeholders: showPlaceholders,
|
|
188
|
+
paragraphs_omitted: omitted,
|
|
189
|
+
truncated: truncated,
|
|
190
|
+
overset: idcOverflows(frame),
|
|
191
|
+
threaded: idcIsThreaded(frame),
|
|
192
|
+
frame_start_index: frameStart,
|
|
193
|
+
frame_end_index: frameEnd,
|
|
194
|
+
frame_character_count: frameChars,
|
|
195
|
+
lock_state: lockInfo.lock_state,
|
|
196
|
+
managed_file: lockInfo.managed_file
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
/* ----------------------------------------------------------------- set_text */
|
|
201
|
+
|
|
202
|
+
IDC.register('set_text', { needs_document: true, read_only: false, ruler: 'none' },
|
|
203
|
+
function (ctx) {
|
|
204
|
+
var args = ctx.args;
|
|
205
|
+
var doc = ctx.doc;
|
|
206
|
+
var found = idcTextFrameArg(doc, args, 'frame_id');
|
|
207
|
+
var frame = found.item;
|
|
208
|
+
var story = idcStoryOf(frame);
|
|
209
|
+
var text, before = 0, after = 0;
|
|
210
|
+
|
|
211
|
+
if (typeof args.text !== 'string') {
|
|
212
|
+
IDC.fail('invalid_argument', 'text is required (a string; "" empties the frame).', null);
|
|
213
|
+
}
|
|
214
|
+
/* A-8.8: erst Absatzmarken normalisieren, dann Platzhalter – {{line_break}} bleibt so ein Zeilenumbruch. */
|
|
215
|
+
var expansion = idcExpandPlaceholders(idcNormaliseText(args.text), args.placeholders !== false);
|
|
216
|
+
var split = idcSplitBreaks(expansion.text);
|
|
217
|
+
text = split.plain;
|
|
218
|
+
idcPlaceholderWarnings(ctx, expansion);
|
|
219
|
+
idcRejectStoryLocked(story, Number(frame.id), 'set_text');
|
|
220
|
+
try { before = Number(story.characters.length); } catch (e0) { before = 0; }
|
|
221
|
+
|
|
222
|
+
/* Wirklich ersetzen: die ganze Story (0 … Laenge), nicht anhaengen. */
|
|
223
|
+
try {
|
|
224
|
+
story.contents = text;
|
|
225
|
+
} catch (e) {
|
|
226
|
+
try {
|
|
227
|
+
if (before > 0) { story.characters.itemByRange(0, before - 1).contents = text; }
|
|
228
|
+
else { story.insertionPoints.item(0).contents = text; }
|
|
229
|
+
} catch (e2) {
|
|
230
|
+
IDC.fail('script_error', 'InDesign could not set the text of frame ' + args.frame_id + ': ' + String(e.message ? e.message : e) +
|
|
231
|
+
' / ' + String(e2.message ? e2.message : e2), { frame_id: args.frame_id });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
try { idcInsertBreaks(story, 0, split.breaks); } catch (eB) {
|
|
235
|
+
if (eB && eB.isIdcError) { throw eB; }
|
|
236
|
+
ctx.warn('Column/frame/page breaks could not be inserted: ' + String(eB.message ? eB.message : eB));
|
|
237
|
+
}
|
|
238
|
+
text = expansion.text;
|
|
239
|
+
try { after = Number(story.characters.length); } catch (e3) { after = null; }
|
|
240
|
+
if (after !== null && after !== text.length) {
|
|
241
|
+
ctx.warn('The story reads ' + after + ' characters after writing ' + text.length + ' – InDesign may have converted or dropped characters.');
|
|
242
|
+
}
|
|
243
|
+
if (idcIsThreaded(frame)) {
|
|
244
|
+
ctx.warn('The frame is threaded (verkettet); the whole story across all its frames was replaced.');
|
|
245
|
+
}
|
|
246
|
+
ctx.changes = { modified_frame_ids: [Number(frame.id)] };
|
|
247
|
+
return {
|
|
248
|
+
frame_id: Number(frame.id),
|
|
249
|
+
character_count: after,
|
|
250
|
+
previous_character_count: before,
|
|
251
|
+
overset: idcOverflows(frame),
|
|
252
|
+
story_id: (function () { try { return Number(story.id); } catch (e4) { return null; } })(),
|
|
253
|
+
placeholders_replaced: expansion.replaced,
|
|
254
|
+
placeholders_unknown: expansion.unknown
|
|
255
|
+
};
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
/* -------------------------------------------------------- set_text_in_range */
|
|
259
|
+
|
|
260
|
+
/*
|
|
261
|
+
* Sitzung 24 (Befund aus dem Praxiseinsatz): contents = auf einem Bereich loescht
|
|
262
|
+
* ihn und setzt am Einfuegepunkt neu ein. Der Einfuegepunkt traegt das
|
|
263
|
+
* Format des Zeichens davor – beginnt der Bereich an einem Absatzanfang, ist
|
|
264
|
+
* das die Absatzmarke des vorigen Absatzes, und der neue Text erbt dessen
|
|
265
|
+
* Format. keep_format_of:
|
|
266
|
+
* start (Vorgabe) neuen Text hinter das erste ersetzte Zeichen setzen –
|
|
267
|
+
* er erbt dessen Format –, dann die alten Zeichen entfernen;
|
|
268
|
+
* before bisheriger Weg (InDesigns eigene Wahl, das Zeichen davor);
|
|
269
|
+
* none bisheriger Weg, danach Zeichenformat [None] und keine lokalen
|
|
270
|
+
* Zeichenabweichungen im neuen Text (Format des Absatzformats).
|
|
271
|
+
*/
|
|
272
|
+
function idcKeepFormatOf(args) {
|
|
273
|
+
var mode = args.keep_format_of;
|
|
274
|
+
if (mode === undefined || mode === null) { return 'start'; }
|
|
275
|
+
if (mode !== 'start' && mode !== 'before' && mode !== 'none') {
|
|
276
|
+
IDC.fail('invalid_argument', 'keep_format_of must be "start", "before" or "none".', { keep_format_of: mode });
|
|
277
|
+
}
|
|
278
|
+
return mode;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/*
|
|
282
|
+
* Bereich [start, end) durch text ersetzen, absatzweise (Nacharbeit 2 zu
|
|
283
|
+
* Sitzung 24, Lauf S24). Vorbild je ersetztem Absatz ist sein erstes Zeichen
|
|
284
|
+
* im Bereich: der Bereichsanfang, dann jede Stelle hinter einer Absatzmarke
|
|
285
|
+
* im Bereich. Der neue Text wird an den Absatzmarken geteilt; Teil 0 (bis
|
|
286
|
+
* einschliesslich der ersten neuen Absatzmarke) bekommt das Format des
|
|
287
|
+
* ersten ersetzten Zeichens, Teil i das des i-ten ersetzten Absatzes, jeder
|
|
288
|
+
* weitere Teil das des letzten ersetzten Absatzes.
|
|
289
|
+
*
|
|
290
|
+
* Jeder Teil wird hinter sein Vorbild eingefuegt und erbt so dessen Format.
|
|
291
|
+
* Ist das Vorbild eine Absatzmarke, liegt der Einfuegepunkt dahinter schon
|
|
292
|
+
* im naechsten Absatz (Lauf S24: 9 statt 20 pt) – dann vor ihr einfuegen,
|
|
293
|
+
* also im Absatz, dessen Marke ersetzt wird. Danach die alten Zeichen
|
|
294
|
+
* entfernen (von hinten) und jedem neuen Absatz das Absatzformat seines
|
|
295
|
+
* Vorbilds zuweisen, wenn InDesign beim Verschmelzen ein anderes gewaehlt
|
|
296
|
+
* hat (lokale Abweichungen bleiben).
|
|
297
|
+
*/
|
|
298
|
+
function idcReplaceKeepingStart(story, start, end, text) {
|
|
299
|
+
var old = '', anchors = [], segments = [], groups = [], i, k, c, shift, ip, piece, first, last, runEnd, offset, para, style;
|
|
300
|
+
try { old = String(story.characters.itemByRange(start, end - 1).contents); } catch (e0) { old = ''; }
|
|
301
|
+
if (old.length !== end - start) {
|
|
302
|
+
old = '';
|
|
303
|
+
for (i = start; i < end; i++) { old += String(story.characters.item(i).contents); }
|
|
304
|
+
}
|
|
305
|
+
anchors.push(start);
|
|
306
|
+
for (i = 0; i < old.length - 1; i++) {
|
|
307
|
+
if (old.charAt(i) === '\r') { anchors.push(start + i + 1); }
|
|
308
|
+
}
|
|
309
|
+
/* neuer Text in Teile bis einschliesslich jeder Absatzmarke */
|
|
310
|
+
piece = '';
|
|
311
|
+
for (i = 0; i < text.length; i++) {
|
|
312
|
+
piece += text.charAt(i);
|
|
313
|
+
if (text.charAt(i) === '\r') { segments.push(piece); piece = ''; }
|
|
314
|
+
}
|
|
315
|
+
if (piece.length > 0 || segments.length === 0) { segments.push(piece); }
|
|
316
|
+
/* Gruppen je Vorbild: Text, Einfuegepunkt, Absatzformat des Vorbilds, Anfang jedes Teils im neuen Text */
|
|
317
|
+
for (k = 0; k < anchors.length; k++) {
|
|
318
|
+
groups.push({ anchor: anchors[k], text: '', parts: [], style: null, ip: 0 });
|
|
319
|
+
}
|
|
320
|
+
offset = 0;
|
|
321
|
+
for (i = 0; i < segments.length; i++) {
|
|
322
|
+
k = i < anchors.length ? i : anchors.length - 1;
|
|
323
|
+
groups[k].parts.push(offset);
|
|
324
|
+
groups[k].text += segments[i];
|
|
325
|
+
offset += segments[i].length;
|
|
326
|
+
}
|
|
327
|
+
for (k = 0; k < groups.length; k++) {
|
|
328
|
+
c = old.charAt(groups[k].anchor - start);
|
|
329
|
+
groups[k].ip = c === '\r' ? groups[k].anchor : groups[k].anchor + 1;
|
|
330
|
+
try { groups[k].style = story.characters.item(groups[k].anchor).appliedParagraphStyle; } catch (eS) { groups[k].style = null; }
|
|
331
|
+
}
|
|
332
|
+
/* einfuegen von hinten, damit die vorderen Stellen gelten */
|
|
333
|
+
for (k = groups.length - 1; k >= 0; k--) {
|
|
334
|
+
if (groups[k].text.length > 0) { story.insertionPoints.item(groups[k].ip).contents = groups[k].text; }
|
|
335
|
+
}
|
|
336
|
+
/* alte Zeichen: neue Lage = alte + Laenge aller Teile, die davor eingefuegt wurden; zusammenhaengend von hinten entfernen */
|
|
337
|
+
runEnd = -1;
|
|
338
|
+
last = -1;
|
|
339
|
+
for (i = end - 1; i >= start - 1; i--) {
|
|
340
|
+
ip = -1;
|
|
341
|
+
if (i >= start) {
|
|
342
|
+
shift = 0;
|
|
343
|
+
for (k = 0; k < groups.length; k++) {
|
|
344
|
+
if (groups[k].ip <= i) { shift += groups[k].text.length; }
|
|
345
|
+
}
|
|
346
|
+
ip = i + shift;
|
|
347
|
+
}
|
|
348
|
+
if (ip >= 0 && runEnd >= 0 && ip === last - 1) {
|
|
349
|
+
last = ip;
|
|
350
|
+
} else {
|
|
351
|
+
if (runEnd >= 0) { story.characters.itemByRange(last, runEnd).remove(); }
|
|
352
|
+
runEnd = ip;
|
|
353
|
+
last = ip;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/* Absatzformat je neuem Teil */
|
|
357
|
+
for (k = 0; k < groups.length; k++) {
|
|
358
|
+
if (groups[k].style === null) { continue; }
|
|
359
|
+
for (i = 0; i < groups[k].parts.length; i++) {
|
|
360
|
+
first = start + groups[k].parts[i];
|
|
361
|
+
if (first >= start + text.length) { continue; }
|
|
362
|
+
try {
|
|
363
|
+
para = story.characters.item(first).paragraphs.item(0);
|
|
364
|
+
style = para.appliedParagraphStyle;
|
|
365
|
+
if (String(style.name) !== String(groups[k].style.name)) {
|
|
366
|
+
try { para.applyParagraphStyle(groups[k].style, false); } catch (eA) { para.appliedParagraphStyle = groups[k].style; }
|
|
367
|
+
}
|
|
368
|
+
} catch (eP) { /* Absatzformat nicht lesbar: InDesigns Wahl bleibt */ }
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* Zeichenformat [None] und keine lokalen Zeichenabweichungen im Bereich [start, start + n). */
|
|
374
|
+
function idcClearCharacterFormat(doc, story, start, n) {
|
|
375
|
+
var range, none;
|
|
376
|
+
if (n < 1) { return; }
|
|
377
|
+
range = story.characters.itemByRange(start, start + n - 1);
|
|
378
|
+
none = idcNoneCharacterStyle(doc);
|
|
379
|
+
if (none !== null) {
|
|
380
|
+
try { range.applyCharacterStyle(none); } catch (e1) { range.appliedCharacterStyle = none; }
|
|
381
|
+
}
|
|
382
|
+
if (typeof OverrideType !== 'undefined') { range.clearOverrides(OverrideType.CHARACTER_ONLY); }
|
|
383
|
+
else { range.clearOverrides(); }
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
IDC.register('set_text_in_range', { needs_document: true, read_only: false, ruler: 'none' },
|
|
387
|
+
function (ctx) {
|
|
388
|
+
var args = ctx.args;
|
|
389
|
+
var doc = ctx.doc;
|
|
390
|
+
var found = idcTextFrameArg(doc, args, 'frame_id');
|
|
391
|
+
var frame = found.item;
|
|
392
|
+
var story = idcStoryOf(frame);
|
|
393
|
+
var start = args.start_index;
|
|
394
|
+
var end = args.end_index;
|
|
395
|
+
var text, length = 0, replaced, after;
|
|
396
|
+
var keepFormat = idcKeepFormatOf(args);
|
|
397
|
+
|
|
398
|
+
if (typeof start !== 'number' || Math.floor(start) !== start || start < 0) {
|
|
399
|
+
IDC.fail('invalid_argument', 'start_index must be a whole number of 0 or more (inclusive).', { start_index: start });
|
|
400
|
+
}
|
|
401
|
+
if (typeof end !== 'number' || Math.floor(end) !== end || end < start) {
|
|
402
|
+
IDC.fail('invalid_argument', 'end_index must be a whole number not smaller than start_index (exclusive).', { start_index: start, end_index: end });
|
|
403
|
+
}
|
|
404
|
+
if (typeof args.text !== 'string') {
|
|
405
|
+
IDC.fail('invalid_argument', 'text is required (a string; "" deletes the range).', null);
|
|
406
|
+
}
|
|
407
|
+
var expansion = idcExpandPlaceholders(idcNormaliseText(args.text), args.placeholders !== false);
|
|
408
|
+
var split = idcSplitBreaks(expansion.text);
|
|
409
|
+
text = split.plain;
|
|
410
|
+
idcPlaceholderWarnings(ctx, expansion);
|
|
411
|
+
try { length = Number(story.characters.length); } catch (e0) { length = 0; }
|
|
412
|
+
if (end > length) {
|
|
413
|
+
IDC.fail('invalid_argument', 'end_index ' + end + ' exceeds the story length ' + length + '.', { end_index: end, story_length: length });
|
|
414
|
+
}
|
|
415
|
+
replaced = end - start;
|
|
416
|
+
idcRejectStoryLocked(story, Number(frame.id), 'set_text_in_range');
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
if (replaced === 0) {
|
|
420
|
+
if (text.length > 0) { story.insertionPoints.item(start).contents = text; }
|
|
421
|
+
} else if (text.length === 0) {
|
|
422
|
+
story.characters.itemByRange(start, end - 1).remove();
|
|
423
|
+
} else if (keepFormat === 'start') {
|
|
424
|
+
idcReplaceKeepingStart(story, start, end, text);
|
|
425
|
+
} else {
|
|
426
|
+
story.characters.itemByRange(start, end - 1).contents = text;
|
|
427
|
+
}
|
|
428
|
+
} catch (e) {
|
|
429
|
+
IDC.fail('script_error', 'InDesign could not change characters ' + start + '–' + end + ' of frame ' + args.frame_id + ': ' +
|
|
430
|
+
String(e.message ? e.message : e), { frame_id: args.frame_id, start_index: start, end_index: end });
|
|
431
|
+
}
|
|
432
|
+
try { idcInsertBreaks(story, start, split.breaks); } catch (eB) {
|
|
433
|
+
if (eB && eB.isIdcError) { throw eB; }
|
|
434
|
+
ctx.warn('Column/frame/page breaks could not be inserted: ' + String(eB.message ? eB.message : eB));
|
|
435
|
+
}
|
|
436
|
+
text = expansion.text;
|
|
437
|
+
if (keepFormat === 'none' && text.length > 0) {
|
|
438
|
+
try { idcClearCharacterFormat(doc, story, start, text.length); } catch (eN) {
|
|
439
|
+
ctx.warn('The new text was written, but its character formatting could not be cleared: ' + String(eN.message ? eN.message : eN));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
try { after = Number(story.characters.length); } catch (e1) { after = null; }
|
|
443
|
+
if (after !== null && after !== length - replaced + text.length) {
|
|
444
|
+
ctx.warn('The story reads ' + after + ' characters, expected ' + (length - replaced + text.length) + '.');
|
|
445
|
+
}
|
|
446
|
+
ctx.changes = { modified_frame_ids: [Number(frame.id)] };
|
|
447
|
+
return {
|
|
448
|
+
frame_id: Number(frame.id),
|
|
449
|
+
replaced_chars: replaced,
|
|
450
|
+
inserted_chars: text.length,
|
|
451
|
+
story_length: after,
|
|
452
|
+
keep_format_of: keepFormat,
|
|
453
|
+
overset: idcOverflows(frame),
|
|
454
|
+
placeholders_replaced: expansion.replaced,
|
|
455
|
+
placeholders_unknown: expansion.unknown
|
|
456
|
+
};
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
/* ------------------------------------------------------------- find_replace */
|
|
460
|
+
|
|
461
|
+
function idcSetFindOptions(options, args) {
|
|
462
|
+
try { options.includeMasterPages = args.include_master_pages === true; } catch (e1) { /* nicht vorhanden */ }
|
|
463
|
+
try { options.includeHiddenLayers = args.include_hidden_layers === true; } catch (e2) { /* nicht vorhanden */ }
|
|
464
|
+
try { options.includeLockedLayersForFind = args.include_locked_layers === true; } catch (e3) { /* nicht vorhanden */ }
|
|
465
|
+
try { options.includeLockedStoriesForFind = args.include_locked_layers === true; } catch (e4) { /* nicht vorhanden */ }
|
|
466
|
+
try { options.includeFootnotes = true; } catch (e5) { /* nicht vorhanden */ }
|
|
467
|
+
try { options.caseSensitive = args.case_sensitive === true; } catch (e6) { /* GREP kennt das nicht */ }
|
|
468
|
+
try { options.wholeWord = args.whole_word === true; } catch (e7) { /* GREP kennt das nicht */ }
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/* Fundstelle beschreiben: Rahmen, Seite, Index, Text. */
|
|
472
|
+
function idcDescribeMatch(doc, textObject) {
|
|
473
|
+
var entry = { frame_id: null, page_id: null, page_name: '', index: null, text: null, story_id: null };
|
|
474
|
+
var frames, frame, landing;
|
|
475
|
+
try { entry.index = Number(textObject.index); } catch (e0) { entry.index = null; }
|
|
476
|
+
try { entry.text = String(textObject.contents); } catch (e1) { entry.text = null; }
|
|
477
|
+
try { entry.story_id = Number(textObject.parentStory.id); } catch (e2) { entry.story_id = null; }
|
|
478
|
+
try {
|
|
479
|
+
frames = textObject.parentTextFrames;
|
|
480
|
+
if (frames && frames.length > 0) {
|
|
481
|
+
frame = IDC.concrete(frames[0]);
|
|
482
|
+
entry.frame_id = Number(frame.id);
|
|
483
|
+
landing = IDC.landing(frame);
|
|
484
|
+
entry.page_id = landing.page_id;
|
|
485
|
+
entry.page_name = landing.page_name;
|
|
486
|
+
}
|
|
487
|
+
} catch (e3) { /* Text ohne Rahmen (Uebersatz) */ }
|
|
488
|
+
return entry;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/*
|
|
492
|
+
* Sitzung 38 (A-23, A-25 Nr. 2 und 4): Fundstellen nach Story ordnen und
|
|
493
|
+
* gesperrte Stories herausnehmen. Liefert { open: [Fundstellen], stories:
|
|
494
|
+
* [freie Stories in Reihenfolge], skipped: [Sperrangaben mit matches] }.
|
|
495
|
+
*/
|
|
496
|
+
function idcSplitMatchesByLock(found) {
|
|
497
|
+
var out = { open: [], stories: [], skipped: [] };
|
|
498
|
+
var seen = {}, i, story, id, info, entry, frames;
|
|
499
|
+
for (i = 0; i < found.length; i++) {
|
|
500
|
+
story = null;
|
|
501
|
+
try { story = found[i].parentStory; } catch (e0) { story = null; }
|
|
502
|
+
id = null;
|
|
503
|
+
try { id = Number(story.id); } catch (e1) { id = null; }
|
|
504
|
+
if (story === null || story === undefined || id === null) { out.open.push(found[i]); continue; }
|
|
505
|
+
if (!IDC.hasOwn(seen, String(id))) {
|
|
506
|
+
info = idcStoryLockInfo(story);
|
|
507
|
+
entry = { story: story, info: info, skipped: null };
|
|
508
|
+
if (info.write_locked) {
|
|
509
|
+
entry.skipped = { story_id: id, frame_id: null, lock_state: info.lock_state, managed_file: info.managed_file, matches: 0 };
|
|
510
|
+
try {
|
|
511
|
+
frames = story.textContainers;
|
|
512
|
+
if (frames && frames.length > 0) { entry.skipped.frame_id = Number(IDC.concrete(frames[0]).id); }
|
|
513
|
+
} catch (e2) { /* ohne Rahmen */ }
|
|
514
|
+
out.skipped.push(entry.skipped);
|
|
515
|
+
} else {
|
|
516
|
+
out.stories.push(story);
|
|
517
|
+
}
|
|
518
|
+
seen[String(id)] = entry;
|
|
519
|
+
}
|
|
520
|
+
entry = seen[String(id)];
|
|
521
|
+
if (entry.skipped !== null) { entry.skipped.matches += 1; } else { out.open.push(found[i]); }
|
|
522
|
+
}
|
|
523
|
+
return out;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/* Rahmen-IDs der geaenderten Stellen (A-25 Nr. 2), jede einmal, in Fundreihenfolge. */
|
|
527
|
+
function idcFrameIdsOfMatches(found) {
|
|
528
|
+
var ids = [], seen = {}, i, frames, id;
|
|
529
|
+
for (i = 0; i < found.length; i++) {
|
|
530
|
+
try {
|
|
531
|
+
frames = found[i].parentTextFrames;
|
|
532
|
+
if (frames && frames.length > 0) {
|
|
533
|
+
id = Number(IDC.concrete(frames[0]).id);
|
|
534
|
+
if (!IDC.hasOwn(seen, String(id))) { seen[String(id)] = true; ids.push(id); }
|
|
535
|
+
}
|
|
536
|
+
} catch (e) { /* Uebersatz: kein Rahmen */ }
|
|
537
|
+
}
|
|
538
|
+
return ids;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/*
|
|
542
|
+
* Ersetzen in einer freien Story: Story.changeText/changeGrep, sonst ueber
|
|
543
|
+
* ihren Text (texts.item(0)) wie im Rahmenbereich. Live zu pruefen (Testplan
|
|
544
|
+
* Sitzung 38): nur dieser Weg laeuft, wenn gesperrte Fundstellen dabei sind.
|
|
545
|
+
*/
|
|
546
|
+
function idcChangeInStory(story, grep) {
|
|
547
|
+
var text = null;
|
|
548
|
+
if (typeof story.changeText === 'function') { return grep ? story.changeGrep() : story.changeText(); }
|
|
549
|
+
try { text = story.texts.item(0); } catch (e0) { text = null; }
|
|
550
|
+
if (text === null || text === undefined) {
|
|
551
|
+
IDC.fail('script_error', 'This story offers no find/change.', null);
|
|
552
|
+
}
|
|
553
|
+
return grep ? text.changeGrep() : text.changeText();
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
IDC.register('find_replace', { needs_document: true, read_only: false, ruler: 'none' },
|
|
557
|
+
function (ctx) {
|
|
558
|
+
var args = ctx.args;
|
|
559
|
+
var doc = ctx.doc;
|
|
560
|
+
var mode = args.mode === undefined || args.mode === null ? 'literal' : args.mode;
|
|
561
|
+
var scope = args.scope === undefined || args.scope === null ? 'document' : args.scope;
|
|
562
|
+
var dryRun = args.dry_run === true;
|
|
563
|
+
var maxMatches = 200;
|
|
564
|
+
var target, frame, found, i, matches = [], count = 0, prefsFind, prefsChange, options;
|
|
565
|
+
var split = { open: [], stories: [], skipped: [] }, changed = [], part, j, skippedMatches = 0, lockedInScope = [], unlisted = 0, frameLock;
|
|
566
|
+
|
|
567
|
+
if (typeof args.find !== 'string' || args.find === '') {
|
|
568
|
+
IDC.fail('invalid_argument', 'find is required and must not be empty.', null);
|
|
569
|
+
}
|
|
570
|
+
if (!dryRun && typeof args.replace !== 'string') {
|
|
571
|
+
IDC.fail('invalid_argument', 'replace is required (a string; "" deletes the matches). Use dry_run true to only count.', null);
|
|
572
|
+
}
|
|
573
|
+
if (mode !== 'literal' && mode !== 'grep') {
|
|
574
|
+
IDC.fail('invalid_argument', 'mode must be literal or grep.', { mode: mode });
|
|
575
|
+
}
|
|
576
|
+
if (scope !== 'document' && scope !== 'frame') {
|
|
577
|
+
IDC.fail('invalid_argument', 'scope must be document or frame.', { scope: scope });
|
|
578
|
+
}
|
|
579
|
+
if (scope === 'frame') {
|
|
580
|
+
frame = idcTextFrameArg(doc, args, 'frame_id').item;
|
|
581
|
+
try { target = frame.texts.item(0); } catch (e0) { target = null; }
|
|
582
|
+
if (target === null || target === undefined) { target = idcStoryOf(frame); }
|
|
583
|
+
} else {
|
|
584
|
+
target = doc;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if (mode === 'grep') {
|
|
588
|
+
prefsFind = 'findGrepPreferences';
|
|
589
|
+
prefsChange = 'changeGrepPreferences';
|
|
590
|
+
options = app.findChangeGrepOptions;
|
|
591
|
+
} else {
|
|
592
|
+
prefsFind = 'findTextPreferences';
|
|
593
|
+
prefsChange = 'changeTextPreferences';
|
|
594
|
+
options = app.findChangeTextOptions;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
try {
|
|
598
|
+
app[prefsFind] = NothingEnum.NOTHING;
|
|
599
|
+
app[prefsChange] = NothingEnum.NOTHING;
|
|
600
|
+
idcSetFindOptions(options, args);
|
|
601
|
+
app[prefsFind].findWhat = args.find;
|
|
602
|
+
if (!dryRun) { app[prefsChange].changeTo = args.replace; }
|
|
603
|
+
|
|
604
|
+
/*
|
|
605
|
+
* Erst suchen, dann nur in freien Stories ersetzen: gesperrte Stories
|
|
606
|
+
* (A-23) aendert InDesign im Layout, die Redaktionsdatei bliebe alt –
|
|
607
|
+
* oder es ersetzt still nichts (A-25 Nr. 4). Ohne gesperrte Fundstellen
|
|
608
|
+
* bleibt der Lauf wie bisher ein einziger changeText/changeGrep.
|
|
609
|
+
*/
|
|
610
|
+
found = mode === 'grep' ? target.findGrep() : target.findText();
|
|
611
|
+
split = idcSplitMatchesByLock(found);
|
|
612
|
+
if (dryRun) {
|
|
613
|
+
count = split.open.length;
|
|
614
|
+
for (i = 0; i < split.open.length && i < maxMatches; i++) { matches.push(idcDescribeMatch(doc, split.open[i])); }
|
|
615
|
+
if (split.open.length > maxMatches) { ctx.warn('Only the first ' + maxMatches + ' of ' + split.open.length + ' matches are listed.'); }
|
|
616
|
+
} else if (split.skipped.length === 0) {
|
|
617
|
+
changed = mode === 'grep' ? target.changeGrep() : target.changeText();
|
|
618
|
+
count = changed.length;
|
|
619
|
+
} else {
|
|
620
|
+
for (i = 0; i < split.stories.length; i++) {
|
|
621
|
+
part = idcChangeInStory(split.stories[i], mode === 'grep');
|
|
622
|
+
for (j = 0; j < part.length; j++) { changed.push(part[j]); }
|
|
623
|
+
}
|
|
624
|
+
count = changed.length;
|
|
625
|
+
}
|
|
626
|
+
} catch (e) {
|
|
627
|
+
IDC.fail('script_error', 'InDesign could not run find/change (' + mode + '): ' + String(e.message ? e.message : e),
|
|
628
|
+
{ find: args.find, mode: mode, scope: scope });
|
|
629
|
+
} finally {
|
|
630
|
+
try { app[prefsFind] = NothingEnum.NOTHING; } catch (er1) { ctx.warn('Could not reset the find preferences.'); }
|
|
631
|
+
try { app[prefsChange] = NothingEnum.NOTHING; } catch (er2) { ctx.warn('Could not reset the change preferences.'); }
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
if (mode === 'literal' && / /.test(args.find)) {
|
|
635
|
+
ctx.warn('The search text contains a non-breaking space (U+00A0); literal search does not find it reliably – use mode grep with ~S.');
|
|
636
|
+
}
|
|
637
|
+
for (i = 0; i < split.skipped.length; i++) { skippedMatches += split.skipped[i].matches; }
|
|
638
|
+
if (split.skipped.length > 0) {
|
|
639
|
+
ctx.warn(skippedMatches + ' match(es) in ' + split.skipped.length + ' locked story/stories were ' + (dryRun ? 'left out of the count' : 'not replaced') +
|
|
640
|
+
' (see skipped_locked). Check the story out in the editorial system or in InCopy first.');
|
|
641
|
+
}
|
|
642
|
+
if (args.include_locked_layers !== true) {
|
|
643
|
+
/* Ohne include_locked_layers sucht InDesign gesperrte Stories nicht ab: darauf hinweisen. */
|
|
644
|
+
if (scope === 'frame') {
|
|
645
|
+
frameLock = idcStoryLockInfo(idcStoryOf(frame));
|
|
646
|
+
if (frameLock.write_locked) { lockedInScope.push(frameLock); }
|
|
647
|
+
} else {
|
|
648
|
+
lockedInScope = idcWriteLockedStories(doc);
|
|
649
|
+
}
|
|
650
|
+
for (i = 0; i < lockedInScope.length; i++) {
|
|
651
|
+
unlisted += 1;
|
|
652
|
+
for (j = 0; j < split.skipped.length; j++) {
|
|
653
|
+
if (split.skipped[j].story_id === lockedInScope[i].story_id) { unlisted -= 1; break; }
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
if (unlisted > 0) {
|
|
657
|
+
ctx.warn(unlisted + ' locked story/stories ' + (scope === 'frame' ? '(this frame) ' : '') + 'were not searched and are never changed by find_replace; include_locked_layers true lists their matches in skipped_locked.');
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
if (!dryRun && count > 0) { ctx.changes = { replacements: count, modified_frame_ids: scope === 'frame' ? [Number(frame.id)] : idcFrameIdsOfMatches(changed) }; }
|
|
661
|
+
var out = {
|
|
662
|
+
replacements: dryRun ? 0 : count,
|
|
663
|
+
matches_found: count,
|
|
664
|
+
dry_run: dryRun,
|
|
665
|
+
scope: scope,
|
|
666
|
+
mode: mode,
|
|
667
|
+
frame_id: scope === 'frame' ? Number(frame.id) : null,
|
|
668
|
+
master_pages_included: args.include_master_pages === true,
|
|
669
|
+
hidden_layers_included: args.include_hidden_layers === true,
|
|
670
|
+
locked_layers_included: args.include_locked_layers === true,
|
|
671
|
+
skipped_locked: split.skipped
|
|
672
|
+
};
|
|
673
|
+
if (dryRun) { out.matches = matches; }
|
|
674
|
+
return out;
|
|
675
|
+
});
|