// ExtendScript for comparing text layers between two PSD files #target photoshop // Function to extract text layers from a document function extractTextLayers(doc) { var result = { documentName: doc.name, textLayers: [] }; // Utility function to traverse layers function traverseLayers(layers, path) { path = path || ""; for (var i = 0; i < layers.length; i++) { var layer = layers[i]; if (layer.typename === "LayerSet") { // This is a layer group, traverse its children var groupPath = path ? path + "/" + layer.name : layer.name; traverseLayers(layer.layers, groupPath); } else if (layer.kind === LayerKind.TEXT) { // This is a text layer, extract its information extractTextLayerInfo(layer, path); } } } function extractTextLayerInfo(layer, path) { var layerPath = path ? path + "/" + layer.name : layer.name; // Extract text content and basic info var layerInfo = { id: layer.id, name: layer.name, path: layerPath, text: layer.textItem.contents, visible: layer.visible }; // Add to the result result.textLayers.push(layerInfo); } // Start the traversal traverseLayers(doc.layers); return result; } // Function to compare text layers between two documents function compareTextLayers(doc1Info, doc2Info) { var results = []; // Create dictionaries of layers by name for easier lookup var doc1Layers = {}; var doc2Layers = {}; for (var i = 0; i < doc1Info.textLayers.length; i++) { var layer = doc1Info.textLayers[i]; doc1Layers[layer.name] = layer; } for (var j = 0; j < doc2Info.textLayers.length; j++) { var layer = doc2Info.textLayers[j]; doc2Layers[layer.name] = layer; } // First check original layers against processed for (var name in doc1Layers) { if (doc1Layers.hasOwnProperty(name)) { var doc1Layer = doc1Layers[name]; if (doc2Layers[name]) { var doc2Layer = doc2Layers[name]; // Check if the text content is different if (doc1Layer.text !== doc2Layer.text) { results.push({ name: name, id1: doc1Layer.id, id2: doc2Layer.id, text1: doc1Layer.text, text2: doc2Layer.text, status: "modified" }); } else { results.push({ name: name, id1: doc1Layer.id, id2: doc2Layer.id, text1: doc1Layer.text, text2: doc2Layer.text, status: "unchanged" }); } } else { // Layer exists in doc1 but not in doc2 results.push({ name: name, id1: doc1Layer.id, id2: "N/A", text1: doc1Layer.text, text2: "LAYER MISSING", status: "missing_in_doc2" }); } } } // Check for new layers in doc2 not in doc1 for (var name in doc2Layers) { if (doc2Layers.hasOwnProperty(name) && !doc1Layers[name]) { var doc2Layer = doc2Layers[name]; results.push({ name: name, id1: "N/A", id2: doc2Layer.id, text1: "LAYER MISSING", text2: doc2Layer.text, status: "new_in_doc2" }); } } return results; } // Main function function main() { if (app.documents.length < 1) { alert("Please open at least one document before running this script."); return; } try { // Get the path to the first document (original) var originalPath = app.activeDocument.fullName.fsName; // Dialog to select the second document (processed) var processedFile = File.openDialog("Select the processed PSD file to compare:", "*.psd"); if (!processedFile) { alert("No processed file selected. Exiting."); return; } // Extract text layers from the original document var originalInfo = extractTextLayers(app.activeDocument); // Remember the original document var originalDoc = app.activeDocument; // Open the processed document app.open(processedFile); // Extract text layers from the processed document var processedInfo = extractTextLayers(app.activeDocument); // Close the processed document app.activeDocument.close(SaveOptions.DONOTSAVECHANGES); // Make sure the original document is active again app.activeDocument = originalDoc; // Compare the text layers var comparisonResults = compareTextLayers(originalInfo, processedInfo); // Generate the report var report = "Text Layer Comparison Results\n"; report += "==================================================\n\n"; report += "Original PSD: " + originalPath + "\n"; report += "Processed PSD: " + processedFile.fsName + "\n\n"; // Count the differences var modifiedCount = 0; var missingCount = 0; var newCount = 0; var unchangedCount = 0; for (var i = 0; i < comparisonResults.length; i++) { var result = comparisonResults[i]; switch (result.status) { case "modified": modifiedCount++; break; case "missing_in_doc2": missingCount++; break; case "new_in_doc2": newCount++; break; case "unchanged": unchangedCount++; break; } } report += "SUMMARY:\n"; report += " Total text layers compared: " + comparisonResults.length + "\n"; report += " Modified layers: " + modifiedCount + "\n"; report += " Missing in processed: " + missingCount + "\n"; report += " New in processed: " + newCount + "\n"; report += " Unchanged layers: " + unchangedCount + "\n\n"; report += "DETAILS:\n"; report += "==================================================\n\n"; // Add details for each comparison for (var i = 0; i < comparisonResults.length; i++) { var result = comparisonResults[i]; report += "Layer: " + result.name + "\n"; report += " Status: " + result.status + "\n"; report += " Original ID: " + result.id1 + "\n"; report += " Processed ID: " + result.id2 + "\n"; report += " Original text: \"" + result.text1 + "\"\n"; report += " Processed text: \"" + result.text2 + "\"\n"; report += "-------------------------------------------------\n\n"; } // Save the report to a text file next to the original PSD var reportFolder = originalDoc.path; var reportFile = new File(reportFolder + "/text_layer_comparison.txt"); reportFile.open("w"); reportFile.write(report); reportFile.close(); alert("Comparison complete! Report saved to:\n" + reportFile.fsName); } catch (e) { alert("Error: " + e.message); } } // Run the main function main();