Skip to main content
Obi-wan Kenobi
Brainiac
November 3, 2016
Question

Create an array of arrays from a .txt file!

  • November 3, 2016
  • 2 replies
  • 4876 views

Hi all scripters,

The beginning is a .txt file containing data as:

text_1;text_12

text_2;text_23

text_3;text_39

I'm able to get an array as:

[text_1;text_12, text_2;text_23, text_3;text_39, …]

But I need that:

[ ["text_1","text_12"], ["text_2","text_23"], ["text_3","text_39"], …]

I've absolutely no idea about the way to get this array of arrays!!

Thanks for your ideas!

(^/)

This topic has been closed for replies.

2 replies

Wosven
Participating Frequently
November 6, 2016

Hi,

Here my “obscure” version with error-handling and a final pop-up listing which layer was renamed.

I hope I'll be able to write as fine scripts as you do Peter,

Swo

//DESCRIPTION:Rename layers from text file

/*

Text file should contains 2 columns (old name;new name), line by line

separator is ";", can be changed at line 27

If script is unable to find layer_names.txt, it asks for a file.

No check for forbidden characters in names:

you need to check the text file before running the script.

*/

(function () {

    if (app.locale.toString() == "FRENCH_LOCALE") {

        var infos = {

            findFile:"Choisir le fichier contenant la liste de noms :",

            msg:" calque(s) renommé(s) :"

        };

    } else {

        var infos = {

            findFile:"Select the text file for layer names:",

            msg:" layer(s) renamed:"

        };

    }

    // Modify text file's name and separator (sepa) if needed

    var txtList = "layer_names.txt",

        sepa= ";";

  

    var oNames = [], nNames = [], rNames = [];

    var myListFile = File(myFindFile(txtList));

    // datas

    var testNames = listNames();

    if (testNames && oNames.length == nNames.length) {

        var myLayers = app.activeDocument.layers, c = 0;

      

        for (var L = 0; L < myLayers.length; L++) {

            var testN = false;

            for (var n = 0; n < oNames.length && !testN; n++) {

                if (myLayers.name == oNames && !app.activeDocument.layers.itemByName(nNames).isValid) {

                    myLayers.name = nNames;

                    // list renamed layers

                    rNames.push(oNames + " => " + nNames);

                    // ensure old name doesn't conflict with same new name :

                    oNames = "";

                    testN = true;

                    c++;

                }

            } // for n

        } // for L

        alert(c + infos.msg + "\n" + rNames.join("\n"));

    }

    function listNames() {

        // Open the file for reading

        myListFile.open("r");

        var text = myListFile.read();

        var lines = text.split("\n");

        if (lines.length > 0) {

            for (var y =0; y < lines.length; y++) {

                var l = lines;

                if (l.length != 0) {

                    if (l[0] !== "") {

                        var names = l.split(sepa);

                        if (names.length == 2) {

                            oNames.push(names[0]);

                            nNames.push(names[1]);

                        }

                    }

                } // l.length

            } // for

            return true;

        } // lines.length

        return false;

    }

    //////// FUNCTIONS ////////////

    function myFindFile(myFilePath) {

        var myScriptFile = myGetScriptPath();

        var myScriptFile = File(myScriptFile);

        var myScriptFolder = myScriptFile.path;

        myFilePath = myScriptFolder + "/" + myFilePath;

        if(File(myFilePath).exists == false) {

            //Display a dialog.

            myFilePath = File.openDialog(infos.findFile);

        }

        // else alert("ok");

        return myFilePath;

    }

    function myGetScriptPath() {

        try {

            myFile = app.activeScript;

        }

        catch(myError){

            myFile = myError.fileName;

        }

        return myFile;

    }

}());

Community Expert
November 4, 2016

Hi Obi-wan,

one split() and one loop with another split() can get you there.

Depending on the line separator—\n or \r—that could be:

var array1 = string.split("\r");

var array2 = [];

for(var n=0;n<array1.length;n++)

{

    array2[array2.length++] = array1.split(";")

};

Regards,
Uwe

Obi-wan Kenobi
Brainiac
November 4, 2016

Hi Uwe,

It seemed interesting but I can't make it work in my script.

The deal: I have 4 Layers [Layer_1, Layer_2, Layer_3 and Layer_4] and I want to change their name but not necessarily for all!

So I have a list (.txt file):

Layer_1;Layer_12

Layer_2;Layer_23

To validate the code, I've temporarily pasted this list directly into the .jsx:

myList = ["Layer_1;Layer_12","Layer_2;Layer_23"];

var myLayers = app.activeDocument.layers;

for (var L = 0; L < myLayers.length; L++) {

        var myLayerName_0 = myLayers.name;

        var mLength_0 = myLayerName_0.length;

        for (var N = 0; N < myList.length; N++) {

                var mList_0 = myList;

                myConcordance = mList_0.slice(0,mLength_0);

                myLayerName_1 = mList_0.slice(mLength_0+1,mList_0.length);

                   

                    if ( myLayerName_0 == myConcordance ) var myLayerName_0 = myLayerName_1;

        }

}

The writing seems logical but nothing happens in the Layers panel! 

Tired! Thanks in advance! 

(^/)

Community Expert
November 5, 2016

Hi Obi-wan,

before talking about your code, I want to talk about the separator string—";"—you are using with your list:


It should be one, that is not used in the listed names of layers. And that could become quite difficult since it seems like every possible character is allowed for forming a name of a layer. Even a tabulator character could be used in a layer name: "\t”. It could not be typed in, but it could be copy/pasted to the Name input field.


So the question boils down to:
What is a good separator string for a concordance list, old name|separator|new name for renaming layers?

How about:
"\u0016"

That is used as a special character for tables with InDesign.

I tried to copy/paste it to the Name input field of the Layers panel, but it was stripped out while pasting.

Still one could assign a name using "\u0016" as part of a string to a layer's name by scripting:

app.documents[0].layers[0].name = "N"+"\u0016"+"N";

Screenshot after running this line:

So it's not 100% save to use a delimiter like that.
Does someone has a better idea?

Hm.

Would a Windows user be able to insert "\u0016" to the Name edit field using the keyboard by pressing Alt+0016 ?

Or Alt 022 or Alt 22 ?
Cannot test this, currently I'm on Mac OSX.

Regards,
Uwe