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.
Files changed (88) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +26 -0
  3. package/README.de.md +338 -0
  4. package/README.md +325 -2
  5. package/THIRD-PARTY-NOTICES.md +2878 -0
  6. package/dist/src/mcp/catalog.js +126 -0
  7. package/dist/src/mcp/config.js +211 -0
  8. package/dist/src/mcp/dispatch.js +164 -0
  9. package/dist/src/mcp/epub-check.js +331 -0
  10. package/dist/src/mcp/epub-orientation.js +132 -0
  11. package/dist/src/mcp/license/free-tools.js +16 -0
  12. package/dist/src/mcp/license/gate.js +210 -0
  13. package/dist/src/mcp/license/index.js +107 -0
  14. package/dist/src/mcp/license/instance-name.js +57 -0
  15. package/dist/src/mcp/license/key-source.js +59 -0
  16. package/dist/src/mcp/license/lemonsqueezy-verifier.js +207 -0
  17. package/dist/src/mcp/license/placeholder-verifier.js +10 -0
  18. package/dist/src/mcp/license/polar-ids.js +100 -0
  19. package/dist/src/mcp/license/polar-verifier.js +285 -0
  20. package/dist/src/mcp/license/product-ids.js +73 -0
  21. package/dist/src/mcp/license/state-store.js +91 -0
  22. package/dist/src/mcp/license/types.js +11 -0
  23. package/dist/src/mcp/logging.js +271 -0
  24. package/dist/src/mcp/product-info.js +54 -0
  25. package/dist/src/mcp/product.js +56 -0
  26. package/dist/src/mcp/server.js +253 -0
  27. package/dist/src/mcp/setup.js +680 -0
  28. package/dist/src/mcp/start.cjs +117 -0
  29. package/dist/src/mcp/tool-definition.js +2 -0
  30. package/dist/src/mcp/tools.js +2425 -0
  31. package/dist/src/mcp/typography-rules.js +70 -0
  32. package/dist/src/transport/com.js +250 -0
  33. package/dist/src/transport/osascript.js +171 -0
  34. package/dist/src/transport/queue.js +19 -0
  35. package/dist/src/transport/script-bundle.js +92 -0
  36. package/dist/src/transport/transport.js +30 -0
  37. package/indesign/commands/10-app.js +6 -0
  38. package/indesign/commands/20-documents.js +517 -0
  39. package/indesign/commands/22-document-setup.js +204 -0
  40. package/indesign/commands/23-save-package.js +258 -0
  41. package/indesign/commands/25-export.js +448 -0
  42. package/indesign/commands/26-export-image.js +202 -0
  43. package/indesign/commands/27-textdefaults.js +151 -0
  44. package/indesign/commands/28-selection.js +174 -0
  45. package/indesign/commands/30-pages.js +1032 -0
  46. package/indesign/commands/31-view.js +210 -0
  47. package/indesign/commands/32-sections.js +203 -0
  48. package/indesign/commands/35-parents.js +428 -0
  49. package/indesign/commands/37-layout.js +837 -0
  50. package/indesign/commands/40-frames.js +851 -0
  51. package/indesign/commands/41-shapes.js +505 -0
  52. package/indesign/commands/42-groups.js +117 -0
  53. package/indesign/commands/43-layers.js +310 -0
  54. package/indesign/commands/44-effects.js +274 -0
  55. package/indesign/commands/45-frame-options.js +247 -0
  56. package/indesign/commands/47-anchored.js +331 -0
  57. package/indesign/commands/50-modify.js +781 -0
  58. package/indesign/commands/52-align.js +139 -0
  59. package/indesign/commands/55-fit.js +106 -0
  60. package/indesign/commands/60-images.js +1128 -0
  61. package/indesign/commands/62-embed.js +120 -0
  62. package/indesign/commands/69-placeholders.js +127 -0
  63. package/indesign/commands/70-text.js +675 -0
  64. package/indesign/commands/71-outlines.js +92 -0
  65. package/indesign/commands/72-place-text.js +476 -0
  66. package/indesign/commands/73-story-lock.js +157 -0
  67. package/indesign/commands/74-stories.js +121 -0
  68. package/indesign/commands/75-tables.js +676 -0
  69. package/indesign/commands/76-text-variables.js +260 -0
  70. package/indesign/commands/77-story-options.js +86 -0
  71. package/indesign/commands/78-frame-lines.js +452 -0
  72. package/indesign/commands/79-check-typography.js +341 -0
  73. package/indesign/commands/80-styles.js +1865 -0
  74. package/indesign/commands/81-composition.js +355 -0
  75. package/indesign/commands/82-object-styles.js +263 -0
  76. package/indesign/commands/83-drop-caps.js +87 -0
  77. package/indesign/commands/83-indents-tabs.js +264 -0
  78. package/indesign/commands/84-import-styles.js +142 -0
  79. package/indesign/commands/85-swatches.js +112 -0
  80. package/indesign/commands/86-gradients.js +185 -0
  81. package/indesign/commands/87-replace-swatch.js +180 -0
  82. package/indesign/commands/88-replace-font.js +212 -0
  83. package/indesign/commands/89-toc-index.js +945 -0
  84. package/indesign/commands/90-print-on-demand.js +495 -0
  85. package/indesign/commands/91-epub.js +546 -0
  86. package/indesign/interpreter.js +779 -0
  87. package/package.json +41 -4
  88. package/rules/typography-rules.json +31 -0
