Vertikale Anordnung von Rahmen und mehrdimensionales Objekt

Indesign Automatisierung mit C# und JavaScript
Programme und Skripte, Libraries, Code Snippets und Basics
Anwenderforen für meine Programme und Skripte
domi77
Beiträge: 7
Registriert: 10. Jul 2014, 07:31

Vertikale Anordnung von Rahmen und mehrdimensionales Objekt

Beitrag von domi77 » 10. Jul 2014, 08:04

Hallo Werner,

vielen Dank erstmal für Deine zuvorkommende Hilfe, dass habe ich so noch nicht erlebt - ich bin begeistert. Es folgen die zwei Fragen in neutraler Form (für die die den anderen Thread nicht kennen).

Mein Ziel ist es in drei Stufen (3 Skripte die letztendlich zu einem vereinigt werden) ein Indesign-Dokument so zu verändern, dass vorliegende Rahmen und Objekte webbrowser-tauglich sind (1). Dazu nutze ich das Skript "prepare.jsx" - es entfernt Spalten aus Textrahmen, Rahmenüberfließenden Text und legt Absatz- und Zeichenstilvorlagen (für CSS) an. Dann exportiere ich in (2) "export.jsx" alle Koordinaten, Größen und sonstigen Parameter in einen JSON-String, außerdem exportiere ich alle Stories in INDD-tagged-text XML-Dokumente. Der letzte Teil des JSON-Strings ist eine Sammlung der Absatz- und Zeichenstilvorgaben, die ich mit prepare fixiert habe. In Teil (3) sammele ich eigentlich nur noch die Fonts (TTF, OTF) und Bilder. Alle Exporte werden zusammen auf einen Webserver geladen und durch PHP geparst, was letztendlich zur Darstellung des Druckbogens/der Seiten im Web führt.

1. Frage) Zuvor habe ich dieses Thema über IDML und XSLT gelöst, wobei die Reihenfolge der Tags (Rectangle, TextFrame, etc.) unabhängig von der Ebene gleichzeitig die vertikale Reihenfolge der Objekte beginnend mit dem untersten wiedergab. In meinem Skript "export.jsx" werden die Objekte, jedoch nach Typ im JSON-String aufgeführt, womit ich die Reihenfolge zerstöre. Es wäre notwendig eine entweder eine Reihenfolge per Nummer gesondert zu speichern oder die Objekte nicht sortiert auszugeben.

2. Frage) Die folgende Funktion aus "export.jsx" sammelt Namen und Parameter von Absatzstilvorlagen, sobald ich mehr als einen Parameter einkommentiere, läuft das Skript in einen Stapelüberlauf. Warum, es sind schon einige Daten, aber das sollte so nicht vorkommen?

Code: Alles auswählen

function doStylesProperty( /*document*/ document) { 
        try { 
            var paragraphStyles = document.paragraphStyles; 
            var numberOfParagraphs = paragraphStyles.length; 
            var obj_paragraphs = new Array(numberOfParagraphs); 
             
            for (var i = 0; i < numberOfParagraphs; i++) { 
                obj_paragraphs[i] = { 
                    paragraphStyleName : paragraphStyles[i].name, 
                    /*appliedFont  : paragraphStyles[i].appliedFont, 
                    appliedLanguage  : paragraphStyles[i].appliedLanguage, 
                    fillColor  : paragraphStyles[i].fillColor, 
                    fontStyle  : paragraphStyles[i].fontStyle, 
                    horizontalScale  : paragraphStyles[i].horizontalScale, 
                    hyphenWeight  : paragraphStyles[i].hyphenWeight, 
                    hyphenateAcrossColumns  : paragraphStyles[i].hyphenateAcrossColumns,  
                    hyphenateAfterFirst  : paragraphStyles[i].hyphenateAfterFirst,  
                    hyphenateBeforeLast  : paragraphStyles[i].hyphenateBeforeLast,  
                    hyphenateCapitalizedWords  : paragraphStyles[i].hyphenateCapitalizedWords,  
                    hyphenateLadderLimit  : paragraphStyles[i].hyphenateLadderLimit,  
                    hyphenateLastWord  : paragraphStyles[i].hyphenateLastWord,  
                    hyphenateWordsLongerThan  : paragraphStyles[i].hyphenateWordsLongerThan,  
                    hyphenation  : paragraphStyles[i].hyphenation, 
                    hyphenationZone  : paragraphStyles[i].hyphenationZone, 
                    justification  : paragraphStyles[i].justification, 
                    leftIndent  : paragraphStyles[i].leftIndent, 
                    pointSize  : paragraphStyles[i].pointSize, 
                    rightIndent  : paragraphStyles[i].rightIndent, 
                    spaceAfter  : paragraphStyles[i].spaceAfter, 
                    spaceBefore  : paragraphStyles[i].spaceBefore, 
                    strikeThru  : paragraphStyles[i].strikeThru, 
                    underline  : paragraphStyles[i].underline, 
                    verticalScale  : paragraphStyles[i].verticalScale*/ 
                } 
            } 
            
        } catch (error) { 
            alert(error); 
        } 
        return obj_paragraphs; 
    } 
