• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

AddText does not add

Community Expert ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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;   // \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.

TOPICS
Scripting

Views

884

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

correct answers 1 Correct answer

Community Expert , May 26, 2016 May 26, 2016

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;  // \

...

Votes

Translate

Translate
Community Expert ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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...

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 ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

Hi Klaus,

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

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 ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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.

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 ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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

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
Mentor ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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

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 ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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

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 ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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

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 ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

@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....

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 ,
May 25, 2016 May 25, 2016

Copy link to clipboard

Copied

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;  // \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.

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 ,
May 26, 2016 May 26, 2016

Copy link to clipboard

Copied

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;  // \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");

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
Mentor ,
May 26, 2016 May 26, 2016

Copy link to clipboard

Copied

LATEST

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

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