• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
5

Clean SL

Advocate ,
Sep 07, 2017 Sep 07, 2017

Copy link to clipboard

Copied

Hello gang!

I just wanted to share with you my small utility tool for Photoshop called Clean SL that cleans ScriptingListenerJS.log file to make it more readable.

Recently watched Davide_Barranca​'s Adobe Photoshop HTML Panels Development course  and realised how painful it is to work with Action Manager's code and how unreadable it is right off the box. I know there are quite a few other tools that cleans log file, however it doesn't hurt to have an option to choose.

Interested? Grab it here: rendertom / Clean SL / source / — Bitbucket

Clean SL.png

Script performs multiple actions such as cleaning-up variable names and hoisting them to the top, wraps code block into function, converts charID to string ID for better readability and such. Resulting code is clean and maintains better readability.

Features:

  • Load entire ScriptingListenerJS.log content
  • Load only last entry in ScriptingListenerJS.log
  • Enter ScriptingListenerJS code manually

Options:

  • Hoist variable declaration to the top
  • Consolidate variables
  • Give descriptive variable names
  • Convert charID to stringID for better readability
  • Replace stringIDToTypeID() to s2t() function
  • Wrap to function block.

Example:

From this:

var idHStr = charIDToTypeID( "HStr" );

    var desc21 = new ActionDescriptor();

    var idpresetKind = stringIDToTypeID( "presetKind" );

    var idpresetKindType = stringIDToTypeID( "presetKindType" );

    var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );

    desc21.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );

    var idClrz = charIDToTypeID( "Clrz" );

    desc21.putBoolean( idClrz, false );

    var idAdjs = charIDToTypeID( "Adjs" );

        var list1 = new ActionList();

            var desc22 = new ActionDescriptor();

            var idH = charIDToTypeID( "H   " );

            desc22.putInteger( idH, 39 );

            var idStrt = charIDToTypeID( "Strt" );

            desc22.putInteger( idStrt, 23 );

            var idLght = charIDToTypeID( "Lght" );

            desc22.putInteger( idLght, -27 );

        var idHsttwo = charIDToTypeID( "Hst2" );

        list1.putObject( idHsttwo, desc22 );

    desc21.putList( idAdjs, list1 );

executeAction( idHStr, desc21, DialogModes.NO );

to this:

hueSaturation();

function hueSaturation() {

    var s2t = function (s) {

        return app.stringIDToTypeID(s);

    };

    var descriptor = new ActionDescriptor();

    var list = new ActionList();

    var descriptor2 = new ActionDescriptor();

    descriptor.putEnumerated( s2t( "presetKind" ), s2t( "presetKindType" ), s2t( "presetKindCustom" ));

    descriptor.putBoolean( s2t( "colorize" ), false );

    descriptor2.putInteger( s2t( "hue" ), 39 );

    descriptor2.putInteger( s2t( "saturation" ), 23 );

    descriptor2.putInteger( s2t( "lightness" ), -27 );

    list.putObject( s2t( "hueSatAdjustmentV2" ), descriptor2 );

    descriptor.putList( s2t( "adjustment" ), list );

    executeAction( s2t( "hueSaturation" ), descriptor, DialogModes.NO );

}

Installation

Clone or download repository and place Clean SJ.jsx script to Photoshop’s Scripts folder:

Adobe Photoshop CC 20XX -> Presets -> Scripts -> Clean JS.jsx

Restart Photoshop to access Clean JS script from File -> Scripts

------------------------------------------------

Since I am rather new to Photoshop Scripting, I might have missed something of my code brakes. So if you find any bugs or issues, please do not hesitate to let me know so I could fix it.

So, happy cleaning everybody!

TOPICS
Actions and scripting

Views

14.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
replies 131 Replies 131
Guide ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

Nice job Tomas, one suggestion.

