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.
Files changed (79) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/LICENSE +26 -0
  3. package/README.de.md +318 -0
  4. package/README.md +304 -4
  5. package/THIRD-PARTY-NOTICES.md +2878 -0
  6. package/dist/src/mcp/config.js +125 -0
  7. package/dist/src/mcp/dispatch.js +123 -0
  8. package/dist/src/mcp/license/free-tools.js +16 -0
  9. package/dist/src/mcp/license/gate.js +209 -0
  10. package/dist/src/mcp/license/index.js +96 -0
  11. package/dist/src/mcp/license/instance-name.js +56 -0
  12. package/dist/src/mcp/license/key-source.js +58 -0
  13. package/dist/src/mcp/license/lemonsqueezy-verifier.js +207 -0
  14. package/dist/src/mcp/license/placeholder-verifier.js +10 -0
  15. package/dist/src/mcp/license/polar-ids.js +63 -0
  16. package/dist/src/mcp/license/polar-verifier.js +265 -0
  17. package/dist/src/mcp/license/product-ids.js +72 -0
  18. package/dist/src/mcp/license/state-store.js +91 -0
  19. package/dist/src/mcp/license/types.js +11 -0
  20. package/dist/src/mcp/logging.js +270 -0
  21. package/dist/src/mcp/product-info.js +48 -0
  22. package/dist/src/mcp/server.js +250 -0
  23. package/dist/src/mcp/setup.js +608 -0
  24. package/dist/src/mcp/start.cjs +95 -0
  25. package/dist/src/mcp/tool-definition.js +2 -0
  26. package/dist/src/mcp/tools.js +2004 -0
  27. package/dist/src/mcp/typography-rules.js +70 -0
  28. package/dist/src/transport/com.js +250 -0
  29. package/dist/src/transport/osascript.js +171 -0
  30. package/dist/src/transport/queue.js +19 -0
  31. package/dist/src/transport/script-bundle.js +92 -0
  32. package/dist/src/transport/transport.js +30 -0
  33. package/indesign/commands/10-app.js +6 -0
  34. package/indesign/commands/20-documents.js +513 -0
  35. package/indesign/commands/22-document-setup.js +118 -0
  36. package/indesign/commands/23-save-package.js +255 -0
  37. package/indesign/commands/25-export.js +379 -0
  38. package/indesign/commands/26-export-image.js +197 -0
  39. package/indesign/commands/27-textdefaults.js +151 -0
  40. package/indesign/commands/28-selection.js +174 -0
  41. package/indesign/commands/30-pages.js +1032 -0
  42. package/indesign/commands/31-view.js +210 -0
  43. package/indesign/commands/32-sections.js +203 -0
  44. package/indesign/commands/35-parents.js +428 -0
  45. package/indesign/commands/37-layout.js +760 -0
  46. package/indesign/commands/40-frames.js +836 -0
  47. package/indesign/commands/41-shapes.js +505 -0
  48. package/indesign/commands/42-groups.js +117 -0
  49. package/indesign/commands/43-layers.js +291 -0
  50. package/indesign/commands/44-effects.js +274 -0
  51. package/indesign/commands/45-frame-options.js +247 -0
  52. package/indesign/commands/47-anchored.js +287 -0
  53. package/indesign/commands/50-modify.js +781 -0
  54. package/indesign/commands/52-align.js +139 -0
  55. package/indesign/commands/55-fit.js +106 -0
  56. package/indesign/commands/60-images.js +771 -0
  57. package/indesign/commands/62-embed.js +120 -0
  58. package/indesign/commands/69-placeholders.js +127 -0
  59. package/indesign/commands/70-text.js +567 -0
  60. package/indesign/commands/71-outlines.js +92 -0
  61. package/indesign/commands/72-place-text.js +366 -0
  62. package/indesign/commands/74-stories.js +116 -0
  63. package/indesign/commands/75-tables.js +676 -0
  64. package/indesign/commands/76-text-variables.js +260 -0
  65. package/indesign/commands/77-story-options.js +86 -0
  66. package/indesign/commands/78-frame-lines.js +304 -0
  67. package/indesign/commands/79-check-typography.js +303 -0
  68. package/indesign/commands/80-styles.js +1620 -0
  69. package/indesign/commands/81-composition.js +355 -0
  70. package/indesign/commands/82-object-styles.js +263 -0
  71. package/indesign/commands/83-indents-tabs.js +237 -0
  72. package/indesign/commands/84-import-styles.js +142 -0
  73. package/indesign/commands/85-swatches.js +112 -0
  74. package/indesign/commands/86-gradients.js +185 -0
  75. package/indesign/commands/87-replace-swatch.js +180 -0
  76. package/indesign/commands/88-replace-font.js +217 -0
  77. package/indesign/interpreter.js +758 -0
  78. package/package.json +55 -6
  79. package/rules/typography-rules.json +31 -0
