Looping through layers and setting them to visible - javascript

I'm trying to loop through the layers in an InDesign doc and set all of them to visible. This is to ensure that file collection occurs correctly.
I put together the following
var myDocument = app.activeDocument;
//make all layers visable
for (i = 0; i < myDocument.layers.length; i++) {
if(myDocument.layers[i].visible = false) {
myDocument.layers[i].visible = true;
};
};
This is excerpted from a larger script that automates the file collect, this is just the routine for the layers.
For context here's the actual script.
function Left(str, n){
if (n <= 0)
return "";
else if (n > String(str).length)
return str;
else
return String(str).substring(0,n);
}
function Right(str, n){
if (n <= 0)
return "";
else if (n > String(str).length)
return str;
else {
var iLen = String(str).length;
return String(str).substring(iLen, iLen - n);
}
}
if (app.documents.length != 0){
var myDocument = app.activeDocument;
var docName = myDocument.name;
var docName = Left(docName, String(docName).length-5)
//alert(docName);
var myFolder = new Folder ("~/Desktop/"+docName+"/");
//myFolder.create("Bob");s
/*new Folder ("~/Desktop/Collected/Hi-Res PDF/");
new Folder ("~/Desktop/Collected/RELEASE INFO/");*/
//make all layers visable
for (i = 0; i < myDocument.layers.length; i++) {
if(myDocument.layers[i].visible = false) {
myDocument.layers[i].visible = true;
};
};
myDocument.packageForPrint (myFolder,1,1,0,1,0,0,0);
var newFolder = new Folder ("~/Desktop/"+docName+"/RELEASE INFO/");
newFolder.create();
var inddFolder = new Folder ("~/Desktop/"+docName+"/Indesign Files/");
inddFolder.create();
var newFolder = new Folder ("~/Desktop/"+docName+"/IDML Files/");
newFolder.create();
//Export IMDL File
myDocument.exportFile(ExportFormat.INDESIGN_MARKUP, File("~/Desktop/"+docName+"/IDML Files/"+docName+".idml"), false);
//Move INDD File
//var myInddfile = File("~/Desktop/"+docName+"/"+docName+".indd");
//myDocument.changePath(File(inddFolder),false);
//Rip Low Res PDFs
var myPDFExportPreset = app.pdfExportPresets.item("CP3 Low Rez");
app.activeDocument.exportFile(ExportFormat.pdfType,
File("~/Desktop/"+docName+"/RELEASE INFO/"+docName+"_LR.pdf"), false, myPDFExportPreset);
//Now export the document. You'll have to fill in your own file path.
//app.activeDocument.exportFile(ExportFormat.pdfType, File("~/Desktop/"+docName+"_FILM/RELEASE INFO/"+docName+"_LR.pdf"), false);
var newFolder = new Folder ("~/Desktop/"+docName+"/Hi-Res PDF/");
newFolder.create();
//Rip Hi-Res PDF
var myPDFExportPreset = app.pdfExportPresets.item("Kern Hi Rez Print");
app.activeDocument.exportFile(ExportFormat.pdfType,
File("~/Desktop/"+docName+"/Hi-Res PDF/"+docName+"_HiRes.pdf"), false, myPDFExportPreset);
//Now export the document. You'll have to fill in your own file path.
//app.activeDocument.exportFile(ExportFormat.pdfType, File("~/Desktop/"+docName+"_FILM/Hi-Res PDF/"+docName+"_HiRes.pdf"), false);
myFolder.execute();
}
else{
alert("Please open a document and try again.");
}
Hopefully, when the script executes, all the layers will be set to visible then the file collect will occur.

