Working off paragraphs in two successive While loops

Advocate ,
Nov 20, 2015 Nov 20, 2015

Copy link to clipboard

Copied

Dear experts,
In continuation of "How to define the offset for a textrange (after a TAB)?" i have implemented the snippet into the existing script-flow (simplefied for the presentation here):

  • Read an RTF which contains two parts of tabbed paragraphs. See the file FM-biblio-collected-test.fm.
    This contains 4 paragraphs in the first part and 3 paragraphs in the second part.
  • Reading pgfs in the first part works perfectly. These all start with [[   (script lines 10 ... 26)
  • The first pgf of the second part (paragraph number 5) is already read, terminating the first While loop due to missing [[ at the beginning.
  • Further processing of this paragraph (script lines 27 ... 35) reveals that not paragraph 5, but paragraph 1 is processed! (textrange in line 41 is from position 21 to 22, which fits only to the first paragraph!
  • Of course this leads to the message in line 43

Why does line 29 not get the same paragraph object (paragraph 5) as it was handled correctly in the previous While as last object?

// Have the expanded RTF file (FM-biblio-collected-test.fm) open

#target framemaker 
 
var goRtfDoc = app.ActiveDoc; 
var pgf = goRtfDoc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;  // get first pgf in flow
var TAB = String.fromCharCode(8);               // FM has wrong ASCI for TAB
var tabRange

// --- read the temp/formatted citations --- "formatted" consist of the reference number only
  while (pgf.ObjectValid()) {
    pgfText = GetText (pgf, goRtfDoc);
    if (pgfText.substring (0,2) === "[[") {       // citation lines start with [[
      parts = pgfText.split(TAB);                 // get the two parts of the line
      parts[0] = parts[0].replace("[[", "{");     // replace [[...]] by {...} for find in user doc
      parts[0] = parts[0].replace("]]", "}");
      if (parts[1].substring (0,1) === "{") {     // this placeholder is unresolved, skip it
        nUnres += 1;
        pgf = pgf.NextPgfInFlow;
        continue;
      }
//    gasFmtCitsRaw.push (parts[0]);              // store the placeholder citation
//    gasFmtCitsFmt.push (parts[1]);              // store the formatted citation (just a number)
      pgf = pgf.NextPgfInFlow;
    } else { break }                              // first line of bibliography encountered
  }
// --- read the bibliography paragraphs
  while (pgf.ObjectValid()) {                     // until end of doc
    tabRange = GetTabRange (pgf, goRtfDoc);       // Get the text range starting after the TAB to the end of the paragraph. 
//  gaoBibliography.push(tabRange);               // store the paragraph-part in the array
    goRtfDoc.TextSelection = tabRange;      // for later use in tests
    goRtfDoc.Copy (0);                      // Check manually what can be copied
    alert ("are we OK?");
    pgf = pgf.NextPgfInFlow;
  }

function GetTabRange (pgf, doc) { 
  var textLoc, textRange, findParams, tabRange; 
  textLoc = new TextLoc (pgf, 0);                 // Make a text location at the beginning of the paragraph.
  findParams = GetFindParams ("\x08");            // Get the find parameters for finding a tab. 
  textRange = doc.Find (textLoc, findParams);     // Search for the string. 
  if (textRange.beg.obj.ObjectValid ()) {         // See if the tab was found. 
    alert (textRange.beg.obj.Unique + "    " + pgf.Unique);   //?? Is <> if cursor is not at start of pgf.
    if (textRange.beg.obj.Unique === pgf.Unique) {// Make sure the tab is in the correct paragraph.
      // Select the text from after the tab up to the end of the paragraph. 
      tabRange = new TextRange (new TextLoc (pgf, textRange.beg.offset+1), new TextLoc (pgf, Constants.FV_OBJ_END_OFFSET - 1)); 
      return tabRange;                            // Return the text range.
    } 
  } 
  return 0;                                       // TAB Not found

 
function GetFindParams (string) { 
  var findParams = AllocatePropVals (1); 
  findParams[0].propIdent.num = Constants.FS_FindText; 
  findParams[0].propVal.valType = Constants.FT_String; 
  findParams[0].propVal.sval = string; 
  return findParams; 
} // --- end of GetFindParams
 
function GetText (textObj, doc) {
  var j, text = "", textItems;
  if (textObj.constructor.name !== "TextRange") { // Get a list of the strings in the text object or text range
    var textItems = textObj.GetText(Constants.FTI_String);
  } else {
    textItems = doc.GetTextForRange(textObj, Constants.FTI_String);
  }
  for (var j = 0; j < textItems.len; j += 1) {    // Concatenate the strings
    text += (textItems.sdata);
  }
  return text;                                    // Return the text
} // --- end GetText

Any ideas are welcome

Klaus Daube

TOPICS
Scripting

Views

571

Likes

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

Mentor , Dec 01, 2015 Dec 01, 2015
Klaus,I can't explain the behavior you are seeing, as it appears that textLoc is ignored in line 41:textRange = doc.Find (textLoc, findParams);I don't know if it is a bug, or what the problem is. However, I did find a potential workaround. I added the following lines just before line 41, in order to force the insertion point to the beginning of the current paragraph:var searchStart = new TextRange(new TextLoc(pgf,0), new TextLoc (pgf, 0));doc.TextSelection = searchStart;...as in: function GetTab...

Likes

Translate

Translate
Advocate ,
Nov 24, 2015 Nov 24, 2015

Copy link to clipboard

Copied

Further investigation with the test file mentioned in the first post.

To come closer to the problem I insert logging (the Console command does not log into the JavaScript console of ESTK, hence the $.writeln)

after line 41:    $.writeln ("3: "+ textRange.beg.obj.Unique + "    " + pgf.Unique);
Line 43 removed.

after line 27:    $.writeln ("2: " + pgf.Unique);
after line 12:    $.writeln ("1: " + pgf.Unique);
Then I put the cursor at the beginning of the the test file and run the script.

The console shows this (<- ... is comment)

1: 999540        <- first para in first part
1: 999551        <- second para in first part
1: 999562        <- third para in first part
1: 999571        <- fourth para in first part
1: 999582        <- fifth para =  first of second part
2: 999582
3: 999540    999582
3: 999551    999593
3: 999562    999606
Result: [object Pgf]

Hence GetTabRange searches in the first three pgfs of the document, although the While loop runs through the 3 pgf of the second part.
Why this?

Likes

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
Advocate ,
Nov 30, 2015 Nov 30, 2015

Copy link to clipboard

Copied

I'm still stuck in this problem:

In fucntion GetTabRange (pgf, doc) the line

textRange = doc.Find (textLoc, findParams);

finds the TAB in the first paragraph of the test document (red rectangle), not in the current paragraph (blue rectangle). The read lines to the right indicate the Para-IDs

01-test-doc.png

I have placed a breakpoint in function GetTabRange and tiptoed until after the Find:

01-breakpoint.png

At this point the databrowser confirms with the values for the begin- and end-offsets that I'm in the first paragraph, not the fifth.

01-databrowse.png

Why does doc.find search not search in the current paragraph (ID = 999582)?

Likes

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 ,
Dec 01, 2015 Dec 01, 2015

Copy link to clipboard

Copied

Klaus,

I can't explain the behavior you are seeing, as it appears that textLoc is ignored in line 41:

textRange = doc.Find (textLoc, findParams);

I don't know if it is a bug, or what the problem is. However, I did find a potential workaround. I added the following lines just before line 41, in order to force the insertion point to the beginning of the current paragraph:

var searchStart = new TextRange(new TextLoc(pgf,0), new TextLoc (pgf, 0));

doc.TextSelection = searchStart;

...as in:

function GetTabRange (pgf, doc) {   

   

  var textLoc, textRange, findParams, tabRange;   
  textLoc = new TextLoc (pgf, 0);             // Make a text location at the beginning of the paragraph.  
  findParams = GetFindParams ("\x08");        // Get the find parameters for finding a tab.   
  var searchStart = new TextRange (new TextLoc (pgf,0), new TextLoc (pgf, 0));   
  doc.TextSelection = searchStart;
  textRange = doc.Find (textLoc, findParams); // Search for the string.   
  if (textRange.beg.obj.ObjectValid ()) {     // See if the tab was found.   
    alert (textRange.beg.obj.Unique + " " + pgf.Unique);   //?? Is <> if cursor is not at start of pgf.  
    if (textRange.beg.obj.Unique === pgf.Unique) {// Make sure the tab is in the correct paragraph.  
      // Select the text from after the tab up to the end of the paragraph.   
      tabRange = new TextRange (new TextLoc (pgf, textRange.beg.offset+1), new TextLoc (pgf, Constants.FV_OBJ_END_OFFSET - 1));   
      return tabRange;                        // Return the text range.  
    }   
  }   
  return 0;                                   // TAB Not found 
}

After this, the behavior of the script seems to match what you want. I hope this helps some. By the way, the code sample looks all crazy in my browser editor, not sure how it will appear when I click Add Reply.

Russ

Likes

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 ,
Dec 01, 2015 Dec 01, 2015

Copy link to clipboard

Copied

OK, it added lots of empty lines, but I think all the content is still there.

Likes

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
Advocate ,
Dec 01, 2015 Dec 01, 2015

Copy link to clipboard

Copied

Thank You very much, Russ, this is really the solution to my problem.

And it's a relief that also the experts have no idee whythe waters are so murky.

Klaus

The correctly working function is this:

function GetTabRange (pgf, doc) { 
  var textLoc, textRange, findParams, tabRange; 
  textLoc = new TextLoc (pgf, 0);                 // Make a text location at the beginning of the paragraph.
  findParams = GetFindParams ("\x08");            // Get the find parameters for finding a tab.
// --- the following two lines by Russ Ward  saved my project
  var searchStart = new TextRange(new TextLoc(pgf,0), new TextLoc (pgf, 0));
  doc.TextSelection = searchStart;
// --- because otherwise the following statement starts at the beginning of the file, not the current pgf
  textRange = doc.Find (textLoc, findParams);     // Search for the string. 
  if (textRange.beg.obj.ObjectValid ()) {         // See if the tab was found. 
    if (textRange.beg.obj.Unique === pgf.Unique) {// Make sure the tab is in the correct paragraph.
      // Select the text from after the tab up to the end of the paragraph. 
      tabRange = new TextRange (new TextLoc (pgf, textRange.beg.offset+1), new TextLoc (pgf, Constants.FV_OBJ_END_OFFSET - 1)); 
      return tabRange;                            // Return the text range.
    } 
  } 
  return 0;                                       // TAB Not found
}

Likes

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 ,
Dec 01, 2015 Dec 01, 2015

Copy link to clipboard

Copied

LATEST

Also, I apologize that my response was so delayed. I took a week off for the US Thanksgiving holiday and hardly touched the computer during that time. I'm thankful for that.

Likes

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