Skip to main content
cwonderly
Participating Frequently
November 27, 2018
Answered

Specific character changing to Small Caps

  • November 27, 2018
  • 1 reply
  • 1014 views

I am writing a code to automate making around 100 graphics. I am trying to write it so I do not have to do any fine tuning after running the script. I do not know how to handle adjusting single characters in a text layer though. Here is an example of what I am trying to accomplish. It is for having a last name on the back of a football jersey.

One if statement I want to make is if the last name starts with "Mc" to change the "c" to small caps. I figured the code should start like this, but not sure how to call on just the second character to make that small caps:

if (variable.startsWith("Mc"){

This would be for instance if the name is "McDonald" to have the "c" as small caps.

Thanks. Sorry I am fairly new to photoshop scripting and have been doing just the simple things. This is by far the most advanced I have done. Let me know if I need to provide anything else.

Message was edited by: Cory Wonderly

Correct answer r-bin

Try to deal with this script.

My English is not good enough to explain everything in detail to you how it works.

 

var s = activeDocument.activeLayer.textItem.contents;

 

var x1 = s.indexOf("Mc");

if (x1 >= 0) set_text_style(x1+1, 1, small_caps); 

 

var x2 = s.indexOf("-");

if (x2 >= 0) set_text_style(x2, 1, set_font); 

 

alert("Done!");

 

function small_caps(d) 

    {

    d.putEnumerated(stringIDToTypeID("fontCaps"), stringIDToTypeID("fontCaps"), stringIDToTypeID("smallCaps")); 

    }       

 

function set_font(d) 

    {

    d.putString(stringIDToTypeID("fontPostScriptName"), "ArialMT"); 

    d.putString(stringIDToTypeID("fontName"), "Arial"); 

    }       

 

function set_size(d) 

    {

    d.putUnitDouble(stringIDToTypeID("size"), stringIDToTypeID("pointsUnit"), 50);

    }

 

function set_text_style(from, len, style_modifier) 

    { 

    try { 

        // get textKey descriptor for activeLayer

           

        var r = new ActionReference(); 

        r.putEnumerated(stringIDToTypeID("textLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); 

        var textKey = executeActionGet(r).getObjectValue(stringIDToTypeID("textKey"));

 

        var list = textKey.getList(stringIDToTypeID("textStyleRange"));

 

        var new_list = new ActionList(); 

 

        // get styles of each char, modify if needed

 

        var styles = new Array();           

 

        var x = 0; // chars counter

 

        for (var i = 0; i < list.count; i++)

            {

            var d = list.getObjectValue(i);

 

            var x0 = d.getInteger(stringIDToTypeID("from"));

            var x1 = d.getInteger(stringIDToTypeID("to"));

            var st = d.getObjectValue(stringIDToTypeID("textStyle"));

 

            for (var n = 0; n < x1-x0; n++)

                {

                if (x >= from && x < from+len) // modify current style

                    {

                    var d = new ActionDescriptor(); 

                    d.fromStream(st.toStream()); // duplicate style

                    style_modifier(d);           // modify current style

                    styles.push(d);

                    }

                else

                    {

                    styles.push(st);

                    }

                ++x;

                }

            }

 

        styles.push(new ActionDescriptor());

 

        // scan styles, modify if needed, compact to range (from-to)

 

        var from = 0;

 

        for (var i = 0; i < styles.length-1; i++)

            {

            if (!styles[i].isEqual(styles[i+1]))

                {

                var d = new ActionDescriptor(); 

                d.putInteger(stringIDToTypeID("from"), from); 

                d.putInteger(stringIDToTypeID("to"), i+1); 

                d.putObject(stringIDToTypeID("textStyle"), stringIDToTypeID("textStyle"), styles[i]); 

                new_list.putObject(stringIDToTypeID("textStyleRange"), d);

 

                from = i+1;

                }

            }

 

        // put new styles to textKey descriptor

 

        textKey.putList(stringIDToTypeID("textStyleRange"), new_list); 

 

        // set modified textKey back to textLayer

 

        var d = new ActionDescriptor(); 

        var r = new ActionReference(); 

        r.putEnumerated(stringIDToTypeID("textLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); 

        d.putReference(stringIDToTypeID("null"), r); 

        d.putObject(stringIDToTypeID("to"), stringIDToTypeID("textLayer"), textKey); 

 

        executeAction(stringIDToTypeID("set"), d, DialogModes.NO); 

        } 

    catch (e) { alert(e); }  

    } 

1 reply

r-binCorrect answer
Legend
November 27, 2018

Try to deal with this script.

My English is not good enough to explain everything in detail to you how it works.

 

var s = activeDocument.activeLayer.textItem.contents;

 

var x1 = s.indexOf("Mc");

if (x1 >= 0) set_text_style(x1+1, 1, small_caps); 

 

var x2 = s.indexOf("-");

if (x2 >= 0) set_text_style(x2, 1, set_font); 

 

alert("Done!");

 

function small_caps(d) 

    {

    d.putEnumerated(stringIDToTypeID("fontCaps"), stringIDToTypeID("fontCaps"), stringIDToTypeID("smallCaps")); 

    }       

 

function set_font(d) 

    {

    d.putString(stringIDToTypeID("fontPostScriptName"), "ArialMT"); 

    d.putString(stringIDToTypeID("fontName"), "Arial"); 

    }       

 

function set_size(d) 

    {

    d.putUnitDouble(stringIDToTypeID("size"), stringIDToTypeID("pointsUnit"), 50);

    }

 

function set_text_style(from, len, style_modifier) 

    { 

    try { 

        // get textKey descriptor for activeLayer

           

        var r = new ActionReference(); 

        r.putEnumerated(stringIDToTypeID("textLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); 

        var textKey = executeActionGet(r).getObjectValue(stringIDToTypeID("textKey"));

 

        var list = textKey.getList(stringIDToTypeID("textStyleRange"));

 

        var new_list = new ActionList(); 

 

        // get styles of each char, modify if needed

 

        var styles = new Array();           

 

        var x = 0; // chars counter

 

        for (var i = 0; i < list.count; i++)

            {

            var d = list.getObjectValue(i);

 

            var x0 = d.getInteger(stringIDToTypeID("from"));

            var x1 = d.getInteger(stringIDToTypeID("to"));

            var st = d.getObjectValue(stringIDToTypeID("textStyle"));

 

            for (var n = 0; n < x1-x0; n++)

                {

                if (x >= from && x < from+len) // modify current style

                    {

                    var d = new ActionDescriptor(); 

                    d.fromStream(st.toStream()); // duplicate style

                    style_modifier(d);           // modify current style

                    styles.push(d);

                    }

                else

                    {

                    styles.push(st);

                    }

                ++x;

                }

            }

 

        styles.push(new ActionDescriptor());

 

        // scan styles, modify if needed, compact to range (from-to)

 

        var from = 0;

 

        for (var i = 0; i < styles.length-1; i++)

            {

            if (!styles[i].isEqual(styles[i+1]))

                {

                var d = new ActionDescriptor(); 

                d.putInteger(stringIDToTypeID("from"), from); 

                d.putInteger(stringIDToTypeID("to"), i+1); 

                d.putObject(stringIDToTypeID("textStyle"), stringIDToTypeID("textStyle"), styles[i]); 

                new_list.putObject(stringIDToTypeID("textStyleRange"), d);

 

                from = i+1;

                }

            }

 

        // put new styles to textKey descriptor

 

        textKey.putList(stringIDToTypeID("textStyleRange"), new_list); 

 

        // set modified textKey back to textLayer

 

        var d = new ActionDescriptor(); 

        var r = new ActionReference(); 

        r.putEnumerated(stringIDToTypeID("textLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); 

        d.putReference(stringIDToTypeID("null"), r); 

        d.putObject(stringIDToTypeID("to"), stringIDToTypeID("textLayer"), textKey); 

 

        executeAction(stringIDToTypeID("set"), d, DialogModes.NO); 

        } 

    catch (e) { alert(e); }  

    } 

Kukurykus
Legend
July 12, 2021

I created document with text layer containing 'McDonalds' word. Running your script I'm getting:

"RefferenceError: styles.isEqual is not a function", then "Done!" alert. Small Caps are not applied?

Legend
July 12, 2021
styles -->> styles[i] in two places.
Find it yourself?