Use triple equals in your if statement for strict equality. For instance:
for (i = 0; i < myDocument.layers.length; i++) {
if(myDocument.layers[i].visible === false) { // <-- Note the `===` instead of `=`
myDocument.layers[i].visible = true;
};
};
Or even better, you can change it to utilize the Logical NOT ! operator
for (i = 0; i < myDocument.layers.length; i++) {
if (!myDocument.layers[i].visible) { // <-- Change to this.
myDocument.layers[i].visible = true;
};
};
Note: Given your example, the conditional if statement is not actually necessary. You could simply do this instead:
for (i = 0; i < myDocument.layers.length; i++) {
myDocument.layers[i].visible = true;
};
Set everything to be visible
If you actually want to make everything visible - including; InDesign document layers and all page items on the sub-layer(s), then you'll need to do something like this example:
var myDocument = app.activeDocument;
// ...
function makeAllVisible() {
for (i = 0, max = myDocument.layers.length; i < max; i++) {
var currentLayer = myDocument.layers[i];
currentLayer.visible = true; // Make the top level layer visible.
// Make all sub layers visible,
// i.e. make all page items on the current layer visible.
var currentLayerPageItems = currentLayer.allPageItems;
for (x = 0, len = currentLayerPageItems.length; x < len; x++) {
currentLayerPageItems[x].visible = true
}
}
}
makeAllVisible(); // Invoke the function.
// ...

Related

Comparing JPG files with Photoshop Layers

Is it possible to compare filenames for a set of files that are imported as Photoshop layers ?
I have a folder of 50 jpg images which I have used in a PSD file.
Now I want to check whether all the JPG files are used or not ?
Is it possible to do so ?
As I've said, Photoshop scripting can help you achieve this by using File Objects and basic javascript knowledge. I've modified my old script as you've desired and now it should work well with any nested groups and images.
I highly encourage you to learn scripting and ask questions here wherever you feels confused.
Save below code as 'Script.jsx' and run it from 'File > Scripts > Browse'
Update 2 : Now it saves log.txt file too as per you requested. P.S. Learn from this script and tweak it to your desired result.
// Managing Document
var docs = app.documents;
// Progress Bar
var win = new Window("window{text:'Progress',bounds:[100,100,400,150],bar:Progressbar{bounds:[20,20,280,31] , value:0,maxvalue:100}};");
// assigning activeDocument
if (docs.length != 0) {
var docRef = app.activeDocument;
// Defining the folder
alert("You will be prompted for the folder containing your images.\n" +
"Files will be selected with a '.png'/'.jpg/.jpeg' on the end in the same folder.");
var folder = Folder.selectDialog();
if (!folder) {
exit;
}
var photoFiles = folder.getFiles(/\.(jpg|jpeg|png)$/i);
var matchFiles = [];
var photoFilesName = [];
//Searching for used images
var increment = parseFloat(0);
var divider = parseFloat(100/photoFiles.length);
win.show();
for (var i = 0; i < photoFiles.length; i++) {
increment = increment + divider;
var indexPhotoName = removeExtension(photoFiles[i].displayName);
photoFilesName.push(indexPhotoName);
var doc = activeDocument;
var curLayer;
goThroughLayers(doc, indexPhotoName);
}
function goThroughLayers(parentLayer, targetName) {
for (var i = 0; i < parentLayer.layers.length; i++) {
curLayer = parentLayer.layers[i];
doc.activeLayer = curLayer;
if (curLayer.typename == 'LayerSet') {
goThroughLayers(curLayer, targetName)
} else {
if (curLayer.name == targetName) {
// if (curLayer.name.match(/[e]/ig)) {
matchFiles.push(targetName);
// }
} //end if
} //end else
} //end loop
} //end function
function arr_diff(a1, a2) {
var a = [],
diff = [];
for (var i = 0; i < a1.length; i++) {
a[a1[i]] = true;
}
for (var i = 0; i < a2.length; i++) {
if (a[a2[i]]) {
delete a[a2[i]];
} else {
a[a2[i]] = true;
}
}
for (var k in a) {
diff.push(k);
}
return diff;
}
function removeExtension(str) {
return str.split('.').slice(0, -1).join('.');
}
var missItems = arr_diff(matchFiles, photoFilesName);
if (missItems.length > 0) {
var missFolder = new Folder(photoFiles[0].path + '/Missed%20Files');
if(!missFolder.exists){
missFolder.create();
}
for (var y = 0; y < photoFiles.length; y++) {
var photoTrimName = removeExtension(photoFiles[y].displayName);
for( var x = 0; x < missItems.length ; x++){
if(photoTrimName == missItems[x]){
photoFiles[y].copy(new File(missFolder+'/'+photoFiles[y].displayName));
}
}
};
win.close();
alert("You've missed total " + missItems.length + " files. Press OK to open folder containing missing files. Log report is generated wherever PSD is saved.");
var FileStr = "";
for(var m=0; m<missItems.length; m++){
FileStr = FileStr + '\n' + (m+1) + '. ' + missItems[m];
}
var str = "Your missed files are : " + FileStr;
saveTxt(str);
missFolder.execute();
} else {
win.close();
saveTxt('All Photos are used');
alert('All Photos are used');
}
} else {
alert('Open atleast one document');
}
function saveTxt(txt)
{
var Name = "LogReport_" + app.activeDocument.name.replace(/\.[^\.]+$/, '');
var Ext = decodeURI(app.activeDocument.name).replace(/^.*\./,'');
if (Ext.toLowerCase() != 'psd')
return;
var Path = app.activeDocument.path;
var saveFile = File(Path + "/" + Name +".txt");
if(saveFile.exists)
saveFile.remove();
saveFile.encoding = "UTF8";
saveFile.open("e", "TEXT", "????");
saveFile.writeln(txt);
saveFile.close();
}
In Javascript, it is possible to get some information related to PSD file layers using PSD.js library

