Skip to main content
Participant
March 14, 2022
Answered

Open every component of a book , copy its content and paste it into a single frame

  • March 14, 2022
  • 5 replies
  • 346 views

Hello,
I have plenty of documents split as components in books. I have a specific need that requires to flatten all these components in a single file and help a publication/conversion process to HTML.

I currently have several chunks of code that succeed independantly the following actions:

1. crawl a book, check every component, and open them individually

2. create a temporary file that will receive the content copied in the components

3. copy content in component from the first paragraph to the last available

3. paste it in the temporary file

Now, I've tried to gather all of this and make it work, but without success. I don't have any error provided, and I suspect a conflict with the identification of the doc where content must be pasted.
I just start to get acquainted with Extendscript and I miss more tutorials or resources. 
Thanks a lot for any pointer and tips!

        counter++;
        comp.ComponentIsSelected = true;
        var compType = comp.ComponentType;        
        comp.ComponentIsSelected = false;
        // goto the next component
        comp = comp.NextBookComponentInDFSOrder;
    }
    var comp = book.FirstComponentInBook;    
    while(comp.ObjectValid())
    {
        if(comp.ComponentType == Constants.FV_BK_FILE)
        {
            if(doc.ObjectValid())
            {
                alert("Successfully opened: \n\n" + comp.Name);
                // variables for the copy/paste process
                var doc = OpenFile(comp.Name);
                var mainflow = doc.MainFlowInDoc;
                var tframe = mainflow.FirstTextFrameInFlow;
                var pgf = tframe.FirstPgf;
                var lastPgf = mainflow.LastTextFrameInFlow.LastPgf;
                //copy the paragraphs from start to end
                tRange.beg.obj = pgf;
                tRange.beg.offset = 0;
                tRange.end.obj = lastPgf;
                tRange.end.offset = Constants.FV_OBJ_END_OFFSET;
                doc.TextSelection = tRange;
                doc.Copy(0);
                // Paste to the other document called duplicateDoc
                duplicateDoc.NewSeriesObject(Constants.FO_Pgf, pgf);
                tRange.beg.obj = pgf.NextPgfInFlow;
                //tRange.beg.offset =0;
                //tRange.end = tRange.beg;
                tRange.end = lastPgf;
                duplicateDoc.TextSelection = tRange;
                duplicateDoc.Paste(0);
            }
            else
            { 
                alert("Could not open: \n\n" 
                    + comp.Name
                    + "\n\nMaybe the file doesn't exist?\n\n"
                    + "We are going to delete this component now "
                    + "because we want to do a book update, but " 
                    + "it will fail with this bogus component.");
                var compToDelete = comp;
                comp = comp.PrevBookComponentInDFSOrder;
                if(!comp.ObjectValid()) comp = comp.FirstComponentInBook;
                compToDelete.Delete();
            }
        }    
        comp = comp.NextBookComponentInDFSOrder;
    }
// required for the crawling of the components
    var index = GetPropIndex(props, Constants.FS_ShowBookErrorLog);
    props[index].propVal.ival = true;
    var returnp = new PropVals();
}
else
    alert("No book is open or active. Cannot run the script.");
    
    
// global function used to handle the warning messages