@@ -0,0 +1,120 @@
1
+ /* Wunschliste J2 Nr. 26 (Sitzung 8) – Verknuepfung einbetten und loesen: embed_link, unembed_link. */
2
+
3
+ /* Verknuepfungen zu link_ids oder frame_id (alle Grafiken des Rahmens) auflisten. */
4
+ function idcLinksArg(doc, args, what) {
5
+ var out = [], i, link, graphics, found;
6
+ var hasIds = args.link_ids !== undefined && args.link_ids !== null;
7
+ var hasFrame = args.frame_id !== undefined && args.frame_id !== null;
8
+ if (hasIds === hasFrame) {
9
+ IDC.fail('invalid_argument', 'Pass either link_ids or frame_id.', null);
10
+ }
11
+ if (hasIds) {
12
+ if (!IDC.isArray(args.link_ids) || args.link_ids.length === 0 || args.link_ids.length > 500) {
13
+ IDC.fail('invalid_argument', 'link_ids must list 1 to 500 link ids.', null);
14
+ }
15
+ for (i = 0; i < args.link_ids.length; i++) {
16
+ link = idcLinkById(doc, args.link_ids[i]);
17
+ if (link === null) { IDC.fail('not_found', 'No link with link_id ' + args.link_ids[i] + '; see list_links.', { link_id: args.link_ids[i] }); }
18
+ out.push(link);
19
+ }
20
+ return out;
21
+ }
22
+ found = idcFrameArg(doc, args, 'frame_id');
23
+ graphics = idcGraphicsOf(found.item);
24
+ for (i = 0; i < graphics.length; i++) {
25
+ link = idcLinkOf(graphics[i]);
26
+ if (link !== null) { out.push(link); }
27
+ }
28
+ if (out.length === 0) {
29
+ IDC.fail('invalid_state', 'Object ' + args.frame_id + ' holds no linked graphic.', { frame_id: args.frame_id });
30
+ }
31
+ return out;
32
+ }
33
+
34
+ function idcIsEmbedded(link) {
35
+ try { return idcLinkStatusName(link.status, true) === 'EMBEDDED'; } catch (e) { return false; }
36
+ }
37
+
38
+ IDC.register('embed_link', { needs_document: true, read_only: false, ruler: 'page' },
39
+ function (ctx) {
40
+ var args = ctx.args;
41
+ var doc = ctx.doc;
42
+ var links = idcLinksArg(doc, args, 'embed_link');
43
+ var done = [], skipped = [], i, link, entry, status, bytes;
44
+
45
+ for (i = 0; i < links.length; i++) {
46
+ link = links[i];
47
+ entry = idcDescribeLink(doc, link);
48
+ if (idcIsEmbedded(link)) { entry.reason = 'already embedded'; skipped.push(entry); continue; }
49
+ status = entry.status;
50
+ if (status === 'LINK_MISSING') { entry.reason = 'file missing'; skipped.push(entry); continue; }
51
+ try { bytes = Number(link.size); } catch (e0) { bytes = null; }
52
+ try {
53
+ link.unlink();
54
+ } catch (e1) {
55
+ IDC.fail('io_error', 'InDesign could not embed link ' + entry.file_name + ': ' + String(e1.message ? e1.message : e1),
56
+ { link_id: entry.link_id, embedded_so_far: done });
57
+ }
58
+ entry.status_before = status;
59
+ entry.bytes = bytes;
60
+ /* Die Verknuepfung wird beim Einbetten in InDesign zu einem neuen Link-Objekt; frisch lesen. */
61
+ try { entry.status = idcLinkStatusName(link.status, true); } catch (e2) { entry.status = 'EMBEDDED'; }
62
+ done.push(entry);
63
+ }
64
+ if (skipped.length > 0) {
65
+ ctx.warn(skipped.length + ' link(s) skipped: ' + idcSkipReasons(skipped));
66
+ }
67
+ if (done.length > 0) { ctx.changes = { modified_link_ids: idcLinkIds(done), modified_document_ids: [Number(doc.id)] }; }
68
+ return { embedded: done, embedded_count: done.length, skipped: skipped, skipped_count: skipped.length, links_after: idcAllLinksBrief(doc) };
69
+ });
70
+
71
+ IDC.register('unembed_link', { needs_document: true, read_only: false, ruler: 'page' },
72
+ function (ctx) {
73
+ var args = ctx.args;
74
+ var doc = ctx.doc;
75
+ var links = idcLinksArg(doc, args, 'unembed_link');
76
+ var folder = null, done = [], skipped = [], i, link, entry;
77
+
78
+ if (args.folder_path !== undefined && args.folder_path !== null) {
79
+ if (typeof args.folder_path !== 'string' || args.folder_path === '') { IDC.fail('invalid_argument', 'folder_path must be a folder path.', null); }
80
+ folder = IDC.folderFor(args.folder_path);
81
+ if (folder.exists !== true) { IDC.fail('io_error', 'folder_path does not exist: ' + args.folder_path, { folder_path: args.folder_path }); }
82
+ }
83
+ for (i = 0; i < links.length; i++) {
84
+ link = links[i];
85
+ entry = idcDescribeLink(doc, link);
86
+ if (!idcIsEmbedded(link)) { entry.reason = 'not embedded'; skipped.push(entry); continue; }
87
+ try {
88
+ if (folder !== null) { link.unembed(folder); } else { link.unembed(); }
89
+ } catch (e0) {
90
+ IDC.fail('io_error', 'InDesign could not unembed link ' + entry.file_name + ' (original file gone? pass folder_path to write it out): ' + String(e0.message ? e0.message : e0),
91
+ { link_id: entry.link_id, unembedded_so_far: done });
92
+ }
93
+ try { entry.status = idcLinkStatusName(link.status, true); } catch (e1) { /* bleibt */ }
94
+ try { entry.file_path = String(link.filePath); } catch (e2) { /* bleibt */ }
95
+ done.push(entry);
96
+ }
97
+ if (skipped.length > 0) { ctx.warn(skipped.length + ' link(s) skipped: ' + idcSkipReasons(skipped)); }
98
+ if (done.length > 0) { ctx.changes = { modified_link_ids: idcLinkIds(done), modified_document_ids: [Number(doc.id)] }; }
99
+ return { unembedded: done, unembedded_count: done.length, skipped: skipped, skipped_count: skipped.length, folder_path: folder === null ? null : IDC.fsPath(folder) || args.folder_path, links_after: idcAllLinksBrief(doc) };
100
+ });
101
+
102
+ function idcSkipReasons(list) {
103
+ var parts = [], i;
104
+ for (i = 0; i < list.length; i++) { parts.push(String(list[i].file_name) + ' (' + list[i].reason + ')'); }
105
+ return parts.join(', ');
106
+ }
107
+
108
+ function idcLinkIds(list) {
109
+ var out = [], i;
110
+ for (i = 0; i < list.length; i++) { out.push(list[i].link_id); }
111
+ return out;
112
+ }
113
+
114
+ function idcAllLinksBrief(doc) {
115
+ var out = [], i;
116
+ try {
117
+ for (i = 0; i < doc.links.length; i++) { out.push(idcDescribeLink(doc, doc.links.item(i))); }
118
+ } catch (e) { /* leer */ }
119
+ return out;
120
+ }
@@ -0,0 +1,127 @@
1
+ /*
2
+ * Auftrag A-8.8 (Sitzung 9) – benannte Sonderzeichen im Text
3
+ * (Wunschliste J Nr. 8): Platzhalter {{name}} in set_text,
4
+ * set_text_in_range und create_text_frame.initial_text werden zu
5
+ * InDesign-Sonderzeichen; get_frame_text zeigt sie mit show_placeholders
6
+ * wieder als Platzhalter. Jeder Platzhalter steht fuer genau ein Zeichen,
7
+ * damit Story-Indizes und Sichtbarkeit zusammenpassen.
8
+ *
9
+ * Zeichen (Unicode; Umbruchzeichen als die Codes, die InDesign in contents
10
+ * fuehrt – 0x0E Spalte, 0x0F Rahmen, 0x10 Seite; live bestaetigt, Journal):
11
+ */
12
+ var IDC_PLACEHOLDERS = [
13
+ ['line_break', '\n'],
14
+ ['nbsp', '\u00A0'],
15
+ ['nbsp_fixed', '\u202F'],
16
+ ['thin_space', '\u2009'],
17
+ ['hair_space', '\u200A'],
18
+ ['soft_hyphen', '\u00AD'],
19
+ ['nb_hyphen', '\u2011'],
20
+ ['en_dash', '\u2013'],
21
+ ['em_dash', '\u2014'],
22
+ ['tab', '\t'],
23
+ ['column_break', '\u000E'],
24
+ ['frame_break', '\u000F'],
25
+ ['page_break', '\u0010']
26
+ ];
27
+
28
+ function idcPlaceholderChar(name) {
29
+ var i;
30
+ for (i = 0; i < IDC_PLACEHOLDERS.length; i++) {
31
+ if (IDC_PLACEHOLDERS[i][0] === name) { return IDC_PLACEHOLDERS[i][1]; }
32
+ }
33
+ return null;
34
+ }
35
+
36
+ /*
37
+ * Platzhalter im Text ersetzen. Liefert { text, replaced {name: n},
38
+ * unknown [] }. Unbekannte {{...}} bleiben woertlich. enabled false:
39
+ * nichts wird ersetzt.
40
+ */
41
+ function idcExpandPlaceholders(text, enabled) {
42
+ var out = { text: String(text), replaced: {}, unknown: [] };
43
+ var s = String(text), result = '', i = 0, open, close, name, ch;
44
+ if (enabled === false) { return out; }
45
+ while (i < s.length) {
46
+ open = s.indexOf('{{', i);
47
+ if (open < 0) { result += s.substr(i); break; }
48
+ close = s.indexOf('}}', open + 2);
49
+ if (close < 0) { result += s.substr(i); break; }
50
+ name = s.substring(open + 2, close);
51
+ ch = /^[a-z_]+$/.test(name) ? idcPlaceholderChar(name) : null;
52
+ result += s.substring(i, open);
53
+ if (ch === null) {
54
+ result += s.substring(open, close + 2);
55
+ if (!idcInList(out.unknown, name)) { out.unknown.push(name); }
56
+ } else {
57
+ result += ch;
58
+ out.replaced[name] = (out.replaced[name] || 0) + 1;
59
+ }
60
+ i = close + 2;
61
+ }
62
+ out.text = result;
63
+ return out;
64
+ }
65
+
66
+ /* Sonderzeichen im gelesenen Text als Platzhalter zeigen (get_frame_text show_placeholders). */
67
+ function idcShowPlaceholders(text) {
68
+ var s = String(text), result = '', i, ch, j, name;
69
+ for (i = 0; i < s.length; i++) {
70
+ ch = s.charAt(i);
71
+ name = null;
72
+ for (j = 0; j < IDC_PLACEHOLDERS.length; j++) {
73
+ if (IDC_PLACEHOLDERS[j][1] === ch && ch !== '\r') { name = IDC_PLACEHOLDERS[j][0]; break; }
74
+ }
75
+ result += name === null ? ch : '{{' + name + '}}';
76
+ }
77
+ return result;
78
+ }
79
+
80
+ function idcPlaceholderWarnings(ctx, expansion) {
81
+ if (expansion.unknown.length > 0) {
82
+ ctx.warn('Unknown placeholder(s) left as written: {{' + expansion.unknown.join('}}, {{') + '}}. Known: ' + idcPlaceholderNames() + '.');
83
+ }
84
+ }
85
+
86
+ function idcPlaceholderNames() {
87
+ var names = [], i;
88
+ for (i = 0; i < IDC_PLACEHOLDERS.length; i++) { names.push(IDC_PLACEHOLDERS[i][0]); }
89
+ return names.join(', ');
90
+ }
91
+
92
+ /*
93
+ * Umbruchzeichen (Spalte 0x0E, Rahmen 0x0F, Seite 0x10) verwirft InDesign,
94
+ * wenn sie ueber contents geschrieben werden (Live-Fund 05.09.2026: 110
95
+ * geschrieben, 107 gelesen). Sie werden deshalb aus dem Text genommen und
96
+ * nach dem Schreiben ueber insertionPoints als SpecialCharacters
97
+ * eingefuegt.
98
+ */
99
+ var IDC_BREAK_ENUMS = {};
100
+ IDC_BREAK_ENUMS['\u000E'] = 'COLUMN_BREAK';
101
+ IDC_BREAK_ENUMS['\u000F'] = 'FRAME_BREAK';
102
+ IDC_BREAK_ENUMS['\u0010'] = 'PAGE_BREAK';
103
+
104
+ /* Text ohne Umbruchzeichen plus Liste {offset, name}; offset = Stelle im bereinigten Text. */
105
+ function idcSplitBreaks(text) {
106
+ var s = String(text), plain = '', breaks = [], i, ch;
107
+ for (i = 0; i < s.length; i++) {
108
+ ch = s.charAt(i);
109
+ if (IDC.hasOwn(IDC_BREAK_ENUMS, ch)) { breaks.push({ offset: plain.length, name: IDC_BREAK_ENUMS[ch] }); }
110
+ else { plain += ch; }
111
+ }
112
+ return { plain: plain, breaks: breaks };
113
+ }
114
+
115
+ /* Umbruchzeichen an den gemerkten Stellen einfuegen (base = Story-Index des Textanfangs). */
116
+ function idcInsertBreaks(textObject, base, breaks) {
117
+ var i, point;
118
+ if (breaks.length === 0) { return 0; }
119
+ if (typeof SpecialCharacters === 'undefined') {
120
+ IDC.fail('invalid_state', 'This runtime has no SpecialCharacters enumeration; column, frame and page breaks cannot be inserted.', null);
121
+ }
122
+ for (i = 0; i < breaks.length; i++) {
123
+ point = textObject.insertionPoints.item(base + breaks[i].offset + i);
124
+ point.contents = SpecialCharacters[breaks[i].name];
125
+ }
126
+ return breaks.length;
127
+ }