Reset an array at the end of the frill processing

Hi,

I have a question with the array resetting after the end of the frill processing.

Originally, I planned to use an array to store texts on each page for indexing. The result is perfect when composing only one page. Unfortunately, when composing more than a page (compose range(+)), the array on each page has changed. I wonder if this is caused by the variables from the next page moved to the previous page for pagination checking.

I have undef the array at the end of the frill processing but the issue still exists. Can anyone point me in the right direction?

Regards,

Terrence

Parents
  • Hi Terrence,

    Just like Jonathan I have trouble understanding exactly what you are asking.

    I guess that the 'array' you are talking about is a perl array? Correct?
    But you will have to give us a lot of more info before we can help you.
    Maybe some extracts of your code might help.
    Also a bit more explanation on what and how you put things into the array and how and where you read them back out.

    Regards

    Bart

  • Hi Jonathan & Bart,

    Thanks for your response. Let me rephrase the question.

    I have a division in which some pages contain tagged text <index>..</index> and I use an array (@index) to store all the captured text and print it to an index page.

    On page 1:
    %<index>Index 1</index>The following are the details ...

    On page 2:
    %We provide property developers, <index>Index 2</index>property owners and <index>Index 3</index>residents with a variety of property management services ...

    The result is perfect when composing only one page, i.e. @index on page 1 contains Index 1 whereas @index on page 2 contains Index 2 and Index 3. However, when composing Whole Division, @index on page 1 contains not only Index 1, but also Index 2 and Index 3. @index on page 2 also contains Index 2 and Index 3. Is there any solution to prevent this from happening?

    Regards,

    Terrence

  • Still insufficient information. You didn't provide any extracts of your Perl code nor provide any detailed explanations regarding the questions Bart asked about. How do you separate the "index" entries that are from different pages when they are being being written to the array (or is that your problem because you are not doing that)?

    I'm going to defer to Bart's Perl expertise.

  • Yes Terrence,

    Like Jonathan said already, we need to see actual code in order to help you.
    In theory there should be no problem with what you are trying to achieve.
    But the devil is sometimes in the detail.
    (like are you using 'our' or 'my' variables, how/when are you trying to empty the arrary, how do add entries onto the array, ...?)

  • I defined the <index>..</index> macros to call a xyPerl function with the 'i' mode flag set, because of the multiple occurrences of the <index> on the same page, and every occurrence has been pushed onto the array. During the frill processing, I shift each index item every time when it hit a line with an <index> and undef the @index at the end of the frill processing to make it ready for the next page.

    In order to pass the array to frill processing, I use 'our' for the array (@index), but use 'my' for the variable for each captured text from perl and undef the array at the end of the frill processing.

    Belows are extract of the codings and how it undef the array

    ##################
    $X -> open_db("first","main","stream");
    if(open_ok) {
       $X->open_db("first","main","block");
       if(open_ok) {
          $X->open_db("first","main","line");
       }
    }
    while(open_ok) {
       if(db("flag")) {
          my $temp = shift @index;
          # Do something
       }
       $X->open_db("next","main","line");
       if(!open_ok){
          $X->open_db("next","main","block");
       }
    } # end while
    undef @index;

    ###################

    Regards,
    Terrence

  • Terrence,

    Do the frills processing function and the function that you use to push index terms onto the @index live in the same package?
    Do you call both functions using the 'p' (persistent) flag?

    Can you try what happens when you explicitly empty the array:
    @index = (); 
    (instead of undef it)

  • Hi Bart,

    Yes, both functions are in the same package and 'p' flag is using when calling perl function.

    The result is the same when using @index = () instead of using undef. 

    Regards,

    Terrence

  • Terrence,

    I just went through the trouble to build my own test job to see if I can duplicate your problem.

    And I can't.
    Everything works without a problem on my system.

    I just entered some text on a page and added some <index>term1</index> (term2, term3,...) entries to it.
    I just push the index term onto the @index array.
    And in the frills I read out all the terms on the index array and then undef the array.

    No problem at all when composing 1 page or all pages or any combination.

    Here is the xyPerl:

    ------------------
    package xybase2;

    our @index;

    sub capture {
      local $/;
      my $term = <STDIN>;
      push @index, $term;
    }

    sub dump {
      my $X = XPPcompo->new();
     ....frills processing loop...
     while(open_ok) {
       if(db("flag")) {
          my $term = shift @index;
         $X->sz('12pt');
         $X->set_text($term);
         $X->qa();
       }
      ...rest of frills processing loop...
      undef @index;

    capture is called from the <index> tag in the main text
    dump is called from the frills block

    and this is the screenshot of page 2:

    note that the <index> will suppress the the text.
    The item4, 5.. are located in the frill block.

    As said before the devil must be in the detail.

    Maybe you need to dumb down your setup and start from something simple like my example.
    This will enable to convince you that what you are trying to do actually works and might help you in finding the error in your real job.

    PS: last question:
    Do you call the xyPerl using the 'm' option?
    If so do not forget to strip the surrounding tags before you output them in the frills block.

Reply
  • Terrence,

    I just went through the trouble to build my own test job to see if I can duplicate your problem.

    And I can't.
    Everything works without a problem on my system.

    I just entered some text on a page and added some <index>term1</index> (term2, term3,...) entries to it.
    I just push the index term onto the @index array.
    And in the frills I read out all the terms on the index array and then undef the array.

    No problem at all when composing 1 page or all pages or any combination.

    Here is the xyPerl:

    ------------------
    package xybase2;

    our @index;

    sub capture {
      local $/;
      my $term = <STDIN>;
      push @index, $term;
    }

    sub dump {
      my $X = XPPcompo->new();
     ....frills processing loop...
     while(open_ok) {
       if(db("flag")) {
          my $term = shift @index;
         $X->sz('12pt');
         $X->set_text($term);
         $X->qa();
       }
      ...rest of frills processing loop...
      undef @index;

    capture is called from the <index> tag in the main text
    dump is called from the frills block

    and this is the screenshot of page 2:

    note that the <index> will suppress the the text.
    The item4, 5.. are located in the frill block.

    As said before the devil must be in the detail.

    Maybe you need to dumb down your setup and start from something simple like my example.
    This will enable to convince you that what you are trying to do actually works and might help you in finding the error in your real job.

    PS: last question:
    Do you call the xyPerl using the 'm' option?
    If so do not forget to strip the surrounding tags before you output them in the frills block.

Children
  • Let's back up a bit.

    I wonder if this is caused by the variables from the next page moved to the previous page for pagination checking.

    Now I'm wondering if fundamentally you're process is not accounting for how XPP composition works (as I now understand that you might have been asking about in your original post), in that (when there is sufficient text) composition first oversets the bottom of blocks (by some twenty or so lines) in order to determine where it is going to vertically break (to account for any keeps and/or widow/orphan rules and/or VJ squeeze rules).

    So, if there are any <index>...</index> occurrences within that "overset" text that then gets pushed to the next page then I can see that your saved array for a page might include index entries that end up on the next page.

    If that's what is happening, then you'll have to figure out a way to account for that.

    Jonathan Dagresta
    SDL XPP Engineering

  • Jonathan,

    Good point.

    But that should not be a problem, at least not with the code extract that Terrence gave us.
    It is OK if the array contains too many entries.

    An example will make this clear:
    Lets say that on the finished page 1 there are 3 index entries.
    Compose of the main text will add these 3 entries as the first 3 on the array.
    If compose needs to compose a few extra lines of page 2 and these extra lines contain further index entries, these extra entries will be pushed at the end of the index array.

    Now frills processing kicks in and we start looping through the lines of page 1. Like this we will only find 3 flagged lines that contain an index entry (see the code that Terrence provided).
    Only when a find a flagged line we shift an entry from the index array.
    Like that we will only read the first 3 entries on the index array as we shift the array only 3 times.
    The extra (page 2) entries will be on the array but they will never get used.
    Then at the end of the loop the array gets reset and is ready for the next page.

    Of course if Terrence looks at the content of the index array at the start of the frills processing, he will see the extra page 2 entries.
    But these should never get used.
    Not according to the code snippet Terrence gave us.

    Maybe it is time that we see the complete code Terrence is actually using...

    PS: I changed my test code example to stick closer to the original code from Terrence. Like this it no longer reads the complete content of the array but only the entries that really appear on the page.

  • Thanks Bart & Jonathan for the clear explanation.

    This is what exactly I want to ask. However, if the paragraph contains <index> tag in which "Index 2" is just located at the beginning of the line, like:

    %<index>Index 1</index>This summary aims to give you an overview of the information contained in this
    <index>Index 2</index>prospectus. Since it is a summary, it does not contain all the information that may be important to you and is qualified in its entirety by and should be read in conjunction with, the full prospectus.

    I am wondering if this may also happen to the line justification. Would "Index 2" be pushed twice into the array?

    Regards,
    Terrence

  • Terrence,

    Not sure. 
    I think the danger is bigger when the <index> tag is glued against the previous word.
    A thing which you can prevent by using the '!' preprocess operator.
    (not sure if that can still be combined with a /Pb macro in 'i' mode).
    I guess Jonathan is in a better position to give you a correct answer.

    I also wonder what you will do when 2 index terms fall on the same line.
    As you get only 1 flag but you need to output 2 index terms.

    Let me guess:
    Initially you simply tried by pushing the index term onto the px;;0 text register.
    But then you ran into the problem of what happens when there are 2 index terms on the same line as there is only 1 instance of the px;;0 register per line.

    Hence you decided to go the perl array route...

    If you really want to solve this multiple occurrence on the same line, then you better switch to the following way of working:

    We are going to use a number register to set a unique index number for each index term.
    So you first get hold of the current value of the (lets say) number register 10, increment it and store the content into the array at that index number.
    Something along the following lines:
    sub capture {
      local $/;
      my $term = <STDIN>;
      my $X = XPPcompo->new();
      my $number = $X->get_reg('#10');
      $number++;
      $index[$number] = $term;
      $X->ns(10,$number);
      $X->fg();
    }

    Then during the frills processing loop, when you encounter a flagged line, you read out the current instance of the same main number register using: 
      my $number = $X->get_main_numreg(10, 't');
    This will give you the array index of the last term for the current line.
    (the current instance is the value of the number register at the end of the line)
    If you keep track of the previous value that you read, you know how many and which terms you need to read from the array.

    Oh and before you start the frills processing loop, you read the first previous instance of the same number register, so that you have an initial value to start with.

    Well that is what I would do.
    There are probably other ways to solve the same problem...

  • Bart,

    It's awesome, but may I know when and how to reset the number register 10?

    Regards,

    Terrence