Anbei eine ZIP mit den Skripten und einem Beispiel IDML mit Import-Bild. Danke für die Hilfe.

LG Dominik
Dateianhänge
Archiv.zip
(366.13 KiB) 1536-mal heruntergeladen

wernerperplies
Beiträge: 250
Registriert: 6. Aug 2011, 17:48
Wohnort: 18374 Zingst
Kontaktdaten:

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von wernerperplies » 10. Jul 2014, 08:20

Hallo Dominik,
vielen Dank erstmal für Deine zuvorkommende Hilfe, dass habe ich so noch nicht erlebt - ich bin begeistert.
Danke, es macht einfach Spaß, wenn ein Rat als das ankommt, als das es gedacht ist: ein Rat.

Und dann lernt man ja auch bei Fragen dazu, bekommt Input für eigene Ideen und manchmal nutzt ein Ratsuchender ja die Gelegenheit, sich mit meinen Skripten zu beschäftigen. :)
Es folgen die zwei Fragen in neutraler Form (für die die den anderen Thread nicht kennen).
Perfekt!

Ich werde mir jetzt Deine Datei und Deine Skripte genauer ansehen und mich später dazu nochmal melden.
einen schönen Tag wünscht

Werner Perplies
https://www.weepee.de

wernerperplies
Beiträge: 250
Registriert: 6. Aug 2011, 17:48
Wohnort: 18374 Zingst
Kontaktdaten:

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von wernerperplies » 10. Jul 2014, 08:50

Hallo Dominik,

Zwischenfrage:
Ich verstehe Dein Anliegen nicht so ganz:
1. Frage) Zuvor habe ich dieses Thema über IDML und XSLT gelöst, wobei die Reihenfolge der Tags (Rectangle, TextFrame, etc.) unabhängig von der Ebene gleichzeitig die vertikale Reihenfolge der Objekte beginnend mit dem untersten wiedergab. In meinem Skript "export.jsx" werden die Objekte, jedoch nach Typ im JSON-String aufgeführt, womit ich die Reihenfolge zerstöre. Es wäre notwendig eine entweder eine Reihenfolge per Nummer gesondert zu speichern oder die Objekte nicht sortiert auszugeben.
Und hätte deshalb auch noch gerne das Ergebnis DEines IDML/XSLT-Weges.

Zuvor aber eine etwas allgemeine Antwort auf Dein Anliegen:

Wenn ich etwas in einer bestimmten Reihenfolge ausgeben möchte, verwende ich je nach Aufwand in der Regel zwei unterschiedliche Wege:
  1. Direkt die Ausgabe in der richtigen Reihenfolge erzeugen
    oder
  2. Die Elemente als Array von Objekten ausgeben, die eine "Eigenschaft" order haben und am Ende dieses Array nach dem Feld Order sortieren.
Durch einen geschickten Aufbau des Job2Do-Objektes kannst Du zwar die Reihenfolge der Ausgabe der unterschiedlichen Eigenschaften steuern, aber nicht die Ausgabe in Reihenfolge der Elemente auf der Seite oder der Anordnung auf den Layout-Ebenen.

Es bleibt also nur der Wege einer zusätzlichen Sortierung.

Diese Sortierung kann m. E. vor der Erzeugung der JSON-Objekte oder danach erfolgen.

Was spricht gegen den Weg, alle auszugebenden Elemente in einem Array zu sammeln, dann das Array in die richtige Reihenfolge zu bringen und anschließend die JSON-Objekte gleich in der richtigen Reihenfolge zu erzeugen?
einen schönen Tag wünscht

Werner Perplies
https://www.weepee.de

wernerperplies
Beiträge: 250
Registriert: 6. Aug 2011, 17:48
Wohnort: 18374 Zingst
Kontaktdaten:

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von wernerperplies » 10. Jul 2014, 09:45