@@ -0,0 +1,151 @@
1
+ /* Bereich A – Textvorgaben des Dokuments. */
2
+
3
+ /* Schriftfamilie und Schnitt der Vorgabe lesen; appliedFont kann Objekt oder "Familie\tSchnitt" sein. */
4
+ function idcReadDefaultFont(defaults) {
5
+ var family = null;
6
+ var style = null;
7
+ var applied, text, tab;
8
+
9
+ try {
10
+ applied = defaults.appliedFont;
11
+ if (applied && typeof applied === 'object') {
12
+ try { family = String(applied.fontFamily); } catch (e1) { family = null; }
13
+ try { style = String(applied.fontStyleName); } catch (e2) { style = null; }
14
+ if (family === null) {
15
+ text = String(applied.name);
16
+ tab = text.indexOf('\t');
17
+ family = tab >= 0 ? text.substr(0, tab) : text;
18
+ }
19
+ } else if (applied !== undefined && applied !== null) {
20
+ text = String(applied);
21
+ tab = text.indexOf('\t');
22
+ family = tab >= 0 ? text.substr(0, tab) : text;
23
+ if (tab >= 0) { style = text.substr(tab + 1); }
24
+ }
25
+ } catch (e) { /* bleibt null */ }
26
+
27
+ if (style === null) {
28
+ try { style = String(defaults.fontStyle); } catch (e3) { style = null; }
29
+ }
30
+ return { family: family, style: style };
31
+ }
32
+
33
+ function idcStyleName(styleObject) {
34
+ try {
35
+ if (styleObject && styleObject.isValid !== false) { return String(styleObject.name); }
36
+ } catch (e) { /* null */ }
37
+ return null;
38
+ }
39
+
40
+ function idcReadTextDefaults(defaults) {
41
+ var font = idcReadDefaultFont(defaults);
42
+ var size = null;
43
+ /*
44
+ * pointSize kommt in der aktuellen Skript-Masseinheit zurueck – unter der
45
+ * Millimeter-Klammer des Interpreters also als 4.233 statt 12. Deshalb auch
46
+ * das Lesen unter Punkt (am lebenden InDesign 21.5 am 04.09.2026 gesehen).
47
+ */
48
+ try {
49
+ size = IDC.inPoints(function () { return IDC.round(defaults.pointSize, 3); });
50
+ } catch (e) { size = null; }
51
+ return {
52
+ font: font.family,
53
+ font_style: font.style,
54
+ point_size: size,
55
+ paragraph_style: idcStyleName(defaults.appliedParagraphStyle),
56
+ character_style: idcStyleName(defaults.appliedCharacterStyle)
57
+ };
58
+ }
59
+
60
+ IDC.register('document_text_defaults', { needs_document: true, read_only: false, ruler: 'none' },
61
+ function (ctx) {
62
+ var args = ctx.args;
63
+ var doc = ctx.doc;
64
+ var defaults = doc.textDefaults;
65
+ var changed = [];
66
+ var problems = [];
67
+ var wantsChange = false;
68
+ var style, fontObject, fontText, after, current;
69
+
70
+ function problem(field, message) {
71
+ problems.push({ field: field, message: String(message) });
72
+ }
73
+
74
+ /* Erst das Absatzformat, dann die Schrift: so bleibt eine ausdrueckliche Schrift Vorrang. */
75
+ if (args.paragraph_style !== undefined && args.paragraph_style !== null) {
76
+ wantsChange = true;
77
+ style = IDC.paragraphStyleByName(doc, String(args.paragraph_style));
78
+ if (style === null) {
79
+ problem('paragraph_style', 'Paragraph style "' + args.paragraph_style + '" not found.');
80
+ } else {
81
+ try {
82
+ defaults.appliedParagraphStyle = style;
83
+ changed.push('paragraph_style');
84
+ } catch (e1) {
85
+ problem('paragraph_style', e1.message ? e1.message : e1);
86
+ }
87
+ }
88
+ }
89
+
90
+ if (args.font !== undefined && args.font !== null) {
91
+ wantsChange = true;
92
+ fontText = String(args.font);
93
+ try {
94
+ if (fontText.indexOf('\t') >= 0) {
95
+ fontObject = app.fonts.itemByName(fontText);
96
+ if (!fontObject || fontObject.isValid !== true) {
97
+ problem('font', 'Font "' + fontText.replace(/\t/g, ' / ') + '" is not installed.');
98
+ } else {
99
+ defaults.appliedFont = fontObject;
100
+ changed.push('font');
101
+ }
102
+ } else {
103
+ defaults.appliedFont = fontText;
104
+ current = idcReadDefaultFont(defaults);
105
+ if (current.family !== fontText) {
106
+ problem('font', 'Font family "' + fontText + '" is not installed; InDesign kept "' + current.family + '".');
107
+ } else {
108
+ changed.push('font');
109
+ }
110
+ }
111
+ } catch (e2) {
112
+ problem('font', e2.message ? e2.message : e2);
113
+ }
114
+ }
115
+
116
+ if (args.font_style !== undefined && args.font_style !== null) {
117
+ wantsChange = true;
118
+ try {
119
+ defaults.fontStyle = String(args.font_style);
120
+ current = idcReadDefaultFont(defaults);
121
+ if (current.style !== String(args.font_style)) {
122
+ problem('font_style', 'Font style "' + args.font_style + '" is not available for "' + current.family + '"; InDesign kept "' + current.style + '".');
123
+ } else {
124
+ changed.push('font_style');
125
+ }
126
+ } catch (e3) {
127
+ problem('font_style', e3.message ? e3.message : e3);
128
+ }
129
+ }
130
+
131
+ if (args.point_size !== undefined && args.point_size !== null) {
132
+ wantsChange = true;
133
+ if (typeof args.point_size !== 'number' || !(args.point_size > 0) || args.point_size > 1296) {
134
+ problem('point_size', 'point_size must be a number above 0 and up to 1296.');
135
+ } else {
136
+ try {
137
+ IDC.inPoints(function () { defaults.pointSize = args.point_size; });
138
+ changed.push('point_size');
139
+ } catch (e4) {
140
+ problem('point_size', e4.message ? e4.message : e4);
141
+ }
142
+ }
143
+ }
144
+
145
+ after = idcReadTextDefaults(defaults);
146
+ after.changed_fields = changed;
147
+ after.problems = problems;
148
+ after.read_only = !wantsChange;
149
+ if (changed.length > 0) { ctx.changes = { modified_document_ids: [Number(doc.id)] }; }
150
+ return after;
151
+ });
@@ -0,0 +1,174 @@
1
+ /* Wunschliste J2 Nr. 25 (Sitzung 8) – Auswahl lesen und setzen: get_selection, set_selection. */
2
+
3
+ var IDC_TEXT_CLASSES = ['Text', 'InsertionPoint', 'Character', 'Word', 'Line', 'Paragraph', 'TextStyleRange', 'TextColumn'];
4
+
5
+ function idcIsTextClass(name) {
6
+ var i;
7
+ for (i = 0; i < IDC_TEXT_CLASSES.length; i++) { if (IDC_TEXT_CLASSES[i] === name) { return true; } }
8
+ return false;
9
+ }
10
+
11
+ function idcDescribeTextSelection(doc, textObject) {
12
+ var out = { story_id: null, start_index: null, end_index: null, length: null, frame_id: null, text: '' };
13
+ var story = null, first = null, count = 0;
14
+ try { story = textObject.parentStory; out.story_id = Number(story.id); } catch (e0) { story = null; }
15
+ try { count = Number(textObject.characters.length); } catch (e1) { count = 0; }
16
+ out.length = count;
17
+ try {
18
+ if (count > 0) {
19
+ first = textObject.characters.item(0);
20
+ out.start_index = Number(first.index);
21
+ out.end_index = out.start_index + count;
22
+ } else {
23
+ out.start_index = Number(textObject.index);
24
+ out.end_index = out.start_index;
25
+ }
26
+ } catch (e2) { /* null */ }
27
+ try {
28
+ if (textObject.parentTextFrames && textObject.parentTextFrames.length > 0) { out.frame_id = Number(IDC.concrete(textObject.parentTextFrames[0]).id); }
29
+ } catch (e3) { /* null */ }
30
+ try { out.text = idcSnippet(textObject.contents, 200); } catch (e4) { out.text = ''; }
31
+ return out;
32
+ }
33
+
34
+ function idcDescribeSelectedItem(doc, item) {
35
+ var concrete = IDC.concrete(item);
36
+ var landing = IDC.landing(concrete);
37
+ var out = { frame_id: null, type: IDC.itemType(concrete), class_name: IDC.className(concrete), page_id: landing.page_id, page_name: landing.page_name,
38
+ on_parent_page: IDC.isOnParentSpread(concrete), coordinate_space: idcBoundsSpace(concrete), bounds_mm: null,
39
+ layer_name: idcLayerName(concrete), parent_group_id: null };
40
+ try { out.frame_id = Number(concrete.id); } catch (e0) { /* null */ }
41
+ try { out.bounds_mm = idcItemBounds(doc, concrete); } catch (e1) { out.bounds_mm = null; }
42
+ try { if (IDC.className(concrete.parent) === 'Group') { out.parent_group_id = Number(concrete.parent.id); } } catch (e2) { /* null */ }
43
+ return out;
44
+ }
45
+
46
+ function idcReadSelection(doc) {
47
+ var selection = null, i, entry, name, items = [], text = null, other = [];
48
+ try { selection = doc.selection; } catch (e0) { selection = null; }
49
+ if (selection === null || selection === undefined) { return { items: items, text: text, other: other }; }
50
+ /* Live 05.09.2026: doc.selection ist in ExtendScript ein Array, das IDC.isArray nicht erkennt (eigener Array-Typ) – ueber length/Klassennamen pruefen. */
51
+ if (!IDC.isArray(selection) && IDC.className(selection) !== 'Array') {
52
+ try { if (typeof selection.length !== 'number') { selection = [selection]; } } catch (e0b) { selection = [selection]; }
53
+ }
54
+ for (i = 0; i < selection.length; i++) {
55
+ entry = selection[i];
56
+ if (entry === null || entry === undefined) { continue; }
57
+ name = IDC.className(entry);
58
+ if (idcIsTextClass(name)) {
59
+ if (text === null) { text = idcDescribeTextSelection(doc, entry); text.class_name = name; }
60
+ continue;
61
+ }
62
+ try {
63
+ if (entry.id !== undefined && entry.geometricBounds !== undefined) { items.push(idcDescribeSelectedItem(doc, entry)); continue; }
64
+ } catch (e1) { /* kein Seitenobjekt */ }
65
+ other.push(name);
66
+ }
67
+ return { items: items, text: text, other: other };
68
+ }
69
+
70
+ IDC.register('get_selection', { needs_document: true, read_only: true, ruler: 'page' },
71
+ function (ctx) {
72
+ var doc = ctx.doc;
73
+ var active = false, read = idcReadSelection(doc), ids = [], i;
74
+ try { active = app.activeDocument !== null && Number(app.activeDocument.id) === Number(doc.id); } catch (e0) { active = false; }
75
+ for (i = 0; i < read.items.length; i++) { ids.push(read.items[i].frame_id); }
76
+ if (!active) { ctx.warn('This document is not the active one; the selection belongs to the document window and may be empty here.'); }
77
+ return {
78
+ count: read.items.length + (read.text === null ? 0 : 1) + read.other.length,
79
+ frame_ids: ids,
80
+ items: read.items,
81
+ text: read.text,
82
+ other: read.other,
83
+ is_active_document: active
84
+ };
85
+ });
86
+
87
+ IDC.register('set_selection', { needs_document: true, read_only: false, ruler: 'page' },
88
+ function (ctx) {
89
+ var args = ctx.args;
90
+ var doc = ctx.doc;
91
+ var ids = args.frame_ids, items = [], i, found, read, option = null, target = null;
92
+
93
+ if (args.clear === true) {
94
+ if (ids !== undefined && ids !== null) { IDC.fail('invalid_argument', 'clear true cannot be combined with frame_ids.', null); }
95
+ try {
96
+ if (typeof NothingEnum !== 'undefined') { doc.select(NothingEnum.NOTHING); }
97
+ else { doc.select([]); }
98
+ } catch (e0) {
99
+ IDC.fail('script_error', 'InDesign could not clear the selection: ' + String(e0.message ? e0.message : e0), null);
100
+ }
101
+ return { count: 0, frame_ids: [], items: [], text: null, cleared: true };
102
+ }
103
+ /* Sitzung 10 (Kleinigkeit aus Sitzung 9): Textbereich waehlen. */
104
+ if (args.text_range !== undefined && args.text_range !== null) {
105
+ if (ids !== undefined && ids !== null) { IDC.fail('invalid_argument', 'text_range cannot be combined with frame_ids.', null); }
106
+ return idcSelectTextRange(ctx, doc, args.text_range);
107
+ }
108
+ if (!IDC.isArray(ids) || ids.length === 0) { IDC.fail('invalid_argument', 'frame_ids must list at least one object id, or text_range {frame_id, start_index, end_index}, or clear true.', null); }
109
+ if (ids.length > 500) { IDC.fail('invalid_argument', 'frame_ids may list at most 500 objects.', { count: ids.length }); }
110
+ for (i = 0; i < ids.length; i++) {
111
+ if (typeof ids[i] !== 'number' || Math.floor(ids[i]) !== ids[i]) { IDC.fail('invalid_argument', 'frame_ids must contain whole numbers.', { frame_ids: ids }); }
112
+ found = IDC.itemById(doc, ids[i], 'any');
113
+ if (found === null) { IDC.fail('not_found', 'No object with frame_id ' + ids[i] + ' in this document.', { frame_id: ids[i] }); }
114
+ items.push(found.item);
115
+ }
116
+ try { if (typeof SelectionOptions !== 'undefined') { option = SelectionOptions.REPLACE_WITH; } } catch (e1) { option = null; }
117
+ target = items.length === 1 ? items[0] : items;
118
+ try {
119
+ if (option !== null) { doc.select(target, option); } else { doc.select(target); }
120
+ } catch (e2) {
121
+ IDC.fail('script_error', 'InDesign could not select the objects (hidden or locked layer? window not open?): ' + String(e2.message ? e2.message : e2), { frame_ids: ids });
122
+ }
123
+ read = idcReadSelection(doc);
124
+ if (read.items.length !== items.length) {
125
+ ctx.warn('InDesign reports ' + read.items.length + ' selected object(s) instead of ' + items.length + ' (objects on hidden or locked layers cannot be selected).');
126
+ }
127
+ ids = [];
128
+ for (i = 0; i < read.items.length; i++) { ids.push(read.items[i].frame_id); }
129
+ return { count: read.items.length, frame_ids: ids, items: read.items, text: read.text, cleared: false };
130
+ });
131
+
132
+ /*
133
+ * Textbereich (oder Einfuegemarke bei start_index == end_index) in der Story
134
+ * eines Rahmens waehlen: doc.select(text) bringt InDesign in den
135
+ * Textmodus und zeigt die Stelle. Rueckgabe wie get_selection.
136
+ */
137
+ function idcSelectTextRange(ctx, doc, spec) {
138
+ var found, frame, story, range, target, option = null, read, length = 0;
139
+ if (typeof spec !== 'object' || IDC.isArray(spec)) {
140
+ IDC.fail('invalid_argument', 'text_range must be an object {frame_id, start_index, end_index}.', null);
141
+ }
142
+ found = idcTextFrameArg(doc, spec, 'frame_id');
143
+ frame = found.item;
144
+ story = idcStoryOf(frame);
145
+ try { length = Number(story.characters.length); } catch (e0) { length = 0; }
146
+ if (typeof spec.start_index === 'number' && spec.start_index === spec.end_index) {
147
+ /* Einfuegemarke: itemByRange(start, start - 1) waere ein leerer Bereich, den InDesign ablehnt. */
148
+ if (Math.floor(spec.start_index) !== spec.start_index || spec.start_index < 0 || spec.start_index > length) {
149
+ IDC.fail('invalid_argument', 'start_index must be a whole number from 0 to the story length ' + length + '.', { start_index: spec.start_index, story_length: length });
150
+ }
151
+ range = { start: spec.start_index, end: spec.start_index, text: null };
152
+ } else {
153
+ range = idcRangeArg(story, spec, false);
154
+ }
155
+ if (range.start === range.end) {
156
+ try { target = story.insertionPoints.item(range.start); } catch (e1) {
157
+ IDC.fail('script_error', 'InDesign could not address insertion point ' + range.start + ': ' + String(e1.message ? e1.message : e1), { start_index: range.start });
158
+ }
159
+ } else {
160
+ target = range.text;
161
+ }
162
+ try { if (typeof SelectionOptions !== 'undefined') { option = SelectionOptions.REPLACE_WITH; } } catch (e2) { option = null; }
163
+ try {
164
+ if (option !== null) { doc.select(target, option); } else { doc.select(target); }
165
+ } catch (e3) {
166
+ IDC.fail('script_error', 'InDesign could not select the text (hidden or locked layer? window not open?): ' + String(e3.message ? e3.message : e3),
167
+ { frame_id: spec.frame_id, start_index: range.start, end_index: range.end });
168
+ }
169
+ read = idcReadSelection(doc);
170
+ if (read.text === null) {
171
+ read.text = { story_id: Number(story.id), start_index: range.start, end_index: range.end, length: range.end - range.start, frame_id: Number(frame.id), text: '', class_name: 'InsertionPoint' };
172
+ }
173
+ return { count: 1, frame_ids: [], items: [], text: read.text, cleared: false, story_length: length };
174
+ }