[GastForen Programme Print/Bildbearbeitung Adobe InDesign Skriptwerkstatt Array sortieren

  • Suche
  • Hilfe
  • Lesezeichen
  • Benutzerliste
Print/Bildbearbeitung - Photos, Layout, Design
Themen
Beiträge
Moderatoren
Letzter Beitrag

Array sortieren

former
Beiträge gesamt: 164

10. Sep 2011, 14:15
Beitrag # 1 von 21
Bewertung:
(6987 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo,

um eine Bibliographie alphabetisch zu sortieren, habe ich die Funktion sort() ins Auge gefasst und folgendes Skript zusammengesucht:
Code
#target InDesign 
var _doc = app.selection[0];
var _abs = _doc.paragraphs;
var _absInhalt = new Array();

for (var n = 0; n <_abs.length; n++){
var _eintrag = _abs[n].contents;
_absInhalt.push(_eintrag);
};

_absInhalt.sort();
$.writeln(_absInhalt.join(""));

Das funktioniert, der Konsole kann ich meine sortierten Einträge entnehmen; allerdings sind diese nun natürlich nicht mehr formatiert.
Ein weiterer Versuch, bei dem ich das Array mit texts(0) fülle (um die Formatierung zu behalten), führt nicht zum Erfolg. Statt einer alphabetischen Sortierung wird nur die Reihenfolge umgekehrt:
Code
#target InDesign 
var _doc = app.activeDocument;
var _docAusw = app.selection[0];
var _abs = _docAusw.paragraphs;
var _textFrame = _doc.textFrames.add({geometricBounds:[0,-100,300, 0]});
var _absInhalt = new Array();

for (var n = 0; n <_abs.length; n++){
var _eintrag = _abs[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame.insertionPoints[0]);
_absInhalt.push(_eintrag);
};

_absInhalt.sort();

Ich vermute, dass hierbei irgendwelche Zahlen eine Rolle spielen, die am Anfang der einzelnen Einträge im Array stehen und nach denen sortiert wird?
Kann mir bitte jemand sagen, wo der Fehler ist; oder vielleicht auch, wie er oder sie das Problem angehen würde!? Bin auch für Quick'n'dirty zu haben, denn falls ich das Problem nicht per Skript lösen kann, muss ich 717 (!) Titel von Hand sortieren.
Vielen Dank und Gruß
Jan
X

Array sortieren

WernerPerplies
Beiträge gesamt: 2762

10. Sep 2011, 16:43
Beitrag # 2 von 21
Beitrag ID: #479978
Bewertung: ||
(6961 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Jan,

ohne Deinen Code näher untersucht zu haben und Deine Daten genau zu kennen, würde ich so vorgehen:

Ein zwei- oder mehrdimensionales Array (je nach Anforderung) erstellen:

z. B.:

Element:
["reiner Text", (Element mit formatiertem Text)]

nach diesem Schema füllst Du Dein Array mit allen Elementen.

Dann schreibst Du eine Funktion "sortElements":

Sorry: Korrektur: statt:
function sortElements(e1, e2)
{
if (e1[1]<e2[1]) return -1;
if (e1[1]>e2[1]) return 1;
return 0;
}

function sortElements(e1, e2)
{
if (e1[0]<e2[0]) return -1;
if (e1[0]>e2[0]) return 1;
return 0;
}

Dann sortierst Du Dein Array so:
meinArrays(sortElements);

Umkehren kannst Du die Reihenfolge durch vertauschen von 1 und -1.

Anschließend sollten Deine Elemente in der richtigen Reihenfolge vorliegen und Du kannst die Daten entsprechend ausgeben.

HTH.


als Antwort auf: [#479971]
(Dieser Beitrag wurde von WernerPerplies am 10. Sep 2011, 17:01 geändert)

Array sortieren

Marco Morgenthaler
Beiträge gesamt: 2474

10. Sep 2011, 17:03
Beitrag # 3 von 21
Beitrag ID: #479979
Bewertung:
(6948 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Jan

Hast du das in Indesign standardmässig mitgelieferte Skript SortParagraphs.jsx (zu finden in der Skripte-Palette) schon ausprobiert?

Gruss, Marco


als Antwort auf: [#479971]

Array sortieren

Peter Kahrel
Beiträge gesamt: 182

10. Sep 2011, 19:16
Beitrag # 4 von 21
Beitrag ID: #479983
Bewertung:
(6905 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Jan,

Vielleicht könnst Du dieses Skript probieren: http://www.kahrel.plus.com/indesign/sort.html. Damit kann man Absätze sortieren und die Formattierung behalten. Es benützt teilweise die Methode die Werner erwähnte. Das Skript das Marco zitierte funktioniert auch, ist aber sehr langsam.

Peter


als Antwort auf: [#479971]

Array sortieren

former
Beiträge gesamt: 164

11. Sep 2011, 13:56
Beitrag # 5 von 21
Beitrag ID: #479993
Bewertung:
(6845 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Werner, Marco und Peter,

zunächst habt vielen, vielen Dank für Eure Antworten.

Bevor ich jedoch auf diese eingegangen bin, habe ich noch eine eigene Idee ausprobiert, und zwar die vorhandenen Formatierungen (ist ja alles mit Zeichenformaten versehen) mit Sonderzeichen vorab zu markieren, um sie nach der Sortierung mit dem "Konsolenskript" per S&E wieder herzustellen. Allerdings kann die Konsole wohl nur eine begrenzte Anzahl von Einträgen aufnehmen, 7 Seiten hat sie noch bewältigt, bei 11 blieb sie aber einfach stumm. Nun gut, ich nehme an, die Konsole ist auch nicht dafür gedacht (sondern lediglich oder vorrangig als Kontrollmöglichkeit beim Programmieren?).

Dann habe ich ein kleines Beispiel mit SortParagraphs.jsx rechnen lassen (das ich tatsächlich nicht kannte), hier kam es jedoch zunächst einmal zu einer Verschiebung der Kursivierung, also eine Reihe von Buchstaben vor dem Beginn des eigentlich kursivierten Bereichs war nach dem Sortieren kursiviert, die entsprechende Anzahl am Ende war nicht kursiviert. Das scheint jedoch ein temporäres Problem gewesen zu sein, denn nachdem ich meine Markierung wie oben beschrieben vorgenommen hatte und das Skript dann gleich mal für mein ganzes Dokument laufen ließ, war die Formatierung am Ende gut (so weit ich sehen konnte). Aber: Es dauerte Stunden! Und hier war ich unklug: und hab das Skript bzw. InDesign mit dem Windows-Task-Manager abgebrochen (ich weiß, ich weiß), mit der Folge, dass das Skript nun stets einen Laufzeitfehler verursacht und unbrauchbar ist. (Falls jemand eine Theorie oder Fakten hat, ob das zusammenhängen kann, und vielleicht auch, wie ich es beheben könnte, wäre ich sehr dankbar.) Immerhin hat es so weit gut sortiert, aber eben nicht zu Ende.

Okay, zum Glück haben wir ja noch Peter Kahrel. Mit seinem Skript habe ich meine Bibliographie nun schön sortiert, alle Formatierungen sind wie zuvor, und gedauert hat es ca. eine Minute. Allerdings gab es zwei Einschränkungen: Erstens lief es nur bei Auswahl eines Textrahmens. Die Auswahl der Absätze verursachte Fehlernummer: 30477 in Zeile 164: "Ungültiger Wert für Parameter "reference" von Ereignis "move". Text, Story, Cell, Row, Column, Table or PageItem erwartet, aber nothing erhalten." Zweitens blieben drei Einträge am Ende "übrig", standen also recht verloren, wenngleich intern sortiert, mit Leerzeile getrennt am Ende des Textes. (Das schreibe ich rein informativ, vielleicht kann es ja zur Verbesserung beitragen, vielleicht sind die Sachverhalte aber auch auf meine individuellen Paramter zurückzuführen.)

Schließlich habe ich auch noch versucht, Werners Weg zu gehen. Das Array habe ich zweidimensional erstellt (glaube ich zumindest), und zwar mit folgender Schleife:
Code
for (var n = 0; n <_abs.length; n++){  
var _eintr_text = _abs[n].contents;
var _eintr_form = _abs[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame.insertionPoints[0]);
_absInhalt.push[_eintr_text, (_eintr_form)];
};

Auch die Funktion wird fehlerfrei absolviert. Doch für die anschließende Zeile
_absInhalt(sortElements);
erhalte ich die Meldung: "Array ist keine Funktion"? Es ist klar, dass nach Lösung des Problems meine Motivation, hier weiterzubasteln, etwas geschwunden ist. Nichtsdestotrotz wäre für den Lerneffekt hier natürlich am meisten zu holen.

Das war's von mir. Noch einmal ein dickes Dankeschön an alle Beteiligten,
Gruß
Jan


als Antwort auf: [#479983]

Array sortieren

Peter Kahrel
Beiträge gesamt: 182

11. Sep 2011, 14:25
Beitrag # 6 von 21
Beitrag ID: #479997
Bewertung:
(6834 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Jan,

Wenn Du mir deine Datei schickst, kann ich sehen was falsch geht. Bitte kahrel@kahrel.plus.com benützen.

Peter


als Antwort auf: [#479993]
(Dieser Beitrag wurde von Peter Kahrel am 11. Sep 2011, 14:27 geändert)

Array sortieren

WernerPerplies
Beiträge gesamt: 2762

11. Sep 2011, 14:28
Beitrag # 7 von 21
Beitrag ID: #479998
Bewertung:
(6829 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Jan,

könntest Du mal Dein ganzes Skript zeigen?

Zitat for (var n = 0; n <_abs.length; n++){
var _eintr_text = _abs[n].contents;
var _eintr_form = _abs[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame.insertionPoints[0]);
_absInhalt.push[_eintr_text, (_eintr_form)];
};


Mir fehlt die Deklaration des Arrays und Definition der Sortierfunktion, außerdem scheint die Zeile mit dem Push syntaktisch nicht korrekt zu sein.

Es sollte in etwa so aussehen:
Code
function loadAndSortArray(_abs, _textFrame) 
{
var array2Sort = new Array();
// dann (den Teil habe ich nicht geprüft!)
for (var n = 0; n <_abs.length; n++){
var _eintr_text = _abs[n].contents;
var _eintr_form = _abs[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame.insertionPoints[0]);
// hier nicht:
_absInhalt.push[_eintr_text, (_eintr_form)];
// sondern

_absInhalt.push([_eintr_text, (_eintr_form)]);
}

return _absInhalt.sort(sortElements);
}
function sortElements(e1, e2)
{
if (e1[0]<e2[0]) return -1;
if (e1[0]>e2[0]) return 1;
return 0;
}

So, ich hoffe, ich habe nichts übersehen.


als Antwort auf: [#479993]

Array sortieren

former
Beiträge gesamt: 164

11. Sep 2011, 16:50
Beitrag # 8 von 21
Beitrag ID: #480006
Bewertung:
(6795 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Peter,
ich habe Dir gemailt.

Hallo Werner,

zunächst ganz uneitel mein Versuch:
Code
#target InDesign 
var _doc = app.activeDocument;
var _docAusw = app.selection[0];
var _abs = _docAusw.paragraphs;
var _textFrame = _doc.textFrames.add({geometricBounds:[0, -100, 300, 0]});
var _textFrame2 = _doc.textFrames.add({geometricBounds:[100, 150, 0, 300]});

var _absInhalt = new Array();

$.writeln(_abs.length);
for (var n = 0; n <_abs.length; n++){
var _eintr_text = _abs[n].contents;
var _eintr_form = _abs[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame.insertionPoints[0]);
_absInhalt.push[_eintr_text, (_eintr_form)];
};
$.writeln(_absInhalt);

function sortElements(e1, e2)
{
if (e1[0]<e2[0]) return -1;
if (e1[0]>e2[0]) return 1;
return 0;
}

_absInhalt(sortElements);

_absInhalt[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame2.insertionPoints[0]);

Schließlich hab ich versucht, Deine Ergänzungen zu berücksichtigen:
Code
#target InDesign 

var _doc = app.activeDocument;
var _docAusw = app.selection[0];
var _abs = _docAusw.paragraphs;

var _textFrame = _doc.textFrames.add({geometricBounds:[0, -100, 300, 0]});
var _textFrame2 = _doc.textFrames.add({geometricBounds:[100, 150, 0, 300]});

var _absInhalt = new Array();

$.writeln(_abs.length);
function loadAndSortArray(_abs, _textFrame)
{
var array2Sort = new Array();
// dann (den Teil habe ich nicht geprüft!)
for (var n = 0; n <_abs.length; n++){
var _eintr_text = _abs[n].contents;
var _eintr_form = _abs[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame.insertionPoints[0]);
_absInhalt.push([_eintr_text, (_eintr_form)]);
}

return _absInhalt.sort(sortElements);
}
function sortElements(e1, e2)
{
if (e1[0]<e2[0]) return -1;
if (e1[0]>e2[0]) return 1;
return 0;
}

_absInhalt(sortElements);

_absInhalt[n].texts[0].duplicate(LocationOptions.AFTER, _textFrame2.insertionPoints[0]);

Das führt aber zum selben Fehler. Ganz bestimmt ist eine grobe Unachtsamkeit oder Unkenntnis meinerseits dafür verantwortlich, denn bedenke bitte, mein Status ist der eines bloody newbie.

Trotzdem danke Euch beiden,
Gruß
Jan


als Antwort auf: [#479998]

Array sortieren

WernerPerplies
Beiträge gesamt: 2762

11. Sep 2011, 17:34
Beitrag # 9 von 21
Beitrag ID: #480007
Bewertung:
(6777 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Jan,

Zitat mein Status ist der eines bloody newbie


Kein Problem, jeder fängt mal an.

Ich würde mir an Deiner Stelle mal ein gutes Buch zur Programmierung zu Gemüte führen.

Also kein Buch zum InDesign-Scripting, dass sollte erst später kommen, denn das ist angewandtes JavaScript.

Ich denke, Dein Problem ist die Reihenfolge der Statements und Syntaxfehler:

Deshalb mal ein wenig zur Technik:

Wenn Du einfach loslegst mit:
var eins; var zwei; var drei;

Definierst Du globale Variablen, deren Inhalt im ganzen Script zu sehen und veränderbar ist.

Das sollte, wenn immer es geht, vermeiden!

besser :

main(); // Aufruf der Funktion main;

function main()
{
// alles was hier definiert wird, ist auch nur hier sichtbar,
// es sei denn, Du übergibst die Variablen einer anderen
// Funktion.
return [optional variable als Parameter}
}

Alle Statements werden innerhalb einer Funktion der Reihe nach abgearbeitet, innerhalb von Funktionen können wieder Funktionen aufgerufen werden.

Bei den Variablen würde ich die Unterstriche weglassen, das macht alles sehr unübersichtlich.

Besser ist die CamelCase-Schreibweise.

Und wenn Du Variablen innerhalb von Funktionen aufrufst, kannst Du auch so etwas wie myVariable weglassen, eine sauber definierte Varaible innerhalb einer Funktion ist eigentlich immer als Deine Variable erkennbar.

Schreibe kurze Funktionen, dann bleibt Dein Skript übersichtlich.

Ein Programm in viele Unterfunktionen aufzuteilen macht die Ausführung minimal langsamer, fördert aber die Übersichtlichkeit ungemein.

Ach ja, wenn ich schon mal dabei bin, vergesse bei der Varablendefinition innerhalb einer Funktion NIEMALS das Wort var. JavaScript macht Dir daraus dann still und heimlich eine globale Variable.

Globale Variablen sollte man NIE, wenn man sie dann schon benutzen muss, innerhalb einer Funktion definieren, sondern am Anfang des Scripts.

Anbei noch ein kleines Script zur Demonstration des Sortierverfahrens:
Code
main(); 

function main()
{
var array2Sort = [["9", "neun"], ["2", "zwei"], ["4", "vier"],["1", "eins"],
["6", "sechs"], ["8", "acht"], ["0", "null"],["5", "fünf"],];
var sortedArray = sortArray(array2Sort);
alert(sortedArray);
}
function sortArray(array2Sort)
{
return array2Sort.sort(sortElements);
}
function sortElements(e1, e2)
{
if (e1[0]<e2[0]) return -1;
if (e1[0]>e2[0]) return 1;
return 0;
}



als Antwort auf: [#480006]

Array sortieren

gfellenz
Beiträge gesamt: 121

11. Sep 2011, 18:15
Beitrag # 10 von 21
Beitrag ID: #480008
Bewertung: ||
(6761 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
hallo former,

nur der vollständigkeit halber habe ich deine erste lösung vervollständigt und mit kommentaren versehen - vielleicht bringt das etwas lerneffekt. die alternativen lösungen für das problem wurden hier ja bereits diskutiert. ich fand deinen ansatz aber eigentlich recht geradheraus runterprogrammiert.

Code
#target InDesign  
var _doc = app.activeDocument;
var _docAusw = app.selection[0];
var _abs = _docAusw.paragraphs;
var _textFrame = _doc.textFrames.add({geometricBounds:[0,-100,300, 0]});
var _absInhalt = new Array();

for (var n = 0; n <_abs.length; n++){
// es reicht einfach das Paragraph-Objekt in den Array zu packen.
var _eintrag = _abs[n];
_absInhalt.push(_eintrag);
}

// im array befinden sich jetzt Paragraph-Objekte, die kann man mit dem normalen sort() nicht mehr sortieren. deswegen muss man sich eine eigene funktion für die sortierung schreiben, die die eigenschaft contents auswertet (siehe unten).
_absInhalt.sort(sort_TextObject_DE);

// nach der sortierung muss der inhalt wieder in den textrahmen - join() funktioniert hier ebenfalls wegen dem Paragraph-Objekt nicht. alternativ würde sich eventuell noch move anbieten.
for (var n = 0; n <_abs.length; n++){
_absInhalt[n].duplicate(LocationOptions.AFTER, _textFrame.insertionPoints[-1]);
}


function sort_TextObject_DE (a, b) {
// ich gehe mal davon aus, dass du deutsche textet sortiert, deswegen wird es etwas umständlicher.
a = removeUmlaut (a);
b = removeUmlaut (b);
if (a ==b) return 0;
if (a > b) return 1;
else return -1;
// Umluate für die Sortierung entfernen
function removeUmlaut (a) {
// hier ist der entscheidende punkt für die sortierfunktion: aus der eigenschaft contents wird der zu sortierende text ermittelt.
a = a.contents.toLowerCase();
a = a.replace(/ä/g,"a");
a = a.replace(/ö/g,"o");
a = a.replace(/ü/g,"u");
a = a.replace(/ß/g,"s");
return a;
}
}


falls du mein buch hast (sieht so aus wegen der schreibweise der variablen): auf seite 255 wird ein ähnlicher fall beschrieben.

ps: @werner: sehe ich etwas anders mit dem buch. auch wenn ich als autor befangen bin, hilft es meiner ansicht nach wenig web-javascript zu lernen und dann auf indesign umzusteigen. soweit war former von der richtigen lösung auch gar nicht entfernt.

und auch das video von gerald singelmann, oder das buch von peter kahrel sind auf einsteiger ausgelegt.


als Antwort auf: [#479971]

Array sortieren

WernerPerplies
Beiträge gesamt: 2762

11. Sep 2011, 18:18
Beitrag # 11 von 21
Beitrag ID: #480009
Bewertung:
(6761 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Jan,

noch eine Ergänzung, die Fehlermeldung kommt durch diese Zeile:

_absInhalt(sortElements)

JavaScript meckert hier völlig zu recht, dass Du eine Array als Funktion missbrauchst.

Korrekt wäre die Array-Methode
_absInhalt.sort(sortElements);


als Antwort auf: [#480006]

Array sortieren

former
Beiträge gesamt: 164

11. Sep 2011, 18:45
Beitrag # 12 von 21
Beitrag ID: #480012
Bewertung:
(6751 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Werner,

danke für Deine Antwort und die praktischen Hinweise. Bei meinen nächsten Versuchen werden sie mir bestimmt hilfreiche Dienste leisten.

Also bis bald,
Gruß
Jan


als Antwort auf: [#480007]

Array sortieren

former
Beiträge gesamt: 164

11. Sep 2011, 19:18
Beitrag # 13 von 21
Beitrag ID: #480013
Bewertung:
(6723 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo gfellenz,

hab vielen Dank für Deine Antwort und die aufmunternde Worte. Dass Du Dir so viel Zeit genommen hast, finde ich großartig. In jedem Fall ist so ein individueller Korrekturdurchgang nicht selbstverständlich, also nochmals danke.
Im Übrigen konnte ich Deine "Verbesserung" in Teilen nachvollziehen, das function-Prinzip muss ich mir aber noch mal separat vornehmen. Zunächst mal war es die Information, dass die sort()-Funktion in einem array mit Paragraph-Objekten nicht läuft, die mir fehlte.
Wie auch immer, nun läuft "mein" Skript rund!

Bis bald,
Gruß
Jan


als Antwort auf: [#480008]

Array sortieren

former
Beiträge gesamt: 164

11. Sep 2011, 19:22
Beitrag # 14 von 21
Beitrag ID: #480014
Bewertung:
(6720 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
{Und noch einmal zu }
Werner,
genau; in dieser Zeile habe ich das .sort vor der Klammer verschludert. Aber auch in der nächsten Zeile gibt es nun einen Stopp. Für den Moment lass ich es aber dabei bewenden, langsam, aber sicher schwirrt mir der Kopf.
Jedenfalls danke noch einmal für Deine Unterstützung.
Gruß
Jan


als Antwort auf: [#480009]

Array sortieren

WernerPerplies
Beiträge gesamt: 2762

11. Sep 2011, 19:32
Beitrag # 15 von 21
Beitrag ID: #480017
Bewertung:
(6715 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Gregor,

Zitat ps: @werner: sehe ich etwas anders mit dem buch. auch wenn ich als autor befangen bin, hilft es meiner ansicht nach wenig web-javascript zu lernen und dann auf indesign umzusteigen. soweit war former von der richtigen lösung auch gar nicht entfernt.



Am besten wäre natürlich ein Buch über Programmiertechnik, den JavaScript gehört ja nun nicht gerade zu den Sprachen, die sauberes Programmieren forcieren, aber Webprogrammierung ist ja auch nur eine Anwendung von JavaScript.

Aber Du hast Recht, die meisten Bücher haben als Schwerpunkt Webprogrammierung.

Für mich (ich programmiere ja auch erst kurz mit JavaScript) hat sich das Buch von Stefan Koch: JavaScript als besonders geeignet erweisen. - Es gibt da gerade eine Neuauflage.


als Antwort auf: [#480008]
X