What should i do in order to print level also in Breadth first search Algo.

What can be done in the below algo in order to print values level wise in binary tree.
BinarySearchTree.prototype.breadthFirstTraversal = function() {
console.log("Breadth First Traversal");
var q = []
q.push(this.root);//You don't need to write the root here, it will be written in the loop
while (q.length > 0)
{
var n = q.shift();
console.log(n.value); //Only write the value when you dequeue it
if (n.left !=null)
{
q.push(n.left);//enqueue the left child
}
if (n.right !=null)
{
q.push(n.right);//enque the right child
}
}
};
Just wanted to add this since it doesn't require the storage of the level of each corresponding node as in the solution above so it doesn't require you to add a property to your object. If you think about it the queue will have, at most, two different levels in it. So you only need one global marker to let you know if you are dealing with a new level and a flag to let you know if you should mark the new right or left node being pushed.
BinarySearchTree.prototype.breadthFirstTraversal = function() {
console.log("Breadth First Traversal");
var q = new Array();
q.push(this.root);
var printArray = [];
var printArray.push(this.root.value);
var newlevel = false;
var marker = 1;
var level = 0;
while(q.length > 0){
if(marker==1){
console.log("level: " + level);
console.log(printArray);
newlevel = true;
}
var n = q.shift();
printArray.shift();
marker -= 1;
//console.log(n.value);
if(n.left != null){
q.push(n.left);
printArray.push(n.left.value);
if(newlevel){
marker = q.length;
level+=1;
newlevel = false;
}
}
if(n.right != null){
q.push(n.right);
printArray.push(n.right.value);
if(newlevel){
marker = q.length;
level+=1;
newlevel = false;
}
}
}
};
Store level for each node, and print them only when level changes:
BinarySearchTree.prototype.breadthFirstTraversal = function() {
console.log("Breadth First Traversal");
var q = [];
var prevLevel = -1; // monitor level switch
var byLevel = []; // store node values for printing
this.root.level = 0; // set root level
q.push(this.root);//You don't need to write the root here, it will be written in the loop
byLevel.push(this.root.value);
while (q.length > 0)
{
var n = q.shift();
// Next level, print and reset
if (n.level > prevLevel) {
console.log(byLevel);
byLevel = [];
prevLevel = n.level;
}
if (n.left !=null)
{
n.left.level = n.level + 1;
q.push(n.left);//enqueue the left child
byLevel.push(n.left.value);
}
if (n.right !=null)
{
n.right.level = n.level + 1;
q.push(n.right);//enque the right child
byLevel.push(n.right.value);
}
}
if (byLevel.length > 0) {
console.log(byLevel);
}
};

Illustrator scripting