outString = outString.replace(/"""/g,'"');

Just to remove triple quotes.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

Just found a bug in the increment function, it is putting a space between the function name and the increment number. A quick fix.

newVariableVersion = coreName.replace(/^\s+|\s$/g,'') + versionNumber;

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

I was about to report that. I have problems where the source will evaluate but the cleaned code does not. I think this it has to do with the Convert charID to stringID  return in make function were failing.  When I un checked the option the function names with sequence numbers may have spaces.

Capture.jpg

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

You guys are rockstars! Thank you for such a great support.  

I read every reply and take into consideration every suggestion you make. So, for today we have these changes in Clean SL v1.2 version:

  • Adds option to remove Action Managers junk code (credits to JJMack​)
  • Adds option to close Clean SL script before evaluating code
  • Adds option to save UI data on script quit (credits to Davide_Barranca​)
  • Fixes invalid function names (credits to SuperMerlin​ and JJMack
  • Replaces three quotes with one quote (credits to SuperMerlin​)
  • Uses external JSON object to read/write UI data
  • Saves output code as JSX instead of TXT
  • Adds tooltips everywhere
  • Removes start-up demo code
  • Removes duplicate functions

Thanks Davide_Barranca​ for "shorter descriptor names" and "load last log" ideas. I added them to todo list.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

Thomas

I want to thank you again for this tool.  I did some testing with different versions of Photoshop.

CS2 is to Old script UI is different your UI does not work in CS2.

CS3 is only a 32bit Photoshop but your script works with CS3

I do not have CS4 and CS5 installed.

Your Script works with CS6, CC, CC2014, CC 2015, CC 2015.5 and CC2017.

A suggestion I would make is.  The Junk code recorded by the scriptlistened started with CC2015.   The Scriptlistener has not been Updated since CS6.   So I would suggest that if  a user running Photoshop CC2015 and above uses you load full Log button that you automatically also run the remove junk code button.

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

Appreciate you testing it on different Photoshop versions. It's cool it works on such old version.

Regarding auto cleaning Junk Code - well, I want to be cautious about this - There might be instances when user needs that junk code. Or worse - maybe my Junk removal clears some sensitive/unrelated info. So it's far better to actually click a button to remove it then have it removed on script launch. It's much safe this way.

Also if you'd compare .log file and the code in Clean SL - they would be different with auto junk removal. And this might raise a few eye-brows.

Anyways, let's have it  as it is right now. I'll add it to todo list for future improvements.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

If you have Save UI data on quit enabled in the interface, script will save both code panels and checkbox values to file Clean SL Settings.txt. You can find this settings file at same location from where you launched Clean SL.jsx file.

You can remove Clean SL Settings.txt file to make script load with default values.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

Hers is a problem I see at times.

Capture.jpg]

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

Some weird stuff is happening there. Can you see some weird variable name on right side var idPnt4039383736..<more digits> ...?

This shouldn't happen. Can you send me Action Manager code the one you have on the left side?

Are you sure you didn't alter Action Manager code before clicking on "Clean Code"? Maybe something broke in your source code?

This code works for me with no problem:

Action Manager:

var idMk = charIDToTypeID( "Mk  " );

    var desc4 = new ActionDescriptor();

    var idNw = charIDToTypeID( "Nw  " );

        var desc5 = new ActionDescriptor();

        var idartboard = stringIDToTypeID( "artboard" );

        desc5.putBoolean( idartboard, false );

        var idMd = charIDToTypeID( "Md  " );

        var idRGBM = charIDToTypeID( "RGBM" );

        desc5.putClass( idMd, idRGBM );

        var idWdth = charIDToTypeID( "Wdth" );

        var idRlt = charIDToTypeID( "#Rlt" );

        desc5.putUnitDouble( idWdth, idRlt, 700.000000 );

        var idHght = charIDToTypeID( "Hght" );

        var idRlt = charIDToTypeID( "#Rlt" );

        desc5.putUnitDouble( idHght, idRlt, 500.000000 );

        var idRslt = charIDToTypeID( "Rslt" );

        var idRsl = charIDToTypeID( "#Rsl" );

        desc5.putUnitDouble( idRslt, idRsl, 72.000000 );

        var idpixelScaleFactor = stringIDToTypeID( "pixelScaleFactor" );

        desc5.putDouble( idpixelScaleFactor, 1.000000 );

        var idFl = charIDToTypeID( "Fl  " );

        var idFl = charIDToTypeID( "Fl  " );

        var idWht = charIDToTypeID( "Wht " );

        desc5.putEnumerated( idFl, idFl, idWht );

        var idDpth = charIDToTypeID( "Dpth" );

        desc5.putInteger( idDpth, 8 );

        var idprofile = stringIDToTypeID( "profile" );

        desc5.putString( idprofile, """none""" );

        var idGdes = charIDToTypeID( "Gdes" );

            var list1 = new ActionList();

        desc5.putList( idGdes, list1 );

    var idDcmn = charIDToTypeID( "Dcmn" );

    desc4.putObject( idNw, idDcmn, desc5 );

    var idDocI = charIDToTypeID( "DocI" );

    desc4.putInteger( idDocI, 195 );

executeAction( idMk, desc4, DialogModes.NO );

Clean Code:

Mk();

function Mk() {

  var s2t = function (s) {

  return app.stringIDToTypeID(s);

  };

  var descriptor = new ActionDescriptor();

  var descriptor2 = new ActionDescriptor();

  var list = new ActionList();

  descriptor2.putBoolean( s2t( "artboard" ), false );

  descriptor2.putClass( charIDToTypeID( "Md  " ), charIDToTypeID( "RGBM" ));

  descriptor2.putUnitDouble( charIDToTypeID( "Wdth" ), charIDToTypeID( "#Rlt" ), 700.000000 );

  descriptor2.putUnitDouble( charIDToTypeID( "Hght" ), charIDToTypeID( "#Rlt" ), 500.000000 );

  descriptor2.putUnitDouble( charIDToTypeID( "Rslt" ), charIDToTypeID( "#Rsl" ), 72.000000 );

  descriptor2.putDouble( s2t( "pixelScaleFactor" ), 1.000000 );

  descriptor2.putEnumerated( charIDToTypeID( "Fl  " ), charIDToTypeID( "Fl  " ), charIDToTypeID( "Wht " ));

  descriptor2.putInteger( charIDToTypeID( "Dpth" ), 8 );

  descriptor2.putString( s2t( "profile" ), "none" );

  descriptor2.putList( charIDToTypeID( "Gdes" ), list );

  descriptor.putObject( charIDToTypeID( "Nw  " ), charIDToTypeID( "Dcmn" ), descriptor2 );

  descriptor.putInteger( charIDToTypeID( "DocI" ), 195 );

  executeAction( charIDToTypeID( "Mk  " ), descriptor, DialogModes.NO );

}

And here's the screenshot of settings:

Screen Shot 2017-09-10 at 02.37.43.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 09, 2017 Sep 09, 2017

Copy link to clipboard

Copied

CSL.zip

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 10, 2017 Sep 10, 2017

Copy link to clipboard

Copied

JJMack​ apparently you found the limitation of Clean SL. Let he explain what's happening.

I opened your ScriptingListenerJS.log file you provided in the link and found one code block (starts at line 621) with an issue. Apparently there are two variable declarations that are braking my script.

var idPnt = charIDToTypeID( "Pnt " ); on line 659 and

var idPnt = charIDToTypeID( "#Pnt" ); on line 676.

From these two line you can see that same variable has 2 different values. This is where Clean SL brakes. My script reads code from top to bottom and it finds var idPnt = charIDToTypeID( "Pnt " ); and does some magic with it:

  • removes this code line from it's original position in the code and pushes it to the top, (hoisting)
  • replaces each instance of idPnt in the code with charIDToTypeID( "Pnt " ); (concatenation)
  • and removes variable declaration
  • boom, this is where we get issues, because var idPnt = charIDToTypeID( "#Pnt" ); never get's "fixed".

This is the limitation of my build, apparently. I didn't realise that same variable can have different values. And I assumed wrong. In order to fix this, I would need to rebuild entire logic of the code, witch I don't really want to do right now

So, to sum it up - if there are save variable declarations with different values - Clean SL will brake. Sorry.

-----------------------------

I was able to evaluate that code block by fixing it manually: renaming var idPnt = charIDToTypeID( "Pnt " ) to var idPntUniq = charIDToTypeID( "Pnt " ) and replacing idPnt to idPntUniq on the next line, where that variable was used. Had to do this 3 times, since same variable was declared 3 times in that block. Then tried Cleaning up the code (had all checkboxes enabled in the UI) and got error - aparentry there was a case xbytor2​ and Davide_Barranca​ mentioned about charID string can have different values: " ... two different stringIDs map to the same charID". So went and disabled Convert charID to stringID in the UI and code evaluated with no problem.

Again, not a perfect solution, but still, it's possible to make it work.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 10, 2017 Sep 10, 2017

Copy link to clipboard

Copied

I understand you not wanting to redo your design.,   I ran into an issue like that when I created my Photo Collage Toolkit.  I did not realize Photoshop only supported up to 53 Alpha Channels.  When I hit the limit it broke my scripts.  Rather the changing my clean simple template design to a complex hard to create and populate template design.  I change my scripts to check for the limit and limit collage templates to a 53 Image limit.  A toolkit script can tile more than 53 Images without any template just a simple script dialog however Image cam not be stamped with names and image are just tiled.  I would like to be able to stamp name on images or below the images. However I'm not that skilled and dealing with size resolution and font is beyond my ability. There the unknown number of character that may be in name complicates finding a suitable font and size that would work.

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Sep 10, 2017 Sep 10, 2017

Copy link to clipboard

Copied

Just a suggestion Tomas, how about a button to replace the cleaned code with c# code?

This example will return Late Binding code that can be used in c sharp.

////////////////////////////////////////////////////////////////////////////////////////

////Check shorten_stringIDToTypeID is not ticked!

/// Uses the cleaned data, so check if data exists first !

//// needs app to be passed into the new function I.E.

//// dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Photoshop.Application"));

////////////////////////////////////////////////////////////////////////////////////////

function javascript2csharp(data,shortStringID){

if(shortStringID){

alert("you must disable 'shorten stringIDToTypeID' before running this function!");

return;

}

var sData = data.split("\n");

var splitData=[];

for(var o in sData) {if(sData.length > 3) splitData.push(sData).toString().replace(/^\s+|\s+$/); }

var name = "function " + splitData[0].toString().replace(/\(\);$/,'');

splitData.splice(0,1);

for (var a in splitData){

if(splitData.length < 3) continue;

item = splitData.toString();

if(item.match( name)){

splitData = item.replace(/.+/,"static void " + name.replace(/function /,'') + "\( dynamic app \)\n{");

}else

if(item.match(/new ActionDescriptor\(\)/)){

splitData = item.replace(/new ActionDescriptor\(\);/g, "Activator.CreateInstance(Type.GetTypeFromProgID(\"Pho...

}else

if(item.match(/new ActionList\(\)/)){

splitData = item.replace(/new ActionList\(\);/g, "Activator.CreateInstance(Type.GetTypeFromProgID(\"Photoshop...

}else

if(item.match(/new ActionReference\(\)/)){

splitData = item.replace(/new ActionReference\(\);/g, "Activator.CreateInstance(Type.GetTypeFromProgID(\"Phot...

}else

if(item.match(/put/)){

splitData = item.replace(/charIDToTypeID/g, "app.CharIDToTypeID").replace(/stringIDToTypeID/g, "app.StringIDT...

}else

if(item.match(/executeAction/)){

item = item.replace(/executeAction/g, "app.ExecuteAction").replace(/DialogModes.NO/g, "3").replace(/"""/g, "\"").replace(/charIDToTypeID/g, "app.CharIDToTypeID")

