11 Replies Latest reply on May 26, 2016 5:17 AM by Russ Ward

    AddText does not add

    K.Daube Level 1

      You know, my favorite errors ar typos... but I have not found any in my codet. So I hope You see my error.

      • I have settings stored in paragraphs of a reference page and want to replace them from contents of an array.
      • At line 6 fo the code snipped the alert displays that replaceString contains 5 lines.
      • Leaving debug mode after line 7 displays that the current content is selected
        selection.png
      • However, after performing line 9 nothing is inserted - the paragraph is empty

       

      // var tr is defined in a subroutine
      var replaceString  = "";
      for (j = 0; j < gasUserVariables.length; j++) {
        replaceString = replaceString + "\n" + gasUserVariables[j];   // \n gives new paragraphs
      }
      alert (replaceString);
      targetDoc.TextSelection = tr;                 // some ¶s excluding last ¶-mark
      targetDoc.Clear(0);                           // delete selected content
      targetDoc.AddText(tr.beg, replaceString);     // insert the text from the array
      

      Where is my mistake?

       

      BTW: in the function where I set up the selection I need to reduce FV_OBJ_END_OFFSET by 2 to exclude the final ¶ mark from the selection (snippet only):

      var tr = new TextRange();
        tr.beg.obj =  oPara;                            // text range starts at the first found para
        tr.beg.offset = 0;
        while (oPara.ObjectValid ()) {
          pgfFmt = oPara.Name;
          if (pgfFmt == type) {                         // must not be interspearsed with other pgf formats
            tr.end = new TextLoc (oPara, Constants.FV_OBJ_END_OFFSET - 2);  
            oPara = oPara.NextPgfInFlow;
            continue;
          }
          break;
        } 
        return tr; 
      

      I'm working in FM-13.

        • 1. Re: AddText does not add
          K.Daube Level 1

          Hec, I can not edit my post ...

          All said starting with "BTW: in the function ..." should be deleted. In the the screenshot you see wha I need a value of 2: there is an empty paragraph of the relevant type, which must not be there...

          • 2. Re: AddText does not add
            Klaus Göbel Level 3

            Hi Klaus,

             

            In line 09 you use a textrange, but to insert text, you don't need a textrange, but a textlocation.

            • 3. Re: AddText does not add
              K.Daube Level 1

              OK, Klaus, but why then does this work in the famous script from Russ Ward in https://forums.adobe.com/message/3888653#3888653 which I have used in my last project?

               

              while(FA_errno === Constants.FE_Success && loopCounter++ < 2*loopMax) { //find and replace loop as long as we keep finding
                  activeDoc.TextSelection = tr;                // set up the text range to clear the original text
                  activeDoc.Clear(0);                          // clear it
                  activeDoc.AddText(tr.beg, replaceString);    // insert the new text at the original beginning of the text range
                  tr.beg.offset += replaceString.length;        // lets jimmy the text range in memory to place it directly after
              

               

              There are plenty of mysteries.

              • 4. Re: AddText does not add
                Klaus Göbel Level 3

                Sorry.

                Of course this is right.

                tr.beg is a textloc

                 

                shame on me.

                 

                EDIT:

                 

                 

                EDIT:

                 

                But in this case you are deleting the whole pgf and so the tr-object is deleted, too

                • 5. Re: AddText does not add
                  Russ Ward Level 4

                  Hi Klaus D.,

                   

                  Thanks for the fame. I didn't know what a sensation that script really is.

                   

                  While Klaus G. is normally the resident genius, I think the advice this time is incorrect. The "beg" and "end" members of a textrange are indeed textlocs, so it is proper to use either with AddText(). I don't know exactly what is wrong with your script, but I am sure that the problem is with your definition of "tr". Here are some notes/observations:

                   

                  1 - Are you absolutely sure that oPara is valid? If it is not, the whole operation will fail from the start.

                   

                  2 - While it may be OK to use new TextLoc() to define tr.end, it seems possibly risky to me. I don't know that for sure, but what I do know is that the previous methodology you use to define tr.beg works reliably. You already have a TextLoc array in the structure, so you can just do tr.end.obj = oPara, etc.

                   

                  3 - It seems like the code can enter an endless loop if the paragraph format varies. Your code to step to the next paragraph (line 8) is inside the "if (pgfFmt == type)" conditional. But then looking again, I see the "break" statement, which means that the while loop will never loop? I think this whole area is problematic.

                   

                  4 - While the following phrase seems logical, it is actually non-functional and may be another source of the problem:

                   

                  Constants.FV_OBJ_END_OFFSET - 2

                   

                  This constant is just some huge integer that FM uses as a flag, not as an explicit offset length. It basically tells FM that you want to select to the end of the object for future operations, but it does not dynamically become the actual length of the object. So, when you subtract 2 from it, you are changing the constant and thus eliminating any meaning it might have had. With your code, you are actually setting some huge explicit offset that FM might be choking on.

                   

                  The only way I know to accomplish your goal is to actually set the text selection, retrieve it again, then adjust the offset. For example:

                   

                  var tr = new TextRange(); 

                  tr.beg.obj =  oPara;                            // text range starts at the first found para 

                  tr.beg.offset = 0; 

                  while (oPara != null && oPara.ObjectValid ()) { 

                    pgfFmt = oPara.Name; 

                    if (pgfFmt == type) {                         // must not be interspearsed with other pgf formats

                      tr.end.obj = oPara;

                      tr.end.offset = Constants.FV_OBJ_END_OFFSET;   

                      oPara = oPara.NextPgfInFlow; 

                    }

                    else oPara = null;

                  }

                   

                  //Select the text in the doc

                  doc.TextSelection = tr;

                   

                  //Reset tr

                  tr = doc.TextSelection;

                  tr.end.offset -= 2;

                   

                  //Since you are replacing the text, maybe just delete it now?

                  //The AddText() method will not replace it!

                  doc.TextSelection = tr;

                  doc.Clear(0);

                   

                  tr = doc.TextSelection;

                   

                  return tr;

                   

                   

                   

                  PLEASE NOTE I just scratched this out, I did not test anything. There are likely some typos, errors, etc. I hope it helps.

                   

                  Russ

                  • 6. Re: AddText does not add
                    Klaus Göbel Level 3

                    Hi Russ,

                     

                    the problem in this case is, that the object of the textrange is deleted.

                     

                    One way could be to remember the my PrevPgf = pgf.PrevPgfInFlow, then delete the text.

                     

                    Rebuild it:

                    pgf = PrevPgf.NextPgfinFlow

                     

                    and use this pgf for a new textlocation.

                     

                    The problem in doing this is, if you delete the first PGF in flow. This you have to handle it separately. And take care of the LastPgf

                    • 7. Re: AddText does not add
                      frameexpert Level 4

                      Hi Russ, One comment on number 4 above: According to the FDK docs, it is OK to add or subtract numbers from the special Constants.FV_OBJ_END_OFFSET variable. From the "FDK Programmers Guide":

                       

                      To specify offsets near the end of an object, you can add or subtract integers from FV_OBJ_END_OFFSET.

                       

                      If have done this successfully in all three environments: the FDK, ExtendScript, and FrameScript. -Rick

                      • 8. Re: AddText does not add
                        K.Daube Level 1

                        @Russ: In my original post everything after "BTW: in the function ..." should be ignored. I could not edit my post after discovering that I had an empty ¶ which needed the -2 rather than a -1 to leave out the final ¶-mark from the selection.

                         

                        @Klaus: no, I'm not deleting the whole selection, because the selection does not include the alst ¶-mark. But nevertheless the tr object may be invalid after the deletion of the selection. I can not use the " PrevPgf = pgf.PrevPgfInFlow, then delete the text." construction, because the ¶s around the selection have other formats. The ¶-format-name is the "selection criterion". The paragraphs within the selection of coarse are

                         

                        Actually I'm very close to the solution (snippet A):

                        targetDoc.TextSelection = tr;                // set up the text range to clear the original text
                        targetDoc.Clear(0);                          // clear it
                        targetDoc.AddText(tr.end, replaceString); 
                        

                         

                        Using tr.end rather than tr.beg in line 3 of this snippet A  results in 'appended' paragraphs:

                         

                        ; ... document, they are also listed here
                        
                        #cats
                        #dogs
                        #HORSE
                        #DUCKUMENT
                        ;  comment line
                        

                        Line 2 is what exists after deleting the selection (line 2 in the snippet). ¶s 1 and 7  have format Ref-Comment, ¶s 2 … 6 have ¶ format Ref-Variables.

                        But manipulating the offset seems not to be a good idea. With (snippet B):

                        targetDoc.TextSelection = tr;                 // set up the text range to clear the original text
                        targetDoc.Clear(0);                           // clear it
                        tr.end.offset = -1;
                        targetDoc.AddText(tr.end, replaceString);
                        

                        The inserted ¶s get the format of ¶ 1 (that is format Ref-Comment)

                        I will try to build a script with just the relevant lines....

                        • 9. Re: AddText does not add
                          K.Daube Level 1

                          Friends, I have now cleaned out everything which is not needed to demonstrate...

                          However, use this test file

                          // ReplaceParagraphs.jsx
                          // use test file ReplaceParagraphs.fm
                          #target framemaker
                          
                          var gasUserVariables = ["#cats", "#dogs", "#HORSE", "#DUCKUMENT"];  
                          var goCurrentDoc = app.ActiveDoc;                // the current document
                          
                          PutRefPageItems ("Ref-Variables", "");
                          
                          function PutRefPageItems (category, itemName) { // ================================================
                            var flowName = "FM-calc";
                            var oFlow, oPara, tr, targetDoc = goCurrentDoc; 
                            var j, replaceString;
                          
                            oFlow = targetDoc.FirstFlowInDoc;              // go to the relevant flow in (ref) page
                            var notFound = true;
                            while (oFlow.ObjectValid()) {
                              if (oFlow.Name == flowName) {
                                notFound = false;
                                break; } 
                                oFlow = oFlow.NextFlowInDoc;
                            }
                            if (notFound) {
                              alert ("PutRefPageItems:\nFlow «" + flowName + "» does not exist in document\n"+ targetDoc);
                              return false;
                            }
                            oPara = oFlow.FirstTextFrameInFlow.FirstPgf;
                          
                            tr = GetParagraphs (oPara, "Ref-Variables");    // paragraphs to be replaced
                          //? $.bp(true);
                            replaceString  = "";
                            for (j = 0; j < gasUserVariables.length; j++) {
                              replaceString = replaceString + "\n" + gasUserVariables[j];  // \n gives new paragraphs
                            }
                            targetDoc.TextSelection = tr;                  // set up the text range to clear the original text
                            targetDoc.Clear(0);                            // clear it
                            tr.end.offset = 0;                              // 0, 1 create 'appended' paragraphs; 
                                                                            // -1 inserts in previous ¶ with wrong format
                            targetDoc.AddText(tr.end, replaceString);      // insert the new text
                          } // --- end PutRefPageItems
                          
                          function GetParagraphs (oPara, type) { // =========================================================
                            var pgfFmt;
                            while (oPara.ObjectValid ()) {
                              pgfFmt = oPara.Name;
                              if (pgfFmt == type) {                        // skip this
                                break;
                              }
                              oPara = oPara.NextPgfInFlow;
                              continue;
                            }                                              // we are now on the first of the relevant ¶
                          //? $.bp(true);
                            var tr = new TextRange();
                            tr.beg.obj =  oPara;                            // set up the starting text range as the very beginning
                            tr.beg.offset = 0;
                            while (oPara.ObjectValid ()) {
                              pgfFmt = oPara.Name;
                              if (pgfFmt == type) {                        // must not be interspearsed with other
                                tr.end = new TextLoc (oPara, Constants.FV_OBJ_END_OFFSET - 1);  
                                oPara = oPara.NextPgfInFlow;
                                continue;
                              }
                              break;
                            } 
                            return tr; 
                          }
                          

                           

                          Lines 37 ... 39 are the 'crucial' ones.

                          • 10. Re: AddText does not add
                            K.Daube Level 1

                            Dear friends,

                            I have found the culprit! It is not the problem with the textrange, but what I insert: The empty paragraph at the beginning of the inserted sequece is the result of a wrong preparation of the inserted string. This starts with an \n ...

                            The relevant portion of the script must read

                            replaceString  = "";
                            if (gasUserVariables.length > 0) {
                              replaceString  = gasUserVariables[0];
                              for (j = 1; j < gasUserVariables.length; j++) {
                                replaceString = replaceString + "\n" + gasUserVariables[j];  // \n gives new paragraphs
                              }
                            }
                            targetDoc.TextSelection = tr;                  // set up the text range to clear the original text
                            targetDoc.Clear(0);                            // clear it
                            targetDoc.AddText(tr.end, replaceString);      // insert the new text
                            

                             

                            Thank You all very much for Your assistance!

                            ... and lines 1 to 7 can be    replaced by

                            replaceString  = gasUserVariables.join("\n");
                            
                            • 11. Re: AddText does not add
                              Russ Ward Level 4

                              I guess I stand corrected about FF_OBJ_END_OFFSET. Somehow I was sure that this did not work. My apologies for the misinformation. It is good to be educated, because I always did believe that this would be very useful.

                               

                              Russ