I am writing a script for an active doc in Illustrator. The active doc already has the spot swatch for "LEAD" in it. All the paths I have to set and symbols need to be set to this swatch. I have worked my way around it by deleting the swatch then re-adding it to the doc. This works for all my paths and objects created. There are 3 symbols in the active doc that are being placed by scrip, that are already set to the spot swatch. When my script deletes the swatch it resets the symbol to 100% black process. Is there a way to pull the swatch from the active doc?All path items reqiure the leadSpotColor variable to set that color. The LEAD swatch already exist in the active doc. If i do not add the swatch remove line before hand it errors out, but the swatch remove line sets my symbols already in the active doc to 100% process black, and they also need to be set to the LEAD swatch.
if ( app.documents.length = "LEAD" ) {
swatchToDelete = app.activeDocument.swatches["LEAD"];
swatchToDelete.remove();
}
var leadSpot = doc.spots.add();
var leadSpotColor = new CMYKColor();
leadSpotColor.cyan = 0;
leadSpotColor.magenta = 0;
leadSpotColor.yellow = 0;
leadSpotColor.black = 100;
leadSpot.name = "LEAD";
leadSpot.colorType = ColorModel.SPOT;
leadSpot.color = leadSpotColor;
var leadSpotColor = new SpotColor();
leadSpotColor.spot = leadSpot;
Why would you want to delete the swatch if you can just edit it ?
var main = function(){
var doc,
leadClr, c;
if(!app.documents.length) return;
doc = app.activeDocument;
leadClr = getLeadColor(doc);
if ( leadClr===null ) {
var leadSpot = doc.spots.add();
var leadSpotColor = new CMYKColor();
leadSpotColor.cyan = 0;
leadSpotColor.magenta = 0;
leadSpotColor.yellow = 0;
leadSpotColor.black = 100;
leadSpot.name = "LEAD";
leadSpot.colorType = ColorModel.SPOT;
leadSpot.color = leadSpotColor;
var leadSpotColor = new SpotColor();
leadSpotColor.spot = leadSpot;
}
else {
c = leadClr.color.spot.color;
c.cyan = 0;
c.magenta = 0;
c.yellow = 0;
c.black = 100;
}
};
var getLeadColor = function(doc){
var clrs = doc.swatches,
n = clrs.length;
while (n-- ) {
if ( clrs[n].name=="LEAD" ) return clrs[n];
}
return null;
}
main();
I would recommend adding some prevention mechanism like ensure swatch is actually a spot prior to reach teh spot property.
First of all first line of your code is wrong
if ( app.documents.length = "LEAD" )
How you can compare length with string "LEAD", its should be a number and also in if statement we use conditional operator and what you are doing is assigning value in if statement.
Here is the script for LEAD spot, that will give you spot color if exist otherwise it will create new spot color with name "LEAD"
function main() {
var currentDocument;
var leadSpotColor;
if (!app.documents.length) {
alert("No document is open");
return;
}
currentDocument = app.activeDocument;
leadSpotColor = getLeadSpotColor(currentDocument);
applyColorToAllPath(leadSpotColor, currentDocument);
}
function getLeadSpotColor(currentDocument) {
try {
var leadSpotColor = currentDocument.spots.getByName('LEAD')
return leadSpotColor;
} catch (e) {
var color = new CMYKColor();
color.cyan = 0;
color.magenta = 0;
color.yellow = 0;
color.black = 100;
var newSpot = currentDocument.spots.add();
newSpot.name = "LEAD";
newSpot.colorType = ColorModel.SPOT;
newSpot.color = color;
var leadSpotColor = new SpotColor();
leadSpotColor.spot = newSpot;
return leadSpotColor;
}
}
function applyColorToAllPath(leadSpotColor, currentDocument) {
// Change code as per your requiremnt. I just handled for pathItems. You can similary for symbols.
var pathItems = currentDocument.pathItems;
for (var i = 0; i < pathItems.length; i++) {
pathItems[i].filled = true;
pathItems[i].fillColor = leadSpotColor;
pathItems[i].stroke = true;
pathItems[i].strokeColor = leadSpotColor;
}
}
main();

Photoshop Javascript to get all layers in the active document