item = item.replace(/stringIDToTypeID/g, "app.StringIDToTypeID");

splitData = item +"\n}";

}}

return splitData.join("\n").replace(/'/g,"\"");;

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 10, 2017 Sep 10, 2017

Copy link to clipboard

Copied

Nice I like!!! Added to todo list I think it's a great idea. I wont be able to test it though, as I only love JavaScript:)

I noticed you are looping the array with for (var o in sData) - why? You know it's a bad practise, right? javascript - Why is using "for...in" with array iteration a bad idea? - Stack Overflow

Don't mean to step on your toes or anything, but it's better to say it now rather hold my peace forever

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 10, 2017 Sep 10, 2017

Copy link to clipboard

Copied

Thomas

You do know that Adobe uses it own version of javsscript plug-in ScriptingSupport.8li its bases on an old version of javascript ECMAScript version 3.

 

 

Including and using ArrayBuffer, Uint8Buffer,FloatBuffer.... into JSX?

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 10, 2017 Sep 10, 2017

Copy link to clipboard

Copied

I don't know what ScriptingSupport.8li is (I'm on Mac), but I do know that Adobe uses extended version of old ECMA3 Javascript. That's why it's called ExtendScript

Why do you ask?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 10, 2017 Sep 10, 2017

Copy link to clipboard

Copied

Adobe did update the ScriptingSupport plug-in for CC 2015.5 they engineered in their designer's bug.

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

Tomas great work

thanks for sharing

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

Another suggestion for one more button Tomas...

$.writeln(etOutputText.text);

This will write the output to the console in ESTK where it can be easily copied to where ever you want.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

SuperMerlin​ why not copying straight from output window? Or are you unable to select text in the UI?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

Yes it will not copy from the window, so it is save open file, copy then paste.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

For real??????? Not selectable on Windows?

It works fine on Mac though. Could you look into my code and see if it's possible to make those fields editable on Windows (maybe I left some parameter out)?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

Panic over, I was trying ctrl/c ctrl/v after selecting the text, this does not work for me, but right click and select copy does work. How strange is that!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

Oh yeah, same on Mac. You have to right click to Copy. Weird indeed.

Anyways, i will add your request to soon-to-come version. I was just wondering if you knew the trick to Clear Console window via script? It would be great before printing to console to clean it out of previous data.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Sep 11, 2017 Sep 11, 2017

Copy link to clipboard

Copied

Here you go...

var bt = new BridgeTalk();

bt.target = 'estoolkit';

bt.body = function(){ app.clc();}.toSource()+"()";

bt.send(5);

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines