9 Replies Latest reply on Aug 2, 2011 8:55 AM by Kasyan Servetsky

    Is it possible to create text frame with nonuniform formatting applied to text?

    Kasyan Servetsky Level 5

      Hi all,

       

      By this script

      var doc = app.documents.add(70, 20, 300, "Test", NewDocumentMode.RGB);
      var textLayer = doc.artLayers.add();
      textLayer.name = "Text";
      textLayer.kind = LayerKind.TEXT;
      
      var solidColorRef = new SolidColor();
      solidColorRef.rgb.red = 0;
      solidColorRef.rgb.green = 174;
      solidColorRef.rgb.blue = 239;
      
      var ti = textLayer.textItem;
      with (ti) {
           contents = "Blah-blah-blah!";
           kind = TextType.PARAGRAPHTEXT;
           height = new UnitValue("20 mm");
           width = new UnitValue("70 mm");
           position = [ new UnitValue("0 mm"), new UnitValue("0 mm") ];
           font = "MinionPro-Bold";
           size = new UnitValue("24 pt");
           color = solidColorRef;
           justification = Justification.CENTER;
      }
      

      I can create a text frame with uniform formatting like so

      SNAG-0011.png
      But, as far as I understand, it’s impossible to make a frame and apply different font sizes, colors, etc. (Please confirm or refute this).

      To achive the result by script like so:

      SNAG-0014.png

      The Data Browser shows formatting only for the beginning of such text.


      What I want to achieve is to take a text frame from  InDesign document and recreate it in psd-file. (The text should be editable)

      Is there another way to achieve this: by plug-ins, extensions, incantation, etc?

       

      Regards,
      Kasyan

        • 1. Re: Is it possible to create text frame with nonuniform formatting applied to text?
          Paul Riggott Level 6

          Have  a look at Text.jsx in xtools or maybe an incantation.

          • 2. Re: Is it possible to create text frame with nonuniform formatting applied to text?
            c.pfaffenbichler Level 9

            Michael L Hale also made some (I think) pertinent remarks in this thread:

            http://forums.adobe.com/message/3746099#3746099

             

            Seems text-objects are not easily worked with in Photoshop Scripting.

            • 3. Re: Is it possible to create text frame with nonuniform formatting applied to text?
              Muppet Mark Level 5

              Kasyan… Alternative route and the way I would look at for what you have in mind… Is for an ID forum tread wanting ID to web designer pages Editable?

               

              Anyhows my route use Illustrators PSD Export (I would expect this to be a plug-in)…

               

              In InDesign export file to PDF. Open PDF in Illustrator Export to PSD. Open PSD in Photoshop… Why… Illustrator will do a pretty good job of text like this there are its limitations but it will do one hell of a lot of work for you… I would also make any required text changes/edits at this stage too…

               

              Tip: in either ID or AI (up to you) get what ever you want organized in to top level layers (ocgs in pdf)…

              Picture 1.png

              Result is… Editable (to end user) Type basics like colors, fonts are maintained…

              Picture 2.png

               

              Oh forgot it can also 'open PSD' files edit the text and export replacing the original. This too would be my preferred of editing text…

              • 4. Re: Is it possible to create text frame with nonuniform formatting applied to text?
                Kasyan Servetsky Level 5

                First of all, thanks to all who replied me.

                 

                @Muppet Mark

                Is for an ID forum tread wanting ID to web designer pages Editable?

                 

                Yes, it is. I've wrote a half of the script, but now I got stuck on this part.

                I tried your approach, but it didn't work for me. (I tried it with different file formats, pdf versions, copy-paste via clipboard, etc).

                When I'm opening the pdf-file in Illustrator I get a warning:

                SNAG-0017.png

                And some text is really gets outlined.

                SNAG-0016.png

                 

                On the other hand, my client wants to avoid using Illustrator because (quote from his e-mail):

                • Text is split into different lines of point text (area text is required by sitegrinder to properly turn it into html/css)
                • Different styling splits the text up as well
                • Vertical text features are lost: leading and space after (sitegrinder turns this stuff into css)

                 

                To make things more clear, here I posted two sample files: an InDesign document with a single text frame and manually created a psd-file — the result I want to get.

                 

                @Paul Riggott

                I have x-tools (the latest version 1.7.5). I know how to use Stdlib (I've even read the whole Stdlib.pdf a couple of years ago).

                However I don't have a clear idea how to use Text.jsx

                 

                Here's what I was trying to do:

                I should load it into my script as a library, shouldn't I?

                So I add this line at the top:

                #include "/C/Program Files/Adobe/xtools/xlib/Text.jsx"
                

                Which results in the "cTID is not function" error (lines 158 and 426).

                SNAG-0018.png

                SNAG-0019.png

                Probably this happens because my PS version (12.0.4, Windows) is newer than x-tools was written for.

                I save the file as copy in my 'Adobe Scripts' folder and comment out the problematic lines.

                Now it loads without errors.

                I try to use the 'addNewTextLayer' method, this simple script works:

                 

                #include "~/Documents/Adobe Scripts/Text_K.jsx"
                var doc = app.activeDocument;
                var color = Text.toRGBColor(255, 0, 0);
                var options = {
                 layerName: "Test",
                 contents: "Blah-Blah-Blah",
                 size: 30,
                 color: color
                };
                var layer = Text.addNewTextLayer(doc, options);
                

                 

                But how to use text ranges: read, write, modify them? I can't find any description.

                Could someone give me (point me to) an example?

                 

                @c.pfaffenbichler

                I am afraid this is far beyond my level. I am not a professional programmer -- just an ordinary user writing scripts in an amateurish way. From time to time, I see some gurus on this forum talking about Action Manager, descriptors, keys, action references, action lists, etc. Sometimes I ask how to do something by script and someone gives me an Action Manager code which works, but I don't understand how it works. I could find only 10 pages on the subject in the PS scripting guide. I don't know even how to approach to this stuff.

                 

                Could someone point me to some information about this I could read? Or give me some simple examples?

                 

                How, for example, can I use this code in practice?

                 

                Thanks in advance,
                Kasyan

                • 5. Re: Is it possible to create text frame with nonuniform formatting applied to text?
                  Paul Riggott Level 6

                  I haven't used Text.jsx myself but there is an example that Mike has done here..

                  http://ps-scripts.com/bb/viewtopic.php?p=4788

                   

                  Maybe X will chime in and give words of wisdom.

                  1 person found this helpful
                  • 6. Re: Is it possible to create text frame with nonuniform formatting applied to text?
                    Michael L Hale Level 5

                    Paul Riggott wrote:

                     

                    Maybe X will chime in and give words of wisdom.

                    Maybe he will. But until then here are some suggestions.

                     

                    It seems for the newer version of text.jsx you need to include stdlib.jx before you include text.js. So with the default install of xtools the includes are:

                     

                    //@includepath "/c/Program Files/Adobe/xtools;/Developer/xtools"
                    //@include "xlib/stdlib.js"
                    //@include "xlib/Text.jsx"
                    

                     

                    It seems that you can't set textRanges with Text.addNewTextLayer() you have to use Text.modifyTextLayer()

                    1 person found this helpful
                    • 7. Re: Is it possible to create text frame with nonuniform formatting applied to text?
                      Michael L Hale Level 5

                      So other things I noticed is text.jsx doesn't work with UnitValues. It uses Action Manager to work with textRanges. And it seems that Adobe has changed how units in textItem work. So it is hard to figure out what values to use. Text.addNewTextLayer() and Text.modifyTextLayer() seem to what different values to have the text the same size.

                       

                      So below is a modified example from the post at PS-Scripts on how to create a text layer with different textRanges using the current text.jsx.Note I hard coded the sizes to get this to work as I expected.

                      function tsrDemo(doc) {
                           var doc = app.documents.add(new UnitValue(70,'mm'), new UnitValue(20,'mm'), 300, "Test", NewDocumentMode.RGB);
                           // we want to create a new text layer so create a new TextOptions with the contents as the argument
                            var opts = new TextOptions("Blah-blah-blah!");
                             // override the default settings
                             opts.layerName = "Test";
                             opts.kind = TextType.PARAGRAPHTEXT;
                             opts.height = 800;// pixels
                             opts.width = 200;
                             opts.position = [ 0, 0 ];// pixels
                             opts.justification = Justification.CENTER;
                             opts.font = Text.findFont("Minion Pro Bold");
                             opts.size = 6;// not sure what unit this needs
                             opts.color = Text.toRGBColor(0, 174, 239);
                             
                             // create a new text layer with those options
                           var layer = Text.addNewTextLayer(doc, opts);
                             
                             
                             var opts = new TextOptions( layer.textItem); 
                             opts.contents = layer.textItem.contents;
                             // now need to construct TextStyles for each range we want to set
                             // for ranges we can only change the font, size, and color
                             // first set a textStyle that matches the TextOptions
                            var s1 = new TextStyle(undefined,undefined,undefined);
                             // now set a textStyle for each different style you want
                            var s2 = new TextStyle(undefined, 12, Text.toRGBColor(0, 0,0));// for some reason size values here are not the same scale as above
                             // define more TextStyles as needed. here we only need one
                           
                            // Now create the set of ranges to apply the styles over
                            var ranges = new TextStyleRanges();
                             // the first range must start at 0.  In this example we want the first range unchanged
                             // so we use the TextStyle that matches the TextOptions
                             // this range covers the entire contents
                            ranges.add(new TextStyleRange(0, opts.contents.length, s1));
                             // this range covers the middle 'blah'
                             ranges.add(new TextStyleRange(5, 9, s2));
                              // we now add the ranges we set to the TextOptions
                            opts.ranges = ranges;
                             
                             Text.modifyTextLayer(doc, opts, doc.activeLayer); 
                      
                          };
                          
                          tsrDemo();
                      
                      
                      • 8. Re: Is it possible to create text frame with nonuniform formatting applied to text?
                        Kasyan Servetsky Level 5

                        Thank you very much for your help, guys.
                        Michael's example works well for me so I see the light at the end of tunnel now.

                         

                        Regards,
                        Kasyan

                        • 9. Re: Is it possible to create text frame with nonuniform formatting applied to text?
                          Kasyan Servetsky Level 5

                           

                          Dear all,

                           

                           

                           

                          I've got very close to what I want.

                           

                          Here I posted a sample InDesign document and the resulting psd-file created by the script below.

                           

                          var layer;
                          var doc = app.activeDocument;
                          var oldXunits =doc.viewPreferences.horizontalMeasurementUnits;
                          var oldYunits = doc.viewPreferences.verticalMeasurementUnits;
                          doc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.MILLIMETERS;
                          doc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.MILLIMETERS;
                                              
                          var layers = doc.layers;
                          for (var i = layers.length-1; i >= 0; i--) {
                               layer = layers[i];
                               if (layer.name.match(/-text$/) !=null) {
                                    textFrame = layer.textFrames[0];
                                    if (textFrame != null && textFrame.appliedObjectStyle == doc.objectStyles.itemByName("-text")) {
                                         var textObj = GetTextData(textFrame);
                                         var serObj = textObj.toSource();
                                         CreateBridgeTalkMessage(serObj);
                                    }
                               }
                          }
                          
                          doc.viewPreferences.horizontalMeasurementUnits = oldXunits;
                          doc.viewPreferences.verticalMeasurementUnits = oldYunits;
                          
                          //===================================== FUNCTIONS  ======================================
                          function CreateBridgeTalkMessage(serObj) {
                               var bt = new BridgeTalk();
                               bt.target = "photoshop";
                               
                               var script = '//@includepath "/c/Program Files/Adobe/xtools;/Developer/xtools;/Applications/Adobe Photoshop CS5/xtools"\r';
                               script += '//@include "xlib/stdlib.js"\r';
                               script += '//@include "xlib/Text.jsx"\r';
                               script += 'ProcessInPS = ' + ProcessInPS.toSource() + '\r';
                               script += 'ProcessInPS(' + serObj + ');';
                               bt.body = script;
                          //~      $.write(script);
                          //~      exit();
                               bt.onError = function(errObj) {
                                    $.writeln("Error: " + errObj.body);
                               }
                               bt.onResult = function(resObj) {} 
                               bt.send(100);
                          }
                          //--------------------------------------------------------------------------------------------------------------------------------------------------------
                          function ProcessInPS(obj) {
                               var doc, tsr, s;
                               var tsrs = obj.textRanges;
                               tsr = tsrs[0];
                               var oldUnits = preferences.rulerUnits;
                               preferences.rulerUnits = Units.MM;
                               var opts = new TextOptions(obj.contents);
                               var width = new UnitValue(obj.frameWidth,'mm');
                               var height = new UnitValue(obj.frameHeight,'mm');
                               if (app.documents.length == 0) {
                                    doc = app.documents.add(obj.pageWidth, obj.pageHeight, 300, "Text test", NewDocumentMode.RGB);
                               }
                               else {
                                    doc = app.activeDocument;
                               }
                               var textLayer = doc.artLayers.add();
                               textLayer.kind = LayerKind.TEXT;
                               var solidColorRef = new SolidColor();
                               solidColorRef.rgb.red = tsr.color[0];
                               solidColorRef.rgb.green = tsr.color[1];
                               solidColorRef.rgb.blue = tsr.color[2];
                               var ti = textLayer.textItem;
                               ti.contents = obj.contents;
                               ti.kind = TextType.PARAGRAPHTEXT;
                               ti.width = width;
                               ti.height = height;
                               ti.position = [new UnitValue(obj.position[0], 'mm'), new UnitValue(obj.position[1], 'mm')];
                               ti.font = tsr.font;
                               ti.size = new UnitValue(tsr.size, 'pt');
                               ti.leading = new UnitValue(obj.leading, 'pt');
                               ti.color = solidColorRef;
                               ti.justification = eval(obj.justification);
                               textLayer.name = obj.layerName;
                               var ranges = new TextStyleRanges();
                               for (var i = 0; i < tsrs.length; i++) {
                                    tsr = tsrs[i];
                                    s = new TextStyle(tsr.font, tsr.size, Text.toRGBColor(tsr.color[0], tsr.color[1], tsr.color[2]));
                                    ranges.add(new TextStyleRange(tsr.from, tsr.to, s));          
                               }
                               opts.ranges = ranges;
                               Text.modifyTextLayer(doc, opts, doc.activeLayer);
                               preferences.rulerUnits = oldUnits;
                          }
                          //--------------------------------------------------------------------------------------------------------------------------------------------------------
                          function GetTextData(tf) {
                               var obj, tsr;
                               var textRanges = [];
                               var txtObj = {}
                               var gb = tf.geometricBounds;
                               var width = gb[3] - gb[1];
                               var height = gb[2] - gb[0];
                               var txt = tf.texts[0];
                               var cont = txt.contents;
                               var tsrs = txt.textStyleRanges;
                               
                               for (var i = 0; i < tsrs.length; i++) {
                                    tsr = tsrs[i];
                                    obj = {
                                         contents : tsr.contents,
                                         color : tsr.fillColor.colorValue,
                                         font : tsr.appliedFont.postscriptName,
                                         size : tsr.pointSize,
                                         length : tsr.characters.length,
                                         from : tsr.characters.firstItem().index,
                                         to : tsr.characters.lastItem().index +1
                                    }
                               
                                    textRanges.push(obj);
                               }
                          
                               txtObj.textRanges = textRanges;
                               txtObj.position = [gb[1], gb[0]];
                               txtObj.frameWidth = width;
                               txtObj.frameHeight = height;
                               txtObj.contents = cont;
                               txtObj.layerName = tf.itemLayer.name;
                               txtObj.leading = txt.leading;
                               txtObj.pageHeight = Math.round(doc.documentPreferences.pageHeight);
                               txtObj.pageWidth = Math.round(doc.documentPreferences.pageWidth);
                               
                               switch(txt.justification) {
                                    case Justification.LEFT_ALIGN:
                                         txtObj.justification = "Justification.LEFT";
                                         break;
                                    case Justification.CENTER_ALIGN:
                                         txtObj.justification = "Justification.CENTER";
                                         break;
                                    case Justification.RIGHT_ALIGN:
                                         txtObj.justification = "Justification.RIGHT";
                                         break;
                                    case Justification.LEFT_JUSTIFIED:
                                         txtObj.justification = "Justification.LEFTJUSTIFIED";
                                         break;          
                                    case Justification.RIGHT_JUSTIFIED:
                                         txtObj.justification = "Justification.RIGHTJUSTIFIED";
                                         break;
                                    case Justification.CENTER_JUSTIFIED:
                                         txtObj.justification = "Justification.CENTERJUSTIFIED";
                                         break;
                                    case Justification.FULLY_JUSTIFIED:
                                         txtObj.justification = "Justification.FULLYJUSTIFIED";
                                         break;               
                                    default:
                                         txtObj.justification = "Justification.LEFT";
                               }
                               
                               return txtObj;
                          }
                          //--------------------------------------------------------------------------------------------------------------------------------------------------------
                          

                           

                           

                          However, I encountered a couple of issues:
                          I am unable to pass returns and new line characters from InDesign to Photoshop. An example like so

                          02-08-2011 18-39-27.png

                          produces an error:

                          02-08-2011 17-49-37.png

                           

                          I dumped the PS script into console, copied it and pasted into a new script — it's obvious that its totally broken.

                          02-08-2011 17-50-36.png

                          An idea came to me to replace returns with another character, for example, underscore:

                          ...
                          var cont = txt.contents.replace(/\r/g, "_");...
                          contents : tsr.contents.replace(/\r/g, "_"),
                          ...
                          

                           

                           

                          And then replace underscores with returns in PS:

                          obj.contents = obj.contents.replace(/_/g, "\r");
                          $.write(obj.contents);
                          ti.contents = obj.contents;
                          

                          but it didn't work. As you see in the screenshot "\r" characters are written into the console

                          02-08-2011 18-06-53.png

                          but they don't appear in the psd file

                          02-08-2011 18-07-11.png

                          Any ideas how to solve this?

                           

                           

                          Another problem is with TextItem's leading property: it is mentioned in the PS scripting reference and in OMV, but it doesn't exist in the Data Browser.02-08-2011 17-42-56.png

                          The line in which I set a leading value doesn't produce any error, it is just ignored and the leading is always set to Auto.

                          InDesign

                          02-08-2011 17-40-47.png

                          Photoshop

                          02-08-2011 17-40-12.png

                          Regards,
                          Kasyan