I'm sure it should be discussed before by Photoshop scripters. I write a solution as following. I think it's logically right, but the result is not correct. Anybody can help to check where's wrong in the code, or have ideas for this topic? I want to get all the layers in a document.
Code:
function getAllLayersInLayerSets(layerNodes) {
var retList = [];
for (var i=0; i<layerNodes.length; i++) {
if(layerNodes[i].layerSets.length > 0)
{
var tmp = getAllLayersInLayerSets(layerNodes[i].layerSets);
var j = (tmp == null) ? -1 : tmp.length-1;
while(tmp && j>=0)
{
retList.push(tmp[i]);
j--;
}
}
for(var layerIndex=0; layerIndex < layerNodes[i].artLayers.length; layerIndex++)
{
var layer=layerNodes[i].artLayers[layerIndex];
retList.push(layer);
}
}
return retList;
}
Many thanks for any help or discussion.
I know this is an old thread, but this might be useful for someone.
I was looking for a function that would get me all the ArtLayers in a Photoshop comp, including layers nested in groups. The above function was returning undefined, so I modified it and got it to work.
var doc = app.activeDocument;
var allLayers = [];
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers){
for (var m = 0; m < doc.layers.length; m++){
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer"){
allLayers.push(theLayer);
}else{
collectAllLayers(theLayer, allLayers);
}
}
return allLayers;
}
Minor expansion on Ghoul Fool's post to only get all VISIBLE art layers in the active document. :P
// Get layers in a document
var sourceDocument = app.activeDocument;
var visibleLayers = [];
var visibleLayers = collectAllLayers(sourceDocument, visibleLayers);
// Print out total layers found
alert(visibleLayers.length);
// Recursively get all visible art layers in a given document
function collectAllLayers (parent, allLayers)
{
for (var m = 0; m < parent.layers.length; m++)
{
var currentLayer = parent.layers[m];
if (currentLayer.typename === "ArtLayer")
{
if(currentLayer.visible)
{
allLayers.push(currentLayer);
}
}
else
{
collectAllLayers(currentLayer, allLayers);
}
}
return allLayers;
}
To get all the layers (and sub layers) you have to have a recursive function
var allLayers = new Array();
var theLayers = collectAllLayers(app.activeDocument, 0);
function collectAllLayers (theParent, level)
{
for (var m = theParent.layers.length - 1; m >= 0; m--)
{
var theLayer = theParent.layers[m];
if (theLayer.typename != "ArtLayer")
{
allLayers.push(level + theLayer.name);
collectAllLayers(theLayer, level + 1)
}
}
}
function selectAllLayers() {
var desc29 = new ActionDescriptor();
var ref23 = new ActionReference();
ref23.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
desc29.putReference(charIDToTypeID('null'), ref23);
executeAction(stringIDToTypeID('selectAllLayers'), desc29, DialogModes.NO);
}

How to Access local CSS file from within Alfresco Javascript?

