• 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

15.3K

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
Community Expert ,
Sep 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

First thing I tried failed.  I I download was the CleanSL script.  It faile with or wothout checking the nes option.  All I di in Photoshop was set a color sampler in CC 2017.  Yos script looped twice throwing the script error and genedated not actual cleaned code. Line 386 the function line

function incrementKeys(string) {

var keyName = string;

keyName = validateName(keyName);

return increment(keyName, storedKeys);

}

here is the scriptlistener log

// =======================================================

var idDlt = charIDToTypeID( "Dlt " );

    var desc112 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref17 = new ActionReference();

        var idClSm = charIDToTypeID( "ClSm" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idAl = charIDToTypeID( "Al  " );

        ref17.putEnumerated( idClSm, idOrdn, idAl );

    desc112.putReference( idnull, ref17 );

executeAction( idDlt, desc112, DialogModes.NO );

// =======================================================

var idtoolModalStateChanged = stringIDToTypeID( "toolModalStateChanged" );

    var desc113 = new ActionDescriptor();

    var idLvl = charIDToTypeID( "Lvl " );

    desc113.putInteger( idLvl, 1 );

    var idStte = charIDToTypeID( "Stte" );

    var idStte = charIDToTypeID( "Stte" );

    var identer = stringIDToTypeID( "enter" );

    desc113.putEnumerated( idStte, idStte, identer );

    var idTool = charIDToTypeID( "Tool" );

        var desc114 = new ActionDescriptor();

        var idIdnt = charIDToTypeID( "Idnt" );

        desc114.putString( idIdnt, """cols""" );

        var idTtl = charIDToTypeID( "Ttl " );

        desc114.putString( idTtl, """Color Sampler Tool""" );

    var idTool = charIDToTypeID( "Tool" );

    desc113.putObject( idTool, idTool, desc114 );

    var idKnd = charIDToTypeID( "Knd " );

    var idKnd = charIDToTypeID( "Knd " );

    var idmouse = stringIDToTypeID( "mouse" );

    desc113.putEnumerated( idKnd, idKnd, idmouse );

    var idkcanDispatchWhileModal = stringIDToTypeID( "kcanDispatchWhileModal" );

    desc113.putBoolean( idkcanDispatchWhileModal, true );

executeAction( idtoolModalStateChanged, desc113, DialogModes.NO );

// =======================================================

var idtoolModalStateChanged = stringIDToTypeID( "toolModalStateChanged" );

    var desc115 = new ActionDescriptor();

    var idLvl = charIDToTypeID( "Lvl " );

    desc115.putInteger( idLvl, 0 );

    var idStte = charIDToTypeID( "Stte" );

    var idStte = charIDToTypeID( "Stte" );

    var idexit = stringIDToTypeID( "exit" );

    desc115.putEnumerated( idStte, idStte, idexit );

    var idTool = charIDToTypeID( "Tool" );

        var desc116 = new ActionDescriptor();

        var idIdnt = charIDToTypeID( "Idnt" );

        desc116.putString( idIdnt, """cols""" );

        var idTtl = charIDToTypeID( "Ttl " );

        desc116.putString( idTtl, """Color Sampler Tool""" );

    var idTool = charIDToTypeID( "Tool" );

    desc115.putObject( idTool, idTool, desc116 );

    var idKnd = charIDToTypeID( "Knd " );

    var idKnd = charIDToTypeID( "Knd " );

    var idmouse = stringIDToTypeID( "mouse" );

    desc115.putEnumerated( idKnd, idKnd, idmouse );

    var idkcanDispatchWhileModal = stringIDToTypeID( "kcanDispatchWhileModal" );

    desc115.putBoolean( idkcanDispatchWhileModal, true );

executeAction( idtoolModalStateChanged, desc115, DialogModes.NO );

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc117 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref18 = new ActionReference();

        var idClSm = charIDToTypeID( "ClSm" );

        ref18.putClass( idClSm );

    desc117.putReference( idnull, ref18 );

    var idPstn = charIDToTypeID( "Pstn" );

        var desc118 = new ActionDescriptor();

        var idHrzn = charIDToTypeID( "Hrzn" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc118.putUnitDouble( idHrzn, idPxl, 316.500000 );

        var idVrtc = charIDToTypeID( "Vrtc" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc118.putUnitDouble( idVrtc, idPxl, 301.500000 );

    var idPnt = charIDToTypeID( "Pnt " );

    desc117.putObject( idPstn, idPnt, desc118 );

executeAction( idMk, desc117, DialogModes.NO );

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 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

Sorry JJMack​ I dont understand.

Also code in your screenshot is different then you have posed here. Can you provide same AM code for me that produced error?

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 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

Oh man, it's probably Clean SL Settings.txt file braking it

can you remove it and try again?

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 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

Will do.  The difference in what I sen ant what you see in the screen shot is the junk was removed I posted the actual logg.

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 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

Actual log you sent me also contains Junk code:)

Anyways, that error in your screenshot comes from Settings file. I did rather poor job writing settings to file. Will have to rework it somehow. Apologies for inconvenience.

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 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

It was the text file.

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
Community Expert ,
Sep 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

I mad what I thought was a very simple test toe see what you new extraction would  do.

I opened a new document added a gradient and set a color sampler.

Wow I did not expect that adding a gradient would record as three steps the first and  third steps  I did not expect and do not know their function.

You extraction of the gradient parameters was very revealing and I now can say perhaps I do not want the new option,  Its very good that you implemented features as options we can convert the code many way using your options.

Here is what I see adding spectrum gradient. with and without the new option

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 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

Yeap, it's overwhelming.

But you can always disable that feature in the UI, so I think it's fine. It might come handy with small AM blocks thou.

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 13, 2017 Sep 13, 2017

Copy link to clipboard

Copied

Yes many time I find I only want to externalize some of the possible parameters and default the other. Like the gradient a path gradient gradient name gradient type.  I would not have thought  that all the spectrum  colors and end and points would be recorded or needed. Gradients look as complex as text.  I thought they would be easy like named layer styles in the style palette. or alpha channel name. Shows what a slow learner I am.  I use PS for some twenty years..

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
Community Expert ,
Sep 14, 2017 Sep 14, 2017

Copy link to clipboard

Copied

Thomas

I find playing with Photoshop and your script and its options is very educational.  I though of an other Button I would like to see. For a new feature I think you may be able to implement.  I like keeping your UI open and cleaning to source code with your different options see the cleaned code and see that the cleaned code evaluates.  I do wish that Photoshop would update the image display in a more timely manor.

The button I would like to see is a Step button.  Where you would evaluate the clean code a step at a time. With each click to would retrieve a step in the cleaned code perhaps highlight it if possible in the cleaned code panel position at the top of the panel and then evaluate that single step where you remember where the next step cleaned code starts. To use when the button is clicked again.

You seem to be enjoying developing a new toy for my pleasure.

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 14, 2017 Sep 14, 2017

Copy link to clipboard

Copied

This is actually not a bad idea. But it will be a lot of fighting ScriptUI with this issue. Not sure I want to go this road:)

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 14, 2017 Sep 14, 2017

Copy link to clipboard

Copied

Only fight it if it will be fun.  ScriptUI is never fun for me.

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
LEGEND ,
Mar 18, 2018 Mar 18, 2018

Copy link to clipboard

Copied

I tested JavierAroche and your Clean SL scripts to see how fast they are with big complex AM codes. They work with same speed and are really fast! Unfortunatelly I must report bug in your code. I made simple 'Puppet Warp' (from Edit menu) on one letter which I just moved of few pixels. It changed code that looked good but didn't work. I got this error:

(...) - Could not transform because of program error. Line: 682

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
Enthusiast ,
Mar 18, 2018 Mar 18, 2018

Copy link to clipboard

Copied

Humanizer is based on bult-in feature which has some problems with some kinds of lists. E.g. custom warp. But what found might be my bug. I will check it.

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
LEGEND ,
Mar 18, 2018 Mar 18, 2018

Copy link to clipboard

Copied

No worries, that was message not to you but to Tomas Sinkunas . Regarding your 'cleaner' I didn't try it yet as I'm not sure I could later be able to use code based on json (I didn't try it so far ). Still you can post how that worked for 'Puppet Warp'.

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 ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

I find that JavierAroche is the fastest and most interesting.

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
LEGEND ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

I just checked how fast is his code comparing to mine, and I found it's not faster. It took exactly same amount of time for some random Puppet Wrap action. I ran it few times and it always was six seconds for mine and six seconds for his code.

Additionaly mine converts all Chars to Strings, while his not. That takes extra time, and script must be ran from Ps, while his is on-line. If he wanted to change Chars to Strings, then possibly he could store all of them in object / array. Strings are not needed after all, so it is still okey.

I think It's good his 'cleaner' works on-line since that wouldn't be good another public code has the same properties.

But maybe I'm wrong and with other piece of code his could be faster. You just had to tell me what you have converted?

By the way JavierAroche if you read it I found bug in your code. When I selected 'Create function' from drop-down menu and then clicked 'Parse' button there missed few closing parenthesis in output. Besides your script is very well done!

Edit: I tried some more complex 'Puppet Wrap' that took 40 seconds for my script. Then the same ScriptListener code I tried with 'parse-action-descriptor-code' what unfortunatelly broke script process after 30 seconds. Another challange for you

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
Enthusiast ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

In C++ SDK is example of Listener. It generates C++ code.

But if you look at these data it are same data as in ScriptListener.log but in another language.

So you can modify listener example code to generate clean javascript instead c++ and compile it into library and get rid of current version script listener.

This is AM for new layer:

var idMk = charIDToTypeID( "Mk  " );

    var desc1430 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref709 = new ActionReference();

        var idLyr = charIDToTypeID( "Lyr " );

        ref709.putClass( idLyr );

    desc1430.putReference( idnull, ref709 );

    var idLyrI = charIDToTypeID( "LyrI" );

    desc1430.putInteger( idLyrI, 36 );

executeAction( idMk, desc1430, DialogModes.NO );

This is generated C++ for new layer:

SPErr PlayeventMake(/*your parameters go here*/void)

{

     PIActionDescriptor result = NULL;

     DescriptorTypeID runtimeKeyID;

     DescriptorTypeID runtimeTypeID;

     DescriptorTypeID runtimeObjID;

     DescriptorTypeID runtimeEnumID;

     DescriptorTypeID runtimeClassID;

     DescriptorTypeID runtimePropID;

     DescriptorTypeID runtimeUnitID;

     SPErr error = kSPNoError;

     // Move this to the top of the routine!

     PIActionDescriptor desc0000000000b55578 = NULL;

     error = sPSActionDescriptor->Make(&desc0000000000b55578);

     if (error) goto returnError;

          // Move this to the top of the routine!

          PIActionReference ref0000000000a83e30 = NULL;

          error = sPSActionReference->Make(&ref0000000000a83e30);

          if (error) goto returnError;

          error = sPSActionReference->PutClass(ref0000000000a83e30, classLayer);

          if (error) goto returnError;

     error = sPSActionDescriptor->PutReference(desc0000000000b55578, keyNull, ref0000000000A83E30);

     if (error) goto returnError;

     error = sPSActionDescriptor->PutInteger(desc0000000000b55578, keyLayerID, 36);

     if (error) goto returnError;

     error = sPSActionControl->Play(&result, eventMake, desc0000000000B55578, plugInDialogSilent);

     if (error) goto returnError;

returnError:

     if (result != NULL) sPSActionDescriptor->Free(result);

     if (desc0000000000b55578 != NULL) sPSActionDescriptor->Free(desc0000000000b55578);

     if (ref0000000000a83e30 != NULL) sPSActionReference->Free(ref0000000000a83e30);

     return error;

}

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
LEGEND ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

Thx for posting it. Maybe one day I'll use it somehow. For now that's black magic for me

btw I just checked that Tomas Sinkunas​ 'cleaner' is the fastest. It took hardly 7 seconds for code my script handled in 40! But I can not give credit to him yet. When I ran output I got error. Although his code is fast it fails at complex 'Puppet Wrap' too

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 ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

Kukurykus

Your script works only for windows

could you make a variant for mac?

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
LEGEND ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

I never used mac, but my script was tested by 3 experienced OSX users and I was said it works, so I have no idea why it doesn't work for you. What error are you getting, in which line (when you run it from ESTK) - give some informations...

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 ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

I downloaded your script and inside the folder there is a .exe row so I thought it was for Windows

So how should I use it?

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
LEGEND ,
Mar 19, 2018 Mar 19, 2018

Copy link to clipboard

Copied

Everything is written in topic you downloaded it from. .exe file was used for original version of this script. When you look at code you'll see there is commented line at the bottom - that was part that worked for Windows only. Then I added last line that let script copy to clipboard final output be used also on OSX. .exe file I left only for those who'd like to try it as well. But with currect version it's completetly not needed. Ignore it and just run script. (Instructions were wrote to help users - right?)

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 ,
Mar 20, 2018 Mar 20, 2018

Copy link to clipboard

Copied

I tried your converter

on my cc2018 and computer mac

it only converts the last event and not all the ScriptingListener

Is it normal that it is like this or not?

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 ,
Mar 20, 2018 Mar 20, 2018

Copy link to clipboard

Copied

His script does not work for me on windows the first Palette window briefly opens the second dialog window never opens and the script terminates all the is generated is a text file one my desktop Code.txt the contains:

function cTT(v) {return charIDToTypeID(v)}; function sTT(v) {return stringIDToTypeID(v)}

function someName() {

(ref1 = new ActionReference()).putProperty(sTT('channel'), sTT('selection'));

(dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref1)

dsc1.putEnumerated(sTT('to'), sTT('ordinal'), sTT('none'))

executeAction(sTT('set'), dsc1, DialogModes.NO);

}

someName()

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