function OpenFile(path)
{
    var index;
    props = GetOpenDefaultParams();
    index = GetPropIndex(props, Constants.FS_AlertUserAboutFailure);
    if(index > -1) 
        props[index].propVal.ival = false;
    index = GetPropIndex(props, Constants.FS_FileIsInUse);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_ResetLockAndContinue;

    index = GetPropIndex(props, Constants.FS_BookIsInUse);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_ResetLockAndContinue;
    index = GetPropIndex(props, Constants.FS_LockCantBeReset);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;
    index = GetPropIndex(props, Constants.FS_DisallowMIF);
    if(index > -1) 
        props[index].propVal.ival = false;
    index = GetPropIndex(props, Constants.FS_DisallowXml);
    if(index > -1) 
        props[index].propVal.ival = false;
    index = GetPropIndex(props, Constants.FS_FileIsOldVersion);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;
    index = GetPropIndex(props, Constants.FS_FontChangedMetric);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;
    index = GetPropIndex(props, Constants.FS_FontNotFoundInCatalog);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;      
    index = GetPropIndex(props, Constants.FS_FontNotFoundInDoc);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;
    index = GetPropIndex(props, Constants.FS_LanguageNotAvailable);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;
   index = GetPropIndex(props, Constants.FS_OpenAsType);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_AUTORECOGNIZE;
    index = GetPropIndex(props, Constants.FS_UpdateTextReferences);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoNo;     
    index = GetPropIndex(props, Constants.FS_UpdateXRefs);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoNo;
    index = GetPropIndex(props, Constants.FS_UseRecoverFile);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoNo;        
    index = GetPropIndex(props, Constants.FS_UseAutoSaveFile);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoNo;
    index = GetPropIndex(props, Constants.FS_OpenFileNotWritable);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;
    index = GetPropIndex(props, Constants.FS_RefFileNotFound);
    if(index > -1) 
        props[index].propVal.ival = Constants.FV_DoOK;
        
    returnp = new PropVals();
    var file = Open(path, props, returnp);
    return file;
}

 

This topic has been closed for replies.
Correct answer frameexpert

One other approach to consider opposed to the clipboard approach: you may want to try importing each component into the combined document (programatically use File > Import > File). That would prevent you from having to open each document and select its contents and then copy/paste.

 

One other thing about the clipboard: it is a stack, so before you copy or cut, you can use this to store the current clipboard's content:

PushClipboard ();
doc.Copy ();

Then, after pasting, you can restore the previous clipboard content:

doc.Paste ();
PopClipboard ();

5 replies

frameexpert
Community Expert
frameexpertCommunity ExpertCorrect answer
Community Expert
March 14, 2022

One other approach to consider opposed to the clipboard approach: you may want to try importing each component into the combined document (programatically use File > Import > File). That would prevent you from having to open each document and select its contents and then copy/paste.

 

One other thing about the clipboard: it is a stack, so before you copy or cut, you can use this to store the current clipboard's content:

PushClipboard ();
doc.Copy ();

Then, after pasting, you can restore the previous clipboard content:

doc.Paste ();
PopClipboard ();
Jeff_Coatsworth
Community Expert
Community Expert
March 14, 2022

I don't know anything about scripting, but what about the approach of creating the target .fm file & then going off and fetching each component from the book and putting it in as a text inset? Maybe that's easier to do?

Participant
March 14, 2022

Actually, I need to automate this task, because there are plenty of books to work from.

frameexpert
Community Expert
Community Expert
March 14, 2022

Hi. I don't have a lot of time to discect your code, but I can give you some advice about what I see. First, I would break this down into separate tasks, that you can test and troubleshoot separately. For example,

  • Navigate the book, opening and closing each component. Or, if you just want to process selected components, navigate the selected components and open and close each one. Suggested function names: processComponents (book) or processSelectedComponents (book). I give these generic names because you could reuse them for other tasks or scripts.
  • For an active document, select and copy the content to the clipboard (copyDocContent (doc)).
  • For the target document, paste content at end (pasteClipboardAtEndOfFlow (doc)). Keep in mind that after you paste the clipboard content at the end of the document, the document may have an empty paragraph at the end, so you don't always have to create a new paragraph to paste into.
  • After you have developed and tested each of your functions, you can put them together in a finished script.
  • I would not delete each component as I go as this will make your testing slower. You will have to revert to save as you test your script because you have deleted the components. If you want to delete them in your finished script, you could simply store them in an array (compsToDelete = []) and then delete all of the components at the end of the process.
Trevor34Author
Participant
March 14, 2022

Thank you! I appreciate your help. It seems a little less challenging when you describe it 🙂

Jeff_Coatsworth
Community Expert
Community Expert
March 14, 2022

Ok - and is this a one-shot deal or will you have to do it repeatedly?

Jeff_Coatsworth
Community Expert
Community Expert
March 14, 2022

Do you need 1 big .fm file? Or are you looking to just produce 1 big HTML file from all the FM content?

Participant
March 14, 2022

Hello, Jeff,
I try to get one big .fm file and to preserve the others files in the component