So I have been able to figure out in Alfresco, there is a form called skin.css that allows me to change the highlighted color of data table items. However, I only want to be able to change this property during the course of a workflow and not as it applies to all data list elements throughout the entire Share website.
To start, I have a script which kicks off based on a rule and moves any updated/new files into a specified folder and then kicks off a workflow for that file. Within starting the workflow, the package items list is populated with all the documents within the same folder as the document that just got moved/the workflow started on. Below is the script:
function main()
{
var counter=0;
//Administrative Adjudication space/folder MUST exist under companyhome.
var rootSpaceName = companyhome.childByNamePath("mainFolder");
//If the rootspacename is null (not previously created), then exit the program as we have nothing to do.
if(rootSpaceName == null)
{
logger.log("Company Home/mainFolder does not exist, so we have nothing to do.");
return;
}
else
{
logger.log("Company Home/mainFolder exists, so carry on our process.");
//Creates an array of all the children under the rootSpaceName
var childList = rootSpaceName.children;
//Creates a variable which counts the number of children in the childList array
var count = childList.length;
//var seconds = new Date().getTime() / 1000;
//If there are no children in the rootSpaceName folder, exit the program.
if(count == 0)
{
logger.log("Company Home/mainFolder does not have child, nothing to do.");
return;
}
else
{
for(var i = 0; i < count; i++)
{
//Title MUST exist.
var childTitle = childList[i].properties["hearing:childTitle"];
//Author MUST exist.
var childAuthor = childList[i].properties["hearing:childAuthor"];
logger.log("childTitle: " + childTitle);
logger.log("childAuthor: " + childAuthor);
if(childTitle == null || childAuthor == null)
{
logger.log(i + ". Both the childTitle and childAuthor are null...");
continue;
}
var child = childList[i];
if(child.isContainer == false)
{
for(var j = 0; j < count; j++)
{
var newChildName = childList[j].properties.name;
logger.log("New child name: " + newChildName);
var newChild = childList[j];
if((newChild.isContainer == true) && (childTitle == newChildName))
{
logger.log("There is a currently existing folder with the same name as the title of original child");
var newSpaceName = rootSpaceName.childByNamePath(newChildName);
var newChildList = newSpaceName.children;
var newCount = newChildList.length;
for(var k = 0; k < newCount; k++)
{
var newNewChildName = newChildList[k].properties.name;
var newNewchildAuthor = newChildList[k].properties.author;
var newNewChild = newChildList[k];
if((newNewChild.isContainer == true) && (newNewchildAuthor == childAuthor))
{
var currentSpace = newSpaceName.childByNamePath(newNewChildName);
if(child.isDocument == true)
{
//Only want the workflow to run once so we increment count
counter=counter+1;
child.move(currentSpace);
//If Count is 1, then run workflow
if(counter==1)
{
//starts HelloWorldUI workflow
var wfdef=workflow.getDefinitionByName("activiti$helloWorldUI");
if(wfdef)
{
var wfparams=new Array();
wfparams["bpm:workflowDescription"]="";
wfparams["bpm:groupAssignee"]=people.getGroup("GROUP_Managers");
var wfpackage=workflow.createPackage();
var rootSpaceName=currentSpace;
var childList=rootSpaceName.children;
var count=childList.length;
//add all existing documents in the space to the workflow
for(var i = 0; i < count; i++)
{
wfpackage.addNode(childList[i]);
}
var wfpath=wfdef.startWorkflow(wfpackage,wfparams);
var tasks=wfpath.getTasks();
for each(task in tasks)
{
task.endTask(null);
}
}
}
}
}
}
}
else
{
// If title folder is already created, not need to create again.
var newSpaceName = companyhome.childByNamePath("mainFolder/" + childTitle);
if(newSpaceName == null)
{
newSpaceName = rootSpaceName.createFolder(childTitle);
logger.log("mainFolder/" + childTitle + " is created.");
}
// If author folder is already created, not need to create again.
var newNewSpaceName = companyhome.childByNamePath("mainFolder/" + childTitle + "/" + childAuthor);
if(newNewSpaceName == null)
{
newNewSpaceName = newSpaceName.createFolder(childAuthor);
logger.log("mainFolder/" + childTitle + "/" + childAuthor + " is created.");
}
if(child.isDocument == true)
{
counter=counter + 1;
child.move(newNewSpaceName);
if(counter == 1)
{
var wfdef=workflow.getDefinitionByName("activiti$helloWorldUI");
if(wfdef)
{
var wfparams=new Array();
wfparams["bpm:workflowDescription"]="";
wfparams["bpm:groupAssignee"]=people.getGroup("GROUP_Managers");
var wfpackage=workflow.createPackage();
var rootSpaceName=newNewSpaceName;
var childList=rootSpaceName.children;
var count=childList.length;
//add all items from the space to the workflow
for(var i = 0; i <c ount; i++)
{
wfpackage.addNode(childList[i]);
}
var wfpath=wfdef.startWorkflow(wfpackage,wfparams);
var tasks=wfpath.getTasks();
for each(task in tasks)
{
task.endTask(null);
}
}
}
logger.log("Moving file " + child.properties.name);
}
}
}
}
}
}
}
return;
}
main();
I would like to be able to create a function of some sort that can be called to access the skin.css file only during the course of the workflow and basically set .yui-skin-default tr.yui-dt-first{background-color:#FFF} in the CSS file. Does anyone know how I would go about doing that?
If you want to change only in start workflow page,
your css should write in start-workflow.css which is pointed by start-workflow.get.head.ftl. This css will override in other css file like skin.css.
Like this way, you can override any css to affect in only start workflow page not others.
You can try for other workflow related pages.
I've found a bookmarklet that will allow you to inject a CSS file on any page you'd like. Only down side is that you'll have to run it every time you load your page.
http://allben.net/post/2010/01/30/CSS-JavaScript-Injection-Bookmarklets.aspx

Categories