es geht (CS5) um zwei Rahmen, die (alles im Skript) innerhalb einer Zeile verankert werden. In den ersten Rahmen wird dann ein Bild platziert. Die Breite des Rahmens ist definiert. Das Bild füllt den Rahmen im nächsten Schritt proportional (mit der definierten Breite, aber einer mir zunächst unbekannten variablen Höhe), dann wird der Rahmen auf diese Höhe verringert (ich habe ihn zuvor groß genug gemacht). So weit, so gut. Der zweite Rahmen wird mit Text befüllt. Er hat die gleiche Breite wie der erste. Zum Schluss soll der zweite Rahmen unterhalb des ersten Rahmen positioniert werden. Dazu verwende ich "geometricBounds". Das Problem ist, der zweite Rahmen bleibt oben in der verankerten Zeile; also auf gleicher Höhe wie der erste, obwohl ihm eigentlich per Skript ein neuer y1-Wert zugewiesen wird. Wenn ich die Koordinaten beider Rahmen im Skript mit "alert" ausgeben lasse, scheint auch alles meinen Absichten und Berechnungen zu entsprechen. Ich vermute, es hängt mit dem Objektformat für den zweiten Rahmen zusammen. Beiden erstellten Rahmen wird ein Objekformat zugewiesen. Dort, bei den "Optionen für verankertes Objekt", ist "Benutzerdefiniert" eingestellt, außerdem "y relativ zu Zeile (Grundlinie)" und 0 mm "y-Versatz". Ich finde hierzu keine Alternative, die es dem Skript erlauben würde, den Rahmen neu zu positionieren. Habt Ihr eine Idee? Vielen Dank für das Interesse! Gruß Jan
Jan, du solltest deinen Beiträgen Blindabsätze und Beispielbilder bzw. .idmls spendieren :)
Ich rate mal: Die geometricBounds greifen nicht, weil das Teil verankert ist. Per y-Versatz bekomme ich den zweiten Rahmen schon unter den ersten. Objekformate haben dann logischerweise eine Abweichung.
Nicht verstanden: Warum verankerst du generell? Was passiert mit Texten oben drüber / unten drunter (Umfluss)? Warum verschiebst du den zweiten Rahmen nicht einfach in einen neuen Absatz …
erst die Rahmen bauen und befüllen. Dann eine Gruppe bilden und diese verankern.
Mit dem "Verankern" gibt's allerdings ein Problem. Ab CS5.5 ist das ein Leichtes über die Funktion insertAnchoredObject(). Mit CS5 etwas umständlicher. Da gibt's diese Funktion noch nicht.
Ansonsten die anchoredObjectSettings des verankerten Objekts inspizieren und dort die Werte ändern. ***** Mit herzlichem Gruß, Uwe Laubender
Kai, Du meinst Leerzeilen zum besseren Lesen, da hast Du wohl recht. Eine idml zu bauen, da scheue ich den Aufwand, ehrlich gesagt;)
Mit scheint aber, Du hast das Problem trotzdem so weit erfasst.
Ich kann den y-Versatz tatsächlich problemlos nach Ablauf des Skripts per Hand ändern und den Rahmen runterschieben. Die Abweichung im OF ist auch klar und kein Problem. Nur das Skript macht es eben nicht.
Ich verankere, weil es sich um Mengensatz handelt und der Text darüber immer mal wieder sich noch ändern kann. So fließen Bild und Quelle (= der zweite Rahmen) immer gleich mit. Der Text bleibt im Übrigen stets ober- oder unterhalb der Bilder.
Dass ich den zweiten Rahmen im selben Absatz habe, hat mit dem Skriptaufbau zu tun (also mit der Textvorlage, mit der ich arbeite). Das wäre aber einen Versuch wert, hier mit zwei verschiedenen Absätzen zu verfahren. Das Skript würde zwar umständlicher, aber das traue ich mir schon zu. Ich werde es probieren.
Uwe, das klingt nach einer guten Idee. Es übersteigt jedoch meine bisherigen Kenntnisse (wie per Skript normalen Rahmen platzieren?, wie gruppieren?; und wenn das Verankern bei CS5 nicht mit der von Dir genannten Funktion geht, wüsste ich hier auch nicht weiter). Ich probier erst mal das mit den Absätzen.
Den zweiten Rahmen in einen eigenen Absatz zu setzen ändert leider auch nichts daran, dass sich dieser Rahmen mit neu berechneten geometricBounds nicht vertikal verschieben lassen will.
Bliebe noch die Option über die Settings, wie von Uwe vorgeschlagen. Wenn ich es richtig verstehe, könnte ich die Einstellungen des verankerten Rahmens per Skript ändern!? Es ginge dann um anchorYoffset. Den Wert kann ich aus den geometricBounds errechnen. Nur leider funktioniert die letzte Zeile in nicht. Wäre ja auch zu schön gewesen.
(Man merkt vielleicht, ich habe diese ganze Skriptsprache nicht verstanden, sondern hangel mich von Versatzstück zu Versatzstück;)
Aber vielleicht kann mir jemand auf die Sprünge helfen?
Edit: Heureka! Natürlich muss es heißen:
Jetzt muss ich nur noch meine Berechnung verbessern, denn die haut noch nicht hin. Aber ein Weg ist da.
Nochmals danke und Gruß Jan
(Dieser Beitrag wurde von former am 23. Jul 2016, 18:18 geändert)
Hallo Jan, ich würde die Sache folgendermaßen angehen: 1. Stelle die gewünschte Situation im UI nach 2. Lese die properties und deren Werte aus den gebauten Objekten aus. Notieren. 3. Lese die properties und deren Werte per Skript aus den gebauten Objekten aus und stelle eine Korrelation der notierten Werte mit den per Skript ausgelesenen Eigenschaften und Werten her.
warum soll hier einer auch nur zwei Minuten Zeit investieren, wenn du den Aufwand scheust eine Demodatei zu bauen?
Damit ich dir eine Antwort geben konnte, hatte ich mir ein Beispiel gebaut. Uwe hat es möglicherweise genauso gemacht.
Ich bin bei meinem Gedanken davon ausgegangen, dass der zweite Rahmen bei korrekt eingerichtetem Zeilenabstand bereits richtig sitzt. Per Skript ausprobiert hatte ich das allerdings nicht.
Und noch etwas: Dir ist klar, was du da vor hast. Andere raten hier aber. Da wäre ein Beispiel vorher / nachher eigentlich nicht zuviel verlangt.
Gruß Kai Rübsamen
(Dieser Beitrag wurde von Kai Rübsamen am 24. Jul 2016, 00:49 geändert)
Hallo, Uwe, hallo, Kai, zunächst danke für Eure Antworten.
Kai, Du hast natürlich völlig Recht, etwas Aufwand kann man schon verlangen, wenn man Hilfe erwartet. Daher habe ich der Vollständigkeit wegen das Skript auf das Notwendigste reduziert und gebe es unten gerne als Beispiel für diesen Beitrag dazu. Eine idml kann ich als Nicht-Member nicht hochladen, aber eine Standardvorlage mit den beiden Objektformaten "OF1" und "OF2" sollte genügen. Dazu muss man noch irgendein Bild von der eigenen Festplatte auswählen.
(Wenn es mir möglich gewesen wäre, zwei vorhandene verankerte Objekte im Skript "anzusprechen", hätten auch noch weniger Zeilen genügt. Nun werden eben die verankerte Rahmen erst erstellt.)
Jedenfalls funktioniert es nun: Es setzt mir den zweiten Rahmen an die korrekte Position.
Ja, über den Zeilenabstand wäre das Positionieren tatsächlich auch möglich (bzw. würde sich quasi von selbst ergeben), nur ist eben das Problem, dass der erste Rahmen eine variable Höhe hat (je nach Bildgröße) und somit nicht (bzw. fast nie) mit den Zeilen abschließt.
Uwe, danke für Deinen Lösungsvorschlag. In das Objektmodell hatte ich bereits mal reingeschaut. Dank Deinem Hinweis auf die AnchoredObjectSettings stieß ich dort auch auf anchorYoffset.
Mit UI meinst Du das normale InDesign-Programm, oder?
Um ehrlich zu sein, beim Auslesen der properties per Skript hätte ich schon nicht gewusst wie. Da ich den Code im Notepad schreibe -- das ist mir einfach angenehmer in der Handhabe --, mangelt es also schon an der Konsole. Aber im Großen und Ganzen bin ich ja trotzdem so vorgegangen. Nur dass ich einfach die geometricBounds statt der AnchoredObjectSettings genommen habe. Mit denen war ich schon vertraut, mit denen habe ich auch schon im Skript hantiert.
Okay, nichts für ungut. Nochmals danke und Gruß Jan
nichts gegen das Schreiben von Scripts in Notepad. Für das Debuggen allerdings ist das ESTK (ExtendScript Toolkit) meiner Meinung nach unverzichtbar. Gerade für Skripter, die entweder noch nicht sattelfest im DOM sind oder für Skripter, die sich auf Bereiche stürzen, mit denen sie noch keine Erfahrung gesammelt haben.
Oder man etabliert ein wirklich sehr ausgefeiltes Error-Handling mit Unterroutinen, die die Eigenschaften von Objekten abklappern oder gar Methoden auf mögliche Argumente untersuchen können. Sehr aufwändig.
Zum Thema Aufwand, was das Bereitstellen von Testdateien angeht: Ein Dropbox-Link ist schnell gepostet. Dropbox einrichten dauert nur ein paar Minuten. Und ist kostenlos.
Und da komme ich zu Deinen Codezeilen: 1. Ohne eine Beispieldatei ist dieser nicht nachvollziehbar, da beispielsweise die Definition der Objektfomate nicht ersichtlich ist.
2. Du schreibst:
Auch das geht. Nämlich über die pageItems eines Textes. Zwei hintereinander verankerte Objekte in einem ausgewählten Text können beispielsweise folgendermaßen angesprochen werden:
Das getElements()[0] ist notwendig, um den genauen Objekttyp zu ermitteln, da die Überklasse PageItems ausgelesen wird. Also: Ist das angesprochene pageItem beispielsweise ein TextFrame, ein Rectangle etc.pp. Es gilt das Motto: "Wie Du in den Wald rufst, schallt es heraus." Konkret: Du fragst nach pageItems, Du bekommst pageItems zurück.
Wenn man natürlich mit absoluter Sicherheit sagen kann, dass da wirklich genau ein Rectangle und ein TextFrame vorhanden sind, dann geht auch:
Praktischer wäre es aber man würde zunächst die Anzahl der pageItems im Text ermitteln, um sie dann mit einer Schleife abzuklappern.
Was sind die Inhalte der Textrahmen? Willst Du Bildbeschreibungen aus den Metadaten der Bilder auslesen? Texte, die im Haupttext vorhanden sind, in den Textrahmen überführen? Ich habe keinen Schimmer…
Deshalb sei mir ein Hinweis auf im Netz vorhandene Skripte erlaubt. Schau Dir u.a. mal WpsCreateAnchoredFrames von Werner Perplies an. Vielleicht taugt Dir das. Das Testen mit wenigen Rahmen ist kostenlos.
Einarbeitungszeit in die sehr umfangreichen Möglichkeiten des Skripts brauchst Du allerdings.
Falls Du auf Mac OSX mit InDesign CS5 unterwegs bist: Das UI der "Voreinstellungen" des Skripts hat bei mir unter OSX 10.6.8 leider ein paar Macken (hab' das soeben festgestellt). Auf Windows sollte das UI anstandslos funktionieren. Wende Dich an Werner, wenn Du Fragen dazu haben solltest.
// Ergänzung: Da Du von "Notepad" schreibst, nehme ich an, dass Du auf Windows unterwegs bist. ***** Mit herzlichem Gruß, Uwe Laubender
(Dieser Beitrag wurde von Uwe Laubender am 25. Jul 2016, 10:49 geändert)
hab ganz vielen Dank für Deine ausführlichen Hinweise!
Du meinst, dass im ESTK Fehler sogleich angezeigt werden, oder wie ist das mit dem Errorhandling gemeint? Ich werde ihm eine neue Chance geben bzw. habe es sogleich probiert, ein paar Vorteile hat es ja schon (Schritt für Schritt durchgehen, die prompte Anzeige der Ergebnisse bei Berechnungen).
Danke auch für das Beispiel, wie man vorhandene verankerte Objekte anspricht. Für das aktuelle Skript habe ich sie zwar nicht verwendet, weil ich darin die Rahmen ohnehin erst erstelle (ich hatte es nur versucht, als ich zuletzt das Skript hier in den Beitrag geschrieben habe, um mich darin auf das Nötigste zu beschränken), aber ich bin mir sicher, auf die getElements zukünftig zurückzugreifen.
Ja, ich arbeite auf Windows.
Und bzgl. meiner Absichten, war Dein zweiter Tipp richtig: Ich möchte Text, der im Haupttext vorhanden ist, in den Rahmen verschieben.
Das Zip enthält ein Vorher (a1.idml), in dem die drei Absätze markiert werden müssen, ein Nachher, dazu ein Bsp.bild (was beliebig ersetzt werden kann) und schließlich das Skript selbst (text.js), das ich aber auch hier vorstellen möchte:
Wie man sieht, habe ich darin noch einige Fragezeichen. Vor allem aber haut das Handling des zweiten Rahmens noch immer nicht sauber hin. Zwar ist mein Ergebnis nun das Gewünschte, aber nur auf Kosten einer Fehlermeldung, was ja nicht der Weisheit letzter Schluss sein kann.
Eigentlich wäre es naheliegend, "einfach" die Rahmenbreite nach dem Befüllen und Anpassen des Rahmens noch einmal festzulegen, wobei die variable Höhe konstant gehalten werden müsste. Aber das scheint doch schwieriger, als man denkt. Wenn man im Objektformat die Breite (die ich leider auch nicht im OM zu den Settings finden kann) ändern will, geht das auch nur über "Feste Breite", und das ist für mich nicht praktikabel, weil ich auch Rahmen mit anderer Breite, aber demselben Objektformat haben will. Und mein Versuch über die geometricBounds ist halt irgendwie fehlerhaft.
Glaub ich nicht! Wenn nur zwei Absätze ausgewählt werden, kommt der alert. Du solltest allerdings auch abfangen, wenn nichts ausgewählt ist.
Wenn das Skript nur läuft, wenn drei Absätze ausgewählt sind, stellt sich diese Frage nicht. Das mit dem Verschieben ginge schon, aber zunächst muss die Auswahl geklärt werden. >> Du könntest prüfen, ob ein Text mit www im zweiten oder dritten Absatz steht und dann reagieren.
Ansonsten: Dein Objektformat 2 erhält eine Abweichung, wenn du das Absatzformat nachträglich zuweist. Ich würde das Absatzformat im Objektformat hinterlegen und dann den Text nicht verschieben, sondern nur den Inhalt einfügen.
Bei der Verankerung bin ich mir nicht ganz sicher, ob ich das richtig verstanden habe. Aber bei mir funktioniert folgendes:
Gruß Kai Rübsamen
(Dieser Beitrag wurde von Kai Rübsamen am 27. Jul 2016, 23:03 geändert)
Das bezieht sich dann natürlich darauf, wenn ich bei der ersten Abfrage 2 Absätze abfragen würde: Wenn ich dann in der Folge den zweiten Rahmen verankern will, kommt der Fehler.
// ein weiteres Problem ist, wenn ich die Webadresse im 2. Absatz habe und in diesem Absatz auch den 2. Rahmen erstelle, kann ich den Text nicht verschieben, weil ich ihn dann an die selbe Stelle verschieben würde (!?)
Wenn das Skript nur läuft, wenn drei Absätze ausgewählt sind, stellt sich diese Frage nicht. Das mit dem Verschieben ginge schon, aber zunächst muss die Auswahl geklärt werden. >> Du könntest prüfen, ob ein Text mit www im zweiten oder dritten Absatz steht und dann reagieren.
Auch diesen Punkt meinte ich unter der Annahme, nur zwei Absätze abzufragen. Ich wollte also erklären, warum drei Absätze markiert sein sollen. Im Prinzip würde es mir auch genügen, nur einen Absatz zu markieren, den mit der Webadresse. Aber ich kam bisher nur so zum Ziel.
Dein Objektformat 2 erhält eine Abweichung, wenn du das Absatzformat nachträglich zuweist. Ich würde das Absatzformat im Objektformat hinterlegen
Ja, das wäre einfacher und sauberer.
Bei der Verankerung bin ich mir nicht ganz sicher, ob ich das richtig verstanden habe.
Exakt so, hatte ich es gemeint
Aber bei mir funktioniert folgendes:
Bei mir auch. Vielen Dank! Auch für die Funktion und die vielen Vereinfachungen!
zunächst: Es gibt Beispieldateien und ein ausführbares Skript: Fast vorbildlich. Aber ;-) : Dein Beispiel ist ja eher "Hello world" als aus der Praxis gegriffen. D.h. wenn du vorher nachher Text hast oder deine URL zweizeilig sein kann, muss das auch im Beispiel abgebildet werden. Sonst kann es sein, das ein hier gepostetes Ergebnis nur zur Hälfte funktioniert. Also beim nächsten Mal …
Das bezieht sich dann natürlich darauf, wenn ich bei der ersten Abfrage 2 Absätze abfragen würde: Wenn ich dann in der Folge den zweiten Rahmen verankern will, kommt der Fehler.
Also: zunächst ist es wichtig, ob du das Skript für dich schreibst oder ob es andere ausführen. Wenn es nur für dich ist, reicht es, wenn du ein bisschen was prüfst. Ist es für Andere, sollte es Idiotensicher sein.
Egal wie, du musst dir Gedanken über die Auswahl machen: Ist nichts ausgewählt? Ist Text ausgewählt? Wieviel Absätze? Was soll passieren, wenn ein, zwei, drei oder mehr Absätze ausgewählt sind?
Wenn zwei Absätze ausgewählt sind, kannst du prüfen, ob im zweiten Absatz die Url steht, bei drei Absätzen, ob im dritten …
// ein weiteres Problem ist, wenn ich die Webadresse im 2. Absatz habe und in diesem Absatz auch den 2. Rahmen erstelle, kann ich den Text nicht verschieben, weil ich ihn dann an die selbe Stelle verschieben würde (!?)
In dem Fall musst du wahrscheinlich von deinem Absatz vorher das erste Zeichen abziehen und dann den Inhalt (nicht den Absatz) verschieben.
Im Prinzip würde es mir auch genügen, nur einen Absatz zu markieren, den mit der Webadresse. Aber ich kam bisher nur so zum Ziel.
Wo hakt es? Du könntest den Absatz markieren, zwei neue Returns vorher einfügen und dort dann deine Rahmen erstellen.
Achso: Überleg mal, ob deine Variablen etwas kürzer sein könnten. Dann wird der Code auch etwas übersichtlicher.
Gruß Kai Rübsamen
(Dieser Beitrag wurde von Kai Rübsamen am 28. Jul 2016, 19:54 geändert)
auch zweizeilige Beispiele anzuführen, wenn diese mit abgedeckt werden sollen, ist sicher sinnvoll. Im Übrigen ist das Skript tatsächlich nur für mich gedacht, daher muss das mit den Abfragen auch nicht unbedingt ;) idiotensicher sein.
Antwort auf: // ein weiteres Problem ist, wenn ich die Webadresse im 2. Absatz habe und in diesem Absatz auch den 2. Rahmen erstelle, kann ich den Text nicht verschieben, weil ich ihn dann an die selbe Stelle verschieben würde (!?)
In dem Fall musst du wahrscheinlich von deinem Absatz vorher das erste Zeichen abziehen und dann den Inhalt (nicht den Absatz) verschieben.
Hier komm ich nicht ganz mit: Was meinst Du mit abziehen? Löschen? Nicht in die Auswahl einbeziehen? Und wenn ich dann den Inhalt verschiebe (wie Du es in Deinem Skript in der Zeile
gemacht hast), fehlt das erste Zeichen dann nicht?
Du könntest den Absatz markieren, zwei neue Returns vorher einfügen und dort dann deine Rahmen erstellen.
Okay. Zwar kennte ich als Weg hierfür nur "changeGrep", womit ich es bestimmt etwas umständlicher machte als nötig, aber es wäre eine für mich handhabbare Möglichkeit.
Überleg mal, ob deine Variablen etwas kürzer sein könnten.
Durch das vorgeschaltete "my" haben meine Variablen immer schon mal zwei Zeichen, die könnte ich vielleicht weglassen. (Nebenbei: Deine "para3contents" ist zwar leicht erkennbar, aber auch nicht unbedingt kurz ;)
Hier komm ich nicht ganz mit: Was meinst Du mit abziehen? Löschen? Nicht in die Auswahl einbeziehen? Und wenn ich dann den Inhalt verschiebe (wie Du es in Deinem Skript in der Zeile
Anhand deines ersten move-Beispiels:
var curSel = app.selection[0]; $.writeln(curSel.paragraphs[1].characters.length); var insP = curSel.paragraphs[1].insertionPoints[0]; var tf = insP.textFrames.add({geometricBounds: [0, 0, 15, 40]}); $.writeln(curSel.paragraphs[1].characters.length); var cRange = curSel.paragraphs[1].characters.itemByRange(1, -2); $.writeln(cRange.length); cRange.move(LocationOptions.AT_END, tf.insertionPoints[0]);
Der zweite Absatz hat zunächst 26 Zeichen. Nach Einfügen des Textrahmens sind es 27. Verschoben dürfen aber nur 25 werden (27 - Textrahmen - Return).
Du könntest den Absatz markieren, zwei neue Returns vorher einfügen und dort dann deine Rahmen erstellen.
Hier würde ich versuchen, im contents 2x "\r" einzufügen. Falls dadurch die Auswahl durcheinander kommt, müsste man anders rangehen.