[GastForen Programme Print/Bildbearbeitung Adobe InDesign Skriptwerkstatt app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

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

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Martin Fischer
  
Beiträge gesamt: 12783

18. Jun 2016, 17:21
Beitrag # 1 von 11
Bewertung:
(6979 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
var ftp_ps = app.findTextPreferences.appliedParagraphStyle;

sowie

var fgp_ps = app.findGrepPreferences.appliedParagraphStyle;

geben den Namen des Absatzformats, das in der Suchen/Ersetzen-Palette eingestellt ist, als String zurück.
Auch dann, wenn es sich um Absatzformate aus einer Gruppe handelt.

Kennt jemand eine Möglichkeit, statt des Strings das paragraphStyle-Objekt mitsamt der parent-Eigenschaft (über welche ggf. die Formatgruppe zu ermitteln wäre) zu ermitteln?
Auch wenn ein Absatzformat mit diesem Namen in mehreren unterschiedlichen Gruppen vorkommt?

Wie ist die passende AF-Gruppe (und bei Verschachtelungen die Folgen der Gruppen) zu ermitteln?


(Wenn in den Preferences nur der Name auftaucht, wie weiß dann InDesign welches AF aus welcher Formatgruppe das richtige ist?)


Dasselbe gilt für Zeichenformate und Zeichenformatgruppen.

(Dieser Beitrag wurde von Martin Fischer am 18. Jun 2016, 17:23 geändert)
X

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Uwe Laubender
Beiträge gesamt: 5319

19. Jun 2016, 13:04
Beitrag # 2 von 11
Beitrag ID: #550563
Bewertung:
(6867 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Martin,
das Zurückliefern eines Strings dürfte der Tatsache geschuldet sein, dass die Suchen/Ersetzen-Funktion auch dokumentübergreifend funktionieren kann.

Die einfachste Möglichkeit ist:
Du lässt die Suche laufen und fragst das Ergebnis ab:

Code
main(); 
function main()
{
var doc = app.documents[0];

var easySearchResult = doc.findText();
if(easySearchResult.length >0)
{
var paraStyle = easySearchResult[0].appliedParagraphStyle;
alert("Found by EasySearch:"+"\r"+paraStyle.name+" ("+paraStyle.parent.name+")");
return paraStyle;
}
};


Falls das Absatzformat im Root der Absatzformatpalette liegt, wird als parent der Name des Dokuments erscheinen.

Was aber machen, falls kein Ergebnis vorliegt?
Das Absatzformat wurde nirgends im Dolument angwendet. Du möchtest aber trotzdem wissen, was da genau vom Anwender gesucht wird.

Meine Überlegung ist, das
Code
allParagraphStyles 

Array zu benutzen, einen neuen, temporären Text anzulegen, der [b]alle im Dokument definierten Absatzformate benutzt und die Suche dann über diesen Text laufen zu lassen.

Stolperstein bei diesem Ansatz:
Erschwerend hinzu kommt die Tatsache, dass der Anwender nach noch mehr Kriterien suchen könnte. Also nicht nur nach dem Absatzformat, sondern beispielsweise einen Text mit der Farbe "Rot" als lokale Abweichung zum gesuchten Absatzformat.

Der temporäre Dummytext müsste also auch diese Abweichung aufweisen, um gefunden werden zu können.

Weiter unten mal ein Entwurf mit dem ich die oben genannten Kriterien versuche zu erfüllen. Allerdings habe ich diesen Ansatz noch nicht vollumfänglich getestet. Läuft aber mit zusätzlichen Suchkriterien wie "Füllfarbe" oder "Textgröße" einandfrei.

Ich denke, dieser Ansatz ließe sich auch allgemeiner schreiben, wenn nach Zeichenformaten gesucht werden soll oder anstatt der Text-Suche die GREP-Suche ausgewertet sein will.

Hat man einmal das Absatzformat-Objekt, ist es ein Leichtes die zugehörige Gruppenhierarchie über dessen parent-Eigenschaft zu ermitteln. Auch die id des Absatzformats ist hilfreich.

Code
// Whats-in-TEXT-Searchs-AppliedParagraphStyle.jsx 
// Uwe Laubender

/**
* @@@BUILDINFO@@@ Whats-in-TEXT-Searchs-AppliedParagraphStyle.jsx !Version! Sun Jun 19 2016 12:50:36 GMT+0200
*/

/*
See discussion at HDS:
"app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?"
Martin Fischer | 18. Jun 2016, 17:21
http://www.hilfdirselbst.ch/gforum/gforum.cgi?post=550558#550558
*/

// Returns a paragraphStyle object or alerts that nothing could be found.

main();

function main()
{

var doc = app.documents[0];

var easySearchResult = doc.findText();
if(easySearchResult.length >0)
{
var paraStyle = easySearchResult[0].appliedParagraphStyle;
alert("Found by EasySearch:"+"\r"+paraStyle.name+" ("+paraStyle.parent.name+")");
return paraStyle;
}

var allParagraphStylesArray = doc.allParagraphStyles;
var tempTextFrame = doc.textFrames.add();
var tempStory = tempTextFrame.parentStory;
var oldProperties = app.findTextPreferences.properties;

for(var n=allParagraphStylesArray.length-1;n>=0;n--)
{
tempStory.texts[0].insertionPoints[0].contents = n+"\r";
tempStory.texts[0].characters[0].appliedParagraphStyle = allParagraphStylesArray[n];

for(var x in oldProperties)
{
try
{
if(x != "appliedParagraphStyle")
{
tempStory.texts[0].paragraphs[0][x] = oldProperties[x];
}
}
catch(e){};

}

}

var complexSearchResult = tempStory.findText();

if(complexSearchResult.length == 0)
{
return alert("Sorry. No match found.");
};


var paraStyle = complexSearchResult[0].appliedParagraphStyle;
alert("Found by complexSearch:"+"\r"+paraStyle.name+" ("+paraStyle.parent.name+")");

tempTextFrame.remove();

return paraStyle;

};



als Antwort auf: [#550558]

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Uwe Laubender
Beiträge gesamt: 5319

19. Jun 2016, 13:18
Beitrag # 3 von 11
Beitrag ID: #550564
Bewertung:
(6864 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Antwort auf [ Martin Fischer ] … (Wenn in den Preferences nur der Name auftaucht, wie weiß dann InDesign welches AF aus welcher Formatgruppe das richtige ist?) …


Ich vermute eine Nachlässigkeit seitens der Entwickler was das DOM angeht.

Denn der Name der Gruppe wird im UI in Klammern nach dem Absatzformatnamen angegeben, wenn das Absatzformat in einer Gruppe verschachtelt ist. Per Skript wird zwar nur der Name des Absatzformats zurückgegeben, aber intern weiss InDesign sehr genau welches Absatzformat gesucht wird.


als Antwort auf: [#550558]

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Uwe Laubender
Beiträge gesamt: 5319

19. Jun 2016, 13:50
Beitrag # 4 von 11
Beitrag ID: #550565
Bewertung:
(6834 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Eine Vereinfachung meines Codes von oben wäre die for-Schleife etwas zu entlasten. Die for-x-in-Schleife braucht es nur einmal. Die kann dann angewendet werden, wenn der gesamte Dummy-Text geschrieben ist:

Code
// Whats-in-TEXT-Searchs-AppliedParagraphStyle-v2.jsx 
// Uwe Laubender

/**
* @@@BUILDINFO@@@ Whats-in-TEXT-Searchs-AppliedParagraphStyle-v2.jsx !Version! Sun Jun 19 2016 13:48:26 GMT+0200
*/

/*
See discussion at HDS:
"app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?"
Martin Fischer | 18. Jun 2016, 17:21
http://www.hilfdirselbst.ch/gforum/gforum.cgi?post=550558#550558
*/

main();

function main()
{

var doc = app.documents[0];

var easySearchResult = doc.findText();
if(easySearchResult.length >0)
{
var paraStyle = easySearchResult[0].appliedParagraphStyle;
alert("Found by EasySearch:"+"\r"+paraStyle.name+" ("+paraStyle.parent.name+")");
return paraStyle;
}

var allParagraphStylesArray = doc.allParagraphStyles;
var tempTextFrame = doc.textFrames.add();
var tempStory = tempTextFrame.parentStory;
var oldProperties = app.findTextPreferences.properties;

for(var n=allParagraphStylesArray.length-1;n>=0;n--)
{
tempStory.texts[0].insertionPoints[0].contents = n+"\r";
tempStory.texts[0].characters[0].appliedParagraphStyle = allParagraphStylesArray[n];

}

for(var x in oldProperties)
{
try
{
if(x != "appliedParagraphStyle")
{
tempStory.texts[0][x] = oldProperties[x];
}
}
catch(e){};

}

var complexSearchResult = tempStory.findText();

if(complexSearchResult.length == 0)
{
return alert("Sorry. No match found.");
};


var paraStyle = complexSearchResult[0].appliedParagraphStyle;
alert("Found by complexSearch:"+"\r"+paraStyle.name+" ("+paraStyle.parent.name+")");

tempTextFrame.remove();

return paraStyle;

};


Zudem müsste man noch eine Lösung einbauen, die darauf Rücksicht nimmt, dass der Anwender zugleich nach einem Absatzformat und einem angewendeten Zeichenformat sucht, das in einer Gruppe steht.

Da nützt die Zuweisung des Zeichenformatnamens für den Dummy-Text absolut nichts.


als Antwort auf: [#550564]

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Martin Fischer
  
Beiträge gesamt: 12783

19. Jun 2016, 14:45
Beitrag # 5 von 11
Beitrag ID: #550566
Bewertung:
(6784 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Uwe,

hab Dank für Deinen Einsatz und Deine tolle Idee, bei einer Suche nach dem eingestellten AF dem ungünstigen Fall mit 0 Ergebnissen vorzubeugen.

Das sieht so gut wie komplex aus. ;-)

Eine kleine Verbesserung ist mir noch in den Sinn gekommen:
In dem temporären Textabschnitt müssen nicht alle Absatzformate bereitgestellt werden, sondern nur diejenigen, deren Namen demjenigen in den find-/change-Preferences entspricht.


Der Hintergrund für meine Frage:
Ich wollte das Skript RecordFindChange.jsx (von Olav Kvern für CS2 entwickelt) zur Aufzeichnung von Ersetzen-Ausdrücken aus der Suchen/Ersetzen-Palette für das Skript FindChangeByList.jsx für aktuelle InDesign-Versionen aufarbeiten.
Dabei bin ich über die Rückgabewerte der Formate als String, ohne Gruppenangaben, gestolpert.

Kurzfristig habe ich mich nun für eine abgespeckte Version entschieden, in der nur die Ausdrücke (ohne Formatierung) aufgezeichnet werden:

Code
/* 
recordFindChange_Expressions.jsx

//DESCRIPTION:Schreibt die aktuellen Text- und GREP-Ersetzenausdrücke in eine Textdatei "findChangeStrings.txt" im Verzeichnis des Skripts.
VERSION: 0.2
AUTHOR: Martin Fischer
EMAIL: InDesign@MartinFischer.de
DATE: 19.6.2016
© Martin Fischer 2016
*/
main();

function main()
{
var str = '',
date_str = '',
script_dir = null, output_file = null;

script_dir = get_scriptdir();
output_file = new File(script_dir + '/findChangeStrings.txt' )

date_str = get_datestring();
str = get_str( date_str );

write_txt_appending(str, output_file);



// ---------------------------------------------------------------
// Ausgabestring ermitteln
// ---------------------------------------------------------------
function get_str(date_str)
{
var str_text = '';
var str_grep = '';

// ------------
// Text
// ------------
if (app.findTextPreferences.findWhat != '')
{
// Suchen
str_text += 'text\t' +
str_text += '{findWhat:"' + app.findTextPreferences.findWhat + '"}';

// Ersetzen
str_text += '\t';
str_text += '{changeTo:"' + app.changeTextPreferences.changeTo + '"}';

// Optionen
str_text += '\t';
str_text += createObject(app.findChangeTextOptions).toSource().replace(/^\(/,'').replace(/\)$/,'');

// Kommentar/Hinweis
str_text += '\t';
str_text += 'HINWEIS: ' + app.findTextPreferences.findWhat;
str_text += ' (' + date_str +')\n';
}

// ------------
// GREP
// ------------
if (app.findGrepPreferences.findWhat != '')
{
// Suchen
str_grep += 'grep\t' +
str_grep += get_prop (app.findGrepPreferences, 'findWhat').toSource().replace(/^\(/,'').replace(/\)$/,'');

// Ersetzen
str_grep += '\t';
str_grep += get_prop (app.changeGrepPreferences, 'changeTo').toSource().replace(/^\(/,'').replace(/\)$/,'');

// Optionen
str_grep += '\t';
str_grep += createObject(app.findChangeGrepOptions).toSource().replace(/^\(/,'').replace(/\)$/,'');

// Kommentar/Hinweis
str_grep += '\t';
str_grep += 'HINWEIS: ' + app.findGrepPreferences.findWhat;
str_grep += ' (' + date_str +')\n';
}

return str_text + str_grep;
}

// ---------------------------------------------------------------
// Textdatei schreiben
// ---------------------------------------------------------------
function write_txt_appending(_data, _file_path)
{
var _file = null, _contents = null;

_file = new File( _file_path);
_file.encoding = 'UTF-8';
if (! Folder(_file.path).exists)
Folder(_file.path).create();
if (_file.exists)
{
_file.open('r');
_contents = _file.read();
if (_contents[_contents.length-1] != '\n')
_contents += '\n';
_contents += _data;
_file.close();
}
else
_contents = _data;

_file.open('w');
_file.write(_contents);
_file.close();
_file.execute();
}

// ---------------------------------------------------------------
// Skriptverzeichnis ermitteln
// ---------------------------------------------------------------
function get_scriptdir()
{
try
{
return File( app.activeScript ).path;
}
catch( e )
{
return File( e.fileName ).path;
}
}

// ---------------------------------------------------------------
// Datum ermitteln
// ---------------------------------------------------------------
function get_datestring()
{
var today = new Date();
var d = pad_00( String(today.getDate()), 2) + '.' + pad_00( String((today.getMonth() +1) ), 2) + '.' + String((today.getYear()+1900));
return d;

// ---------------------------------------------------------------
// 0 auffüllen
// ---------------------------------------------------------------
function pad_00(_num, _digits)
{
var theFills = _digits - (_num + "").length;
for (oneDigit = 0; oneDigit < theFills; oneDigit++ )
{
_num = "0" + _num;
}
return _num;
}
}

// ---------------------------------------------------------------
// Objekt aus Properties erzeugen
// ---------------------------------------------------------------
// nach © Gregor Fellenz in http://www.indesignblog.com/2016/06/einstellungen-des-epub-exports-sichern/#comment-2011
function createObject (object)
{
if (object == null) return null;
if (object == undefined) return undefined;
if ( object.hasOwnProperty("properties") )
{
object = object.properties;
delete object.index;
delete object.id;
delete object.parent;
delete object.events;
delete object.eventListeners;
delete object.isValid;
delete object.level;

for ( var property in object )
{
// Filter: NothingEnum.nothing, empty string, null
if (object[property] == 1851876449 || object[property] === "" || object[property] == null )
delete object[property];
else
object[property] = createObject(object[property]);
}
} else if ( object.constructor.name == "Enumerator" )
{
object = object.valueOf();
}
return object;
}

// ---------------------------------------------------------------
// einzelne Property aus einem Objekt ermitteln
// ---------------------------------------------------------------
function get_prop (obj, prop)
{
if (obj == null) return null;
if (obj == undefined) return undefined;
if( obj.hasOwnProperty("properties") )
{
obj = obj.properties;
for (var i in obj)
{
if (i != prop )
delete obj[i];
}
}
return obj;
}
}


Darin enthalten ist eine etwas umständliche Methode, die Backslashes aus den GREP-Ausdrücken "escaped" (also mit vorangestelltem Backslash) in die Textdatei zu übernehmen (siehe die Funktion get_prop (obj, prop) ).
Vielleicht hast Du oder hat jemand Anderer dazu noch eine bessere Idee?

Eine erweiterte Version mit Berücksichtigung von Formaten bleibt einstweilen eine Baustelle.
Werde mit Deinem Workaround experimentieren.
Allerdings muss man dabei wiederum aufpassen, dass einem die temporären Ersetzen-Einstellungen nicht in die Quere kommen und man versehentlich die temporären Einstellungen aufzeichnet und nicht die ursprünglichen. ;-)

Mit *dieser* Erweiterung um die Formate eilt es mir nicht so sehr, weil auf der anderen Seite bei FindChangeByList.jsx noch Vorkehrungen für den Fall, dass bestimmte in der Liste angegebene Formate im Dokument nicht vorhanden sind, getroffen werden müssten.



Dir noch einen schönen Sonntag

Martin


als Antwort auf: [#550565]
(Dieser Beitrag wurde von Martin Fischer am 19. Jun 2016, 18:08 geändert)

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Martin Fischer
  
Beiträge gesamt: 12783

19. Jun 2016, 15:12
Beitrag # 6 von 11
Beitrag ID: #550569
Bewertung:
(6765 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Antwort auf: Allerdings muss man dabei wiederum aufpassen, dass einem die temporären Ersetzen-Einstellungen nicht in die Quere kommen und man versehentlich die temporären Einstellungen aufzeichnet und nicht die ursprünglichen. ;-)


Es ist gar nicht so einfach, wie man spontan annehmen könnte, die ursprünglichen Sucheinstellungen zu sichern und später wiederherzustellen:
Code
var old_pref = app.findGrepPreferences; 
app.findGrepPreferences = NothingEnum.nothing;
try
{
app.findGrepPreferences = old_pref;
}
catch(e)
{
$.writeln( e.message );
}


Fehlermeldung: Ungültiger Wert für Einrichtung der Eigenschaft "findGrepPreferences". NothingEnum enumerator erwartet, aber FindGrepPreference erhalten.


Selbst dann, wenn die app.findGrepPreferences auf NothingEnum.nothing zurückgesetzt sind. ;-)

Code
app.findGrepPreferences = NothingEnum.nothing; 
try
{
app.findGrepPreferences = app.findGrepPreferences;
}
catch(e)
{
$.writeln( e.message );
}



als Antwort auf: [#550566]
(Dieser Beitrag wurde von Martin Fischer am 19. Jun 2016, 15:26 geändert)

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Uwe Laubender
Beiträge gesamt: 5319

19. Jun 2016, 15:25
Beitrag # 7 von 11
Beitrag ID: #550570
Bewertung:
(6758 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Antwort auf [ Martin Fischer ] … Es ist gar nicht so einfach, wie man spontan annehmen könnte, die ursrpünglichen Sucheinstellungen zu sichern und später wiedrherzustellen …


Hallo Martin,
weiss ich. Bei meiner Recherche habe ich eigene Aufzeichnungen von Mitte Dezember 2013 zum Thema vorgefunden, die mir das deutlich machten. Das war wohl damals auf HDS auch mal Thema. Allerdings hatte ich keinen Link gespeichert, sodass ich im Moment nicht weiss, ob wir damals eine Lösung erarbeitet hatten.

Dir auch einen schönen Sonntag!
Werde jetzt die Sonne genießen :-)


als Antwort auf: [#550569]

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

gfellenz
Beiträge gesamt: 121

20. Jun 2016, 07:41
Beitrag # 8 von 11
Beitrag ID: #550579
Bewertung:
(6521 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Martin, Hallo Uwe,

ich habe leider gerade keine Zeit und habe euren Text auch nicht komplett durchgelesen.

Über das auslesen der gespeicheten Queries habe ich die Formatgruppen aber in meinen Chain-GREP Skript gelöst.

http://www.publishingx.de/download/chain-grep/

Ist auch in meinem Buch beschrieben, aber letztlich ist alles aus dem Code ersichtlich.


als Antwort auf: [#550558]

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Martin Fischer
  
Beiträge gesamt: 12783

20. Jun 2016, 08:42
Beitrag # 9 von 11
Beitrag ID: #550580
Bewertung:
(6234 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Gregor,

vielen Dank für Deinen Hinweis.
(Da hätte ich auch selbst draufkommen und spickeln können.)

Hab den Code neugierigerweise mal kurz überflogen.
Das Geheimnis scheint in der Funktion getStyleByString() gelöst zu werden.

Ich werd's heute Abend mal genauer nachstellen und prüfen.
Das sieht vielversprechend aus.


als Antwort auf: [#550579]

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Martin Fischer
  
Beiträge gesamt: 12783

20. Jun 2016, 10:19
Beitrag # 10 von 11
Beitrag ID: #550581
Bewertung:
(6172 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Gregor,

bei der Auswertung der gespeicherten Abfragen/Queries bist Du mit Deinem Skript im Vorteil.
Denn in den Abfragen wird anders als in den Find-/Change-Preferences eine Information zur Formatgruppe hinterlegt. Und zwar so wie in der Suchen/Ersetzen-Palette angezeigt.

Beispiel:
Code
<TextAttribute type="pstyle" value="d:28 FN"> 

-> Absatzformat "28 FN" in Formatgruppe "d"


Die Find-/Change-Preferences geben nach meinen Untersuchungen gar keinen Hinweis auf eine mögliche Formatgruppe.

Eine Lösung des Problems bei der Sicherung der aktuellen Formateinstellungen der Suchen/Ersetzen könnte aber darin bestehen, eine temporäre Abfrage zu sichern, diese auszuwerten und dann wieder zu löschen.

Im Prinzip könnte man dafür Dein Skript verwenden und statt auf eine Auswahl an Abfragen auf die eine temporäre Abfrage zugreifen.

Vielen Dank für Deinen Anstoß!



Deine Funktion getStyleByString() beinhaltet ferner eine Fehlerroutine, die im originalen FindChangeByList.jsx so noch nicht angelegt ist. Das müsste dort nachgetragen werden.


als Antwort auf: [#550579]
(Dieser Beitrag wurde von Martin Fischer am 20. Jun 2016, 10:20 geändert)

app.findTextPreferences.appliedParagraphStyle: wie das Objekt statt eines Strings ermitteln?

Uwe Laubender
Beiträge gesamt: 5319

20. Jun 2016, 12:20
Beitrag # 11 von 11
Beitrag ID: #550583
Bewertung:
(6124 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo Gregor,
danke für den Hinweis auch von meiner Seite.

Ja, mit gespeicherten Queries im XML-Format zu arbeiten, hat 'was.
Das Auslesen erfolgt dann über xPath() der gelesenen Queries-Datei als XML-Objekt, wenn ich Deinen Code in ChainGREP.jsx richtig interpretiere.


als Antwort auf: [#550579]
X