Hallo Dominik,
2. Frage) Die folgende Funktion aus "export.jsx" sammelt Namen und Parameter von Absatzstilvorlagen, sobald ich mehr als einen Parameter einkommentiere, läuft das Skript in einen Stapelüberlauf. Warum, es sind schon einige Daten, aber das sollte so nicht vorkommen?
Das Problem liegt hier:

Code: Alles auswählen

    function str(key, holder) {
        var i,
            k,
            v,
            length,
            mind = gap,
            partial,
            value = holder[key];

        if (value && typeof value === 'object' &&
            typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }


        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':

            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':

            return String(value);


        case 'object':

            if (!value) {
                return 'null';
            }

            gap += indent;
            partial = [];

            if (Object.prototype.toString.apply(value) === '[object Array]') {

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

                v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    if (typeof rep[i] === 'string') {
                        k = rep[i];
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {

                for (k in value) {
                    if (Object.prototype.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

            v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
Und speziell hier (endlose Rekursion)

Code: Alles auswählen

            if (Object.prototype.toString.apply(value) === '[object Array]') {

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

                v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

Ich habe jetzt hier nicht tiefer gesucht, schau Dir das mal im Einzelschrittverfahren an.

HTH
einen schönen Tag wünscht

Werner Perplies
https://www.weepee.de

domi77
Beiträge: 7
Registriert: 10. Jul 2014, 07:31

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von domi77 » 10. Jul 2014, 10:09

Hallo,

Beispiel-Ausgaben der XSL-Transformation kann ich Dir nicht direkt geben, aber ich werde das XSL-File mal anhängen. Man muss dann bspw. das machen:

Code: Alles auswählen

//PHP
$xslFile = 'pfadZuDemXSL';
$xmlFile = 'pfadZuEinemBeliebigenSpreadXmlAusDemIdmlArchiv'; //*.idml entpacken, und */Spreads/Spread_ub6.xml o.ä.nehmen
 
$xmlDoc = new DOMDocument();
$xmlDoc->load($xmlFile);

$xslt = new XSLTProcessor;

$xslt->registerPHPFunctions();
$xslt->importStyleSheet(DomDocument::load($xslFile));

$output = $xslt->transformToXML($xmlDoc);
echo $output;

//optional
function getBaseId() { //Dies ist eine Funktion die eine ID/Ordnernamen an das XSL sendet, damit die Pfade stimmen (wirst Du wohl i.d. Zusammenhang nicht brauchen, aber wer weiß)
    return 'base-' . $_GET['idmlId'];
}
Hier mal Pseudo-Code der Spread.xml:

Code: Alles auswählen

<Spread>
     <Rectangle id=1></Rectangle>
     <TextFrame id=1></TextFrame>
     <Rectangle id=2></Rectangle>
     <Layer id=2>
          <TextFrame id=3></TextFrame>
          <Rectangle id=4></Rectangle>
     </Layer>
     <Layer id=1>
          <TextFrame id=2></TextFrame>
          <Rectangle id=3></Rectangle>
     </Layer>
</Spread>
Das XML besagt, dass die Objekte wie folgt von Unten nach Oben angeordnet sind: R1-T1-R2-T3-R4-T2-R3. Übrigens ist Layer2 vor Layer1, weil es später eingefügt wurde und dann in der Anordnung eine Ebene tiefer gesetzt wurde (Bsp.).

In meinem Skript würden die Objekte folgendermaßen angeordnet werden: R1-R2-R3-R4/T1-T2-T3

Meine Annahme ist, dass wenn ich in JSX folgenden Befehl absetzte:

Code: Alles auswählen

var allItems = app.activeDocument.page[x].allItems;
... ich die Objekte in der korrekten Reihenfolge herausbekomme, aber wir sortieren ja anschließend alle Rects, TextFrames und Ovals, etc. nach Typ. Sowas ist gefragt:

Code: Alles auswählen

for (i=0; i < allItems; i++) {
     var arrayForJson.push(allItem[i].type);
}
[CODE]

das ergibt R-T-T-T-R-R-T-R-R-R-T bspw.

Bis später. LG
Dateianhänge
standard_form.xsl.zip
(4.52 KiB) 1474-mal heruntergeladen

wernerperplies
Beiträge: 250
Registriert: 6. Aug 2011, 17:48
Wohnort: 18374 Zingst
Kontaktdaten:

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von wernerperplies » 10. Jul 2014, 10:17

Hallo Dominik,
Meine Annahme ist, dass wenn ich in JSX folgenden Befehl absetzte:

Code: [Alles auswählen] [Expand/Collapse] [Download] (Untitled.txt)
var allItems = app.activeDocument.pages.allItems;
Bekommst Du wohl einen Syntaxerror ;-).

Aber sei es drum, die Reihenfolge der PageItems auf einer Seite ist recht willkürlich, zuerst einmal ergibt sie sich aus dem Zeitpunkt der Entstehung, danach kann sie sich regelmäßig durch Bearbeitung ändern.

Du musste deshalb in etwa so vorgehen:
  1. alle Seiten einlesen
  2. je Seite die Layer in der richtigen Reihenfolge einlesen
  3. je Layer die PageItems einlesen und nach der Location sortieren
  4. dann über das gesamte Array schleifen und mit meiner Routine für jedes Arrayelement die Eigenschaften auslesen und nach JSON exportieren
Alles klar?
einen schönen Tag wünscht

Werner Perplies
https://www.weepee.de

domi77
Beiträge: 7
Registriert: 10. Jul 2014, 07:31

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von domi77 » 10. Jul 2014, 11:16

Bin mit beiden Ansätzen gerade am kämpfen, dass geht schon sehr ins eingemachte. Aber ich versuchs, sollte ich es nicht hinbekommen, melde ich mich nochmal. Bei ersterem bin ich so weit, dass ich eine dynamische Variable vergebe.

Code: Alles auswählen

for (var i = 0; i < numberOfParagraphs; i++) {
                obj_paragraphs.i = {
                    paragraphStyleName : paragraphStyles[i].name,
                    appliedFont  : paragraphStyles[i].appliedFont,
                    appliedLanguage  : paragraphStyles[i].appliedLanguage,
                    fillColor  : paragraphStyles[i].fillColor,
                    fontStyle  : paragraphStyles[i].fontStyle,
                    horizontalScale  : paragraphStyles[i].horizontalScale,
                    hyphenWeight  : paragraphStyles[i].hyphenWeight,
                    hyphenateAcrossColumns  : paragraphStyles[i].hyphenateAcrossColumns,
                    hyphenateAfterFirst  : paragraphStyles[i].hyphenateAfterFirst,
                    hyphenateBeforeLast  : paragraphStyles[i].hyphenateBeforeLast,
                    hyphenateCapitalizedWords  : paragraphStyles[i].hyphenateCapitalizedWords,
                    hyphenateLadderLimit  : paragraphStyles[i].hyphenateLadderLimit,
                    hyphenateLastWord  : paragraphStyles[i].hyphenateLastWord,
                    hyphenateWordsLongerThan  : paragraphStyles[i].hyphenateWordsLongerThan,
                    hyphenation  : paragraphStyles[i].hyphenation,
                    hyphenationZone  : paragraphStyles[i].hyphenationZone,
                    justification  : paragraphStyles[i].justification,
                    leftIndent  : paragraphStyles[i].leftIndent,
                    pointSize  : paragraphStyles[i].pointSize,
                    rightIndent  : paragraphStyles[i].rightIndent,
                    spaceAfter  : paragraphStyles[i].spaceAfter,
                    spaceBefore  : paragraphStyles[i].spaceBefore,
                    strikeThru  : paragraphStyles[i].strikeThru,
                    underline  : paragraphStyles[i].underline,
                    verticalScale  : paragraphStyles[i].verticalScale
                }
            }
Jetzt muss ich nur noch die Funktion dazu kriegen eine Ebene tiefer im Objekt nach Werten zu suchen, daran scheitere ich gerade. Wird schon.

Gruss
Dominik

wernerperplies
Beiträge: 250
Registriert: 6. Aug 2011, 17:48
Wohnort: 18374 Zingst
Kontaktdaten:

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von wernerperplies » 10. Jul 2014, 11:50

Hallo Dominik,
Bin mit beiden Ansätzen gerade am kämpfen, dass geht schon sehr ins eingemachte. Aber ich versuchs, sollte ich es nicht hinbekommen, melde ich mich nochmal.
Gerne.
Bei ersterem bin ich so weit, dass ich eine dynamische Variable vergebe.
Ich bin jetzt ein wenig ins Schleudern gekommen, mit ersterem und zweitem. :)
Was meinst Du genau?

Was die Rekursion angeht, das dürfte ein Datentypproblem sein, vermutlich erhältst Du ein Array wo Du keins erwartest.

Rekursion ist eine super Sache, sie macht vieles einfacher, aber es muss immer ein eindeutiges Abbruchkriterium geben, z. B. Loop über Scheife, Loop über Bedingung, wenn sicher gestellt ist, dass sich die Bedingung irgendwann ändert.

Also melde Dich, wenn Du nicht weiter kommst, dann steige ich tiefer ein.

Viel Erfolg.
einen schönen Tag wünscht

Werner Perplies
https://www.weepee.de

domi77
Beiträge: 7
Registriert: 10. Jul 2014, 07:31

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von domi77 » 11. Jul 2014, 04:44

Guten Morgen,

irgendwie ist mir das zu hoch, da ich insbesondere mit der JS Kurzschreibweise nicht so vertraut bin. Nach einigen Fehlschlägen in der Funktion str(), habe ich mich wieder an die Ausgangsfunktion doStylesProperty() gemacht und habe diese so umgeschrieben, dass ein zu den Items und TextFrames identischer Objektbaum herauskommt. Ich nahm an das der Rest der Funktion (die nicht von mir ist) dann damit klarkommt, doch falsch gedacht der Stapelüberlauf bleibt bestehen. An dem anderen Problem war ich noch gar nicht dran.

Code: Alles auswählen

function doStylesProperty( /*document*/ document) {
         try {
             var paragraphStyles = document.paragraphStyles;
             var numberOfParagraphs = paragraphStyles.length;
             var obj_paragraphs = new Object();
             obj_paragraphs.paragraph = new Object();

             for (var i = 0; i < numberOfParagraphs; i++) {
                 var nameOfParagraph = paragraphStyles[i].name;
                 obj_paragraphs.paragraph[nameOfParagraph] = {
                     //paragraphStyleName : paragraphStyles[i].name,
                     appliedFont: paragraphStyles[i].appliedFont,
                     appliedLanguage: paragraphStyles[i].appliedLanguage,
                     fillColor: paragraphStyles[i].fillColor,
                     fontStyle: paragraphStyles[i].fontStyle,
                     horizontalScale: paragraphStyles[i].horizontalScale,
                     hyphenWeight: paragraphStyles[i].hyphenWeight,
                     hyphenateAcrossColumns: paragraphStyles[i].hyphenateAcrossColumns,
                     hyphenateAfterFirst: paragraphStyles[i].hyphenateAfterFirst,
                     hyphenateBeforeLast: paragraphStyles[i].hyphenateBeforeLast,
                     hyphenateCapitalizedWords: paragraphStyles[i].hyphenateCapitalizedWords,
                     hyphenateLadderLimit: paragraphStyles[i].hyphenateLadderLimit,
                     hyphenateLastWord: paragraphStyles[i].hyphenateLastWord,
                     hyphenateWordsLongerThan: paragraphStyles[i].hyphenateWordsLongerThan,
                     hyphenation: paragraphStyles[i].hyphenation,
                     hyphenationZone: paragraphStyles[i].hyphenationZone,
                     justification: paragraphStyles[i].justification,
                     leftIndent: paragraphStyles[i].leftIndent,
                     pointSize: paragraphStyles[i].pointSize,
                     rightIndent: paragraphStyles[i].rightIndent,
                     spaceAfter: paragraphStyles[i].spaceAfter,
                     spaceBefore: paragraphStyles[i].spaceBefore,
                     strikeThru: paragraphStyles[i].strikeThru,
                     underline: paragraphStyles[i].underline,
                     verticalScale: paragraphStyles[i].verticalScale
                 }
             }

         } catch (error) {
             alert(error);
         }
         return obj_paragraphs;
     }
Anbei ein Screenshot, dass der Objektbaum homogen ist.

LG Dominik
Dateianhänge
Bildschirmfoto 2014-07-11 um 05.30.41.png

wernerperplies
Beiträge: 250
Registriert: 6. Aug 2011, 17:48
Wohnort: 18374 Zingst
Kontaktdaten:

Re: Vertikale Anordnung von Rahmen und mehrdimensionales Obj

Beitrag von wernerperplies » 11. Jul 2014, 06:10

Hallo Dominik,

war das jetzt eine lange Nacht oder ein früher Morgen?
...da ich insbesondere mit der JS Kurzschreibweise nicht so vertraut bin...
Ich mag diese Schreibweise überhaupt und weiß auch nicht wo der Gewinn ist.

Für mich muss der Code möglichst übersichtlich und gut zu debuggen sein.

Deshalb versuche ich meistens für jedes Statement eine Zeile zu verwenden, - nach dem Motto:
Den Rest wird der Runtime-Compiler wirds schon richten.

Für mich liegt die Ursache des Problems ganz klar in der str()-Funktion .

Un die werde ich mir jetzt mal genauer zu Gemüte führen. Ich melde mich später dazu.
einen schönen Tag wünscht

Werner Perplies
https://www.weepee.de

Antworten

Zurück zu „Adobe® InDesign® Automatisierung“