Listing graphics in order of appearance – Part 2

Since we want a list of graphics, there are a couple of ways to approach this. First, we can write our report at the same time as we are collecting the data. Or, we can collect all of the data first, and then write the report. I prefer the second approach because it tends to make the code simpler to understand.

What kind of data should we collect? It all depends on our needs but it usually doesn’t hurt to collect more than we need in case we need it later. Here is what I would suggest collecting:

  • The absolute path to the imported graphic.
  • The absolute path to the FrameMaker document containing the graphic.
  • The page number.
  • The unique ID of the anchored frame containing the graphic. This will allow us to build a hypertext link from the report to the graphic if desired.

Here is a function we can use to create a data structure to hold the graphic data. There are several ways that this could be done, but this approach uses a series of parallel lists to hold the data.

Set oImageData = GetDataStructure{};

Function GetDataStructure
//
Local Result(eUtl.EStructure{});

// Add a string list to hold the graphic paths.
Result.Graphics = eUtl.StringList{};

// Add a string list to hold the document paths.
Result.Docs = eUtl.StringList{};

// Add a string list to hold the page numbers.
Result.Pages = eUtl.StringList{};

// Add an integer list to hold the unique ids of the anchored frames.
Result.Uniques = eUtl.IntList{};
//
EndFunc //--------------------------------------------------------------------

This function will show you how to add to the data structure for each anchored frame.

Function ProcessAFrame oAFrame oImageData oDoc
//
Local oGraphic(0);

// Loop through the graphics in the anchored frame.
Set oGraphic = oAFrame.FirstGraphicInFrame;
Loop While(oGraphic)
  // Test for an imported graphic.
  If oGraphic.ObjectName = 'Inset'
    // See if it was imported by reference.
    If oGraphic.InsetFile <> ''
      // Add the data to the data structure.
      Add Member(oGraphic.InsetFile) To(oImageData.Graphics);
      Add Member(oDoc.Name) To(oImageData.Docs);
      Add Member(oAFrame.Page.PageNumString) To(oImageData.Pages);
      Add Member(oAFrame.Unique) To(oImageData.Uniques);
    EndIf
  EndIf
  Set oGraphic = oGraphic.NextGraphicInFrame;
EndLoop
//
EndFunc //--------------------------------------------------------------------

You will have to pass this oImageData object into your functions as you navigate the paragraphs and anchored frames in your document (or book). Let me backtrack and rework the code from the last post. I am just going to just post shells of the existing functions and point out what is different. See if you can put the pieces together.

// Test for an active document or book.
If (ActiveDoc = 0) and (ActiveBook = 0)
  MsgBox 'Please open a document or book.    ';
  LeaveSub; // Exit the script.
EndIf

// Call the function to make the empty data strucure.
Set oImageData = GetDataStructure{};

If ActiveBook
  // Book code can be added later.
  // Set iResult = ProcessBook{ActiveBook,oImageData};
Else
  Set iResult = ProcessDoc{ActiveDoc,oImageData};
EndIf

// Now write the report with the data.
// ... Call a report writing function here ...

Function ProcessDoc oDoc oImageData
//
Local i(0), tTextList(0), iResult(0);

// Lines 4 through 11 of the second code listing in the previous post go here.
// Line 8 will be replaced with this:
Set iResult = ProcessParagraph{oPgf,oImageData,oDoc};
//
EndFunc //--------------------------------------------------------------------

Function ProcessParagraph oPgf oImageData oDoc
//
Local tTextList(0), i(0), oAFrame(0), iResult(0);

// Lines 3 through 10 of the ProcessParagraph function in the previous post
// go here. Line 9 will be replaced with a call to the ProcessAFrame
// function in this post (above).
Set iResult = ProcessAFrame{oAFrame,oImageData,oDoc};
//
EndFunc //--------------------------------------------------------------------

Function ProcessTable oTbl oImageData oDoc
//
// This is the function from lines 17 to 45 of the second code listing in the
// previous post. Everything is the same, except we added a couple of
// parameters to line 17. Line 19 will now be:
Local oCell(0), oPgf(0), iResult(0);

// Lines 24, 32, and 40 will now contain this:
Set iResult = ProcessParagraph{oPgf,oImageData,oDoc};
//
EndFunc //--------------------------------------------------------------------

See if you can put it all together from both posts and make it work. You can test it by adding this line after line 18 in the previous code listing:

Display oImageData.Graphics;

This should display a list of the graphic names in a message box. Note that if you have a ton of graphics in your document, you might not see the entire dialog box. You should be able to press Enter or Escape to dismiss it if you can’t see the OK/Cancel buttons. Alternatively, you can write the list to the FrameMaker Console window by using this:

Write Console oImageData.Graphics;

In another post, we can explore how to write the report. Comments or questions are welcome.

Leave a Reply

Your email address will not be published. Required fields are marked *